<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title></title>
</head>
<body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; color: rgb(0, 0, 0); font-size: 14px; font-family: Calibri, sans-serif;">
<div style="font-family: 'Helvetica Neue';">Hi,</div>
<div style="font-family: 'Helvetica Neue';"><br>
</div>
<div style="font-family: 'Helvetica Neue';">I’d like to trigger explicit template instantiations from within clang plugin/tool, how could I achieve it?</div>
<div style="font-family: 'Helvetica Neue';">Algorithm I’m looking to implement looks like this:</div>
<div style="font-family: 'Helvetica Neue';">Input: AST + pairs of (X, X_model) template classes. X_model will be instantiable with same template arguments as X</div>
<div style="font-family: 'Helvetica Neue';">Condition: There is instantiation of class X<T> in the AST (where T is concrete type)</div>
<div style="font-family: 'Helvetica Neue';">Result: Additional explicit instantiation of X_model<T> is added to AST</div>
<div style="font-family: 'Helvetica Neue';"><br>
</div>
<div style="font-family: 'Helvetica Neue';">I’ve looked around clang codebase, but I see no obvious way to do that. Two approaches I was able to spot:</div>
<ol style="font-family: 'Helvetica Neue';">
<li>Call functions from Sema. Sema::ActOnExplicitInstantiation has code that looks relevant to my problem. It seems to be deep into clang internals though (and I never used Sema inside plugin/tool before)</li><li>clang static analyzer already has a concept of .model files that produce extra AST for functions defined outside of TranslationUnit: <a href="https://github.com/llvm-mirror/clang/commit/fdf0d3513240fd8e4da6942e9cd26d2d730eb37b">https://github.com/llvm-mirror/clang/commit/fdf0d3513240fd8e4da6942e9cd26d2d730eb37b</a></li></ol>
<div style="font-family: 'Helvetica Neue';"><br>
</div>
<div style="font-family: 'Helvetica Neue';">Context:</div>
<div style="font-family: 'Helvetica Neue';">I’m working on static analysis tool called infer and we have clang plugin that exports AST (in json-like format) which then is read by our frontend. We rely on clang to do template instantiations for us and it’s been
 working great so far.</div>
<div style="font-family: 'Helvetica Neue';">However, in order for our tool to better understand standard library, we write simplified versions (we call them models) of some functions.</div>
<div style="font-family: 'Helvetica Neue';">In C it means writing code for memcpy etc and then ‘linking’ this code with the rest of the program [1]</div>
<div style="font-family: 'Helvetica Neue';">In C++ it means that we want to write simplified versions of std::shared_ptr, std::unique_ptr, std::vector etc. The challenge here is that we need clang to instantiate simplified code with concrete types [2]</div>
<div style="font-family: 'Helvetica Neue';">Current solution involves writing our own version of std::vector header which compiles with the rest of stdlibc++ and libc++. Then, we replace standard header with our header and run compilation. This approach is
 hard to write and maintain in the long run - we have dense templated code which has nothing to do with our models, but required for compilation to succeed. Most importantly, maintaining compatibility with future versions of stdlibc++ and libc++ is non trivial.</div>
<div style="font-family: 'Helvetica Neue';">The solution I’m exploring now is the following:</div>
<ol style="font-family: 'Helvetica Neue';">
<li>Every time we see std::vector instantiation, instantiate infer_std::vector with same arguments.</li><li>Export AST with instantiations of infer_std::vector</li><li>In infer’s frontend do some matching of fields/methods between std::vector and infer_std::vector and then use infer_std::vector instead of std::vector. In case of failure (such as no right method in infer_std::vector class), carry on instead of failing.<br>
</li></ol>
<div style="font-family: 'Helvetica Neue';"><br>
</div>
<div style="font-family: 'Helvetica Neue';">[1] This is how memcpy model look like - it’s fairly easy to understand actual logic:</div>
<div style="font-family: 'Helvetica Neue';"><a href="https://github.com/facebook/infer/blob/master/infer/models/c/src/libc_basic.c#L393">https://github.com/facebook/infer/blob/master/infer/models/c/src/libc_basic.c#L393</a></div>
<div style="font-family: 'Helvetica Neue';"><br>
</div>
<div style="font-family: 'Helvetica Neue';">[2] Currently our vector model looks like this – right now we need to get everything right for compilation to succeed. </div>
<div style="font-family: 'Helvetica Neue';"><a href="https://github.com/facebook/infer/blob/master/infer/models/cpp/include/infer_model/vector.h">https://github.com/facebook/infer/blob/master/infer/models/cpp/include/infer_model/vector.h</a></div>
</body>
</html>