Instantiator
Generate c++ template instantiations
Loading...
Searching...
No Matches
Template.cpp
Go to the documentation of this file.
1#include "Template.hpp"
2
3#include <cstddef>
4#include <llvm/Support/Casting.h>
5
6#include "spdlog/spdlog.h"
7
8#include "clang/AST/DeclTemplate.h"
9
10#include "Injection.hpp"
11#include "Parsing.hpp"
12#include "TemplateArgument.hpp"
13
14namespace clang {
15class ParmVarDecl;
16}
17
18Template Template::createFromFS(const clang::FunctionDecl* FS, clang::PrintingPolicy pp)
19{
20 Template candidate;
21 candidate.is_member = false;
22 candidate.is_constructor = false;
23 candidate.func_name = FS->getNameAsString();
24 llvm::raw_string_ostream OS(candidate.nested_namespace);
25 FS->printNestedNameSpecifier(OS, pp);
26 OS.str();
27 std::vector<clang::ParmVarDecl*> parms(FS->parameters().begin(), FS->parameters().end());
28 spdlog::debug("Loaded candidate (wo params): {} with #{} parameters.", candidate, parms.size());
29 candidate.params = internal::parseFunctionArgs(parms, pp);
30 return candidate;
31}
32
33Template Template::createFromMFS(const clang::CXXMethodDecl* MFS, clang::PrintingPolicy pp)
34{
35 Template candidate = Template::createFromFS(MFS, pp);
36 candidate.is_member = true;
37 const clang::CXXConstructorDecl* ConstructorCheck = llvm::dyn_cast<clang::CXXConstructorDecl>(MFS);
38 candidate.is_constructor = not(ConstructorCheck == nullptr);
39 candidate.is_const = MFS->isConst();
40 candidate.nested_namespace = "";
41 llvm::raw_string_ostream OS(candidate.nested_namespace);
42 MFS->getParent()->printNestedNameSpecifier(OS, pp);
43 OS.str();
44 candidate.class_name = MFS->getParent()->getNameAsString();
45 if(const auto CTPS = llvm::dyn_cast<clang::ClassTemplatePartialSpecializationDecl>(MFS->getParent())) {
46 auto targs = &CTPS->getTemplateArgs();
47 candidate.class_Targs.reserve(targs->size());
48 for(std::size_t i = 0; i < targs->size(); ++i) {
49 candidate.class_Targs.push_back(Instantiator::TemplateArgument::createFromTemplateArgument(&targs->get(i), pp));
50 }
51 } else if(auto CTD = MFS->getParent()->getDescribedClassTemplate()) {
52 auto ttypes = CTD->getTemplateParameters();
53 candidate.class_Targs.resize(ttypes->size());
54 for(std::size_t i = 0; i < ttypes->size(); ++i) {
55 candidate.class_Targs[i].is_dependent = true;
56 candidate.class_Targs[i].names[0] = "";
57 if(auto ttype_decl = llvm::dyn_cast<clang::TemplateTypeParmDecl>(ttypes->getParam(i))) {
58 if(ttype_decl->isParameterPack()) {
59 candidate.class_Targs[i].kind = Instantiator::Kind::Pack;
60 continue;
61 }
62 candidate.class_Targs[i].kind = Instantiator::Kind::Type;
63 } else if(auto tnontype_decl = llvm::dyn_cast<clang::NonTypeTemplateParmDecl>(ttypes->getParam(i))) {
64 if(tnontype_decl->isParameterPack()) {
65 candidate.class_Targs[i].kind = Instantiator::Kind::Pack;
66 continue;
67 }
68 candidate.class_Targs[i].kind = Instantiator::Kind::NonType;
69 } else if(auto ttemplate_decl = llvm::dyn_cast<clang::TemplateTemplateParmDecl>(ttypes->getParam(i))) {
70 if(ttemplate_decl->isParameterPack()) {
71 candidate.class_Targs[i].kind = Instantiator::Kind::Pack;
72 continue;
73 }
74 candidate.class_Targs[i].kind = Instantiator::Kind::Template;
75 }
76 }
77 }
78
79 return candidate;
80}
81
82bool Template::isTemplateFor(const Injection& toDo) const
83{
84 spdlog::debug("Calling isTemplateFor between\n\t{}\n\t{}", *this, toDo);
85 if(is_constructor != toDo.is_constructor) { return false; }
86 if(not(is_constructor) and func_name != toDo.func_name) { return false; }
87 if(nested_namespace != toDo.nested_namespace) { return false; }
88 if(params.size() != toDo.nonresolved_params.size()) { return false; }
89 if(class_name != toDo.class_name) { return false; }
90 if(is_const != toDo.is_const) { return false; }
91 if(params != toDo.nonresolved_params) { return false; }
92 if(class_Targs != toDo.class_Targs) { return false; }
93 return true;
94}
Helper functions for parsing information from AST nodes.
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
StringType nested_namespace
Definition Injection.hpp:34
StringType func_name
Definition Injection.hpp:27
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
static TemplateArgument createFromTemplateArgument(const clang::TemplateArgument *parm, clang::PrintingPolicy pp)
Struct for the collection of all relevant data for a template function which can provide a definition...
Definition Template.hpp:18
bool is_constructor
Definition Template.hpp:65
bool is_member
Definition Template.hpp:59
bool isTemplateFor(const Injection &candidate) const
Definition Template.cpp:82
StringType nested_namespace
Definition Template.hpp:31
StringType func_name
Definition Template.hpp:24
StringType class_name
Definition Template.hpp:37
static Template createFromFS(const clang::FunctionDecl *FS, clang::PrintingPolicy pp)
Definition Template.cpp:18
bool is_const
Definition Template.hpp:56
std::vector< Param > params
Definition Template.hpp:45
static Template createFromMFS(const clang::CXXMethodDecl *MFS, clang::PrintingPolicy pp)
Definition Template.cpp:33
std::vector< Instantiator::TemplateArgument > class_Targs
Definition Template.hpp:53