[cfe-commits] r154743 - in /cfe/trunk: include/clang/Basic/DelayedCleanupPool.h include/clang/Parse/Parser.h include/clang/Sema/ParsedTemplate.h lib/Parse/ParseExprCXX.cpp lib/Parse/ParseTemplate.cpp lib/Parse/Parser.cpp
Benjamin Kramer
benny.kra at googlemail.com
Sat Apr 14 05:14:03 PDT 2012
Author: d0k
Date: Sat Apr 14 07:14:03 2012
New Revision: 154743
URL: http://llvm.org/viewvc/llvm-project?rev=154743&view=rev
Log:
Parser: Don't manage TemplateAnnotationIds in a delayed cleanup pool.
Instead, make it the allocation function's responsibility to add them
to a list and clear it when a top-level decl is finished.
This plugs leakage of TemplateAnnotationIds. DelayedCleanupPool is
ugly and unused, remove it.
Removed:
cfe/trunk/include/clang/Basic/DelayedCleanupPool.h
Modified:
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/include/clang/Sema/ParsedTemplate.h
cfe/trunk/lib/Parse/ParseExprCXX.cpp
cfe/trunk/lib/Parse/ParseTemplate.cpp
cfe/trunk/lib/Parse/Parser.cpp
Removed: cfe/trunk/include/clang/Basic/DelayedCleanupPool.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DelayedCleanupPool.h?rev=154742&view=auto
==============================================================================
--- cfe/trunk/include/clang/Basic/DelayedCleanupPool.h (original)
+++ cfe/trunk/include/clang/Basic/DelayedCleanupPool.h (removed)
@@ -1,110 +0,0 @@
-//=== DelayedCleanupPool.h - Delayed Clean-up Pool Implementation *- C++ -*===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines a facility to delay calling cleanup methods until specific
-// points.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_DELAYEDCLEANUPPOOL_H
-#define LLVM_CLANG_BASIC_DELAYEDCLEANUPPOOL_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallVector.h"
-
-namespace clang {
-
-/// \brief Gathers pairs of pointer-to-object/pointer-to-cleanup-function
-/// allowing the cleanup functions to get called (with the pointer as parameter)
-/// at specific points.
-///
-/// The use case is to simplify clean-up of certain resources that, while their
-/// lifetime is well-known and restricted, cleaning them up manually is easy to
-/// miss and cause a leak.
-///
-/// The same pointer can be added multiple times; its clean-up function will
-/// only be called once.
-class DelayedCleanupPool {
-public:
- typedef void (*CleanupFn)(void *ptr);
-
- /// \brief Adds a pointer and its associated cleanup function to be called
- /// at a later point.
- ///
- /// \returns false if the pointer is already added, true otherwise.
- bool delayCleanup(void *ptr, CleanupFn fn) {
- assert(ptr && "Expected valid pointer to object");
- assert(fn && "Expected valid pointer to function");
-
- CleanupFn &mapFn = Ptrs[ptr];
- assert((!mapFn || mapFn == fn) &&
- "Adding a pointer with different cleanup function!");
-
- if (!mapFn) {
- mapFn = fn;
- Cleanups.push_back(std::make_pair(ptr, fn));
- return true;
- }
-
- return false;
- }
-
- template <typename T>
- bool delayDelete(T *ptr) {
- return delayCleanup(ptr, cleanupWithDelete<T>);
- }
-
- template <typename T, void (T::*Fn)()>
- bool delayMemberFunc(T *ptr) {
- return delayCleanup(ptr, cleanupWithMemberFunc<T, Fn>);
- }
-
- void doCleanup() {
- for (SmallVector<std::pair<void *, CleanupFn>, 8>::reverse_iterator
- I = Cleanups.rbegin(), E = Cleanups.rend(); I != E; ++I)
- I->second(I->first);
- Cleanups.clear();
- Ptrs.clear();
- }
-
- ~DelayedCleanupPool() {
- doCleanup();
- }
-
-private:
- llvm::DenseMap<void *, CleanupFn> Ptrs;
- SmallVector<std::pair<void *, CleanupFn>, 8> Cleanups;
-
- template <typename T>
- static void cleanupWithDelete(void *ptr) {
- delete static_cast<T *>(ptr);
- }
-
- template <typename T, void (T::*Fn)()>
- static void cleanupWithMemberFunc(void *ptr) {
- (static_cast<T *>(ptr)->*Fn)();
- }
-};
-
-/// \brief RAII object for triggering a cleanup of a DelayedCleanupPool.
-class DelayedCleanupPoint {
- DelayedCleanupPool &Pool;
-
-public:
- DelayedCleanupPoint(DelayedCleanupPool &pool) : Pool(pool) { }
-
- ~DelayedCleanupPoint() {
- Pool.doCleanup();
- }
-};
-
-} // end namespace clang
-
-#endif
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=154743&r1=154742&r2=154743&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Sat Apr 14 07:14:03 2012
@@ -15,7 +15,6 @@
#define LLVM_CLANG_PARSE_PARSER_H
#include "clang/Basic/Specifiers.h"
-#include "clang/Basic/DelayedCleanupPool.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/CodeCompletionHandler.h"
#include "clang/Sema/Sema.h"
@@ -192,9 +191,9 @@
/// Factory object for creating AttributeList objects.
AttributeFactory AttrFactory;
- /// \brief Gathers and cleans up objects when parsing of a top-level
- /// declaration is finished.
- DelayedCleanupPool TopLevelDeclCleanupPool;
+ /// \brief Gathers and cleans up TemplateIdAnnotations when parsing of a
+ /// top-level declaration is finished.
+ SmallVector<TemplateIdAnnotation *, 16> TemplateIds;
IdentifierInfo *getSEHExceptKeyword();
@@ -568,9 +567,7 @@
const char *&PrevSpec, unsigned &DiagID,
bool &isInvalid);
- /// \brief Get the TemplateIdAnnotation from the token and put it in the
- /// cleanup pool so that it gets destroyed when parsing the current top level
- /// declaration is finished.
+ /// \brief Get the TemplateIdAnnotation from the token.
TemplateIdAnnotation *takeTemplateIdAnnotation(const Token &tok);
/// TentativeParsingAction - An object that is used as a kind of "tentative
Modified: cfe/trunk/include/clang/Sema/ParsedTemplate.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/ParsedTemplate.h?rev=154743&r1=154742&r2=154743&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/ParsedTemplate.h (original)
+++ cfe/trunk/include/clang/Sema/ParsedTemplate.h Sat Apr 14 07:14:03 2012
@@ -178,8 +178,11 @@
ParsedTemplateArgument *getTemplateArgs() {
return reinterpret_cast<ParsedTemplateArgument *>(this + 1);
}
-
- static TemplateIdAnnotation* Allocate(unsigned NumArgs) {
+
+ /// \brief Creates a new TemplateIdAnnotation with NumArgs arguments and
+ /// appends it to List.
+ static TemplateIdAnnotation *
+ Allocate(unsigned NumArgs, SmallVectorImpl<TemplateIdAnnotation*> &List) {
TemplateIdAnnotation *TemplateId
= (TemplateIdAnnotation *)std::malloc(sizeof(TemplateIdAnnotation) +
sizeof(ParsedTemplateArgument) * NumArgs);
@@ -193,6 +196,7 @@
for (unsigned I = 0; I != NumArgs; ++I)
new (TemplateArgs + I) ParsedTemplateArgument();
+ List.push_back(TemplateId);
return TemplateId;
}
Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=154743&r1=154742&r2=154743&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Sat Apr 14 07:14:03 2012
@@ -1711,7 +1711,7 @@
// Form a parsed representation of the template-id to be stored in the
// UnqualifiedId.
TemplateIdAnnotation *TemplateId
- = TemplateIdAnnotation::Allocate(TemplateArgs.size());
+ = TemplateIdAnnotation::Allocate(TemplateArgs.size(), TemplateIds);
if (Id.getKind() == UnqualifiedId::IK_Identifier) {
TemplateId->Name = Id.Identifier;
Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=154743&r1=154742&r2=154743&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp Sat Apr 14 07:14:03 2012
@@ -838,7 +838,7 @@
// later.
Tok.setKind(tok::annot_template_id);
TemplateIdAnnotation *TemplateId
- = TemplateIdAnnotation::Allocate(TemplateArgs.size());
+ = TemplateIdAnnotation::Allocate(TemplateArgs.size(), TemplateIds);
TemplateId->TemplateNameLoc = TemplateNameLoc;
if (TemplateName.getKind() == UnqualifiedId::IK_Identifier) {
TemplateId->Name = TemplateName.Identifier;
Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=154743&r1=154742&r2=154743&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Sat Apr 14 07:14:03 2012
@@ -397,6 +397,8 @@
PP.RemovePragmaHandler("STDC", FPContractHandler.get());
FPContractHandler.reset();
PP.clearCodeCompletionHandler();
+
+ assert(TemplateIds.empty() && "Still alive TemplateIdAnnotations around?");
}
/// Initialize - Warm up the parser.
@@ -470,10 +472,30 @@
}
}
+namespace {
+ /// \brief RAIIObject to destroy the contents of a SmallVector of
+ /// TemplateIdAnnotation pointers and clear the vector.
+ class DestroyTemplateIdAnnotationsRAIIObj {
+ SmallVectorImpl<TemplateIdAnnotation *> &Container;
+ public:
+ DestroyTemplateIdAnnotationsRAIIObj(SmallVectorImpl<TemplateIdAnnotation *>
+ &Container)
+ : Container(Container) {}
+
+ ~DestroyTemplateIdAnnotationsRAIIObj() {
+ for (SmallVectorImpl<TemplateIdAnnotation *>::iterator I =
+ Container.begin(), E = Container.end();
+ I != E; ++I)
+ (*I)->Destroy();
+ Container.clear();
+ }
+ };
+}
+
/// ParseTopLevelDecl - Parse one top-level declaration, return whatever the
/// action tells us to. This returns true if the EOF was encountered.
bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result) {
- DelayedCleanupPoint CleanupRAII(TopLevelDeclCleanupPool);
+ DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(TemplateIds);
// Skip over the EOF token, flagging end of previous input for incremental
// processing
@@ -543,7 +565,7 @@
Parser::DeclGroupPtrTy
Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
ParsingDeclSpec *DS) {
- DelayedCleanupPoint CleanupRAII(TopLevelDeclCleanupPool);
+ DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(TemplateIds);
ParenBraceBracketBalancer BalancerRAIIObj(*this);
if (PP.isCodeCompletionReached()) {
@@ -1201,8 +1223,6 @@
assert(tok.is(tok::annot_template_id) && "Expected template-id token");
TemplateIdAnnotation *
Id = static_cast<TemplateIdAnnotation *>(tok.getAnnotationValue());
- TopLevelDeclCleanupPool.delayMemberFunc< TemplateIdAnnotation,
- &TemplateIdAnnotation::Destroy>(Id);
return Id;
}
More information about the cfe-commits
mailing list