std::shared_ptr, RTTI, and LLDB

Currently, LLDB uses std::shared_ptr. With gcc (or at least gcc 4.4),
that means RTTI must be enabled. However, LLVM and clang build with
RTTI disabled (at least by default), so an RTTI-enabled LLDB won't
link. So I have two questions:

1. How difficult would it be to stop using shared_ptr?
2. Does the LLVM build in llvm.zip have RTTI enabled? If so, how do
you build LLVM that way?

-Eli

Currently, LLDB uses std::shared_ptr. With gcc (or at least gcc 4.4),
that means RTTI must be enabled. However, LLVM and clang build with
RTTI disabled (at least by default), so an RTTI-enabled LLDB won't
link. So I have two questions:

1. How difficult would it be to stop using shared_ptr?

We use a lot of shared pointers, though we aren't currently using the fancy RTTI aspects of it. We really want _some_ sort of shared pointer so we can have STL collections of objects that don't move around when collections grow. Also with a lot of our partial parsing we can determine how many objects there are in a collection, resize the collection to contain that many objects, then lazily populate such objects.

2. Does the LLVM build in llvm.zip have RTTI enabled?

No.

If so, how do you build LLVM that way?

We don't. There are a few Clang/LLVM files that have RTTI manually disabled (add "-fno-rtti" to the compiler flags for these files) on them:

ClangASTContext.cpp
RecordingMemoryManager.cpp
ClangASTSource.cpp

We try to not just intersperse Clang/LLVM just anywhere, we tend to try and abstract those calls behind one of these files. The main reason for this is then we know the interface that we will eventually require from LLVM/Clang when/if they ever vend shared library versions of themselves.

So for now, any code that runs into RTTI issues is abtracted into files that can disable RTTI and do the work in the implementation file (cpp file) and keep the header files RTTI neutral.

Currently, LLDB uses std::shared_ptr. With gcc (or at least gcc 4.4),
that means RTTI must be enabled. However, LLVM and clang build with
RTTI disabled (at least by default), so an RTTI-enabled LLDB won't
link. So I have two questions:

1. How difficult would it be to stop using shared_ptr?

We use a lot of shared pointers, though we aren't currently using the fancy RTTI aspects of it. We really want _some_ sort of shared pointer so we can have STL collections of objects that don't move around when collections grow. Also with a lot of our partial parsing we can determine how many objects there are in a collection, resize the collection to contain that many objects, then lazily populate such objects.

Okay... so it might potentially be possible to switch to something
simpler, more like boost::intrusive_ptr? I won't bother if there's a
simpler solution, though; see below.

2. Does the LLVM build in llvm.zip have RTTI enabled?

No.

If so, how do you build LLVM that way?

We don't. There are a few Clang/LLVM files that have RTTI manually disabled (add "-fno-rtti" to the compiler flags for these files) on them:

ClangASTContext.cpp
RecordingMemoryManager.cpp
ClangASTSource.cpp

Ah, I see. There's a bit of an issue here, then: LLVM's make system
only supports enabling/disabling RTTI on a per-directory basis. Would
you mind moving those files into subdirectories?

We try to not just intersperse Clang/LLVM just anywhere, we tend to try and abstract those calls behind one of these files. The main reason for this is then we know the interface that we will eventually require from LLVM/Clang when/if they ever vend shared library versions of themselves.

Oh... I don't know if you've noticed, but I've been doing things like
using llvm/ADT/StringExtras.h; is that not okay?

-Eli

Currently, LLDB uses std::shared_ptr. With gcc (or at least gcc 4.4),
that means RTTI must be enabled. However, LLVM and clang build with
RTTI disabled (at least by default), so an RTTI-enabled LLDB won't
link. So I have two questions:

1. How difficult would it be to stop using shared_ptr?

We use a lot of shared pointers, though we aren't currently using the fancy RTTI aspects of it. We really want _some_ sort of shared pointer so we can have STL collections of objects that don't move around when collections grow. Also with a lot of our partial parsing we can determine how many objects there are in a collection, resize the collection to contain that many objects, then lazily populate such objects.

Okay... so it might potentially be possible to switch to something
simpler, more like boost::intrusive_ptr? I won't bother if there's a
simpler solution, though; see below.

As long as it is a reference counted pointer that doesn't require us to build boost.

We can easily replace all shared pointers within LLDB by redefining "lldb::SharedPtr" in lldb-types.h.

Feel free to experiment, though I would rather not pull in all of boost just to get a shared pointer... We currently get that from a tr1 directory on MacOSX. Does linux have a similar implementation in tr1 (#include <tr1/memory>)? We do make use of putting objects into shared pointers that are the virtual base class impementations of pure virtual protocols, so I am not sure if this requires RTTI (I can't remember what role RTTI plays in the shared pointers...).

2. Does the LLVM build in llvm.zip have RTTI enabled?

No.

If so, how do you build LLVM that way?

We don't. There are a few Clang/LLVM files that have RTTI manually disabled (add "-fno-rtti" to the compiler flags for these files) on them:

ClangASTContext.cpp
RecordingMemoryManager.cpp
ClangASTSource.cpp

Ah, I see. There's a bit of an issue here, then: LLVM's make system
only supports enabling/disabling RTTI on a per-directory basis. Would
you mind moving those files into subdirectories?

We can do that.

We try to not just intersperse Clang/LLVM just anywhere, we tend to try and abstract those calls behind one of these files. The main reason for this is then we know the interface that we will eventually require from LLVM/Clang when/if they ever vend shared library versions of themselves.

Oh... I don't know if you've noticed, but I've been doing things like
using llvm/ADT/StringExtras.h; is that not okay?

What are the main uses of this? Was this for the gcc hash map replacement stuff I saw where we use LLVM's hasher? That's not so bad as long as we don't run into RTTI issues.

Greg Clayton

Currently, LLDB uses std::shared_ptr. With gcc (or at least gcc 4.4),
that means RTTI must be enabled. However, LLVM and clang build with
RTTI disabled (at least by default), so an RTTI-enabled LLDB won't
link. So I have two questions:

1. How difficult would it be to stop using shared_ptr?

We use a lot of shared pointers, though we aren't currently using the fancy RTTI aspects of it. We really want _some_ sort of shared pointer so we can have STL collections of objects that don't move around when collections grow. Also with a lot of our partial parsing we can determine how many objects there are in a collection, resize the collection to contain that many objects, then lazily populate such objects.

Okay... so it might potentially be possible to switch to something
simpler, more like boost::intrusive_ptr? I won't bother if there's a
simpler solution, though; see below.

As long as it is a reference counted pointer that doesn't require us to build boost.

We can easily replace all shared pointers within LLDB by redefining "lldb::SharedPtr" in lldb-types.h.

Feel free to experiment, though I would rather not pull in all of boost just to get a shared pointer... We currently get that from a tr1 directory on MacOSX. Does linux have a similar implementation in tr1 (#include <tr1/memory>)? We do make use of putting objects into shared pointers that are the virtual base class impementations of pure virtual protocols, so I am not sure if this requires RTTI (I can't remember what role RTTI plays in the shared pointers...).

AFAIK, the shared_ptr RTTI is only necessary for get_deleter. And
actually, I think it's possible to use it without RTTI with the
libstdc++ in gcc 4.5.

I didn't remember originally, but actually we don't have to pull in
anything; llvm::IntrusiveRefCntPtr is roughly equivalent.

2. Does the LLVM build in llvm.zip have RTTI enabled?

No.

If so, how do you build LLVM that way?

We don't. There are a few Clang/LLVM files that have RTTI manually disabled (add "-fno-rtti" to the compiler flags for these files) on them:

ClangASTContext.cpp
RecordingMemoryManager.cpp
ClangASTSource.cpp

Ah, I see. There's a bit of an issue here, then: LLVM's make system
only supports enabling/disabling RTTI on a per-directory basis. Would
you mind moving those files into subdirectories?

We can do that.

Let me try out converting everything to IntrusiveRefCntPtr; we can go
with this if that doesn't work out.

We try to not just intersperse Clang/LLVM just anywhere, we tend to try and abstract those calls behind one of these files. The main reason for this is then we know the interface that we will eventually require from LLVM/Clang when/if they ever vend shared library versions of themselves.

Oh... I don't know if you've noticed, but I've been doing things like
using llvm/ADT/StringExtras.h; is that not okay?

What are the main uses of this? Was this for the gcc hash map replacement stuff I saw where we use LLVM's hasher? That's not so bad as long as we don't run into RTTI issues.

Yes, stuff like that. So possibly-RTTI stuff is primarily the issue?
Okay then; everything I can think of in ADT should be safe.

-Eli

Currently, LLDB uses std::shared_ptr. With gcc (or at least gcc 4.4),
that means RTTI must be enabled. However, LLVM and clang build with
RTTI disabled (at least by default), so an RTTI-enabled LLDB won't
link. So I have two questions:

1. How difficult would it be to stop using shared_ptr?

We use a lot of shared pointers, though we aren't currently using the fancy RTTI aspects of it. We really want _some_ sort of shared pointer so we can have STL collections of objects that don't move around when collections grow. Also with a lot of our partial parsing we can determine how many objects there are in a collection, resize the collection to contain that many objects, then lazily populate such objects.

Okay... so it might potentially be possible to switch to something
simpler, more like boost::intrusive_ptr? I won't bother if there's a
simpler solution, though; see below.

As long as it is a reference counted pointer that doesn't require us to build boost.

We can easily replace all shared pointers within LLDB by redefining "lldb::SharedPtr" in lldb-types.h.

Feel free to experiment, though I would rather not pull in all of boost just to get a shared pointer... We currently get that from a tr1 directory on MacOSX. Does linux have a similar implementation in tr1 (#include <tr1/memory>)? We do make use of putting objects into shared pointers that are the virtual base class impementations of pure virtual protocols, so I am not sure if this requires RTTI (I can't remember what role RTTI plays in the shared pointers...).

AFAIK, the shared_ptr RTTI is only necessary for get_deleter. And
actually, I think it's possible to use it without RTTI with the
libstdc++ in gcc 4.5.

I didn't remember originally, but actually we don't have to pull in
anything; llvm::IntrusiveRefCntPtr is roughly equivalent.

Hmm, I didn't realize the shared_ptrs were being so heavily used; it's
way too much work to convert to an intrusive refcounting pointer.

2. Does the LLVM build in llvm.zip have RTTI enabled?

No.

If so, how do you build LLVM that way?

We don't. There are a few Clang/LLVM files that have RTTI manually disabled (add "-fno-rtti" to the compiler flags for these files) on them:

ClangASTContext.cpp
RecordingMemoryManager.cpp
ClangASTSource.cpp

Ah, I see. There's a bit of an issue here, then: LLVM's make system
only supports enabling/disabling RTTI on a per-directory basis. Would
you mind moving those files into subdirectories?

We can do that.

Let me try out converting everything to IntrusiveRefCntPtr; we can go
with this if that doesn't work out.

So, please move the files into subdirectories.

-Eli