1 //===- unittests/StaticAnalyzer/Reusables.h -------------------------------===//
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 #ifndef LLVM_CLANG_UNITTESTS_STATICANALYZER_REUSABLES_H
10 #define LLVM_CLANG_UNITTESTS_STATICANALYZER_REUSABLES_H
11 
12 #include "clang/ASTMatchers/ASTMatchFinder.h"
13 #include "clang/Frontend/CompilerInstance.h"
14 #include "clang/CrossTU/CrossTranslationUnit.h"
15 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
16 
17 namespace clang {
18 namespace ento {
19 
20 // Find a node in the current AST that matches a matcher.
21 template <typename T, typename MatcherT>
findNode(const Decl * Where,MatcherT What)22 const T *findNode(const Decl *Where, MatcherT What) {
23   using namespace ast_matchers;
24   auto Matches = match(decl(hasDescendant(What.bind("root"))),
25                        *Where, Where->getASTContext());
26   assert(Matches.size() <= 1 && "Ambiguous match!");
27   assert(Matches.size() >= 1 && "Match not found!");
28   const T *Node = selectFirst<T>("root", Matches);
29   assert(Node && "Type mismatch!");
30   return Node;
31 }
32 
33 // Find a declaration in the current AST by name.
34 template <typename T>
findDeclByName(const Decl * Where,StringRef Name)35 const T *findDeclByName(const Decl *Where, StringRef Name) {
36   using namespace ast_matchers;
37   return findNode<T>(Where, namedDecl(hasName(Name)));
38 }
39 
40 // A re-usable consumer that constructs ExprEngine out of CompilerInvocation.
41 class ExprEngineConsumer : public ASTConsumer {
42 protected:
43   CompilerInstance &C;
44 
45 private:
46   // We need to construct all of these in order to construct ExprEngine.
47   CheckerManager ChkMgr;
48   cross_tu::CrossTranslationUnitContext CTU;
49   PathDiagnosticConsumers Consumers;
50   AnalysisManager AMgr;
51   SetOfConstDecls VisitedCallees;
52   FunctionSummariesTy FS;
53 
54 protected:
55   ExprEngine Eng;
56 
57 public:
ExprEngineConsumer(CompilerInstance & C)58   ExprEngineConsumer(CompilerInstance &C)
59       : C(C),
60         ChkMgr(C.getASTContext(), *C.getAnalyzerOpts(), C.getPreprocessor()),
61         CTU(C), Consumers(),
62         AMgr(C.getASTContext(), C.getPreprocessor(), Consumers,
63              CreateRegionStoreManager, CreateRangeConstraintManager, &ChkMgr,
64              *C.getAnalyzerOpts()),
65         VisitedCallees(), FS(),
66         Eng(CTU, AMgr, &VisitedCallees, &FS, ExprEngine::Inline_Regular) {}
67 };
68 
69 } // namespace ento
70 } // namespace clang
71 
72 #endif
73