http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59469
--- Comment #2 from Markus Trippelsdorf <octoploid at yandex dot com> ---
markus@x4 llvm_build % cat BasicBlock.ii
struct A {};
namespace llvm {
struct B {};
template <typename> struct ilist_traits : B {};
template <typename> class ilist_iterator : A {
public:
ilist_iterator(int) {}
int operator!=(ilist_iterator &);
void operator++();
};
template <typename NodeTy, typename Traits = ilist_traits<NodeTy> >
class C : Traits {
C &transfer_L2;
public:
A splice_where;
void splice() { this->transferNodesFromList(transfer_L2, 0, 0); }
};
class Function;
template <typename ValueSubClass, typename ItemParentClass>
class SymbolTableListTraits : B {
public:
ItemParentClass *getListOwner();
void transferNodesFromList(ilist_traits<ValueSubClass> &p1,
ilist_iterator<ValueSubClass>,
ilist_iterator<ValueSubClass>);
};
class BasicBlock {
Function *getParent();
void moveBefore();
};
template <typename ValueSubClass, typename ItemParentClass>
void
SymbolTableListTraits<ValueSubClass, ItemParentClass>::transferNodesFromList(
ilist_traits<ValueSubClass> &p1, ilist_iterator<ValueSubClass> p2,
ilist_iterator<ValueSubClass> p3) {
ItemParentClass a = *getListOwner() = *p1.getListOwner();
int b = *ilist_traits<ValueSubClass>::getSymTab(0);
for (; p2 != p3; ++p2)
;
}
template <>
struct ilist_traits<BasicBlock> : SymbolTableListTraits<BasicBlock, Function> {
static int *getSymTab(Function *);
};
class Function : BasicBlock {
public:
C<llvm::BasicBlock> &getBasicBlockList();
};
}
using namespace llvm;
BasicBlock c;
void BasicBlock::moveBefore() {
c.getParent()->getBasicBlockList().splice();
c.getParent()->getBasicBlockList().splice();
}
markus@x4 llvm_build % cat Function.ii
struct A {};
namespace llvm {
template <typename> struct ilist_traits;
class Function;
struct B {};
template <typename> class ilist_iterator : A {};
template <typename ValueSubClass, typename> class SymbolTableListTraits : B {
void transferNodesFromList(ilist_traits<ValueSubClass> &p1,
ilist_iterator<ValueSubClass>,
ilist_iterator<ValueSubClass>);
};
class BasicBlock;
template <typename ValueSubClass, typename ItemParentClass>
void
SymbolTableListTraits<ValueSubClass, ItemParentClass>::transferNodesFromList(
ilist_traits<ValueSubClass> &p1, ilist_iterator<ValueSubClass>,
ilist_iterator<ValueSubClass>) {}
}
using namespace llvm;
template class ::SymbolTableListTraits<BasicBlock, Function>;
markus@x4 llvm_build % g++ -flto -O3 -fPIC -shared BasicBlock.ii Function.ii
markus@x4 llvm_build % nm ./a.out | c++filt | grep ::transferNodesFromList
markus@x4 llvm_build % g++ -flto -O2 -fPIC -shared BasicBlock.ii Function.ii
markus@x4 llvm_build % nm ./a.out | c++filt | grep ::transferNodesFromList
00000000000009e0 t llvm::SymbolTableListTraits<llvm::BasicBlock,
llvm::Function>::transferNodesFromList(llvm::ilist_traits<llvm::BasicBlock>&,
llvm::ilist_iterator<llvm::BasicBlock>, llvm::ilist_iterator<llvm::BasicBlock>)
markus@x4 llvm_build % g++ -O3 -fPIC -shared BasicBlock.ii Function.ii
markus@x4 llvm_build % nm ./a.out | c++filt | grep ::transferNodesFromList
0000000000000b50 W llvm::SymbolTableListTraits<llvm::BasicBlock,
llvm::Function>::transferNodesFromList(llvm::ilist_traits<llvm::BasicBlock>&,
llvm::ilist_iterator<llvm::BasicBlock>, llvm::ilist_iterator<llvm::BasicBlock>)
markus@x4 llvm_build % clang++ -flto -O3 -w -fPIC -shared BasicBlock.ii
Function.ii
markus@x4 llvm_build % nm ./a.out | c++filt | grep ::transferNodesFromList
0000000000000b70 W llvm::SymbolTableListTraits<llvm::BasicBlock,
llvm::Function>::transferNodesFromList(llvm::ilist_traits<llvm::BasicBlock>&,
llvm::ilist_iterator<llvm::BasicBlock>, llvm::ilist_iterator<llvm::BasicBlock>)
markus@x4 llvm_build %