File indexing completed on 2024-04-28 16:57:49

0001 /*
0002     This file is part of the clazy static checker.
0003 
0004     Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
0005     Author: SĂ©rgio Martins <sergio.martins@kdab.com>
0006 
0007     Copyright (C) 2015-2017 Sergio Martins <smartins@kde.org>
0008 
0009     This library is free software; you can redistribute it and/or
0010     modify it under the terms of the GNU Library General Public
0011     License as published by the Free Software Foundation; either
0012     version 2 of the License, or (at your option) any later version.
0013 
0014     This library is distributed in the hope that it will be useful,
0015     but WITHOUT ANY WARRANTY; without even the implied warranty of
0016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0017     Library General Public License for more details.
0018 
0019     You should have received a copy of the GNU Library General Public License
0020     along with this library; see the file COPYING.LIB.  If not, write to
0021     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0022     Boston, MA 02110-1301, USA.
0023 */
0024 
0025 #ifndef CLAZY_AST_ACTION_H
0026 #define CLAZY_AST_ACTION_H
0027 
0028 #include "checkmanager.h"
0029 #include "ClazyContext.h"
0030 #include "checkbase.h"
0031 
0032 #include <clang/AST/ASTConsumer.h>
0033 #include <clang/Frontend/FrontendAction.h>
0034 #include <clang/AST/RecursiveASTVisitor.h>
0035 #include <llvm/ADT/StringRef.h>
0036 
0037 #include <memory>
0038 #include <vector>
0039 #include <string>
0040 #include <utility>
0041 
0042 namespace llvm {
0043 class raw_ostream;
0044 }  // namespace llvm
0045 
0046 namespace clang {
0047 class CompilerInstance;
0048 class ASTContext;
0049 class Decl;
0050 class Stmt;
0051 }
0052 
0053 /**
0054  * This is the FrontendAction that is run when clazy is used as a clang plugin.
0055  */
0056 class ClazyASTAction
0057     : public clang::PluginASTAction
0058 {
0059 public:
0060     ClazyASTAction();
0061 
0062 protected:
0063     /// @note This function is reentrant
0064     std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(clang::CompilerInstance &ci, llvm::StringRef) override;
0065     /// @note This function is reentrant
0066     bool ParseArgs(const clang::CompilerInstance &ci, const std::vector<std::string> &args_) override;
0067 
0068     void PrintHelp(llvm::raw_ostream &ros) const;
0069     void PrintAnchorHeader(llvm::raw_ostream &ro, RegisteredCheck::List &checks) const;
0070 private:
0071     void printRequestedChecks() const;
0072     RegisteredCheck::List m_checks;
0073     ClazyContext::ClazyOptions m_options = 0;
0074     CheckManager *const m_checkManager;
0075     ClazyContext *m_context = nullptr;
0076 };
0077 
0078 /**
0079  * This is the FrontendAction that is run when clazy is invoked via clazy-standalone.
0080  */
0081 class ClazyStandaloneASTAction
0082     : public clang::ASTFrontendAction
0083 {
0084 public:
0085     explicit ClazyStandaloneASTAction(const std::string &checkList,
0086                                       const std::string &headerFilter,
0087                                       const std::string &ignoreDirs,
0088                                       const std::string &exportFixesFilename,
0089                                       const std::vector<std::string> &translationUnitPaths,
0090                                       ClazyContext::ClazyOptions = ClazyContext::ClazyOption_None);
0091 protected:
0092     std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(clang::CompilerInstance &ci, llvm::StringRef) override;
0093 private:
0094     const std::string m_checkList;
0095     const std::string m_headerFilter;
0096     const std::string m_ignoreDirs;
0097     const std::string m_exportFixesFilename;
0098     const std::vector<std::string> m_translationUnitPaths;
0099     const ClazyContext::ClazyOptions m_options;
0100 };
0101 
0102 /**
0103  * Clazy's AST Consumer.
0104  */
0105 class ClazyASTConsumer
0106     : public clang::ASTConsumer
0107     , public clang::RecursiveASTVisitor<ClazyASTConsumer>
0108 {
0109 public:
0110     explicit ClazyASTConsumer(ClazyContext *context);
0111     ~ClazyASTConsumer() override;
0112     bool shouldVisitImplicitCode() const { return m_context->isVisitImplicitCode(); }
0113 
0114     bool VisitDecl(clang::Decl *decl);
0115     bool VisitStmt(clang::Stmt *stm);
0116     void HandleTranslationUnit(clang::ASTContext &ctx) override;
0117     void addCheck(const std::pair<CheckBase *, RegisteredCheck> &check);
0118 
0119     ClazyContext *context() const { return m_context; }
0120 
0121 private:
0122     ClazyASTConsumer(const ClazyASTConsumer &) = delete;
0123     clang::Stmt *lastStm = nullptr;
0124     ClazyContext *const m_context;
0125     //CheckBase::List m_createdChecks;
0126     CheckBase::List m_checksToVisitStmts;
0127     CheckBase::List m_checksToVisitDecls;
0128 #ifndef CLAZY_DISABLE_AST_MATCHERS
0129     clang::ast_matchers::MatchFinder *m_matchFinder = nullptr;
0130 #endif
0131 };
0132 
0133 #endif