File indexing completed on 2024-04-28 16:57:52
0001 /* 0002 This file is part of the clazy static checker. 0003 0004 Copyright (C) 2016 Sergio Martins <smartins@kde.org> 0005 0006 This library is free software; you can redistribute it and/or 0007 modify it under the terms of the GNU Library General Public 0008 License as published by the Free Software Foundation; either 0009 version 2 of the License, or (at your option) any later version. 0010 0011 This library is distributed in the hope that it will be useful, 0012 but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0014 Library General Public License for more details. 0015 0016 You should have received a copy of the GNU Library General Public License 0017 along with this library; see the file COPYING.LIB. If not, write to 0018 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0019 Boston, MA 02110-1301, USA. 0020 */ 0021 0022 #include "TemplateUtils.h" 0023 #include "StringUtils.h" 0024 0025 #include <clang/AST/DeclCXX.h> 0026 #include <clang/AST/DeclTemplate.h> 0027 #include <clang/AST/Decl.h> 0028 #include <clang/AST/TemplateBase.h> 0029 #include <clang/AST/Type.h> 0030 #include <clang/Basic/LLVM.h> 0031 #include <llvm/Support/Casting.h> 0032 0033 namespace clang { 0034 class LangOptions; 0035 } // namespace clang 0036 0037 using namespace std; 0038 using namespace clang; 0039 0040 static vector<QualType> typesFromTemplateArguments(const TemplateArgumentList *templateArgs) 0041 { 0042 vector<QualType> result; 0043 const int numArgs = templateArgs->size(); 0044 result.reserve(numArgs); 0045 for (int i = 0; i < numArgs; ++i) { 0046 const TemplateArgument &arg = templateArgs->get(i); 0047 if (arg.getKind() == TemplateArgument::Type) 0048 result.push_back(arg.getAsType()); 0049 } 0050 0051 return result; 0052 } 0053 0054 vector<QualType> clazy::getTemplateArgumentsTypes(CXXMethodDecl *method) 0055 { 0056 if (!method) 0057 return {}; 0058 0059 FunctionTemplateSpecializationInfo *specializationInfo = method->getTemplateSpecializationInfo(); 0060 if (!specializationInfo || !specializationInfo->TemplateArguments) 0061 return {}; 0062 0063 return typesFromTemplateArguments(specializationInfo->TemplateArguments); 0064 } 0065 0066 std::vector<clang::QualType> clazy::getTemplateArgumentsTypes(CXXRecordDecl *record) 0067 { 0068 if (!record) 0069 return {}; 0070 0071 ClassTemplateSpecializationDecl *templateDecl = dyn_cast<ClassTemplateSpecializationDecl>(record); 0072 if (!templateDecl) 0073 return {}; 0074 0075 return typesFromTemplateArguments(&(templateDecl->getTemplateInstantiationArgs())); 0076 } 0077 0078 ClassTemplateSpecializationDecl *clazy::templateDecl(Decl *decl) 0079 { 0080 if (isa<ClassTemplateSpecializationDecl>(decl)) 0081 return dyn_cast<ClassTemplateSpecializationDecl>(decl); 0082 0083 VarDecl *varDecl = dyn_cast<VarDecl>(decl); 0084 if (!varDecl) return nullptr; 0085 QualType qt = varDecl->getType(); 0086 const Type *t = qt.getTypePtrOrNull(); 0087 if (!t) return nullptr; 0088 CXXRecordDecl *classDecl = t->getAsCXXRecordDecl(); 0089 if (!classDecl) return nullptr; 0090 return dyn_cast<ClassTemplateSpecializationDecl>(classDecl); 0091 } 0092 0093 string clazy::getTemplateArgumentTypeStr(ClassTemplateSpecializationDecl *specialization, 0094 unsigned int index, const LangOptions &lo, bool recordOnly) 0095 { 0096 if (!specialization) 0097 return {}; 0098 0099 auto &args = specialization->getTemplateArgs(); 0100 if (args.size() <= index) 0101 return {}; 0102 0103 QualType qt = args[index].getAsType(); 0104 if (recordOnly) { 0105 const Type *t = qt.getTypePtrOrNull(); 0106 if (!t || !t->getAsCXXRecordDecl()) 0107 return {}; 0108 } 0109 0110 return clazy::simpleTypeName(args[index].getAsType(), lo); 0111 } 0112 0113 clang::QualType clazy::getTemplateArgumentType(ClassTemplateSpecializationDecl *specialization, unsigned int index) 0114 { 0115 if (!specialization) 0116 return {}; 0117 0118 auto &args = specialization->getTemplateArgs(); 0119 if (args.size() <= index) 0120 return {}; 0121 0122 return args[index].getAsType(); 0123 }