106f32e7eSjoerg //== AnalysisManager.h - Path sensitive analysis data manager ------*- C++ -*-// 206f32e7eSjoerg // 306f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 406f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information. 506f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 606f32e7eSjoerg // 706f32e7eSjoerg //===----------------------------------------------------------------------===// 806f32e7eSjoerg // 906f32e7eSjoerg // This file defines the AnalysisManager class that manages the data and policy 1006f32e7eSjoerg // for path sensitive analysis. 1106f32e7eSjoerg // 1206f32e7eSjoerg //===----------------------------------------------------------------------===// 1306f32e7eSjoerg 1406f32e7eSjoerg #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_ANALYSISMANAGER_H 1506f32e7eSjoerg #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_ANALYSISMANAGER_H 1606f32e7eSjoerg 1706f32e7eSjoerg #include "clang/Analysis/AnalysisDeclContext.h" 1806f32e7eSjoerg #include "clang/Analysis/PathDiagnostic.h" 19*13fbcb42Sjoerg #include "clang/Lex/Preprocessor.h" 2006f32e7eSjoerg #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" 2106f32e7eSjoerg #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" 2206f32e7eSjoerg #include "clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h" 2306f32e7eSjoerg 2406f32e7eSjoerg namespace clang { 2506f32e7eSjoerg 2606f32e7eSjoerg class CodeInjector; 2706f32e7eSjoerg 2806f32e7eSjoerg namespace ento { 2906f32e7eSjoerg class CheckerManager; 3006f32e7eSjoerg 3106f32e7eSjoerg class AnalysisManager : public BugReporterData { 3206f32e7eSjoerg virtual void anchor(); 3306f32e7eSjoerg AnalysisDeclContextManager AnaCtxMgr; 3406f32e7eSjoerg 3506f32e7eSjoerg ASTContext &Ctx; 36*13fbcb42Sjoerg Preprocessor &PP; 3706f32e7eSjoerg const LangOptions &LangOpts; 3806f32e7eSjoerg PathDiagnosticConsumers PathConsumers; 3906f32e7eSjoerg 4006f32e7eSjoerg // Configurable components creators. 4106f32e7eSjoerg StoreManagerCreator CreateStoreMgr; 4206f32e7eSjoerg ConstraintManagerCreator CreateConstraintMgr; 4306f32e7eSjoerg 4406f32e7eSjoerg CheckerManager *CheckerMgr; 4506f32e7eSjoerg 4606f32e7eSjoerg public: 4706f32e7eSjoerg AnalyzerOptions &options; 4806f32e7eSjoerg 49*13fbcb42Sjoerg AnalysisManager(ASTContext &ctx, Preprocessor &PP, 5006f32e7eSjoerg const PathDiagnosticConsumers &Consumers, 5106f32e7eSjoerg StoreManagerCreator storemgr, 5206f32e7eSjoerg ConstraintManagerCreator constraintmgr, 5306f32e7eSjoerg CheckerManager *checkerMgr, AnalyzerOptions &Options, 5406f32e7eSjoerg CodeInjector *injector = nullptr); 5506f32e7eSjoerg 5606f32e7eSjoerg ~AnalysisManager() override; 5706f32e7eSjoerg ClearContexts()5806f32e7eSjoerg void ClearContexts() { 5906f32e7eSjoerg AnaCtxMgr.clear(); 6006f32e7eSjoerg } 6106f32e7eSjoerg getAnalysisDeclContextManager()6206f32e7eSjoerg AnalysisDeclContextManager& getAnalysisDeclContextManager() { 6306f32e7eSjoerg return AnaCtxMgr; 6406f32e7eSjoerg } 6506f32e7eSjoerg getPreprocessor()66*13fbcb42Sjoerg Preprocessor &getPreprocessor() override { return PP; } 67*13fbcb42Sjoerg getStoreManagerCreator()6806f32e7eSjoerg StoreManagerCreator getStoreManagerCreator() { 6906f32e7eSjoerg return CreateStoreMgr; 7006f32e7eSjoerg } 7106f32e7eSjoerg getAnalyzerOptions()7206f32e7eSjoerg AnalyzerOptions& getAnalyzerOptions() override { 7306f32e7eSjoerg return options; 7406f32e7eSjoerg } 7506f32e7eSjoerg getConstraintManagerCreator()7606f32e7eSjoerg ConstraintManagerCreator getConstraintManagerCreator() { 7706f32e7eSjoerg return CreateConstraintMgr; 7806f32e7eSjoerg } 7906f32e7eSjoerg getCheckerManager()8006f32e7eSjoerg CheckerManager *getCheckerManager() const { return CheckerMgr; } 8106f32e7eSjoerg getASTContext()8206f32e7eSjoerg ASTContext &getASTContext() override { 8306f32e7eSjoerg return Ctx; 8406f32e7eSjoerg } 8506f32e7eSjoerg getSourceManager()8606f32e7eSjoerg SourceManager &getSourceManager() override { 8706f32e7eSjoerg return getASTContext().getSourceManager(); 8806f32e7eSjoerg } 8906f32e7eSjoerg getLangOpts()9006f32e7eSjoerg const LangOptions &getLangOpts() const { 9106f32e7eSjoerg return LangOpts; 9206f32e7eSjoerg } 9306f32e7eSjoerg getPathDiagnosticConsumers()9406f32e7eSjoerg ArrayRef<PathDiagnosticConsumer*> getPathDiagnosticConsumers() override { 9506f32e7eSjoerg return PathConsumers; 9606f32e7eSjoerg } 9706f32e7eSjoerg 9806f32e7eSjoerg void FlushDiagnostics(); 9906f32e7eSjoerg shouldVisualize()10006f32e7eSjoerg bool shouldVisualize() const { 10106f32e7eSjoerg return options.visualizeExplodedGraphWithGraphViz; 10206f32e7eSjoerg } 10306f32e7eSjoerg shouldInlineCall()10406f32e7eSjoerg bool shouldInlineCall() const { 10506f32e7eSjoerg return options.getIPAMode() != IPAK_None; 10606f32e7eSjoerg } 10706f32e7eSjoerg getCFG(Decl const * D)10806f32e7eSjoerg CFG *getCFG(Decl const *D) { 10906f32e7eSjoerg return AnaCtxMgr.getContext(D)->getCFG(); 11006f32e7eSjoerg } 11106f32e7eSjoerg 11206f32e7eSjoerg template <typename T> getAnalysis(Decl const * D)11306f32e7eSjoerg T *getAnalysis(Decl const *D) { 11406f32e7eSjoerg return AnaCtxMgr.getContext(D)->getAnalysis<T>(); 11506f32e7eSjoerg } 11606f32e7eSjoerg getParentMap(Decl const * D)11706f32e7eSjoerg ParentMap &getParentMap(Decl const *D) { 11806f32e7eSjoerg return AnaCtxMgr.getContext(D)->getParentMap(); 11906f32e7eSjoerg } 12006f32e7eSjoerg getAnalysisDeclContext(const Decl * D)12106f32e7eSjoerg AnalysisDeclContext *getAnalysisDeclContext(const Decl *D) { 12206f32e7eSjoerg return AnaCtxMgr.getContext(D); 12306f32e7eSjoerg } 12406f32e7eSjoerg isInCodeFile(SourceLocation SL,const SourceManager & SM)12506f32e7eSjoerg static bool isInCodeFile(SourceLocation SL, const SourceManager &SM) { 12606f32e7eSjoerg if (SM.isInMainFile(SL)) 12706f32e7eSjoerg return true; 12806f32e7eSjoerg 12906f32e7eSjoerg // Support the "unified sources" compilation method (eg. WebKit) that 13006f32e7eSjoerg // involves producing non-header files that include other non-header files. 13106f32e7eSjoerg // We should be included directly from a UnifiedSource* file 13206f32e7eSjoerg // and we shouldn't be a header - which is a very safe defensive check. 13306f32e7eSjoerg SourceLocation IL = SM.getIncludeLoc(SM.getFileID(SL)); 13406f32e7eSjoerg if (!IL.isValid() || !SM.isInMainFile(IL)) 13506f32e7eSjoerg return false; 13606f32e7eSjoerg // Should rather be "file name starts with", but the current .getFilename 13706f32e7eSjoerg // includes the full path. 13806f32e7eSjoerg if (SM.getFilename(IL).contains("UnifiedSource")) { 13906f32e7eSjoerg // It might be great to reuse FrontendOptions::getInputKindForExtension() 14006f32e7eSjoerg // but for now it doesn't discriminate between code and header files. 14106f32e7eSjoerg return llvm::StringSwitch<bool>(SM.getFilename(SL).rsplit('.').second) 14206f32e7eSjoerg .Cases("c", "m", "mm", "C", "cc", "cp", true) 14306f32e7eSjoerg .Cases("cpp", "CPP", "c++", "cxx", "cppm", true) 14406f32e7eSjoerg .Default(false); 14506f32e7eSjoerg } 14606f32e7eSjoerg 14706f32e7eSjoerg return false; 14806f32e7eSjoerg } 14906f32e7eSjoerg isInCodeFile(SourceLocation SL)15006f32e7eSjoerg bool isInCodeFile(SourceLocation SL) { 15106f32e7eSjoerg const SourceManager &SM = getASTContext().getSourceManager(); 15206f32e7eSjoerg return isInCodeFile(SL, SM); 15306f32e7eSjoerg } 15406f32e7eSjoerg }; 15506f32e7eSjoerg 15606f32e7eSjoerg } // enAnaCtxMgrspace 15706f32e7eSjoerg 15806f32e7eSjoerg } // end clang namespace 15906f32e7eSjoerg 16006f32e7eSjoerg #endif 161