File indexing completed on 2024-04-28 16:57:48
0001 /* 0002 This file is part of the clazy static checker. 0003 0004 Copyright (C) 2016 Sergio Martins <smartins@kde.org> 0005 Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com 0006 0007 This library is free software; you can redistribute it and/or 0008 modify it under the terms of the GNU Library General Public 0009 License as published by the Free Software Foundation; either 0010 version 2 of the License, or (at your option) any later version. 0011 0012 This library is distributed in the hope that it will be useful, 0013 but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0015 Library General Public License for more details. 0016 0017 You should have received a copy of the GNU Library General Public License 0018 along with this library; see the file COPYING.LIB. If not, write to 0019 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0020 Boston, MA 02110-1301, USA. 0021 */ 0022 0023 #ifndef CLAZY_ACCESS_SPECIFIER_MANAGER_H 0024 #define CLAZY_ACCESS_SPECIFIER_MANAGER_H 0025 0026 #include "checkbase.h" 0027 0028 #include <clang/Frontend/CompilerInstance.h> 0029 #include <clang/Basic/SourceLocation.h> 0030 #include <clang/Basic/Specifiers.h> 0031 #include <llvm/ADT/StringRef.h> 0032 0033 #include <unordered_map> 0034 #include <vector> 0035 0036 /* 0037 clang supports "public", "private" and "protected" 0038 This is a small wrapper to have support for "public slots", "signals", etc. so you can easily 0039 query if a method is a signal or slot 0040 0041 This works in two steps, first the pre-processor kicks in and we use a PPCallbacks class to catch 0042 Q_SLOTS and Q_SIGNALS, then the normal access specifiers come in from the AST, inside VisitDeclaration(). 0043 0044 After that we just need to merge the two lists, and sort by source location. All the info is kept 0045 inside m_specifiersMap, which is indexed by the class definition. 0046 */ 0047 0048 namespace clang 0049 { 0050 class SourceManager; 0051 class LangOptions; 0052 class Decl; 0053 class CXXRecordDecl; 0054 class SourceLocation; 0055 class CXXMethodDecl; 0056 class CompilerInstance; 0057 } 0058 0059 class AccessSpecifierPreprocessorCallbacks; 0060 class ClazyContext; 0061 0062 enum QtAccessSpecifierType 0063 { 0064 QtAccessSpecifier_None, 0065 QtAccessSpecifier_Unknown, 0066 QtAccessSpecifier_Slot, 0067 QtAccessSpecifier_Signal, 0068 QtAccessSpecifier_Invokable 0069 }; 0070 0071 struct ClazyAccessSpecifier 0072 { 0073 clang::SourceLocation loc; 0074 clang::AccessSpecifier accessSpecifier; 0075 QtAccessSpecifierType qtAccessSpecifier; 0076 }; 0077 0078 using ClazySpecifierList = std::vector<ClazyAccessSpecifier>; 0079 0080 class AccessSpecifierManager 0081 { 0082 public: 0083 explicit AccessSpecifierManager(ClazyContext *); 0084 void VisitDeclaration(clang::Decl *decl); 0085 0086 /** 0087 * Returns if a method is a signal, a slot, or neither. 0088 */ 0089 QtAccessSpecifierType qtAccessSpecifierType(const clang::CXXMethodDecl*) const; 0090 0091 /** 0092 * Returns if a method is scriptable (Q_SCRIPTABLE) 0093 */ 0094 bool isScriptable(const clang::CXXMethodDecl*) const; 0095 0096 /** 0097 * Returns a string representations of a Qt Access Specifier Type 0098 */ 0099 llvm::StringRef qtAccessSpecifierTypeStr(QtAccessSpecifierType) const; 0100 0101 clang::SourceLocation firstLocationOfSection(clang::AccessSpecifier specifier, 0102 clang::CXXRecordDecl *decl) const; 0103 0104 private: 0105 ClazySpecifierList &entryForClassDefinition(clang::CXXRecordDecl*); 0106 const clang::CompilerInstance &m_ci; 0107 const clang::CXXRecordDecl *classDefinitionForLoc(clang::SourceLocation loc) const; 0108 std::unordered_map<const clang::CXXRecordDecl*, ClazySpecifierList> m_specifiersMap; 0109 AccessSpecifierPreprocessorCallbacks *const m_preprocessorCallbacks; 0110 const bool m_fixitsEnabled; 0111 bool m_visitsNonQObjects = false; 0112 }; 0113 0114 #endif