[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