forked from OSchip/llvm-project
Require AddStmtChoice::alwaysAdd() to take a CFGBuilder& and Stmt*. Prep for functionality changes.
llvm-svn: 127387
This commit is contained in:
parent
2866bab5fa
commit
7c58d35240
|
@ -36,6 +36,8 @@ static SourceLocation GetEndLoc(Decl* D) {
|
||||||
return D->getLocation();
|
return D->getLocation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class CFGBuilder;
|
||||||
|
|
||||||
/// The CFG builder uses a recursive algorithm to build the CFG. When
|
/// The CFG builder uses a recursive algorithm to build the CFG. When
|
||||||
/// we process an expression, sometimes we know that we must add the
|
/// we process an expression, sometimes we know that we must add the
|
||||||
/// subexpressions as block-level expressions. For example:
|
/// subexpressions as block-level expressions. For example:
|
||||||
|
@ -55,13 +57,13 @@ public:
|
||||||
|
|
||||||
AddStmtChoice(Kind a_kind = NotAlwaysAdd) : kind(a_kind) {}
|
AddStmtChoice(Kind a_kind = NotAlwaysAdd) : kind(a_kind) {}
|
||||||
|
|
||||||
bool alwaysAdd() const { return kind & AlwaysAdd; }
|
bool alwaysAdd(CFGBuilder &builder,
|
||||||
|
const Stmt *stmt) const;
|
||||||
|
|
||||||
/// Return a copy of this object, except with the 'always-add' bit
|
/// Return a copy of this object, except with the 'always-add' bit
|
||||||
/// set as specified.
|
/// set as specified.
|
||||||
AddStmtChoice withAlwaysAdd(bool alwaysAdd) const {
|
AddStmtChoice withAlwaysAdd(bool alwaysAdd) const {
|
||||||
return AddStmtChoice(alwaysAdd ? Kind(kind | AlwaysAdd) :
|
return AddStmtChoice(alwaysAdd ? AlwaysAdd : NotAlwaysAdd);
|
||||||
Kind(kind & ~AlwaysAdd));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -441,6 +443,11 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool AddStmtChoice::alwaysAdd(CFGBuilder &builder,
|
||||||
|
const Stmt *stmt) const {
|
||||||
|
return kind == AlwaysAdd;
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: Add support for dependent-sized array types in C++?
|
// FIXME: Add support for dependent-sized array types in C++?
|
||||||
// Does it even make sense to build a CFG for an uninstantiated template?
|
// Does it even make sense to build a CFG for an uninstantiated template?
|
||||||
static const VariableArrayType *FindVA(const Type *t) {
|
static const VariableArrayType *FindVA(const Type *t) {
|
||||||
|
@ -934,7 +941,7 @@ tryAgain:
|
||||||
}
|
}
|
||||||
|
|
||||||
CFGBlock *CFGBuilder::VisitStmt(Stmt *S, AddStmtChoice asc) {
|
CFGBlock *CFGBuilder::VisitStmt(Stmt *S, AddStmtChoice asc) {
|
||||||
if (asc.alwaysAdd()) {
|
if (asc.alwaysAdd(*this, S)) {
|
||||||
autoCreateBlock();
|
autoCreateBlock();
|
||||||
appendStmt(Block, S);
|
appendStmt(Block, S);
|
||||||
}
|
}
|
||||||
|
@ -957,7 +964,7 @@ CFGBlock *CFGBuilder::VisitAddrLabelExpr(AddrLabelExpr *A,
|
||||||
AddStmtChoice asc) {
|
AddStmtChoice asc) {
|
||||||
AddressTakenLabels.insert(A->getLabel());
|
AddressTakenLabels.insert(A->getLabel());
|
||||||
|
|
||||||
if (asc.alwaysAdd()) {
|
if (asc.alwaysAdd(*this, A)) {
|
||||||
autoCreateBlock();
|
autoCreateBlock();
|
||||||
appendStmt(Block, A);
|
appendStmt(Block, A);
|
||||||
}
|
}
|
||||||
|
@ -967,7 +974,7 @@ CFGBlock *CFGBuilder::VisitAddrLabelExpr(AddrLabelExpr *A,
|
||||||
|
|
||||||
CFGBlock *CFGBuilder::VisitUnaryOperator(UnaryOperator *U,
|
CFGBlock *CFGBuilder::VisitUnaryOperator(UnaryOperator *U,
|
||||||
AddStmtChoice asc) {
|
AddStmtChoice asc) {
|
||||||
if (asc.alwaysAdd()) {
|
if (asc.alwaysAdd(*this, U)) {
|
||||||
autoCreateBlock();
|
autoCreateBlock();
|
||||||
appendStmt(Block, U);
|
appendStmt(Block, U);
|
||||||
}
|
}
|
||||||
|
@ -1030,7 +1037,7 @@ CFGBlock *CFGBuilder::VisitBinaryOperator(BinaryOperator *B,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (B->isAssignmentOp()) {
|
if (B->isAssignmentOp()) {
|
||||||
if (asc.alwaysAdd()) {
|
if (asc.alwaysAdd(*this, B)) {
|
||||||
autoCreateBlock();
|
autoCreateBlock();
|
||||||
appendStmt(Block, B);
|
appendStmt(Block, B);
|
||||||
}
|
}
|
||||||
|
@ -1038,7 +1045,7 @@ CFGBlock *CFGBuilder::VisitBinaryOperator(BinaryOperator *B,
|
||||||
return Visit(B->getRHS());
|
return Visit(B->getRHS());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (asc.alwaysAdd()) {
|
if (asc.alwaysAdd(*this, B)) {
|
||||||
autoCreateBlock();
|
autoCreateBlock();
|
||||||
appendStmt(Block, B);
|
appendStmt(Block, B);
|
||||||
}
|
}
|
||||||
|
@ -1052,7 +1059,7 @@ CFGBlock *CFGBuilder::VisitBinaryOperator(BinaryOperator *B,
|
||||||
}
|
}
|
||||||
|
|
||||||
CFGBlock *CFGBuilder::VisitBlockExpr(BlockExpr *E, AddStmtChoice asc) {
|
CFGBlock *CFGBuilder::VisitBlockExpr(BlockExpr *E, AddStmtChoice asc) {
|
||||||
if (asc.alwaysAdd()) {
|
if (asc.alwaysAdd(*this, E)) {
|
||||||
autoCreateBlock();
|
autoCreateBlock();
|
||||||
appendStmt(Block, E);
|
appendStmt(Block, E);
|
||||||
}
|
}
|
||||||
|
@ -1680,7 +1687,7 @@ CFGBlock* CFGBuilder::VisitForStmt(ForStmt* F) {
|
||||||
}
|
}
|
||||||
|
|
||||||
CFGBlock *CFGBuilder::VisitMemberExpr(MemberExpr *M, AddStmtChoice asc) {
|
CFGBlock *CFGBuilder::VisitMemberExpr(MemberExpr *M, AddStmtChoice asc) {
|
||||||
if (asc.alwaysAdd()) {
|
if (asc.alwaysAdd(*this, M)) {
|
||||||
autoCreateBlock();
|
autoCreateBlock();
|
||||||
appendStmt(Block, M);
|
appendStmt(Block, M);
|
||||||
}
|
}
|
||||||
|
@ -2116,7 +2123,7 @@ CFGBlock* CFGBuilder::VisitContinueStmt(ContinueStmt* C) {
|
||||||
CFGBlock *CFGBuilder::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E,
|
CFGBlock *CFGBuilder::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E,
|
||||||
AddStmtChoice asc) {
|
AddStmtChoice asc) {
|
||||||
|
|
||||||
if (asc.alwaysAdd()) {
|
if (asc.alwaysAdd(*this, E)) {
|
||||||
autoCreateBlock();
|
autoCreateBlock();
|
||||||
appendStmt(Block, E);
|
appendStmt(Block, E);
|
||||||
}
|
}
|
||||||
|
@ -2134,7 +2141,7 @@ CFGBlock *CFGBuilder::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E,
|
||||||
/// VisitStmtExpr - Utility method to handle (nested) statement
|
/// VisitStmtExpr - Utility method to handle (nested) statement
|
||||||
/// expressions (a GCC extension).
|
/// expressions (a GCC extension).
|
||||||
CFGBlock* CFGBuilder::VisitStmtExpr(StmtExpr *SE, AddStmtChoice asc) {
|
CFGBlock* CFGBuilder::VisitStmtExpr(StmtExpr *SE, AddStmtChoice asc) {
|
||||||
if (asc.alwaysAdd()) {
|
if (asc.alwaysAdd(*this, SE)) {
|
||||||
autoCreateBlock();
|
autoCreateBlock();
|
||||||
appendStmt(Block, SE);
|
appendStmt(Block, SE);
|
||||||
}
|
}
|
||||||
|
@ -2471,7 +2478,7 @@ CFGBlock *CFGBuilder::VisitExprWithCleanups(ExprWithCleanups *E,
|
||||||
|
|
||||||
CFGBlock *CFGBuilder::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E,
|
CFGBlock *CFGBuilder::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E,
|
||||||
AddStmtChoice asc) {
|
AddStmtChoice asc) {
|
||||||
if (asc.alwaysAdd()) {
|
if (asc.alwaysAdd(*this, E)) {
|
||||||
autoCreateBlock();
|
autoCreateBlock();
|
||||||
appendStmt(Block, E);
|
appendStmt(Block, E);
|
||||||
|
|
||||||
|
@ -2492,7 +2499,7 @@ CFGBlock *CFGBuilder::VisitCXXConstructExpr(CXXConstructExpr *C,
|
||||||
|
|
||||||
CFGBlock *CFGBuilder::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E,
|
CFGBlock *CFGBuilder::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E,
|
||||||
AddStmtChoice asc) {
|
AddStmtChoice asc) {
|
||||||
if (asc.alwaysAdd()) {
|
if (asc.alwaysAdd(*this, E)) {
|
||||||
autoCreateBlock();
|
autoCreateBlock();
|
||||||
appendStmt(Block, E);
|
appendStmt(Block, E);
|
||||||
// We do not want to propagate the AlwaysAdd property.
|
// We do not want to propagate the AlwaysAdd property.
|
||||||
|
@ -2517,7 +2524,7 @@ CFGBlock *CFGBuilder::VisitCXXMemberCallExpr(CXXMemberCallExpr *C,
|
||||||
|
|
||||||
CFGBlock *CFGBuilder::VisitImplicitCastExpr(ImplicitCastExpr *E,
|
CFGBlock *CFGBuilder::VisitImplicitCastExpr(ImplicitCastExpr *E,
|
||||||
AddStmtChoice asc) {
|
AddStmtChoice asc) {
|
||||||
if (asc.alwaysAdd()) {
|
if (asc.alwaysAdd(*this, E)) {
|
||||||
autoCreateBlock();
|
autoCreateBlock();
|
||||||
appendStmt(Block, E);
|
appendStmt(Block, E);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue