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