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 %

Reply via email to