Instantiator
Generate c++ template instantiations
Loading...
Searching...
No Matches
Injection.cpp
Go to the documentation of this file.
1#include "Injection.hpp"
2
3#include <ostream>
4#include <sstream>
5
6#include "spdlog/spdlog.h"
7
8#include "clang/AST/Decl.h"
9#include "clang/AST/DeclCXX.h"
10#include "clang/AST/DeclTemplate.h"
11#include "clang/AST/TemplateName.h"
12
13#include "Parsing.hpp"
14
15bool Injection::match(const Injection& other) const
16{
17 if(is_constructor != other.is_constructor) { return false; }
18 if(not(is_constructor) and func_name != other.func_name) { return false; }
19 if(nested_namespace != other.nested_namespace) { return false; }
20 if(params.size() != other.params.size()) { return false; }
21 if(class_name != other.class_name) { return false; }
22 if(is_const != other.is_const) { return false; }
23 if(func_Ttypes != other.func_Ttypes) { return false; }
24 if(class_Targs != other.class_Targs) { return false; }
25 if(params != other.params) { return false; }
26
27 return true;
28}
29
30Injection Injection::createFromFS(const clang::FunctionDecl* FS, clang::PrintingPolicy pp)
31{
32 spdlog::debug("Create Injection from function {}.", FS->getNameAsString());
33 Injection toDo;
34 toDo.is_member = false;
35 toDo.is_constructor = false;
36 toDo.func_name = FS->getNameAsString();
37 toDo.return_type = FS->getReturnType().getAsString(pp);
38 llvm::raw_string_ostream OS(toDo.nested_namespace);
39 FS->printNestedNameSpecifier(OS, pp);
40 OS.str();
41 toDo.func_Ttypes = internal::parseTemplateArgs(FS->getTemplateSpecializationArgs(), pp);
42 std::vector<clang::ParmVarDecl*> parms(FS->parameters().begin(), FS->parameters().end());
43 toDo.params = internal::parseFunctionArgs(parms, pp);
44 if(const clang::FunctionTemplateSpecializationInfo* TSI = FS->getTemplateSpecializationInfo()) {
45 std::vector<clang::ParmVarDecl*> nonresolved_parms(TSI->getTemplate()->getTemplatedDecl()->parameters().begin(),
46 TSI->getTemplate()->getTemplatedDecl()->parameters().end());
47 toDo.nonresolved_params = internal::parseFunctionArgs(nonresolved_parms, pp);
48 }
49 return toDo;
50}
51
52Injection Injection::createFromMFS(const clang::CXXMethodDecl* MFS, clang::PrintingPolicy pp)
53{
54 spdlog::debug("Create Injection from member function {}.", MFS->getNameAsString());
55 Injection toDo = createFromFS(MFS, pp);
56 toDo.is_member = true;
57 const clang::CXXConstructorDecl* ConstructorCheck = llvm::dyn_cast<clang::CXXConstructorDecl>(MFS);
58 toDo.is_constructor = not(ConstructorCheck == nullptr);
59 toDo.is_const = MFS->isConst();
60 toDo.nested_namespace = "";
61 llvm::raw_string_ostream OS(toDo.nested_namespace);
62 MFS->getParent()->printNestedNameSpecifier(OS, pp);
63 OS.str();
64
65 toDo.class_name = MFS->getParent()->getNameAsString();
66 if(const clang::ClassTemplateSpecializationDecl* CTS = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(MFS->getParent())) {
67 auto targs = &CTS->getTemplateArgs();
68 toDo.class_Targs.reserve(targs->size());
69 for(std::size_t i = 0; i < targs->size(); ++i) {
71 }
72 }
73
74 if(const clang::FunctionTemplateSpecializationInfo* TSI = MFS->getTemplateSpecializationInfo()) {
75 auto* node = TSI->getTemplate()->getTemplatedDecl();
76 if(auto* DFT = node->getDescribedFunctionTemplate()) {
77 if(auto* MT = DFT->getInstantiatedFromMemberTemplate()) {
78 if(auto* TMFS = MT->getTemplatedDecl()) {
79 std::vector<clang::ParmVarDecl*> nonresolved_parms(TMFS->parameters().begin(), TMFS->parameters().end());
80 toDo.nonresolved_params = internal::parseFunctionArgs(nonresolved_parms, pp);
81 }
82 }
83 }
84 } else {
85 if(const clang::MemberSpecializationInfo* MSI = MFS->getMemberSpecializationInfo()) {
86 if(const clang::CXXMethodDecl* TMFS = llvm::dyn_cast<const clang::CXXMethodDecl>(MSI->getInstantiatedFrom())) {
87 std::vector<clang::ParmVarDecl*> nonresolved_parms(TMFS->parameters().begin(), TMFS->parameters().end());
88 toDo.nonresolved_params = internal::parseFunctionArgs(nonresolved_parms, pp);
89 }
90 }
91 }
92 return toDo;
93}
94
95std::string Injection::getInstantiation() const
96{
97 std::stringstream res;
98 res << "\ntemplate ";
99 if(not is_constructor) { res << return_type << " "; }
100 res << nested_namespace;
101 if(is_member) {
102 res << class_name;
103 if(class_Targs.size() > 0) {
104 res << "<";
105 for(std::size_t i = 0; i < class_Targs.size(); i++) {
106 if(i + 1 < class_Targs.size()) {
107 res << class_Targs[i].name(",") << ",";
108 } else {
109 res << class_Targs[i].name(",") << ">";
110 }
111 }
112 }
113 res << "::";
114 }
115 res << func_name;
116 if(func_Ttypes.size() > 0) {
117 res << "<";
118 for(std::size_t i = 0; i < func_Ttypes.size(); i++) {
119 if(i + 1 < func_Ttypes.size()) {
120 res << func_Ttypes[i] << ",";
121 } else {
122 res << func_Ttypes[i] << ">";
123 }
124 }
125 }
126 res << "(";
127 for(std::size_t i = 0; i < params.size(); i++) {
128 if(i + 1 < params.size()) {
129 res << params[i].name << ",";
130 } else {
131 res << params[i].name;
132 }
133 }
134 res << ")";
135 if(is_member) {
136 if(is_const) { res << " const"; }
137 }
138 res << ";";
139 return res.str();
140}
Helper functions for parsing information from AST nodes.
std::vector< std::string > parseTemplateArgs(const clang::TemplateArgumentList *TAL, clang::PrintingPolicy pp)
Definition Parsing.cpp:9
std::vector< Param > parseFunctionArgs(std::vector< clang::ParmVarDecl * > Args, clang::PrintingPolicy pp)
Definition Parsing.cpp:69
Struct for the collection of all relevant data for a template instantiation which needs to be inserte...
Definition Injection.hpp:21
static Injection createFromFS(const clang::FunctionDecl *FS, clang::PrintingPolicy pp)
Definition Injection.cpp:30
bool match(const Injection &other) const
Definition Injection.cpp:15
std::string getInstantiation() const
Definition Injection.cpp:95
StringType nested_namespace
Definition Injection.hpp:34
std::vector< std::string > func_Ttypes
Definition Injection.hpp:51
static Injection createFromMFS(const clang::CXXMethodDecl *MFS, clang::PrintingPolicy pp)
Definition Injection.cpp:52
StringType func_name
Definition Injection.hpp:27
std::string return_type
Definition Injection.hpp:45
StringType class_name
Definition Injection.hpp:40
bool is_const
Definition Injection.hpp:73
std::vector< Instantiator::TemplateArgument > class_Targs
Definition Injection.hpp:57
bool is_constructor
Definition Injection.hpp:82
std::vector< Param > nonresolved_params
Definition Injection.hpp:70
bool is_member
Definition Injection.hpp:76
std::vector< Param > params
Definition Injection.hpp:63
static TemplateArgument createFromTemplateArgument(const clang::TemplateArgument *parm, clang::PrintingPolicy pp)