File indexing completed on 2024-04-14 05:32:05
0001 /* 0002 SPDX-FileCopyrightText: 2016 Sergio Martins <smartins@kde.org> 0003 SPDX-FileCopyrightText: 2016 Klarälvdalens Datakonsult AB a KDAB Group company info@kdab.com 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #ifndef CLAZY_ACCESS_SPECIFIER_MANAGER_H 0009 #define CLAZY_ACCESS_SPECIFIER_MANAGER_H 0010 0011 #include "checkbase.h" 0012 0013 #include <clang/Basic/SourceLocation.h> 0014 #include <clang/Basic/Specifiers.h> 0015 #include <clang/Frontend/CompilerInstance.h> 0016 #include <llvm/ADT/StringRef.h> 0017 0018 #include <unordered_map> 0019 #include <vector> 0020 0021 /* 0022 clang supports "public", "private" and "protected" 0023 This is a small wrapper to have support for "public slots", "signals", etc. so you can easily 0024 query if a method is a signal or slot 0025 0026 This works in two steps, first the pre-processor kicks in and we use a PPCallbacks class to catch 0027 Q_SLOTS and Q_SIGNALS, then the normal access specifiers come in from the AST, inside VisitDeclaration(). 0028 0029 After that we just need to merge the two lists, and sort by source location. All the info is kept 0030 inside m_specifiersMap, which is indexed by the class definition. 0031 */ 0032 0033 namespace clang 0034 { 0035 class SourceManager; 0036 class LangOptions; 0037 class Decl; 0038 class CXXRecordDecl; 0039 class SourceLocation; 0040 class CXXMethodDecl; 0041 class CompilerInstance; 0042 } 0043 0044 class AccessSpecifierPreprocessorCallbacks; 0045 class ClazyContext; 0046 0047 enum QtAccessSpecifierType { QtAccessSpecifier_None, QtAccessSpecifier_Unknown, QtAccessSpecifier_Slot, QtAccessSpecifier_Signal, QtAccessSpecifier_Invokable }; 0048 0049 struct ClazyAccessSpecifier { 0050 clang::SourceLocation loc; 0051 clang::AccessSpecifier accessSpecifier; 0052 QtAccessSpecifierType qtAccessSpecifier; 0053 }; 0054 0055 using ClazySpecifierList = std::vector<ClazyAccessSpecifier>; 0056 0057 class AccessSpecifierManager 0058 { 0059 public: 0060 explicit AccessSpecifierManager(ClazyContext *); 0061 void VisitDeclaration(clang::Decl *decl); 0062 0063 /** 0064 * Returns if a method is a signal, a slot, or neither. 0065 */ 0066 QtAccessSpecifierType qtAccessSpecifierType(const clang::CXXMethodDecl *) const; 0067 0068 /** 0069 * Returns if a method is scriptable (Q_SCRIPTABLE) 0070 */ 0071 bool isScriptable(const clang::CXXMethodDecl *) const; 0072 0073 /** 0074 * Returns a string representations of a Qt Access Specifier Type 0075 */ 0076 llvm::StringRef qtAccessSpecifierTypeStr(QtAccessSpecifierType) const; 0077 0078 clang::SourceLocation firstLocationOfSection(clang::AccessSpecifier specifier, clang::CXXRecordDecl *decl) const; 0079 0080 private: 0081 ClazySpecifierList &entryForClassDefinition(clang::CXXRecordDecl *); 0082 const clang::CompilerInstance &m_ci; 0083 const clang::CXXRecordDecl *classDefinitionForLoc(clang::SourceLocation loc) const; 0084 std::unordered_map<const clang::CXXRecordDecl *, ClazySpecifierList> m_specifiersMap; 0085 AccessSpecifierPreprocessorCallbacks *const m_preprocessorCallbacks; 0086 const bool m_fixitsEnabled; 0087 bool m_visitsNonQObjects = false; 0088 }; 0089 0090 #endif