File indexing completed on 2024-04-28 09:33:47
0001 /* 0002 SPDX-FileCopyrightText: 2017 Sergio Martins <smartins@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #ifndef CLAZY_PREPROCESSOR_VISITOR_H 0008 #define CLAZY_PREPROCESSOR_VISITOR_H 0009 0010 // Each check can visit the preprocessor, but doing things per-check can be 0011 // time consuming and we might want to do them only once. 0012 // For example, getting the Qt version can be done once and the result shared 0013 // with all checks 0014 0015 #include "checkbase.h" 0016 0017 #include <clang/Lex/PPCallbacks.h> 0018 #include <llvm/ADT/StringRef.h> 0019 0020 #include <string> 0021 #include <unordered_map> 0022 #include <vector> 0023 0024 namespace clang 0025 { 0026 class CompilerInstance; 0027 class SourceManager; 0028 class SourceRange; 0029 class Token; 0030 class MacroDefinition; 0031 class MacroArgs; 0032 class SourceLocation; 0033 } 0034 0035 using uint = unsigned; 0036 0037 class PreProcessorVisitor : public clang::PPCallbacks 0038 { 0039 PreProcessorVisitor(const PreProcessorVisitor &) = delete; 0040 0041 public: 0042 explicit PreProcessorVisitor(const clang::CompilerInstance &ci); 0043 0044 // Returns for example 050601 (Qt 5.6.1), or -1 if we don't know the version 0045 int qtVersion() const 0046 { 0047 return m_qtVersion; 0048 } 0049 0050 bool isBetweenQtNamespaceMacros(clang::SourceLocation loc); 0051 0052 // Returns true if QT_NO_KEYWORDS is defined 0053 bool isQT_NO_KEYWORDS() const 0054 { 0055 return m_isQtNoKeywords; 0056 } 0057 0058 bool hasInclude(const std::string &fileName, bool IsAngled) const; 0059 clang::SourceLocation endOfIncludeSection() const; 0060 0061 protected: 0062 void MacroExpands(const clang::Token &MacroNameTok, const clang::MacroDefinition &, clang::SourceRange range, const clang::MacroArgs *) override; 0063 void InclusionDirective(clang::SourceLocation HashLoc, 0064 const clang::Token &IncludeTok, 0065 clang::StringRef FileName, 0066 bool IsAngled, 0067 clang::CharSourceRange FilenameRange, 0068 clazy::OptionalFileEntryRef File, 0069 clang::StringRef SearchPath, 0070 clang::StringRef RelativePath, 0071 const clang::Module *Imported, 0072 clang::SrcMgr::CharacteristicKind FileType) override; 0073 0074 private: 0075 std::string getTokenSpelling(const clang::MacroDefinition &) const; 0076 void updateQtVersion(); 0077 void handleQtNamespaceMacro(clang::SourceLocation loc, clang::StringRef name); 0078 0079 const clang::CompilerInstance &m_ci; 0080 int m_qtMajorVersion = -1; 0081 int m_qtMinorVersion = -1; 0082 int m_qtPatchVersion = -1; 0083 int m_qtVersion = -1; 0084 bool m_isQtNoKeywords = false; 0085 0086 // Indexed by FileId, has a list of QT_BEGIN_NAMESPACE/QT_END_NAMESPACE location 0087 std::unordered_map<uint, std::vector<clang::SourceRange>> m_q_namespace_macro_locations; 0088 const clang::SourceManager &m_sm; 0089 0090 struct IncludeInfo { 0091 clang::StringRef fileName; 0092 bool IsAngled; 0093 clang::CharSourceRange filenameRange; 0094 }; 0095 0096 std::vector<IncludeInfo> m_includeInfo; 0097 }; 0098 0099 #endif