Skip to content
Snippets Groups Projects
Commit fd8d8ca2 authored by Ted Kremenek's avatar Ted Kremenek
Browse files

Removed DataflowStmtVisitor. It is no longer used, and is obsoleted

by newer visitor interfaces.

llvm-svn: 42662
parent 1151ffde
No related branches found
No related tags found
No related merge requests found
//===--- DataFlowStmtVisitor.h - StmtVisitor for Dataflow -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by Ted Kremenek and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the DataflowStmtVisitor interface, which extends
// CFGStmtVisitor. This interface is useful for visiting statements in a CFG
// with the understanding that statements are walked in order of the analysis
// traversal.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_ANALYSIS_DATAFLOW_STMTVISITOR_H
#define LLVM_CLANG_ANALYSIS_DATAFLOW_STMTVISITOR_H
#include "clang/Analysis/Visitors/CFGStmtVisitor.h"
namespace clang {
// Tag classes describing what direction the dataflow analysis goes.
namespace dataflow {
struct forward_analysis_tag {};
struct backward_analysis_tag {};
}
template < typename ImplClass,
typename AnalysisTag=dataflow::forward_analysis_tag >
class DataflowStmtVisitor : public CFGStmtVisitor<ImplClass,void> {
public:
//===--------------------------------------------------------------------===//
// Observer methods. These are called before a statement is visited, and
// there is no special dispatch on statement type. This allows subclasses
// to inject extra functionality (e.g. monitoring) that applies to all
// visited statements.
//===--------------------------------------------------------------------===//
void ObserveStmt(Stmt* S) {}
void ObserveBlockStmt(Stmt* S) {
static_cast<ImplClass*>(this)->ObserveStmt(S);
}
//===--------------------------------------------------------------------===//
// Statment visitor methods. These modify the behavior of CFGVisitor::Visit
// and CFGVisitor::BlockStmt_Visit by performing a traversal of substatements
// depending on the direction of the dataflow analysis. For forward
// analyses, the traversal is postorder (representing evaluation order)
// and for backward analysis it is preorder (reverse-evaluation order).
//===--------------------------------------------------------------------===//
void BlockStmt_Visit(Stmt* S) { BlockStmt_Visit(S,AnalysisTag()); }
void BlockStmt_Visit(Stmt* S, dataflow::forward_analysis_tag) {
// Process statements in a postorder traversal of the AST.
if (!CFG::hasImplicitControlFlow(S) ||
S->getStmtClass() == Stmt::CallExprClass)
static_cast<ImplClass*>(this)->VisitChildren(S);
static_cast<ImplClass*>(this)->ObserveBlockStmt(S);
static_cast<CFGStmtVisitor<ImplClass,void>*>(this)->BlockStmt_Visit(S);
}
void BlockStmt_Visit(Stmt* S, dataflow::backward_analysis_tag) {
// Process statements in a preorder traversal of the AST.
static_cast<ImplClass*>(this)->ObserveBlockStmt(S);
static_cast<CFGStmtVisitor<ImplClass,void>*>(this)->BlockStmt_Visit(S);
if (!CFG::hasImplicitControlFlow(S) ||
S->getStmtClass() == Stmt::CallExprClass)
static_cast<ImplClass*>(this)->VisitChildren(S);
}
void Visit(Stmt* S) { Visit(S,AnalysisTag()); }
void Visit(Stmt* S, dataflow::forward_analysis_tag) {
if (CFG::hasImplicitControlFlow(S))
return;
// Process statements in a postorder traversal of the AST.
static_cast<ImplClass*>(this)->VisitChildren(S);
static_cast<ImplClass*>(this)->ObserveStmt(S);
static_cast<CFGStmtVisitor<ImplClass,void>*>(this)->Visit(S);
}
void Visit(Stmt* S, dataflow::backward_analysis_tag) {
if (CFG::hasImplicitControlFlow(S))
return;
// Process statements in a preorder traversal of the AST.
static_cast<ImplClass*>(this)->ObserveStmt(S);
static_cast<CFGStmtVisitor<ImplClass,void>*>(this)->Visit(S);
static_cast<ImplClass*>(this)->VisitChildren(S);
}
//===--------------------------------------------------------------------===//
// Methods for visiting entire CFGBlocks.
//===--------------------------------------------------------------------===//
void VisitBlockEntry(const CFGBlock* B) {}
void VisitBlockExit(const CFGBlock* B) {}
void VisitBlock(const CFGBlock* B) { VisitBlock(B,AnalysisTag()); }
void VisitBlock(const CFGBlock* B, dataflow::forward_analysis_tag ) {
static_cast<ImplClass*>(this)->VisitBlockEntry(B);
for (CFGBlock::const_iterator I=B->begin(), E=B->end(); I!=E; ++I)
static_cast<ImplClass*>(this)->BlockStmt_Visit(const_cast<Stmt*>(*I));
static_cast<ImplClass*>(this)->VisitBlockExit(B);
}
void VisitBlock(const CFGBlock* B, dataflow::backward_analysis_tag ) {
static_cast<ImplClass*>(this)->VisitBlockExit(B);
for (CFGBlock::const_reverse_iterator I=B->rbegin(), E=B->rend(); I!=E; ++I)
static_cast<ImplClass*>(this)->BlockStmt_Visit(const_cast<Stmt*>(*I));
static_cast<ImplClass*>(this)->VisitBlockEntry(B);
}
};
} // end namespace clang
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment