[cfe-commits] r94090 - in /cfe/trunk: include/clang/AST/Type.h lib/AST/ASTContext.cpp lib/AST/Type.cpp

Ted Kremenek kremenek at apple.com
Thu Jan 21 11:22:35 PST 2010


Author: kremenek
Date: Thu Jan 21 13:22:34 2010
New Revision: 94090

URL: http://llvm.org/viewvc/llvm-project?rev=94090&view=rev
Log:
Allocate the 'Protocols' array in ObjCInterfaceType and
ObjCObjectPointerType using the allocator associated with ASTContext.
Not only does this fix a memory leak, but it also makes these arrays
BumpPtrAllocated (in the typical case).

Modified:
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/Type.cpp

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=94090&r1=94089&r2=94090&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Thu Jan 21 13:22:34 2010
@@ -2514,26 +2514,31 @@
 
   // List of protocols for this protocol conforming object type
   // List is sorted on protocol name. No protocol is enterred more than once.
-  llvm::SmallVector<ObjCProtocolDecl*, 4> Protocols;
+  ObjCProtocolDecl **Protocols;
+  unsigned NumProtocols;
 
-  ObjCInterfaceType(QualType Canonical, ObjCInterfaceDecl *D,
-                    ObjCProtocolDecl **Protos, unsigned NumP) :
-    Type(ObjCInterface, Canonical, /*Dependent=*/false),
-    Decl(D), Protocols(Protos, Protos+NumP) { }
+  ObjCInterfaceType(ASTContext &Ctx, QualType Canonical, ObjCInterfaceDecl *D,
+                    ObjCProtocolDecl **Protos, unsigned NumP);
   friend class ASTContext;  // ASTContext creates these.
 public:
+  void Destroy(ASTContext& C);
+
   ObjCInterfaceDecl *getDecl() const { return Decl; }
 
   /// getNumProtocols - Return the number of qualifying protocols in this
   /// interface type, or 0 if there are none.
-  unsigned getNumProtocols() const { return Protocols.size(); }
+  unsigned getNumProtocols() const { return NumProtocols; }
 
   /// qual_iterator and friends: this provides access to the (potentially empty)
   /// list of protocols qualifying this interface.
-  typedef llvm::SmallVector<ObjCProtocolDecl*, 8>::const_iterator qual_iterator;
-  qual_iterator qual_begin() const { return Protocols.begin(); }
-  qual_iterator qual_end() const   { return Protocols.end(); }
-  bool qual_empty() const { return Protocols.size() == 0; }
+  typedef ObjCProtocolDecl*  const * qual_iterator;
+  qual_iterator qual_begin() const {
+    return Protocols;
+  }
+  qual_iterator qual_end() const   {
+    return Protocols ? Protocols + NumProtocols : 0;
+  }
+  bool qual_empty() const { return NumProtocols == 0; }
 
   bool isSugared() const { return false; }
   QualType desugar() const { return QualType(this, 0); }
@@ -2559,15 +2564,16 @@
 
   // List of protocols for this protocol conforming object type
   // List is sorted on protocol name. No protocol is entered more than once.
-  llvm::SmallVector<ObjCProtocolDecl*, 8> Protocols;
+  ObjCProtocolDecl **Protocols;
+  unsigned NumProtocols;
 
-  ObjCObjectPointerType(QualType Canonical, QualType T,
-                        ObjCProtocolDecl **Protos, unsigned NumP) :
-    Type(ObjCObjectPointer, Canonical, /*Dependent=*/false),
-    PointeeType(T), Protocols(Protos, Protos+NumP) { }
+  ObjCObjectPointerType(ASTContext &Ctx, QualType Canonical, QualType T,
+                        ObjCProtocolDecl **Protos, unsigned NumP);
   friend class ASTContext;  // ASTContext creates these.
 
 public:
+  void Destroy(ASTContext& C);
+
   // Get the pointee type. Pointee will either be:
   // - a built-in type (for 'id' and 'Class').
   // - an interface type (for user-defined types).
@@ -2585,35 +2591,39 @@
   /// isObjCIdType - true for "id".
   bool isObjCIdType() const {
     return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCId) &&
-           !Protocols.size();
+           !NumProtocols;
   }
   /// isObjCClassType - true for "Class".
   bool isObjCClassType() const {
     return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCClass) &&
-           !Protocols.size();
+           !NumProtocols;
   }
   
   /// isObjCQualifiedIdType - true for "id <p>".
   bool isObjCQualifiedIdType() const {
     return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCId) &&
-           Protocols.size();
+           NumProtocols;
   }
   /// isObjCQualifiedClassType - true for "Class <p>".
   bool isObjCQualifiedClassType() const {
     return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCClass) &&
-           Protocols.size();
+           NumProtocols;
   }
   /// qual_iterator and friends: this provides access to the (potentially empty)
   /// list of protocols qualifying this interface.
-  typedef llvm::SmallVector<ObjCProtocolDecl*, 8>::const_iterator qual_iterator;
+  typedef ObjCProtocolDecl*  const * qual_iterator;
 
-  qual_iterator qual_begin() const { return Protocols.begin(); }
-  qual_iterator qual_end() const   { return Protocols.end(); }
-  bool qual_empty() const { return Protocols.size() == 0; }
+  qual_iterator qual_begin() const {
+    return Protocols;
+  }
+  qual_iterator qual_end() const   {
+    return Protocols ? Protocols + NumProtocols : NULL;
+  }
+  bool qual_empty() const { return NumProtocols == 0; }
 
   /// getNumProtocols - Return the number of qualifying protocols in this
   /// interface type, or 0 if there are none.
-  unsigned getNumProtocols() const { return Protocols.size(); }
+  unsigned getNumProtocols() const { return NumProtocols; }
 
   bool isSugared() const { return false; }
   QualType desugar() const { return QualType(this, 0); }

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=94090&r1=94089&r2=94090&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Thu Jan 21 13:22:34 2010
@@ -2127,7 +2127,8 @@
 
   // No Match;
   ObjCObjectPointerType *QType = new (*this, TypeAlignment)
-    ObjCObjectPointerType(Canonical, InterfaceT, Protocols, NumProtocols);
+    ObjCObjectPointerType(*this, Canonical, InterfaceT, Protocols,
+                          NumProtocols);
 
   Types.push_back(QType);
   ObjCObjectPointerTypes.InsertNode(QType, InsertPos);
@@ -2161,7 +2162,7 @@
   }
 
   ObjCInterfaceType *QType = new (*this, TypeAlignment)
-    ObjCInterfaceType(Canonical, const_cast<ObjCInterfaceDecl*>(Decl),
+    ObjCInterfaceType(*this, Canonical, const_cast<ObjCInterfaceDecl*>(Decl),
                       Protocols, NumProtocols);
 
   Types.push_back(QType);

Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=94090&r1=94089&r2=94090&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Thu Jan 21 13:22:34 2010
@@ -339,6 +339,25 @@
   return 0;
 }
 
+ObjCInterfaceType::ObjCInterfaceType(ASTContext &Ctx, QualType Canonical,
+                                     ObjCInterfaceDecl *D,
+                                     ObjCProtocolDecl **Protos, unsigned NumP) :
+  Type(ObjCInterface, Canonical, /*Dependent=*/false),
+  Decl(D), Protocols(0), NumProtocols(NumP)
+{
+  if (NumProtocols) {
+    Protocols = new (Ctx) ObjCProtocolDecl*[NumProtocols];
+    memcpy(Protocols, Protos, NumProtocols * sizeof(*Protocols));
+  }
+}
+
+void ObjCInterfaceType::Destroy(ASTContext& C) {
+  if (Protocols)
+    C.Deallocate(Protocols);
+  this->~ObjCInterfaceType();
+  C.Deallocate(this);
+}
+
 const ObjCInterfaceType *Type::getAsObjCQualifiedInterfaceType() const {
   // There is no sugar for ObjCInterfaceType's, just return the canonical
   // type pointer if it is the right class.  There is no typedef information to
@@ -353,6 +372,26 @@
   return getAsObjCQualifiedInterfaceType() != 0;
 }
 
+ObjCObjectPointerType::ObjCObjectPointerType(ASTContext &Ctx,
+                                             QualType Canonical, QualType T,
+                                             ObjCProtocolDecl **Protos,
+                                             unsigned NumP) :
+  Type(ObjCObjectPointer, Canonical, /*Dependent=*/false),
+  PointeeType(T), Protocols(NULL), NumProtocols(NumP)
+{
+  if (NumProtocols) {
+    Protocols = new (Ctx) ObjCProtocolDecl*[NumProtocols];
+    memcpy(Protocols, Protos, NumProtocols * sizeof(*Protocols));
+  }
+}
+
+void ObjCObjectPointerType::Destroy(ASTContext& C) {
+  if (Protocols)
+    C.Deallocate(Protocols);
+  this->~ObjCObjectPointerType();
+  C.Deallocate(this);
+}
+
 const ObjCObjectPointerType *Type::getAsObjCQualifiedIdType() const {
   // There is no sugar for ObjCQualifiedIdType's, just return the canonical
   // type pointer if it is the right class.





More information about the cfe-commits mailing list