aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/Expr.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2010-02-19 00:42:33 +0000
committerTed Kremenek <kremenek@apple.com>2010-02-19 00:42:33 +0000
commit9f9269e810bfe9aea0a57b09250be215808fc1a2 (patch)
treed7cb45bf9e3387ffdacb0a1106cd2ceca04cf454 /lib/AST/Expr.cpp
parentb9c903bc7c11adf86b1f1e68ad35cd49703dc654 (diff)
Change InitListExpr to allocate the array for holding references
to initializer expressions in an array allocated using ASTContext. This plugs a memory leak when ASTContext uses a BumpPtrAllocator to allocate memory for AST nodes. In my mind this isn't an ideal solution; it would be nice to have a general "vector"-like class that allocates memory using ASTContext, but whose guts could be separated from the methods of InitListExpr itself. I haven't gone and taken this approach yet because it isn't clear yet if we'll eventually want an alternate solution for recylcing memory using by InitListExprs as we are constructing the ASTs. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96642 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/Expr.cpp')
-rw-r--r--lib/AST/Expr.cpp85
1 files changed, 58 insertions, 27 deletions
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index fac65064c0..58776f47d9 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -713,40 +713,75 @@ OverloadedOperatorKind BinaryOperator::getOverloadedOperator(Opcode Opc) {
return OverOps[Opc];
}
-InitListExpr::InitListExpr(SourceLocation lbraceloc,
+InitListExpr::InitListExpr(ASTContext &C, SourceLocation lbraceloc,
Expr **initExprs, unsigned numInits,
SourceLocation rbraceloc)
: Expr(InitListExprClass, QualType(), false, false),
+ InitExprs(0), NumInits(numInits), Capacity(numInits),
LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), SyntacticForm(0),
- UnionFieldInit(0), HadArrayRangeDesignator(false)
-{
- for (unsigned I = 0; I != numInits; ++I) {
- if (initExprs[I]->isTypeDependent())
+ UnionFieldInit(0), HadArrayRangeDesignator(false)
+{
+ if (NumInits == 0)
+ return;
+
+ InitExprs = new (C) Stmt*[Capacity];
+
+ for (unsigned I = 0; I != NumInits; ++I) {
+ Expr *Ex = initExprs[I];
+ if (Ex->isTypeDependent())
TypeDependent = true;
- if (initExprs[I]->isValueDependent())
+ if (Ex->isValueDependent())
ValueDependent = true;
+ InitExprs[I] = Ex;
}
-
- InitExprs.insert(InitExprs.end(), initExprs, initExprs+numInits);
}
-void InitListExpr::reserveInits(unsigned NumInits) {
- if (NumInits > InitExprs.size())
- InitExprs.reserve(NumInits);
+void InitListExpr::DoDestroy(ASTContext &C) {
+ DestroyChildren(C);
+ if (InitExprs)
+ C.Deallocate(InitExprs);
+ this->~InitListExpr();
+ C.Deallocate((void*) this);
}
-void InitListExpr::resizeInits(ASTContext &Context, unsigned NumInits) {
- for (unsigned Idx = NumInits, LastIdx = InitExprs.size();
- Idx < LastIdx; ++Idx)
- InitExprs[Idx]->Destroy(Context);
- InitExprs.resize(NumInits, 0);
+void InitListExpr::reserveInits(ASTContext &C, unsigned newCapacity) {
+ if (newCapacity > Capacity) {
+ if (!Capacity)
+ Capacity = newCapacity;
+ else if ((Capacity *= 2) < newCapacity)
+ Capacity = newCapacity;
+
+ Stmt **newInits = new (C) Stmt*[Capacity];
+ if (InitExprs) {
+ memcpy(newInits, InitExprs, NumInits * sizeof(*InitExprs));
+ C.Deallocate(InitExprs);
+ }
+ InitExprs = newInits;
+ }
}
-Expr *InitListExpr::updateInit(unsigned Init, Expr *expr) {
- if (Init >= InitExprs.size()) {
- InitExprs.insert(InitExprs.end(), Init - InitExprs.size() + 1, 0);
- InitExprs.back() = expr;
- return 0;
+void InitListExpr::resizeInits(ASTContext &C, unsigned N) {
+ // If the new number of expressions is less than the old one, destroy
+ // the expressions that are beyond the new size.
+ for (unsigned i = N, LastIdx = NumInits; i < LastIdx; ++i)
+ InitExprs[i]->Destroy(C);
+
+ // If we are expanding the number of expressions, reserve space.
+ reserveInits(C, N);
+
+ // If we are expanding the number of expressions, zero out beyond our
+ // current capacity.
+ for (unsigned i = NumInits; i < N; ++i)
+ InitExprs[i] = 0;
+
+ NumInits = N;
+}
+
+Expr *InitListExpr::updateInit(ASTContext &C, unsigned Init, Expr *expr) {
+ if (Init >= NumInits) {
+ // Resize the number of initializers. This will adjust the amount
+ // of memory allocated as well as zero-pad the initializers.
+ resizeInits(C, Init+1);
}
Expr *Result = cast_or_null<Expr>(InitExprs[Init]);
@@ -2586,12 +2621,8 @@ Stmt::child_iterator VAArgExpr::child_begin() { return &Val; }
Stmt::child_iterator VAArgExpr::child_end() { return &Val+1; }
// InitListExpr
-Stmt::child_iterator InitListExpr::child_begin() {
- return InitExprs.size() ? &InitExprs[0] : 0;
-}
-Stmt::child_iterator InitListExpr::child_end() {
- return InitExprs.size() ? &InitExprs[0] + InitExprs.size() : 0;
-}
+Stmt::child_iterator InitListExpr::child_begin() { return begin(); }
+Stmt::child_iterator InitListExpr::child_end() { return end(); }
// DesignatedInitExpr
Stmt::child_iterator DesignatedInitExpr::child_begin() {