I am compiling this code in AppleClang 12.0.5, using command:
clang++ -O2 -g -fvisibility=hidden -std=c++17 -Wpedantic -c sharedlib.cpp
and I am checking list of symbols in object file via:
nm -om sharedlib.o | c++filt | grep "typeinfo for"
Code itself (sharedlib.cpp):
namespace Foo
{
template <class T>
class BarHidden;
class BarExported;
}
typedef Foo::BarHidden<double> BarHiddenTypedef;
typedef Foo::BarExported BarExportedTypedef;
namespace Foo
{
template<typename T>
class __attribute__((visibility("default"))) BarHidden
{
public:
virtual ~BarHidden(){};
};
class __attribute__((visibility("default"))) BarExported
{
public:
virtual ~BarExported(){};
};
}
void __attribute__((visibility("default"))) Throw()
{
// throw Foo::BarExported(); // weak external typeinfo for Foo::BarExported
// throw Foo::BarHidden<int>(); // weak external typeinfo for Foo::BarHidden<int>
throw Foo::BarHidden<double>(); // weak private external typeinfo for Foo::BarHidden<double>
}
Can someone explain why 1st and 2nd throw leave visible external typeinfo (expected), but third throw leaves typeinfo symbol with hidden visibility? It looks like typedef instantiates Foo::BarHidden with incorrect visibility attribute (I blame typedef because compiler produces visible typeinfo if I remove BarHiddenTypedef typedef), but is this behavior expected? Is it possible to disable it? I have huge codebase that can potentially have problems of this kind, and I want to be sure all typeinfos of my dylib are visible.