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