File indexing completed on 2024-04-14 05:32:08
0001 /* 0002 SPDX-FileCopyrightText: 2016 Sergio Martins <smartins@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "TemplateUtils.h" 0008 #include "StringUtils.h" 0009 0010 #include <clang/AST/Decl.h> 0011 #include <clang/AST/DeclCXX.h> 0012 #include <clang/AST/DeclTemplate.h> 0013 #include <clang/AST/TemplateBase.h> 0014 #include <clang/AST/Type.h> 0015 #include <clang/Basic/LLVM.h> 0016 #include <llvm/Support/Casting.h> 0017 0018 namespace clang 0019 { 0020 class LangOptions; 0021 } // namespace clang 0022 0023 using namespace clang; 0024 0025 static std::vector<QualType> typesFromTemplateArguments(const TemplateArgumentList *templateArgs) 0026 { 0027 std::vector<QualType> result; 0028 const int numArgs = templateArgs->size(); 0029 result.reserve(numArgs); 0030 for (int i = 0; i < numArgs; ++i) { 0031 const TemplateArgument &arg = templateArgs->get(i); 0032 if (arg.getKind() == TemplateArgument::Type) { 0033 result.push_back(arg.getAsType()); 0034 } 0035 } 0036 0037 return result; 0038 } 0039 0040 std::vector<QualType> clazy::getTemplateArgumentsTypes(CXXMethodDecl *method) 0041 { 0042 if (!method) { 0043 return {}; 0044 } 0045 0046 FunctionTemplateSpecializationInfo *specializationInfo = method->getTemplateSpecializationInfo(); 0047 if (!specializationInfo || !specializationInfo->TemplateArguments) { 0048 return {}; 0049 } 0050 0051 return typesFromTemplateArguments(specializationInfo->TemplateArguments); 0052 } 0053 0054 std::vector<clang::QualType> clazy::getTemplateArgumentsTypes(CXXRecordDecl *record) 0055 { 0056 if (!record) { 0057 return {}; 0058 } 0059 0060 auto *templateDecl = dyn_cast<ClassTemplateSpecializationDecl>(record); 0061 if (!templateDecl) { 0062 return {}; 0063 } 0064 0065 return typesFromTemplateArguments(&(templateDecl->getTemplateInstantiationArgs())); 0066 } 0067 0068 ClassTemplateSpecializationDecl *clazy::templateDecl(Decl *decl) 0069 { 0070 if (isa<ClassTemplateSpecializationDecl>(decl)) { 0071 return dyn_cast<ClassTemplateSpecializationDecl>(decl); 0072 } 0073 0074 auto *varDecl = dyn_cast<VarDecl>(decl); 0075 if (!varDecl) { 0076 return nullptr; 0077 } 0078 QualType qt = varDecl->getType(); 0079 const Type *t = qt.getTypePtrOrNull(); 0080 if (!t) { 0081 return nullptr; 0082 } 0083 CXXRecordDecl *classDecl = t->getAsCXXRecordDecl(); 0084 if (!classDecl) { 0085 return nullptr; 0086 } 0087 return dyn_cast<ClassTemplateSpecializationDecl>(classDecl); 0088 } 0089 0090 std::string clazy::getTemplateArgumentTypeStr(ClassTemplateSpecializationDecl *specialization, unsigned int index, const LangOptions &lo, bool recordOnly) 0091 { 0092 if (!specialization) { 0093 return {}; 0094 } 0095 0096 const auto &args = specialization->getTemplateArgs(); 0097 if (args.size() <= index) { 0098 return {}; 0099 } 0100 0101 QualType qt = args[index].getAsType(); 0102 if (recordOnly) { 0103 const Type *t = qt.getTypePtrOrNull(); 0104 if (!t || !t->getAsCXXRecordDecl()) { 0105 return {}; 0106 } 0107 } 0108 0109 return clazy::simpleTypeName(args[index].getAsType(), lo); 0110 } 0111 0112 clang::QualType clazy::getTemplateArgumentType(ClassTemplateSpecializationDecl *specialization, unsigned int index) 0113 { 0114 if (!specialization) { 0115 return {}; 0116 } 0117 0118 const auto &args = specialization->getTemplateArgs(); 0119 if (args.size() <= index) { 0120 return {}; 0121 } 0122 0123 return args[index].getAsType(); 0124 }