@@ -4999,6 +4999,8 @@ class StmtPrinterHelper : public PrinterHelper {
4999
4999
public:
5000
5000
StmtPrinterHelper (const CFG* cfg, const LangOptions &LO)
5001
5001
: LangOpts(LO) {
5002
+ if (!cfg)
5003
+ return ;
5002
5004
for (CFG::const_iterator I = cfg->begin (), E = cfg->end (); I != E; ++I ) {
5003
5005
unsigned j = 1 ;
5004
5006
for (CFGBlock::const_iterator BI = (*I)->begin (), BEnd = (*I)->end () ;
@@ -5320,10 +5322,22 @@ static void print_construction_context(raw_ostream &OS,
5320
5322
}
5321
5323
}
5322
5324
5325
+ static void print_elem (raw_ostream &OS, StmtPrinterHelper &Helper,
5326
+ const CFGElement &E);
5327
+
5328
+ void CFGElement::dumpToStream (llvm::raw_ostream &OS) const {
5329
+ StmtPrinterHelper Helper (nullptr , {});
5330
+ print_elem (OS, Helper, *this );
5331
+ }
5332
+
5323
5333
static void print_elem (raw_ostream &OS, StmtPrinterHelper &Helper,
5324
5334
const CFGElement &E) {
5325
- if (Optional<CFGStmt> CS = E.getAs <CFGStmt>()) {
5326
- const Stmt *S = CS->getStmt ();
5335
+ switch (E.getKind ()) {
5336
+ case CFGElement::Kind::Statement:
5337
+ case CFGElement::Kind::CXXRecordTypedCall:
5338
+ case CFGElement::Kind::Constructor: {
5339
+ CFGStmt CS = E.castAs <CFGStmt>();
5340
+ const Stmt *S = CS.getStmt ();
5327
5341
assert (S != nullptr && " Expecting non-null Stmt" );
5328
5342
5329
5343
// special printing for statement-expressions.
@@ -5375,12 +5389,18 @@ static void print_elem(raw_ostream &OS, StmtPrinterHelper &Helper,
5375
5389
// Expressions need a newline.
5376
5390
if (isa<Expr>(S))
5377
5391
OS << ' \n ' ;
5378
- } else if (Optional<CFGInitializer> IE = E.getAs <CFGInitializer>()) {
5379
- print_initializer (OS, Helper, IE->getInitializer ());
5392
+
5393
+ break ;
5394
+ }
5395
+
5396
+ case CFGElement::Kind::Initializer:
5397
+ print_initializer (OS, Helper, E.castAs <CFGInitializer>().getInitializer ());
5380
5398
OS << ' \n ' ;
5381
- } else if (Optional<CFGAutomaticObjDtor> DE =
5382
- E.getAs <CFGAutomaticObjDtor>()) {
5383
- const VarDecl *VD = DE->getVarDecl ();
5399
+ break ;
5400
+
5401
+ case CFGElement::Kind::AutomaticObjectDtor: {
5402
+ CFGAutomaticObjDtor DE = E.castAs <CFGAutomaticObjDtor>();
5403
+ const VarDecl *VD = DE.getVarDecl ();
5384
5404
Helper.handleDecl (VD, OS);
5385
5405
5386
5406
QualType T = VD->getType ();
@@ -5390,53 +5410,75 @@ static void print_elem(raw_ostream &OS, StmtPrinterHelper &Helper,
5390
5410
OS << " .~" ;
5391
5411
T.getUnqualifiedType ().print (OS, PrintingPolicy (Helper.getLangOpts ()));
5392
5412
OS << " () (Implicit destructor)\n " ;
5393
- } else if (Optional<CFGLifetimeEnds> DE = E.getAs <CFGLifetimeEnds>()) {
5394
- const VarDecl *VD = DE->getVarDecl ();
5395
- Helper.handleDecl (VD, OS);
5413
+ break ;
5414
+ }
5396
5415
5416
+ case CFGElement::Kind::LifetimeEnds:
5417
+ Helper.handleDecl (E.castAs <CFGLifetimeEnds>().getVarDecl (), OS);
5397
5418
OS << " (Lifetime ends)\n " ;
5398
- } else if (Optional<CFGLoopExit> LE = E.getAs <CFGLoopExit>()) {
5399
- const Stmt *LoopStmt = LE->getLoopStmt ();
5400
- OS << LoopStmt->getStmtClassName () << " (LoopExit)\n " ;
5401
- } else if (Optional<CFGScopeBegin> SB = E.getAs <CFGScopeBegin>()) {
5419
+ break ;
5420
+
5421
+ case CFGElement::Kind::LoopExit:
5422
+ OS << E.castAs <CFGLoopExit>().getLoopStmt ()->getStmtClassName () << " (LoopExit)\n " ;
5423
+ break ;
5424
+
5425
+ case CFGElement::Kind::ScopeBegin:
5402
5426
OS << " CFGScopeBegin(" ;
5403
- if (const VarDecl *VD = SB-> getVarDecl ())
5427
+ if (const VarDecl *VD = E. castAs <CFGScopeBegin>(). getVarDecl ())
5404
5428
OS << VD->getQualifiedNameAsString ();
5405
5429
OS << " )\n " ;
5406
- } else if (Optional<CFGScopeEnd> SE = E.getAs <CFGScopeEnd>()) {
5430
+ break ;
5431
+
5432
+ case CFGElement::Kind::ScopeEnd:
5407
5433
OS << " CFGScopeEnd(" ;
5408
- if (const VarDecl *VD = SE-> getVarDecl ())
5434
+ if (const VarDecl *VD = E. castAs <CFGScopeEnd>(). getVarDecl ())
5409
5435
OS << VD->getQualifiedNameAsString ();
5410
5436
OS << " )\n " ;
5411
- } else if (Optional<CFGNewAllocator> NE = E.getAs <CFGNewAllocator>()) {
5437
+ break ;
5438
+
5439
+ case CFGElement::Kind::NewAllocator:
5412
5440
OS << " CFGNewAllocator(" ;
5413
- if (const CXXNewExpr *AllocExpr = NE-> getAllocatorExpr ())
5441
+ if (const CXXNewExpr *AllocExpr = E. castAs <CFGNewAllocator>(). getAllocatorExpr ())
5414
5442
AllocExpr->getType ().print (OS, PrintingPolicy (Helper.getLangOpts ()));
5415
5443
OS << " )\n " ;
5416
- } else if (Optional<CFGDeleteDtor> DE = E.getAs <CFGDeleteDtor>()) {
5417
- const CXXRecordDecl *RD = DE->getCXXRecordDecl ();
5444
+ break ;
5445
+
5446
+ case CFGElement::Kind::DeleteDtor: {
5447
+ CFGDeleteDtor DE = E.castAs <CFGDeleteDtor>();
5448
+ const CXXRecordDecl *RD = DE.getCXXRecordDecl ();
5418
5449
if (!RD)
5419
5450
return ;
5420
5451
CXXDeleteExpr *DelExpr =
5421
- const_cast <CXXDeleteExpr*>(DE-> getDeleteExpr ());
5452
+ const_cast <CXXDeleteExpr*>(DE. getDeleteExpr ());
5422
5453
Helper.handledStmt (cast<Stmt>(DelExpr->getArgument ()), OS);
5423
5454
OS << " ->~" << RD->getName ().str () << " ()" ;
5424
5455
OS << " (Implicit destructor)\n " ;
5425
- } else if (Optional<CFGBaseDtor> BE = E.getAs <CFGBaseDtor>()) {
5426
- const CXXBaseSpecifier *BS = BE->getBaseSpecifier ();
5456
+ break ;
5457
+ }
5458
+
5459
+ case CFGElement::Kind::BaseDtor: {
5460
+ const CXXBaseSpecifier *BS = E.castAs <CFGBaseDtor>().getBaseSpecifier ();
5427
5461
OS << " ~" << BS->getType ()->getAsCXXRecordDecl ()->getName () << " ()" ;
5428
5462
OS << " (Base object destructor)\n " ;
5429
- } else if (Optional<CFGMemberDtor> ME = E.getAs <CFGMemberDtor>()) {
5430
- const FieldDecl *FD = ME->getFieldDecl ();
5463
+ break ;
5464
+ }
5465
+
5466
+ case CFGElement::Kind::MemberDtor: {
5467
+ const FieldDecl *FD = E.castAs <CFGMemberDtor>().getFieldDecl ();
5431
5468
const Type *T = FD->getType ()->getBaseElementTypeUnsafe ();
5432
5469
OS << " this->" << FD->getName ();
5433
5470
OS << " .~" << T->getAsCXXRecordDecl ()->getName () << " ()" ;
5434
5471
OS << " (Member object destructor)\n " ;
5435
- } else if (Optional<CFGTemporaryDtor> TE = E.getAs <CFGTemporaryDtor>()) {
5436
- const CXXBindTemporaryExpr *BT = TE->getBindTemporaryExpr ();
5472
+ break ;
5473
+ }
5474
+
5475
+ case CFGElement::Kind::TemporaryDtor: {
5476
+ const CXXBindTemporaryExpr *BT = E.castAs <CFGTemporaryDtor>().getBindTemporaryExpr ();
5437
5477
OS << " ~" ;
5438
5478
BT->getType ().print (OS, PrintingPolicy (Helper.getLangOpts ()));
5439
5479
OS << " () (Temporary object destructor)\n " ;
5480
+ break ;
5481
+ }
5440
5482
}
5441
5483
}
5442
5484
0 commit comments