[cfe-dev] The confusing types resulting from compiling STL list

Xiaolong Tang xiaolong.snake at gmail.com
Wed Jul 28 02:10:54 PDT 2010


Hello, 

> 
> Given a program using the STL list, Clang emits the following type
> information:
> 
>   %"class.__gnu_cxx::new_allocator" = type { i8 }
>   %"class.std::_List_base" = type { %"struct.std::_List_base<int, std::allocator<int> >::_List_impl" }
>   %"class.std::allocator" = type { i8 }
>   %"class.std::list" = type { [16 x i8] }
>   %"struct.std::_List_base<int, std::allocator<int> >::_List_impl" = type { %"struct.std::_List_node_base" }
>   %"struct.std::_List_const_iterator" = type { %"struct.std::_List_node_base"* }
>   %"struct.std::_List_iterator" = type { %"struct.std::_List_node_base"* }
>   %"struct.std::_List_node" = type { [16 x i8], i32, [4 x i8] }
>   %"struct.std::_List_node_base" = type { %"struct.std::_List_node_base"*, %"struct.std::_List_node_base"* }
>   %"struct.std::__false_type" = type { i8 }
> 
> Amongst the types, %"struct.std::_List_node" and %"class.std::list"
> are not nature to me. My questions are:
>   - Why do the two types have no corresponding type arguments? And
>     roughly how are they computed?
>   - Is this unique to Clang? Can I have control on how Clang handles
>     these types? E.g. something like this:
> 
>   %"struct.std::list<int,std::allocator<int> >" = type { %"struct.std::_List_base<int,std::allocator<int> >" }
>   %"struct.std::_List_node<int>" = type { %"struct.std::_List_node_base", i32 }


In addition to the above description on the type information in LLVM
output, I further checked the cases when the STL list is instantiated
with different types. For example, in a program I instantiated the
List class with int and a Student class. This time the type
information in the LLVM output is as below:

  %0 = type { [16 x i8], i32, [4 x i8] }
  %"class.__gnu_cxx::new_allocator" = type { i8 }
  %"class.std::_List_base" = type { %"struct.std::_List_base<int, std::allocator<int> >::_List_impl" }
  %"class.std::allocator" = type { i8 }
  %"class.std::list" = type { [16 x i8] }
  %"struct.std::_List_base<int, std::allocator<int> >::_List_impl" = type { %"struct.std::_List_node_base" }
  %"struct.std::_List_base<student, std::allocator<student> >::_List_impl" = type { %"struct.std::_List_node_base" }
  %"struct.std::_List_const_iterator" = type { %"struct.std::_List_node_base"* }
  %"struct.std::_List_iterator" = type { %"struct.std::_List_node_base"* }
  %"struct.std::_List_node" = type { [16 x i8], %struct.student }
  %"struct.std::_List_node_base" = type { %"struct.std::_List_node_base"*, %"struct.std::_List_node_base"* }
  %"struct.std::__false_type" = type { i8 }
  %struct.student = type { i32, i32, i32, i32 }

As we see, there is only one entry starting with
%"class.std::list". This indicates that the list class does not
distinguish between various type arguments. In this example, we
instantiate the List class with two distinct types, however, there is
only one instance. Another surprise to me is the type
%"struct.std::_List_node". Similarly, the _list_node class does not
distinguish between various type arguments. 

So, I am wondering why the type information is so? Such type
information makes it hard to figure out the type hierarchies in some
cases.

Best, 
Xiaolong



More information about the cfe-dev mailing list