src/TemplateUtils.cpp (98 lines of code) (raw):

/* SPDX-FileCopyrightText: 2016 Sergio Martins <smartins@kde.org> SPDX-License-Identifier: LGPL-2.0-or-later */ #include "TemplateUtils.h" #include "StringUtils.h" #include <clang/AST/Decl.h> #include <clang/AST/DeclCXX.h> #include <clang/AST/DeclTemplate.h> #include <clang/AST/TemplateBase.h> #include <clang/AST/Type.h> #include <clang/Basic/LLVM.h> #include <llvm/Support/Casting.h> namespace clang { class LangOptions; } // namespace clang using namespace clang; static std::vector<QualType> typesFromTemplateArguments(const TemplateArgumentList *templateArgs) { std::vector<QualType> result; const int numArgs = templateArgs->size(); result.reserve(numArgs); for (int i = 0; i < numArgs; ++i) { const TemplateArgument &arg = templateArgs->get(i); if (arg.getKind() == TemplateArgument::Type) { result.push_back(arg.getAsType()); } } return result; } std::vector<QualType> clazy::getTemplateArgumentsTypes(CXXMethodDecl *method) { if (!method) { return {}; } const FunctionTemplateSpecializationInfo *specializationInfo = method->getTemplateSpecializationInfo(); if (!specializationInfo || !specializationInfo->TemplateArguments) { return {}; } return typesFromTemplateArguments(specializationInfo->TemplateArguments); } std::vector<clang::QualType> clazy::getTemplateArgumentsTypes(CXXRecordDecl *record) { if (!record) { return {}; } auto *templateDecl = dyn_cast<ClassTemplateSpecializationDecl>(record); if (!templateDecl) { return {}; } return typesFromTemplateArguments(&(templateDecl->getTemplateInstantiationArgs())); } ClassTemplateSpecializationDecl *clazy::templateDecl(Decl *decl) { if (isa<ClassTemplateSpecializationDecl>(decl)) { return dyn_cast<ClassTemplateSpecializationDecl>(decl); } auto *varDecl = dyn_cast<VarDecl>(decl); if (!varDecl) { return nullptr; } QualType qt = varDecl->getType(); const Type *t = qt.getTypePtrOrNull(); if (!t) { return nullptr; } CXXRecordDecl *classDecl = t->getAsCXXRecordDecl(); if (!classDecl) { return nullptr; } return dyn_cast<ClassTemplateSpecializationDecl>(classDecl); } std::string clazy::getTemplateArgumentTypeStr(ClassTemplateSpecializationDecl *specialization, unsigned int index, const LangOptions &lo, bool recordOnly) { if (!specialization) { return {}; } const auto &args = specialization->getTemplateArgs(); if (args.size() <= index) { return {}; } QualType qt = args[index].getAsType(); if (recordOnly) { const Type *t = qt.getTypePtrOrNull(); if (!t || !t->getAsCXXRecordDecl()) { return {}; } } return clazy::simpleTypeName(args[index].getAsType(), lo); } clang::QualType clazy::getTemplateArgumentType(ClassTemplateSpecializationDecl *specialization, unsigned int index) { if (!specialization) { return {}; } const auto &args = specialization->getTemplateArgs(); if (args.size() <= index) { return {}; } return args[index].getAsType(); }