summaryrefslogtreecommitdiffstats
path: root/clang/lib/Analysis/CFG.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Analysis/CFG.cpp')
-rw-r--r--clang/lib/Analysis/CFG.cpp194
1 files changed, 97 insertions, 97 deletions
diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp
index ee64bd2f3fe..d5fde0a8198 100644
--- a/clang/lib/Analysis/CFG.cpp
+++ b/clang/lib/Analysis/CFG.cpp
@@ -133,8 +133,8 @@ private:
CFGBlock *createBlock(bool add_successor = true);
bool FinishBlock(CFGBlock* B);
CFGBlock *addStmt(Stmt *S) { return Visit(S, true); }
-
-
+
+
/// TryResult - a class representing a variant over the values
/// 'true', 'false', or 'unknown'. This is returned by TryEvaluateBool,
/// and is used by the CFGBuilder to decide if a branch condition
@@ -144,7 +144,7 @@ private:
public:
TryResult(bool b) : X(b ? 1 : 0) {}
TryResult() : X(-1) {}
-
+
bool isTrue() const { return X == 1; }
bool isFalse() const { return X == 0; }
bool isKnown() const { return X >= 0; }
@@ -153,7 +153,7 @@ private:
X ^= 0x1;
}
};
-
+
/// TryEvaluateBool - Try and evaluate the Stmt and return 0 or 1
/// if we can evaluate to a known value, otherwise return -1.
TryResult TryEvaluateBool(Expr *S) {
@@ -292,109 +292,109 @@ tryAgain:
case Stmt::AddrLabelExprClass:
return VisitAddrLabelExpr(cast<AddrLabelExpr>(S), alwaysAdd);
-
+
case Stmt::BinaryOperatorClass:
return VisitBinaryOperator(cast<BinaryOperator>(S), alwaysAdd);
-
+
case Stmt::BlockExprClass:
return VisitBlockExpr(cast<BlockExpr>(S), alwaysAdd);
case Stmt::BlockDeclRefExprClass:
return VisitBlockDeclRefExpr(cast<BlockDeclRefExpr>(S), alwaysAdd);
-
+
case Stmt::BreakStmtClass:
return VisitBreakStmt(cast<BreakStmt>(S));
-
+
case Stmt::CallExprClass:
return VisitCallExpr(cast<CallExpr>(S), alwaysAdd);
-
+
case Stmt::CaseStmtClass:
return VisitCaseStmt(cast<CaseStmt>(S));
case Stmt::ChooseExprClass:
return VisitChooseExpr(cast<ChooseExpr>(S));
-
+
case Stmt::CompoundStmtClass:
return VisitCompoundStmt(cast<CompoundStmt>(S));
-
+
case Stmt::ConditionalOperatorClass:
return VisitConditionalOperator(cast<ConditionalOperator>(S));
-
+
case Stmt::ContinueStmtClass:
return VisitContinueStmt(cast<ContinueStmt>(S));
-
+
case Stmt::DeclStmtClass:
return VisitDeclStmt(cast<DeclStmt>(S));
-
+
case Stmt::DefaultStmtClass:
return VisitDefaultStmt(cast<DefaultStmt>(S));
-
+
case Stmt::DoStmtClass:
return VisitDoStmt(cast<DoStmt>(S));
-
+
case Stmt::ForStmtClass:
return VisitForStmt(cast<ForStmt>(S));
-
+
case Stmt::GotoStmtClass:
return VisitGotoStmt(cast<GotoStmt>(S));
-
+
case Stmt::IfStmtClass:
return VisitIfStmt(cast<IfStmt>(S));
-
+
case Stmt::IndirectGotoStmtClass:
return VisitIndirectGotoStmt(cast<IndirectGotoStmt>(S));
-
+
case Stmt::LabelStmtClass:
return VisitLabelStmt(cast<LabelStmt>(S));
-
+
case Stmt::ObjCAtCatchStmtClass:
- return VisitObjCAtCatchStmt(cast<ObjCAtCatchStmt>(S));
-
+ return VisitObjCAtCatchStmt(cast<ObjCAtCatchStmt>(S));
+
case Stmt::CXXThrowExprClass:
return VisitCXXThrowExpr(cast<CXXThrowExpr>(S));
case Stmt::ObjCAtSynchronizedStmtClass:
return VisitObjCAtSynchronizedStmt(cast<ObjCAtSynchronizedStmt>(S));
-
+
case Stmt::ObjCAtThrowStmtClass:
return VisitObjCAtThrowStmt(cast<ObjCAtThrowStmt>(S));
-
+
case Stmt::ObjCAtTryStmtClass:
return VisitObjCAtTryStmt(cast<ObjCAtTryStmt>(S));
-
+
case Stmt::ObjCForCollectionStmtClass:
return VisitObjCForCollectionStmt(cast<ObjCForCollectionStmt>(S));
-
+
case Stmt::ParenExprClass:
S = cast<ParenExpr>(S)->getSubExpr();
- goto tryAgain;
-
+ goto tryAgain;
+
case Stmt::NullStmtClass:
return Block;
-
+
case Stmt::ReturnStmtClass:
return VisitReturnStmt(cast<ReturnStmt>(S));
-
+
case Stmt::SizeOfAlignOfExprClass:
- return VisitSizeOfAlignOfExpr(cast<SizeOfAlignOfExpr>(S), alwaysAdd);
-
+ return VisitSizeOfAlignOfExpr(cast<SizeOfAlignOfExpr>(S), alwaysAdd);
+
case Stmt::StmtExprClass:
return VisitStmtExpr(cast<StmtExpr>(S), alwaysAdd);
-
+
case Stmt::SwitchStmtClass:
return VisitSwitchStmt(cast<SwitchStmt>(S));
-
+
case Stmt::WhileStmtClass:
return VisitWhileStmt(cast<WhileStmt>(S));
}
}
-
+
CFGBlock *CFGBuilder::VisitStmt(Stmt *S, bool alwaysAdd) {
if (alwaysAdd) {
autoCreateBlock();
Block->appendStmt(S);
}
-
+
return VisitChildren(S);
}
@@ -407,7 +407,7 @@ CFGBlock *CFGBuilder::VisitChildren(Stmt* Terminator) {
}
return B;
}
-
+
CFGBlock *CFGBuilder::VisitAddrLabelExpr(AddrLabelExpr *A, bool alwaysAdd) {
AddressTakenLabels.insert(A->getLabel());
@@ -418,26 +418,26 @@ CFGBlock *CFGBuilder::VisitAddrLabelExpr(AddrLabelExpr *A, bool alwaysAdd) {
return Block;
}
-
+
CFGBlock *CFGBuilder::VisitBinaryOperator(BinaryOperator *B, bool alwaysAdd) {
if (B->isLogicalOp()) { // && or ||
CFGBlock* ConfluenceBlock = Block ? Block : createBlock();
ConfluenceBlock->appendStmt(B);
-
+
if (!FinishBlock(ConfluenceBlock))
return 0;
-
+
// create the block evaluating the LHS
CFGBlock* LHSBlock = createBlock(false);
LHSBlock->setTerminator(B);
-
+
// create the block evaluating the RHS
Succ = ConfluenceBlock;
Block = NULL;
CFGBlock* RHSBlock = addStmt(B->getRHS());
if (!FinishBlock(RHSBlock))
return 0;
-
+
// See if this is a known constant.
TryResult KnownVal = TryEvaluateBool(B->getLHS());
if (KnownVal.isKnown() && (B->getOpcode() == BinaryOperator::LOr))
@@ -447,23 +447,23 @@ CFGBlock *CFGBuilder::VisitBinaryOperator(BinaryOperator *B, bool alwaysAdd) {
if (B->getOpcode() == BinaryOperator::LOr) {
LHSBlock->addSuccessor(KnownVal.isTrue() ? NULL : ConfluenceBlock);
LHSBlock->addSuccessor(KnownVal.isFalse() ? NULL : RHSBlock);
- } else {
+ } else {
assert (B->getOpcode() == BinaryOperator::LAnd);
LHSBlock->addSuccessor(KnownVal.isFalse() ? NULL : RHSBlock);
LHSBlock->addSuccessor(KnownVal.isTrue() ? NULL : ConfluenceBlock);
}
-
+
// Generate the blocks for evaluating the LHS.
Block = LHSBlock;
return addStmt(B->getLHS());
- }
+ }
else if (B->getOpcode() == BinaryOperator::Comma) { // ,
autoCreateBlock();
Block->appendStmt(B);
addStmt(B->getRHS());
return addStmt(B->getLHS());
}
-
+
return VisitStmt(B, alwaysAdd);
}
@@ -477,28 +477,28 @@ CFGBlock *CFGBuilder::VisitBlockDeclRefExpr(BlockDeclRefExpr* E,
// FIXME
return NYS();
}
-
+
CFGBlock *CFGBuilder::VisitBreakStmt(BreakStmt *B) {
// "break" is a control-flow statement. Thus we stop processing the current
// block.
if (Block && !FinishBlock(Block))
return 0;
-
+
// Now create a new block that ends with the break statement.
Block = createBlock(false);
Block->setTerminator(B);
-
+
// If there is no target for the break, then we are looking at an incomplete
// AST. This means that the CFG cannot be constructed.
if (BreakTargetBlock)
Block->addSuccessor(BreakTargetBlock);
else
badCFG = true;
-
-
+
+
return Block;
}
-
+
CFGBlock *CFGBuilder::VisitCallExpr(CallExpr *C, bool alwaysAdd) {
// If this is a call to a no-return function, this stops the block here.
bool NoReturn = false;
@@ -512,17 +512,17 @@ CFGBlock *CFGBuilder::VisitCallExpr(CallExpr *C, bool alwaysAdd) {
if (!NoReturn)
return VisitStmt(C, alwaysAdd);
-
+
if (Block && !FinishBlock(Block))
return 0;
-
+
// Create new block with no successor for the remaining pieces.
Block = createBlock(false);
Block->appendStmt(C);
// Wire this to the exit block directly.
Block->addSuccessor(&cfg->getExit());
-
+
return VisitChildren(C);
}
@@ -531,42 +531,42 @@ CFGBlock *CFGBuilder::VisitChooseExpr(ChooseExpr *C) {
ConfluenceBlock->appendStmt(C);
if (!FinishBlock(ConfluenceBlock))
return 0;
-
+
Succ = ConfluenceBlock;
Block = NULL;
CFGBlock* LHSBlock = addStmt(C->getLHS());
if (!FinishBlock(LHSBlock))
return 0;
-
+
Succ = ConfluenceBlock;
Block = NULL;
CFGBlock* RHSBlock = addStmt(C->getRHS());
if (!FinishBlock(RHSBlock))
return 0;
-
+
Block = createBlock(false);
// See if this is a known constant.
const TryResult& KnownVal = TryEvaluateBool(C->getCond());
Block->addSuccessor(KnownVal.isFalse() ? NULL : LHSBlock);
Block->addSuccessor(KnownVal.isTrue() ? NULL : RHSBlock);
Block->setTerminator(C);
- return addStmt(C->getCond());
+ return addStmt(C->getCond());
}
-
-
-CFGBlock* CFGBuilder::VisitCompoundStmt(CompoundStmt* C) {
- CFGBlock* LastBlock = Block;
+
+
+CFGBlock* CFGBuilder::VisitCompoundStmt(CompoundStmt* C) {
+ CFGBlock* LastBlock = Block;
for (CompoundStmt::reverse_body_iterator I=C->body_rbegin(), E=C->body_rend();
I != E; ++I ) {
LastBlock = addStmt(*I);
-
+
if (badCFG)
return NULL;
- }
+ }
return LastBlock;
}
-
+
CFGBlock *CFGBuilder::VisitConditionalOperator(ConditionalOperator *C) {
// Create the confluence block that will "merge" the results of the ternary
// expression.
@@ -574,7 +574,7 @@ CFGBlock *CFGBuilder::VisitConditionalOperator(ConditionalOperator *C) {
ConfluenceBlock->appendStmt(C);
if (!FinishBlock(ConfluenceBlock))
return 0;
-
+
// Create a block for the LHS expression if there is an LHS expression. A
// GCC extension allows LHS to be NULL, causing the condition to be the
// value that is returned instead.
@@ -588,16 +588,16 @@ CFGBlock *CFGBuilder::VisitConditionalOperator(ConditionalOperator *C) {
return 0;
Block = NULL;
}
-
+
// Create the block for the RHS expression.
Succ = ConfluenceBlock;
CFGBlock* RHSBlock = addStmt(C->getRHS());
if (!FinishBlock(RHSBlock))
return 0;
-
+
// Create the block that will contain the condition.
Block = createBlock(false);
-
+
// See if this is a known constant.
const TryResult& KnownVal = TryEvaluateBool(C->getCond());
if (LHSBlock) {
@@ -622,8 +622,8 @@ CFGBlock *CFGBuilder::VisitConditionalOperator(ConditionalOperator *C) {
ConfluenceBlock->pred_end());
}
}
-
- Block->addSuccessor(KnownVal.isTrue() ? NULL : RHSBlock);
+
+ Block->addSuccessor(KnownVal.isTrue() ? NULL : RHSBlock);
Block->setTerminator(C);
return addStmt(C->getCond());
}
@@ -635,45 +635,45 @@ CFGBlock *CFGBuilder::VisitDeclStmt(DeclStmt *DS) {
Block->appendStmt(DS);
return VisitDeclSubExpr(DS->getSingleDecl());
}
-
+
CFGBlock *B = 0;
-
+
// FIXME: Add a reverse iterator for DeclStmt to avoid this extra copy.
typedef llvm::SmallVector<Decl*,10> BufTy;
BufTy Buf(DS->decl_begin(), DS->decl_end());
-
+
for (BufTy::reverse_iterator I = Buf.rbegin(), E = Buf.rend(); I != E; ++I) {
// Get the alignment of the new DeclStmt, padding out to >=8 bytes.
unsigned A = llvm::AlignOf<DeclStmt>::Alignment < 8
? 8 : llvm::AlignOf<DeclStmt>::Alignment;
-
+
// Allocate the DeclStmt using the BumpPtrAllocator. It will get
// automatically freed with the CFG.
DeclGroupRef DG(*I);
Decl *D = *I;
- void *Mem = cfg->getAllocator().Allocate(sizeof(DeclStmt), A);
+ void *Mem = cfg->getAllocator().Allocate(sizeof(DeclStmt), A);
DeclStmt *DSNew = new (Mem) DeclStmt(DG, D->getLocation(), GetEndLoc(D));
-
+
// Append the fake DeclStmt to block.
Block->appendStmt(DSNew);
B = VisitDeclSubExpr(D);
}
-
- return B;
+
+ return B;
}
-
+
/// VisitDeclSubExpr - Utility method to add block-level expressions for
/// initializers in Decls.
CFGBlock *CFGBuilder::VisitDeclSubExpr(Decl* D) {
assert(Block);
VarDecl *VD = dyn_cast<VarDecl>(D);
-
+
if (!VD)
return Block;
-
+
Expr *Init = VD->getInit();
-
+
if (Init) {
// Optimization: Don't create separate block-level statements for literals.
switch (Init->getStmtClass()) {
@@ -685,12 +685,12 @@ CFGBlock *CFGBuilder::VisitDeclSubExpr(Decl* D) {
Block = addStmt(Init);
}
}
-
+
// If the type of VD is a VLA, then we must process its size expressions.
for (VariableArrayType* VA = FindVA(VD->getType().getTypePtr()); VA != 0;
VA = FindVA(VA->getElementType().getTypePtr()))
Block = addStmt(VA->getSizeExpr());
-
+
return Block;
}
@@ -879,7 +879,7 @@ CFGBlock* CFGBuilder::VisitForStmt(ForStmt* F) {
// See if this is a known constant.
TryResult KnownVal(true);
-
+
if (F->getCond())
KnownVal = TryEvaluateBool(F->getCond());
@@ -1171,8 +1171,8 @@ CFGBlock* CFGBuilder::VisitWhileStmt(WhileStmt* W) {
Succ = EntryConditionBlock;
return EntryConditionBlock;
}
-
-
+
+
CFGBlock *CFGBuilder::VisitObjCAtCatchStmt(ObjCAtCatchStmt* S) {
// FIXME: For now we pretend that @catch and the code it contains does not
// exit.
@@ -1329,7 +1329,7 @@ CFGBlock* CFGBuilder::VisitContinueStmt(ContinueStmt* C) {
return Block;
}
-
+
CFGBlock *CFGBuilder::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E,
bool alwaysAdd) {
@@ -1337,17 +1337,17 @@ CFGBlock *CFGBuilder::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E,
autoCreateBlock();
Block->appendStmt(E);
}
-
+
// VLA types have expressions that must be evaluated.
if (E->isArgumentType()) {
for (VariableArrayType* VA = FindVA(E->getArgumentType().getTypePtr());
VA != 0; VA = FindVA(VA->getElementType().getTypePtr()))
addStmt(VA->getSizeExpr());
}
-
+
return Block;
}
-
+
/// VisitStmtExpr - Utility method to handle (nested) statement
/// expressions (a GCC extension).
CFGBlock* CFGBuilder::VisitStmtExpr(StmtExpr *SE, bool alwaysAdd) {
@@ -1416,7 +1416,7 @@ CFGBlock* CFGBuilder::VisitCaseStmt(CaseStmt* CS) {
if (CS->getSubStmt())
addStmt(CS->getSubStmt());
-
+
CFGBlock* CaseBlock = Block;
if (!CaseBlock)
CaseBlock = createBlock();
@@ -1445,7 +1445,7 @@ CFGBlock* CFGBuilder::VisitCaseStmt(CaseStmt* CS) {
CFGBlock* CFGBuilder::VisitDefaultStmt(DefaultStmt* Terminator) {
if (Terminator->getSubStmt())
addStmt(Terminator->getSubStmt());
-
+
DefaultCaseBlock = Block;
if (!DefaultCaseBlock)
@@ -1454,7 +1454,7 @@ CFGBlock* CFGBuilder::VisitDefaultStmt(DefaultStmt* Terminator) {
// Default statements partition blocks, so this is the top of the basic block
// we were processing (the "default:" is the label).
DefaultCaseBlock->setLabel(Terminator);
-
+
if (!FinishBlock(DefaultCaseBlock))
return 0;
OpenPOWER on IntegriCloud