Add cleanup call.
[mono.git] / mcs / mcs / parameter.cs
index 9ad2daa7b6d72d9a28ca041e20500f01f313a0a7..d344c3a8dcdc12a8177c0a90a0d77ee8a67ff681 100755 (executable)
@@ -23,19 +23,21 @@ namespace Mono.CSharp {
        public class Parameter {
                [Flags]
                public enum Modifier : byte {
-                       NONE   = 0,
-                       REF    = 1,
-                       OUT    = 2,
-                       PARAMS = 4,
+                       NONE    = 0,
+                       REF     = 1,
+                       OUT     = 2,
+                       PARAMS  = 4,
+                       // This is a flag which says that it's either REF or OUT.
+                       ISBYREF = 8
                }
 
-               public readonly string   TypeName;
-               public readonly string   Name;
+               public readonly Expression TypeName;
                public readonly Modifier ModFlags;
                public Attributes OptAttributes;
+               public readonly string Name;
                public Type parameter_type;
                
-               public Parameter (string type, string name, Modifier mod, Attributes attrs)
+               public Parameter (Expression type, string name, Modifier mod, Attributes attrs)
                {
                        Name = name;
                        ModFlags = mod;
@@ -48,23 +50,19 @@ namespace Mono.CSharp {
                // </summary>
                public bool Resolve (DeclSpace ds, Location l)
                {
-                       parameter_type = RootContext.LookupType (ds, TypeName, false, l);
-                       return parameter_type != null;
-               }
+                       parameter_type = ds.ResolveType (TypeName, false, l);
 
-               // <summary>
-               //   ResolveAndDefine is used by delegate declarations, because
-               //   they happen during the initial tree resolution process
-               // </summary>
-               public bool ResolveAndDefine (DeclSpace ds)
-               {
-                       parameter_type = ds.FindType (TypeName);
+                       if (parameter_type == TypeManager.void_type){
+                               Report.Error (1536, l, "`void' parameter is not permitted");
+                               return false;
+                       }
+                       
                        return parameter_type != null;
                }
-               
+
                public Type ExternalType (DeclSpace ds, Location l)
                {
-                       if ((ModFlags & (Parameter.Modifier.REF | Parameter.Modifier.OUT)) != 0){
+                       if ((ModFlags & Parameter.Modifier.ISBYREF) != 0){
                                string n = parameter_type.FullName + "&";
 
                                Type t = RootContext.LookupType (ds, n, false, l);
@@ -83,7 +81,8 @@ namespace Mono.CSharp {
                
                public ParameterAttributes Attributes {
                        get {
-                               switch (ModFlags){
+                               int flags = ((int) ModFlags) & ~((int) Parameter.Modifier.ISBYREF);
+                               switch ((Modifier) flags) {
                                case Modifier.NONE:
                                        return ParameterAttributes.None;
                                case Modifier.REF:
@@ -136,12 +135,13 @@ namespace Mono.CSharp {
                ///   This is used to reuse a set of empty parameters, because they
                ///   are common
                /// </summary>
-               public static Parameters GetEmptyReadOnlyParameters ()
-               {
-                       if (empty_parameters == null)
-                               empty_parameters = new Parameters (null, null, Location.Null);
+               public static Parameters EmptyReadOnlyParameters {
+                       get {
+                               if (empty_parameters == null)
+                                       empty_parameters = new Parameters (null, null, Location.Null);
                        
-                       return empty_parameters;
+                               return empty_parameters;
+                       }
                }
                
                public bool Empty {
@@ -166,7 +166,7 @@ namespace Mono.CSharp {
                        //
                }
 
-               static void error100 (string name)
+               static void Error_DuplicateParameterName (string name)
                {
                        Report.Error (
                                100, "The parameter name `" + name + "' is a duplicate");
@@ -188,12 +188,12 @@ namespace Mono.CSharp {
                                for (j = i + 1; j < count; j++){
                                        if (base_name != FixedParameters [j].Name)
                                                continue;
-                                       error100 (base_name);
+                                       Error_DuplicateParameterName (base_name);
                                        return false;
                                }
 
                                if (base_name == array_par_name){
-                                       error100 (base_name);
+                                       Error_DuplicateParameterName (base_name);
                                        return false;
                                }
                        }
@@ -275,14 +275,16 @@ namespace Mono.CSharp {
                                }
                        }
                        
-                       if (failed)
-                               types = null;
-                       
                        if (extra > 0){
                                if (ArrayParameter.Resolve (ds, loc))
                                        types [i] = ArrayParameter.ExternalType (ds, loc);
-                               else
-                                       return false;
+                               else 
+                                       failed = true;
+                       }
+
+                       if (failed){
+                               types = null;
+                               return false;
                        }
 
                        return true;
@@ -316,7 +318,7 @@ namespace Mono.CSharp {
                                foreach (Parameter p in FixedParameters){
                                        Type t = null;
                                        
-                                       if (p.ResolveAndDefine (ds))
+                                       if (p.Resolve (ds, loc))
                                                t = p.ExternalType (ds, loc);
                                        else
                                                ok_flag = false;
@@ -327,7 +329,7 @@ namespace Mono.CSharp {
                        }
                        
                        if (extra > 0){
-                               if (ArrayParameter.ResolveAndDefine (ds))
+                               if (ArrayParameter.Resolve (ds, loc))
                                        types [i] = ArrayParameter.ExternalType (ds, loc);
                                else
                                        ok_flag = false;
@@ -371,9 +373,9 @@ namespace Mono.CSharp {
                ///   Note that the returned type will not contain any dereference in this
                ///   case (ie, you get "int" for a ref int instead of "int&"
                /// </summary>
-               public Type GetParameterInfo (DeclSpace ds, int idx, out bool is_out)
+               public Type GetParameterInfo (DeclSpace ds, int idx, out Parameter.Modifier mod)
                {
-                       is_out = false;
+                       mod = Parameter.Modifier.NONE;
                        
                        if (!VerifyArgs ()){
                                FixedParameters = null;
@@ -384,25 +386,24 @@ namespace Mono.CSharp {
                                return null;
                        
                        if (types == null)
-                               if (ComputeParameterTypes (ds) == false){
-                                       is_out = false;
+                               if (ComputeParameterTypes (ds) == false)
                                        return null;
-                               }
 
                        //
                        // If this is a request for the variable lenght arg.
                        //
                        int array_idx = (FixedParameters != null ? FixedParameters.Length : 0);
-                       if (idx == array_idx){
-                               is_out = false;
+                       if (idx == array_idx)
                                return types [idx];
-                       } 
 
                        //
                        // Otherwise, it is a fixed parameter
                        //
                        Parameter p = FixedParameters [idx];
-                       is_out = ((p.ModFlags & (Parameter.Modifier.REF | Parameter.Modifier.OUT)) != 0);
+                       mod = p.ModFlags;
+
+                       if ((mod & (Parameter.Modifier.REF | Parameter.Modifier.OUT)) != 0)
+                               mod |= Parameter.Modifier.ISBYREF;
 
                        return p.ParameterType;
                }