[cfe-commits] r49142 - in /cfe/trunk: include/clang/AST/TranslationUnit.h lib/AST/TranslationUnit.cpp

Ted Kremenek kremenek at apple.com
Thu Apr 3 09:48:01 PDT 2008


On Apr 3, 2008, at 8:39 AM, Sam Bishop wrote:

> Sam Bishop wrote:
>> +TranslationUnit::~TranslationUnit() {
>> +  for (iterator I=begin(), E=end(); I!=E; ++I)
>> +    delete *I;
>> +}
>
> Meh.  I'm already over my head...
>
> I expect that we would like serializing to be transparent.  In other
> words, a new decl and a deserialized decl ought to be equivalent.
>
> Decls are usually created using Create() calls, which takes a  
> pointer to
> an ASTContext object.  The deserialization code can't use those  
> Create()
> calls, because it's generic LLVM code which doesn't know anything  
> about
> the ASTContext class.
>
> The reason that's a problem is because the ASTContext object  
> determines
> the allocator to use, at least in the "from source code" case.
> Currently, the allocator is llvm::MallocAllocator, but the
> deserialization code uses new.
>
> Any suggestions?  "Here's a simpler project for you..." would  
> work.  ;)
> But I think that once I'm over this hump I can get back to trivial
> additions of deletes and destructors...

Hi Sam,

Right now all Decls are deserialized using a combination of

   static Decl* Create(llvm::Deserializer& D);   (from "Decl")

and implementation methods, e.g.:

   /// CreateImpl - Deserialize a BlockVarDecl.  Called by Decl::Create.
   static BlockVarDecl* CreateImpl(llvm::Deserializer& D);

Conceptually we could easily replace these with:

   static Decl* Create(llvm::Deserializer& D, Allocator& A);
   static BlockVarDecl* CreateImpl(llvm::Deserializer& D, Allocator &A);

To get this to work with the Serialization library, we simply need to  
add a few more member templates to Deserializer to handle an extra  
argument to pass to the "Create" methods.  For example, here is the  
current implementation of Deserializer::ReadOwnedPtr from  
Deserialize.h (in the llvm tree):

   template <typename T>
   inline T* ReadOwnedPtr(bool AutoRegister = true) {
     SerializedPtrID PtrID = ReadPtrID();

     if (!PtrID)
       return NULL;

     T* x = SerializeTrait<T>::Create(*this);

     if (AutoRegister)
       RegisterPtr(PtrID,x);

     return x;
   }

We can simply have a second version of this in Deserialize.h that  
accepts a second template argument:

   template <typename T, typename Arg1>
   inline T* ReadOwnedPtr(Arg1& arg1, bool AutoRegister = true) {
     SerializedPtrID PtrID = ReadPtrID();

     if (!PtrID)
       return NULL;

     T* x = SerializeTrait<T>::Create(*this, arg1);

     if (AutoRegister)
       RegisterPtr(PtrID,x);

     return x;
   }

We would also need to do this for all versions BatchReadOwnedPtrs that  
we also wanted to use in this way.

Finally, we would need to extend the default implementation of  
SerializeTrait<> (defined in Serialization.h).  Right now it is  
defined as:

template <typename T>
struct SerializeTrait {
   static inline void Emit(Serializer& S, const T& X) { X.Emit(S); }
   static inline void Read(Deserializer& D, T& X) { X.Read(D); }
   static inline T* Create(Deserializer& D) { return T::Create(D); }
};

We would just need to make a member template version of "Create":

template <typename T>
struct SerializeTrait {
   static inline void Emit(Serializer& S, const T& X) { X.Emit(S); }
   static inline void Read(Deserializer& D, T& X) { X.Read(D); }

   static inline T* Create(Deserializer& D) { return T::Create(D); }

   template <typename Arg1>
   static inline T* Create(Deserializer& D, Arg1& arg1) { return  
T::Create(D, arg1); }
};

Because of the magic of template instantiation, only the methods that  
are used in SerializeTrait are instantiated, so it should all just  
magically work.

So I think the solution is not technically all that hard; it just  
requires some tedious engineering to make separate instances of all  
the mentioned methods (and to of course add the necessary "Allocator"  
argument to the Decl::Create methods, etc.).

I've gone and taken an initial step by adding the member template to  
SerializeTrait:

   http://llvm.org/viewvc/llvm-project?view=rev&revision=49169

I can also start gradually adding the support that I mentioned in the  
Serialization library but doing a few template functions, and  
potentially allowing others to implementing all the instances of  
BatchReadOwnedPtrs that we need.

Ted

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20080403/fe59e3ab/attachment.html>


More information about the cfe-commits mailing list