On Fri, 2 Aug 2019 at 15:05, Romulo via cfe-users <cfe-users@lists.llvm.org> wrote:
> Hello there, thanks for your time reading this :) > > I am trying to extract the code for a specialized template function, but I > have no idea on how to proceed. I know I can use SourceManager to get the > original 'pure template' code but I don't know how to access the > specialized functions (the SourceLocation for them points to the original > function in the AST). My idea is to allow users to write some sugar code > like: > > template <typename T> > T myAdd(T x, T y) { > return x + y; > } > > myAdd< double >(5.5, 3.3); > or > myAdd(1, 2); > > and after parsing their source files, generate the specialized functions > with a different name in a separated utility file, replacing the > occurrences of of use (that's the easy part). > The utility file would look like: > > double _impl_double_myAdd(double x, double y) { > return x + y; > } > > int _impl_int_myAdd(int x, int y) { > return x + y; > } > > and the calls: > > _impl_double_myAdd(5.5, 3.3); > and > _impl_int_myAdd(1, 2); > > Can anyone point me in the right direction? I though about just replacing > the usage cases of 'T' but that seems really manual and error prone. > You can call clang::Decl::print <https://clang.llvm.org/doxygen/classclang_1_1Decl.html#a5bac5131c3f19c2f460c1437eedb051c> on the template specialization declaration to see what it looks like after substitution. We don't guarantee that the output will be valid C++ code in all cases (and in fact, there are some constructs that can be produced by template instantiation and cannot be written directly in C++, but they're generally very rare), but it usually will be. If you want a sample of what that looks like, try compiling your code with "-Xclang -ast-print -S -o -" For your original example (with the calls to myAdd moved to a function f()), I get this with clang trunk: template <typename T> T myAdd(T x, T y) { return x + y; } template<> double myAdd<double>(double x, double y) { return x + y; } template<> int myAdd<int>(int x, int y) { return x + y; } void f() { myAdd<double>(5.5, 3.2999999999999998); myAdd(1, 2); } Example case where the output is not valid C++: template <typename T> void destroy(T &t) { t.~T(); } void f(int n) { destroy(n); } ... produces ... template <typename T> void destroy(T &t) { t.~T(); } template<> void destroy<int>(int &t) { t.~int(); // this won't parse } void f(int n) { destroy(n); }
_______________________________________________ cfe-users mailing list cfe-users@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users