X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fparameter.cs;h=25a7bba803c54eabc7e5864f8f9107423d5f2ed4;hb=3c055d5b4ae37ed3732dd6903c451f872ecfef27;hp=843028f920886c087b0e12e95aae2cad8e6501cb;hpb=7d264ba7cc444cef2e2fedf750f71c0e5475be03;p=mono.git diff --git a/mcs/mcs/parameter.cs b/mcs/mcs/parameter.cs index 843028f9208..25a7bba803c 100755 --- a/mcs/mcs/parameter.cs +++ b/mcs/mcs/parameter.cs @@ -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 Type ParameterType; + 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; @@ -43,28 +45,39 @@ namespace Mono.CSharp { OptAttributes = attrs; } + // + // Resolve is used in method definitions + // public bool Resolve (DeclSpace ds, Location l) { - ParameterType = RootContext.LookupType (ds, TypeName, false, l); - return ParameterType != null; + parameter_type = ds.ResolveType (TypeName, false, l); + + 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){ - string n = ParameterType.FullName + "&"; - - Type t = RootContext.LookupType (ds, n, false, l); + if ((ModFlags & Parameter.Modifier.ISBYREF) != 0) + return TypeManager.GetReferenceType (parameter_type); + + return parameter_type; + } - return t; + public Type ParameterType { + get { + return parameter_type; } - - return ParameterType; } 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: @@ -85,7 +98,7 @@ namespace Mono.CSharp { /// public string GetSignature (DeclSpace ds, Location loc) { - if (ParameterType == null){ + if (parameter_type == null){ if (!Resolve (ds, loc)) return null; } @@ -117,12 +130,13 @@ namespace Mono.CSharp { /// This is used to reuse a set of empty parameters, because they /// are common /// - 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 { @@ -147,7 +161,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"); @@ -169,12 +183,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; } } @@ -233,7 +247,7 @@ namespace Mono.CSharp { pc = extra; else pc = extra + FixedParameters.Length; - + types = new Type [pc]; if (!VerifyArgs ()){ @@ -241,12 +255,15 @@ namespace Mono.CSharp { return false; } + bool failed = false; if (FixedParameters != null){ foreach (Parameter p in FixedParameters){ Type t = null; if (p.Resolve (ds, loc)) t = p.ExternalType (ds, loc); + else + failed = true; types [i] = t; i++; @@ -256,10 +273,72 @@ namespace Mono.CSharp { if (extra > 0){ if (ArrayParameter.Resolve (ds, loc)) types [i] = ArrayParameter.ExternalType (ds, loc); + else + failed = true; + } + + if (failed){ + types = null; + return false; } return true; } + + // + // This variant is used by Delegates, because they need to + // resolve/define names, instead of the plain LookupType + // + public bool ComputeAndDefineParameterTypes (DeclSpace ds) + { + int extra = (ArrayParameter != null) ? 1 : 0; + int i = 0; + int pc; + + if (FixedParameters == null) + pc = extra; + else + pc = extra + FixedParameters.Length; + + types = new Type [pc]; + + if (!VerifyArgs ()){ + FixedParameters = null; + return false; + } + + bool ok_flag = true; + + if (FixedParameters != null){ + foreach (Parameter p in FixedParameters){ + Type t = null; + + if (p.Resolve (ds, loc)) + t = p.ExternalType (ds, loc); + else + ok_flag = false; + + types [i] = t; + i++; + } + } + + if (extra > 0){ + if (ArrayParameter.Resolve (ds, loc)) + types [i] = ArrayParameter.ExternalType (ds, loc); + else + ok_flag = false; + } + + // + // invalidate the cached types + // + if (!ok_flag){ + types = null; + } + + return ok_flag; + } /// /// Returns the argument types as an array @@ -274,9 +353,11 @@ namespace Mono.CSharp { if (FixedParameters == null && ArrayParameter == null) return no_types; - if (ComputeParameterTypes (ds) == false) + if (ComputeParameterTypes (ds) == false){ + types = null; return null; - + } + return types; } @@ -287,9 +368,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&" /// - 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; @@ -300,25 +381,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; }