[cfe-commits] r115237 - /cfe/trunk/lib/Analysis/CFG.cpp
Marcin Swiderski
marcin.sfider at gmail.com
Thu Sep 30 16:05:01 PDT 2010
Author: sfider
Date: Thu Sep 30 18:05:00 2010
New Revision: 115237
URL: http://llvm.org/viewvc/llvm-project?rev=115237&view=rev
Log:
Added methods for adding LocalScopes and CFGAutomaticObjDtors.
Modified:
cfe/trunk/lib/Analysis/CFG.cpp
Modified: cfe/trunk/lib/Analysis/CFG.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFG.cpp?rev=115237&r1=115236&r2=115237&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CFG.cpp (original)
+++ cfe/trunk/lib/Analysis/CFG.cpp Thu Sep 30 18:05:00 2010
@@ -304,7 +304,19 @@
CFGBlock *addStmt(Stmt *S) {
return Visit(S, AddStmtChoice::AlwaysAdd);
}
+ CFGBlock *addAutomaticObjDtors(LocalScope::const_iterator B,
+ LocalScope::const_iterator E, Stmt* S);
+
+ // Local scopes creation.
+ LocalScope* createOrReuseLocalScope(LocalScope* Scope);
+
+ LocalScope* addLocalScopeForStmt(Stmt* S, LocalScope* Scope = NULL);
+ LocalScope* addLocalScopeForDeclStmt(DeclStmt* DS, LocalScope* Scope = NULL);
+ LocalScope* addLocalScopeForVarDecl(VarDecl* VD, LocalScope* Scope = NULL);
+
+ void addLocalScopeAndDtors(Stmt* S);
+ // Interface to CFGBlock - adding CFGElements.
void AppendStmt(CFGBlock *B, Stmt *S,
AddStmtChoice asc = AddStmtChoice::AlwaysAdd) {
B->appendStmt(S, cfg->getBumpVectorContext(), asc.asLValue());
@@ -454,6 +466,125 @@
return B;
}
+/// addAutomaticObjDtors - Add to current block automatic objects destructors
+/// for objects in range of local scope positions. Use S as trigger statement
+/// for destructors.
+CFGBlock* CFGBuilder::addAutomaticObjDtors(LocalScope::const_iterator B,
+ LocalScope::const_iterator E, Stmt* S) {
+ if (!BuildOpts.AddImplicitDtors)
+ return Block;
+ if (B == E)
+ return Block;
+
+ autoCreateBlock();
+ appendAutomaticObjDtors(Block, B, E, S);
+ return Block;
+}
+
+/// createOrReuseLocalScope - If Scope is NULL create new LocalScope. Either
+/// way return valid LocalScope object.
+LocalScope* CFGBuilder::createOrReuseLocalScope(LocalScope* Scope) {
+ if (!Scope) {
+ Scope = cfg->getAllocator().Allocate<LocalScope>();
+ new (Scope) LocalScope(ScopePos);
+ }
+ return Scope;
+}
+
+/// addLocalScopeForStmt - Add LocalScope to local scopes tree for statement
+/// that should create implicit scope (e.g. if/else substatements). Will reuse
+/// Scope if not NULL.
+LocalScope* CFGBuilder::addLocalScopeForStmt(Stmt* S, LocalScope* Scope) {
+ if (!BuildOpts.AddImplicitDtors)
+ return Scope;
+
+ // For compound statement we will be creating explicit scope.
+ if (CompoundStmt* CS = dyn_cast<CompoundStmt>(S)) {
+ for (CompoundStmt::body_iterator BI = CS->body_begin(), BE = CS->body_end()
+ ; BI != BE; ++BI) {
+ Stmt* SI = *BI;
+ if (LabelStmt* LS = dyn_cast<LabelStmt>(SI))
+ SI = LS->getSubStmt();
+ if (DeclStmt* DS = dyn_cast<DeclStmt>(SI))
+ Scope = addLocalScopeForDeclStmt(DS, Scope);
+ }
+ return Scope;
+ }
+
+ // For any other statement scope will be implicit and as such will be
+ // interesting only for DeclStmt.
+ if (LabelStmt* LS = dyn_cast<LabelStmt>(S))
+ S = LS->getSubStmt();
+ if (DeclStmt* DS = dyn_cast<DeclStmt>(S))
+ Scope = addLocalScopeForDeclStmt(DS, Scope);
+ return Scope;
+}
+
+/// addLocalScopeForDeclStmt - Add LocalScope for declaration statement. Will
+/// reuse Scope if not NULL.
+LocalScope* CFGBuilder::addLocalScopeForDeclStmt(DeclStmt* DS,
+ LocalScope* Scope) {
+ if (!BuildOpts.AddImplicitDtors)
+ return Scope;
+
+ for (DeclStmt::decl_iterator DI = DS->decl_begin(), DE = DS->decl_end()
+ ; DI != DE; ++DI) {
+ if (VarDecl* VD = dyn_cast<VarDecl>(*DI))
+ Scope = addLocalScopeForVarDecl(VD, Scope);
+ }
+ return Scope;
+}
+
+/// addLocalScopeForVarDecl - Add LocalScope for variable declaration. It will
+/// create add scope for automatic objects and temporary objects bound to
+/// const reference. Will reuse Scope if not NULL.
+LocalScope* CFGBuilder::addLocalScopeForVarDecl(VarDecl* VD,
+ LocalScope* Scope) {
+ if (!BuildOpts.AddImplicitDtors)
+ return Scope;
+
+ // Check if variable is local.
+ switch (VD->getStorageClass()) {
+ case SC_None:
+ case SC_Auto:
+ case SC_Register:
+ break;
+ default: return Scope;
+ }
+
+ // Check for const references bound to temporary. Set type to pointee.
+ QualType QT = VD->getType();
+ if (const ReferenceType* RT = QT.getTypePtr()->getAs<ReferenceType>()) {
+ QT = RT->getPointeeType();
+ if (!QT.isConstQualified())
+ return Scope;
+ if (!VD->getInit() || !VD->getInit()->Classify(*Context).isRValue())
+ return Scope;
+ }
+
+ // Check if type is a C++ class with non-trivial destructor.
+ const RecordType* RT = QT.getTypePtr()->getAs<RecordType>();
+ if (!RT || cast<CXXRecordDecl>(RT->getDecl())->hasTrivialDestructor())
+ return Scope;
+
+ // Add the variable to scope
+ Scope = createOrReuseLocalScope(Scope);
+ Scope->addVar(VD);
+ ScopePos = Scope->begin();
+ return Scope;
+}
+
+/// addLocalScopeAndDtors - For given statement add local scope for it and
+/// add destructors that will cleanup the scope. Will reuse Scope if not NULL.
+void CFGBuilder::addLocalScopeAndDtors(Stmt* S) {
+ if (!BuildOpts.AddImplicitDtors)
+ return;
+
+ LocalScope::const_iterator scopeBeginPos = ScopePos;
+ addLocalScopeForStmt(S, NULL);
+ addAutomaticObjDtors(ScopePos, scopeBeginPos, S);
+}
+
/// insertAutomaticObjDtors - Insert destructor CFGElements for variables with
/// automatic storage duration to CFGBlock's elements vector. Insertion will be
/// performed in place specified with iterator.
More information about the cfe-commits
mailing list