actually fix the varargs handling
authorJb Evain <jbevain@gmail.com>
Thu, 19 Jul 2007 16:14:28 +0000 (16:14 -0000)
committerJb Evain <jbevain@gmail.com>
Thu, 19 Jul 2007 16:14:28 +0000 (16:14 -0000)
svn path=/trunk/mcs/; revision=82297

mcs/class/Mono.Cecil/Mono.Cecil.Cil/CodeReader.cs
mcs/class/Mono.Cecil/Mono.Cecil.Signatures/SignatureReader.cs
mcs/class/Mono.Cecil/Mono.Cecil.Signatures/SignatureWriter.cs
mcs/class/Mono.Cecil/Mono.Cecil/MethodReference.cs
mcs/class/Mono.Cecil/Mono.Cecil/ReflectionReader.cs
mcs/class/Mono.Cecil/Mono.Cecil/SentinelType.cs

index 8e9c313ba59e21e670747a10a4aef21e57159bb5..696b34ee67365bd78aabd1043f294ba139b1e444 100644 (file)
@@ -325,12 +325,11 @@ namespace Mono.Cecil.Cil {
 
                        for (int i = 0; i < ms.ParamCount; i++) {
                                Param p = ms.Parameters [i];
-                               cs.Parameters.Add (m_reflectReader.BuildParameterDefinition (
-                                               string.Concat ("A_", i),
-                                               i, (ParameterAttributes) 0,
-                                               p, context));
+                               cs.Parameters.Add (m_reflectReader.BuildParameterDefinition (i, p, context));
                        }
 
+                       ReflectionReader.CreateSentinelIfNeeded (cs, ms);
+
                        return cs;
                }
 
index 82e591a524b516e3ce2126272d82475e3bcbb54d..7f8b00b101b02f1d22b55292424c611c406f3aeb 100644 (file)
@@ -401,8 +401,10 @@ namespace Mono.Cecil.Signatures {
                                int curs = start;
                                int flag = Utilities.ReadCompressedInteger (data, start, out start);
 
-                               if (flag == (int) ElementType.Sentinel)
+                               if (flag == (int) ElementType.Sentinel) {
                                        sentinelpos = i;
+                                       curs = start;
+                               }
 
                                ret [i] = ReadParameter (data, curs, out start);
                        }
index e47d8a92a6fbc1e0a46a765bdbf655bacb7ae189..65714503d5a3ba57f8b6bf76c9823ad3ad7524d9 100644 (file)
@@ -137,7 +137,7 @@ namespace Mono.Cecil.Signatures {
                                Write (methodDef.GenericParameterCount);
                        Write (methodDef.ParamCount);
                        Write (methodDef.RetType);
-                       Write (methodDef.Parameters);
+                       Write (methodDef.Parameters, methodDef.Sentinel);
                }
 
                public override void VisitMethodRefSig (MethodRefSig methodRef)
@@ -145,7 +145,7 @@ namespace Mono.Cecil.Signatures {
                        m_sigWriter.Write (methodRef.CallingConvention);
                        Write (methodRef.ParamCount);
                        Write (methodRef.RetType);
-                       Write (methodRef.Parameters);
+                       Write (methodRef.Parameters, methodRef.Sentinel);
                }
 
                public override void VisitFieldSig (FieldSig field)
@@ -201,6 +201,16 @@ namespace Mono.Cecil.Signatures {
                                Write (retType.Type);
                }
 
+               void Write (Param [] parameters, int sentinel)
+               {
+                       for (int i = 0; i < parameters.Length; i++) {
+                               if (i == sentinel)
+                                       Write (ElementType.Sentinel);
+
+                               Write (parameters [i]);
+                       }
+               }
+
                void Write (Param [] parameters)
                {
                        foreach (Param p in parameters)
index 7f589ba01f939693994305b3a928f904dba286a1..dff8dac543b8483e95270918c948a00b80df3d54 100644 (file)
@@ -110,13 +110,19 @@ namespace Mono.Cecil {
 
                public override string ToString ()
                {
+                       int sentinel = GetSentinel ();
+
                        StringBuilder sb = new StringBuilder ();
                        sb.Append (m_returnType.ReturnType.FullName);
                        sb.Append (" ");
                        sb.Append (base.ToString ());
                        sb.Append ("(");
                        for (int i = 0; i < this.Parameters.Count; i++) {
+                               if (i == sentinel)
+                                       sb.Append ("...,");
+
                                sb.Append (this.Parameters [i].ParameterType.FullName);
+
                                if (i < this.Parameters.Count - 1)
                                        sb.Append (",");
                        }
index fff0d9ba71420fc00ac965edc2c9df2b98f0fd4a..c9fab35216bc7ea8988a3ac871fff04e97d82c6f 100644 (file)
@@ -210,45 +210,14 @@ namespace Mono.Cecil {
                                        string name = m_root.Streams.StringsHeap [mrefRow.Name];
                                        MethodSig ms = (MethodSig) sig;
 
-                                       MethodReference methref = new MethodReference (
-                                               name, ms.HasThis, ms.ExplicitThis, ms.MethCallConv);
-                                       methref.DeclaringType = declaringType;
-
-                                       if (sig is MethodDefSig) {
-                                               int arity = (sig as MethodDefSig).GenericParameterCount;
-                                               for (int i = 0; i < arity; i++)
-                                                       methref.GenericParameters.Add (new GenericParameter (i, methref));
-                                       }
-
-                                       if (methref.GenericParameters.Count > 0)
-                                               nc.Method = methref;
-
-                                       methref.ReturnType = GetMethodReturnType (ms, nc);
-
-                                       methref.ReturnType.Method = methref;
-                                       for (int j = 0; j < ms.ParamCount; j++) {
-                                               Param p = ms.Parameters [j];
-                                               ParameterDefinition pdef = BuildParameterDefinition (
-                                                       string.Concat ("A_", j), j, new ParameterAttributes (), p, nc);
-                                               pdef.Method = methref;
-                                               methref.Parameters.Add (pdef);
-                                       }
-
-                                       member = methref;
+                                       member = CreateMethodReferenceFromSig (ms, name, declaringType, nc);
                                }
                                break;
                        case TokenType.Method :
                                // really not sure about this
                                MethodDefinition methdef = GetMethodDefAt (mrefRow.Class.RID);
-                               MethodReference methRef = new MethodReference (
-                                       methdef.Name, methdef.HasThis,
-                                       methdef.ExplicitThis, methdef.CallingConvention);
-
-                               methRef.DeclaringType = methdef.DeclaringType;
-                               methRef.ReturnType = methdef.ReturnType;
-                               foreach (ParameterDefinition param in methdef.Parameters)
-                                       methRef.Parameters.Add (param);
-                               member = methRef;
+
+                               member = CreateMethodReferenceFromSig ((MethodSig) sig, methdef.Name, methdef.DeclaringType, new GenericContext ());
                                break;
                        case TokenType.ModuleRef :
                                break; // TODO, implement that, or not
@@ -261,6 +230,51 @@ namespace Mono.Cecil {
                        return member;
                }
 
+               MethodReference CreateMethodReferenceFromSig (MethodSig ms, string name, TypeReference declaringType, GenericContext context)
+               {
+                       MethodReference methref = new MethodReference (
+                               name, ms.HasThis, ms.ExplicitThis, ms.MethCallConv);
+                       methref.DeclaringType = declaringType;
+
+                       if (ms is MethodDefSig) {
+                               int arity = (ms as MethodDefSig).GenericParameterCount;
+                               for (int i = 0; i < arity; i++)
+                                       methref.GenericParameters.Add (new GenericParameter (i, methref));
+                       }
+
+                       if (methref.GenericParameters.Count > 0)
+                               context.Method = methref;
+
+                       methref.ReturnType = GetMethodReturnType (ms, context);
+
+                       methref.ReturnType.Method = methref;
+                       for (int j = 0; j < ms.ParamCount; j++) {
+                               Param p = ms.Parameters [j];
+                               ParameterDefinition pdef = BuildParameterDefinition (j, p, context);
+                               pdef.Method = methref;
+                               methref.Parameters.Add (pdef);
+                       }
+
+                       CreateSentinelIfNeeded (methref, ms);
+
+                       return methref;
+               }
+
+               public static void CreateSentinelIfNeeded (IMethodSignature meth, MethodSig signature)
+               {
+                       MethodDefSig sig = signature as MethodDefSig;
+                       if (sig == null)
+                               return;
+
+                       int sentinel = sig.Sentinel;
+
+                       if (sig.Sentinel < 0 || sig.Sentinel >= meth.Parameters.Count)
+                               return;
+
+                       ParameterDefinition param = meth.Parameters [sentinel];
+                       param.ParameterType = new SentinelType (param.ParameterType);
+               }
+
                public PropertyDefinition GetPropertyDefAt (uint rid)
                {
                        return m_properties [rid - 1];
@@ -711,9 +725,7 @@ namespace Mono.Cecil {
                                                        pdef.MetadataToken = MetadataToken.FromMetadataRow (TokenType.Param, pointer);
                                                        m_parameters [pointer] = pdef;
                                                } else
-                                                       pdef = BuildParameterDefinition (
-                                                               string.Concat ("A_", mdef.IsStatic ? k : k + 1),
-                                                               k + 1, (ParameterAttributes) 0, psig, context);
+                                                       pdef = BuildParameterDefinition (k + 1, psig, context);
 
                                                pdef.Method = mdef;
                                                mdef.Parameters.Add (pdef);
@@ -835,25 +847,40 @@ namespace Mono.Cecil {
                        return cattr;
                }
 
-               public ParameterDefinition BuildParameterDefinition (string name, int sequence,
-                       ParameterAttributes attrs, Param psig, GenericContext context)
+               void CompleteParameter (ParameterDefinition parameter, Param signature, GenericContext context)
                {
-                       ParameterDefinition ret = new ParameterDefinition (name, sequence, attrs, null);
                        TypeReference paramType;
 
-                       if (psig.ByRef)
-                               paramType = new ReferenceType (GetTypeRefFromSig (psig.Type, context));
-                       else if (psig.TypedByRef)
+                       if (signature.ByRef)
+                               paramType = new ReferenceType (GetTypeRefFromSig (signature.Type, context));
+                       else if (signature.TypedByRef)
                                paramType = SearchCoreType (Constants.TypedReference);
                        else
-                               paramType = GetTypeRefFromSig (psig.Type, context);
+                               paramType = GetTypeRefFromSig (signature.Type, context);
 
-                       if (psig.CustomMods.Length > 0)
-                               paramType = GetModifierType (psig.CustomMods, paramType);
+                       if (signature.CustomMods.Length > 0)
+                               paramType = GetModifierType (signature.CustomMods, paramType);
 
-                       ret.ParameterType = paramType;
+                       parameter.ParameterType = paramType;
+               }
 
-                       return ret;
+               public ParameterDefinition BuildParameterDefinition (int sequence, Param psig, GenericContext context)
+               {
+                       ParameterDefinition parameter = new ParameterDefinition (null);
+                       parameter.Sequence = sequence;
+
+                       CompleteParameter (parameter, psig, context);
+
+                       return parameter;
+               }
+
+               public ParameterDefinition BuildParameterDefinition (string name, int sequence, ParameterAttributes attrs, Param psig, GenericContext context)
+               {
+                       ParameterDefinition parameter = new ParameterDefinition (name, sequence, attrs, null);
+
+                       CompleteParameter (parameter, psig, context);
+
+                       return parameter;
                }
 
                protected SecurityDeclaration BuildSecurityDeclaration (DeclSecurityRow dsRow)
@@ -1010,12 +1037,11 @@ namespace Mono.Cecil {
 
                                for (int i = 0; i < funcptr.Method.ParamCount; i++) {
                                        Param p = funcptr.Method.Parameters [i];
-                                       fnptr.Parameters.Add (BuildParameterDefinition (
-                                                       string.Concat ("A_", i),
-                                                       i, (ParameterAttributes) 0,
-                                                       p, context));
+                                       fnptr.Parameters.Add (BuildParameterDefinition (i, p, context));
                                }
 
+                               CreateSentinelIfNeeded (fnptr, funcptr.Method);
+
                                return fnptr;
                        case ElementType.Var:
                                VAR var = t as VAR;
@@ -1042,8 +1068,6 @@ namespace Mono.Cecil {
                                                ginst.Signature.Types [i], context));
 
                                return instance;
-                       case ElementType.Sentinel:
-                               return new SentinelType ();
                        default:
                                break;
                        }
index 5fa097275aa5ac6bf8c2e4185306ccec12737792..1aed1609a33beb2acaacb09417892af07dd8e6d7 100644 (file)
@@ -28,9 +28,9 @@
 
 namespace Mono.Cecil {
 
-       public sealed class SentinelType : TypeReference {
+       public sealed class SentinelType : TypeSpecification {
 
-               public SentinelType () : base ("...", null)
+               public SentinelType (TypeReference elementType) : base (elementType)
                {
                }
        }