PageRenderTime 69ms CodeModel.GetById 13ms app.highlight 45ms RepoModel.GetById 1ms app.codeStats 0ms

/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/parameter.cs

http://github.com/icsharpcode/ILSpy
C# | 1472 lines | 1104 code | 250 blank | 118 comment | 299 complexity | e6be4bca20fe1faa7ab400d09f4fccc8 MD5 | raw file
   1//
   2// parameter.cs: Parameter definition.
   3//
   4// Author: Miguel de Icaza (miguel@gnu.org)
   5//         Marek Safar (marek.safar@seznam.cz)
   6//
   7// Dual licensed under the terms of the MIT X11 or GNU GPL
   8//
   9// Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
  10// Copyright 2003-2008 Novell, Inc. 
  11// Copyright 2011 Xamarin Inc
  12//
  13//
  14using System;
  15using System.Text;
  16
  17#if STATIC
  18using MetaType = IKVM.Reflection.Type;
  19using IKVM.Reflection;
  20using IKVM.Reflection.Emit;
  21#else
  22using MetaType = System.Type;
  23using System.Reflection;
  24using System.Reflection.Emit;
  25#endif
  26
  27namespace Mono.CSharp {
  28
  29	/// <summary>
  30	///   Abstract Base class for parameters of a method.
  31	/// </summary>
  32	public abstract class ParameterBase : Attributable
  33	{
  34		protected ParameterBuilder builder;
  35
  36		public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
  37		{
  38#if false
  39			if (a.Type == pa.MarshalAs) {
  40				UnmanagedMarshal marshal = a.GetMarshal (this);
  41				if (marshal != null) {
  42					builder.SetMarshal (marshal);
  43				}
  44				return;
  45			}
  46#endif
  47			if (a.HasSecurityAttribute) {
  48				a.Error_InvalidSecurityParent ();
  49				return;
  50			}
  51
  52			if (a.Type == pa.Dynamic) {
  53				a.Error_MisusedDynamicAttribute ();
  54				return;
  55			}
  56
  57			builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
  58		}
  59
  60		public ParameterBuilder Builder {
  61			get {
  62				return builder;
  63			}
  64		}
  65
  66		public override bool IsClsComplianceRequired()
  67		{
  68			return false;
  69		}
  70	}
  71
  72	/// <summary>
  73	/// Class for applying custom attributes on the return type
  74	/// </summary>
  75	public class ReturnParameter : ParameterBase
  76	{
  77		MemberCore method;
  78
  79		// TODO: merge method and mb
  80		public ReturnParameter (MemberCore method, MethodBuilder mb, Location location)
  81		{
  82			this.method = method;
  83			try {
  84				builder = mb.DefineParameter (0, ParameterAttributes.None, "");			
  85			}
  86			catch (ArgumentOutOfRangeException) {
  87				method.Compiler.Report.RuntimeMissingSupport (location, "custom attributes on the return type");
  88			}
  89		}
  90
  91		public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
  92		{
  93			if (a.Type == pa.CLSCompliant) {
  94				method.Compiler.Report.Warning (3023, 1, a.Location,
  95					"CLSCompliant attribute has no meaning when applied to return types. Try putting it on the method instead");
  96			}
  97
  98			// This occurs after Warning -28
  99			if (builder == null)
 100				return;
 101
 102			base.ApplyAttributeBuilder (a, ctor, cdata, pa);
 103		}
 104
 105		public override AttributeTargets AttributeTargets {
 106			get {
 107				return AttributeTargets.ReturnValue;
 108			}
 109		}
 110
 111		/// <summary>
 112		/// Is never called
 113		/// </summary>
 114		public override string[] ValidAttributeTargets {
 115			get {
 116				return null;
 117			}
 118		}
 119	}
 120
 121	public class ImplicitLambdaParameter : Parameter
 122	{
 123		public ImplicitLambdaParameter (string name, Location loc)
 124			: base (null, name, Modifier.NONE, null, loc)
 125		{
 126		}
 127
 128		public override TypeSpec Resolve (IMemberContext ec, int index)
 129		{
 130			if (parameter_type == null)
 131				throw new InternalErrorException ("A type of implicit lambda parameter `{0}' is not set",
 132					Name);
 133
 134			base.idx = index;
 135			return parameter_type;
 136		}
 137
 138		public void SetParameterType (TypeSpec type)
 139		{
 140			parameter_type = type;
 141		}
 142	}
 143
 144	public class ParamsParameter : Parameter {
 145		public ParamsParameter (FullNamedExpression type, string name, Attributes attrs, Location loc):
 146			base (type, name, Parameter.Modifier.PARAMS, attrs, loc)
 147		{
 148		}
 149
 150		public override TypeSpec Resolve (IMemberContext ec, int index)
 151		{
 152			if (base.Resolve (ec, index) == null)
 153				return null;
 154
 155			var ac = parameter_type as ArrayContainer;
 156			if (ac == null || ac.Rank != 1) {
 157				ec.Module.Compiler.Report.Error (225, Location, "The params parameter must be a single dimensional array");
 158				return null;
 159			}
 160
 161			return parameter_type;
 162		}
 163
 164		public override void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index, PredefinedAttributes pa)
 165		{
 166			base.ApplyAttributes (mb, cb, index, pa);
 167			pa.ParamArray.EmitAttribute (builder);
 168		}
 169	}
 170
 171	public class ArglistParameter : Parameter {
 172		// Doesn't have proper type because it's never chosen for better conversion
 173		public ArglistParameter (Location loc) :
 174			base (null, String.Empty, Parameter.Modifier.NONE, null, loc)
 175		{
 176			parameter_type = InternalType.Arglist;
 177		}
 178
 179		public override void  ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index, PredefinedAttributes pa)
 180		{
 181			// Nothing to do
 182		}
 183
 184		public override bool CheckAccessibility (InterfaceMemberBase member)
 185		{
 186			return true;
 187		}
 188
 189		public override TypeSpec Resolve (IMemberContext ec, int index)
 190		{
 191			return parameter_type;
 192		}
 193	}
 194
 195	public interface IParameterData
 196	{
 197		Expression DefaultValue { get; }
 198		bool HasExtensionMethodModifier { get; }
 199		bool HasDefaultValue { get; }
 200		Parameter.Modifier ModFlags { get; }
 201		string Name { get; }
 202	}
 203
 204	//
 205	// Parameter information created by parser
 206	//
 207	public class Parameter : ParameterBase, IParameterData, ILocalVariable // TODO: INamedBlockVariable
 208	{
 209		[Flags]
 210		public enum Modifier : byte {
 211			NONE    = 0,
 212			PARAMS  = 1 << 0,
 213			REF = 1 << 1,
 214			OUT = 1 << 2,
 215			This = 1 << 3,
 216			CallerMemberName = 1 << 4,
 217			CallerLineNumber = 1 << 5,
 218			CallerFilePath = 1 << 6,
 219
 220			RefOutMask = REF | OUT,
 221			ModifierMask = PARAMS | REF | OUT | This,
 222			CallerMask = CallerMemberName | CallerLineNumber | CallerFilePath
 223		}
 224
 225		static readonly string[] attribute_targets = new [] { "param" };
 226
 227		FullNamedExpression texpr;
 228		Modifier modFlags;
 229		string name;
 230		Expression default_expr;
 231		protected TypeSpec parameter_type;
 232		readonly Location loc;
 233		protected int idx;
 234		public bool HasAddressTaken;
 235
 236		TemporaryVariableReference expr_tree_variable;
 237
 238		HoistedParameter hoisted_variant;
 239
 240		public Parameter (FullNamedExpression type, string name, Modifier mod, Attributes attrs, Location loc)
 241		{
 242			this.name = name;
 243			modFlags = mod;
 244			this.loc = loc;
 245			texpr = type;
 246
 247			// Only assign, attributes will be attached during resolve
 248			base.attributes = attrs;
 249		}
 250
 251		#region Properties
 252
 253		public Expression DefaultExpression {
 254			get {
 255				return default_expr;
 256			}
 257		}
 258
 259		public DefaultParameterValueExpression DefaultValue {
 260			get {
 261				return default_expr as DefaultParameterValueExpression;
 262			}
 263			set {
 264				default_expr = value;
 265			}
 266		}
 267
 268		Expression IParameterData.DefaultValue {
 269			get {
 270				var expr = default_expr as DefaultParameterValueExpression;
 271				return expr == null ? default_expr : expr.Child;
 272			}
 273		}
 274
 275		bool HasOptionalExpression {
 276			get {
 277				return default_expr is DefaultParameterValueExpression;
 278			}
 279		}
 280
 281		public Location Location {
 282			get {
 283				return loc;
 284			}
 285		}
 286
 287		public Modifier ParameterModifier {
 288			get {
 289				return modFlags;
 290			}
 291		}
 292
 293		public TypeSpec Type {
 294			get {
 295				return parameter_type;
 296			}
 297			set {
 298				parameter_type = value;
 299			}
 300		}
 301
 302		public FullNamedExpression TypeExpression  {
 303			get {
 304				return texpr;
 305			}
 306		}
 307
 308		public override string[] ValidAttributeTargets {
 309			get {
 310				return attribute_targets;
 311			}
 312		}
 313
 314		#endregion
 315
 316		public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
 317		{
 318			if (a.Type == pa.In && ModFlags == Modifier.OUT) {
 319				a.Report.Error (36, a.Location, "An out parameter cannot have the `In' attribute");
 320				return;
 321			}
 322
 323			if (a.Type == pa.ParamArray) {
 324				a.Report.Error (674, a.Location, "Do not use `System.ParamArrayAttribute'. Use the `params' keyword instead");
 325				return;
 326			}
 327
 328			if (a.Type == pa.Out && (ModFlags & Modifier.REF) != 0 &&
 329			    !OptAttributes.Contains (pa.In)) {
 330				a.Report.Error (662, a.Location,
 331					"Cannot specify only `Out' attribute on a ref parameter. Use both `In' and `Out' attributes or neither");
 332				return;
 333			}
 334
 335			if (a.Type == pa.CLSCompliant) {
 336				a.Report.Warning (3022, 1, a.Location, "CLSCompliant attribute has no meaning when applied to parameters. Try putting it on the method instead");
 337			} else if (a.Type == pa.DefaultParameterValue || a.Type == pa.OptionalParameter) {
 338				if (HasOptionalExpression) {
 339					a.Report.Error (1745, a.Location,
 340						"Cannot specify `{0}' attribute on optional parameter `{1}'",
 341						a.Type.GetSignatureForError ().Replace ("Attribute", ""), Name);
 342				}
 343
 344				if (a.Type == pa.DefaultParameterValue)
 345					return;
 346			} else if (a.Type == pa.CallerMemberNameAttribute) {
 347				if ((modFlags & Modifier.CallerMemberName) == 0) {
 348					a.Report.Error (4022, a.Location,
 349						"The CallerMemberName attribute can only be applied to parameters with default value");
 350				}
 351			} else if (a.Type == pa.CallerLineNumberAttribute) {
 352				if ((modFlags & Modifier.CallerLineNumber) == 0) {
 353					a.Report.Error (4020, a.Location,
 354						"The CallerLineNumber attribute can only be applied to parameters with default value");
 355				}
 356			} else if (a.Type == pa.CallerFilePathAttribute) {
 357				if ((modFlags & Modifier.CallerFilePath) == 0) {
 358					a.Report.Error (4021, a.Location,
 359						"The CallerFilePath attribute can only be applied to parameters with default value");
 360				}
 361			}
 362
 363			base.ApplyAttributeBuilder (a, ctor, cdata, pa);
 364		}
 365		
 366		public virtual bool CheckAccessibility (InterfaceMemberBase member)
 367		{
 368			if (parameter_type == null)
 369				return true;
 370
 371			return member.IsAccessibleAs (parameter_type);
 372		}
 373
 374		bool IsValidCallerContext (MemberCore memberContext)
 375		{
 376			var m = memberContext as Method;
 377			if (m != null)
 378				return !m.IsPartialImplementation;
 379
 380			return true;
 381		}
 382
 383		// <summary>
 384		//   Resolve is used in method definitions
 385		// </summary>
 386		public virtual TypeSpec Resolve (IMemberContext rc, int index)
 387		{
 388			if (parameter_type != null)
 389				return parameter_type;
 390
 391			if (attributes != null)
 392				attributes.AttachTo (this, rc);
 393
 394			parameter_type = texpr.ResolveAsType (rc);
 395			if (parameter_type == null)
 396				return null;
 397
 398			this.idx = index;
 399
 400			if ((modFlags & Parameter.Modifier.RefOutMask) != 0 && parameter_type.IsSpecialRuntimeType) {
 401				rc.Module.Compiler.Report.Error (1601, Location, "Method or delegate parameter cannot be of type `{0}'",
 402					GetSignatureForError ());
 403				return null;
 404			}
 405
 406			VarianceDecl.CheckTypeVariance (parameter_type,
 407				(modFlags & Parameter.Modifier.RefOutMask) != 0 ? Variance.None : Variance.Contravariant,
 408				rc);
 409
 410			if (parameter_type.IsStatic) {
 411				rc.Module.Compiler.Report.Error (721, Location, "`{0}': static types cannot be used as parameters",
 412					texpr.GetSignatureForError ());
 413				return parameter_type;
 414			}
 415
 416			if ((modFlags & Modifier.This) != 0 && (parameter_type.IsPointer || parameter_type.BuiltinType == BuiltinTypeSpec.Type.Dynamic)) {
 417				rc.Module.Compiler.Report.Error (1103, Location, "The extension method cannot be of type `{0}'",
 418					parameter_type.GetSignatureForError ());
 419			}
 420
 421			return parameter_type;
 422		}
 423
 424		void ResolveCallerAttributes (ResolveContext rc)
 425		{
 426			var pa = rc.Module.PredefinedAttributes;
 427			TypeSpec caller_type;
 428			Attribute callerMemberName = null, callerFilePath = null;
 429
 430			foreach (var attr in attributes.Attrs) {
 431				var atype = attr.ResolveTypeForComparison ();
 432				if (atype == null)
 433					continue;
 434
 435				if (atype == pa.CallerMemberNameAttribute) {
 436					caller_type = rc.BuiltinTypes.String;
 437					if (caller_type != parameter_type && !Convert.ImplicitReferenceConversionExists (caller_type, parameter_type)) {
 438						rc.Report.Error (4019, attr.Location,
 439							"The CallerMemberName attribute cannot be applied because there is no standard conversion from `{0}' to `{1}'",
 440							caller_type.GetSignatureForError (), parameter_type.GetSignatureForError ());
 441					}
 442
 443					if (!IsValidCallerContext (rc.CurrentMemberDefinition)) {
 444						rc.Report.Warning (4026, 1, attr.Location,
 445							"The CallerMemberName applied to parameter `{0}' will have no effect because it applies to a member that is used in context that do not allow optional arguments",
 446							name);
 447					}
 448
 449					modFlags |= Modifier.CallerMemberName;
 450					callerMemberName = attr;
 451					continue;
 452				}
 453
 454				if (atype == pa.CallerLineNumberAttribute) {
 455					caller_type = rc.BuiltinTypes.Int;
 456					if (caller_type != parameter_type && !Convert.ImplicitStandardConversionExists (new IntConstant (caller_type, int.MaxValue, Location.Null), parameter_type)) {
 457						rc.Report.Error (4017, attr.Location,
 458							"The CallerLineNumberAttribute attribute cannot be applied because there is no standard conversion from `{0}' to `{1}'",
 459							caller_type.GetSignatureForError (), parameter_type.GetSignatureForError ());
 460					}
 461
 462					if (!IsValidCallerContext (rc.CurrentMemberDefinition)) {
 463						rc.Report.Warning (4024, 1, attr.Location,
 464							"The CallerLineNumberAttribute applied to parameter `{0}' will have no effect because it applies to a member that is used in context that do not allow optional arguments",
 465							name);
 466					}
 467
 468					modFlags |= Modifier.CallerLineNumber;
 469					continue;
 470				}
 471
 472				if (atype == pa.CallerFilePathAttribute) {
 473					caller_type = rc.BuiltinTypes.String;
 474					if (caller_type != parameter_type && !Convert.ImplicitReferenceConversionExists (caller_type, parameter_type)) {
 475						rc.Report.Error (4018, attr.Location,
 476							"The CallerFilePath attribute cannot be applied because there is no standard conversion from `{0}' to `{1}'",
 477							caller_type.GetSignatureForError (), parameter_type.GetSignatureForError ());
 478					}
 479
 480					if (!IsValidCallerContext (rc.CurrentMemberDefinition)) {
 481						rc.Report.Warning (4025, 1, attr.Location,
 482							"The CallerFilePath applied to parameter `{0}' will have no effect because it applies to a member that is used in context that do not allow optional arguments",
 483							name);
 484					}
 485
 486					modFlags |= Modifier.CallerFilePath;
 487					callerFilePath = attr;
 488					continue;
 489				}
 490			}
 491
 492			if ((modFlags & Modifier.CallerLineNumber) != 0) {
 493				if (callerMemberName != null) {
 494					rc.Report.Warning (7081, 1, callerMemberName.Location,
 495						"The CallerMemberNameAttribute applied to parameter `{0}' will have no effect. It is overridden by the CallerLineNumberAttribute",
 496						Name);
 497				}
 498
 499				if (callerFilePath != null) {
 500					rc.Report.Warning (7082, 1, callerFilePath.Location,
 501						"The CallerFilePathAttribute applied to parameter `{0}' will have no effect. It is overridden by the CallerLineNumberAttribute",
 502						name);
 503				}
 504			}
 505
 506			if ((modFlags & Modifier.CallerMemberName) != 0) {
 507				if (callerFilePath != null) {
 508					rc.Report.Warning (7080, 1, callerFilePath.Location,
 509						"The CallerMemberNameAttribute applied to parameter `{0}' will have no effect. It is overridden by the CallerFilePathAttribute",
 510						name);
 511				}
 512
 513			}
 514		}
 515
 516		public void ResolveDefaultValue (ResolveContext rc)
 517		{
 518			//
 519			// Default value was specified using an expression
 520			//
 521			if (default_expr != null) {
 522				((DefaultParameterValueExpression)default_expr).Resolve (rc, this);
 523				if (attributes != null)
 524					ResolveCallerAttributes (rc);
 525
 526				return;
 527			}
 528
 529			if (attributes == null)
 530				return;
 531
 532			var pa = rc.Module.PredefinedAttributes;
 533			var def_attr = attributes.Search (pa.DefaultParameterValue);
 534			if (def_attr != null) {
 535				if (def_attr.Resolve () == null)
 536					return;
 537
 538				var default_expr_attr = def_attr.GetParameterDefaultValue ();
 539				if (default_expr_attr == null)
 540					return;
 541
 542				var dpa_rc = def_attr.CreateResolveContext ();
 543				default_expr = default_expr_attr.Resolve (dpa_rc);
 544
 545				if (default_expr is BoxedCast)
 546					default_expr = ((BoxedCast) default_expr).Child;
 547
 548				Constant c = default_expr as Constant;
 549				if (c == null) {
 550					if (parameter_type.BuiltinType == BuiltinTypeSpec.Type.Object) {
 551						rc.Report.Error (1910, default_expr.Location,
 552							"Argument of type `{0}' is not applicable for the DefaultParameterValue attribute",
 553							default_expr.Type.GetSignatureForError ());
 554					} else {
 555						rc.Report.Error (1909, default_expr.Location,
 556							"The DefaultParameterValue attribute is not applicable on parameters of type `{0}'",
 557							default_expr.Type.GetSignatureForError ());
 558					}
 559
 560					default_expr = null;
 561					return;
 562				}
 563
 564				if (TypeSpecComparer.IsEqual (default_expr.Type, parameter_type) ||
 565					(default_expr is NullConstant && TypeSpec.IsReferenceType (parameter_type) && !parameter_type.IsGenericParameter) ||
 566					parameter_type.BuiltinType == BuiltinTypeSpec.Type.Object) {
 567					return;
 568				}
 569
 570				//
 571				// LAMESPEC: Some really weird csc behaviour which we have to mimic
 572				// User operators returning same type as parameter type are considered
 573				// valid for this attribute only
 574				//
 575				// struct S { public static implicit operator S (int i) {} }
 576				//
 577				// void M ([DefaultParameterValue (3)]S s)
 578				//
 579				var expr = Convert.ImplicitUserConversion (dpa_rc, default_expr, parameter_type, loc);
 580				if (expr != null && TypeSpecComparer.IsEqual (expr.Type, parameter_type)) {
 581					return;
 582				}
 583				
 584				rc.Report.Error (1908, default_expr.Location, "The type of the default value should match the type of the parameter");
 585				return;
 586			}
 587
 588			var opt_attr = attributes.Search (pa.OptionalParameter);
 589			if (opt_attr != null) {
 590				default_expr = EmptyExpression.MissingValue;
 591			}
 592		}
 593
 594		public bool HasDefaultValue {
 595			get { return default_expr != null; }
 596		}
 597
 598		public bool HasExtensionMethodModifier {
 599			get { return (modFlags & Modifier.This) != 0; }
 600		}
 601
 602		//
 603		// Hoisted parameter variant
 604		//
 605		public HoistedParameter HoistedVariant {
 606			get {
 607				return hoisted_variant;
 608			}
 609			set {
 610				hoisted_variant = value;
 611			}
 612		}
 613
 614		public Modifier ModFlags {
 615			get { return modFlags & ~Modifier.This; }
 616		}
 617
 618		public string Name {
 619			get { return name; }
 620			set { name = value; }
 621		}
 622
 623		public override AttributeTargets AttributeTargets {
 624			get {
 625				return AttributeTargets.Parameter;
 626			}
 627		}
 628
 629		public void Error_DuplicateName (Report r)
 630		{
 631			r.Error (100, Location, "The parameter name `{0}' is a duplicate", Name);
 632		}
 633
 634		public virtual string GetSignatureForError ()
 635		{
 636			string type_name;
 637			if (parameter_type != null)
 638				type_name = parameter_type.GetSignatureForError ();
 639			else
 640				type_name = texpr.GetSignatureForError ();
 641
 642			string mod = GetModifierSignature (modFlags);
 643			if (mod.Length > 0)
 644				return String.Concat (mod, " ", type_name);
 645
 646			return type_name;
 647		}
 648
 649		public static string GetModifierSignature (Modifier mod)
 650		{
 651			switch (mod) {
 652			case Modifier.OUT:
 653				return "out";
 654			case Modifier.PARAMS:
 655				return "params";
 656			case Modifier.REF:
 657				return "ref";
 658			case Modifier.This:
 659				return "this";
 660			default:
 661				return "";
 662			}
 663		}
 664
 665		public void IsClsCompliant (IMemberContext ctx)
 666		{
 667			if (parameter_type.IsCLSCompliant ())
 668				return;
 669
 670			ctx.Module.Compiler.Report.Warning (3001, 1, Location,
 671				"Argument type `{0}' is not CLS-compliant", parameter_type.GetSignatureForError ());
 672		}
 673
 674		public virtual void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index, PredefinedAttributes pa)
 675		{
 676			if (builder != null)
 677				throw new InternalErrorException ("builder already exists");
 678
 679			var pattrs = ParametersCompiled.GetParameterAttribute (modFlags);
 680			if (HasOptionalExpression)
 681				pattrs |= ParameterAttributes.Optional;
 682
 683			if (mb == null)
 684				builder = cb.DefineParameter (index, pattrs, Name);
 685			else
 686				builder = mb.DefineParameter (index, pattrs, Name);
 687
 688			if (OptAttributes != null)
 689				OptAttributes.Emit ();
 690
 691			if (HasDefaultValue && default_expr.Type != null) {
 692				//
 693				// Emit constant values for true constants only, the other
 694				// constant-like expressions will rely on default value expression
 695				//
 696				var def_value = DefaultValue;
 697				Constant c = def_value != null ? def_value.Child as Constant : default_expr as Constant;
 698				if (c != null) {
 699					if (c.Type.BuiltinType == BuiltinTypeSpec.Type.Decimal) {
 700						pa.DecimalConstant.EmitAttribute (builder, (decimal) c.GetValue (), c.Location);
 701					} else {
 702						builder.SetConstant (c.GetValue ());
 703					}
 704				} else if (default_expr.Type.IsStruct || default_expr.Type.IsGenericParameter) {
 705					//
 706					// Handles special case where default expression is used with value-type or type parameter
 707					//
 708					// void Foo (S s = default (S)) {}
 709					//
 710					builder.SetConstant (null);
 711				}
 712			}
 713
 714			if (parameter_type != null) {
 715				if (parameter_type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
 716					pa.Dynamic.EmitAttribute (builder);
 717				} else if (parameter_type.HasDynamicElement) {
 718					pa.Dynamic.EmitAttribute (builder, parameter_type, Location);
 719				}
 720			}
 721		}
 722
 723		public Parameter Clone ()
 724		{
 725			Parameter p = (Parameter) MemberwiseClone ();
 726			if (attributes != null)
 727				p.attributes = attributes.Clone ();
 728
 729			return p;
 730		}
 731
 732		public ExpressionStatement CreateExpressionTreeVariable (BlockContext ec)
 733		{
 734			if ((modFlags & Modifier.RefOutMask) != 0)
 735				ec.Report.Error (1951, Location, "An expression tree parameter cannot use `ref' or `out' modifier");
 736
 737			expr_tree_variable = TemporaryVariableReference.Create (ResolveParameterExpressionType (ec, Location).Type, ec.CurrentBlock.ParametersBlock, Location);
 738			expr_tree_variable = (TemporaryVariableReference) expr_tree_variable.Resolve (ec);
 739
 740			Arguments arguments = new Arguments (2);
 741			arguments.Add (new Argument (new TypeOf (parameter_type, Location)));
 742			arguments.Add (new Argument (new StringConstant (ec.BuiltinTypes, Name, Location)));
 743			return new SimpleAssign (ExpressionTreeVariableReference (),
 744				Expression.CreateExpressionFactoryCall (ec, "Parameter", null, arguments, Location));
 745		}
 746
 747		public void Emit (EmitContext ec)
 748		{
 749			ec.EmitArgumentLoad (idx);
 750		}
 751
 752		public void EmitAssign (EmitContext ec)
 753		{
 754			ec.EmitArgumentStore (idx);
 755		}
 756
 757		public void EmitAddressOf (EmitContext ec)
 758		{
 759			if ((ModFlags & Modifier.RefOutMask) != 0) {
 760				ec.EmitArgumentLoad (idx);
 761			} else {
 762				ec.EmitArgumentAddress (idx);
 763			}
 764		}
 765
 766		public TemporaryVariableReference ExpressionTreeVariableReference ()
 767		{
 768			return expr_tree_variable;
 769		}
 770
 771		//
 772		// System.Linq.Expressions.ParameterExpression type
 773		//
 774		public static TypeExpr ResolveParameterExpressionType (IMemberContext ec, Location location)
 775		{
 776			TypeSpec p_type = ec.Module.PredefinedTypes.ParameterExpression.Resolve ();
 777			return new TypeExpression (p_type, location);
 778		}
 779
 780		public void SetIndex (int index)
 781		{
 782			idx = index;
 783		}
 784
 785		public void Warning_UselessOptionalParameter (Report Report)
 786		{
 787			Report.Warning (1066, 1, Location,
 788				"The default value specified for optional parameter `{0}' will never be used",
 789				Name);
 790		}
 791	}
 792
 793	//
 794	// Imported or resolved parameter information
 795	//
 796	public class ParameterData : IParameterData
 797	{
 798		readonly string name;
 799		readonly Parameter.Modifier modifiers;
 800		readonly Expression default_value;
 801
 802		public ParameterData (string name, Parameter.Modifier modifiers)
 803		{
 804			this.name = name;
 805			this.modifiers = modifiers;
 806		}
 807
 808		public ParameterData (string name, Parameter.Modifier modifiers, Expression defaultValue)
 809			: this (name, modifiers)
 810		{
 811			this.default_value = defaultValue;
 812		}
 813
 814		#region IParameterData Members
 815
 816		public Expression DefaultValue {
 817			get { return default_value; }
 818		}
 819
 820		public bool HasExtensionMethodModifier {
 821			get { return (modifiers & Parameter.Modifier.This) != 0; }
 822		}
 823
 824		public bool HasDefaultValue {
 825			get { return default_value != null; }
 826		}
 827
 828		public Parameter.Modifier ModFlags {
 829			get { return modifiers; }
 830		}
 831
 832		public string Name {
 833			get { return name; }
 834		}
 835
 836		#endregion
 837	}
 838
 839	public abstract class AParametersCollection
 840	{
 841		protected bool has_arglist;
 842		protected bool has_params;
 843
 844		// Null object pattern
 845		protected IParameterData [] parameters;
 846		protected TypeSpec [] types;
 847
 848		public CallingConventions CallingConvention {
 849			get {
 850				return has_arglist ?
 851					CallingConventions.VarArgs :
 852					CallingConventions.Standard;
 853			}
 854		}
 855
 856		public int Count {
 857			get { return parameters.Length; }
 858		}
 859
 860		public TypeSpec ExtensionMethodType {
 861			get {
 862				if (Count == 0)
 863					return null;
 864
 865				return FixedParameters [0].HasExtensionMethodModifier ?
 866					types [0] : null;
 867			}
 868		}
 869
 870		public IParameterData [] FixedParameters {
 871			get {
 872				return parameters;
 873			}
 874		}
 875
 876		public static ParameterAttributes GetParameterAttribute (Parameter.Modifier modFlags)
 877		{
 878			return (modFlags & Parameter.Modifier.OUT) != 0 ?
 879				ParameterAttributes.Out : ParameterAttributes.None;
 880		}
 881
 882		// Very expensive operation
 883		public MetaType[] GetMetaInfo ()
 884		{
 885			MetaType[] types;
 886			if (has_arglist) {
 887				if (Count == 1)
 888					return MetaType.EmptyTypes;
 889
 890				types = new MetaType[Count - 1];
 891			} else {
 892				if (Count == 0)
 893					return MetaType.EmptyTypes;
 894
 895				types = new MetaType[Count];
 896			}
 897
 898			for (int i = 0; i < types.Length; ++i) {
 899				types[i] = Types[i].GetMetaInfo ();
 900
 901				if ((FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask) == 0)
 902					continue;
 903
 904				// TODO MemberCache: Should go to MetaInfo getter
 905				types [i] = types [i].MakeByRefType ();
 906			}
 907
 908			return types;
 909		}
 910
 911		//
 912		// Returns the parameter information based on the name
 913		//
 914		public int GetParameterIndexByName (string name)
 915		{
 916			for (int idx = 0; idx < Count; ++idx) {
 917				if (parameters [idx].Name == name)
 918					return idx;
 919			}
 920
 921			return -1;
 922		}
 923
 924		public string GetSignatureForDocumentation ()
 925		{
 926			if (IsEmpty)
 927				return string.Empty;
 928
 929			StringBuilder sb = new StringBuilder ("(");
 930			for (int i = 0; i < Count; ++i) {
 931				if (i != 0)
 932					sb.Append (",");
 933
 934				sb.Append (types [i].GetSignatureForDocumentation ());
 935
 936				if ((parameters[i].ModFlags & Parameter.Modifier.RefOutMask) != 0)
 937					sb.Append ("@");
 938			}
 939			sb.Append (")");
 940
 941			return sb.ToString ();
 942		}
 943
 944		public string GetSignatureForError ()
 945		{
 946			return GetSignatureForError ("(", ")", Count);
 947		}
 948
 949		public string GetSignatureForError (string start, string end, int count)
 950		{
 951			StringBuilder sb = new StringBuilder (start);
 952			for (int i = 0; i < count; ++i) {
 953				if (i != 0)
 954					sb.Append (", ");
 955				sb.Append (ParameterDesc (i));
 956			}
 957			sb.Append (end);
 958			return sb.ToString ();
 959		}
 960
 961		public bool HasArglist {
 962			get { return has_arglist; }
 963		}
 964
 965		public bool HasExtensionMethodType {
 966			get {
 967				if (Count == 0)
 968					return false;
 969
 970				return FixedParameters [0].HasExtensionMethodModifier;
 971			}
 972		}
 973
 974		public bool HasParams {
 975			get { return has_params; }
 976		}
 977
 978		public bool IsEmpty {
 979			get { return parameters.Length == 0; }
 980		}
 981
 982		public AParametersCollection Inflate (TypeParameterInflator inflator)
 983		{
 984			TypeSpec[] inflated_types = null;
 985			bool default_value = false;
 986
 987			for (int i = 0; i < Count; ++i) {
 988				var inflated_param = inflator.Inflate (types[i]);
 989				if (inflated_types == null) {
 990					if (inflated_param == types[i])
 991						continue;
 992
 993					default_value |= FixedParameters[i].HasDefaultValue;
 994					inflated_types = new TypeSpec[types.Length];
 995					Array.Copy (types, inflated_types, types.Length);
 996				} else {
 997					if (inflated_param == types[i])
 998						continue;
 999
1000					default_value |= FixedParameters[i].HasDefaultValue;
1001				}
1002
1003				inflated_types[i] = inflated_param;
1004			}
1005
1006			if (inflated_types == null)
1007				return this;
1008
1009			var clone = (AParametersCollection) MemberwiseClone ();
1010			clone.types = inflated_types;
1011
1012			//
1013			// Default expression is original expression from the parameter
1014			// declaration context which can be of nested enum in generic class type.
1015			// In such case we end up with expression type of G<T>.E and e.g. parameter
1016			// type of G<int>.E and conversion would fail without inflate in this
1017			// context.
1018			//
1019			if (default_value) {
1020				clone.parameters = new IParameterData[Count];
1021				for (int i = 0; i < Count; ++i) {
1022					var fp = FixedParameters[i];
1023					clone.FixedParameters[i] = fp;
1024
1025					if (!fp.HasDefaultValue)
1026						continue;
1027
1028					var expr = fp.DefaultValue;
1029
1030					if (inflated_types[i] == expr.Type)
1031						continue;
1032
1033					var c = expr as Constant;
1034					if (c != null) {
1035						//
1036						// It may fail we are inflating before type validation is done
1037						//
1038						c = Constant.ExtractConstantFromValue (inflated_types[i], c.GetValue (), expr.Location);
1039						if (c == null)
1040							expr = new DefaultValueExpression (new TypeExpression (inflated_types[i], expr.Location), expr.Location);
1041						else
1042							expr = c;
1043					} else if (expr is DefaultValueExpression)
1044						expr = new DefaultValueExpression (new TypeExpression (inflated_types[i], expr.Location), expr.Location);
1045
1046					clone.FixedParameters[i] = new ParameterData (fp.Name, fp.ModFlags, expr);
1047				}
1048			}
1049
1050			return clone;
1051		}
1052
1053		public string ParameterDesc (int pos)
1054		{
1055			if (types == null || types [pos] == null)
1056				return ((Parameter)FixedParameters [pos]).GetSignatureForError ();
1057
1058			string type = types [pos].GetSignatureForError ();
1059			if (FixedParameters [pos].HasExtensionMethodModifier)
1060				return "this " + type;
1061
1062			var mod = FixedParameters[pos].ModFlags & Parameter.Modifier.ModifierMask;
1063			if (mod == 0)
1064				return type;
1065
1066			return Parameter.GetModifierSignature (mod) + " " + type;
1067		}
1068
1069		public TypeSpec[] Types {
1070			get { return types; }
1071			set { types = value; }
1072		}
1073	}
1074
1075	//
1076	// A collection of imported or resolved parameters
1077	//
1078	public class ParametersImported : AParametersCollection
1079	{
1080		public ParametersImported (IParameterData [] parameters, TypeSpec [] types, bool hasArglist, bool hasParams)
1081		{
1082			this.parameters = parameters;
1083			this.types = types;
1084			this.has_arglist = hasArglist;
1085			this.has_params = hasParams;
1086		}
1087
1088		public ParametersImported (IParameterData[] param, TypeSpec[] types, bool hasParams)
1089		{
1090			this.parameters = param;
1091			this.types = types;
1092			this.has_params = hasParams;
1093		}
1094	}
1095
1096	/// <summary>
1097	///   Represents the methods parameters
1098	/// </summary>
1099	public class ParametersCompiled : AParametersCollection
1100	{
1101		public static readonly ParametersCompiled EmptyReadOnlyParameters = new ParametersCompiled ();
1102		
1103		// Used by C# 2.0 delegates
1104		public static readonly ParametersCompiled Undefined = new ParametersCompiled ();
1105
1106		private ParametersCompiled ()
1107		{
1108			parameters = new Parameter [0];
1109			types = TypeSpec.EmptyTypes;
1110		}
1111
1112		private ParametersCompiled (IParameterData[] parameters, TypeSpec[] types)
1113		{
1114			this.parameters = parameters;
1115		    this.types = types;
1116		}
1117		
1118		public ParametersCompiled (params Parameter[] parameters)
1119		{
1120			if (parameters == null || parameters.Length == 0)
1121				throw new ArgumentException ("Use EmptyReadOnlyParameters");
1122
1123			this.parameters = parameters;
1124			int count = parameters.Length;
1125
1126			for (int i = 0; i < count; i++){
1127				has_params |= (parameters [i].ModFlags & Parameter.Modifier.PARAMS) != 0;
1128			}
1129		}
1130
1131		public ParametersCompiled (Parameter [] parameters, bool has_arglist) :
1132			this (parameters)
1133		{
1134			this.has_arglist = has_arglist;
1135		}
1136		
1137		public static ParametersCompiled CreateFullyResolved (Parameter p, TypeSpec type)
1138		{
1139			return new ParametersCompiled (new Parameter [] { p }, new TypeSpec [] { type });
1140		}
1141		
1142		public static ParametersCompiled CreateFullyResolved (Parameter[] parameters, TypeSpec[] types)
1143		{
1144			return new ParametersCompiled (parameters, types);
1145		}
1146
1147		public static ParametersCompiled Prefix (ParametersCompiled parameters, Parameter p, TypeSpec type)
1148		{
1149			var ptypes = new TypeSpec [parameters.Count + 1];
1150			ptypes [0] = type;
1151			Array.Copy (parameters.Types, 0, ptypes, 1, parameters.Count);
1152
1153			var param = new Parameter [ptypes.Length];
1154			param [0] = p;
1155			for (int i = 0; i < parameters.Count; ++i) {
1156				var pi = parameters [i];
1157				param [i + 1] = pi;
1158				pi.SetIndex (i + 1);
1159			}
1160
1161			return ParametersCompiled.CreateFullyResolved (param, ptypes);
1162		}
1163
1164		//
1165		// TODO: This does not fit here, it should go to different version of AParametersCollection
1166		// as the underlying type is not Parameter and some methods will fail to cast
1167		//
1168		public static AParametersCollection CreateFullyResolved (params TypeSpec[] types)
1169		{
1170			var pd = new ParameterData [types.Length];
1171			for (int i = 0; i < pd.Length; ++i)
1172				pd[i] = new ParameterData (null, Parameter.Modifier.NONE, null);
1173
1174			return new ParametersCompiled (pd, types);
1175		}
1176
1177		public static ParametersCompiled CreateImplicitParameter (FullNamedExpression texpr, Location loc)
1178		{
1179			return new ParametersCompiled (
1180				new[] { new Parameter (texpr, "value", Parameter.Modifier.NONE, null, loc) },
1181				null);
1182		}
1183
1184		public void CheckConstraints (IMemberContext mc)
1185		{
1186			foreach (Parameter p in parameters) {
1187				//
1188				// It's null for compiler generated types or special types like __arglist
1189				//
1190				if (p.TypeExpression != null)
1191					ConstraintChecker.Check (mc, p.Type, p.TypeExpression.Location);
1192			}
1193		}
1194
1195		//
1196		// Returns non-zero value for equal CLS parameter signatures
1197		//
1198		public static int IsSameClsSignature (AParametersCollection a, AParametersCollection b)
1199		{
1200			int res = 0;
1201
1202			for (int i = 0; i < a.Count; ++i) {
1203				var a_type = a.Types[i];
1204				var b_type = b.Types[i];
1205				if (TypeSpecComparer.Override.IsEqual (a_type, b_type)) {
1206					if ((a.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask) != (b.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask))
1207						res |= 1;
1208
1209					continue;
1210				}
1211
1212				var ac_a = a_type as ArrayContainer;
1213				if (ac_a == null)
1214					return 0;
1215
1216				var ac_b = b_type as ArrayContainer;
1217				if (ac_b == null)
1218					return 0;
1219
1220				if (ac_a.Element is ArrayContainer || ac_b.Element is ArrayContainer) {
1221					res |= 2;
1222					continue;
1223				}
1224
1225				if (ac_a.Rank != ac_b.Rank && TypeSpecComparer.Override.IsEqual (ac_a.Element, ac_b.Element)) {
1226					res |= 1;
1227					continue;
1228				}
1229
1230				return 0;
1231			}
1232
1233			return res;
1234		}
1235
1236		public static ParametersCompiled MergeGenerated (CompilerContext ctx, ParametersCompiled userParams, bool checkConflicts, Parameter compilerParams, TypeSpec compilerTypes)
1237		{
1238			return MergeGenerated (ctx, userParams, checkConflicts,
1239				new Parameter [] { compilerParams },
1240				new TypeSpec [] { compilerTypes });
1241		}
1242
1243		//
1244		// Use this method when you merge compiler generated parameters with user parameters
1245		//
1246		public static ParametersCompiled MergeGenerated (CompilerContext ctx, ParametersCompiled userParams, bool checkConflicts, Parameter[] compilerParams, TypeSpec[] compilerTypes)
1247		{
1248			Parameter[] all_params = new Parameter [userParams.Count + compilerParams.Length];
1249			userParams.FixedParameters.CopyTo(all_params, 0);
1250
1251			TypeSpec [] all_types;
1252			if (userParams.types != null) {
1253				all_types = new TypeSpec [all_params.Length];
1254				userParams.Types.CopyTo (all_types, 0);
1255			} else {
1256				all_types = null;
1257			}
1258
1259			int last_filled = userParams.Count;
1260			int index = 0;
1261			foreach (Parameter p in compilerParams) {
1262				for (int i = 0; i < last_filled; ++i) {
1263					while (p.Name == all_params [i].Name) {
1264						if (checkConflicts && i < userParams.Count) {
1265							ctx.Report.Error (316, userParams[i].Location,
1266								"The parameter name `{0}' conflicts with a compiler generated name", p.Name);
1267						}
1268						p.Name = '_' + p.Name;
1269					}
1270				}
1271				all_params [last_filled] = p;
1272				if (all_types != null)
1273					all_types [last_filled] = compilerTypes [index++];
1274				++last_filled;
1275			}
1276			
1277			ParametersCompiled parameters = new ParametersCompiled (all_params, all_types);
1278			parameters.has_params = userParams.has_params;
1279			return parameters;
1280		}
1281
1282		//
1283		// Parameters checks for members which don't have a block
1284		//
1285		public void CheckParameters (MemberCore member)
1286		{
1287			for (int i = 0; i < parameters.Length; ++i) {
1288				var name = parameters[i].Name;
1289				for (int ii = i + 1; ii < parameters.Length; ++ii) {
1290					if (parameters[ii].Name == name)
1291						this[ii].Error_DuplicateName (member.Compiler.Report);
1292				}
1293			}
1294		}
1295
1296		public bool Resolve (IMemberContext ec)
1297		{
1298			if (types != null)
1299				return true;
1300			
1301			types = new TypeSpec [Count];
1302			
1303			bool ok = true;
1304			Parameter p;
1305			for (int i = 0; i < FixedParameters.Length; ++i) {
1306				p = this [i];
1307				TypeSpec t = p.Resolve (ec, i);
1308				if (t == null) {
1309					ok = false;
1310					continue;
1311				}
1312
1313				types [i] = t;
1314			}
1315
1316			return ok;
1317		}
1318
1319		public void ResolveDefaultValues (MemberCore m)
1320		{
1321			ResolveContext rc = null;
1322			for (int i = 0; i < parameters.Length; ++i) {
1323				Parameter p = (Parameter) parameters [i];
1324
1325				//
1326				// Try not to enter default values resolution if there are is not any default value possible
1327				//
1328				if (p.HasDefaultValue || p.OptAttributes != null) {
1329					if (rc == null)
1330						rc = new ResolveContext (m);
1331
1332					p.ResolveDefaultValue (rc);
1333				}
1334			}
1335		}
1336
1337		// Define each type attribute (in/out/ref) and
1338		// the argument names.
1339		public void ApplyAttributes (IMemberContext mc, MethodBase builder)
1340		{
1341			if (Count == 0)
1342				return;
1343
1344			MethodBuilder mb = builder as MethodBuilder;
1345			ConstructorBuilder cb = builder as ConstructorBuilder;
1346			var pa = mc.Module.PredefinedAttributes;
1347
1348			for (int i = 0; i < Count; i++) {
1349				this [i].ApplyAttributes (mb, cb, i + 1, pa);
1350			}
1351		}
1352
1353		public void VerifyClsCompliance (IMemberContext ctx)
1354		{
1355			foreach (Parameter p in FixedParameters)
1356				p.IsClsCompliant (ctx);
1357		}
1358
1359		public Parameter this [int pos] {
1360			get { return (Parameter) parameters [pos]; }
1361		}
1362
1363		public Expression CreateExpressionTree (BlockContext ec, Location loc)
1364		{
1365			var initializers = new ArrayInitializer (Count, loc);
1366			foreach (Parameter p in FixedParameters) {
1367				//
1368				// Each parameter expression is stored to local variable
1369				// to save some memory when referenced later.
1370				//
1371				StatementExpression se = new StatementExpression (p.CreateExpressionTreeVariable (ec), Location.Null);
1372				if (se.Resolve (ec)) {
1373					ec.CurrentBlock.AddScopeStatement (new TemporaryVariableReference.Declarator (p.ExpressionTreeVariableReference ()));
1374					ec.CurrentBlock.AddScopeStatement (se);
1375				}
1376				
1377				initializers.Add (p.ExpressionTreeVariableReference ());
1378			}
1379
1380			return new ArrayCreation (
1381				Parameter.ResolveParameterExpressionType (ec, loc),
1382				initializers, loc);
1383		}
1384
1385		public ParametersCompiled Clone ()
1386		{
1387			ParametersCompiled p = (ParametersCompiled) MemberwiseClone ();
1388
1389			p.parameters = new IParameterData [parameters.Length];
1390			for (int i = 0; i < Count; ++i)
1391				p.parameters [i] = this [i].Clone ();
1392
1393			return p;
1394		}
1395	}
1396
1397	//
1398	// Default parameter value expression. We need this wrapper to handle
1399	// default parameter values of folded constants (e.g. indexer parameters).
1400	// The expression is resolved only once but applied to two methods which
1401	// both share reference to this expression and we ensure that resolving
1402	// this expression always returns same instance
1403	//
1404	public class DefaultParameterValueExpression : CompositeExpression
1405	{
1406		public DefaultParameterValueExpression (Expression expr)
1407			: base (expr)
1408		{
1409		}
1410
1411		public void Resolve (ResolveContext rc, Parameter p)
1412		{
1413			var expr = Resolve (rc);
1414			if (expr == null) {
1415				this.expr = ErrorExpression.Instance;
1416				return;
1417			}
1418
1419			expr = Child;
1420
1421			if (!(expr is Constant || expr is DefaultValueExpression || (expr is New && ((New) expr).IsDefaultStruct))) {
1422				if (!(expr is ErrorExpression)) {
1423					rc.Report.Error (1736, Location,
1424						"The expression being assigned to optional parameter `{0}' must be a constant or default value",
1425						p.Name);
1426				}
1427
1428				return;
1429			}
1430
1431			var parameter_type = p.Type;
1432			if (type == parameter_type)
1433				return;
1434
1435			var res = Convert.ImplicitConversionStandard (rc, expr, parameter_type, Location);
1436			if (res != null) {
1437				if (parameter_type.IsNullableType && res is Nullable.Wrap) {
1438					Nullable.Wrap wrap = (Nullable.Wrap) res;
1439					res = wrap.Child;
1440					if (!(res is Constant)) {
1441						rc.Report.Error (1770, Location,
1442							"The expression being assigned to nullable optional parameter `{0}' must be default value",
1443							p.Name);
1444						return;
1445					}
1446				}
1447
1448				if (!expr.IsNull && TypeSpec.IsReferenceType (parameter_type) && parameter_type.BuiltinType != BuiltinTypeSpec.Type.String) {
1449					rc.Report.Error (1763, Location,
1450						"Optional parameter `{0}' of type `{1}' can only be initialized with `null'",
1451						p.Name, parameter_type.GetSignatureForError ());
1452
1453					return;
1454				}
1455
1456				this.expr = res;
1457				return;
1458			}
1459
1460			rc.Report.Error (1750, Location,
1461				"Optional parameter expression of type `{0}' cannot be converted to parameter type `{1}'",
1462				type.GetSignatureForError (), parameter_type.GetSignatureForError ());
1463
1464			this.expr = ErrorExpression.Instance;
1465		}
1466		
1467		public override object Accept (StructuralVisitor visitor)
1468		{
1469			return visitor.Visit (this);
1470		}
1471	}
1472}