1 //== AnalysisManager.h - Path sensitive analysis data manager ------*- C++ -*-// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines the AnalysisManager class that manages the data and policy 10 // for path sensitive analysis. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_ANALYSISMANAGER_H 15 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_ANALYSISMANAGER_H 16 17 #include "clang/Analysis/AnalysisDeclContext.h" 18 #include "clang/Analysis/PathDiagnostic.h" 19 #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" 20 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" 21 #include "clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h" 22 23 namespace clang { 24 25 class CodeInjector; 26 27 namespace ento { 28 class CheckerManager; 29 30 class AnalysisManager : public BugReporterData { 31 virtual void anchor(); 32 AnalysisDeclContextManager AnaCtxMgr; 33 34 ASTContext &Ctx; 35 const LangOptions &LangOpts; 36 PathDiagnosticConsumers PathConsumers; 37 38 // Configurable components creators. 39 StoreManagerCreator CreateStoreMgr; 40 ConstraintManagerCreator CreateConstraintMgr; 41 42 CheckerManager *CheckerMgr; 43 44 public: 45 AnalyzerOptions &options; 46 47 AnalysisManager(ASTContext &ctx, 48 const PathDiagnosticConsumers &Consumers, 49 StoreManagerCreator storemgr, 50 ConstraintManagerCreator constraintmgr, 51 CheckerManager *checkerMgr, AnalyzerOptions &Options, 52 CodeInjector *injector = nullptr); 53 54 ~AnalysisManager() override; 55 56 void ClearContexts() { 57 AnaCtxMgr.clear(); 58 } 59 60 AnalysisDeclContextManager& getAnalysisDeclContextManager() { 61 return AnaCtxMgr; 62 } 63 64 StoreManagerCreator getStoreManagerCreator() { 65 return CreateStoreMgr; 66 } 67 68 AnalyzerOptions& getAnalyzerOptions() override { 69 return options; 70 } 71 72 ConstraintManagerCreator getConstraintManagerCreator() { 73 return CreateConstraintMgr; 74 } 75 76 CheckerManager *getCheckerManager() const { return CheckerMgr; } 77 78 ASTContext &getASTContext() override { 79 return Ctx; 80 } 81 82 SourceManager &getSourceManager() override { 83 return getASTContext().getSourceManager(); 84 } 85 86 const LangOptions &getLangOpts() const { 87 return LangOpts; 88 } 89 90 ArrayRef<PathDiagnosticConsumer*> getPathDiagnosticConsumers() override { 91 return PathConsumers; 92 } 93 94 void FlushDiagnostics(); 95 96 bool shouldVisualize() const { 97 return options.visualizeExplodedGraphWithGraphViz; 98 } 99 100 bool shouldInlineCall() const { 101 return options.getIPAMode() != IPAK_None; 102 } 103 104 CFG *getCFG(Decl const *D) { 105 return AnaCtxMgr.getContext(D)->getCFG(); 106 } 107 108 template <typename T> 109 T *getAnalysis(Decl const *D) { 110 return AnaCtxMgr.getContext(D)->getAnalysis<T>(); 111 } 112 113 ParentMap &getParentMap(Decl const *D) { 114 return AnaCtxMgr.getContext(D)->getParentMap(); 115 } 116 117 AnalysisDeclContext *getAnalysisDeclContext(const Decl *D) { 118 return AnaCtxMgr.getContext(D); 119 } 120 121 static bool isInCodeFile(SourceLocation SL, const SourceManager &SM) { 122 if (SM.isInMainFile(SL)) 123 return true; 124 125 // Support the "unified sources" compilation method (eg. WebKit) that 126 // involves producing non-header files that include other non-header files. 127 // We should be included directly from a UnifiedSource* file 128 // and we shouldn't be a header - which is a very safe defensive check. 129 SourceLocation IL = SM.getIncludeLoc(SM.getFileID(SL)); 130 if (!IL.isValid() || !SM.isInMainFile(IL)) 131 return false; 132 // Should rather be "file name starts with", but the current .getFilename 133 // includes the full path. 134 if (SM.getFilename(IL).contains("UnifiedSource")) { 135 // It might be great to reuse FrontendOptions::getInputKindForExtension() 136 // but for now it doesn't discriminate between code and header files. 137 return llvm::StringSwitch<bool>(SM.getFilename(SL).rsplit('.').second) 138 .Cases("c", "m", "mm", "C", "cc", "cp", true) 139 .Cases("cpp", "CPP", "c++", "cxx", "cppm", true) 140 .Default(false); 141 } 142 143 return false; 144 } 145 146 bool isInCodeFile(SourceLocation SL) { 147 const SourceManager &SM = getASTContext().getSourceManager(); 148 return isInCodeFile(SL, SM); 149 } 150 }; 151 152 } // enAnaCtxMgrspace 153 154 } // end clang namespace 155 156 #endif 157