martong updated this revision to Diff 283254.
martong added a comment.

- Remove dummy test file


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D85319/new/

https://reviews.llvm.org/D85319

Files:
  clang/include/clang/CodeGen/CodeGenMangling.h
  clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
  clang/include/clang/StaticAnalyzer/Core/IRContext.h
  clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
  clang/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h
  clang/include/clang/StaticAnalyzer/Frontend/FrontendActions.h
  clang/lib/CodeGen/CMakeLists.txt
  clang/lib/CodeGen/CodeGenMangling.cpp
  clang/lib/StaticAnalyzer/Core/CMakeLists.txt
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
  clang/lib/StaticAnalyzer/Core/IRContext.cpp
  clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
  clang/lib/StaticAnalyzer/Frontend/CMakeLists.txt
  clang/lib/StaticAnalyzer/Frontend/FrontendActions.cpp
  clang/test/Analysis/analyzer-config.c
  clang/test/Analysis/ctu-different-triples.cpp
  clang/test/Analysis/ircontext.cpp
  clang/unittests/StaticAnalyzer/Reusables.h

Index: clang/unittests/StaticAnalyzer/Reusables.h
===================================================================
--- clang/unittests/StaticAnalyzer/Reusables.h
+++ clang/unittests/StaticAnalyzer/Reusables.h
@@ -10,8 +10,9 @@
 #define LLVM_CLANG_UNITTESTS_STATICANALYZER_REUSABLES_H
 
 #include "clang/ASTMatchers/ASTMatchFinder.h"
-#include "clang/Frontend/CompilerInstance.h"
 #include "clang/CrossTU/CrossTranslationUnit.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/StaticAnalyzer/Core/IRContext.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
 
 namespace clang {
@@ -41,11 +42,13 @@
 class ExprEngineConsumer : public ASTConsumer {
 protected:
   CompilerInstance &C;
+  CodeGenerator *CG = nullptr;
 
 private:
   // We need to construct all of these in order to construct ExprEngine.
   CheckerManager ChkMgr;
   cross_tu::CrossTranslationUnitContext CTU;
+  IRContext IRCtx;
   PathDiagnosticConsumers Consumers;
   AnalysisManager AMgr;
   SetOfConstDecls VisitedCallees;
@@ -58,12 +61,12 @@
   ExprEngineConsumer(CompilerInstance &C)
       : C(C),
         ChkMgr(C.getASTContext(), *C.getAnalyzerOpts(), C.getPreprocessor()),
-        CTU(C), Consumers(),
+        CTU(C), IRCtx(CG), Consumers(),
         AMgr(C.getASTContext(), C.getPreprocessor(), Consumers,
              CreateRegionStoreManager, CreateRangeConstraintManager, &ChkMgr,
              *C.getAnalyzerOpts()),
-        VisitedCallees(), FS(),
-        Eng(CTU, AMgr, &VisitedCallees, &FS, ExprEngine::Inline_Regular) {}
+        VisitedCallees(), FS(), Eng(CTU, IRCtx, AMgr, &VisitedCallees, &FS,
+                                    ExprEngine::Inline_Regular) {}
 };
 
 } // namespace ento
Index: clang/test/Analysis/ircontext.cpp
===================================================================
--- /dev/null
+++ clang/test/Analysis/ircontext.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_analyze_cc1 %s \
+// RUN:   -analyzer-checker=core,debug.ExprInspection \
+// RUN:   -analyzer-config eagerly-assume=false \
+// RUN:   -analyzer-config ipa=none \
+// RUN:   -analyzer-config generate-llvm-ir=true \
+// RUN:   -triple i686-unknown-linux \
+// RUN:   -verify
+
+void clang_analyzer_eval(int);
+
+int g = 0;
+int foo(int *x) { return *x; }
+
+void test() {
+  g = 3;
+  int l = 0;
+  foo(&l);
+  clang_analyzer_eval(g == 3); // expected-warning{{TRUE}}
+}
Index: clang/test/Analysis/ctu-different-triples.cpp
===================================================================
--- clang/test/Analysis/ctu-different-triples.cpp
+++ clang/test/Analysis/ctu-different-triples.cpp
@@ -12,6 +12,8 @@
 
 // We expect an error in this file, but without a location.
 // expected-error-re@./ctu-different-triples.cpp:*{{imported AST from {{.*}} had been generated for a different target, current: powerpc64-montavista-linux-gnu, imported: x86_64-pc-linux-gnu}}
+// FIXME Why do we get the error twice?
+// expected-error-re@./ctu-different-triples.cpp:*{{imported AST from {{.*}} had been generated for a different target, current: powerpc64-montavista-linux-gnu, imported: x86_64-pc-linux-gnu}}
 
 int f(int);
 
Index: clang/test/Analysis/analyzer-config.c
===================================================================
--- clang/test/Analysis/analyzer-config.c
+++ clang/test/Analysis/analyzer-config.c
@@ -80,6 +80,7 @@
 // CHECK-NEXT: experimental-enable-naive-ctu-analysis = false
 // CHECK-NEXT: exploration_strategy = unexplored_first_queue
 // CHECK-NEXT: faux-bodies = true
+// CHECK-NEXT: generate-llvm-ir = false
 // CHECK-NEXT: graph-trim-interval = 1000
 // CHECK-NEXT: inline-lambdas = true
 // CHECK-NEXT: ipa = dynamic-bifurcate
Index: clang/lib/StaticAnalyzer/Frontend/FrontendActions.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Frontend/FrontendActions.cpp
+++ clang/lib/StaticAnalyzer/Frontend/FrontendActions.cpp
@@ -7,14 +7,61 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
+#include "clang/Frontend/MultiplexConsumer.h"
 #include "clang/StaticAnalyzer/Frontend/AnalysisConsumer.h"
 #include "clang/StaticAnalyzer/Frontend/ModelConsumer.h"
+
+#include "clang/CodeGen/ModuleBuilder.h"
+#include "clang/Frontend/CompilerInstance.h"
+
+#include "llvm/IR/LLVMContext.h"
+
 using namespace clang;
 using namespace ento;
 
+namespace {
+std::unique_ptr<CodeGenerator> BuildCodeGen(CompilerInstance &CI,
+                                            llvm::LLVMContext &LLVMCtx,
+                                            DiagnosticsEngine &CodeGenDiags) {
+  StringRef ModuleName("csa_module");
+  CodeGenOptions &CGO = CI.getCodeGenOpts();
+  // Set the optimization level, so CodeGenFunciton would emit lifetime
+  // markers which are used by some LLVM analysis (e.g. AliasAnalysis).
+  CGO.OptimizationLevel = 2; // -O2
+
+  return std::unique_ptr<CodeGenerator>(
+      CreateLLVMCodeGen(CodeGenDiags, ModuleName, CI.getHeaderSearchOpts(),
+                        CI.getPreprocessorOpts(), CGO, LLVMCtx));
+}
+} // namespace
+
+AnalysisAction::~AnalysisAction() {}
+
 std::unique_ptr<ASTConsumer>
 AnalysisAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
-  return CreateAnalysisConsumer(CI);
+  std::vector<std::unique_ptr<ASTConsumer>> ASTConsumers;
+  auto AConsumer = CreateAnalysisConsumer(CI);
+
+  AnalyzerOptionsRef Opts = CI.getAnalyzerOpts();
+  if (Opts->GenerateLLVMIR) {
+    DiagnosticsEngine &SADiagEng = CI.getDiagnostics();
+    // Supress diagnostics during CodeGen.
+    CodeGenDiags = std::make_unique<DiagnosticsEngine>(
+        SADiagEng.getDiagnosticIDs(), &SADiagEng.getDiagnosticOptions(),
+        SADiagEng.getClient(), /*ShouldOwnClient=*/false);
+    CodeGenDiags->setSuppressAllDiagnostics(true);
+    LLVMCtx = std::make_shared<llvm::LLVMContext>();
+    auto CGConsumer = BuildCodeGen(CI, *LLVMCtx, *CodeGenDiags);
+    AConsumer->setCodeGen(CGConsumer.get());
+    ASTConsumers.push_back(std::move(CGConsumer));
+  }
+
+  ASTConsumers.push_back(std::move(AConsumer));
+  return std::make_unique<MultiplexConsumer>(std::move(ASTConsumers));
+}
+
+std::unique_ptr<AnalysisAction> CreateAnalysisAction() {
+  return std::make_unique<AnalysisAction>();
 }
 
 ParseModelFileAction::ParseModelFileAction(llvm::StringMap<Stmt *> &Bodies)
Index: clang/lib/StaticAnalyzer/Frontend/CMakeLists.txt
===================================================================
--- clang/lib/StaticAnalyzer/Frontend/CMakeLists.txt
+++ clang/lib/StaticAnalyzer/Frontend/CMakeLists.txt
@@ -14,10 +14,12 @@
   ModelInjector.cpp
 
   LINK_LIBS
+  LLVMCore
   clangAST
   clangASTMatchers
   clangAnalysis
   clangBasic
+  clangCodeGen
   clangCrossTU
   clangFrontend
   clangLex
Index: clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -30,6 +30,7 @@
 #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/IRContext.h"
 #include "clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
@@ -90,6 +91,7 @@
   ArrayRef<std::string> Plugins;
   CodeInjector *Injector;
   cross_tu::CrossTranslationUnitContext CTU;
+  IRContext IRCtx;
 
   /// Stores the declarations from the local translation unit.
   /// Note, we pre-compute the local declarations at parse time as an
@@ -122,7 +124,7 @@
                    CodeInjector *injector)
       : RecVisitorMode(0), RecVisitorBR(nullptr), Ctx(nullptr),
         PP(CI.getPreprocessor()), OutDir(outdir), Opts(std::move(opts)),
-        Plugins(plugins), Injector(injector), CTU(CI) {
+        Plugins(plugins), Injector(injector), CTU(CI), IRCtx(CG) {
     DigestAnalyzerOptions();
     if (Opts->PrintStats || Opts->ShouldSerializeStats) {
       AnalyzerTimers = std::make_unique<llvm::TimerGroup>(
@@ -541,6 +543,7 @@
     reportAnalyzerProgress("All checks are disabled using a supplied option\n");
   } else {
     // Otherwise, just run the analysis.
+    IRCtx.runOptimizerPipeline();
     runAnalysisOnTranslationUnit(C);
   }
 
@@ -693,7 +696,7 @@
   if (!Mgr->getAnalysisDeclContext(D)->getAnalysis<RelaxedLiveVariables>())
     return;
 
-  ExprEngine Eng(CTU, *Mgr, VisitedCallees, &FunctionSummaries, IMode);
+  ExprEngine Eng(CTU, IRCtx, *Mgr, VisitedCallees, &FunctionSummaries, IMode);
 
   // Execute the worklist algorithm.
   if (ExprEngineTimer)
Index: clang/lib/StaticAnalyzer/Core/IRContext.cpp
===================================================================
--- /dev/null
+++ clang/lib/StaticAnalyzer/Core/IRContext.cpp
@@ -0,0 +1,100 @@
+//===-------------- IRContext.cpp -----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/StaticAnalyzer/Core/IRContext.h"
+#include "clang/CodeGen/CodeGenMangling.h"
+#include "clang/CodeGen/ModuleBuilder.h"
+
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/Passes/PassBuilder.h"
+#include "llvm/Transforms/Utils/EntryExitInstrumenter.h"
+
+using namespace llvm;
+using namespace clang;
+using namespace ento;
+
+void IRContext::runOptimizerPipeline() {
+  if (CodeGen == nullptr)
+    return;
+
+  // TargetMachine is not set, so we will not do optimizations based on
+  // target-aware cost modeling of IR contructs. Still, a default
+  // TargetIRAnalysis is registerd in registerFunctionAnalyses. That will use
+  // the module's datalayout to construct a baseline conservative result.
+  PassBuilder PB;
+
+  // FIXME make this an option.
+  constexpr const bool Debug = false;
+
+  LoopAnalysisManager LAM(Debug);
+  FunctionAnalysisManager FAM(Debug);
+  CGSCCAnalysisManager CGAM(Debug);
+  ModuleAnalysisManager MAM(Debug);
+
+  // Register the AA manager first so that our version is the one used.
+  FAM.registerPass([&] { return PB.buildDefaultAAPipeline(); });
+
+  auto *M = CodeGen->GetModule();
+
+  // Register the target library analysis directly and give it a customized
+  // preset TLI.
+  Triple TargetTriple(M->getTargetTriple());
+  std::unique_ptr<TargetLibraryInfoImpl> TLII(
+      new TargetLibraryInfoImpl(TargetTriple));
+  FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); });
+
+  // Register all the basic analyses with the managers.
+  PB.registerModuleAnalyses(MAM);
+  PB.registerCGSCCAnalyses(CGAM);
+  PB.registerFunctionAnalyses(FAM);
+  PB.registerLoopAnalyses(LAM);
+  PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
+
+  ModulePassManager MPM(Debug);
+
+  PB.registerPipelineStartEPCallback([](ModulePassManager &MPM) {
+    MPM.addPass(createModuleToFunctionPassAdaptor(
+        EntryExitInstrumenterPass(/*PostInlining=*/false)));
+  });
+
+  MPM = PB.buildPerModuleDefaultPipeline(PassBuilder::OptimizationLevel::O2,
+                                         Debug);
+  MPM.run(*M, MAM);
+}
+
+llvm::Function *IRContext::getFunction(GlobalDecl GD) {
+  if (CodeGen == nullptr)
+    return nullptr;
+
+  CodeGen::CodeGenModule &CGM = CodeGen->CGM();
+  StringRef Name = getMangledName(CGM, GD);
+
+  auto *M = CodeGen->GetModule();
+  // There are functions which are not generated. E.g. not used operator=, etc.
+  return M->getFunction(Name);
+}
+
+llvm::Function *IRContext::getFunction(const FunctionDecl *FD) {
+  if (CodeGen == nullptr)
+    return nullptr;
+
+  // We use the complete versions of the constructors and desctructors.
+  // Use the other overload of getFunction to get the base object ctor/dtor.
+  GlobalDecl GD;
+  if (const auto *CD = dyn_cast<CXXConstructorDecl>(FD))
+    GD = GlobalDecl(CD, Ctor_Complete);
+  else if (const auto *DD = dyn_cast<CXXDestructorDecl>(FD))
+    GD = GlobalDecl(DD, Dtor_Complete);
+  else if (FD->hasAttr<CUDAGlobalAttr>())
+    GD = GlobalDecl(FD, KernelReferenceKind::Kernel);
+  else
+    GD = GlobalDecl(FD);
+
+  return getFunction(GD);
+}
Index: clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
+++ clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
@@ -17,10 +17,12 @@
 #include "clang/Analysis/Analyses/LiveVariables.h"
 #include "clang/Analysis/ConstructionContext.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/IRContext.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/Statistic.h"
+#include "llvm/IR/Function.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/SaveAndRestore.h"
@@ -707,6 +709,16 @@
 // a conjured return value.
 void ExprEngine::conservativeEvalCall(const CallEvent &Call, NodeBuilder &Bldr,
                                       ExplodedNode *Pred, ProgramStateRef State) {
+  // Query the LLVM IR whether this function is pure.
+  if (const Decl *D = Call.getRuntimeDefinition().getDecl())
+    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+      if (FD->getDefinition())
+        if (auto *F = getIRContext()->getFunction(FD))
+          // Pure function.
+          if (F->getAttributes().hasFnAttribute(llvm::Attribute::ReadNone) ||
+              F->getAttributes().hasFnAttribute(llvm::Attribute::ReadOnly))
+            return;
+
   State = Call.invalidateRegions(currBldrCtx->blockCount(), State);
   State = bindReturnValue(Call, Pred->getLocationContext(), State);
 
Index: clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -200,24 +200,18 @@
 static const char* TagProviderName = "ExprEngine";
 
 ExprEngine::ExprEngine(cross_tu::CrossTranslationUnitContext &CTU,
-                       AnalysisManager &mgr,
+                       IRContext &IRCtx, AnalysisManager &mgr,
                        SetOfConstDecls *VisitedCalleesIn,
-                       FunctionSummariesTy *FS,
-                       InliningModes HowToInlineIn)
-    : CTU(CTU), AMgr(mgr),
+                       FunctionSummariesTy *FS, InliningModes HowToInlineIn)
+    : CTU(CTU), IRCtx(IRCtx), AMgr(mgr),
       AnalysisDeclContexts(mgr.getAnalysisDeclContextManager()),
       Engine(*this, FS, mgr.getAnalyzerOptions()), G(Engine.getGraph()),
       StateMgr(getContext(), mgr.getStoreManagerCreator(),
-               mgr.getConstraintManagerCreator(), G.getAllocator(),
-               this),
-      SymMgr(StateMgr.getSymbolManager()),
-      MRMgr(StateMgr.getRegionManager()),
-      svalBuilder(StateMgr.getSValBuilder()),
-      ObjCNoRet(mgr.getASTContext()),
-      BR(mgr, *this),
-      VisitedCallees(VisitedCalleesIn),
-      HowToInline(HowToInlineIn)
-  {
+               mgr.getConstraintManagerCreator(), G.getAllocator(), this),
+      SymMgr(StateMgr.getSymbolManager()), MRMgr(StateMgr.getRegionManager()),
+      svalBuilder(StateMgr.getSValBuilder()), ObjCNoRet(mgr.getASTContext()),
+      BR(mgr, *this), VisitedCallees(VisitedCalleesIn),
+      HowToInline(HowToInlineIn) {
   unsigned TrimInterval = mgr.options.GraphTrimInterval;
   if (TrimInterval != 0) {
     // Enable eager node reclamation when constructing the ExplodedGraph.
Index: clang/lib/StaticAnalyzer/Core/CMakeLists.txt
===================================================================
--- clang/lib/StaticAnalyzer/Core/CMakeLists.txt
+++ clang/lib/StaticAnalyzer/Core/CMakeLists.txt
@@ -31,6 +31,7 @@
   ExprEngineObjC.cpp
   FunctionSummary.cpp
   HTMLDiagnostics.cpp
+  IRContext.cpp
   IssueHash.cpp
   LoopUnrolling.cpp
   LoopWidening.cpp
@@ -52,10 +53,15 @@
   WorkList.cpp
 
   LINK_LIBS
+  LLVMAnalysis
+  LLVMCore
+  LLVMPasses
+  LLVMTransformUtils
   clangAST
   clangASTMatchers
   clangAnalysis
   clangBasic
+  clangCodeGen
   clangCrossTU
   clangFrontend
   clangLex
Index: clang/lib/CodeGen/CodeGenMangling.cpp
===================================================================
--- /dev/null
+++ clang/lib/CodeGen/CodeGenMangling.cpp
@@ -0,0 +1,25 @@
+//==--- CodeGenMangling.cpp - Get mangled names from the CodeGenModule -----==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// CodeGenMangling provides name mangling that depends on the target set for
+// the given CodeGen.
+//===----------------------------------------------------------------------===//
+
+#include "clang/CodeGen/CodeGenMangling.h"
+#include "CodeGenModule.h"
+
+using namespace llvm;
+
+namespace clang {
+namespace CodeGen {
+
+StringRef getMangledName(CodeGenModule &CGM, GlobalDecl GD) {
+  return CGM.getMangledName(GD);
+}
+
+} // namespace CodeGen
+} // namespace clang
Index: clang/lib/CodeGen/CMakeLists.txt
===================================================================
--- clang/lib/CodeGen/CMakeLists.txt
+++ clang/lib/CodeGen/CMakeLists.txt
@@ -68,6 +68,7 @@
   CodeGenABITypes.cpp
   CodeGenAction.cpp
   CodeGenFunction.cpp
+  CodeGenMangling.cpp
   CodeGenModule.cpp
   CodeGenPGO.cpp
   CodeGenTBAA.cpp
Index: clang/include/clang/StaticAnalyzer/Frontend/FrontendActions.h
===================================================================
--- clang/include/clang/StaticAnalyzer/Frontend/FrontendActions.h
+++ clang/include/clang/StaticAnalyzer/Frontend/FrontendActions.h
@@ -13,6 +13,12 @@
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
 
+#include <memory>
+
+namespace llvm {
+class LLVMContext;
+} // namespace llvm
+
 namespace clang {
 
 class Stmt;
@@ -27,11 +33,21 @@
 //===----------------------------------------------------------------------===//
 
 class AnalysisAction : public ASTFrontendAction {
+  // Cannot be a unique_ptr because then ClangFrontendTool would
+  // depend on this lib.
+  std::shared_ptr<llvm::LLVMContext> LLVMCtx;
+  std::unique_ptr<DiagnosticsEngine> CodeGenDiags;
+
 protected:
   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
                                                  StringRef InFile) override;
+
+public:
+  ~AnalysisAction();
 };
 
+std::unique_ptr<AnalysisAction> CreateAnalysisAction();
+
 /// Frontend action to parse model files.
 ///
 /// This frontend action is responsible for parsing model files. Model files can
Index: clang/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h
===================================================================
--- clang/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h
+++ clang/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h
@@ -24,6 +24,7 @@
 class Preprocessor;
 class DiagnosticsEngine;
 class CodeInjector;
+class CodeGenerator;
 class CompilerInstance;
 
 namespace ento {
@@ -32,6 +33,9 @@
 class CheckerRegistry;
 
 class AnalysisASTConsumer : public ASTConsumer {
+protected:
+  CodeGenerator *CG = nullptr;
+
 public:
   virtual void AddDiagnosticConsumer(PathDiagnosticConsumer *Consumer) = 0;
 
@@ -47,6 +51,8 @@
   ///   });
   virtual void
   AddCheckerRegistrationFn(std::function<void(CheckerRegistry &)> Fn) = 0;
+
+  void setCodeGen(CodeGenerator *Cg) { CG = Cg; }
 };
 
 /// CreateAnalysisConsumer - Creates an ASTConsumer to run various code
@@ -57,6 +63,6 @@
 
 } // namespace ento
 
-} // end clang namespace
+} // namespace clang
 
 #endif
Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
===================================================================
--- clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -87,6 +87,7 @@
 class ExplodedNodeSet;
 class ExplodedNode;
 class IndirectGotoNodeBuilder;
+class IRContext;
 class MemRegion;
 struct NodeBuilderContext;
 class NodeBuilderWithSinks;
@@ -140,6 +141,8 @@
 private:
   cross_tu::CrossTranslationUnitContext &CTU;
 
+  IRContext &IRCtx;
+
   AnalysisManager &AMgr;
 
   AnalysisDeclContextManager &AnalysisDeclContexts;
@@ -181,8 +184,8 @@
   InliningModes HowToInline;
 
 public:
-  ExprEngine(cross_tu::CrossTranslationUnitContext &CTU, AnalysisManager &mgr,
-             SetOfConstDecls *VisitedCalleesIn,
+  ExprEngine(cross_tu::CrossTranslationUnitContext &CTU, IRContext &IRCtx,
+             AnalysisManager &mgr, SetOfConstDecls *VisitedCalleesIn,
              FunctionSummariesTy *FS, InliningModes HowToInlineIn);
 
   virtual ~ExprEngine() = default;
@@ -224,6 +227,8 @@
     return &CTU;
   }
 
+  IRContext *getIRContext() { return &IRCtx; }
+
   const NodeBuilderContext &getBuilderContext() {
     assert(currBldrCtx);
     return *currBldrCtx;
Index: clang/include/clang/StaticAnalyzer/Core/IRContext.h
===================================================================
--- /dev/null
+++ clang/include/clang/StaticAnalyzer/Core/IRContext.h
@@ -0,0 +1,48 @@
+//== IRContext.h - Get info from the IR in CSA -*- C++ -*--------------------=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines auxilary structures for getting data from the IR inside
+// the Clang Static Analyzer.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_IRCONTEXT_H
+#define LLVM_CLANG_STATICANALYZER_CORE_IRCONTEXT_H
+
+#include "clang/AST/GlobalDecl.h"
+
+namespace llvm {
+class Function;
+} // namespace llvm
+
+namespace clang {
+class CodeGenerator;
+class FunctionDecl;
+
+namespace ento {
+
+// Static Analyzer components can get access to the LLVM IR of a translation
+// unit throught this class.
+class IRContext {
+  // Set by AnalysisAction if the AnalyzerOptions requires that.
+  clang::CodeGenerator *&CodeGen;
+
+public:
+  IRContext(clang::CodeGenerator *&CodeGen) : CodeGen(CodeGen) {}
+  void runOptimizerPipeline();
+  llvm::Function *getFunction(GlobalDecl GD);
+  // Get the LLVM code for a function. We use the complete versions of the
+  // constructors and desctructors in this overload. Use the other overload to
+  // get the base object ctor/dtor.
+  llvm::Function *getFunction(const FunctionDecl *FD);
+};
+
+} // namespace ento
+} // namespace clang
+
+#endif
Index: clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
===================================================================
--- clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
+++ clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
@@ -314,6 +314,11 @@
                 "Display the checker name for textual outputs",
                 true)
 
+ANALYZER_OPTION(bool, GenerateLLVMIR, "generate-llvm-ir",
+                "Whether to generate LLVM IR for the translation unit. "
+                "The analyzer can be more precise by using info from the IR.",
+                false)
+
 //===----------------------------------------------------------------------===//
 // Unsigned analyzer options.
 //===----------------------------------------------------------------------===//
Index: clang/include/clang/CodeGen/CodeGenMangling.h
===================================================================
--- /dev/null
+++ clang/include/clang/CodeGen/CodeGenMangling.h
@@ -0,0 +1,27 @@
+//==----- CodeGenMangling.h - Get mangled names from the CodeGenModule -----==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// CodeGenMangling provides name mangling that depends on the target set for
+// the given CodeGen.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CODEGEN_CODEGENMANGLING_H
+#define LLVM_CLANG_CODEGEN_CODEGENMANGLING_H
+
+#include "clang/AST/GlobalDecl.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace clang {
+namespace CodeGen {
+class CodeGenModule;
+
+llvm::StringRef getMangledName(CodeGenModule &CGM, GlobalDecl GD);
+
+} // namespace CodeGen
+} // namespace clang
+
+#endif
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to