[cfe-dev] GCOV instrumentation for non-instantiated code (e.g. template functions)

David Blaikie dblaikie at gmail.com
Sun May 13 12:54:14 PDT 2012

On Sun, May 13, 2012 at 8:06 AM, Holtgrewe, Manuel
<manuel.holtgrewe at fu-berlin.de> wrote:
> Dear all,
> (first of all: Sorry if there is any confusion because I am not using the right C++/compiler lingo, I'm more of a C++ "consumer" than a language lawyer/expert. I'm interested in any hints or corrections so I can learn, though).
> I have done some work on the GCOV instrumentation that allows uninstantiated code (e.g. template functions, in-class defined member methods) to appear in GCOV output.

Just as an aside: is it possible you're conflating "in-class defined
member methods" with "inline functions"? Basically any member function
defined within the class definition is implicitly marked 'inline'. If
there's no call to that function within the current TU, there's no
need to emit that definition (since other TUs will follow this same
rule, since they all have access to the definition & have to rely on
the linker to remove the duplicates anyway).

Knowing this you might be able to generalize your solution to
"templates and inline functions". You /might/ also find that
namespace-scope static (or anonymous namespace) functions don't get
code coverage either - I doubt Clang emits those if there are no calls
to them (though there's a warning for that, since it can be checked at
compile-time - so you probably just want to turn that on).

- David

> I have contacted Nick Lewicky (since he is the author of the GCOV cod ein Clang, so thanks to him!) and he gave my some guidance. Attached is my resulting patch to current trunk of Clang/LLVM. The code contains some debug output right now that needs to be removed before any possible future inclusion.
> I would like to get some feedback on this:
> - Do you think it is useful (I hope I can convince you below ;), i.e. would you consider it for inclusion into Clang/LLVM?
> - Is my approach correct? Can it be improved upon?
> - Are there other large issues to work on?
> - Are there smaller issues to work on?
> Also there are some questions:
> - How can I check whether a member function was defined out-of-class? Currently, incorrect GCNO is generated here.
> - Am I missing functions classes that no code is generated for, and: Is there a better way to look for them?
> - Can you think of a good way to write tests for this or: How can I write tests for this using any existing Clang test system.
> - Can you think of some systematic scheme of functions to generate "dead nodes" for?
> Below is a quick description of my motivation and what the patch contains. The patch itself is attached, together with the output of compiling with -ftest-coverage -fprofile-arcs -o gcov_cases2, running the program and then calling gcov on them. The files ending on g++ are the output when compiling with g++, the files ending with clang++ are the output when compiling with patched clang++.
> There are two example programs, one where the functions are called (gcov_cases.cpp) and one where no function is called (gcov_cases2.cpp).
> Cheers!
> Manuel
> Motivation -- Why is this useful?
> ---------------------------------
> Some C++ functions do not show up in GCOV output since no code is generated for them. Some examples are template functions but also in-class defined member methods. Consider the following small example program:
> template <typename T>
> void f()
> {
>  std::cout << T() << '\n';
> }
> class Klass
> {
> public:
>  Klass()
>  {
>    f();
>  }
> };
> int main() { return 0; }
> Both the template function f and the constructor of Klass will not turn up in the GCNO file (which describe the program to GCOV in a graph structure). This means if you compile the program with coverage instrumentation, run it and then generate the gcov output, f and the constructor will not show up. They are treated like empty or comment lines.
> This has the problem that the gcov output can no longer be considered a good measure for test coverage if you have a lot of template functions, e.g. when writing tests for a template library, say the STL or Boost.
> My Approach
> -----------
> Currently, the GCOV support in is implemented in LLVM: LLVM looks at the generated generated debug meta data and generates the GCNO file with the graph structure. No debug meta data is generated for the uninstantiated code right now and (according to Nick) should not be added because of bloating up the output and DWARF does support debug symbols for uninstantiated code.
> The first part of my patch is to generate meta data "gcov.extralines" that consists of one entry for each line that should be added to the GCOV output. This change is added to clang-trunk/lib/CodeGen/ModuleBuilder.cpp where I traverse the AST and look out for functions that no code is generated for. Currently, I look for function templates definitions that are not fully specialized and unused member function definitions or of uninstantiated C++ template classes. Unused virtual functions will have code emitted for them, as far as I understand.
> This meta data is then interpreted in llvm-trunk/lib/Transforms/Instrumentation/GCOVProfiling.cpp and we emit fake functions in the GNO functions for them.
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev

More information about the cfe-dev mailing list