xref: /openbsd-src/gnu/llvm/clang/lib/StaticAnalyzer/Frontend/ModelInjector.h (revision 12c855180aad702bbcca06e0398d774beeafb155)
1*e5dd7070Spatrick //===-- ModelInjector.h -----------------------------------------*- C++ -*-===//
2*e5dd7070Spatrick //
3*e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5*e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*e5dd7070Spatrick //
7*e5dd7070Spatrick //===----------------------------------------------------------------------===//
8*e5dd7070Spatrick ///
9*e5dd7070Spatrick /// \file
10*e5dd7070Spatrick /// This file defines the clang::ento::ModelInjector class which implements the
11*e5dd7070Spatrick /// clang::CodeInjector interface. This class is responsible for injecting
12*e5dd7070Spatrick /// function definitions that were synthesized from model files.
13*e5dd7070Spatrick ///
14*e5dd7070Spatrick /// Model files allow definitions of functions to be lazily constituted for functions
15*e5dd7070Spatrick /// which lack bodies in the original source code.  This allows the analyzer
16*e5dd7070Spatrick /// to more precisely analyze code that calls such functions, analyzing the
17*e5dd7070Spatrick /// artificial definitions (which typically approximate the semantics of the
18*e5dd7070Spatrick /// called function) when called by client code.  These definitions are
19*e5dd7070Spatrick /// reconstituted lazily, on-demand, by the static analyzer engine.
20*e5dd7070Spatrick ///
21*e5dd7070Spatrick //===----------------------------------------------------------------------===//
22*e5dd7070Spatrick 
23*e5dd7070Spatrick #ifndef LLVM_CLANG_SA_FRONTEND_MODELINJECTOR_H
24*e5dd7070Spatrick #define LLVM_CLANG_SA_FRONTEND_MODELINJECTOR_H
25*e5dd7070Spatrick 
26*e5dd7070Spatrick #include "clang/Analysis/CodeInjector.h"
27*e5dd7070Spatrick #include "llvm/ADT/StringMap.h"
28*e5dd7070Spatrick 
29*e5dd7070Spatrick namespace clang {
30*e5dd7070Spatrick 
31*e5dd7070Spatrick class CompilerInstance;
32*e5dd7070Spatrick class NamedDecl;
33*e5dd7070Spatrick 
34*e5dd7070Spatrick namespace ento {
35*e5dd7070Spatrick class ModelInjector : public CodeInjector {
36*e5dd7070Spatrick public:
37*e5dd7070Spatrick   ModelInjector(CompilerInstance &CI);
38*e5dd7070Spatrick   Stmt *getBody(const FunctionDecl *D) override;
39*e5dd7070Spatrick   Stmt *getBody(const ObjCMethodDecl *D) override;
40*e5dd7070Spatrick 
41*e5dd7070Spatrick private:
42*e5dd7070Spatrick   /// Synthesize a body for a declaration
43*e5dd7070Spatrick   ///
44*e5dd7070Spatrick   /// This method first looks up the appropriate model file based on the
45*e5dd7070Spatrick   /// model-path configuration option and the name of the declaration that is
46*e5dd7070Spatrick   /// looked up. If no model were synthesized yet for a function with that name
47*e5dd7070Spatrick   /// it will create a new compiler instance to parse the model file using the
48*e5dd7070Spatrick   /// ASTContext, Preprocessor, SourceManager of the original compiler instance.
49*e5dd7070Spatrick   /// The former resources are shared between the two compiler instance, so the
50*e5dd7070Spatrick   /// newly created instance have to "leak" these objects, since they are owned
51*e5dd7070Spatrick   /// by the original instance.
52*e5dd7070Spatrick   ///
53*e5dd7070Spatrick   /// The model-path should be either an absolute path or relative to the
54*e5dd7070Spatrick   /// working directory of the compiler.
55*e5dd7070Spatrick   void onBodySynthesis(const NamedDecl *D);
56*e5dd7070Spatrick 
57*e5dd7070Spatrick   CompilerInstance &CI;
58*e5dd7070Spatrick 
59*e5dd7070Spatrick   // FIXME: double memoization is redundant, with memoization both here and in
60*e5dd7070Spatrick   // BodyFarm.
61*e5dd7070Spatrick   llvm::StringMap<Stmt *> Bodies;
62*e5dd7070Spatrick };
63*e5dd7070Spatrick }
64*e5dd7070Spatrick }
65*e5dd7070Spatrick 
66*e5dd7070Spatrick #endif
67