This revision was automatically updated to reflect the committed changes.
Closed by commit rL371765: [CFG] Add dumps for CFGElement and CFGElementRef 
(authored by Szelethus, committed by ).
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
Changed prior to commit:
  https://reviews.llvm.org/D66715?vs=217040&id=219979#toc

Repository:
  rL LLVM

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

https://reviews.llvm.org/D66715

Files:
  cfe/trunk/include/clang/Analysis/CFG.h
  cfe/trunk/lib/Analysis/CFG.cpp

Index: cfe/trunk/lib/Analysis/CFG.cpp
===================================================================
--- cfe/trunk/lib/Analysis/CFG.cpp
+++ cfe/trunk/lib/Analysis/CFG.cpp
@@ -4999,6 +4999,8 @@
 public:
   StmtPrinterHelper(const CFG* cfg, const LangOptions &LO)
       : LangOpts(LO) {
+    if (!cfg)
+      return;
     for (CFG::const_iterator I = cfg->begin(), E = cfg->end(); I != E; ++I ) {
       unsigned j = 1;
       for (CFGBlock::const_iterator BI = (*I)->begin(), BEnd = (*I)->end() ;
@@ -5321,9 +5323,21 @@
 }
 
 static void print_elem(raw_ostream &OS, StmtPrinterHelper &Helper,
+                       const CFGElement &E);
+
+void CFGElement::dumpToStream(llvm::raw_ostream &OS) const {
+  StmtPrinterHelper Helper(nullptr, {});
+  print_elem(OS, Helper, *this);
+}
+
+static void print_elem(raw_ostream &OS, StmtPrinterHelper &Helper,
                        const CFGElement &E) {
-  if (Optional<CFGStmt> CS = E.getAs<CFGStmt>()) {
-    const Stmt *S = CS->getStmt();
+  switch (E.getKind()) {
+  case CFGElement::Kind::Statement:
+  case CFGElement::Kind::CXXRecordTypedCall:
+  case CFGElement::Kind::Constructor: {
+    CFGStmt CS = E.castAs<CFGStmt>();
+    const Stmt *S = CS.getStmt();
     assert(S != nullptr && "Expecting non-null Stmt");
 
     // special printing for statement-expressions.
@@ -5375,12 +5389,18 @@
     // Expressions need a newline.
     if (isa<Expr>(S))
       OS << '\n';
-  } else if (Optional<CFGInitializer> IE = E.getAs<CFGInitializer>()) {
-    print_initializer(OS, Helper, IE->getInitializer());
+
+    break;
+  }
+
+  case CFGElement::Kind::Initializer:
+    print_initializer(OS, Helper, E.castAs<CFGInitializer>().getInitializer());
     OS << '\n';
-  } else if (Optional<CFGAutomaticObjDtor> DE =
-                 E.getAs<CFGAutomaticObjDtor>()) {
-    const VarDecl *VD = DE->getVarDecl();
+    break;
+
+  case CFGElement::Kind::AutomaticObjectDtor: {
+    CFGAutomaticObjDtor DE = E.castAs<CFGAutomaticObjDtor>();
+    const VarDecl *VD = DE.getVarDecl();
     Helper.handleDecl(VD, OS);
 
     QualType T = VD->getType();
@@ -5390,53 +5410,75 @@
     OS << ".~";
     T.getUnqualifiedType().print(OS, PrintingPolicy(Helper.getLangOpts()));
     OS << "() (Implicit destructor)\n";
-  } else if (Optional<CFGLifetimeEnds> DE = E.getAs<CFGLifetimeEnds>()) {
-    const VarDecl *VD = DE->getVarDecl();
-    Helper.handleDecl(VD, OS);
+    break;
+  }
 
+  case CFGElement::Kind::LifetimeEnds:
+    Helper.handleDecl(E.castAs<CFGLifetimeEnds>().getVarDecl(), OS);
     OS << " (Lifetime ends)\n";
-  } else if (Optional<CFGLoopExit> LE = E.getAs<CFGLoopExit>()) {
-    const Stmt *LoopStmt = LE->getLoopStmt();
-    OS << LoopStmt->getStmtClassName() << " (LoopExit)\n";
-  } else if (Optional<CFGScopeBegin> SB = E.getAs<CFGScopeBegin>()) {
+    break;
+
+  case CFGElement::Kind::LoopExit:
+    OS << E.castAs<CFGLoopExit>().getLoopStmt()->getStmtClassName() << " (LoopExit)\n";
+    break;
+
+  case CFGElement::Kind::ScopeBegin:
     OS << "CFGScopeBegin(";
-    if (const VarDecl *VD = SB->getVarDecl())
+    if (const VarDecl *VD = E.castAs<CFGScopeBegin>().getVarDecl())
       OS << VD->getQualifiedNameAsString();
     OS << ")\n";
-  } else if (Optional<CFGScopeEnd> SE = E.getAs<CFGScopeEnd>()) {
+    break;
+
+  case CFGElement::Kind::ScopeEnd:
     OS << "CFGScopeEnd(";
-    if (const VarDecl *VD = SE->getVarDecl())
+    if (const VarDecl *VD = E.castAs<CFGScopeEnd>().getVarDecl())
       OS << VD->getQualifiedNameAsString();
     OS << ")\n";
-  } else if (Optional<CFGNewAllocator> NE = E.getAs<CFGNewAllocator>()) {
+    break;
+
+  case CFGElement::Kind::NewAllocator:
     OS << "CFGNewAllocator(";
-    if (const CXXNewExpr *AllocExpr = NE->getAllocatorExpr())
+    if (const CXXNewExpr *AllocExpr = E.castAs<CFGNewAllocator>().getAllocatorExpr())
       AllocExpr->getType().print(OS, PrintingPolicy(Helper.getLangOpts()));
     OS << ")\n";
-  } else if (Optional<CFGDeleteDtor> DE = E.getAs<CFGDeleteDtor>()) {
-    const CXXRecordDecl *RD = DE->getCXXRecordDecl();
+    break;
+
+  case CFGElement::Kind::DeleteDtor: {
+    CFGDeleteDtor DE = E.castAs<CFGDeleteDtor>();
+    const CXXRecordDecl *RD = DE.getCXXRecordDecl();
     if (!RD)
       return;
     CXXDeleteExpr *DelExpr =
-        const_cast<CXXDeleteExpr*>(DE->getDeleteExpr());
+        const_cast<CXXDeleteExpr*>(DE.getDeleteExpr());
     Helper.handledStmt(cast<Stmt>(DelExpr->getArgument()), OS);
     OS << "->~" << RD->getName().str() << "()";
     OS << " (Implicit destructor)\n";
-  } else if (Optional<CFGBaseDtor> BE = E.getAs<CFGBaseDtor>()) {
-    const CXXBaseSpecifier *BS = BE->getBaseSpecifier();
+    break;
+  }
+
+  case CFGElement::Kind::BaseDtor: {
+    const CXXBaseSpecifier *BS = E.castAs<CFGBaseDtor>().getBaseSpecifier();
     OS << "~" << BS->getType()->getAsCXXRecordDecl()->getName() << "()";
     OS << " (Base object destructor)\n";
-  } else if (Optional<CFGMemberDtor> ME = E.getAs<CFGMemberDtor>()) {
-    const FieldDecl *FD = ME->getFieldDecl();
+    break;
+  }
+
+  case CFGElement::Kind::MemberDtor: {
+    const FieldDecl *FD = E.castAs<CFGMemberDtor>().getFieldDecl();
     const Type *T = FD->getType()->getBaseElementTypeUnsafe();
     OS << "this->" << FD->getName();
     OS << ".~" << T->getAsCXXRecordDecl()->getName() << "()";
     OS << " (Member object destructor)\n";
-  } else if (Optional<CFGTemporaryDtor> TE = E.getAs<CFGTemporaryDtor>()) {
-    const CXXBindTemporaryExpr *BT = TE->getBindTemporaryExpr();
+    break;
+  }
+
+  case CFGElement::Kind::TemporaryDtor: {
+    const CXXBindTemporaryExpr *BT = E.castAs<CFGTemporaryDtor>().getBindTemporaryExpr();
     OS << "~";
     BT->getType().print(OS, PrintingPolicy(Helper.getLangOpts()));
     OS << "() (Temporary object destructor)\n";
+    break;
+  }
   }
 }
 
Index: cfe/trunk/include/clang/Analysis/CFG.h
===================================================================
--- cfe/trunk/include/clang/Analysis/CFG.h
+++ cfe/trunk/include/clang/Analysis/CFG.h
@@ -121,6 +121,12 @@
     x |= Data1.getInt();
     return (Kind) x;
   }
+
+  void dumpToStream(llvm::raw_ostream &OS) const;
+
+  void dump() const {
+    dumpToStream(llvm::errs());
+  }
 };
 
 class CFGStmt : public CFGElement {
@@ -650,8 +656,17 @@
     }
 
     bool operator!=(ElementRefImpl Other) const { return !(*this == Other); }
-    CFGElement operator*() { return (*Parent)[Index]; }
-    CFGElementPtr operator->() { return &*(Parent->begin() + Index); }
+    CFGElement operator*() const { return (*Parent)[Index]; }
+    CFGElementPtr operator->() const { return &*(Parent->begin() + Index); }
+
+    void dumpToStream(llvm::raw_ostream &OS) const {
+      OS << getIndexInBlock() + 1 << ": ";
+      (*this)->dumpToStream(OS);
+    }
+
+    void dump() const {
+      dumpToStream(llvm::errs());
+    }
   };
 
   template <bool IsReverse, bool IsConst> class ElementRefIterator {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D66715: [CFG] Add ... Artem Dergachev via Phabricator via cfe-commits
    • [PATCH] D66715: [CFG]... Kristóf Umann via Phabricator via cfe-commits

Reply via email to