aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Analysis/CFG.cpp40
1 files changed, 34 insertions, 6 deletions
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp
index 047568a32a..4eac9ae351 100644
--- a/lib/Analysis/CFG.cpp
+++ b/lib/Analysis/CFG.cpp
@@ -304,7 +304,7 @@ private:
CFGBlock *addStmt(Stmt *S) {
return Visit(S, AddStmtChoice::AlwaysAdd);
}
-
+ CFGBlock *addInitializer(CXXBaseOrMemberInitializer *I);
void addAutomaticObjDtors(LocalScope::const_iterator B,
LocalScope::const_iterator E, Stmt* S);
@@ -322,6 +322,9 @@ private:
AddStmtChoice asc = AddStmtChoice::AlwaysAdd) {
B->appendStmt(S, cfg->getBumpVectorContext(), asc.asLValue());
}
+ void appendInitializer(CFGBlock *B, CXXBaseOrMemberInitializer *I) {
+ B->appendInitializer(I, cfg->getBumpVectorContext());
+ }
void insertAutomaticObjDtors(CFGBlock* Blk, CFGBlock::iterator I,
LocalScope::const_iterator B, LocalScope::const_iterator E, Stmt* S);
@@ -410,14 +413,19 @@ CFG* CFGBuilder::buildCFG(const Decl *D, Stmt* Statement, ASTContext* C,
if (badCFG)
return NULL;
- if (B)
- Succ = B;
-
+ // For C++ constructor add initializers to CFG.
if (const CXXConstructorDecl *CD = dyn_cast_or_null<CXXConstructorDecl>(D)) {
- // FIXME: Add code for base initializers and member initializers.
- (void)CD;
+ for (CXXConstructorDecl::init_const_reverse_iterator I = CD->init_rbegin(),
+ E = CD->init_rend(); I != E; ++I) {
+ B = addInitializer(*I);
+ if (badCFG)
+ return NULL;
+ }
}
+ if (B)
+ Succ = B;
+
// Backpatch the gotos whose label -> block mappings we didn't know when we
// encountered them.
for (BackpatchBlocksTy::iterator I = BackpatchBlocks.begin(),
@@ -466,6 +474,26 @@ CFGBlock* CFGBuilder::createBlock(bool add_successor) {
return B;
}
+/// addInitializer - Add C++ base or member initializer element to CFG.
+CFGBlock *CFGBuilder::addInitializer(CXXBaseOrMemberInitializer *I) {
+ if (!BuildOpts.AddInitializers)
+ return Block;
+
+ autoCreateBlock();
+ appendInitializer(Block, I);
+
+ if (Expr *Init = I->getInit()) {
+ AddStmtChoice::Kind K = AddStmtChoice::NotAlwaysAdd;
+ if (FieldDecl *FD = I->getMember())
+ if (FD->getType()->isReferenceType())
+ K = AddStmtChoice::AsLValueNotAlwaysAdd;
+
+ return Visit(Init, AddStmtChoice(K));
+ }
+
+ return Block;
+}
+
/// addAutomaticObjDtors - Add to current block automatic objects destructors
/// for objects in range of local scope positions. Use S as trigger statement
/// for destructors.