diff options
-rw-r--r-- | src/context.cpp | 23 | ||||
-rw-r--r-- | src/context.h | 2 | ||||
-rw-r--r-- | src/definition.cpp | 1 | ||||
-rw-r--r-- | src/definition.h | 7 | ||||
-rw-r--r-- | src/layout.cpp | 1 | ||||
-rw-r--r-- | src/template.cpp | 42 |
6 files changed, 70 insertions, 6 deletions
diff --git a/src/context.cpp b/src/context.cpp index d32f6ea..e696981 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -3845,6 +3845,7 @@ TemplateVariant createLinkedText(Definition *def,const QCString &relPath,const Q if (tg) { linkifyText(*tg,def->getOuterScope(),def->getBodyDef(),def,text); + delete tg; return TemplateVariant(s.data(),TRUE); } else @@ -10201,6 +10202,28 @@ void generateOutputViaTemplate() } } + // clear all cached data in Definition objects. + QDictIterator<DefinitionIntf> di(*Doxygen::symbolMap); + DefinitionIntf *intf; + for (;(intf=di.current());++di) + { + if (intf->definitionType()==DefinitionIntf::TypeSymbolList) // list of symbols + { + DefinitionListIterator dli(*(DefinitionList*)intf); + Definition *d; + // for each symbol + for (dli.toFirst();(d=dli.current());++dli) + { + d->setCookie(0); + } + } + else // single symbol + { + Definition *d = (Definition *)intf; + d->setCookie(0); + } + } + e.destroyContext(ctx); } } diff --git a/src/context.h b/src/context.h index 66b1634..7c98222 100644 --- a/src/context.h +++ b/src/context.h @@ -71,7 +71,7 @@ class RefCountedContext m_className=className; m_insideRelease = FALSE; } - ~RefCountedContext() + virtual ~RefCountedContext() { if (!m_insideRelease) abort(); } diff --git a/src/definition.cpp b/src/definition.cpp index 39164d5..649cea8 100644 --- a/src/definition.cpp +++ b/src/definition.cpp @@ -390,6 +390,7 @@ Definition::~Definition() m_impl=0; } delete m_cookie; + m_cookie=0; } void Definition::setName(const char *name) diff --git a/src/definition.h b/src/definition.h index 2a66ebc..6277c6c 100644 --- a/src/definition.h +++ b/src/definition.h @@ -92,7 +92,10 @@ class DefinitionIntf class Definition : public DefinitionIntf { public: - struct Cookie {}; + struct Cookie + { + virtual ~Cookie() {} + }; /*! Create a new definition */ Definition( @@ -345,7 +348,7 @@ class Definition : public DefinitionIntf void addSectionsToIndex(); void writeToc(OutputList &ol); - void setCookie(Cookie *cookie) { m_cookie = cookie; } + void setCookie(Cookie *cookie) { delete m_cookie; m_cookie = cookie; } Cookie *cookie() const { return m_cookie; } protected: diff --git a/src/layout.cpp b/src/layout.cpp index 01d5d18..1f45631 100644 --- a/src/layout.cpp +++ b/src/layout.cpp @@ -1269,6 +1269,7 @@ class LayoutParser : public QXmlDefaultHandler private: LayoutParser() : m_sHandler(163), m_eHandler(17), m_invalidEntry(FALSE) { } + ~LayoutParser() { delete m_rootNav; } QDict<StartElementHandler> m_sHandler; QDict<EndElementHandler> m_eHandler; diff --git a/src/template.cpp b/src/template.cpp index 2ad5ecc..527148c 100644 --- a/src/template.cpp +++ b/src/template.cpp @@ -1409,6 +1409,10 @@ class ExprAstFunctionVariable : public ExprAst { TRACE(("ExprAstFunctionVariable()\n")); m_args.setAutoDelete(TRUE); } + ~ExprAstFunctionVariable() + { + delete m_var; + } virtual TemplateVariant resolve(TemplateContext *c) { QValueList<TemplateVariant> args; @@ -2260,6 +2264,7 @@ class TemplateImpl : public TemplateNode, public Template public: TemplateImpl(TemplateEngine *e,const QCString &name,const QCString &data, const QCString &extension); + ~TemplateImpl(); void render(FTextStream &ts, TemplateContext *c); TemplateEngine *engine() const { return m_engine; } @@ -2274,6 +2279,22 @@ class TemplateImpl : public TemplateNode, public Template //---------------------------------------------------------- +/** @brief Weak reference wrapper for TemplateStructIntf that provides access to the + * wrapped struct without holding a reference. + */ +class TemplateStructWeakRef : public TemplateStructIntf +{ + public: + TemplateStructWeakRef(TemplateStructIntf *ref) : m_ref(ref), m_refCount(0) {} + virtual TemplateVariant get(const char *name) const { return m_ref->get(name); } + virtual int addRef() { return ++m_refCount; } + virtual int release() { int count=--m_refCount; if (count<=0) { delete this; } return count; } + private: + TemplateStructIntf *m_ref; + int m_refCount; +}; + +//---------------------------------------------------------- TemplateContextImpl::TemplateContextImpl(const TemplateEngine *e) : m_engine(e), m_templateName("<unknown>"), m_line(1), m_activeEscapeIntf(0), @@ -2418,7 +2439,7 @@ void TemplateContextImpl::warn(const char *fileName,int line,const char *fmt,... void TemplateContextImpl::openSubIndex(const QCString &indexName) { - //printf("TemplateContextImpl::openSubIndex(%s)\n",indexName.data()); + printf("TemplateContextImpl::openSubIndex(%s)\n",indexName.data()); QStack<TemplateVariant> *stack = m_indexStacks.find(indexName); if (!stack || stack->isEmpty() || stack->top()->type()==TemplateVariant::List) // error: no stack yet or no entry { @@ -2439,7 +2460,7 @@ void TemplateContextImpl::openSubIndex(const QCString &indexName) void TemplateContextImpl::closeSubIndex(const QCString &indexName) { - //printf("TemplateContextImpl::closeSubIndex(%s)\n",indexName.data()); + printf("TemplateContextImpl::closeSubIndex(%s)\n",indexName.data()); QStack<TemplateVariant> *stack = m_indexStacks.find(indexName); if (!stack || stack->count()<3) { @@ -2462,6 +2483,7 @@ void TemplateContextImpl::closeSubIndex(const QCString &indexName) } } } + //fprintf(stderr,"TemplateContextImpl::closeSubIndex(%s) end g_count=%d\n\n",indexName.data(),g_count); } static void getPathListFunc(TemplateStructIntf *entry,TemplateList *list) @@ -2520,7 +2542,9 @@ void TemplateContextImpl::addIndexEntry(const QCString &indexName,const QValueLi if (stack->count()>1) { TemplateVariant *tmp = stack->pop(); - parent = *stack->top(); + // To prevent a cyclic dependency between parent and child which causes a memory + // leak, we wrap the parent into a weak reference version. + parent = new TemplateStructWeakRef(stack->top()->toStruct()); stack->push(tmp); ASSERT(parent.type()==TemplateVariant::Struct); } @@ -3652,6 +3676,7 @@ class TemplateNodeTree : public TemplateNodeCreator<TemplateNodeTree> } } c->pop(); + delete it; return result.data(); } void render(FTextStream &ts, TemplateContext *c) @@ -4058,6 +4083,11 @@ class TemplateNodeMarkers : public TemplateNodeCreator<TemplateNodeMarkers> parser->removeNextToken(); // skip over endmarkers TRACE(("}TemplateNodeMarkers(%s)\n",data.data())); } + ~TemplateNodeMarkers() + { + delete m_listExpr; + delete m_patternExpr; + } void render(FTextStream &ts, TemplateContext *c) { TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c); @@ -4109,6 +4139,7 @@ class TemplateNodeMarkers : public TemplateNodeCreator<TemplateNodeMarkers> } ts << str.right(str.length()-index); // write text after last marker c->pop(); + delete it; } else { @@ -4770,6 +4801,11 @@ TemplateImpl::TemplateImpl(TemplateEngine *engine,const QCString &name,const QCS parser.parse(this,1,QStrList(),m_nodes); } +TemplateImpl::~TemplateImpl() +{ + //printf("deleting template %s\n",m_name.data()); +} + void TemplateImpl::render(FTextStream &ts, TemplateContext *c) { TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c); |