Fix aidl to cope with multiple collection types per method.

Bug: http://code.google.com/p/android/issues/detail?id=18497
Change-Id: I152416022524d2860cb16b46c4812c5be6bdcbad
diff --git a/tools/aidl/Type.cpp b/tools/aidl/Type.cpp
index a44072d..6b69864 100755
--- a/tools/aidl/Type.cpp
+++ b/tools/aidl/Type.cpp
@@ -198,7 +198,7 @@
 }
 
 void
-Type::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+Type::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
 {
     fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n",
             __FILE__, __LINE__, m_qualifiedName.c_str());
@@ -207,7 +207,7 @@
 }
 
 void
-Type::ReadFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+Type::ReadFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
 {
     fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n",
             __FILE__, __LINE__, m_qualifiedName.c_str());
@@ -226,7 +226,7 @@
 
 void
 Type::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
-                            Variable* parcel)
+                            Variable* parcel, Variable**)
 {
     fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n",
             __FILE__, __LINE__, m_qualifiedName.c_str());
@@ -235,7 +235,7 @@
 }
 
 void
-Type::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+Type::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
 {
     fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n",
             __FILE__, __LINE__, m_qualifiedName.c_str());
@@ -284,7 +284,7 @@
 }
 
 void
-BasicType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+BasicType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
 {
     addTo->Add(new Assignment(v, new MethodCall(parcel, m_unmarshallMethod)));
 }
@@ -303,13 +303,13 @@
 
 void
 BasicType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
-                            Variable* parcel)
+                            Variable* parcel, Variable**)
 {
     addTo->Add(new Assignment(v, new MethodCall(parcel, m_createArrayMethod)));
 }
 
 void
-BasicType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+BasicType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
 {
     addTo->Add(new MethodCall(parcel, m_readArrayMethod, 1, v));
 }
@@ -331,7 +331,7 @@
 }
 
 void
-BooleanType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+BooleanType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
 {
     addTo->Add(new Assignment(v, new Comparison(new LiteralExpression("0"),
                     "!=", new MethodCall(parcel, "readInt"))));
@@ -351,13 +351,13 @@
 
 void
 BooleanType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
-                            Variable* parcel)
+                            Variable* parcel, Variable**)
 {
     addTo->Add(new Assignment(v, new MethodCall(parcel, "createBooleanArray")));
 }
 
 void
-BooleanType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+BooleanType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
 {
     addTo->Add(new MethodCall(parcel, "readBooleanArray", 1, v));
 }
@@ -378,7 +378,7 @@
 }
 
 void
-CharType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+CharType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
 {
     addTo->Add(new Assignment(v, new MethodCall(parcel, "readInt"), this));
 }
@@ -397,13 +397,13 @@
 
 void
 CharType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
-                            Variable* parcel)
+                            Variable* parcel, Variable**)
 {
     addTo->Add(new Assignment(v, new MethodCall(parcel, "createCharArray")));
 }
 
 void
-CharType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+CharType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
 {
     addTo->Add(new MethodCall(parcel, "readCharArray", 1, v));
 }
@@ -428,7 +428,7 @@
 }
 
 void
-StringType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+StringType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
 {
     addTo->Add(new Assignment(v, new MethodCall(parcel, "readString")));
 }
@@ -447,13 +447,13 @@
 
 void
 StringType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
-                            Variable* parcel)
+                            Variable* parcel, Variable**)
 {
     addTo->Add(new Assignment(v, new MethodCall(parcel, "createStringArray")));
 }
 
 void
-StringType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+StringType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
 {
     addTo->Add(new MethodCall(parcel, "readStringArray", 1, v));
 }
@@ -496,7 +496,7 @@
 
 void
 CharSequenceType::CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                Variable* parcel)
+                                Variable* parcel, Variable**)
 {
     // if (0 != parcel.readInt()) {
     //     v = TextUtils.createFromParcel(parcel)
@@ -532,7 +532,7 @@
 }
 
 void
-RemoteExceptionType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+RemoteExceptionType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
 {
     fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
 }
@@ -551,7 +551,7 @@
 }
 
 void
-RuntimeExceptionType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+RuntimeExceptionType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
 {
     fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
 }
@@ -571,7 +571,7 @@
 }
 
 void
-IBinderType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+IBinderType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
 {
     addTo->Add(new Assignment(v, new MethodCall(parcel, "readStrongBinder")));
 }
@@ -584,13 +584,13 @@
 
 void
 IBinderType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
-                            Variable* parcel)
+                            Variable* parcel, Variable**)
 {
     addTo->Add(new Assignment(v, new MethodCall(parcel, "createBinderArray")));
 }
 
 void
-IBinderType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+IBinderType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
 {
     addTo->Add(new MethodCall(parcel, "readBinderArray", 1, v));
 }
@@ -610,7 +610,7 @@
 }
 
 void
-IInterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+IInterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
 {
     fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
 }
@@ -631,7 +631,7 @@
 
 void
 BinderType::CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel)
+                                    Variable* parcel, Variable**)
 {
     fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
 }
@@ -652,7 +652,7 @@
 
 void
 BinderProxyType::CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel)
+                                    Variable* parcel, Variable**)
 {
     fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
 }
@@ -672,7 +672,7 @@
 }
 
 void
-ParcelType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+ParcelType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
 {
     fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
 }
@@ -691,7 +691,7 @@
 }
 
 void
-ParcelableInterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+ParcelableInterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
 {
     fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
 }
@@ -709,25 +709,31 @@
     addTo->Add(new MethodCall(parcel, "writeMap", 1, v));
 }
 
-void
-MapType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+static void EnsureClassLoader(StatementBlock* addTo, Variable** cl)
 {
-    Variable *cl = new Variable(CLASSLOADER_TYPE, "cl");
-    addTo->Add(new VariableDeclaration(cl,
-        new LiteralExpression("this.getClass().getClassLoader()"),
-        CLASSLOADER_TYPE));
-    addTo->Add(new Assignment(v, new MethodCall(parcel, "readHashMap", 1, cl)));
+    // We don't want to look up the class loader once for every
+    // collection argument, so ensure we do it at most once per method.
+    if (*cl == NULL) {
+        *cl = new Variable(CLASSLOADER_TYPE, "cl");
+        addTo->Add(new VariableDeclaration(*cl,
+                new LiteralExpression("this.getClass().getClassLoader()"),
+                CLASSLOADER_TYPE));
+    }
+}
+
+void
+MapType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable** cl)
+{
+    EnsureClassLoader(addTo, cl);
+    addTo->Add(new Assignment(v, new MethodCall(parcel, "readHashMap", 1, *cl)));
 }
 
 void
 MapType::ReadFromParcel(StatementBlock* addTo, Variable* v,
-                    Variable* parcel)
+                    Variable* parcel, Variable** cl)
 {
-    Variable *cl = new Variable(CLASSLOADER_TYPE, "cl");
-    addTo->Add(new VariableDeclaration(cl, 
-        new LiteralExpression("this.getClass().getClassLoader()"),
-        CLASSLOADER_TYPE));
-    addTo->Add(new MethodCall(parcel, "readMap", 2, v, cl));
+    EnsureClassLoader(addTo, cl);
+    addTo->Add(new MethodCall(parcel, "readMap", 2, v, *cl));
 }
 
 
@@ -751,24 +757,18 @@
 }
 
 void
-ListType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+ListType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable** cl)
 {
-    Variable *cl = new Variable(CLASSLOADER_TYPE, "cl");
-    addTo->Add(new VariableDeclaration(cl, 
-        new LiteralExpression("this.getClass().getClassLoader()"),
-        CLASSLOADER_TYPE));
-    addTo->Add(new Assignment(v, new MethodCall(parcel, "readArrayList", 1, cl)));
+    EnsureClassLoader(addTo, cl);
+    addTo->Add(new Assignment(v, new MethodCall(parcel, "readArrayList", 1, *cl)));
 }
 
 void
 ListType::ReadFromParcel(StatementBlock* addTo, Variable* v,
-                    Variable* parcel)
+                    Variable* parcel, Variable** cl)
 {
-    Variable *cl = new Variable(CLASSLOADER_TYPE, "cl");
-    addTo->Add(new VariableDeclaration(cl, 
-        new LiteralExpression("this.getClass().getClassLoader()"),
-        CLASSLOADER_TYPE));
-    addTo->Add(new MethodCall(parcel, "readList", 2, v, cl));
+    EnsureClassLoader(addTo, cl);
+    addTo->Add(new MethodCall(parcel, "readList", 2, v, *cl));
 }
 
 
@@ -811,7 +811,7 @@
 }
 
 void
-ParcelableType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+ParcelableType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
 {
     // if (0 != parcel.readInt()) {
     //     v = CLASS.CREATOR.createFromParcel(parcel)
@@ -833,7 +833,7 @@
 
 void
 ParcelableType::ReadFromParcel(StatementBlock* addTo, Variable* v,
-                    Variable* parcel)
+                    Variable* parcel, Variable**)
 {
     // TODO: really, we don't need to have this extra check, but we
     // don't have two separate marshalling code paths
@@ -862,7 +862,7 @@
 
 void
 ParcelableType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
-                            Variable* parcel)
+                            Variable* parcel, Variable**)
 {
     string creator = v->type->QualifiedName() + ".CREATOR";
     addTo->Add(new Assignment(v, new MethodCall(parcel,
@@ -870,7 +870,7 @@
 }
 
 void
-ParcelableType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+ParcelableType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
 {
     string creator = v->type->QualifiedName() + ".CREATOR";
     addTo->Add(new MethodCall(parcel, "readTypedArray", 2,
@@ -907,7 +907,7 @@
 }
 
 void
-InterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+InterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
 {
     // v = Interface.asInterface(parcel.readStrongBinder());
     string type = v->type->QualifiedName();
@@ -961,14 +961,14 @@
 }
 
 void
-GenericType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+GenericType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
 {
     fprintf(stderr, "implement GenericType::CreateFromParcel\n");
 }
 
 void
 GenericType::ReadFromParcel(StatementBlock* addTo, Variable* v,
-                            Variable* parcel)
+                            Variable* parcel, Variable**)
 {
     fprintf(stderr, "implement GenericType::ReadFromParcel\n");
 }
@@ -1009,7 +1009,7 @@
 }
 
 void
-GenericListType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+GenericListType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
 {
     if (m_creator == STRING_TYPE->CreatorName()) {
         addTo->Add(new Assignment(v,
@@ -1027,7 +1027,7 @@
 
 void
 GenericListType::ReadFromParcel(StatementBlock* addTo, Variable* v,
-                            Variable* parcel)
+                            Variable* parcel, Variable**)
 {
     if (m_creator == STRING_TYPE->CreatorName()) {
         addTo->Add(new MethodCall(parcel, "readStringList", 1, v));
diff --git a/tools/aidl/Type.h b/tools/aidl/Type.h
index 2ea3ac9..662e3a2 100755
--- a/tools/aidl/Type.h
+++ b/tools/aidl/Type.h
@@ -46,18 +46,18 @@
     virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, int flags);
     virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
     virtual void    ReadFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
 
     virtual bool    CanBeArray() const;
 
     virtual void    WriteArrayToParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, int flags);
     virtual void    CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
     virtual void    ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
 
 protected:
     void SetQualifiedName(const string& qualified);
@@ -89,16 +89,16 @@
     virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, int flags);
     virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
 
     virtual bool    CanBeArray() const;
 
     virtual void    WriteArrayToParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, int flags);
     virtual void    CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
     virtual void    ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
 
 private:
     string m_marshallMethod;
@@ -116,16 +116,16 @@
     virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, int flags);
     virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
 
     virtual bool    CanBeArray() const;
 
     virtual void    WriteArrayToParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, int flags);
     virtual void    CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
     virtual void    ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
 };
 
 class CharType : public Type
@@ -136,16 +136,16 @@
     virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, int flags);
     virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
 
     virtual bool    CanBeArray() const;
 
     virtual void    WriteArrayToParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, int flags);
     virtual void    CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
     virtual void    ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
 };
 
 
@@ -159,16 +159,16 @@
     virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, int flags);
     virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
 
     virtual bool    CanBeArray() const;
 
     virtual void    WriteArrayToParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, int flags);
     virtual void    CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
     virtual void    ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
 };
 
 class CharSequenceType : public Type
@@ -181,7 +181,7 @@
     virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, int flags);
     virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
 };
 
 class RemoteExceptionType : public Type
@@ -192,7 +192,7 @@
     virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, int flags);
     virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
 };
 
 class RuntimeExceptionType : public Type
@@ -203,7 +203,7 @@
     virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, int flags);
     virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
 };
 
 class IBinderType : public Type
@@ -214,14 +214,14 @@
     virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, int flags);
     virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
 
     virtual void    WriteArrayToParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, int flags);
     virtual void    CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
     virtual void    ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
 };
 
 class IInterfaceType : public Type
@@ -232,7 +232,7 @@
     virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, int flags);
     virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
 };
 
 class BinderType : public Type
@@ -243,7 +243,7 @@
     virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, int flags);
     virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
 };
 
 class BinderProxyType : public Type
@@ -254,7 +254,7 @@
     virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, int flags);
     virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
 };
 
 class ParcelType : public Type
@@ -265,7 +265,7 @@
     virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, int flags);
     virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
 };
 
 class ParcelableInterfaceType : public Type
@@ -276,7 +276,7 @@
     virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, int flags);
     virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
 };
 
 class MapType : public Type
@@ -287,9 +287,9 @@
     virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, int flags);
     virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
     virtual void    ReadFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
 };
 
 class ListType : public Type
@@ -302,9 +302,9 @@
     virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, int flags);
     virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
     virtual void    ReadFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
 };
 
 class ParcelableType : public Type
@@ -318,18 +318,18 @@
     virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, int flags);
     virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
     virtual void    ReadFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
 
     virtual bool    CanBeArray() const;
 
     virtual void    WriteArrayToParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, int flags);
     virtual void    CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
     virtual void    ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
 };
 
 class InterfaceType : public Type
@@ -344,7 +344,7 @@
     virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, int flags);
     virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
                                     
 private:
     bool m_oneway;
@@ -364,9 +364,9 @@
     virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, int flags);
     virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
     virtual void    ReadFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
 
 private:
     string m_genericArguments;
@@ -387,9 +387,9 @@
     virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, int flags);
     virtual void    CreateFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
     virtual void    ReadFromParcel(StatementBlock* addTo, Variable* v,
-                                    Variable* parcel);
+                                    Variable* parcel, Variable** cl);
 
 private:
     string m_creator;
diff --git a/tools/aidl/aidl.cpp b/tools/aidl/aidl.cpp
index f17f66b..92f5b64 100644
--- a/tools/aidl/aidl.cpp
+++ b/tools/aidl/aidl.cpp
@@ -948,8 +948,6 @@
 int
 main(int argc, const char **argv)
 {
-    int err = 0;
-
     Options options;
     int result = parse_options(argc, argv, &options);
     if (result) {
diff --git a/tools/aidl/generate_java.cpp b/tools/aidl/generate_java.cpp
index 0f18132..83e3bbc 100644
--- a/tools/aidl/generate_java.cpp
+++ b/tools/aidl/generate_java.cpp
@@ -286,25 +286,25 @@
 
 static void
 generate_create_from_parcel(Type* t, StatementBlock* addTo, Variable* v,
-                            Variable* parcel)
+                            Variable* parcel, Variable** cl)
 {
     if (v->dimension == 0) {
-        t->CreateFromParcel(addTo, v, parcel);
+        t->CreateFromParcel(addTo, v, parcel, cl);
     }
     if (v->dimension == 1) {
-        t->CreateArrayFromParcel(addTo, v, parcel);
+        t->CreateArrayFromParcel(addTo, v, parcel, cl);
     }
 }
 
 static void
 generate_read_from_parcel(Type* t, StatementBlock* addTo, Variable* v,
-                            Variable* parcel)
+                            Variable* parcel, Variable** cl)
 {
     if (v->dimension == 0) {
-        t->ReadFromParcel(addTo, v, parcel);
+        t->ReadFromParcel(addTo, v, parcel, cl);
     }
     if (v->dimension == 1) {
-        t->ReadArrayFromParcel(addTo, v, parcel);
+        t->ReadArrayFromParcel(addTo, v, parcel, cl);
     }
 }
 
@@ -362,6 +362,7 @@
             "enforceInterface", 1, new LiteralExpression("DESCRIPTOR")));
 
     // args
+    Variable* cl = NULL;
     VariableFactory stubArgs("_arg");
     arg = method->args;
     while (arg != NULL) {
@@ -373,7 +374,7 @@
 
         if (convert_direction(arg->direction.data) & IN_PARAMETER) {
             generate_create_from_parcel(t, c->statements, v,
-                    stubClass->transact_data);
+                    stubClass->transact_data, &cl);
         } else {
             if (arg->type.dimension == 0) {
                 c->statements->Add(new Assignment(
@@ -531,7 +532,7 @@
     if (_reply != NULL) {
         if (_result != NULL) {
             generate_create_from_parcel(proxy->returnType,
-                                    tryStatement->statements, _result, _reply);
+                    tryStatement->statements, _result, _reply, &cl);
         }
 
         // the out/inout parameters
@@ -541,7 +542,7 @@
             Variable* v = new Variable(t, arg->name.data, arg->type.dimension);
             if (convert_direction(arg->direction.data) & OUT_PARAMETER) {
                 generate_read_from_parcel(t, tryStatement->statements,
-                                            v, _reply);
+                                            v, _reply, &cl);
             }
             arg = arg->next;
         }