File indexing completed on 2024-05-12 05:40:56

0001 /*
0002     SPDX-FileCopyrightText: 2016 Sergio Martins <smartins@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "qenums.h"
0008 #include "ClazyContext.h"
0009 #include "PreProcessorVisitor.h"
0010 #include "clazy_stl.h"
0011 
0012 #include <clang/Basic/IdentifierTable.h>
0013 #include <clang/Basic/SourceManager.h>
0014 #include <clang/Lex/Lexer.h>
0015 #include <clang/Lex/Token.h>
0016 #include <llvm/ADT/StringRef.h>
0017 
0018 namespace clang
0019 {
0020 class MacroInfo;
0021 } // namespace clang
0022 
0023 using namespace clang;
0024 
0025 QEnums::QEnums(const std::string &name, ClazyContext *context)
0026     : CheckBase(name, context)
0027 {
0028     enablePreProcessorCallbacks();
0029     context->enablePreprocessorVisitor();
0030 }
0031 
0032 void QEnums::VisitMacroExpands(const Token &MacroNameTok, const SourceRange &range, const clang::MacroInfo *)
0033 {
0034     PreProcessorVisitor *preProcessorVisitor = m_context->preprocessorVisitor;
0035     if (!preProcessorVisitor || preProcessorVisitor->qtVersion() < 50500) {
0036         return;
0037     }
0038 
0039     IdentifierInfo *ii = MacroNameTok.getIdentifierInfo();
0040     if (!ii || ii->getName() != "Q_ENUMS") {
0041         return;
0042     }
0043 
0044     {
0045         // Don't warn when importing enums of other classes, because Q_ENUM doesn't support it.
0046         // We simply check if :: is present because it's very cumbersome to to check for different classes when dealing with the pre-processor
0047 
0048         CharSourceRange crange = Lexer::getAsCharRange(range, sm(), lo());
0049         std::string text = static_cast<std::string>(Lexer::getSourceText(crange, sm(), lo()));
0050         if (clazy::contains(text, "::")) {
0051             return;
0052         }
0053     }
0054 
0055     if (range.getBegin().isMacroID()) {
0056         return;
0057     }
0058 
0059     if (sm().isInSystemHeader(range.getBegin())) {
0060         return;
0061     }
0062 
0063     emitWarning(range.getBegin(), "Use Q_ENUM instead of Q_ENUMS");
0064 }