I have a large program that's generating object files that are much larger than I expect. My suspicion is that somewhere in the program, someone is using inefficient template metaprogramming that's generating O(n**2) template types. Is there a command-line tool that I can use to list all of the template types that exist in an object file (.o)?
Normally I would suspect nm or objdump is the right tool for this kind of thing, but it's not obvious to me what flags to pass to list the template types.
I've verified that the information is in the .o file using this simple test program:
template <typename T, typename... Ts>
struct foo : public foo<Ts...> {};
template <>
struct foo<int> {};
void bar() {
foo<int, int, int, int, int, int, int, int> x;
}
Then running:
gcc -g -c test.cc -o test.o && strings test.o
Outputs:
foo<int, int, int, int, int, int, int, int>
GNU C++17 13.2.0 -mtune=generic -march=x86-64 -g -fasynchronous-unwind-tables
_Z3barv
foo<int, int, int, int, int, int, int>
foo<int, int, int, int>
foo<int, int, int, int, int, int>
foo<int, int, int>
foo<int>
foo<int, int>
foo<int, int, int, int, int>
/tmp
test.cc
/tmp
test.cc
test.cc
GCC: (Debian 13.2.0-10) 13.2.0
test.cc
_Z3barv
.symtab
.strtab
.shstrtab
.text
.data
.bss
.rela.debug_info
.debug_abbrev
.rela.debug_aranges
.rela.debug_line
.debug_str
.debug_line_str
.comment
.note.GNU-stack
.rela.eh_frame
I'm looking for a command that will output foo<int>, foo<int, int>, etc. from test.o.
In my previous, now deleted, answer I kicked off with:
To which you commented:
Which is so. I should have chosen my words more carefully. Classes have no linkage representation. But that's quite immaterial if you can readily make an object file containing the strings your're looking for. The strings you are seeing are DWARF debugging info, which GCC by default packages into the object the file (or optionally with a separate
.dwofile). I didn't consider getting the debug info, but indeed it is - or it contains - the information you want.Naturally you can get at the debug info in a straightforwardly structured format unpolluted with whatever other strings the object file might contain. If I compile my previous
example.cpplike so:then the compiler is instructed (GCC manual: 3.10 Options for Debugging Your Program):
Then, the
.debug_pubtypessection will itemise every type that is used in the object file, and they can be specifically extracted with:This appears to be exactly what you need, and I am wiser than I was :)