<div dir="ltr">Hi all,<div><br></div><div>I recently picked up the Templight code (see <a href="http://plc.inf.elte.hu/templight/">http://plc.inf.elte.hu/templight/</a>) because I love the idea of having proper debugging and profiling tools for template meta-programming in C++. As admitted by the original authors (Zoltán Borók-Nagy, Zoltán Porkoláb and József Mihalicza), the code was rather crude, but a great first step. </div>
<div><br></div><div>-- Templight "version 2" -- (patch: templight_v2_clang35.diff)</div><div><br></div><div>So, I refactored the code to make it a bit more modular and less intrusive on the Sema class. Here is an outline of the main changes included in the attached patch (from Clang r202671):</div>
<div><br></div><div>Changes to existing Clang code-base:</div><div><br></div><div> (1) Moved the "ActiveTemplateInstantiation" class out of the Sema class scope, and into the clang namespace-scope. This was done to make the templight code independent from the Sema class by allowing a forward-declaration of ActiveTemplateInstantiation (can't be done if it is nested in Sema).</div>
<div><span class=""><br></span></div><div> (2) Minor updates to reflect the above change in scope of the ActiveTemplateInstantiation class.</div><div><br></div><div> (3) Created a "TemplateInstantiationObserver" base-class which bundles callback functions that are called during the template instantiations (and when leaving them). This class also supports linked-list-style chaining of additional observers.</div>
<div><br></div><div> (4) Added a OwningPtr<TemplateInstantiationObserver> in the Sema class to hold the chain of template instantiation observers.</div><div><br></div><div> (5) Added callbacks for begin / end of template instantiations. These were added in all the places where the original Templight code had templight calls. This replaces the original templight tracing calls.</div>
<div><br></div><div> (6) Added calls to initialize and finalize the template instantiation observers in the ParseAST code (see issues below).</div><div><br></div><div> (7) Added front-end options for Templight (mostly the same as in the original templight patch).</div>
<div><span class=""><br></span></div><div>Changes to the Templight implementation: (unless noted here, the behavior is the same)</div><div>N.B.: The output (yaml, xml, txt) is *identical* to the original Templight code.</div>
<div><br></div><div> (8) All the templight code was moved out of the Sema class and into its own cpp-file. This was done mainly to avoid additional pollution in the Sema class, and to isolate the templight code's implementation dependencies (llvm support libs, yaml output code, etc.).</div>
<div><span class=""><br></span></div><div> (9) Created the TemplightTracer class (derived from TemplateInstantiationObserver) to expose the functionality of Templight. This class is PImpl'd.</div><div><span class=""><br>
</span></div><div> (10) Removed the "TemplightFlag" in favor of having created the tracer or not.</div><div><br></div><div> (11) Removed the "-templight-capacity" option because I changed the non-safe-mode to record the instantiation traces up to when the instantiations come back to the top-level context, at which point, I dump the traces. This will not affect the profiling because at the top-level context there is no pending timing or memory to be recorded. With this change, the number of traces recorded become proportional to the maximum instantiation depth (which is limited by the compiler), therefore making the templight-capacity redundant.</div>
<div><span class=""><br></span></div><div> (12) Changed the recording of the traces to be stored in a std::vector, as opposed to a bare dynamic array.</div><div><span class=""><br></span></div><div> (13) Added the "-templight-ignore-system" option to ignore (not traced) any template instantiation coming from a system-include header file.</div>
<div><br></div><div> (14) Updated the "creation" code where front-end options are pulled and used to create the tracer.</div><div><br></div><div><br class="">-- Templight GDB-style Debugger -- (patch: templight_v2_clang35_with_debugger.diff)<br>
</div><div><span class=""><br></span></div><div>Here is the really sweet part. When I realized how easy it would be to create a gdb-style debugger with the new layout that I described above, I just had to give it a go, and the result is pretty nice, albeit still crude. I welcome you to try it!</div>
<div><span class=""><br></span></div><div>I added the option "-templight-debugger" which turns on an interactive debugging session during the template instantiations. This is implemented in the TemplightDebugger class (also PImpl'd, and also deriving from TemplateInstantiationObserver). The debugger respects the relevant <span class="" style="background-color:rgb(255,255,255);font-size:small;line-height:normal">templight</span> options (memory and ignore-system) and can be used in parallel with the templight tracer (although timing values will obviously be useless).</div>
<div><span class=""><br></span></div><div>The debugger implements most of the basic gdb commands and reproduces its behavior as much as possible. You can set breakpoints (by complete name of template instantiation), you can "step", "next", "run", "kill", etc.. with the same behavior as gdb. You can print back-traces. And each time a template instantiation is entered or left, there is a structured print out similar to gdb, making it usable (I hope) in a GUI front-end similar to the various GUI front-ends to gdb.</div>
<div><span class=""><br></span></div><div>This is really just a first draft of it, it's quite crude. I use C-style functions for the console input to avoid pulling in the C++ iostream monster (as required in coding standards of LLVM). And, as usual with interactive programs, it's hard to make sure that it is robust to people entering random nonsense.</div>
<div><span class=""><br></span></div><div>Here are a few issues I'd like some feedback on:</div><div><br></div><div> (15) I feel that the XML output of the templight tracer could easily be nested, as opposed to having matched "Begin" and "End" blocks. </div>
<div><br></div><div> (16) I feel a bit uneasy about the place where the tracer / debugger get created, initialized and finalized. Currently, this is done in the "createSema" function and in the ParseAST code. It works this way, but it feels out-of-place. I don't know the Clang code-base well enough (in fact, barely at all) to know where this should go. Ideally, I would also like to get rid of the initialize / finalize functions in the TemplateInstantiationObserver class, but that is impossible as long as the Sema object and most of Clang's main structures are left to leak (always-on "-delete-free" option), as RAII is no longer available as a mechanism for handling the clean up. If anyone that understands Clang's main structures could weight in on this, I'd be glad to hear suggestions.</div>
<div><span class=""><br></span></div><div> (17) Is there anything in LLVM/Clang that can help in terms of doing console input? Currently, I use <cstdio> functions and hand-written "tokenizing".</div><div><br>
</div><div> (18) I feel like the template debugger should be a separate entity (not an option to the main clang compiler), but at the same time, it needs the entire compilation process to be running, and so, if separate, it would have to be duplicate of clang with only small additions (in terms of code).</div>
<div><br></div><div> (19) Finally, I'd like to have ideas about what kind of diagnostic information that could be added to the debugger. Currently, it only prints out the name of the template instantiation, the location, and total memory usage. It would be nice to have features similar to GDB's "print" commands, like being able to print the list of template arguments and their values within the current context, and things like that. I simply don't have enough knowledge of Clang's code to know how to tap into that kind of information.</div>
<div><br></div><div><br></div><div>I know this was a long email, but I hope you had the interest to read up to here, and I hope to hear back.</div><div><br></div><div>Cheers,</div><div>Mikael.</div><div><br></div><div><br>
</div><div>-- <br>Sven Mikael Persson, M.Sc.(Tech.)<br>PhD Candidate, McGill University,<br>
</div></div>