109 lines · cpp
1//===- Facts.cpp - Lifetime Analysis Facts Implementation -------*- 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-exception6//7//===----------------------------------------------------------------------===//8 9#include "clang/Analysis/Analyses/LifetimeSafety/Facts.h"10#include "clang/AST/Decl.h"11#include "clang/Analysis/Analyses/PostOrderCFGView.h"12 13namespace clang::lifetimes::internal {14 15void Fact::dump(llvm::raw_ostream &OS, const LoanManager &,16 const OriginManager &) const {17 OS << "Fact (Kind: " << static_cast<int>(K) << ")\n";18}19 20void IssueFact::dump(llvm::raw_ostream &OS, const LoanManager &LM,21 const OriginManager &OM) const {22 OS << "Issue (";23 LM.getLoan(getLoanID()).dump(OS);24 OS << ", ToOrigin: ";25 OM.dump(getOriginID(), OS);26 OS << ")\n";27}28 29void ExpireFact::dump(llvm::raw_ostream &OS, const LoanManager &LM,30 const OriginManager &) const {31 OS << "Expire (";32 LM.getLoan(getLoanID()).dump(OS);33 OS << ")\n";34}35 36void OriginFlowFact::dump(llvm::raw_ostream &OS, const LoanManager &,37 const OriginManager &OM) const {38 OS << "OriginFlow (Dest: ";39 OM.dump(getDestOriginID(), OS);40 OS << ", Src: ";41 OM.dump(getSrcOriginID(), OS);42 OS << (getKillDest() ? "" : ", Merge");43 OS << ")\n";44}45 46void OriginEscapesFact::dump(llvm::raw_ostream &OS, const LoanManager &,47 const OriginManager &OM) const {48 OS << "OriginEscapes (";49 OM.dump(getEscapedOriginID(), OS);50 OS << ")\n";51}52 53void UseFact::dump(llvm::raw_ostream &OS, const LoanManager &,54 const OriginManager &OM) const {55 OS << "Use (";56 OM.dump(getUsedOrigin(), OS);57 OS << ", " << (isWritten() ? "Write" : "Read") << ")\n";58}59 60void TestPointFact::dump(llvm::raw_ostream &OS, const LoanManager &,61 const OriginManager &) const {62 OS << "TestPoint (Annotation: \"" << getAnnotation() << "\")\n";63}64 65llvm::StringMap<ProgramPoint> FactManager::getTestPoints() const {66 llvm::StringMap<ProgramPoint> AnnotationToPointMap;67 for (const auto &BlockFacts : BlockToFacts) {68 for (const Fact *F : BlockFacts) {69 if (const auto *TPF = F->getAs<TestPointFact>()) {70 StringRef PointName = TPF->getAnnotation();71 assert(!AnnotationToPointMap.contains(PointName) &&72 "more than one test points with the same name");73 AnnotationToPointMap[PointName] = F;74 }75 }76 }77 return AnnotationToPointMap;78}79 80void FactManager::dump(const CFG &Cfg, AnalysisDeclContext &AC) const {81 llvm::dbgs() << "==========================================\n";82 llvm::dbgs() << " Lifetime Analysis Facts:\n";83 llvm::dbgs() << "==========================================\n";84 if (const Decl *D = AC.getDecl())85 if (const auto *ND = dyn_cast<NamedDecl>(D))86 llvm::dbgs() << "Function: " << ND->getQualifiedNameAsString() << "\n";87 // Print blocks in the order as they appear in code for a stable ordering.88 for (const CFGBlock *B : *AC.getAnalysis<PostOrderCFGView>()) {89 llvm::dbgs() << " Block B" << B->getBlockID() << ":\n";90 for (const Fact *F : getFacts(B)) {91 llvm::dbgs() << " ";92 F->dump(llvm::dbgs(), LoanMgr, OriginMgr);93 }94 llvm::dbgs() << " End of Block\n";95 }96}97 98llvm::ArrayRef<const Fact *>99FactManager::getBlockContaining(ProgramPoint P) const {100 for (const auto &BlockToFactsVec : BlockToFacts) {101 for (const Fact *F : BlockToFactsVec)102 if (F == P)103 return BlockToFactsVec;104 }105 return {};106}107 108} // namespace clang::lifetimes::internal109