Instantiator
Generate c++ template instantiations
Loading...
Searching...
No Matches
TemplateArgument.cpp
Go to the documentation of this file.
2
3#include <clang/AST/APValue.h>
4#include <clang/AST/DeclCXX.h>
5#include <clang/AST/Expr.h>
6#include <clang/AST/TemplateBase.h>
7#include <cstddef>
8
9#include "spdlog/spdlog.h"
10
11#include "clang/AST/TemplateName.h"
12#include "llvm/ADT/SmallString.h"
13
14namespace Instantiator {
15
16std::string TemplateArgument::name(const std::string& sep) const
17{
18 std::string out = {};
19 for(std::size_t i = 0; i < names.size(); ++i) {
20 if(i < names.size() - 1) {
21 out += names[i] + sep;
22 } else {
23 out += names[i];
24 }
25 }
26 return out;
27}
28
29TemplateArgument TemplateArgument::createFromTemplateArgument(const clang::TemplateArgument* parm, const clang::PrintingPolicy pp)
30{
32
33 out.is_dependent = parm->isDependent();
34
35 switch(parm->getKind()) {
36 case clang::TemplateArgument::ArgKind::Type: {
37 out.names[0] = parm->getAsType().getAsString(pp);
39 spdlog::debug("type: {}", out.names[0]);
40 break;
41 }
42 case clang::TemplateArgument::ArgKind::Integral: {
43 llvm::SmallString<10> tmp_name;
44 parm->getAsIntegral().toString(tmp_name);
45 out.names[0] = tmp_name.str().str();
47 spdlog::debug("integral: {}", out.names[0]);
48 break;
49 }
50 case clang::TemplateArgument::ArgKind::Pack: {
51 out.names.resize(parm->pack_size());
52 for(auto pack_it = parm->pack_begin(); pack_it != parm->pack_end(); pack_it++) {
53 switch(pack_it->getKind()) {
54 case clang::TemplateArgument::ArgKind::Type: {
55 out.names[std::distance(parm->pack_begin(), pack_it)] = pack_it->getAsType().getAsString(pp);
56 break;
57 }
58 case clang::TemplateArgument::ArgKind::Integral: {
59 llvm::SmallString<10> name;
60 pack_it->getAsIntegral().toString(name);
61 out.names[std::distance(parm->pack_begin(), pack_it)] = name.str().str();
62 break;
63 }
64 default: {
65 break;
66 }
67 }
68 }
70 break;
71 }
72 case clang::TemplateArgument::ArgKind::Template: {
73 llvm::raw_string_ostream OS(out.names[0]);
74#if INSTANTIATOR_LLVM_MAJOR > 13
75 parm->getAsTemplate().print(OS, pp, clang::TemplateName::Qualified::AsWritten);
76#else
77 parm->getAsTemplate().print(OS, pp, false);
78#endif
79 OS.str();
81 break;
82 }
83#if INSTANTIATOR_LLVM_MAJOR > 17
84 case clang::TemplateArgument::ArgKind::StructuralValue: {
85 spdlog::critical("NTTP are not implemented correctly. Param={}", parm->getAsStructuralValue().isStruct());
86 break;
87 }
88#endif
89 case clang::TemplateArgument::ArgKind::Expression: {
90 spdlog::critical("Expression TA are not implemented correctly. Param={}", parm->getAsExpr()->getType().getAsString(pp));
91 break;
92 }
93 default: {
94 spdlog::critical("Unhandled clang::TemplateArgument::ArgKind={}, isExpression={}",
95 static_cast<int>(parm->getKind()),
96 parm->getKind() == clang::TemplateArgument::ArgKind::Expression);
97 break;
98 }
99 }
100 return out;
101}
102
104{
105 spdlog::debug("name dependent={}, other.name dependent={}", is_dependent, other.is_dependent);
106 if(is_dependent or other.is_dependent) { return true /*kind == other.kind*/; }
107 spdlog::debug("Compare of {} and {}", name(), other.name());
108 return name() == other.name();
109}
110
111} // namespace Instantiator
Struct for the collection of all relevant data for a function parameter.
std::vector< std::string > names
static TemplateArgument createFromTemplateArgument(const clang::TemplateArgument *parm, clang::PrintingPolicy pp)
std::string name(const std::string &sep=" ") const
bool compare(const TemplateArgument &other) const