2 // class.cs: Class and Struct handlers
4 // Authors: Miguel de Icaza (miguel@gnu.org)
5 // Martin Baulig (martin@gnome.org)
6 // Marek Safar (marek.safar@seznam.cz)
8 // Licensed under the terms of the GNU GPL
10 // (C) 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
13 // 2002-10-11 Miguel de Icaza <miguel@ximian.com>
15 // * class.cs: Following the comment from 2002-09-26 to AddMethod, I
16 // have fixed a remaining problem: not every AddXXXX was adding a
17 // fully qualified name.
19 // Now everyone registers a fully qualified name in the DeclSpace as
20 // being defined instead of the partial name.
22 // Downsides: we are slower than we need to be due to the excess
23 // copies and the names being registered this way.
25 // The reason for this is that we currently depend (on the corlib
26 // bootstrap for instance) that types are fully qualified, because
27 // we dump all the types in the namespace, and we should really have
28 // types inserted into the proper namespace, so we can only store the
29 // basenames in the defined_names array.
34 using System.Collections;
35 using System.Collections.Specialized;
36 using System.Reflection;
37 using System.Reflection.Emit;
38 using System.Runtime.CompilerServices;
39 using System.Runtime.InteropServices;
40 using System.Security;
41 using System.Security.Permissions;
44 using Mono.CompilerServices.SymbolWriter;
46 namespace Mono.CSharp {
56 /// This is the base class for structs and classes.
58 public abstract class TypeContainer : DeclSpace, IMemberContainer {
60 public class MemberCoreArrayList: ArrayList
63 /// Defines the MemberCore objects that are in this array
65 public virtual void DefineContainerMembers ()
67 foreach (MemberCore mc in this) {
72 public virtual void Emit ()
74 foreach (MemberCore mc in this)
79 public class MethodArrayList: MemberCoreArrayList
87 CachedMethods cached_method;
88 TypeContainer container;
90 public MethodArrayList (TypeContainer container)
92 this.container = container;
96 /// Method container contains Equals method
98 public bool HasEquals {
100 cached_method |= CachedMethods.Equals;
104 return (cached_method & CachedMethods.Equals) != 0;
109 /// Method container contains GetHashCode method
111 public bool HasGetHashCode {
113 cached_method |= CachedMethods.GetHashCode;
117 return (cached_method & CachedMethods.GetHashCode) != 0;
121 public override void DefineContainerMembers ()
123 base.DefineContainerMembers ();
125 if ((RootContext.WarningLevel >= 3) && HasEquals && !HasGetHashCode) {
126 Report.Warning (659, container.Location, "'{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", container.GetSignatureForError ());
132 public sealed class IndexerArrayList: MemberCoreArrayList
135 /// The indexer name for this container
137 public string IndexerName = DefaultIndexerName;
139 bool seen_normal_indexers = false;
141 TypeContainer container;
143 public IndexerArrayList (TypeContainer container)
145 this.container = container;
149 /// Defines the indexers, and also verifies that the IndexerNameAttribute in the
150 /// class is consistent. Either it is `Item' or it is the name defined by all the
151 /// indexers with the `IndexerName' attribute.
153 /// Turns out that the IndexerNameAttribute is applied to each indexer,
154 /// but it is never emitted, instead a DefaultMember attribute is attached
157 public override void DefineContainerMembers()
159 base.DefineContainerMembers ();
161 string class_indexer_name = null;
164 // If there's both an explicit and an implicit interface implementation, the
165 // explicit one actually implements the interface while the other one is just
166 // a normal indexer. See bug #37714.
169 // Invariant maintained by AddIndexer(): All explicit interface indexers precede normal indexers
170 foreach (Indexer i in this) {
171 if (i.InterfaceType != null) {
172 if (seen_normal_indexers)
173 throw new Exception ("Internal Error: 'Indexers' array not sorted properly.");
177 seen_normal_indexers = true;
179 if (class_indexer_name == null) {
180 class_indexer_name = i.ShortName;
184 if (i.ShortName != class_indexer_name)
185 Report.Error (668, i.Location, "Two indexers have different names; the IndexerName attribute must be used with the same name on every indexer within a type");
188 if (class_indexer_name != null)
189 IndexerName = class_indexer_name;
192 public override void Emit ()
196 if (!seen_normal_indexers)
199 CustomAttributeBuilder cb = new CustomAttributeBuilder (TypeManager.default_member_ctor, new string [] { IndexerName });
200 container.TypeBuilder.SetCustomAttribute (cb);
204 public class OperatorArrayList: MemberCoreArrayList
206 TypeContainer container;
208 public OperatorArrayList (TypeContainer container)
210 this.container = container;
214 // Operator pair checking
219 public Type ret_type;
220 public Type type1, type2;
222 public Operator.OpType ot;
224 public OperatorEntry (int f, Operator o)
228 ret_type = o.OperatorMethod.ReturnType;
229 Type [] pt = o.OperatorMethod.ParameterTypes;
236 public override int GetHashCode ()
238 return ret_type.GetHashCode ();
241 public override bool Equals (object o)
243 OperatorEntry other = (OperatorEntry) o;
245 if (other.ret_type != ret_type)
247 if (other.type1 != type1)
249 if (other.type2 != type2)
256 // Checks that some operators come in pairs:
262 // They are matched based on the return type and the argument types
264 void CheckPairedOperators ()
266 Hashtable pairs = new Hashtable (null, null);
267 Operator true_op = null;
268 Operator false_op = null;
269 bool has_equality_or_inequality = false;
271 // Register all the operators we care about.
272 foreach (Operator op in this){
275 switch (op.OperatorType){
276 case Operator.OpType.Equality:
278 has_equality_or_inequality = true;
280 case Operator.OpType.Inequality:
282 has_equality_or_inequality = true;
285 case Operator.OpType.True:
288 case Operator.OpType.False:
292 case Operator.OpType.GreaterThan:
294 case Operator.OpType.LessThan:
297 case Operator.OpType.GreaterThanOrEqual:
299 case Operator.OpType.LessThanOrEqual:
305 OperatorEntry oe = new OperatorEntry (reg, op);
307 object o = pairs [oe];
311 oe = (OperatorEntry) o;
316 if (true_op != null){
317 if (false_op == null)
318 Report.Error (216, true_op.Location, "operator true requires a matching operator false");
319 } else if (false_op != null)
320 Report.Error (216, false_op.Location, "operator false requires a matching operator true");
323 // Look for the mistakes.
325 foreach (DictionaryEntry de in pairs){
326 OperatorEntry oe = (OperatorEntry) de.Key;
333 case Operator.OpType.Equality:
336 case Operator.OpType.Inequality:
339 case Operator.OpType.GreaterThan:
342 case Operator.OpType.LessThan:
345 case Operator.OpType.GreaterThanOrEqual:
348 case Operator.OpType.LessThanOrEqual:
352 Report.Error (216, oe.op.Location,
353 "The operator `" + oe.op + "' requires a matching operator `" + s + "' to also be defined");
356 if (has_equality_or_inequality && (RootContext.WarningLevel > 2)) {
357 if (container.Methods == null || !container.Methods.HasEquals)
358 Report.Warning (660, container.Location, "'{0}' defines operator == or operator != but does not override Object.Equals(object o)", container.GetSignatureForError ());
360 if (container.Methods == null || !container.Methods.HasGetHashCode)
361 Report.Warning (661, container.Location, "'{0}' defines operator == or operator != but does not override Object.GetHashCode()", container.GetSignatureForError ());
365 public override void DefineContainerMembers ()
367 base.DefineContainerMembers ();
368 CheckPairedOperators ();
373 // Whether this is a struct, class or interface
374 public readonly Kind Kind;
376 // Holds a list of classes and structures
379 // Holds the list of properties
380 MemberCoreArrayList properties;
382 // Holds the list of enumerations
383 MemberCoreArrayList enums;
385 // Holds the list of delegates
386 MemberCoreArrayList delegates;
388 // Holds the list of constructors
389 protected MemberCoreArrayList instance_constructors;
391 // Holds the list of fields
392 MemberCoreArrayList fields;
394 // Holds a list of fields that have initializers
395 protected ArrayList initialized_fields;
397 // Holds a list of static fields that have initializers
398 protected ArrayList initialized_static_fields;
400 // Holds the list of constants
401 MemberCoreArrayList constants;
404 MemberCoreArrayList interfaces;
406 // Holds the methods.
407 MethodArrayList methods;
410 protected MemberCoreArrayList events;
412 // Holds the indexers
413 IndexerArrayList indexers;
415 // Holds the operators
416 MemberCoreArrayList operators;
418 // Holds the iterators
421 // Holds the parts of a partial class;
424 // The emit context for toplevel objects.
427 public EmitContext EmitContext {
432 // Pointers to the default constructor and the default static constructor
434 protected Constructor default_constructor;
435 protected Constructor default_static_constructor;
438 // Whether we have at least one non-static field
440 bool have_nonstatic_fields = false;
443 // This one is computed after we can distinguish interfaces
444 // from classes from the arraylist `type_bases'
446 string base_class_name;
447 public Type base_class_type;
449 ArrayList type_bases;
451 bool members_defined;
452 bool members_defined_ok;
454 // The interfaces we implement.
456 protected Type[] base_inteface_types;
458 // The parent member container and our member cache
459 IMemberContainer parent_container;
460 MemberCache member_cache;
462 public const string DefaultIndexerName = "Item";
464 public TypeContainer (NamespaceEntry ns, TypeContainer parent, MemberName name,
465 Attributes attrs, Kind kind, Location l)
466 : base (ns, parent, name, attrs, l)
470 types = new ArrayList ();
472 base_class_name = null;
475 public bool AddToMemberContainer (MemberCore symbol, bool is_method)
477 return AddToContainer (symbol, is_method, String.Concat (Name, '.', symbol.Name), symbol.Name);
480 bool AddToTypeContainer (DeclSpace ds)
482 return AddToContainer (ds, false, ds.Name, ds.Basename);
485 public void AddConstant (Const constant)
487 if (!AddToMemberContainer (constant, false))
490 if (constants == null)
491 constants = new MemberCoreArrayList ();
493 constants.Add (constant);
496 public void AddEnum (Mono.CSharp.Enum e)
498 if (!AddToTypeContainer (e))
502 enums = new MemberCoreArrayList ();
507 public void AddClassOrStruct (TypeContainer c)
509 if (!AddToTypeContainer (c))
515 public void AddDelegate (Delegate d)
517 if (!AddToTypeContainer (d))
520 if (delegates == null)
521 delegates = new MemberCoreArrayList ();
526 public void AddMethod (Method method)
528 if (!AddToMemberContainer (method, true))
532 methods = new MethodArrayList (this);
534 if (method.Name.IndexOf ('.') != -1)
535 methods.Insert (0, method);
537 methods.Add (method);
540 public void AddConstructor (Constructor c)
542 if (c.Name != Basename) {
543 Report.Error (1520, c.Location, "Class, struct, or interface method must have a return type");
546 bool is_static = (c.ModFlags & Modifiers.STATIC) != 0;
549 if (default_static_constructor != null) {
550 Report.SymbolRelatedToPreviousError (default_static_constructor);
551 Report.Error (111, c.Location, Error111, Name, c.Name);
555 default_static_constructor = c;
558 if (default_constructor != null) {
559 Report.SymbolRelatedToPreviousError (default_constructor);
560 Report.Error (111, c.Location, Error111, c.Location, Name, c.Name);
563 default_constructor = c;
566 if (instance_constructors == null)
567 instance_constructors = new MemberCoreArrayList ();
569 instance_constructors.Add (c);
573 internal static string Error111 {
575 return "Type '{0}' already defines a member called '{1}' with the same parameter types";
579 public void AddInterface (TypeContainer iface)
581 if (!AddToTypeContainer (iface))
584 if (interfaces == null) {
585 interfaces = new MemberCoreArrayList ();
588 interfaces.Add (iface);
591 public void AddField (Field field)
593 if (!AddToMemberContainer (field, false))
597 fields = new MemberCoreArrayList ();
601 if (field.HasInitializer){
602 if ((field.ModFlags & Modifiers.STATIC) != 0){
603 if (initialized_static_fields == null)
604 initialized_static_fields = new ArrayList ();
606 initialized_static_fields.Add (field);
608 if (initialized_fields == null)
609 initialized_fields = new ArrayList ();
611 initialized_fields.Add (field);
615 if ((field.ModFlags & Modifiers.STATIC) == 0)
616 have_nonstatic_fields = true;
619 public void AddProperty (Property prop)
621 if (!AddToMemberContainer (prop, false) ||
622 !AddToMemberContainer (prop.Get, true) || !AddToMemberContainer (prop.Set, true))
625 if (properties == null)
626 properties = new MemberCoreArrayList ();
628 if (prop.Name.IndexOf ('.') != -1)
629 properties.Insert (0, prop);
631 properties.Add (prop);
634 public void AddEvent (Event e)
636 if (!AddToMemberContainer (e, false))
639 if (e is EventProperty) {
640 if (!AddToMemberContainer (e.Add, true))
643 if (!AddToMemberContainer (e.Remove, true))
648 events = new MemberCoreArrayList ();
655 /// Indexer has special handling in constrast to other AddXXX because the name can be driven by IndexerNameAttribute
657 public void AddIndexer (Indexer i)
659 if (indexers == null)
660 indexers = new IndexerArrayList (this);
662 if (i.IsExplicitImpl)
663 indexers.Insert (0, i);
668 public void AddOperator (Operator op)
670 if (!AddToMemberContainer (op, true))
673 if (operators == null)
674 operators = new OperatorArrayList (this);
679 public void AddIterator (Iterator i)
681 if (iterators == null)
682 iterators = new ArrayList ();
687 public void AddType (TypeContainer tc)
692 public void AddPart (ClassPart part)
695 parts = new ArrayList ();
700 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
702 if (a.Type == TypeManager.default_member_type) {
703 if (Indexers != null) {
704 Report.Error (646, a.Location,
705 "Cannot specify the DefaultMember attribute on" +
706 " a type containing an indexer");
711 base.ApplyAttributeBuilder (a, cb);
714 public override AttributeTargets AttributeTargets {
716 throw new NotSupportedException ();
720 public ArrayList Types {
726 public MethodArrayList Methods {
732 public ArrayList Constants {
738 public ArrayList Interfaces {
744 public ArrayList Iterators {
752 return base_class_name;
756 public ArrayList Bases {
766 public ArrayList Fields {
772 public ArrayList InstanceConstructors {
774 return instance_constructors;
778 public ArrayList Properties {
784 public ArrayList Events {
790 public ArrayList Enums {
796 public ArrayList Indexers {
802 public ArrayList Operators {
808 public ArrayList Delegates {
814 public ArrayList Parts {
820 public virtual TypeAttributes TypeAttr {
822 return Modifiers.TypeAttr (ModFlags, this);
826 public string IndexerName {
828 return indexers == null ? DefaultIndexerName : indexers.IndexerName;
833 // Emits the instance field initializers
835 public bool EmitFieldInitializers (EmitContext ec)
838 Expression instance_expr;
841 fields = initialized_static_fields;
842 instance_expr = null;
844 fields = initialized_fields;
845 instance_expr = new This (Location.Null).Resolve (ec);
851 foreach (Field f in fields){
852 Expression e = f.GetInitializerExpression (ec);
856 Location l = f.Location;
857 FieldExpr fe = new FieldExpr (f.FieldBuilder, l);
858 fe.InstanceExpression = instance_expr;
859 ExpressionStatement a = new Assign (fe, e, l);
861 a = a.ResolveStatement (ec);
865 a.EmitStatement (ec);
872 // Defines the default constructors
874 protected void DefineDefaultConstructor (bool is_static)
878 // The default constructor is public
879 // If the class is abstract, the default constructor is protected
880 // The default static constructor is private
882 int mods = Modifiers.PUBLIC;
884 mods = Modifiers.STATIC | Modifiers.PRIVATE;
885 else if ((ModFlags & Modifiers.ABSTRACT) != 0)
886 mods = Modifiers.PROTECTED;
888 c = new Constructor (this, Basename, mods, Parameters.EmptyReadOnlyParameters,
889 new ConstructorBaseInitializer (
890 null, Parameters.EmptyReadOnlyParameters,
896 c.Block = new ToplevelBlock (null, Location);
901 /// The pending methods that need to be implemented
902 // (interfaces or abstract methods)
904 public PendingImplementation Pending;
906 public abstract void Register ();
908 public abstract PendingImplementation GetPendingImplementations ();
910 TypeExpr[] GetPartialBases (out TypeExpr parent, out bool error)
912 ArrayList ifaces = new ArrayList ();
915 Location parent_loc = Location.Null;
917 foreach (ClassPart part in parts) {
919 TypeExpr[] new_ifaces;
921 new_ifaces = part.GetClassBases (out new_parent, out error);
925 if ((parent != null) && (new_parent != null) &&
926 !parent.Equals (new_parent)) {
927 Report.Error (263, part.Location,
928 "Partial declarations of `{0}' must " +
929 "not specify different base classes",
932 if (!Location.IsNull (parent_loc))
933 Report.LocationOfPreviousError (parent_loc);
939 if ((parent == null) && (new_parent != null)) {
941 parent_loc = part.Location;
944 if (new_ifaces == null)
947 foreach (TypeExpr iface in new_ifaces) {
949 foreach (TypeExpr old_iface in ifaces) {
950 if (old_iface.Equals (iface)) {
963 TypeExpr[] retval = new TypeExpr [ifaces.Count];
964 ifaces.CopyTo (retval, 0);
968 TypeExpr[] GetNormalBases (out TypeExpr parent, out bool error)
972 int count = Bases.Count;
975 if (Kind == Kind.Class){
976 TypeExpr name = ResolveTypeExpr (
977 (Expression) Bases [0], false, Location);
994 TypeExpr [] ifaces = new TypeExpr [count-start];
996 for (i = start, j = 0; i < count; i++, j++){
997 Expression name = (Expression) Bases [i];
998 TypeExpr resolved = ResolveTypeExpr (name, false, Location);
999 if (resolved == null) {
1004 ifaces [j] = resolved;
1012 /// This function computes the Base class and also the
1013 /// list of interfaces that the class or struct @c implements.
1015 /// The return value is an array (might be null) of
1016 /// interfaces implemented (as Types).
1018 /// The @parent argument is set to the parent object or null
1019 /// if this is `System.Object'.
1021 TypeExpr [] GetClassBases (out TypeExpr parent, out bool error)
1030 ifaces = GetPartialBases (out parent, out error);
1031 else if (Bases == null){
1035 ifaces = GetNormalBases (out parent, out error);
1040 if ((parent != null) && (Kind == Kind.Class)){
1041 if (parent.IsSealed){
1043 Report.SymbolRelatedToPreviousError (parent.Type);
1044 if (parent.Type.IsAbstract) {
1045 Report.Error (709, Location, "'{0}': Cannot derive from static class", GetSignatureForError ());
1047 Report.Error (509, Location, "'{0}': Cannot derive from sealed class", GetSignatureForError ());
1052 if (!parent.CanInheritFrom ()){
1053 Report.Error (644, Location,
1054 "`{0}' cannot inherit from special class `{1}'",
1060 if (!parent.AsAccessible (this, ModFlags))
1061 Report.Error (60, Location,
1062 "Inconsistent accessibility: base class `" +
1063 parent.Name + "' is less accessible than class `" +
1068 base_class_name = parent.Name;
1073 int count = ifaces != null ? ifaces.Length : 0;
1075 for (i = 0; i < count; i++) {
1076 TypeExpr iface = (TypeExpr) ifaces [i];
1078 if ((Kind != Kind.Class) && !iface.IsInterface){
1079 string what = Kind == Kind.Struct ?
1080 "Struct" : "Interface";
1082 Report.Error (527, Location,
1083 "In {0} `{1}', type `{2}' is not "+
1084 "an interface", what, Name, iface.Name);
1089 if (iface.IsClass) {
1090 if (parent != null){
1091 Report.Error (527, Location,
1092 "In Class `{0}', `{1}' is not " +
1093 "an interface", Name, iface.Name);
1099 for (int x = 0; x < i; x++) {
1100 if (iface.Equals (ifaces [x])) {
1101 Report.Error (528, Location,
1102 "`{0}' is already listed in " +
1103 "interface list", iface.Name);
1109 if ((Kind == Kind.Interface) &&
1110 !iface.AsAccessible (Parent, ModFlags))
1111 Report.Error (61, Location,
1112 "Inconsistent accessibility: base " +
1113 "interface `{0}' is less accessible " +
1114 "than interface `{1}'", iface.Name,
1118 return TypeManager.ExpandInterfaces (ifaces);
1124 // Defines the type in the appropriate ModuleBuilder or TypeBuilder.
1126 public override TypeBuilder DefineType ()
1130 if (TypeBuilder != null)
1137 Report.Error (146, Location, "Class definition is circular: `{0}'", Name);
1144 ec = new EmitContext (this, Mono.CSharp.Location.Null, null, null, ModFlags);
1146 ifaces = GetClassBases (out parent, out error);
1150 if (parent == null) {
1151 if (Kind == Kind.Class){
1152 if (RootContext.StdLib)
1153 parent = TypeManager.system_object_expr;
1154 else if (Name != "System.Object")
1155 parent = TypeManager.system_object_expr;
1156 } else if (Kind == Kind.Struct) {
1158 // If we are compiling our runtime,
1159 // and we are defining ValueType, then our
1160 // parent is `System.Object'.
1162 if (!RootContext.StdLib && Name == "System.ValueType")
1163 parent = TypeManager.system_object_expr;
1165 parent = TypeManager.system_valuetype_expr;
1169 if ((Kind == Kind.Struct) && TypeManager.value_type == null)
1170 throw new Exception ();
1172 TypeAttributes type_attributes = TypeAttr;
1174 if (parent != null) {
1175 base_class_type = parent.ResolveType (ec);
1176 if (base_class_type == null) {
1184 if (TypeManager.NamespaceClash (Name, Location)) {
1189 ModuleBuilder builder = CodeGen.Module.Builder;
1190 TypeBuilder = builder.DefineType (
1191 Name, type_attributes, base_class_type, null);
1194 TypeBuilder builder = Parent.DefineType ();
1195 if (builder == null)
1198 TypeBuilder = builder.DefineNestedType (
1199 Basename, type_attributes, base_class_type, null);
1202 catch (ArgumentException) {
1203 Report.RuntimeMissingSupport (Location, "static classes");
1208 // Structs with no fields need to have at least one byte.
1209 // The right thing would be to set the PackingSize in a DefineType
1210 // but there are no functions that allow interfaces *and* the size to
1214 if ((Kind == Kind.Struct) && !have_nonstatic_fields){
1215 TypeBuilder.DefineField ("$PRIVATE$", TypeManager.byte_type,
1216 FieldAttributes.Private);
1219 // add interfaces that were not added at type creation
1220 if (ifaces != null) {
1221 base_inteface_types = new Type[ifaces.Length];
1222 for (int i = 0; i < ifaces.Length; ++i) {
1223 Type itype = ifaces [i].ResolveType (ec);
1224 if (itype == null) {
1228 TypeBuilder.AddInterfaceImplementation (itype);
1229 base_inteface_types [i] = itype;
1237 // Finish the setup for the EmitContext
1239 ec.ContainerType = TypeBuilder;
1241 TypeManager.AddUserType (Name, TypeBuilder, this, ifaces);
1243 if ((parent != null) && parent.IsAttribute) {
1244 RootContext.RegisterAttribute (this);
1245 } else if (!(this is Iterator))
1246 RootContext.RegisterOrder (this);
1248 if (!DefineNestedTypes ()) {
1257 protected virtual bool DefineNestedTypes ()
1259 if (Interfaces != null) {
1260 foreach (TypeContainer iface in Interfaces)
1261 if (iface.DefineType () == null)
1265 if (Types != null) {
1266 foreach (TypeContainer tc in Types)
1267 if (tc.DefineType () == null)
1271 if (Delegates != null) {
1272 foreach (Delegate d in Delegates)
1273 if (d.DefineType () == null)
1277 if (Enums != null) {
1278 foreach (Enum en in Enums)
1279 if (en.DefineType () == null)
1283 if (Parts != null) {
1284 foreach (ClassPart part in Parts) {
1285 part.TypeBuilder = TypeBuilder;
1286 part.base_class_type = base_class_type;
1287 part.ec = new EmitContext (part, Mono.CSharp.Location.Null, null, null, ModFlags);
1294 static void Error_KeywordNotAllowed (Location loc)
1296 Report.Error (1530, loc, "Keyword new not allowed for namespace elements");
1300 /// Populates our TypeBuilder with fields and methods
1302 public override bool DefineMembers (TypeContainer container)
1304 if (members_defined)
1305 return members_defined_ok;
1307 members_defined_ok = DoDefineMembers ();
1308 members_defined = true;
1310 return members_defined_ok;
1313 bool DoDefineMembers ()
1316 // We need to be able to use the member cache while we are checking/defining
1318 if (TypeBuilder.BaseType != null)
1319 parent_container = TypeManager.LookupMemberContainer (TypeBuilder.BaseType);
1321 if (TypeBuilder.IsInterface)
1322 parent_container = TypeManager.LookupInterfaceContainer (base_inteface_types);
1325 if ((ModFlags & Modifiers.NEW) != 0)
1326 Error_KeywordNotAllowed (Location);
1328 // HACK: missing implemenation
1329 // This is not fully functional. Better way how to handle this is to have recursive definition of containers
1330 // instead of flat as we have now.
1331 // Now we are not able to check inner attribute class because its parent had not been defined.
1333 // TODO: remove this if
1334 if (Parent.MemberCache != null) {
1335 MemberInfo conflict_symbol = Parent.MemberCache.FindMemberWithSameName (Basename, false, TypeBuilder);
1336 if (conflict_symbol == null) {
1337 if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0))
1338 Report.Warning (109, Location, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
1340 if ((ModFlags & Modifiers.NEW) == 0) {
1341 Report.SymbolRelatedToPreviousError (conflict_symbol);
1342 Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError ());
1348 DefineContainerMembers (constants);
1349 DefineContainerMembers (fields);
1351 if ((Kind == Kind.Class) && !(this is ClassPart) && !(this is StaticClass)){
1352 if ((instance_constructors == null) &&
1353 !(this is StaticClass)) {
1354 if (default_constructor == null)
1355 DefineDefaultConstructor (false);
1358 if (initialized_static_fields != null &&
1359 default_static_constructor == null)
1360 DefineDefaultConstructor (true);
1363 if (Kind == Kind.Struct){
1365 // Structs can not have initialized instance
1368 if (initialized_static_fields != null &&
1369 default_static_constructor == null)
1370 DefineDefaultConstructor (true);
1372 if (initialized_fields != null)
1373 ReportStructInitializedInstanceError ();
1376 Pending = GetPendingImplementations ();
1378 if (parts != null) {
1379 foreach (ClassPart part in parts) {
1380 if (!part.DefineMembers (this))
1386 // Constructors are not in the defined_names array
1388 DefineContainerMembers (instance_constructors);
1390 if (default_static_constructor != null)
1391 default_static_constructor.Define ();
1393 DefineContainerMembers (properties);
1394 DefineContainerMembers (events);
1395 DefineContainerMembers (indexers);
1396 DefineContainerMembers (methods);
1397 DefineContainerMembers (operators);
1398 DefineContainerMembers (enums);
1399 DefineContainerMembers (delegates);
1402 if (!(this is ClassPart))
1403 member_cache = new MemberCache (this, false);
1406 if (parts != null) {
1407 foreach (ClassPart part in parts)
1408 part.member_cache = member_cache;
1411 if (iterators != null) {
1412 foreach (Iterator iterator in iterators) {
1413 if (iterator.DefineType () == null)
1417 foreach (Iterator iterator in iterators) {
1418 if (!iterator.DefineMembers (this))
1426 void ReportStructInitializedInstanceError ()
1428 string n = TypeBuilder.FullName;
1430 foreach (Field f in initialized_fields){
1433 "`" + n + "." + f.Name + "': can not have " +
1434 "instance field initializers in structs");
1438 protected virtual void DefineContainerMembers (MemberCoreArrayList mcal)
1441 mcal.DefineContainerMembers ();
1444 public override bool Define ()
1446 if (parts != null) {
1447 foreach (ClassPart part in parts) {
1448 if (!part.Define ())
1456 public MemberInfo FindMemberWithSameName (string name, bool ignore_methods)
1458 return ParentContainer.MemberCache.FindMemberWithSameName (name, ignore_methods, null);
1462 /// This function is based by a delegate to the FindMembers routine
1464 static bool AlwaysAccept (MemberInfo m, object filterCriteria)
1470 /// This filter is used by FindMembers, and we just keep
1471 /// a global for the filter to `AlwaysAccept'
1473 static MemberFilter accepting_filter;
1476 static TypeContainer ()
1478 accepting_filter = new MemberFilter (AlwaysAccept);
1481 public MethodInfo[] GetMethods ()
1483 ArrayList members = new ArrayList ();
1485 DefineMembers (null);
1487 if (methods != null) {
1488 int len = methods.Count;
1489 for (int i = 0; i < len; i++) {
1490 Method m = (Method) methods [i];
1492 members.Add (m.MethodBuilder);
1496 if (operators != null) {
1497 int len = operators.Count;
1498 for (int i = 0; i < len; i++) {
1499 Operator o = (Operator) operators [i];
1501 members.Add (o.OperatorMethodBuilder);
1505 if (properties != null) {
1506 int len = properties.Count;
1507 for (int i = 0; i < len; i++) {
1508 Property p = (Property) properties [i];
1510 if (p.GetBuilder != null)
1511 members.Add (p.GetBuilder);
1512 if (p.SetBuilder != null)
1513 members.Add (p.SetBuilder);
1517 if (indexers != null) {
1518 int len = indexers.Count;
1519 for (int i = 0; i < len; i++) {
1520 Indexer ix = (Indexer) indexers [i];
1522 if (ix.GetBuilder != null)
1523 members.Add (ix.GetBuilder);
1524 if (ix.SetBuilder != null)
1525 members.Add (ix.SetBuilder);
1529 if (events != null) {
1530 int len = events.Count;
1531 for (int i = 0; i < len; i++) {
1532 Event e = (Event) events [i];
1534 if (e.AddBuilder != null)
1535 members.Add (e.AddBuilder);
1536 if (e.RemoveBuilder != null)
1537 members.Add (e.RemoveBuilder);
1541 MethodInfo[] retMethods = new MethodInfo [members.Count];
1542 members.CopyTo (retMethods, 0);
1546 // Indicated whether container has StructLayout attribute set Explicit
1547 public virtual bool HasExplicitLayout {
1554 /// This method returns the members of this type just like Type.FindMembers would
1555 /// Only, we need to use this for types which are _being_ defined because MS'
1556 /// implementation can't take care of that.
1559 // FIXME: return an empty static array instead of null, that cleans up
1560 // some code and is consistent with some coding conventions I just found
1564 // Notice that in various cases we check if our field is non-null,
1565 // something that would normally mean that there was a bug elsewhere.
1567 // The problem happens while we are defining p-invoke methods, as those
1568 // will trigger a FindMembers, but this happens before things are defined
1570 // Since the whole process is a no-op, it is fine to check for null here.
1572 public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
1573 MemberFilter filter, object criteria)
1575 ArrayList members = null;
1578 if ((bf & BindingFlags.Public) != 0)
1579 modflags |= Modifiers.PUBLIC | Modifiers.PROTECTED |
1581 if ((bf & BindingFlags.NonPublic) != 0)
1582 modflags |= Modifiers.PRIVATE;
1584 int static_mask = 0, static_flags = 0;
1585 switch (bf & (BindingFlags.Static | BindingFlags.Instance)) {
1586 case BindingFlags.Static:
1587 static_mask = static_flags = Modifiers.STATIC;
1590 case BindingFlags.Instance:
1591 static_mask = Modifiers.STATIC;
1596 static_mask = static_flags = 0;
1600 Timer.StartTimer (TimerType.TcFindMembers);
1603 filter = accepting_filter;
1605 if ((mt & MemberTypes.Field) != 0) {
1606 if (fields != null) {
1607 int len = fields.Count;
1608 for (int i = 0; i < len; i++) {
1609 Field f = (Field) fields [i];
1611 if ((f.ModFlags & modflags) == 0)
1613 if ((f.ModFlags & static_mask) != static_flags)
1616 FieldBuilder fb = f.FieldBuilder;
1617 if (fb != null && filter (fb, criteria) == true) {
1618 if (members == null)
1619 members = new ArrayList ();
1626 if (constants != null) {
1627 int len = constants.Count;
1628 for (int i = 0; i < len; i++) {
1629 Const con = (Const) constants [i];
1631 if ((con.ModFlags & modflags) == 0)
1633 if ((con.ModFlags & static_mask) != static_flags)
1636 FieldBuilder fb = con.FieldBuilder;
1637 if (fb != null && filter (fb, criteria) == true) {
1638 if (members == null)
1639 members = new ArrayList ();
1647 if ((mt & MemberTypes.Method) != 0) {
1648 if (methods != null) {
1649 int len = methods.Count;
1650 for (int i = 0; i < len; i++) {
1651 Method m = (Method) methods [i];
1653 if ((m.ModFlags & modflags) == 0)
1655 if ((m.ModFlags & static_mask) != static_flags)
1658 MethodBuilder mb = m.MethodBuilder;
1660 if (mb != null && filter (mb, criteria) == true) {
1661 if (members == null)
1662 members = new ArrayList ();
1669 if (operators != null) {
1670 int len = operators.Count;
1671 for (int i = 0; i < len; i++) {
1672 Operator o = (Operator) operators [i];
1674 if ((o.ModFlags & modflags) == 0)
1676 if ((o.ModFlags & static_mask) != static_flags)
1679 MethodBuilder ob = o.OperatorMethodBuilder;
1680 if (ob != null && filter (ob, criteria) == true) {
1681 if (members == null)
1682 members = new ArrayList ();
1689 if (properties != null) {
1690 int len = properties.Count;
1691 for (int i = 0; i < len; i++) {
1692 Property p = (Property) properties [i];
1694 if ((p.ModFlags & modflags) == 0)
1696 if ((p.ModFlags & static_mask) != static_flags)
1702 if (b != null && filter (b, criteria) == true) {
1703 if (members == null)
1704 members = new ArrayList ();
1710 if (b != null && filter (b, criteria) == true) {
1711 if (members == null)
1712 members = new ArrayList ();
1719 if (indexers != null) {
1720 int len = indexers.Count;
1721 for (int i = 0; i < len; i++) {
1722 Indexer ix = (Indexer) indexers [i];
1724 if ((ix.ModFlags & modflags) == 0)
1726 if ((ix.ModFlags & static_mask) != static_flags)
1732 if (b != null && filter (b, criteria) == true) {
1733 if (members == null)
1734 members = new ArrayList ();
1740 if (b != null && filter (b, criteria) == true) {
1741 if (members == null)
1742 members = new ArrayList ();
1750 if ((mt & MemberTypes.Event) != 0) {
1751 if (events != null) {
1752 int len = events.Count;
1753 for (int i = 0; i < len; i++) {
1754 Event e = (Event) events [i];
1756 if ((e.ModFlags & modflags) == 0)
1758 if ((e.ModFlags & static_mask) != static_flags)
1761 MemberInfo eb = e.EventBuilder;
1762 if (eb != null && filter (eb, criteria) == true) {
1763 if (members == null)
1764 members = new ArrayList ();
1766 members.Add (e.EventBuilder);
1772 if ((mt & MemberTypes.Property) != 0){
1773 if (properties != null) {
1774 int len = properties.Count;
1775 for (int i = 0; i < len; i++) {
1776 Property p = (Property) properties [i];
1778 if ((p.ModFlags & modflags) == 0)
1780 if ((p.ModFlags & static_mask) != static_flags)
1783 MemberInfo pb = p.PropertyBuilder;
1784 if (pb != null && filter (pb, criteria) == true) {
1785 if (members == null)
1786 members = new ArrayList ();
1788 members.Add (p.PropertyBuilder);
1793 if (indexers != null) {
1794 int len = indexers.Count;
1795 for (int i = 0; i < len; i++) {
1796 Indexer ix = (Indexer) indexers [i];
1798 if ((ix.ModFlags & modflags) == 0)
1800 if ((ix.ModFlags & static_mask) != static_flags)
1803 MemberInfo ib = ix.PropertyBuilder;
1804 if (ib != null && filter (ib, criteria) == true) {
1805 if (members == null)
1806 members = new ArrayList ();
1808 members.Add (ix.PropertyBuilder);
1814 if ((mt & MemberTypes.NestedType) != 0) {
1815 if (types != null) {
1816 int len = types.Count;
1817 for (int i = 0; i < len; i++) {
1818 TypeContainer t = (TypeContainer) types [i];
1820 if ((t.ModFlags & modflags) == 0)
1823 TypeBuilder tb = t.TypeBuilder;
1824 if (tb != null && (filter (tb, criteria) == true)) {
1825 if (members == null)
1826 members = new ArrayList ();
1833 if (enums != null) {
1834 int len = enums.Count;
1835 for (int i = 0; i < len; i++) {
1836 Enum en = (Enum) enums [i];
1838 if ((en.ModFlags & modflags) == 0)
1841 TypeBuilder tb = en.TypeBuilder;
1842 if (tb != null && (filter (tb, criteria) == true)) {
1843 if (members == null)
1844 members = new ArrayList ();
1851 if (delegates != null) {
1852 int len = delegates.Count;
1853 for (int i = 0; i < len; i++) {
1854 Delegate d = (Delegate) delegates [i];
1856 if ((d.ModFlags & modflags) == 0)
1859 TypeBuilder tb = d.TypeBuilder;
1860 if (tb != null && (filter (tb, criteria) == true)) {
1861 if (members == null)
1862 members = new ArrayList ();
1869 if (interfaces != null) {
1870 int len = interfaces.Count;
1871 for (int i = 0; i < len; i++) {
1872 TypeContainer iface = (TypeContainer) interfaces [i];
1874 if ((iface.ModFlags & modflags) == 0)
1877 TypeBuilder tb = iface.TypeBuilder;
1878 if (tb != null && (filter (tb, criteria) == true)) {
1879 if (members == null)
1880 members = new ArrayList ();
1888 if ((mt & MemberTypes.Constructor) != 0){
1889 if (((bf & BindingFlags.Instance) != 0) && (instance_constructors != null)){
1890 int len = instance_constructors.Count;
1891 for (int i = 0; i < len; i++) {
1892 Constructor c = (Constructor) instance_constructors [i];
1894 ConstructorBuilder cb = c.ConstructorBuilder;
1895 if (cb != null && filter (cb, criteria) == true) {
1896 if (members == null)
1897 members = new ArrayList ();
1904 if (((bf & BindingFlags.Static) != 0) && (default_static_constructor != null)){
1905 ConstructorBuilder cb =
1906 default_static_constructor.ConstructorBuilder;
1908 if (cb != null && filter (cb, criteria) == true) {
1909 if (members == null)
1910 members = new ArrayList ();
1918 // Lookup members in parent if requested.
1920 if ((bf & BindingFlags.DeclaredOnly) == 0) {
1921 if (TypeBuilder.BaseType != null) {
1922 MemberList list = FindMembers (TypeBuilder.BaseType, mt, bf, filter, criteria);
1923 if (list.Count > 0) {
1924 if (members == null)
1925 members = new ArrayList ();
1927 members.AddRange (list);
1930 if (base_inteface_types != null) {
1931 foreach (Type base_type in base_inteface_types) {
1932 MemberList list = TypeContainer.FindMembers (base_type, mt, bf, filter, criteria);
1934 if (list.Count > 0) {
1935 if (members == null)
1936 members = new ArrayList ();
1937 members.AddRange (list);
1943 Timer.StopTimer (TimerType.TcFindMembers);
1945 if (members == null)
1946 return MemberList.Empty;
1948 return new MemberList (members);
1951 public override MemberCache MemberCache {
1953 return member_cache;
1957 public static MemberList FindMembers (Type t, MemberTypes mt, BindingFlags bf,
1958 MemberFilter filter, object criteria)
1960 DeclSpace ds = TypeManager.LookupDeclSpace (t);
1963 return ds.FindMembers (mt, bf, filter, criteria);
1965 return new MemberList (t.FindMembers (mt, bf, filter, criteria));
1970 // FindMethods will look for methods not only in the type `t', but in
1971 // any interfaces implemented by the type.
1973 public static MethodInfo [] FindMethods (Type t, BindingFlags bf,
1974 MemberFilter filter, object criteria)
1980 /// Emits the values for the constants
1982 public void EmitConstants ()
1984 if (constants != null)
1985 foreach (Const con in constants)
1990 protected virtual void VerifyMembers (EmitContext ec)
1993 // Check for internal or private fields that were never assigned
1995 if (RootContext.WarningLevel >= 3) {
1996 if (fields != null){
1997 foreach (Field f in fields) {
1998 if ((f.ModFlags & Modifiers.Accessibility) != Modifiers.PRIVATE)
2001 if ((f.status & Field.Status.USED) == 0){
2002 Report.Warning (169, f.Location, "The private field '{0}' is never used", f.GetSignatureForError ());
2007 // Only report 649 on level 4
2009 if (RootContext.WarningLevel < 4)
2012 if ((f.status & Field.Status.ASSIGNED) != 0)
2015 Report.Warning (649, f.Location, "Field '{0}' is never assigned to, and will always have its default value '{1}'", f.GetSignatureForError (), "");
2022 /// Emits the code, this step is performed after all
2023 /// the types, enumerations, constructors
2025 public void EmitType ()
2027 if (OptAttributes != null)
2028 OptAttributes.Emit (ec, this);
2032 if (instance_constructors != null) {
2033 if (TypeBuilder.IsSubclassOf (TypeManager.attribute_type) && RootContext.VerifyClsCompliance && IsClsCompliaceRequired (this)) {
2034 bool has_compliant_args = false;
2036 foreach (Constructor c in instance_constructors) {
2039 if (has_compliant_args)
2042 has_compliant_args = c.HasCompliantArgs;
2044 if (!has_compliant_args)
2045 Report.Error (3015, Location, "'{0}' has no accessible constructors which use only CLS-compliant types", GetSignatureForError ());
2047 foreach (Constructor c in instance_constructors)
2054 if (default_static_constructor != null)
2055 default_static_constructor.Emit ();
2057 if (methods != null)
2058 foreach (Method m in methods)
2061 if (operators != null)
2062 foreach (Operator o in operators)
2065 if (properties != null)
2066 foreach (Property p in properties)
2069 if (indexers != null){
2074 foreach (Field f in fields)
2077 if (events != null){
2078 foreach (Event e in Events)
2082 if (delegates != null) {
2083 foreach (Delegate d in Delegates) {
2088 if (enums != null) {
2089 foreach (Enum e in enums) {
2094 if (parts != null) {
2095 foreach (ClassPart part in parts)
2099 if ((Pending != null) && !(this is ClassPart))
2100 if (Pending.VerifyPendingMethods ())
2105 if (iterators != null)
2106 foreach (Iterator iterator in iterators)
2107 iterator.EmitType ();
2109 // if (types != null)
2110 // foreach (TypeContainer tc in types)
2114 public override void CloseType ()
2116 if ((caching_flags & Flags.CloseTypeCreated) != 0)
2120 caching_flags |= Flags.CloseTypeCreated;
2121 TypeBuilder.CreateType ();
2122 } catch (TypeLoadException){
2124 // This is fine, the code still created the type
2126 // Report.Warning (-20, "Exception while creating class: " + TypeBuilder.Name);
2127 // Console.WriteLine (e.Message);
2129 Console.WriteLine ("In type: " + Name);
2134 foreach (Enum en in Enums)
2138 foreach (TypeContainer tc in Types)
2139 if (tc.Kind == Kind.Struct)
2142 foreach (TypeContainer tc in Types)
2143 if (tc.Kind != Kind.Struct)
2147 if (Delegates != null)
2148 foreach (Delegate d in Delegates)
2151 if (Iterators != null)
2152 foreach (Iterator i in Iterators)
2160 initialized_fields = null;
2161 initialized_static_fields = null;
2170 default_constructor = null;
2171 default_static_constructor = null;
2173 OptAttributes = null;
2175 parent_container = null;
2176 member_cache = null;
2179 // TODO: make it obsolete and use GetSignatureForError
2180 public string MakeName (string n)
2182 return "`" + Name + "." + n + "'";
2186 // Performs the validation on a Method's modifiers (properties have
2187 // the same properties).
2189 public bool MethodModifiersValid (int flags, string n, Location loc)
2191 const int vao = (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE);
2192 const int va = (Modifiers.VIRTUAL | Modifiers.ABSTRACT);
2193 const int nv = (Modifiers.NEW | Modifiers.VIRTUAL);
2197 // At most one of static, virtual or override
2199 if ((flags & Modifiers.STATIC) != 0){
2200 if ((flags & vao) != 0){
2202 112, loc, "static method " + MakeName (n) + "can not be marked " +
2203 "as virtual, abstract or override");
2208 if (Kind == Kind.Struct){
2209 if ((flags & va) != 0){
2210 Modifiers.Error_InvalidModifier (loc, "virtual or abstract");
2215 if ((flags & Modifiers.OVERRIDE) != 0 && (flags & nv) != 0){
2217 113, loc, MakeName (n) +
2218 " marked as override cannot be marked as new or virtual");
2223 // If the declaration includes the abstract modifier, then the
2224 // declaration does not include static, virtual or extern
2226 if ((flags & Modifiers.ABSTRACT) != 0){
2227 if ((flags & Modifiers.EXTERN) != 0){
2229 180, loc, MakeName (n) + " can not be both abstract and extern");
2233 if ((flags & Modifiers.VIRTUAL) != 0){
2235 503, loc, MakeName (n) + " can not be both abstract and virtual");
2239 if ((ModFlags & Modifiers.ABSTRACT) == 0){
2241 513, loc, MakeName (n) +
2242 " is abstract but its container class is not");
2248 if ((flags & Modifiers.PRIVATE) != 0){
2249 if ((flags & vao) != 0){
2251 621, loc, MakeName (n) +
2252 " virtual or abstract members can not be private");
2257 if ((flags & Modifiers.SEALED) != 0){
2258 if ((flags & Modifiers.OVERRIDE) == 0){
2260 238, loc, MakeName (n) +
2261 " cannot be sealed because it is not an override");
2269 public bool UserDefinedStaticConstructor {
2271 return default_static_constructor != null;
2275 protected override bool VerifyClsCompliance (DeclSpace ds)
2277 if (!base.VerifyClsCompliance (ds))
2282 // parent_container is null for System.Object
2283 if (parent_container != null && !AttributeTester.IsClsCompliant (parent_container.Type)) {
2284 Report.Error (3009, Location, "'{0}': base type '{1}' is not CLS-compliant", GetSignatureForError (), TypeManager.CSharpName (parent_container.Type));
2291 /// Checks whether container name is CLS Compliant
2293 void VerifyClsName ()
2295 Hashtable parent_members = parent_container == null ?
2297 parent_container.MemberCache.GetPublicMembers ();
2298 Hashtable this_members = new Hashtable ();
2300 foreach (DictionaryEntry entry in defined_names) {
2301 MemberCore mc = (MemberCore)entry.Value;
2302 if (!mc.IsClsCompliaceRequired (this))
2305 string name = (string)entry.Key;
2306 string basename = name.Substring (name.LastIndexOf ('.') + 1);
2308 string lcase = basename.ToLower (System.Globalization.CultureInfo.InvariantCulture);
2309 object found = parent_members [lcase];
2310 if (found == null) {
2311 found = this_members [lcase];
2312 if (found == null) {
2313 this_members.Add (lcase, mc);
2318 if ((mc.ModFlags & Modifiers.OVERRIDE) != 0)
2321 if (found is MemberInfo) {
2322 if (basename == ((MemberInfo)found).Name)
2324 Report.SymbolRelatedToPreviousError ((MemberInfo)found);
2326 Report.SymbolRelatedToPreviousError ((MemberCore) found);
2328 Report.Error (3005, mc.Location, "Identifier '{0}' differing only in case is not CLS-compliant", mc.GetSignatureForError ());
2334 /// Performs checks for an explicit interface implementation. First it
2335 /// checks whether the `interface_type' is a base inteface implementation.
2336 /// Then it checks whether `name' exists in the interface type.
2338 public virtual bool VerifyImplements (Type interface_type, string full,
2339 string name, Location loc)
2343 if (ifaces != null){
2344 foreach (TypeExpr t in ifaces){
2345 if (t.Type == interface_type){
2353 Report.Error (540, "`" + full + "': containing class does not implement interface `" + interface_type.FullName + "'");
2360 protected override void VerifyObsoleteAttribute()
2362 CheckUsageOfObsoleteAttribute (base_class_type);
2367 foreach (TypeExpr expr in ifaces) {
2368 CheckUsageOfObsoleteAttribute (expr.Type);
2377 string IMemberContainer.Name {
2383 Type IMemberContainer.Type {
2389 MemberCache IMemberContainer.MemberCache {
2391 return member_cache;
2395 bool IMemberContainer.IsInterface {
2397 return Kind == Kind.Interface;
2401 MemberList IMemberContainer.GetMembers (MemberTypes mt, BindingFlags bf)
2403 return FindMembers (mt, bf | BindingFlags.DeclaredOnly, null, null);
2406 public virtual IMemberContainer ParentContainer {
2408 return parent_container;
2413 public class PartialContainer : TypeContainer {
2415 public readonly Namespace Namespace;
2416 public readonly int OriginalModFlags;
2417 public readonly int AllowedModifiers;
2418 public readonly TypeAttributes DefaultTypeAttributes;
2420 static PartialContainer Create (NamespaceEntry ns, TypeContainer parent,
2421 MemberName name, int mod_flags, Kind kind,
2424 PartialContainer pc;
2425 string full_name = name.GetName (true);
2426 DeclSpace ds = (DeclSpace) RootContext.Tree.Decls [full_name];
2428 pc = ds as PartialContainer;
2432 260, ds.Location, "Missing partial modifier " +
2433 "on declaration of type `{0}'; another " +
2434 "partial implementation of this type exists",
2437 Report.LocationOfPreviousError (loc);
2441 if (pc.Kind != kind) {
2443 261, loc, "Partial declarations of `{0}' " +
2444 "must be all classes, all structs or " +
2445 "all interfaces", name);
2449 if (pc.OriginalModFlags != mod_flags) {
2451 262, loc, "Partial declarations of `{0}' " +
2452 "have conflicting accessibility modifiers",
2460 pc = new PartialContainer (ns, parent, name, mod_flags, kind, loc);
2461 RootContext.Tree.RecordDecl (full_name, pc);
2462 parent.AddType (pc);
2467 public static ClassPart CreatePart (NamespaceEntry ns, TypeContainer parent,
2468 MemberName name, int mod, Attributes attrs,
2469 Kind kind, Location loc)
2471 PartialContainer pc = Create (ns, parent, name, mod, kind, loc);
2473 // An error occured; create a dummy container, but don't
2475 pc = new PartialContainer (ns, parent, name, mod, kind, loc);
2478 ClassPart part = new ClassPart (ns, pc, mod, attrs, kind, loc);
2483 protected PartialContainer (NamespaceEntry ns, TypeContainer parent,
2484 MemberName name, int mod, Kind kind, Location l)
2485 : base (ns, parent, name, null, kind, l)
2487 this.Namespace = ns.NS;
2491 AllowedModifiers = Class.AllowedModifiers;
2492 DefaultTypeAttributes = Class.DefaultTypeAttributes;
2496 AllowedModifiers = Struct.AllowedModifiers;
2497 DefaultTypeAttributes = Struct.DefaultTypeAttributes;
2500 case Kind.Interface:
2501 AllowedModifiers = Interface.AllowedModifiers;
2502 DefaultTypeAttributes = Interface.DefaultTypeAttributes;
2506 throw new InvalidOperationException ();
2510 if (parent.Parent == null)
2511 accmods = Modifiers.INTERNAL;
2513 accmods = Modifiers.PRIVATE;
2515 this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
2516 this.OriginalModFlags = mod;
2519 public override void Register ()
2521 if (Kind == Kind.Interface)
2522 Parent.AddInterface (this);
2523 else if (Kind == Kind.Class || Kind == Kind.Struct)
2524 Parent.AddClassOrStruct (this);
2526 throw new InvalidOperationException ();
2529 public override PendingImplementation GetPendingImplementations ()
2531 return PendingImplementation.GetPendingImplementations (this);
2534 public ClassPart AddPart (NamespaceEntry ns, int mod, Attributes attrs,
2537 ClassPart part = new ClassPart (ns, this, mod, attrs, Kind, l);
2542 public override TypeAttributes TypeAttr {
2544 return base.TypeAttr | DefaultTypeAttributes;
2549 public class ClassPart : TypeContainer, IMemberContainer {
2550 public readonly PartialContainer PartialContainer;
2551 public readonly bool IsPartial;
2553 public ClassPart (NamespaceEntry ns, PartialContainer parent,
2554 int mod, Attributes attrs, Kind kind, Location l)
2555 : base (ns, parent.Parent, parent.MemberName, attrs, kind, l)
2557 this.PartialContainer = parent;
2558 this.IsPartial = true;
2561 if (parent.Parent == null)
2562 accmods = Modifiers.INTERNAL;
2564 accmods = Modifiers.PRIVATE;
2566 this.ModFlags = Modifiers.Check (
2567 parent.AllowedModifiers, mod, accmods, l);
2570 public override void Register ()
2574 public override PendingImplementation GetPendingImplementations ()
2576 return PartialContainer.Pending;
2579 public override bool VerifyImplements (Type interface_type, string full,
2580 string name, Location loc)
2582 return PartialContainer.VerifyImplements (
2583 interface_type, full, name, loc);
2586 public override IMemberContainer ParentContainer {
2588 return PartialContainer.ParentContainer;
2593 public abstract class ClassOrStruct : TypeContainer {
2594 bool hasExplicitLayout = false;
2595 ListDictionary declarative_security;
2597 public ClassOrStruct (NamespaceEntry ns, TypeContainer parent,
2598 MemberName name, Attributes attrs, Kind kind,
2600 : base (ns, parent, name, attrs, kind, l)
2604 public override PendingImplementation GetPendingImplementations ()
2606 return PendingImplementation.GetPendingImplementations (this);
2609 public override bool HasExplicitLayout {
2611 return hasExplicitLayout;
2615 protected override void VerifyMembers (EmitContext ec)
2617 base.VerifyMembers (ec);
2619 if ((events != null) && (RootContext.WarningLevel >= 3)) {
2620 foreach (Event e in events){
2622 Report.Warning (67, e.Location, "The event '{0}' is never used", e.GetSignatureForError ());
2627 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
2629 if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
2630 if (declarative_security == null)
2631 declarative_security = new ListDictionary ();
2633 a.ExtractSecurityPermissionSet (declarative_security);
2637 if (a.Type == TypeManager.struct_layout_attribute_type
2638 && (LayoutKind) a.GetPositionalValue (0) == LayoutKind.Explicit)
2639 hasExplicitLayout = true;
2641 base.ApplyAttributeBuilder (a, cb);
2644 public override void Emit()
2648 if (declarative_security != null) {
2649 foreach (DictionaryEntry de in declarative_security) {
2650 TypeBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
2655 public override void Register ()
2657 Parent.AddClassOrStruct (this);
2662 /// Class handles static classes declaration
2664 public sealed class StaticClass: Class {
2665 public StaticClass (NamespaceEntry ns, TypeContainer parent, MemberName name, int mod,
2666 Attributes attrs, Location l)
2667 : base (ns, parent, name, mod & ~Modifiers.STATIC, attrs, l)
2669 if (RootContext.Version == LanguageVersion.ISO_1) {
2670 Report.FeatureIsNotStandardized (l, "static classes");
2671 Environment.Exit (1);
2675 protected override void DefineContainerMembers (MemberCoreArrayList list)
2680 foreach (MemberCore m in list) {
2681 if (m is Operator) {
2682 Report.Error (715, m.Location, "'{0}': static classes cannot contain user-defined operators", m.GetSignatureForError (this));
2686 if ((m.ModFlags & Modifiers.STATIC) != 0)
2689 if (m is Constructor) {
2690 Report.Error (710, m.Location, "'{0}': Static classes cannot have instance constructors", GetSignatureForError ());
2694 if (m is Destructor) {
2695 Report.Error (711, m.Location, "'{0}': Static class cannot contain destructor", GetSignatureForError ());
2699 Report.Error (708, m.Location, "'{0}': cannot declare instance members in a static class", m.GetSignatureForError (this));
2702 base.DefineContainerMembers (list);
2705 public override TypeBuilder DefineType()
2707 TypeBuilder tb = base.DefineType ();
2711 if (base_class_type != TypeManager.object_type) {
2712 Report.Error (713, Location, "Static class '{0}' cannot derive from type '{1}'. Static classes must derive from object", GetSignatureForError (), TypeManager.CSharpName (base_class_type));
2716 if (base_inteface_types != null) {
2717 foreach (Type t in base_inteface_types)
2718 Report.SymbolRelatedToPreviousError (t);
2719 Report.Error (714, Location, "'{0}': static classes cannot implement interfaces", GetSignatureForError ());
2724 public override TypeAttributes TypeAttr {
2726 return base.TypeAttr | TypeAttributes.Abstract | TypeAttributes.Sealed;
2731 public class Class : ClassOrStruct {
2733 // Modifiers allowed in a class declaration
2735 public const int AllowedModifiers =
2738 Modifiers.PROTECTED |
2739 Modifiers.INTERNAL |
2741 Modifiers.ABSTRACT |
2745 // Information in the case we are an attribute type
2746 AttributeUsageAttribute attribute_usage;
2748 public Class (NamespaceEntry ns, TypeContainer parent, MemberName name, int mod,
2749 Attributes attrs, Location l)
2750 : base (ns, parent, name, attrs, Kind.Class, l)
2754 if (parent.Parent == null)
2755 accmods = Modifiers.INTERNAL;
2757 accmods = Modifiers.PRIVATE;
2759 this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
2760 if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.SEALED)) == (Modifiers.ABSTRACT | Modifiers.SEALED)) {
2761 Report.Error (502, Location, "'{0}' cannot be both abstract and sealed", GetSignatureForError ());
2764 attribute_usage = new AttributeUsageAttribute (AttributeTargets.All);
2767 public override AttributeTargets AttributeTargets {
2769 return AttributeTargets.Class;
2773 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
2775 if (a.UsageAttribute != null) {
2776 if (base_class_type != TypeManager.attribute_type && !base_class_type.IsSubclassOf (TypeManager.attribute_type) &&
2777 TypeBuilder.FullName != "System.Attribute") {
2778 Report.Error (641, a.Location, "Attribute '{0}' is only valid on classes derived from System.Attribute", a.Name);
2780 attribute_usage = a.UsageAttribute;
2783 base.ApplyAttributeBuilder (a, cb);
2786 public AttributeUsageAttribute AttributeUsage {
2788 return attribute_usage;
2792 public const TypeAttributes DefaultTypeAttributes =
2793 TypeAttributes.AutoLayout | TypeAttributes.Class;
2796 // FIXME: How do we deal with the user specifying a different
2799 public override TypeAttributes TypeAttr {
2801 return base.TypeAttr | DefaultTypeAttributes;
2806 public class Struct : ClassOrStruct {
2808 // Modifiers allowed in a struct declaration
2810 public const int AllowedModifiers =
2813 Modifiers.PROTECTED |
2814 Modifiers.INTERNAL |
2818 public Struct (NamespaceEntry ns, TypeContainer parent, MemberName name,
2819 int mod, Attributes attrs, Location l)
2820 : base (ns, parent, name, attrs, Kind.Struct, l)
2824 if (parent.Parent == null)
2825 accmods = Modifiers.INTERNAL;
2827 accmods = Modifiers.PRIVATE;
2829 this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
2831 this.ModFlags |= Modifiers.SEALED;
2834 public override AttributeTargets AttributeTargets {
2836 return AttributeTargets.Struct;
2840 public const TypeAttributes DefaultTypeAttributes =
2841 TypeAttributes.SequentialLayout |
2842 TypeAttributes.Sealed |
2843 TypeAttributes.BeforeFieldInit;
2846 // FIXME: Allow the user to specify a different set of attributes
2847 // in some cases (Sealed for example is mandatory for a class,
2848 // but what SequentialLayout can be changed
2850 public override TypeAttributes TypeAttr {
2852 return base.TypeAttr | DefaultTypeAttributes;
2860 public class Interface : TypeContainer, IMemberContainer {
2862 /// Modifiers allowed in a class declaration
2864 public const int AllowedModifiers =
2867 Modifiers.PROTECTED |
2868 Modifiers.INTERNAL |
2872 public Interface (NamespaceEntry ns, TypeContainer parent, MemberName name, int mod,
2873 Attributes attrs, Location l)
2874 : base (ns, parent, name, attrs, Kind.Interface, l)
2878 if (parent.Parent == null)
2879 accmods = Modifiers.INTERNAL;
2881 accmods = Modifiers.PRIVATE;
2883 this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
2886 public override void Register ()
2888 Parent.AddInterface (this);
2891 public override PendingImplementation GetPendingImplementations ()
2896 public override AttributeTargets AttributeTargets {
2898 return AttributeTargets.Interface;
2902 public const TypeAttributes DefaultTypeAttributes =
2903 TypeAttributes.AutoLayout |
2904 TypeAttributes.Abstract |
2905 TypeAttributes.Interface;
2907 public override TypeAttributes TypeAttr {
2909 return base.TypeAttr | DefaultTypeAttributes;
2914 public abstract class MethodCore : MemberBase {
2915 public readonly Parameters Parameters;
2916 protected ToplevelBlock block;
2919 // Parameters, cached for semantic analysis.
2921 protected InternalParameters parameter_info;
2922 protected Type [] parameter_types;
2924 // Whether this is an operator method.
2925 public bool IsOperator;
2928 // The method we're overriding if this is an override method.
2930 protected MethodInfo parent_method = null;
2932 static string[] attribute_targets = new string [] { "method", "return" };
2934 public MethodCore (TypeContainer parent, Expression type, int mod,
2935 int allowed_mod, bool is_interface, MemberName name,
2936 Attributes attrs, Parameters parameters, Location loc)
2937 : base (parent, type, mod, allowed_mod, Modifiers.PRIVATE, name,
2940 Parameters = parameters;
2941 IsInterface = is_interface;
2945 // Returns the System.Type array for the parameters of this method
2947 public Type [] ParameterTypes {
2949 return parameter_types;
2953 public InternalParameters ParameterInfo
2956 return parameter_info;
2960 public ToplevelBlock Block {
2970 protected override bool CheckBase ()
2972 if (!base.CheckBase ())
2975 // Check whether arguments were correct.
2976 if (!DoDefineParameters ())
2979 if ((caching_flags & Flags.TestMethodDuplication) != 0 && !CheckForDuplications ())
2985 // Is null for System.Object while compiling corlib and base interfaces
2986 if (Parent.ParentContainer == null) {
2987 if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) {
2988 Report.Warning (109, Location, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError (Parent));
2993 Type parent_ret_type = null;
2994 parent_method = FindOutParentMethod (Parent, ref parent_ret_type);
2996 // method is override
2997 if (parent_method != null) {
2999 if (!CheckMethodAgainstBase ())
3002 if ((ModFlags & Modifiers.NEW) == 0) {
3003 if (MemberType != TypeManager.TypeToCoreType (parent_ret_type)) {
3004 Report.SymbolRelatedToPreviousError (parent_method);
3005 Report.Error (508, Location, GetSignatureForError (Parent) + ": cannot " +
3006 "change return type when overriding inherited member");
3010 if (parent_method.IsAbstract && !IsInterface) {
3011 Report.SymbolRelatedToPreviousError (parent_method);
3012 Report.Error (533, Location, "'{0}' hides inherited abstract member", GetSignatureForError (Parent));
3017 if (parent_method.IsSpecialName && !(this is PropertyBase)) {
3018 Report.Error (561, Location, "'{0}': cannot override '{1}' because it is a special compiler-generated method", GetSignatureForError (Parent), TypeManager.GetFullNameSignature (parent_method));
3022 if (RootContext.WarningLevel > 2) {
3023 if (Name == "Equals" && parameter_types.Length == 1 && parameter_types [0] == TypeManager.object_type)
3024 Parent.Methods.HasEquals = true;
3025 else if (Name == "GetHashCode" && parameter_types.Length == 0)
3026 Parent.Methods.HasGetHashCode = true;
3029 ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (parent_method);
3031 EmitContext ec = new EmitContext (this.Parent, this.Parent, Location, null, null, ModFlags, false);
3032 if (OptAttributes == null || !OptAttributes.Contains (TypeManager.obsolete_attribute_type, ec)) {
3033 Report.SymbolRelatedToPreviousError (parent_method);
3034 Report.Warning (672, 1, Location, "Member '{0}' overrides obsolete member. Add the Obsolete attribute to '{0}'", GetSignatureForError (Parent));
3040 MemberInfo conflict_symbol = Parent.FindMemberWithSameName (Name, !(this is Property));
3041 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
3042 if (conflict_symbol != null) {
3043 Report.SymbolRelatedToPreviousError (conflict_symbol);
3044 if (this is PropertyBase)
3045 Report.Error (544, Location, "'{0}': cannot override because '{1}' is not a property", GetSignatureForError (Parent), TypeManager.GetFullNameSignature (conflict_symbol));
3047 Report.Error (505, Location, "'{0}': cannot override because '{1}' is not a method", GetSignatureForError (Parent), TypeManager.GetFullNameSignature (conflict_symbol));
3049 Report.Error (115, Location, "'{0}': no suitable methods found to override", GetSignatureForError (Parent));
3053 if (conflict_symbol == null) {
3054 if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) {
3055 Report.Warning (109, Location, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError (Parent));
3060 if ((ModFlags & Modifiers.NEW) == 0) {
3061 if (this is Method && conflict_symbol is MethodBase)
3064 Report.SymbolRelatedToPreviousError (conflict_symbol);
3065 Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent));
3073 // Performs various checks on the MethodInfo `mb' regarding the modifier flags
3074 // that have been defined.
3076 // `name' is the user visible name for reporting errors (this is used to
3077 // provide the right name regarding method names and properties)
3079 bool CheckMethodAgainstBase ()
3083 // TODO: replace with GetSignatureForError
3084 string name = parent_method.DeclaringType.Name + "." + parent_method.Name;
3086 if ((ModFlags & Modifiers.OVERRIDE) != 0){
3087 if (!(parent_method.IsAbstract || parent_method.IsVirtual)){
3089 506, Location, Parent.MakeName (Name) +
3090 ": cannot override inherited member `" +
3091 name + "' because it is not " +
3092 "virtual, abstract or override");
3096 // Now we check that the overriden method is not final
3098 if (parent_method.IsFinal) {
3099 // This happens when implementing interface methods.
3100 if (parent_method.IsHideBySig && parent_method.IsVirtual) {
3102 506, Location, Parent.MakeName (Name) +
3103 ": cannot override inherited member `" +
3104 name + "' because it is not " +
3105 "virtual, abstract or override");
3107 Report.Error (239, Location, Parent.MakeName (Name) + " : cannot " +
3108 "override inherited member `" + name +
3109 "' because it is sealed.");
3113 // Check that the permissions are not being changed
3115 MethodAttributes thisp = flags & MethodAttributes.MemberAccessMask;
3116 MethodAttributes parentp = parent_method.Attributes & MethodAttributes.MemberAccessMask;
3119 // special case for "protected internal"
3122 if ((parentp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
3124 // when overriding protected internal, the method can be declared
3125 // protected internal only within the same assembly
3128 if ((thisp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
3129 if (Parent.TypeBuilder.Assembly != parent_method.DeclaringType.Assembly){
3131 // assemblies differ - report an error
3134 Error_CannotChangeAccessModifiers (Parent, parent_method, name);
3136 } else if (thisp != parentp) {
3138 // same assembly, but other attributes differ - report an error
3141 Error_CannotChangeAccessModifiers (Parent, parent_method, name);
3144 } else if ((thisp & MethodAttributes.Family) != MethodAttributes.Family) {
3146 // if it's not "protected internal", it must be "protected"
3149 Error_CannotChangeAccessModifiers (Parent, parent_method, name);
3151 } else if (Parent.TypeBuilder.Assembly == parent_method.DeclaringType.Assembly) {
3153 // protected within the same assembly - an error
3155 Error_CannotChangeAccessModifiers (Parent, parent_method, name);
3157 } else if ((thisp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem)) !=
3158 (parentp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem))) {
3160 // protected ok, but other attributes differ - report an error
3162 Error_CannotChangeAccessModifiers (Parent, parent_method, name);
3166 if (thisp != parentp){
3167 Error_CannotChangeAccessModifiers (Parent, parent_method, name);
3173 if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0 && Name != "Finalize") {
3174 ModFlags |= Modifiers.NEW;
3175 Report.SymbolRelatedToPreviousError (parent_method);
3176 if (!IsInterface && (parent_method.IsVirtual || parent_method.IsAbstract)) {
3177 if (RootContext.WarningLevel >= 2)
3178 Report.Warning (114, Location, "'{0}' hides inherited member '{1}'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword", GetSignatureForError (Parent), TypeManager.CSharpSignature (parent_method));
3180 Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent));
3186 void Error_CannotChangeAccessModifiers (TypeContainer parent, MethodInfo parent_method, string name)
3189 // FIXME: report the old/new permissions?
3192 507, Location, parent.MakeName (Name) +
3193 ": can't change the access modifiers when overriding inherited " +
3194 "member `" + name + "'");
3197 protected static string Error722 {
3199 return "'{0}': static types cannot be used as return types";
3204 /// For custom member duplication search in a container
3206 protected abstract bool CheckForDuplications ();
3209 /// Gets parent method and its return type
3211 protected abstract MethodInfo FindOutParentMethod (TypeContainer container, ref Type parent_ret_type);
3213 protected virtual bool DoDefineParameters ()
3215 EmitContext ec = Parent.EmitContext;
3217 throw new InternalErrorException ("DoDefineParameters invoked too early");
3219 bool old_unsafe = ec.InUnsafe;
3220 ec.InUnsafe = InUnsafe;
3221 // Check if arguments were correct
3222 parameter_types = Parameters.GetParameterInfo (ec);
3223 ec.InUnsafe = old_unsafe;
3225 if ((parameter_types == null) ||
3226 !CheckParameters (Parent, parameter_types))
3229 parameter_info = new InternalParameters (parameter_types, Parameters);
3231 Parameter array_param = Parameters.ArrayParameter;
3232 if ((array_param != null) &&
3233 (!array_param.ParameterType.IsArray ||
3234 (array_param.ParameterType.GetArrayRank () != 1))) {
3235 Report.Error (225, Location, "params parameter has to be a single dimensional array");
3242 public override string[] ValidAttributeTargets {
3244 return attribute_targets;
3248 protected override bool VerifyClsCompliance (DeclSpace ds)
3250 if (!base.VerifyClsCompliance (ds)) {
3251 if ((ModFlags & Modifiers.ABSTRACT) != 0 && IsExposedFromAssembly (ds) && ds.IsClsCompliaceRequired (ds)) {
3252 Report.Error (3011, Location, "'{0}': only CLS-compliant members can be abstract", GetSignatureForError ());
3257 if (Parameters.HasArglist) {
3258 Report.Error (3000, Location, "Methods with variable arguments are not CLS-compliant");
3261 if (!AttributeTester.IsClsCompliant (MemberType)) {
3262 Report.Error (3002, Location, "Return type of '{0}' is not CLS-compliant", GetSignatureForError ());
3265 AttributeTester.AreParametersCompliant (Parameters.FixedParameters, Location);
3270 protected bool IsDuplicateImplementation (MethodCore method)
3272 if ((method == this) || (method.Name != Name))
3275 Type[] param_types = method.ParameterTypes;
3276 if (param_types == null)
3279 if (param_types.Length != ParameterTypes.Length)
3282 for (int i = 0; i < param_types.Length; i++)
3283 if (param_types [i] != ParameterTypes [i])
3286 // TODO: make operator compatible with MethodCore to avoid this
3287 if (this is Operator && method is Operator) {
3288 if (MemberType != method.MemberType)
3293 // Try to report 663: method only differs on out/ref
3295 ParameterData info = ParameterInfo;
3296 ParameterData other_info = method.ParameterInfo;
3297 for (int i = 0; i < info.Count; i++){
3298 if (info.ParameterModifier (i) != other_info.ParameterModifier (i)){
3299 Report.Error (663, Location, "Overload method only differs in parameter modifier");
3304 Report.SymbolRelatedToPreviousError (method);
3305 Report.Error (111, Location, TypeContainer.Error111, Parent.Name, Name);
3309 protected override void VerifyObsoleteAttribute()
3311 base.VerifyObsoleteAttribute ();
3313 if (parameter_types == null)
3316 foreach (Type type in parameter_types) {
3317 CheckUsageOfObsoleteAttribute (type);
3322 public class SourceMethod : ISourceMethod
3324 TypeContainer container;
3327 protected SourceMethod (TypeContainer container, MethodBase builder,
3328 ISourceFile file, Location start, Location end)
3330 this.container = container;
3331 this.builder = builder;
3333 CodeGen.SymbolWriter.OpenMethod (
3334 file, this, start.Row, 0, end.Row, 0);
3337 public string Name {
3338 get { return builder.Name; }
3341 public int NamespaceID {
3342 get { return container.NamespaceEntry.SymbolFileID; }
3347 if (builder is MethodBuilder)
3348 return ((MethodBuilder) builder).GetToken ().Token;
3349 else if (builder is ConstructorBuilder)
3350 return ((ConstructorBuilder) builder).GetToken ().Token;
3352 throw new NotSupportedException ();
3356 public void CloseMethod ()
3358 if (CodeGen.SymbolWriter != null)
3359 CodeGen.SymbolWriter.CloseMethod ();
3362 public static SourceMethod Create (TypeContainer parent,
3363 MethodBase builder, Block block)
3365 if (CodeGen.SymbolWriter == null)
3370 Location start_loc = block.StartLocation;
3371 if (Location.IsNull (start_loc))
3374 Location end_loc = block.EndLocation;
3375 if (Location.IsNull (end_loc))
3378 ISourceFile file = start_loc.SourceFile;
3382 return new SourceMethod (
3383 parent, builder, file, start_loc, end_loc);
3387 public class Method : MethodCore, IIteratorContainer, IMethodData {
3388 public MethodBuilder MethodBuilder;
3389 public MethodData MethodData;
3390 ReturnParameter return_attributes;
3391 ListDictionary declarative_security;
3394 /// Modifiers allowed in a class declaration
3396 const int AllowedModifiers =
3399 Modifiers.PROTECTED |
3400 Modifiers.INTERNAL |
3405 Modifiers.OVERRIDE |
3406 Modifiers.ABSTRACT |
3408 Modifiers.METHOD_YIELDS |
3411 const int AllowedInterfaceModifiers =
3412 Modifiers.NEW | Modifiers.UNSAFE;
3415 // return_type can be "null" for VOID values.
3417 public Method (TypeContainer ds, Expression return_type, int mod, bool is_iface,
3418 MemberName name, Parameters parameters, Attributes attrs,
3420 : base (ds, return_type, mod,
3421 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
3422 is_iface, name, attrs, parameters, l)
3426 public override AttributeTargets AttributeTargets {
3428 return AttributeTargets.Method;
3432 public override string GetSignatureForError()
3434 if (MethodBuilder == null) {
3435 return GetSignatureForError (Parent);
3437 return TypeManager.CSharpSignature (MethodBuilder);
3441 /// Use this method when MethodBuilder is null
3443 public override string GetSignatureForError (TypeContainer tc)
3445 // TODO: get params from somewhere
3446 if (parameter_info == null)
3447 return base.GetSignatureForError (tc);
3449 // TODO: move to parameters
3450 System.Text.StringBuilder args = new System.Text.StringBuilder ();
3451 if (parameter_info.Parameters.FixedParameters != null) {
3452 for (int i = 0; i < parameter_info.Parameters.FixedParameters.Length; ++i) {
3453 Parameter p = parameter_info.Parameters.FixedParameters [i];
3454 args.Append (p.GetSignatureForError ());
3456 if (i < parameter_info.Parameters.FixedParameters.Length - 1)
3461 return String.Concat (base.GetSignatureForError (tc), "(", args.ToString (), ")");
3464 void DuplicateEntryPoint (MethodInfo b, Location location)
3468 "Program `" + CodeGen.FileName +
3469 "' has more than one entry point defined: `" +
3470 TypeManager.CSharpSignature(b) + "'");
3473 public bool IsEntryPoint (MethodBuilder b, InternalParameters pinfo)
3475 if (b.ReturnType != TypeManager.void_type &&
3476 b.ReturnType != TypeManager.int32_type)
3479 if (pinfo.Count == 0)
3482 if (pinfo.Count > 1)
3485 Type t = pinfo.ParameterType(0);
3487 (t.GetArrayRank() == 1) &&
3488 (TypeManager.GetElementType(t) == TypeManager.string_type) &&
3489 (pinfo.ParameterModifier(0) == Parameter.Modifier.NONE))
3495 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
3497 if (a.Target == AttributeTargets.ReturnValue) {
3498 if (return_attributes == null)
3499 return_attributes = new ReturnParameter (MethodBuilder, Location);
3501 return_attributes.ApplyAttributeBuilder (a, cb);
3505 if (a.Type == TypeManager.methodimpl_attr_type && a.IsInternalCall) {
3506 MethodBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall | MethodImplAttributes.Runtime);
3509 if (a.Type == TypeManager.dllimport_type) {
3510 const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
3511 if ((ModFlags & extern_static) != extern_static) {
3512 Report.Error (601, a.Location, "The DllImport attribute must be specified on a method marked `static' and `extern'");
3518 if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
3519 if (declarative_security == null)
3520 declarative_security = new ListDictionary ();
3521 a.ExtractSecurityPermissionSet (declarative_security);
3525 if (a.Type == TypeManager.conditional_attribute_type) {
3526 if (IsOperator || IsExplicitImpl) {
3527 Report.Error (577, Location, "Conditional not valid on '{0}' because it is a destructor, operator, or explicit interface implementation", GetSignatureForError ());
3531 if (ReturnType != TypeManager.void_type) {
3532 Report.Error (578, Location, "Conditional not valid on '{0}' because its return new ErrorData ( type is not void", GetSignatureForError ());
3536 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
3537 Report.Error (243, Location, "Conditional not valid on '{0}' because it is an override method", GetSignatureForError ());
3542 Report.Error (582, Location, "Conditional not valid on interface members");
3546 if (MethodData.IsImplementing) {
3547 Report.Error (629, Location, "Conditional member '{0}' cannot implement interface member", GetSignatureForError ());
3551 for (int i = 0; i < parameter_info.Count; ++i) {
3552 if ((parameter_info.ParameterModifier (i) & Parameter.Modifier.OUT) != 0) {
3553 Report.Error (685, Location, "Conditional method '{0}' cannot have an out parameter", GetSignatureForError ());
3559 MethodBuilder.SetCustomAttribute (cb);
3562 protected override bool CheckForDuplications ()
3564 ArrayList ar = Parent.Methods;
3566 int arLen = ar.Count;
3568 for (int i = 0; i < arLen; i++) {
3569 Method m = (Method) ar [i];
3570 if (IsDuplicateImplementation (m))
3575 ar = Parent.Properties;
3577 for (int i = 0; i < ar.Count; ++i) {
3578 PropertyBase pb = (PropertyBase) ar [i];
3579 if (pb.AreAccessorsDuplicateImplementation (this))
3584 ar = Parent.Indexers;
3586 for (int i = 0; i < ar.Count; ++i) {
3587 PropertyBase pb = (PropertyBase) ar [i];
3588 if (pb.AreAccessorsDuplicateImplementation (this))
3595 for (int i = 0; i < ar.Count; ++i) {
3596 Event ev = (Event) ar [i];
3597 if (ev.AreAccessorsDuplicateImplementation (this))
3608 public override bool Define ()
3617 flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
3619 MethodData = new MethodData (this, ParameterInfo, ModFlags, flags, this);
3621 if (!MethodData.Define (Parent))
3625 // Setup iterator if we are one
3627 if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
3628 Iterator iterator = new Iterator (
3629 Parent, Name, MemberType, ParameterTypes,
3630 ParameterInfo, ModFlags, block, Location);
3632 if (!iterator.DefineIterator ())
3635 block = iterator.Block;
3638 MethodBuilder = MethodData.MethodBuilder;
3641 // This is used to track the Entry Point,
3643 if (Name == "Main" &&
3644 ((ModFlags & Modifiers.STATIC) != 0) && RootContext.NeedsEntryPoint &&
3645 (RootContext.MainClass == null ||
3646 RootContext.MainClass == Parent.TypeBuilder.FullName)){
3647 if (IsEntryPoint (MethodBuilder, ParameterInfo)) {
3648 if (RootContext.EntryPoint == null) {
3649 RootContext.EntryPoint = MethodBuilder;
3650 RootContext.EntryPointLocation = Location;
3652 DuplicateEntryPoint (RootContext.EntryPoint, RootContext.EntryPointLocation);
3653 DuplicateEntryPoint (MethodBuilder, Location);
3656 if (RootContext.WarningLevel >= 4)
3657 Report.Warning (28, Location, "'{0}' has the wrong signature to be an entry point", TypeManager.CSharpSignature(MethodBuilder));
3661 if (MemberType.IsAbstract && MemberType.IsSealed) {
3662 Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
3672 public override void Emit ()
3674 MethodData.Emit (Parent, this);
3677 if (declarative_security != null) {
3678 foreach (DictionaryEntry de in declarative_security) {
3679 MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
3687 protected override MethodInfo FindOutParentMethod (TypeContainer container, ref Type parent_ret_type)
3689 MethodInfo mi = (MethodInfo) container.ParentContainer.MemberCache.FindMemberToOverride (
3690 container.TypeBuilder, Name, ParameterTypes, false);
3695 parent_ret_type = mi.ReturnType;
3699 protected override bool VerifyClsCompliance(DeclSpace ds)
3701 if (!base.VerifyClsCompliance (ds))
3704 if (parameter_types.Length > 0) {
3705 ArrayList al = (ArrayList)ds.MemberCache.Members [Name];
3707 ds.MemberCache.VerifyClsParameterConflict (al, this, MethodBuilder);
3714 void IIteratorContainer.SetYields ()
3716 ModFlags |= Modifiers.METHOD_YIELDS;
3719 #region IMethodData Members
3721 public CallingConventions CallingConventions {
3723 CallingConventions cc = Parameters.GetCallingConvention ();
3724 if (Parameters.HasArglist)
3725 block.HasVarargs = true;
3728 if ((ModFlags & Modifiers.STATIC) == 0)
3729 cc |= CallingConventions.HasThis;
3731 // FIXME: How is `ExplicitThis' used in C#?
3737 public Type ReturnType {
3743 public MemberName MethodName {
3749 public new Location Location {
3751 return base.Location;
3755 public EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig)
3757 return new EmitContext (
3758 tc, Parent, Location, ig, ReturnType, ModFlags, false);
3761 public ObsoleteAttribute GetObsoleteAttribute ()
3763 return GetObsoleteAttribute (Parent);
3767 /// Returns true if method has conditional attribute and the conditions is not defined (method is excluded).
3769 public bool IsExcluded (EmitContext ec)
3771 if ((caching_flags & Flags.Excluded_Undetected) == 0)
3772 return (caching_flags & Flags.Excluded) != 0;
3774 caching_flags &= ~Flags.Excluded_Undetected;
3776 if (parent_method == null) {
3777 if (OptAttributes == null)
3780 Attribute[] attrs = OptAttributes.SearchMulti (TypeManager.conditional_attribute_type, ec);
3785 foreach (Attribute a in attrs) {
3786 string condition = a.GetConditionalAttributeValue (
3788 if (RootContext.AllDefines.Contains (condition))
3792 caching_flags |= Flags.Excluded;
3796 IMethodData md = TypeManager.GetMethod (parent_method);
3798 if (AttributeTester.IsConditionalMethodExcluded (parent_method)) {
3799 caching_flags |= Flags.Excluded;
3805 if (md.IsExcluded (ec)) {
3806 caching_flags |= Flags.Excluded;
3815 public abstract class ConstructorInitializer {
3816 ArrayList argument_list;
3817 protected ConstructorInfo parent_constructor;
3818 Parameters parameters;
3821 public ConstructorInitializer (ArrayList argument_list, Parameters parameters,
3824 this.argument_list = argument_list;
3825 this.parameters = parameters;
3829 public ArrayList Arguments {
3831 return argument_list;
3835 public bool Resolve (ConstructorBuilder caller_builder, EmitContext ec)
3837 Expression parent_constructor_group;
3840 ec.CurrentBlock = new ToplevelBlock (Block.Flags.Implicit, parameters, loc);
3842 if (argument_list != null){
3843 foreach (Argument a in argument_list){
3844 if (!a.Resolve (ec, loc))
3848 ec.CurrentBlock = null;
3850 if (this is ConstructorBaseInitializer) {
3851 if (ec.ContainerType.BaseType == null)
3854 t = ec.ContainerType.BaseType;
3855 if (ec.ContainerType.IsValueType) {
3856 Report.Error (522, loc,
3857 "structs cannot call base class constructors");
3861 t = ec.ContainerType;
3863 parent_constructor_group = Expression.MemberLookup (
3864 ec, t, ".ctor", MemberTypes.Constructor,
3865 BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
3868 if (parent_constructor_group == null){
3869 parent_constructor_group = Expression.MemberLookup (
3870 ec, t, ".ctor", MemberTypes.Constructor,
3871 BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly,
3874 if (parent_constructor_group != null)
3876 112, loc, "`{0}.{1}' is inaccessible due to " +
3877 "its protection level", t.FullName, t.Name);
3880 1501, loc, "Can not find a constructor for " +
3881 "this argument list");
3885 parent_constructor = (ConstructorInfo) Invocation.OverloadResolve (
3886 ec, (MethodGroupExpr) parent_constructor_group, argument_list,
3889 if (parent_constructor == null){
3890 Report.Error (1501, loc,
3891 "Can not find a constructor for this argument list");
3895 if (parent_constructor == caller_builder){
3896 Report.Error (516, String.Format ("Constructor `{0}' can not call itself", TypeManager.CSharpSignature (caller_builder)));
3903 public void Emit (EmitContext ec)
3905 if (parent_constructor != null){
3906 ec.Mark (loc, false);
3908 Invocation.EmitCall (ec, true, true, null, parent_constructor, argument_list, loc);
3910 Invocation.EmitCall (ec, true, false, ec.GetThis (loc), parent_constructor, argument_list, loc);
3915 /// Method search for base ctor. (We do not cache it).
3917 Constructor GetOverloadedConstructor (TypeContainer tc)
3919 if (tc.InstanceConstructors == null)
3922 foreach (Constructor c in tc.InstanceConstructors) {
3923 if (Arguments == null) {
3924 if (c.ParameterTypes.Length == 0)
3932 int count = c.ParameterInfo.Count;
3934 c.ParameterInfo.ParameterModifier (count - 1) == Parameter.Modifier.PARAMS) {
3935 for (int i = 0; i < count-1; i++)
3936 if (c.ParameterTypes [i] != ((Argument)Arguments [i]).Type) {
3941 if (c.ParameterTypes.Length != Arguments.Count)
3944 for (int i = 0; i < Arguments.Count; ++i)
3945 if (c.ParameterTypes [i] != ((Argument)Arguments [i]).Type) {
3960 //TODO: implement caching when it will be necessary
3961 public virtual void CheckObsoleteAttribute (TypeContainer tc, Location loc)
3963 Constructor ctor = GetOverloadedConstructor (tc);
3967 ObsoleteAttribute oa = ctor.GetObsoleteAttribute (tc);
3971 AttributeTester.Report_ObsoleteMessage (oa, ctor.GetSignatureForError (), loc);
3975 public class ConstructorBaseInitializer : ConstructorInitializer {
3976 public ConstructorBaseInitializer (ArrayList argument_list, Parameters pars, Location l) :
3977 base (argument_list, pars, l)
3981 public override void CheckObsoleteAttribute(TypeContainer tc, Location loc) {
3982 if (parent_constructor == null)
3985 TypeContainer type_ds = TypeManager.LookupTypeContainer (tc.base_class_type);
3986 if (type_ds == null) {
3987 ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (parent_constructor);
3990 AttributeTester.Report_ObsoleteMessage (oa, TypeManager.CSharpSignature (parent_constructor), loc);
3995 base.CheckObsoleteAttribute (type_ds, loc);
4000 public class ConstructorThisInitializer : ConstructorInitializer {
4001 public ConstructorThisInitializer (ArrayList argument_list, Parameters pars, Location l) :
4002 base (argument_list, pars, l)
4007 public class Constructor : MethodCore, IMethodData {
4008 public ConstructorBuilder ConstructorBuilder;
4009 public ConstructorInitializer Initializer;
4010 ListDictionary declarative_security;
4013 // Modifiers allowed for a constructor.
4015 public const int AllowedModifiers =
4017 Modifiers.PROTECTED |
4018 Modifiers.INTERNAL |
4024 bool has_compliant_args = false;
4026 // The spec claims that static is not permitted, but
4027 // my very own code has static constructors.
4029 public Constructor (TypeContainer ds, string name, int mod, Parameters args,
4030 ConstructorInitializer init, Location l)
4031 : base (ds, null, mod, AllowedModifiers, false, new MemberName (name),
4037 public override string GetSignatureForError()
4039 if (ConstructorBuilder == null)
4040 return GetSignatureForError (Parent);
4042 return TypeManager.CSharpSignature (ConstructorBuilder);
4045 public bool HasCompliantArgs {
4047 return has_compliant_args;
4051 public override AttributeTargets AttributeTargets {
4053 return AttributeTargets.Constructor;
4059 // Returns true if this is a default constructor
4061 public bool IsDefault ()
4063 if ((ModFlags & Modifiers.STATIC) != 0)
4064 return (Parameters.FixedParameters == null ? true : Parameters.Empty) &&
4065 (Parameters.ArrayParameter == null ? true : Parameters.Empty);
4068 return (Parameters.FixedParameters == null ? true : Parameters.Empty) &&
4069 (Parameters.ArrayParameter == null ? true : Parameters.Empty) &&
4070 (Initializer is ConstructorBaseInitializer) &&
4071 (Initializer.Arguments == null);
4074 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
4076 if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
4077 if (declarative_security == null) {
4078 declarative_security = new ListDictionary ();
4080 a.ExtractSecurityPermissionSet (declarative_security);
4084 ConstructorBuilder.SetCustomAttribute (cb);
4087 protected override bool CheckForDuplications ()
4089 ArrayList ar = Parent.InstanceConstructors;
4091 int arLen = ar.Count;
4093 for (int i = 0; i < arLen; i++) {
4094 Constructor m = (Constructor) ar [i];
4095 if (IsDuplicateImplementation (m))
4102 protected override bool CheckBase ()
4104 // Check whether arguments were correct.
4105 if (!DoDefineParameters ())
4108 // TODO: skip the rest for generated ctor
4109 if ((ModFlags & Modifiers.STATIC) != 0)
4112 if (!CheckForDuplications ())
4115 if (Parent.Kind == Kind.Struct) {
4116 if (ParameterTypes.Length == 0) {
4117 Report.Error (568, Location,
4118 "Structs can not contain explicit parameterless " +
4123 if ((ModFlags & Modifiers.PROTECTED) != 0) {
4124 Report.Error (666, Location, "Protected member in struct declaration");
4129 if ((RootContext.WarningLevel >= 4) && ((Parent.ModFlags & Modifiers.SEALED) != 0 && (ModFlags & Modifiers.PROTECTED) != 0)) {
4130 Report.Warning (628, Location, "'{0}': new protected member declared in sealed class", GetSignatureForError (Parent));
4137 // Creates the ConstructorBuilder
4139 public override bool Define ()
4141 MethodAttributes ca = (MethodAttributes.RTSpecialName |
4142 MethodAttributes.SpecialName);
4144 if ((ModFlags & Modifiers.STATIC) != 0) {
4145 ca |= MethodAttributes.Static | MethodAttributes.Private;
4147 ca |= MethodAttributes.HideBySig;
4149 if ((ModFlags & Modifiers.PUBLIC) != 0)
4150 ca |= MethodAttributes.Public;
4151 else if ((ModFlags & Modifiers.PROTECTED) != 0){
4152 if ((ModFlags & Modifiers.INTERNAL) != 0)
4153 ca |= MethodAttributes.FamORAssem;
4155 ca |= MethodAttributes.Family;
4156 } else if ((ModFlags & Modifiers.INTERNAL) != 0)
4157 ca |= MethodAttributes.Assembly;
4158 else if (IsDefault ())
4159 ca |= MethodAttributes.Public;
4161 ca |= MethodAttributes.Private;
4164 // Check if arguments were correct.
4168 ConstructorBuilder = Parent.TypeBuilder.DefineConstructor (
4169 ca, CallingConventions,
4172 if ((ModFlags & Modifiers.UNSAFE) != 0)
4173 ConstructorBuilder.InitLocals = false;
4175 TypeManager.AddMethod (ConstructorBuilder, this);
4178 // HACK because System.Reflection.Emit is lame
4180 TypeManager.RegisterMethod (ConstructorBuilder, ParameterInfo, ParameterTypes);
4188 public override void Emit ()
4190 EmitContext ec = CreateEmitContext (null, null);
4193 // extern methods have no bodies
4195 if ((ModFlags & Modifiers.EXTERN) != 0) {
4196 if ((block != null) && ((ModFlags & Modifiers.EXTERN) != 0)) {
4198 179, Location, "External constructor `" +
4199 TypeManager.CSharpSignature (ConstructorBuilder) +
4200 "' can not have a body");
4203 } else if (block == null) {
4205 501, Location, "Constructor `" +
4206 TypeManager.CSharpSignature (ConstructorBuilder) +
4207 "' must declare a body since it is not marked extern");
4211 if ((ModFlags & Modifiers.STATIC) == 0){
4212 if (Parent.Kind == Kind.Class && Initializer == null)
4213 Initializer = new ConstructorBaseInitializer (
4214 null, Parameters.EmptyReadOnlyParameters, Location);
4218 // Spec mandates that Initializers will not have
4222 if (Initializer != null && !Initializer.Resolve (ConstructorBuilder, ec))
4224 ec.IsStatic = false;
4227 Parameters.LabelParameters (ec, ConstructorBuilder, Location);
4229 SourceMethod source = SourceMethod.Create (
4230 Parent, ConstructorBuilder, block);
4233 // Classes can have base initializers and instance field initializers.
4235 if (Parent.Kind == Kind.Class){
4236 if ((ModFlags & Modifiers.STATIC) == 0){
4239 // If we use a "this (...)" constructor initializer, then
4240 // do not emit field initializers, they are initialized in the other constructor
4242 if (!(Initializer != null && Initializer is ConstructorThisInitializer))
4243 Parent.EmitFieldInitializers (ec);
4246 if (Initializer != null) {
4247 if (GetObsoleteAttribute (Parent) == null && Parent.GetObsoleteAttribute (Parent.Parent) == null)
4248 Initializer.CheckObsoleteAttribute (Parent, Location);
4250 ec.TestObsoleteMethodUsage = false;
4251 Initializer.Emit (ec);
4254 if ((ModFlags & Modifiers.STATIC) != 0)
4255 Parent.EmitFieldInitializers (ec);
4257 if (OptAttributes != null)
4258 OptAttributes.Emit (ec, this);
4260 // If this is a non-static `struct' constructor and doesn't have any
4261 // initializer, it must initialize all of the struct's fields.
4262 if ((Parent.Kind == Kind.Struct) &&
4263 ((ModFlags & Modifiers.STATIC) == 0) && (Initializer == null))
4264 Block.AddThisVariable (Parent, Location);
4266 ec.EmitTopBlock (block, ParameterInfo, Location);
4269 source.CloseMethod ();
4273 if (declarative_security != null) {
4274 foreach (DictionaryEntry de in declarative_security) {
4275 ConstructorBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
4282 // Is never override
4283 protected override MethodInfo FindOutParentMethod (TypeContainer container, ref Type parent_ret_type)
4288 protected override bool VerifyClsCompliance (DeclSpace ds)
4290 if (!base.VerifyClsCompliance (ds) || !IsExposedFromAssembly (ds)) {
4294 if (parameter_types.Length > 0) {
4295 ArrayList al = (ArrayList)ds.MemberCache.Members [".ctor"];
4297 ds.MemberCache.VerifyClsParameterConflict (al, this, ConstructorBuilder);
4299 if (ds.TypeBuilder.IsSubclassOf (TypeManager.attribute_type)) {
4300 foreach (Type param in parameter_types) {
4301 if (param.IsArray) {
4307 has_compliant_args = true;
4311 #region IMethodData Members
4313 public System.Reflection.CallingConventions CallingConventions {
4315 CallingConventions cc = Parameters.GetCallingConvention ();
4317 if (Parent.Kind == Kind.Class)
4318 if ((ModFlags & Modifiers.STATIC) == 0)
4319 cc |= CallingConventions.HasThis;
4321 // FIXME: How is `ExplicitThis' used in C#?
4327 public new Location Location {
4329 return base.Location;
4333 public MemberName MethodName {
4339 public Type ReturnType {
4345 public EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig)
4347 ILGenerator ig_ = ConstructorBuilder.GetILGenerator ();
4348 return new EmitContext (Parent, Location, ig_, null, ModFlags, true);
4351 public ObsoleteAttribute GetObsoleteAttribute ()
4356 public bool IsExcluded(EmitContext ec)
4365 /// Interface for MethodData class. Holds links to parent members to avoid member duplication.
4367 public interface IMethodData
4369 CallingConventions CallingConventions { get; }
4370 Location Location { get; }
4371 MemberName MethodName { get; }
4372 Type[] ParameterTypes { get; }
4373 Type ReturnType { get; }
4375 Attributes OptAttributes { get; }
4376 ToplevelBlock Block { get; }
4378 EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig);
4379 ObsoleteAttribute GetObsoleteAttribute ();
4380 string GetSignatureForError (TypeContainer tc);
4381 bool IsExcluded (EmitContext ec);
4382 bool IsClsCompliaceRequired (DeclSpace ds);
4386 // Encapsulates most of the Method's state
4388 public class MethodData {
4390 readonly IMethodData method;
4393 // The return type of this method
4395 public readonly InternalParameters ParameterInfo;
4398 // Are we implementing an interface ?
4400 public bool IsImplementing = false;
4405 protected MemberBase member;
4406 protected int modifiers;
4407 protected MethodAttributes flags;
4409 MethodBuilder builder = null;
4410 public MethodBuilder MethodBuilder {
4416 public MethodData (MemberBase member, InternalParameters parameters,
4417 int modifiers, MethodAttributes flags, IMethodData method)
4419 this.member = member;
4420 this.ParameterInfo = parameters;
4421 this.modifiers = modifiers;
4424 this.method = method;
4427 public bool Define (TypeContainer container)
4429 MethodInfo implementing = null;
4431 string method_name = method.MethodName.GetFullName ();
4432 string name = method.MethodName.Name;
4434 Type[] ParameterTypes = method.ParameterTypes;
4436 if (container.Pending != null){
4437 if (member is Indexer)
4438 implementing = container.Pending.IsInterfaceIndexer (
4439 member.InterfaceType, method.ReturnType, ParameterTypes);
4441 implementing = container.Pending.IsInterfaceMethod (
4442 member.InterfaceType, name, method.ReturnType, ParameterTypes);
4444 if (member.InterfaceType != null && implementing == null){
4445 Report.Error (539, method.Location, "'{0}' in explicit interface declaration is not an interface", method_name);
4451 // For implicit implementations, make sure we are public, for
4452 // explicit implementations, make sure we are private.
4454 if (implementing != null){
4456 // Setting null inside this block will trigger a more
4457 // verbose error reporting for missing interface implementations
4459 // The "candidate" function has been flagged already
4460 // but it wont get cleared
4462 if (member.IsExplicitImpl){
4463 if ((modifiers & (Modifiers.PUBLIC | Modifiers.ABSTRACT | Modifiers.VIRTUAL)) != 0){
4464 Modifiers.Error_InvalidModifier (method.Location, "public, virtual or abstract");
4465 implementing = null;
4467 } else if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public){
4468 if (TypeManager.IsInterfaceType (implementing.DeclaringType)){
4470 // If this is an interface method implementation,
4471 // check for public accessibility
4473 implementing = null;
4474 } else if ((flags & MethodAttributes.MemberAccessMask) == MethodAttributes.Private){
4475 // We may never be private.
4476 implementing = null;
4477 } else if ((modifiers & Modifiers.OVERRIDE) == 0){
4479 // We may be protected if we're overriding something.
4481 implementing = null;
4486 // Static is not allowed
4488 if ((modifiers & Modifiers.STATIC) != 0){
4489 implementing = null;
4490 Modifiers.Error_InvalidModifier (method.Location, "static");
4495 // If implementing is still valid, set flags
4497 if (implementing != null){
4499 // When implementing interface methods, set NewSlot
4500 // unless, we are overwriting a method.
4502 if (implementing.DeclaringType.IsInterface){
4503 if ((modifiers & Modifiers.OVERRIDE) == 0)
4504 flags |= MethodAttributes.NewSlot;
4507 MethodAttributes.Virtual |
4508 MethodAttributes.HideBySig;
4510 // Set Final unless we're virtual, abstract or already overriding a method.
4511 if ((modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE)) == 0)
4512 flags |= MethodAttributes.Final;
4514 IsImplementing = true;
4517 EmitContext ec = method.CreateEmitContext (container, null);
4519 DefineMethodBuilder (ec, container, method_name, ParameterTypes);
4521 if (builder == null)
4524 if ((modifiers & Modifiers.UNSAFE) != 0)
4525 builder.InitLocals = false;
4527 if (IsImplementing){
4529 // clear the pending implemntation flag
4531 if (member is Indexer) {
4532 container.Pending.ImplementIndexer (
4533 member.InterfaceType, builder, method.ReturnType,
4534 ParameterTypes, member.IsExplicitImpl);
4536 container.Pending.ImplementMethod (
4537 member.InterfaceType, name, method.ReturnType,
4538 ParameterTypes, member.IsExplicitImpl);
4540 if (member.IsExplicitImpl)
4541 container.TypeBuilder.DefineMethodOverride (
4542 builder, implementing);
4546 TypeManager.RegisterMethod (builder, ParameterInfo, ParameterTypes);
4547 TypeManager.AddMethod (builder, method);
4554 /// Create the MethodBuilder for the method
4556 void DefineMethodBuilder (EmitContext ec, TypeContainer container, string method_name, Type[] ParameterTypes)
4558 const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
4560 if ((modifiers & extern_static) == extern_static) {
4562 if (method.OptAttributes != null) {
4563 Attribute dllimport_attribute = method.OptAttributes.Search (TypeManager.dllimport_type, ec);
4564 if (dllimport_attribute != null) {
4565 flags |= MethodAttributes.PinvokeImpl;
4566 builder = dllimport_attribute.DefinePInvokeMethod (
4567 ec, container.TypeBuilder, method_name, flags,
4568 method.ReturnType, ParameterTypes);
4574 // for extern static method must be specified either DllImport attribute or MethodImplAttribute.
4575 // We are more strict than Microsoft and report CS0626 like error
4576 if (method.OptAttributes == null ||
4577 !method.OptAttributes.Contains (TypeManager.methodimpl_attr_type, ec)) {
4578 Report.Error (626, method.Location, "Method, operator, or accessor '{0}' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation", method.GetSignatureForError (container));
4583 builder = container.TypeBuilder.DefineMethod (
4584 method_name, flags, method.CallingConventions,
4585 method.ReturnType, ParameterTypes);
4591 public void Emit (TypeContainer container, Attributable kind)
4594 if ((flags & MethodAttributes.PinvokeImpl) == 0)
4595 ec = method.CreateEmitContext (container, builder.GetILGenerator ());
4597 ec = method.CreateEmitContext (container, null);
4599 if (method.GetObsoleteAttribute () != null || container.GetObsoleteAttribute (container.Parent) != null)
4600 ec.TestObsoleteMethodUsage = false;
4602 Location loc = method.Location;
4603 Attributes OptAttributes = method.OptAttributes;
4605 if (OptAttributes != null)
4606 OptAttributes.Emit (ec, kind);
4608 if (member is MethodCore)
4609 ((MethodCore) member).Parameters.LabelParameters (ec, MethodBuilder, loc);
4611 SymbolWriter sw = CodeGen.SymbolWriter;
4612 ToplevelBlock block = method.Block;
4615 // abstract or extern methods have no bodies
4617 if ((modifiers & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0){
4622 // abstract or extern methods have no bodies.
4624 if ((modifiers & Modifiers.ABSTRACT) != 0)
4626 500, method.Location, "Abstract method `" +
4627 TypeManager.CSharpSignature (builder) +
4628 "' can not have a body");
4630 if ((modifiers & Modifiers.EXTERN) != 0)
4632 179, method.Location, "External method `" +
4633 TypeManager.CSharpSignature (builder) +
4634 "' can not have a body");
4640 // Methods must have a body unless they're extern or abstract
4642 if (block == null) {
4644 501, method.Location, "Method `" +
4645 TypeManager.CSharpSignature (builder) +
4646 "' must declare a body since it is not marked " +
4647 "abstract or extern");
4651 SourceMethod source = SourceMethod.Create (
4652 container, MethodBuilder, method.Block);
4655 // Handle destructors specially
4657 // FIXME: This code generates buggy code
4659 if (member is Destructor)
4660 EmitDestructor (ec, block);
4662 ec.EmitTopBlock (block, ParameterInfo, loc);
4665 source.CloseMethod ();
4668 void EmitDestructor (EmitContext ec, ToplevelBlock block)
4670 ILGenerator ig = ec.ig;
4672 Label finish = ig.DefineLabel ();
4674 block.SetDestructor ();
4676 ig.BeginExceptionBlock ();
4677 ec.ReturnLabel = finish;
4678 ec.HasReturnLabel = true;
4679 ec.EmitTopBlock (block, null, method.Location);
4681 // ig.MarkLabel (finish);
4682 ig.BeginFinallyBlock ();
4684 if (ec.ContainerType.BaseType != null) {
4685 Expression member_lookup = Expression.MemberLookup (
4686 ec, ec.ContainerType.BaseType, null, ec.ContainerType.BaseType,
4687 "Finalize", MemberTypes.Method, Expression.AllBindingFlags, method.Location);
4689 if (member_lookup != null){
4690 MethodGroupExpr parent_destructor = ((MethodGroupExpr) member_lookup);
4692 ig.Emit (OpCodes.Ldarg_0);
4693 ig.Emit (OpCodes.Call, (MethodInfo) parent_destructor.Methods [0]);
4697 ig.EndExceptionBlock ();
4698 //ig.MarkLabel (ec.ReturnLabel);
4699 ig.Emit (OpCodes.Ret);
4703 public class Destructor : Method {
4705 public Destructor (TypeContainer ds, Expression return_type, int mod,
4706 string name, Parameters parameters, Attributes attrs,
4708 : base (ds, return_type, mod, false, new MemberName (name),
4709 parameters, attrs, l)
4712 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
4714 if (a.Type == TypeManager.conditional_attribute_type) {
4715 Report.Error (577, Location, "Conditional not valid on '{0}' because it is a destructor, operator, or explicit interface implementation", GetSignatureForError ());
4719 base.ApplyAttributeBuilder (a, cb);
4723 abstract public class MemberBase : MemberCore {
4724 public Expression Type;
4726 public MethodAttributes flags;
4728 protected readonly int explicit_mod_flags;
4731 // The "short" name of this property / indexer / event. This is the
4732 // name without the explicit interface.
4734 public string ShortName;
4737 // The type of this property / indexer / event
4739 public Type MemberType;
4742 // If true, this is an explicit interface implementation
4744 public bool IsExplicitImpl = false;
4747 // The name of the interface we are explicitly implementing
4749 public MemberName ExplicitInterfaceName = null;
4752 // Whether this is an interface member.
4754 public bool IsInterface;
4757 // If true, the interface type we are explicitly implementing
4759 public Type InterfaceType = null;
4762 // The constructor is only exposed to our children
4764 protected MemberBase (TypeContainer parent, Expression type, int mod,
4765 int allowed_mod, int def_mod, MemberName name,
4766 Attributes attrs, Location loc)
4767 : base (parent, name, attrs, loc)
4769 explicit_mod_flags = mod;
4771 ModFlags = Modifiers.Check (allowed_mod, mod, def_mod, loc);
4773 // Check for explicit interface implementation
4774 if (MemberName.Left != null) {
4775 ExplicitInterfaceName = MemberName.Left;
4776 ShortName = MemberName.Name;
4777 IsExplicitImpl = true;
4782 protected virtual bool CheckBase ()
4784 if ((ModFlags & Modifiers.PROTECTED) != 0 && Parent.Kind == Kind.Struct) {
4785 Report.Error (666, Location, "Protected member in struct declaration");
4789 if ((RootContext.WarningLevel >= 4) &&
4790 ((Parent.ModFlags & Modifiers.SEALED) != 0) &&
4791 ((ModFlags & Modifiers.PROTECTED) != 0) &&
4792 ((ModFlags & Modifiers.OVERRIDE) == 0) && (Name != "Finalize")) {
4793 Report.Warning (628, Location, "'{0}': new protected member declared in sealed class", GetSignatureForError (Parent));
4798 protected virtual bool CheckParameters (DeclSpace ds, Type [] parameters)
4802 foreach (Type partype in parameters){
4803 if (partype == TypeManager.void_type) {
4805 1547, Location, "Keyword 'void' cannot " +
4806 "be used in this context");
4810 if (partype.IsPointer){
4813 if (!TypeManager.VerifyUnManaged (TypeManager.GetElementType (partype), Location))
4817 if (ds.AsAccessible (partype, ModFlags))
4820 if (this is Indexer)
4821 Report.Error (55, Location,
4822 "Inconsistent accessibility: parameter type `" +
4823 TypeManager.CSharpName (partype) + "' is less " +
4824 "accessible than indexer `" + Name + "'");
4825 else if ((this is Method) && ((Method) this).IsOperator)
4826 Report.Error (57, Location,
4827 "Inconsistent accessibility: parameter type `" +
4828 TypeManager.CSharpName (partype) + "' is less " +
4829 "accessible than operator `" + Name + "'");
4831 Report.Error (51, Location,
4832 "Inconsistent accessibility: parameter type `" +
4833 TypeManager.CSharpName (partype) + "' is less " +
4834 "accessible than method `" + Name + "'");
4841 protected virtual bool DoDefine ()
4843 EmitContext ec = Parent.EmitContext;
4845 throw new InternalErrorException ("MemberBase.DoDefine called too early");
4848 throw new InternalErrorException ();
4851 ModFlags = Modifiers.PUBLIC |
4852 Modifiers.ABSTRACT |
4853 Modifiers.VIRTUAL | (ModFlags & Modifiers.UNSAFE) | (ModFlags & Modifiers.NEW);
4855 flags = MethodAttributes.Public |
4856 MethodAttributes.Abstract |
4857 MethodAttributes.HideBySig |
4858 MethodAttributes.NewSlot |
4859 MethodAttributes.Virtual;
4861 if (!Parent.MethodModifiersValid (ModFlags, Name, Location))
4864 flags = Modifiers.MethodAttr (ModFlags);
4867 // Lookup Type, verify validity
4868 bool old_unsafe = ec.InUnsafe;
4869 ec.InUnsafe = InUnsafe;
4870 Type = Type.ResolveAsTypeTerminal (ec, false);
4871 ec.InUnsafe = old_unsafe;
4876 MemberType = Type.Type;
4878 if ((Parent.ModFlags & Modifiers.SEALED) != 0){
4879 if ((ModFlags & (Modifiers.VIRTUAL|Modifiers.ABSTRACT)) != 0){
4880 Report.Error (549, Location, "Virtual method can not be contained in sealed class");
4885 // verify accessibility
4886 if (!Parent.AsAccessible (MemberType, ModFlags)) {
4887 if (this is Property)
4888 Report.Error (53, Location,
4889 "Inconsistent accessibility: property type `" +
4890 TypeManager.CSharpName (MemberType) + "' is less " +
4891 "accessible than property `" + Name + "'");
4892 else if (this is Indexer)
4893 Report.Error (54, Location,
4894 "Inconsistent accessibility: indexer return type `" +
4895 TypeManager.CSharpName (MemberType) + "' is less " +
4896 "accessible than indexer `" + Name + "'");
4897 else if (this is Method) {
4898 if (((Method) this).IsOperator)
4899 Report.Error (56, Location,
4900 "Inconsistent accessibility: return type `" +
4901 TypeManager.CSharpName (MemberType) + "' is less " +
4902 "accessible than operator `" + Name + "'");
4904 Report.Error (50, Location,
4905 "Inconsistent accessibility: return type `" +
4906 TypeManager.CSharpName (MemberType) + "' is less " +
4907 "accessible than method `" + Name + "'");
4909 Report.Error (52, Location,
4910 "Inconsistent accessibility: field type `" +
4911 TypeManager.CSharpName (MemberType) + "' is less " +
4912 "accessible than field `" + Name + "'");
4916 if (MemberType.IsPointer && !UnsafeOK (Parent))
4919 if (IsExplicitImpl) {
4920 Expression expr = ExplicitInterfaceName.GetTypeExpression (Location);
4921 TypeExpr texpr = expr.ResolveAsTypeTerminal (ec, false);
4925 InterfaceType = texpr.ResolveType (ec);
4927 if (InterfaceType.IsClass) {
4928 Report.Error (538, Location, "'{0}' in explicit interface declaration is not an interface", ExplicitInterfaceName);
4933 // Compute the full name that we need to export.
4934 if (InterfaceType.FullName != ExplicitInterfaceName) {
4935 ExplicitInterfaceName = InterfaceType.FullName;
4936 UpdateMemberName ();
4940 if (!Parent.VerifyImplements (InterfaceType, ShortName, Name, Location))
4943 Modifiers.Check (Modifiers.AllowedExplicitImplFlags, explicit_mod_flags, 0, Location);
4950 /// The name of the member can be changed during definition (see IndexerName attribute)
4952 protected virtual void UpdateMemberName ()
4954 MemberName.Name = ShortName;
4957 public override string GetSignatureForError (TypeContainer tc)
4959 return String.Concat (tc.Name, '.', base.GetSignatureForError (tc));
4962 protected bool IsTypePermitted ()
4964 if (MemberType == TypeManager.arg_iterator_type || MemberType == TypeManager.typed_reference_type) {
4965 Report.Error (610, Location, "Field or property cannot be of type '{0}'", TypeManager.CSharpName (MemberType));
4971 protected override bool VerifyClsCompliance(DeclSpace ds)
4973 if (base.VerifyClsCompliance (ds)) {
4977 if (IsInterface && HasClsCompliantAttribute && ds.IsClsCompliaceRequired (ds)) {
4978 Report.Error (3010, Location, "'{0}': CLS-compliant interfaces must have only CLS-compliant members", GetSignatureForError ());
4983 protected override void VerifyObsoleteAttribute()
4985 CheckUsageOfObsoleteAttribute (MemberType);
4990 // Fields and Events both generate FieldBuilders, we use this to share
4991 // their common bits. This is also used to flag usage of the field
4993 abstract public class FieldBase : MemberBase {
4994 public FieldBuilder FieldBuilder;
4995 public Status status;
4998 public enum Status : byte {
5003 static string[] attribute_targets = new string [] { "field" };
5006 /// Symbol with same name in parent class/struct
5008 public MemberInfo conflict_symbol;
5011 // The constructor is only exposed to our children
5013 protected FieldBase (TypeContainer parent, Expression type, int mod,
5014 int allowed_mod, MemberName name, object init,
5015 Attributes attrs, Location loc)
5016 : base (parent, type, mod, allowed_mod, Modifiers.PRIVATE,
5022 public override AttributeTargets AttributeTargets {
5024 return AttributeTargets.Field;
5028 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
5030 if (a.Type == TypeManager.marshal_as_attr_type) {
5031 UnmanagedMarshal marshal = a.GetMarshal (this);
5032 if (marshal != null) {
5033 FieldBuilder.SetMarshal (marshal);
5038 if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
5039 a.Error_InvalidSecurityParent ();
5043 FieldBuilder.SetCustomAttribute (cb);
5047 // Whether this field has an initializer.
5049 public bool HasInitializer {
5051 return init != null;
5055 protected readonly Object init;
5058 Expression init_expr;
5059 bool init_expr_initialized = false;
5062 // Resolves and returns the field initializer.
5064 public Expression GetInitializerExpression (EmitContext ec)
5066 if (init_expr_initialized)
5070 if (init is Expression)
5071 e = (Expression) init;
5073 e = new ArrayCreation (Type, "", (ArrayList)init, Location);
5075 ec.IsFieldInitializer = true;
5076 e = e.DoResolve (ec);
5077 ec.IsFieldInitializer = false;
5080 init_expr_initialized = true;
5085 protected override bool CheckBase ()
5087 if (!base.CheckBase ())
5094 conflict_symbol = Parent.FindMemberWithSameName (Name, false);
5095 if (conflict_symbol == null) {
5096 if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) {
5097 Report.Warning (109, Location, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError (Parent));
5102 if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0) {
5103 Report.SymbolRelatedToPreviousError (conflict_symbol);
5104 Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent));
5110 protected override bool DoDefine ()
5112 if (!base.DoDefine ())
5115 if (MemberType == TypeManager.void_type) {
5116 Report.Error (1547, Location,
5117 "Keyword 'void' cannot be used in this context");
5123 public override string GetSignatureForError ()
5125 if (FieldBuilder == null) {
5126 return base.GetSignatureForError (Parent);
5128 return TypeManager.GetFullNameSignature (FieldBuilder);
5131 public override string[] ValidAttributeTargets {
5133 return attribute_targets;
5137 protected override bool VerifyClsCompliance (DeclSpace ds)
5139 if (!base.VerifyClsCompliance (ds))
5142 if (FieldBuilder == null) {
5146 if (!AttributeTester.IsClsCompliant (FieldBuilder.FieldType)) {
5147 Report.Error (3003, Location, "Type of '{0}' is not CLS-compliant", GetSignatureForError ());
5153 public void SetAssigned ()
5155 status |= Status.ASSIGNED;
5159 public abstract class FieldMember: FieldBase
5161 bool has_field_offset = false;
5163 protected FieldMember (TypeContainer parent, Expression type, int mod,
5164 int allowed_mod, MemberName name, object init, Attributes attrs, Location loc)
5165 : base (parent, type, mod, allowed_mod, name, init, attrs, loc)
5169 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
5171 if (a.Type == TypeManager.field_offset_attribute_type)
5173 has_field_offset = true;
5175 if (!Parent.HasExplicitLayout) {
5176 Report.Error (636, Location, "The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit)");
5180 if ((ModFlags & Modifiers.STATIC) != 0 || this is Const) {
5181 Report.Error (637, Location, "The FieldOffset attribute is not allowed on static or const fields");
5185 base.ApplyAttributeBuilder (a, cb);
5189 public override bool Define()
5191 EmitContext ec = Parent.EmitContext;
5193 throw new InternalErrorException ("FieldMember.Define called too early");
5195 bool old_unsafe = ec.InUnsafe;
5196 ec.InUnsafe = InUnsafe;
5197 TypeExpr texpr = Type.ResolveAsTypeTerminal (ec, false);
5201 MemberType = texpr.ResolveType (ec);
5202 ec.InUnsafe = old_unsafe;
5207 if (!Parent.AsAccessible (MemberType, ModFlags)) {
5208 Report.Error (52, Location,
5209 "Inconsistent accessibility: field type `" +
5210 TypeManager.CSharpName (MemberType) + "' is less " +
5211 "accessible than field `" + Name + "'");
5215 if (!IsTypePermitted ())
5218 if (MemberType.IsPointer && !UnsafeOK (Parent))
5224 public override void Emit ()
5226 if (Parent.HasExplicitLayout && !has_field_offset && (ModFlags & Modifiers.STATIC) == 0) {
5227 Report.Error (625, Location, "'{0}': Instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute.", GetSignatureForError ());
5235 // The Field class is used to represents class/struct fields during parsing.
5237 public class Field : FieldMember {
5239 // Modifiers allowed in a class declaration
5241 const int AllowedModifiers =
5244 Modifiers.PROTECTED |
5245 Modifiers.INTERNAL |
5248 Modifiers.VOLATILE |
5252 public Field (TypeContainer parent, Expression type, int mod, string name,
5253 Object expr_or_array_init, Attributes attrs, Location loc)
5254 : base (parent, type, mod, AllowedModifiers, new MemberName (name),
5255 expr_or_array_init, attrs, loc)
5259 public override bool Define ()
5261 if (!base.Define ())
5264 if (RootContext.WarningLevel > 1){
5265 Type ptype = Parent.TypeBuilder.BaseType;
5267 // ptype is only null for System.Object while compiling corlib.
5269 TypeContainer.FindMembers (
5270 ptype, MemberTypes.Method,
5271 BindingFlags.Public |
5272 BindingFlags.Static | BindingFlags.Instance,
5273 System.Type.FilterName, Name);
5277 if ((ModFlags & Modifiers.VOLATILE) != 0){
5278 if (!MemberType.IsClass){
5279 Type vt = MemberType;
5281 if (TypeManager.IsEnumType (vt))
5282 vt = TypeManager.EnumToUnderlying (MemberType);
5284 if (!((vt == TypeManager.bool_type) ||
5285 (vt == TypeManager.sbyte_type) ||
5286 (vt == TypeManager.byte_type) ||
5287 (vt == TypeManager.short_type) ||
5288 (vt == TypeManager.ushort_type) ||
5289 (vt == TypeManager.int32_type) ||
5290 (vt == TypeManager.uint32_type) ||
5291 (vt == TypeManager.char_type) ||
5292 (vt == TypeManager.float_type) ||
5293 (!vt.IsValueType))){
5295 677, Location, Parent.MakeName (Name) +
5296 " A volatile field can not be of type `" +
5297 TypeManager.CSharpName (vt) + "'");
5302 if ((ModFlags & Modifiers.READONLY) != 0){
5305 "A field can not be both volatile and readonly");
5310 FieldAttributes fa = Modifiers.FieldAttr (ModFlags);
5312 if (Parent.Kind == Kind.Struct &&
5313 ((fa & FieldAttributes.Static) == 0) &&
5314 MemberType == Parent.TypeBuilder &&
5315 !TypeManager.IsBuiltinType (MemberType)){
5316 Report.Error (523, Location, "Struct member `" + Parent.Name + "." + Name +
5317 "' causes a cycle in the structure layout");
5322 FieldBuilder = Parent.TypeBuilder.DefineField (
5323 Name, MemberType, Modifiers.FieldAttr (ModFlags));
5325 TypeManager.RegisterFieldBase (FieldBuilder, this);
5327 catch (ArgumentException) {
5328 Report.Warning (-24, Location, "The Microsoft runtime is unable to use [void|void*] as a field type, try using the Mono runtime.");
5335 public override void Emit ()
5337 if (OptAttributes != null) {
5338 EmitContext ec = new EmitContext (
5339 Parent, Location, null, FieldBuilder.FieldType,
5341 OptAttributes.Emit (ec, this);
5349 // `set' and `get' accessors are represented with an Accessor.
5351 public class Accessor {
5353 // Null if the accessor is empty, or a Block if not
5355 public ToplevelBlock Block;
5356 public Attributes Attributes;
5357 public Location Location;
5359 public Accessor (ToplevelBlock b, Attributes attrs, Location loc)
5368 // Ooouh Martin, templates are missing here.
5369 // When it will be possible move here a lot of child code and template method type.
5370 public abstract class AbstractPropertyEventMethod: MemberCore, IMethodData {
5371 protected MethodData method_data;
5372 protected ToplevelBlock block;
5373 protected ListDictionary declarative_security;
5375 // The accessor are created event if they are not wanted.
5376 // But we need them because their names are reserved.
5377 // Field says whether accessor will be emited or not
5378 public readonly bool IsDummy;
5380 protected readonly string prefix;
5382 ReturnParameter return_attributes;
5384 public AbstractPropertyEventMethod (MemberBase member, string prefix)
5385 : base (null, SetupName (prefix, member), null, member.Location)
5387 this.prefix = prefix;
5391 public AbstractPropertyEventMethod (MemberBase member, Accessor accessor,
5393 : base (null, SetupName (prefix, member),
5394 accessor.Attributes, accessor.Location)
5396 this.prefix = prefix;
5397 this.block = accessor.Block;
5400 static MemberName SetupName (string prefix, MemberBase member)
5402 MemberName name = member.MemberName.Clone ();
5403 name.Name = prefix + member.ShortName;
5407 public void UpdateName (MemberBase member)
5409 MemberName.Name = prefix + member.ShortName;
5412 #region IMethodData Members
5414 public ToplevelBlock Block {
5424 public CallingConventions CallingConventions {
5426 return CallingConventions.Standard;
5430 public bool IsExcluded (EmitContext ec)
5435 public MemberName MethodName {
5441 public abstract ObsoleteAttribute GetObsoleteAttribute ();
5442 public abstract Type[] ParameterTypes { get; }
5443 public abstract Type ReturnType { get; }
5444 public abstract EmitContext CreateEmitContext(TypeContainer tc, ILGenerator ig);
5448 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
5450 if (a.Type == TypeManager.cls_compliant_attribute_type || a.Type == TypeManager.obsolete_attribute_type ||
5451 a.Type == TypeManager.conditional_attribute_type) {
5452 Report.Error (1667, a.Location, "'{0}' is not valid on property or event accessors. It is valid on '{1}' declarations only", TypeManager.CSharpName (a.Type), a.GetValidTargets ());
5456 if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
5457 if (declarative_security == null)
5458 declarative_security = new ListDictionary ();
5459 a.ExtractSecurityPermissionSet (declarative_security);
5463 if (a.Target == AttributeTargets.Method) {
5464 method_data.MethodBuilder.SetCustomAttribute (cb);
5468 if (a.Target == AttributeTargets.ReturnValue) {
5469 if (return_attributes == null)
5470 return_attributes = new ReturnParameter (method_data.MethodBuilder, Location);
5472 return_attributes.ApplyAttributeBuilder (a, cb);
5476 ApplyToExtraTarget (a, cb);
5479 virtual protected void ApplyToExtraTarget (Attribute a, CustomAttributeBuilder cb)
5481 System.Diagnostics.Debug.Fail ("You forgot to define special attribute target handling");
5484 public override bool Define()
5489 public virtual void Emit (TypeContainer container)
5491 method_data.Emit (container, this);
5493 if (declarative_security != null) {
5494 foreach (DictionaryEntry de in declarative_security) {
5495 method_data.MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
5502 public override bool IsClsCompliaceRequired(DeclSpace ds)
5507 public bool IsDuplicateImplementation (MethodCore method)
5509 if (Name != method.Name)
5512 Type[] param_types = method.ParameterTypes;
5514 if (param_types.Length != ParameterTypes.Length)
5517 for (int i = 0; i < param_types.Length; i++)
5518 if (param_types [i] != ParameterTypes [i])
5521 Report.SymbolRelatedToPreviousError (method);
5522 Report.Error (111, Location, TypeContainer.Error111, method.Parent.GetSignatureForError (), Name);
5526 public new Location Location {
5528 return base.Location;
5532 protected override void VerifyObsoleteAttribute()
5539 // Properties and Indexers both generate PropertyBuilders, we use this to share
5540 // their common bits.
5542 abstract public class PropertyBase : MethodCore {
5544 public class GetMethod: PropertyMethod
5546 static string[] attribute_targets = new string [] { "method", "return" };
5548 public GetMethod (MethodCore method):
5549 base (method, "get_")
5553 public GetMethod (MethodCore method, Accessor accessor):
5554 base (method, accessor, "get_")
5558 public override MethodBuilder Define(TypeContainer container)
5560 method_data = new MethodData (method, method.ParameterInfo, method.ModFlags, method.flags, this);
5562 if (!method_data.Define (container))
5565 return method_data.MethodBuilder;
5568 public override string GetSignatureForError (TypeContainer tc)
5570 return String.Concat (base.GetSignatureForError (tc), ".get");
5573 public override Type ReturnType {
5575 return method.MemberType;
5579 public override string[] ValidAttributeTargets {
5581 return attribute_targets;
5586 public class SetMethod: PropertyMethod {
5588 static string[] attribute_targets = new string [] { "method", "param", "return" };
5589 ImplicitParameter param_attr;
5591 public SetMethod (MethodCore method):
5592 base (method, "set_")
5596 public SetMethod (MethodCore method, Accessor accessor):
5597 base (method, accessor, "set_")
5601 protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
5603 if (a.Target == AttributeTargets.Parameter) {
5604 if (param_attr == null)
5605 param_attr = new ImplicitParameter (method_data.MethodBuilder);
5607 param_attr.ApplyAttributeBuilder (a, cb);
5611 base.ApplyAttributeBuilder (a, cb);
5614 protected virtual InternalParameters GetParameterInfo (EmitContext ec)
5616 Parameter [] parms = new Parameter [1];
5617 parms [0] = new Parameter (method.Type, "value", Parameter.Modifier.NONE, null);
5618 Parameters parameters = new Parameters (parms, null, method.Location);
5619 Type [] types = parameters.GetParameterInfo (ec);
5620 return new InternalParameters (types, parameters);
5623 public override MethodBuilder Define(TypeContainer container)
5625 if (container.EmitContext == null)
5626 throw new InternalErrorException ("SetMethod.Define called too early");
5627 method_data = new MethodData (method, GetParameterInfo (container.EmitContext), method.ModFlags, method.flags, this);
5629 if (!method_data.Define (container))
5632 return method_data.MethodBuilder;
5635 public override string GetSignatureForError (TypeContainer tc)
5637 return String.Concat (base.GetSignatureForError (tc), ".set");
5640 public override Type[] ParameterTypes {
5642 return new Type[] { method.MemberType };
5646 public override Type ReturnType {
5648 return TypeManager.void_type;
5652 public override string[] ValidAttributeTargets {
5654 return attribute_targets;
5659 static string[] attribute_targets = new string [] { "property" };
5661 public abstract class PropertyMethod: AbstractPropertyEventMethod
5663 protected readonly MethodCore method;
5665 public PropertyMethod (MethodCore method, string prefix)
5666 : base (method, prefix)
5668 this.method = method;
5671 public PropertyMethod (MethodCore method, Accessor accessor,
5673 : base (method, accessor, prefix)
5675 this.method = method;
5678 public override AttributeTargets AttributeTargets {
5680 return AttributeTargets.Method;
5684 public override bool IsClsCompliaceRequired(DeclSpace ds)
5686 return method.IsClsCompliaceRequired (ds);
5689 public InternalParameters ParameterInfo
5692 return method_data.ParameterInfo;
5696 public abstract MethodBuilder Define (TypeContainer container);
5698 public override Type[] ParameterTypes {
5700 return TypeManager.NoTypes;
5704 public override EmitContext CreateEmitContext (TypeContainer tc,
5707 return new EmitContext (
5708 tc, method.Parent, method.Location, ig, ReturnType,
5709 method.ModFlags, false);
5712 public override ObsoleteAttribute GetObsoleteAttribute ()
5714 return method.GetObsoleteAttribute (method.Parent);
5717 public override string GetSignatureForError (TypeContainer tc)
5719 return String.Concat (tc.Name, '.', method.Name);
5724 public PropertyMethod Get, Set;
5725 public PropertyBuilder PropertyBuilder;
5726 public MethodBuilder GetBuilder, SetBuilder;
5728 protected EmitContext ec;
5730 public PropertyBase (TypeContainer ds, Expression type, int mod_flags,
5731 int allowed_mod, bool is_iface, MemberName name,
5732 Parameters parameters, Attributes attrs,
5734 : base (ds, type, mod_flags, allowed_mod, is_iface, name,
5735 attrs, parameters, loc)
5739 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
5741 if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
5742 a.Error_InvalidSecurityParent ();
5746 PropertyBuilder.SetCustomAttribute (cb);
5749 public override AttributeTargets AttributeTargets {
5751 return AttributeTargets.Property;
5755 public override bool Define ()
5760 if (!IsTypePermitted ())
5766 protected override bool DoDefine ()
5768 if (!base.DoDefine ())
5771 if (MemberType.IsAbstract && MemberType.IsSealed) {
5772 Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
5776 ec = new EmitContext (Parent, Location, null, MemberType, ModFlags);
5780 public override string GetSignatureForError()
5782 if (PropertyBuilder == null)
5783 return GetSignatureForError (Parent);
5785 return TypeManager.CSharpSignature (PropertyBuilder, false);
5789 protected override bool CheckForDuplications ()
5791 ArrayList ar = Parent.Indexers;
5793 int arLen = ar.Count;
5795 for (int i = 0; i < arLen; i++) {
5796 Indexer m = (Indexer) ar [i];
5797 if (IsDuplicateImplementation (m))
5802 ar = Parent.Properties;
5804 int arLen = ar.Count;
5806 for (int i = 0; i < arLen; i++) {
5807 Property m = (Property) ar [i];
5808 if (IsDuplicateImplementation (m))
5816 // TODO: rename to Resolve......
5817 protected override MethodInfo FindOutParentMethod (TypeContainer container, ref Type parent_ret_type)
5819 PropertyInfo parent_property = container.ParentContainer.MemberCache.FindMemberToOverride (
5820 container.TypeBuilder, Name, ParameterTypes, true) as PropertyInfo;
5822 if (parent_property == null)
5825 parent_ret_type = parent_property.PropertyType;
5826 MethodInfo get_accessor = parent_property.GetGetMethod (true);
5827 MethodInfo set_accessor = parent_property.GetSetMethod (true);
5829 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
5830 if (Get != null && !Get.IsDummy && get_accessor == null) {
5831 Report.SymbolRelatedToPreviousError (parent_property);
5832 Report.Error (545, Location, "'{0}': cannot override because '{1}' does not have an overridable get accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (parent_property));
5835 if (Set != null && !Set.IsDummy && set_accessor == null) {
5836 Report.SymbolRelatedToPreviousError (parent_property);
5837 Report.Error (546, Location, "'{0}': cannot override because '{1}' does not have an overridable set accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (parent_property));
5841 return get_accessor != null ? get_accessor : set_accessor;
5844 public override void Emit ()
5847 // The PropertyBuilder can be null for explicit implementations, in that
5848 // case, we do not actually emit the ".property", so there is nowhere to
5849 // put the attribute
5851 if (PropertyBuilder != null && OptAttributes != null)
5852 OptAttributes.Emit (ec, this);
5864 /// Tests whether accessors are not in collision with some method (CS0111)
5866 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
5868 return Get.IsDuplicateImplementation (mc) || Set.IsDuplicateImplementation (mc);
5871 protected override void UpdateMemberName ()
5873 base.UpdateMemberName ();
5875 Get.UpdateName (this);
5876 Set.UpdateName (this);
5880 public override string[] ValidAttributeTargets {
5882 return attribute_targets;
5887 public class Property : PropertyBase, IIteratorContainer {
5888 const int AllowedModifiers =
5891 Modifiers.PROTECTED |
5892 Modifiers.INTERNAL |
5896 Modifiers.OVERRIDE |
5897 Modifiers.ABSTRACT |
5900 Modifiers.METHOD_YIELDS |
5903 const int AllowedInterfaceModifiers =
5906 public Property (TypeContainer ds, Expression type, int mod, bool is_iface,
5907 MemberName name, Attributes attrs, Accessor get_block,
5908 Accessor set_block, Location loc)
5909 : base (ds, type, mod,
5910 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
5911 is_iface, name, Parameters.EmptyReadOnlyParameters, attrs,
5914 if (get_block == null)
5915 Get = new GetMethod (this);
5917 Get = new GetMethod (this, get_block);
5919 if (set_block == null)
5920 Set = new SetMethod (this);
5922 Set = new SetMethod (this, set_block);
5925 public override bool Define ()
5927 if (!base.Define ())
5933 flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
5937 GetBuilder = Get.Define (Parent);
5938 if (GetBuilder == null)
5942 // Setup iterator if we are one
5944 if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
5945 Iterator iterator = new Iterator (
5946 Parent, "get", MemberType,
5947 TypeManager.NoTypes, Get.ParameterInfo,
5948 ModFlags, Get.Block, Location);
5950 if (!iterator.DefineIterator ())
5952 Get.Block = iterator.Block;
5957 SetBuilder = Set.Define (Parent);
5958 if (SetBuilder == null)
5961 SetBuilder.DefineParameter (1, ParameterAttributes.None, "value");
5964 // FIXME - PropertyAttributes.HasDefault ?
5966 PropertyAttributes prop_attr = PropertyAttributes.None;
5968 prop_attr |= PropertyAttributes.RTSpecialName |
5969 PropertyAttributes.SpecialName;
5971 if (!IsExplicitImpl){
5972 PropertyBuilder = Parent.TypeBuilder.DefineProperty (
5973 Name, prop_attr, MemberType, null);
5976 PropertyBuilder.SetGetMethod (GetBuilder);
5979 PropertyBuilder.SetSetMethod (SetBuilder);
5981 TypeManager.RegisterProperty (PropertyBuilder, GetBuilder, SetBuilder);
5986 public void SetYields ()
5988 ModFlags |= Modifiers.METHOD_YIELDS;
5993 /// Gigantic workaround for lameness in SRE follows :
5994 /// This class derives from EventInfo and attempts to basically
5995 /// wrap around the EventBuilder so that FindMembers can quickly
5996 /// return this in it search for members
5998 public class MyEventBuilder : EventInfo {
6001 // We use this to "point" to our Builder which is
6002 // not really a MemberInfo
6004 EventBuilder MyBuilder;
6007 // We "catch" and wrap these methods
6009 MethodInfo raise, remove, add;
6011 EventAttributes attributes;
6012 Type declaring_type, reflected_type, event_type;
6017 public MyEventBuilder (Event ev, TypeBuilder type_builder, string name, EventAttributes event_attr, Type event_type)
6019 MyBuilder = type_builder.DefineEvent (name, event_attr, event_type);
6021 // And now store the values in our own fields.
6023 declaring_type = type_builder;
6025 reflected_type = type_builder;
6027 attributes = event_attr;
6030 this.event_type = event_type;
6034 // Methods that you have to override. Note that you only need
6035 // to "implement" the variants that take the argument (those are
6036 // the "abstract" methods, the others (GetAddMethod()) are
6039 public override MethodInfo GetAddMethod (bool nonPublic)
6044 public override MethodInfo GetRemoveMethod (bool nonPublic)
6049 public override MethodInfo GetRaiseMethod (bool nonPublic)
6055 // These methods make "MyEventInfo" look like a Builder
6057 public void SetRaiseMethod (MethodBuilder raiseMethod)
6059 raise = raiseMethod;
6060 MyBuilder.SetRaiseMethod (raiseMethod);
6063 public void SetRemoveOnMethod (MethodBuilder removeMethod)
6065 remove = removeMethod;
6066 MyBuilder.SetRemoveOnMethod (removeMethod);
6069 public void SetAddOnMethod (MethodBuilder addMethod)
6072 MyBuilder.SetAddOnMethod (addMethod);
6075 public void SetCustomAttribute (CustomAttributeBuilder cb)
6077 MyBuilder.SetCustomAttribute (cb);
6080 public override object [] GetCustomAttributes (bool inherit)
6082 // FIXME : There's nothing which can be seemingly done here because
6083 // we have no way of getting at the custom attribute objects of the
6088 public override object [] GetCustomAttributes (Type t, bool inherit)
6090 // FIXME : Same here !
6094 public override bool IsDefined (Type t, bool b)
6099 public override EventAttributes Attributes {
6105 public override string Name {
6111 public override Type DeclaringType {
6113 return declaring_type;
6117 public override Type ReflectedType {
6119 return reflected_type;
6123 public Type EventType {
6129 public void SetUsed ()
6131 if (my_event != null)
6132 my_event.status = (FieldBase.Status.ASSIGNED | FieldBase.Status.USED);
6137 /// For case when event is declared like property (with add and remove accessors).
6139 public class EventProperty: Event {
6141 static string[] attribute_targets = new string [] { "event", "property" };
6143 public EventProperty (TypeContainer parent, Expression type, int mod_flags,
6144 bool is_iface, MemberName name, Object init,
6145 Attributes attrs, Accessor add, Accessor remove,
6147 : base (parent, type, mod_flags, is_iface, name, init, attrs, loc)
6149 Add = new AddDelegateMethod (this, add);
6150 Remove = new RemoveDelegateMethod (this, remove);
6153 public override string[] ValidAttributeTargets {
6155 return attribute_targets;
6161 /// Event is declared like field.
6163 public class EventField: Event {
6165 static string[] attribute_targets = new string [] { "event", "field", "method" };
6167 public EventField (TypeContainer parent, Expression type, int mod_flags,
6168 bool is_iface, MemberName name, Object init,
6169 Attributes attrs, Location loc)
6170 : base (parent, type, mod_flags, is_iface, name, init, attrs, loc)
6172 Add = new AddDelegateMethod (this);
6173 Remove = new RemoveDelegateMethod (this);
6176 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
6178 if (a.Target == AttributeTargets.Field) {
6179 FieldBuilder.SetCustomAttribute (cb);
6183 if (a.Target == AttributeTargets.Method) {
6184 AddBuilder.SetCustomAttribute (cb);
6185 RemoveBuilder.SetCustomAttribute (cb);
6189 base.ApplyAttributeBuilder (a, cb);
6192 public override string[] ValidAttributeTargets {
6194 return attribute_targets;
6199 public abstract class Event : FieldBase {
6201 protected sealed class AddDelegateMethod: DelegateMethod
6204 public AddDelegateMethod (Event method):
6205 base (method, "add_")
6209 public AddDelegateMethod (Event method, Accessor accessor):
6210 base (method, accessor, "add_")
6214 protected override MethodInfo DelegateMethodInfo {
6216 return TypeManager.delegate_combine_delegate_delegate;
6222 protected sealed class RemoveDelegateMethod: DelegateMethod
6224 public RemoveDelegateMethod (Event method):
6225 base (method, "remove_")
6229 public RemoveDelegateMethod (Event method, Accessor accessor):
6230 base (method, accessor, "remove_")
6234 protected override MethodInfo DelegateMethodInfo {
6236 return TypeManager.delegate_remove_delegate_delegate;
6242 public abstract class DelegateMethod: AbstractPropertyEventMethod
6244 protected readonly Event method;
6245 ImplicitParameter param_attr;
6247 static string[] attribute_targets = new string [] { "method", "param", "return" };
6249 public DelegateMethod (Event method, string prefix)
6250 : base (method, prefix)
6252 this.method = method;
6255 public DelegateMethod (Event method, Accessor accessor, string prefix)
6256 : base (method, accessor, prefix)
6258 this.method = method;
6261 protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
6263 if (a.Target == AttributeTargets.Parameter) {
6264 if (param_attr == null)
6265 param_attr = new ImplicitParameter (method_data.MethodBuilder);
6267 param_attr.ApplyAttributeBuilder (a, cb);
6271 base.ApplyAttributeBuilder (a, cb);
6274 public override AttributeTargets AttributeTargets {
6276 return AttributeTargets.Method;
6280 public override bool IsClsCompliaceRequired(DeclSpace ds)
6282 return method.IsClsCompliaceRequired (ds);
6285 public MethodBuilder Define (TypeContainer container, InternalParameters ip)
6287 method_data = new MethodData (method, ip, method.ModFlags,
6288 method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this);
6290 if (!method_data.Define (container))
6293 MethodBuilder mb = method_data.MethodBuilder;
6294 mb.DefineParameter (1, ParameterAttributes.None, "value");
6299 public override void Emit (TypeContainer tc)
6301 if (block != null) {
6306 ILGenerator ig = method_data.MethodBuilder.GetILGenerator ();
6307 EmitContext ec = CreateEmitContext (tc, ig);
6308 FieldInfo field_info = (FieldInfo)method.FieldBuilder;
6310 method_data.MethodBuilder.SetImplementationFlags (MethodImplAttributes.Synchronized);
6311 if ((method.ModFlags & Modifiers.STATIC) != 0) {
6312 ig.Emit (OpCodes.Ldsfld, field_info);
6313 ig.Emit (OpCodes.Ldarg_0);
6314 ig.Emit (OpCodes.Call, DelegateMethodInfo);
6315 ig.Emit (OpCodes.Castclass, method.MemberType);
6316 ig.Emit (OpCodes.Stsfld, field_info);
6318 ig.Emit (OpCodes.Ldarg_0);
6319 ig.Emit (OpCodes.Ldarg_0);
6320 ig.Emit (OpCodes.Ldfld, field_info);
6321 ig.Emit (OpCodes.Ldarg_1);
6322 ig.Emit (OpCodes.Call, DelegateMethodInfo);
6323 ig.Emit (OpCodes.Castclass, method.MemberType);
6324 ig.Emit (OpCodes.Stfld, field_info);
6326 ig.Emit (OpCodes.Ret);
6329 protected abstract MethodInfo DelegateMethodInfo { get; }
6331 public override Type[] ParameterTypes {
6333 return new Type[] { method.MemberType };
6337 public override Type ReturnType {
6339 return TypeManager.void_type;
6343 public override EmitContext CreateEmitContext (TypeContainer tc,
6346 return new EmitContext (
6347 tc, method.Parent, Location, ig, ReturnType,
6348 method.ModFlags, false);
6351 public override string GetSignatureForError (TypeContainer tc)
6353 return String.Concat (tc.Name, '.', method.Name);
6356 public override ObsoleteAttribute GetObsoleteAttribute ()
6358 return method.GetObsoleteAttribute (method.Parent);
6361 public override string[] ValidAttributeTargets {
6363 return attribute_targets;
6369 const int AllowedModifiers =
6372 Modifiers.PROTECTED |
6373 Modifiers.INTERNAL |
6378 Modifiers.OVERRIDE |
6382 const int AllowedInterfaceModifiers =
6385 public DelegateMethod Add, Remove;
6386 public MyEventBuilder EventBuilder;
6387 public MethodBuilder AddBuilder, RemoveBuilder;
6389 public Event (TypeContainer parent, Expression type, int mod_flags,
6390 bool is_iface, MemberName name, Object init, Attributes attrs,
6392 : base (parent, type, mod_flags,
6393 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
6394 name, init, attrs, loc)
6396 IsInterface = is_iface;
6399 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
6401 if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
6402 a.Error_InvalidSecurityParent ();
6406 EventBuilder.SetCustomAttribute (cb);
6409 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
6411 return Add.IsDuplicateImplementation (mc) || Remove.IsDuplicateImplementation (mc);
6414 public override AttributeTargets AttributeTargets {
6416 return AttributeTargets.Event;
6420 public override bool Define ()
6422 EventAttributes e_attr;
6423 e_attr = EventAttributes.None;
6428 if (init != null && ((ModFlags & Modifiers.ABSTRACT) != 0)){
6429 Report.Error (74, Location, "'" + Parent.Name + "." + Name +
6430 "': abstract event can not have an initializer");
6434 if (!MemberType.IsSubclassOf (TypeManager.delegate_type)) {
6435 Report.Error (66, Location, "'" + Parent.Name + "." + Name +
6436 "' : event must be of a delegate type");
6440 EmitContext ec = Parent.EmitContext;
6442 throw new InternalErrorException ("Event.Define called too early?");
6443 bool old_unsafe = ec.InUnsafe;
6444 ec.InUnsafe = InUnsafe;
6446 Parameter [] parms = new Parameter [1];
6447 parms [0] = new Parameter (Type, "value", Parameter.Modifier.NONE, null);
6448 Parameters parameters = new Parameters (parms, null, Location);
6449 Type [] types = parameters.GetParameterInfo (ec);
6450 InternalParameters ip = new InternalParameters (types, parameters);
6452 ec.InUnsafe = old_unsafe;
6458 // Now define the accessors
6461 AddBuilder = Add.Define (Parent, ip);
6462 if (AddBuilder == null)
6465 RemoveBuilder = Remove.Define (Parent, ip);
6466 if (RemoveBuilder == null)
6469 if (!IsExplicitImpl){
6470 EventBuilder = new MyEventBuilder (this,
6471 Parent.TypeBuilder, Name, e_attr, MemberType);
6473 if (Add.Block == null && Remove.Block == null &&
6475 FieldBuilder = Parent.TypeBuilder.DefineField (
6477 FieldAttributes.Private | ((ModFlags & Modifiers.STATIC) != 0 ? FieldAttributes.Static : 0));
6478 TypeManager.RegisterPrivateFieldOfEvent (
6479 (EventInfo) EventBuilder, FieldBuilder);
6480 TypeManager.RegisterFieldBase (FieldBuilder, this);
6483 EventBuilder.SetAddOnMethod (AddBuilder);
6484 EventBuilder.SetRemoveOnMethod (RemoveBuilder);
6486 TypeManager.RegisterEvent (EventBuilder, AddBuilder, RemoveBuilder);
6492 protected override bool CheckBase ()
6494 if (!base.CheckBase ())
6497 if (conflict_symbol != null && (ModFlags & Modifiers.NEW) == 0) {
6498 if (!(conflict_symbol is EventInfo)) {
6499 Report.SymbolRelatedToPreviousError (conflict_symbol);
6500 Report.Error (72, Location, "Event '{0}' can override only event", GetSignatureForError (Parent));
6508 public override void Emit ()
6510 if (OptAttributes != null) {
6511 EmitContext ec = new EmitContext (
6512 Parent, Location, null, MemberType, ModFlags);
6513 OptAttributes.Emit (ec, this);
6518 Remove.Emit (Parent);
6524 public override string GetSignatureForError ()
6526 if (EventBuilder == null)
6527 return base.GetSignatureForError (Parent);
6529 return TypeManager.GetFullNameSignature (EventBuilder);
6534 public class Indexer : PropertyBase {
6536 class GetIndexerMethod: GetMethod
6538 public GetIndexerMethod (MethodCore method):
6543 public GetIndexerMethod (MethodCore method, Accessor accessor):
6544 base (method, accessor)
6548 public override Type[] ParameterTypes {
6550 return method.ParameterTypes;
6555 class SetIndexerMethod: SetMethod
6557 readonly Parameters parameters;
6559 public SetIndexerMethod (MethodCore method):
6564 public SetIndexerMethod (MethodCore method, Parameters parameters, Accessor accessor):
6565 base (method, accessor)
6567 this.parameters = parameters;
6570 public override Type[] ParameterTypes {
6572 int top = method.ParameterTypes.Length;
6573 Type [] set_pars = new Type [top + 1];
6574 method.ParameterTypes.CopyTo (set_pars, 0);
6575 set_pars [top] = method.MemberType;
6580 protected override InternalParameters GetParameterInfo (EmitContext ec)
6582 Parameter [] fixed_parms = parameters.FixedParameters;
6584 if (fixed_parms == null){
6585 throw new Exception ("We currently do not support only array arguments in an indexer at: " + method.Location);
6586 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
6587 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
6589 // Here is the problem: the `value' parameter has
6590 // to come *after* the array parameter in the declaration
6592 // X (object [] x, Type value)
6595 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
6596 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
6600 Parameter [] tmp = new Parameter [fixed_parms.Length + 1];
6602 fixed_parms.CopyTo (tmp, 0);
6603 tmp [fixed_parms.Length] = new Parameter (
6604 method.Type, "value", Parameter.Modifier.NONE, null);
6606 Parameters set_formal_params = new Parameters (tmp, null, method.Location);
6607 Type [] types = set_formal_params.GetParameterInfo (ec);
6609 return new InternalParameters (types, set_formal_params);
6614 const int AllowedModifiers =
6617 Modifiers.PROTECTED |
6618 Modifiers.INTERNAL |
6622 Modifiers.OVERRIDE |
6627 const int AllowedInterfaceModifiers =
6631 public Indexer (TypeContainer ds, Expression type, MemberName name, int mod,
6632 bool is_iface, Parameters parameters, Attributes attrs,
6633 Accessor get_block, Accessor set_block, Location loc)
6634 : base (ds, type, mod,
6635 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
6636 is_iface, name, parameters, attrs, loc)
6638 if (get_block == null)
6639 Get = new GetIndexerMethod (this);
6641 Get = new GetIndexerMethod (this, get_block);
6643 if (set_block == null)
6644 Set = new SetIndexerMethod (this);
6646 Set = new SetIndexerMethod (this, parameters, set_block);
6649 public override bool Define ()
6651 PropertyAttributes prop_attr =
6652 PropertyAttributes.RTSpecialName |
6653 PropertyAttributes.SpecialName;
6655 if (!base.Define ())
6658 if (OptAttributes != null) {
6659 Attribute indexer_attr = OptAttributes.GetIndexerNameAttribute (ec);
6660 if (indexer_attr != null) {
6661 ShortName = indexer_attr.GetIndexerAttributeValue (ec);
6663 if (IsExplicitImpl) {
6664 Report.Error (415, indexer_attr.Location, "The 'IndexerName' attribute is valid only on an indexer that is not an explicit interface member declaration");
6668 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
6669 Report.Error (609, indexer_attr.Location, "Cannot set the 'IndexerName' attribute on an indexer marked override");
6673 if (!Tokenizer.IsValidIdentifier (ShortName)) {
6674 Report.Error (633, indexer_attr.Location, "The argument to the 'IndexerName' attribute must be a valid identifier");
6678 UpdateMemberName ();
6682 if (InterfaceType != null) {
6683 string parent_IndexerName = TypeManager.IndexerPropertyName (InterfaceType);
6684 if (parent_IndexerName != Name)
6685 ShortName = parent_IndexerName;
6686 UpdateMemberName ();
6689 if (!Parent.AddToMemberContainer (this, true) ||
6690 !Parent.AddToMemberContainer (Get, true) || !Parent.AddToMemberContainer (Set, true))
6696 flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
6698 GetBuilder = Get.Define (Parent);
6699 if (GetBuilder == null)
6704 SetBuilder = Set.Define (Parent);
6705 if (SetBuilder == null)
6710 // Now name the parameters
6712 Parameter [] p = Parameters.FixedParameters;
6714 if ((p [0].ModFlags & Parameter.Modifier.ISBYREF) != 0) {
6715 Report.Error (631, Location, "ref and out are not valid in this context");
6721 for (i = 0; i < p.Length; ++i) {
6723 GetBuilder.DefineParameter (
6724 i + 1, p [i].Attributes, p [i].Name);
6727 SetBuilder.DefineParameter (
6728 i + 1, p [i].Attributes, p [i].Name);
6732 SetBuilder.DefineParameter (
6733 i + 1, ParameterAttributes.None, "value");
6735 if (i != ParameterTypes.Length) {
6736 Parameter array_param = Parameters.ArrayParameter;
6738 SetBuilder.DefineParameter (
6739 i + 1, array_param.Attributes, array_param.Name);
6744 // Define the PropertyBuilder if one of the following conditions are met:
6745 // a) we're not implementing an interface indexer.
6746 // b) the indexer has a different IndexerName and this is no
6747 // explicit interface implementation.
6749 if (!IsExplicitImpl) {
6750 PropertyBuilder = Parent.TypeBuilder.DefineProperty (
6751 ShortName, prop_attr, MemberType, ParameterTypes);
6754 PropertyBuilder.SetGetMethod (GetBuilder);
6757 PropertyBuilder.SetSetMethod (SetBuilder);
6759 TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder,
6766 public override string GetSignatureForError ()
6768 if (PropertyBuilder == null)
6769 return GetSignatureForError (Parent);
6771 return TypeManager.CSharpSignature (PropertyBuilder, true);
6774 public override string GetSignatureForError(TypeContainer tc)
6776 return String.Concat (tc.Name, ".this[", Parameters.FixedParameters [0].TypeName.ToString (), ']');
6780 public class Operator : MethodCore, IIteratorContainer {
6782 const int AllowedModifiers =
6788 public enum OpType : byte {
6798 // Unary and Binary operators
6821 // Implicit and Explicit
6826 public readonly OpType OperatorType;
6827 public MethodBuilder OperatorMethodBuilder;
6829 public Method OperatorMethod;
6831 static string[] attribute_targets = new string [] { "method", "return" };
6833 public Operator (TypeContainer parent, OpType type, Expression ret_type,
6834 int mod_flags, Parameters parameters,
6835 ToplevelBlock block, Attributes attrs, Location loc)
6836 : base (parent, ret_type, mod_flags, AllowedModifiers, false,
6837 new MemberName ("op_" + type), attrs, parameters, loc)
6839 OperatorType = type;
6843 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
6845 OperatorMethod.ApplyAttributeBuilder (a, cb);
6848 public override AttributeTargets AttributeTargets {
6850 return AttributeTargets.Method;
6854 protected override bool CheckForDuplications()
6856 ArrayList ar = Parent.Operators;
6858 int arLen = ar.Count;
6860 for (int i = 0; i < arLen; i++) {
6861 Operator o = (Operator) ar [i];
6862 if (IsDuplicateImplementation (o))
6867 ar = Parent.Methods;
6869 int arLen = ar.Count;
6871 for (int i = 0; i < arLen; i++) {
6872 Method m = (Method) ar [i];
6873 if (IsDuplicateImplementation (m))
6881 public override bool Define ()
6884 const int RequiredModifiers = Modifiers.PUBLIC | Modifiers.STATIC;
6885 if ((ModFlags & RequiredModifiers) != RequiredModifiers){
6886 Report.Error (558, Location, "User defined operators '{0}' must be declared static and public", GetSignatureForError (Parent));
6893 OperatorMethod = new Method (
6894 Parent, Type, ModFlags, false, MemberName,
6895 Parameters, OptAttributes, Location);
6897 OperatorMethod.Block = Block;
6898 OperatorMethod.IsOperator = true;
6899 OperatorMethod.flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
6900 OperatorMethod.Define ();
6902 if (OperatorMethod.MethodBuilder == null)
6905 OperatorMethodBuilder = OperatorMethod.MethodBuilder;
6907 parameter_types = OperatorMethod.ParameterTypes;
6908 Type declaring_type = OperatorMethodBuilder.DeclaringType;
6909 Type return_type = OperatorMethod.ReturnType;
6910 Type first_arg_type = parameter_types [0];
6915 // Rules for conversion operators
6917 if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
6918 if (first_arg_type == return_type && first_arg_type == declaring_type){
6921 "User-defined conversion cannot take an object of the " +
6922 "enclosing type and convert to an object of the enclosing" +
6927 if (first_arg_type != declaring_type && return_type != declaring_type){
6930 "User-defined conversion must convert to or from the " +
6935 if (first_arg_type == TypeManager.object_type ||
6936 return_type == TypeManager.object_type){
6939 "User-defined conversion cannot convert to or from " +
6944 if (first_arg_type.IsInterface || return_type.IsInterface){
6947 "User-defined conversion cannot convert to or from an " +
6952 if (first_arg_type.IsSubclassOf (return_type)
6953 || return_type.IsSubclassOf (first_arg_type)){
6954 if (declaring_type.IsSubclassOf (return_type)) {
6955 Report.Error (553, Location, "'{0}' : user defined conversion to/from base class", GetSignatureForError ());
6958 Report.Error (554, Location, "'{0}' : user defined conversion to/from derived class", GetSignatureForError ());
6961 } else if (OperatorType == OpType.LeftShift || OperatorType == OpType.RightShift) {
6962 if (first_arg_type != declaring_type || parameter_types [1] != TypeManager.int32_type) {
6963 Report.Error (564, Location, "Overloaded shift operator must have the type of the first operand be the containing type, and the type of the second operand must be int");
6966 } else if (Parameters.FixedParameters.Length == 1) {
6967 // Checks for Unary operators
6969 if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
6970 if (return_type != declaring_type && !return_type.IsSubclassOf (declaring_type)) {
6971 Report.Error (448, Location,
6972 "The return type for ++ or -- operator must be the containing type or derived from the containing type");
6975 if (first_arg_type != declaring_type) {
6977 559, Location, "The parameter type for ++ or -- operator must be the containing type");
6982 if (first_arg_type != declaring_type){
6985 "The parameter of a unary operator must be the " +
6990 if (OperatorType == OpType.True || OperatorType == OpType.False) {
6991 if (return_type != TypeManager.bool_type){
6994 "The return type of operator True or False " +
7001 // Checks for Binary operators
7003 if (first_arg_type != declaring_type &&
7004 parameter_types [1] != declaring_type){
7007 "One of the parameters of a binary operator must " +
7008 "be the containing type");
7016 public override void Emit ()
7019 // abstract or extern methods have no bodies
7021 if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
7024 OperatorMethod.Emit ();
7028 // Operator cannot be override
7029 protected override MethodInfo FindOutParentMethod (TypeContainer container, ref Type parent_ret_type)
7034 public static string GetName (OpType ot)
7037 case OpType.LogicalNot:
7039 case OpType.OnesComplement:
7041 case OpType.Increment:
7043 case OpType.Decrement:
7049 case OpType.Addition:
7051 case OpType.Subtraction:
7053 case OpType.UnaryPlus:
7055 case OpType.UnaryNegation:
7057 case OpType.Multiply:
7059 case OpType.Division:
7061 case OpType.Modulus:
7063 case OpType.BitwiseAnd:
7065 case OpType.BitwiseOr:
7067 case OpType.ExclusiveOr:
7069 case OpType.LeftShift:
7071 case OpType.RightShift:
7073 case OpType.Equality:
7075 case OpType.Inequality:
7077 case OpType.GreaterThan:
7079 case OpType.LessThan:
7081 case OpType.GreaterThanOrEqual:
7083 case OpType.LessThanOrEqual:
7085 case OpType.Implicit:
7087 case OpType.Explicit:
7093 public override string GetSignatureForError (TypeContainer tc)
7095 StringBuilder sb = new StringBuilder ();
7096 sb.AppendFormat ("{0}.operator {1} {2}({3}", tc.Name, GetName (OperatorType), Type.Type == null ? Type.ToString () : TypeManager.CSharpName (Type.Type),
7097 Parameters.FixedParameters [0].GetSignatureForError ());
7099 if (Parameters.FixedParameters.Length > 1) {
7101 sb.Append (Parameters.FixedParameters [1].GetSignatureForError ());
7104 return sb.ToString ();
7107 public override string GetSignatureForError ()
7112 public override string ToString ()
7114 if (OperatorMethod == null)
7117 Type return_type = OperatorMethod.ReturnType;
7118 Type [] param_types = OperatorMethod.ParameterTypes;
7120 if (Parameters.FixedParameters.Length == 1)
7121 return String.Format (
7122 "{0} operator {1}({2})",
7123 TypeManager.CSharpName (return_type),
7124 GetName (OperatorType),
7127 return String.Format (
7128 "{0} operator {1}({2}, {3})",
7129 TypeManager.CSharpName (return_type),
7130 GetName (OperatorType),
7131 param_types [0], param_types [1]);
7134 public override string[] ValidAttributeTargets {
7136 return attribute_targets;
7140 public void SetYields ()
7142 ModFlags |= Modifiers.METHOD_YIELDS;
7147 // This is used to compare method signatures
7149 struct MethodSignature {
7151 public Type RetType;
7152 public Type [] Parameters;
7155 /// This delegate is used to extract methods which have the
7156 /// same signature as the argument
7158 public static MemberFilter method_signature_filter = new MemberFilter (MemberSignatureCompare);
7160 public MethodSignature (string name, Type ret_type, Type [] parameters)
7165 if (parameters == null)
7166 Parameters = TypeManager.NoTypes;
7168 Parameters = parameters;
7171 public override string ToString ()
7174 if (Parameters.Length != 0){
7175 System.Text.StringBuilder sb = new System.Text.StringBuilder ();
7176 for (int i = 0; i < Parameters.Length; i++){
7177 sb.Append (Parameters [i]);
7178 if (i+1 < Parameters.Length)
7181 pars = sb.ToString ();
7184 return String.Format ("{0} {1} ({2})", RetType, Name, pars);
7187 public override int GetHashCode ()
7189 return Name.GetHashCode ();
7192 public override bool Equals (Object o)
7194 MethodSignature other = (MethodSignature) o;
7196 if (other.Name != Name)
7199 if (other.RetType != RetType)
7202 if (Parameters == null){
7203 if (other.Parameters == null)
7208 if (other.Parameters == null)
7211 int c = Parameters.Length;
7212 if (other.Parameters.Length != c)
7215 for (int i = 0; i < c; i++)
7216 if (other.Parameters [i] != Parameters [i])
7222 static bool MemberSignatureCompare (MemberInfo m, object filter_criteria)
7224 MethodSignature sig = (MethodSignature) filter_criteria;
7226 if (m.Name != sig.Name)
7230 MethodInfo mi = m as MethodInfo;
7231 PropertyInfo pi = m as PropertyInfo;
7234 ReturnType = mi.ReturnType;
7235 else if (pi != null)
7236 ReturnType = pi.PropertyType;
7241 // we use sig.RetType == null to mean `do not check the
7242 // method return value.
7244 if (sig.RetType != null)
7245 if (ReturnType != sig.RetType)
7250 args = TypeManager.GetArgumentTypes (mi);
7252 args = TypeManager.GetArgumentTypes (pi);
7253 Type [] sigp = sig.Parameters;
7255 if (args.Length != sigp.Length)
7258 for (int i = args.Length; i > 0; ){
7260 if (args [i] != sigp [i])