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