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 TypeExpr parent_type;
449 ArrayList type_bases;
451 bool members_defined;
452 bool members_defined_ok;
454 // The interfaces we implement.
455 protected Type [] ifaces;
456 protected Type ptype;
458 // The parent member cache and our member cache
459 MemberCache parent_cache;
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,
1124 // Defines the type in the appropriate ModuleBuilder or TypeBuilder.
1126 public override TypeBuilder DefineType ()
1128 if (TypeBuilder != null)
1135 Report.Error (146, Location, "Class definition is circular: `{0}'", Name);
1142 ec = new EmitContext (this, Mono.CSharp.Location.Null, null, null, ModFlags);
1144 TypeExpr[] iface_exprs = GetClassBases (out parent_type, out error);
1148 if (parent_type == null) {
1149 if (Kind == Kind.Class){
1150 if (RootContext.StdLib)
1151 parent_type = TypeManager.system_object_expr;
1152 else if (Name != "System.Object")
1153 parent_type = TypeManager.system_object_expr;
1154 } else if (Kind == Kind.Struct) {
1156 // If we are compiling our runtime,
1157 // and we are defining ValueType, then our
1158 // parent is `System.Object'.
1160 if (!RootContext.StdLib && Name == "System.ValueType")
1161 parent_type = TypeManager.system_object_expr;
1163 parent_type = TypeManager.system_valuetype_expr;
1167 if ((Kind == Kind.Struct) && TypeManager.value_type == null)
1168 throw new Exception ();
1170 TypeAttributes type_attributes = TypeAttr;
1172 if (parent_type != null) {
1173 ptype = parent_type.ResolveType (ec);
1174 if (ptype == null) {
1182 if (TypeManager.NamespaceClash (Name, Location)) {
1187 ModuleBuilder builder = CodeGen.Module.Builder;
1188 TypeBuilder = builder.DefineType (
1189 Name, type_attributes, ptype, null);
1192 TypeBuilder builder = Parent.DefineType ();
1193 if (builder == null)
1196 TypeBuilder = builder.DefineNestedType (
1197 Basename, type_attributes, ptype, null);
1200 catch (ArgumentException) {
1201 Report.RuntimeMissingSupport (Location, "static classes");
1206 // Structs with no fields need to have at least one byte.
1207 // The right thing would be to set the PackingSize in a DefineType
1208 // but there are no functions that allow interfaces *and* the size to
1212 if ((Kind == Kind.Struct) && !have_nonstatic_fields){
1213 TypeBuilder.DefineField ("$PRIVATE$", TypeManager.byte_type,
1214 FieldAttributes.Private);
1217 // add interfaces that were not added at type creation
1218 if (iface_exprs != null) {
1219 ifaces = TypeManager.ExpandInterfaces (ec, iface_exprs);
1220 if (ifaces == null) {
1225 foreach (Type itype in ifaces)
1226 TypeBuilder.AddInterfaceImplementation (itype);
1228 TypeManager.RegisterBuilder (TypeBuilder, ifaces);
1232 // Finish the setup for the EmitContext
1234 ec.ContainerType = TypeBuilder;
1236 TypeManager.AddUserType (Name, TypeBuilder, this);
1238 if ((parent_type != null) && parent_type.IsAttribute) {
1239 RootContext.RegisterAttribute (this);
1240 } else if (!(this is Iterator))
1241 RootContext.RegisterOrder (this);
1243 if (!DefineNestedTypes ()) {
1252 protected virtual bool DefineNestedTypes ()
1254 if (Interfaces != null) {
1255 foreach (TypeContainer iface in Interfaces)
1256 if (iface.DefineType () == null)
1260 if (Types != null) {
1261 foreach (TypeContainer tc in Types)
1262 if (tc.DefineType () == null)
1266 if (Delegates != null) {
1267 foreach (Delegate d in Delegates)
1268 if (d.DefineType () == null)
1272 if (Enums != null) {
1273 foreach (Enum en in Enums)
1274 if (en.DefineType () == null)
1278 if (Parts != null) {
1279 foreach (ClassPart part in Parts) {
1280 part.TypeBuilder = TypeBuilder;
1282 part.ec = new EmitContext (part, Mono.CSharp.Location.Null, null, null, ModFlags);
1289 static void Error_KeywordNotAllowed (Location loc)
1291 Report.Error (1530, loc, "Keyword new not allowed for namespace elements");
1295 /// Populates our TypeBuilder with fields and methods
1297 public override bool DefineMembers (TypeContainer container)
1299 if (members_defined)
1300 return members_defined_ok;
1302 members_defined_ok = DoDefineMembers ();
1303 members_defined = true;
1305 return members_defined_ok;
1308 bool DoDefineMembers ()
1311 // We need to be able to use the member cache while we are checking/defining
1313 if (TypeBuilder.BaseType != null)
1314 parent_cache = TypeManager.LookupMemberCache (TypeBuilder.BaseType);
1316 if (TypeBuilder.IsInterface)
1317 parent_cache = TypeManager.LookupParentInterfacesCache (TypeBuilder);
1320 if ((ModFlags & Modifiers.NEW) != 0)
1321 Error_KeywordNotAllowed (Location);
1323 // HACK: missing implemenation
1324 // This is not fully functional. Better way how to handle this is to have recursive definition of containers
1325 // instead of flat as we have now.
1326 // Now we are not able to check inner attribute class because its parent had not been defined.
1328 // TODO: remove this if
1329 if (Parent.MemberCache != null) {
1330 MemberInfo conflict_symbol = Parent.MemberCache.FindMemberWithSameName (Basename, false, TypeBuilder);
1331 if (conflict_symbol == null) {
1332 if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0))
1333 Report.Warning (109, Location, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
1335 if ((ModFlags & Modifiers.NEW) == 0) {
1336 Report.SymbolRelatedToPreviousError (conflict_symbol);
1337 Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError ());
1343 DefineContainerMembers (constants);
1344 DefineContainerMembers (fields);
1346 if ((Kind == Kind.Class) && !(this is ClassPart) && !(this is StaticClass)){
1347 if ((instance_constructors == null) &&
1348 !(this is StaticClass)) {
1349 if (default_constructor == null)
1350 DefineDefaultConstructor (false);
1353 if (initialized_static_fields != null &&
1354 default_static_constructor == null)
1355 DefineDefaultConstructor (true);
1358 if (Kind == Kind.Struct){
1360 // Structs can not have initialized instance
1363 if (initialized_static_fields != null &&
1364 default_static_constructor == null)
1365 DefineDefaultConstructor (true);
1367 if (initialized_fields != null)
1368 ReportStructInitializedInstanceError ();
1371 Pending = GetPendingImplementations ();
1373 if (parts != null) {
1374 foreach (ClassPart part in parts) {
1375 if (!part.DefineMembers (this))
1381 // Constructors are not in the defined_names array
1383 DefineContainerMembers (instance_constructors);
1385 if (default_static_constructor != null)
1386 default_static_constructor.Define ();
1388 DefineContainerMembers (properties);
1389 DefineContainerMembers (events);
1390 DefineContainerMembers (indexers);
1391 DefineContainerMembers (methods);
1392 DefineContainerMembers (operators);
1393 DefineContainerMembers (enums);
1394 DefineContainerMembers (delegates);
1397 if (!(this is ClassPart))
1398 member_cache = new MemberCache (this);
1401 if (parts != null) {
1402 foreach (ClassPart part in parts)
1403 part.member_cache = member_cache;
1406 if (iterators != null) {
1407 foreach (Iterator iterator in iterators) {
1408 if (iterator.DefineType () == null)
1412 foreach (Iterator iterator in iterators) {
1413 if (!iterator.DefineMembers (this))
1421 void ReportStructInitializedInstanceError ()
1423 string n = TypeBuilder.FullName;
1425 foreach (Field f in initialized_fields){
1428 "`" + n + "." + f.Name + "': can not have " +
1429 "instance field initializers in structs");
1433 protected virtual void DefineContainerMembers (MemberCoreArrayList mcal)
1436 mcal.DefineContainerMembers ();
1439 public override bool Define ()
1441 if (parts != null) {
1442 foreach (ClassPart part in parts) {
1443 if (!part.Define ())
1451 public MemberInfo FindMemberWithSameName (string name, bool ignore_methods)
1453 return ParentCache.FindMemberWithSameName (name, ignore_methods, null);
1457 /// This function is based by a delegate to the FindMembers routine
1459 static bool AlwaysAccept (MemberInfo m, object filterCriteria)
1465 /// This filter is used by FindMembers, and we just keep
1466 /// a global for the filter to `AlwaysAccept'
1468 static MemberFilter accepting_filter;
1471 static TypeContainer ()
1473 accepting_filter = new MemberFilter (AlwaysAccept);
1476 public MethodInfo[] GetMethods ()
1478 ArrayList members = new ArrayList ();
1480 DefineMembers (null);
1482 if (methods != null) {
1483 int len = methods.Count;
1484 for (int i = 0; i < len; i++) {
1485 Method m = (Method) methods [i];
1487 members.Add (m.MethodBuilder);
1491 if (operators != null) {
1492 int len = operators.Count;
1493 for (int i = 0; i < len; i++) {
1494 Operator o = (Operator) operators [i];
1496 members.Add (o.OperatorMethodBuilder);
1500 if (properties != null) {
1501 int len = properties.Count;
1502 for (int i = 0; i < len; i++) {
1503 Property p = (Property) properties [i];
1505 if (p.GetBuilder != null)
1506 members.Add (p.GetBuilder);
1507 if (p.SetBuilder != null)
1508 members.Add (p.SetBuilder);
1512 if (indexers != null) {
1513 int len = indexers.Count;
1514 for (int i = 0; i < len; i++) {
1515 Indexer ix = (Indexer) indexers [i];
1517 if (ix.GetBuilder != null)
1518 members.Add (ix.GetBuilder);
1519 if (ix.SetBuilder != null)
1520 members.Add (ix.SetBuilder);
1524 if (events != null) {
1525 int len = events.Count;
1526 for (int i = 0; i < len; i++) {
1527 Event e = (Event) events [i];
1529 if (e.AddBuilder != null)
1530 members.Add (e.AddBuilder);
1531 if (e.RemoveBuilder != null)
1532 members.Add (e.RemoveBuilder);
1536 MethodInfo[] retMethods = new MethodInfo [members.Count];
1537 members.CopyTo (retMethods, 0);
1541 // Indicated whether container has StructLayout attribute set Explicit
1542 public virtual bool HasExplicitLayout {
1549 /// This method returns the members of this type just like Type.FindMembers would
1550 /// Only, we need to use this for types which are _being_ defined because MS'
1551 /// implementation can't take care of that.
1554 // FIXME: return an empty static array instead of null, that cleans up
1555 // some code and is consistent with some coding conventions I just found
1559 // Notice that in various cases we check if our field is non-null,
1560 // something that would normally mean that there was a bug elsewhere.
1562 // The problem happens while we are defining p-invoke methods, as those
1563 // will trigger a FindMembers, but this happens before things are defined
1565 // Since the whole process is a no-op, it is fine to check for null here.
1567 public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
1568 MemberFilter filter, object criteria)
1570 ArrayList members = null;
1573 if ((bf & BindingFlags.Public) != 0)
1574 modflags |= Modifiers.PUBLIC | Modifiers.PROTECTED |
1576 if ((bf & BindingFlags.NonPublic) != 0)
1577 modflags |= Modifiers.PRIVATE;
1579 int static_mask = 0, static_flags = 0;
1580 switch (bf & (BindingFlags.Static | BindingFlags.Instance)) {
1581 case BindingFlags.Static:
1582 static_mask = static_flags = Modifiers.STATIC;
1585 case BindingFlags.Instance:
1586 static_mask = Modifiers.STATIC;
1591 static_mask = static_flags = 0;
1595 Timer.StartTimer (TimerType.TcFindMembers);
1598 filter = accepting_filter;
1600 if ((mt & MemberTypes.Field) != 0) {
1601 if (fields != null) {
1602 int len = fields.Count;
1603 for (int i = 0; i < len; i++) {
1604 Field f = (Field) fields [i];
1606 if ((f.ModFlags & modflags) == 0)
1608 if ((f.ModFlags & static_mask) != static_flags)
1611 FieldBuilder fb = f.FieldBuilder;
1612 if (fb != null && filter (fb, criteria) == true) {
1613 if (members == null)
1614 members = new ArrayList ();
1621 if (constants != null) {
1622 int len = constants.Count;
1623 for (int i = 0; i < len; i++) {
1624 Const con = (Const) constants [i];
1626 if ((con.ModFlags & modflags) == 0)
1628 if ((con.ModFlags & static_mask) != static_flags)
1631 FieldBuilder fb = con.FieldBuilder;
1632 if (fb != null && filter (fb, criteria) == true) {
1633 if (members == null)
1634 members = new ArrayList ();
1642 if ((mt & MemberTypes.Method) != 0) {
1643 if (methods != null) {
1644 int len = methods.Count;
1645 for (int i = 0; i < len; i++) {
1646 Method m = (Method) methods [i];
1648 if ((m.ModFlags & modflags) == 0)
1650 if ((m.ModFlags & static_mask) != static_flags)
1653 MethodBuilder mb = m.MethodBuilder;
1655 if (mb != null && filter (mb, criteria) == true) {
1656 if (members == null)
1657 members = new ArrayList ();
1664 if (operators != null) {
1665 int len = operators.Count;
1666 for (int i = 0; i < len; i++) {
1667 Operator o = (Operator) operators [i];
1669 if ((o.ModFlags & modflags) == 0)
1671 if ((o.ModFlags & static_mask) != static_flags)
1674 MethodBuilder ob = o.OperatorMethodBuilder;
1675 if (ob != null && filter (ob, criteria) == true) {
1676 if (members == null)
1677 members = new ArrayList ();
1684 if (properties != null) {
1685 int len = properties.Count;
1686 for (int i = 0; i < len; i++) {
1687 Property p = (Property) properties [i];
1689 if ((p.ModFlags & modflags) == 0)
1691 if ((p.ModFlags & static_mask) != static_flags)
1697 if (b != null && filter (b, criteria) == true) {
1698 if (members == null)
1699 members = new ArrayList ();
1705 if (b != null && filter (b, criteria) == true) {
1706 if (members == null)
1707 members = new ArrayList ();
1714 if (indexers != null) {
1715 int len = indexers.Count;
1716 for (int i = 0; i < len; i++) {
1717 Indexer ix = (Indexer) indexers [i];
1719 if ((ix.ModFlags & modflags) == 0)
1721 if ((ix.ModFlags & static_mask) != static_flags)
1727 if (b != null && filter (b, criteria) == true) {
1728 if (members == null)
1729 members = new ArrayList ();
1735 if (b != null && filter (b, criteria) == true) {
1736 if (members == null)
1737 members = new ArrayList ();
1745 if ((mt & MemberTypes.Event) != 0) {
1746 if (events != null) {
1747 int len = events.Count;
1748 for (int i = 0; i < len; i++) {
1749 Event e = (Event) events [i];
1751 if ((e.ModFlags & modflags) == 0)
1753 if ((e.ModFlags & static_mask) != static_flags)
1756 MemberInfo eb = e.EventBuilder;
1757 if (eb != null && filter (eb, criteria) == true) {
1758 if (members == null)
1759 members = new ArrayList ();
1761 members.Add (e.EventBuilder);
1767 if ((mt & MemberTypes.Property) != 0){
1768 if (properties != null) {
1769 int len = properties.Count;
1770 for (int i = 0; i < len; i++) {
1771 Property p = (Property) properties [i];
1773 if ((p.ModFlags & modflags) == 0)
1775 if ((p.ModFlags & static_mask) != static_flags)
1778 MemberInfo pb = p.PropertyBuilder;
1779 if (pb != null && filter (pb, criteria) == true) {
1780 if (members == null)
1781 members = new ArrayList ();
1783 members.Add (p.PropertyBuilder);
1788 if (indexers != null) {
1789 int len = indexers.Count;
1790 for (int i = 0; i < len; i++) {
1791 Indexer ix = (Indexer) indexers [i];
1793 if ((ix.ModFlags & modflags) == 0)
1795 if ((ix.ModFlags & static_mask) != static_flags)
1798 MemberInfo ib = ix.PropertyBuilder;
1799 if (ib != null && filter (ib, criteria) == true) {
1800 if (members == null)
1801 members = new ArrayList ();
1803 members.Add (ix.PropertyBuilder);
1809 if ((mt & MemberTypes.NestedType) != 0) {
1810 if (types != null) {
1811 int len = types.Count;
1812 for (int i = 0; i < len; i++) {
1813 TypeContainer t = (TypeContainer) types [i];
1815 if ((t.ModFlags & modflags) == 0)
1818 TypeBuilder tb = t.TypeBuilder;
1819 if (tb != null && (filter (tb, criteria) == true)) {
1820 if (members == null)
1821 members = new ArrayList ();
1828 if (enums != null) {
1829 int len = enums.Count;
1830 for (int i = 0; i < len; i++) {
1831 Enum en = (Enum) enums [i];
1833 if ((en.ModFlags & modflags) == 0)
1836 TypeBuilder tb = en.TypeBuilder;
1837 if (tb != null && (filter (tb, criteria) == true)) {
1838 if (members == null)
1839 members = new ArrayList ();
1846 if (delegates != null) {
1847 int len = delegates.Count;
1848 for (int i = 0; i < len; i++) {
1849 Delegate d = (Delegate) delegates [i];
1851 if ((d.ModFlags & modflags) == 0)
1854 TypeBuilder tb = d.TypeBuilder;
1855 if (tb != null && (filter (tb, criteria) == true)) {
1856 if (members == null)
1857 members = new ArrayList ();
1864 if (interfaces != null) {
1865 int len = interfaces.Count;
1866 for (int i = 0; i < len; i++) {
1867 TypeContainer iface = (TypeContainer) interfaces [i];
1869 if ((iface.ModFlags & modflags) == 0)
1872 TypeBuilder tb = iface.TypeBuilder;
1873 if (tb != null && (filter (tb, criteria) == true)) {
1874 if (members == null)
1875 members = new ArrayList ();
1883 if ((mt & MemberTypes.Constructor) != 0){
1884 if (((bf & BindingFlags.Instance) != 0) && (instance_constructors != null)){
1885 int len = instance_constructors.Count;
1886 for (int i = 0; i < len; i++) {
1887 Constructor c = (Constructor) instance_constructors [i];
1889 ConstructorBuilder cb = c.ConstructorBuilder;
1890 if (cb != null && filter (cb, criteria) == true) {
1891 if (members == null)
1892 members = new ArrayList ();
1899 if (((bf & BindingFlags.Static) != 0) && (default_static_constructor != null)){
1900 ConstructorBuilder cb =
1901 default_static_constructor.ConstructorBuilder;
1903 if (cb != null && filter (cb, criteria) == true) {
1904 if (members == null)
1905 members = new ArrayList ();
1913 // Lookup members in parent if requested.
1915 if ((bf & BindingFlags.DeclaredOnly) == 0) {
1916 if (TypeBuilder.BaseType != null) {
1917 MemberList list = FindMembers (TypeBuilder.BaseType, mt, bf, filter, criteria);
1918 if (list.Count > 0) {
1919 if (members == null)
1920 members = new ArrayList ();
1922 members.AddRange (list);
1925 if (ifaces != null) {
1926 foreach (Type base_type in ifaces) {
1927 MemberList list = TypeContainer.FindMembers (base_type, mt, bf, filter, criteria);
1929 if (list.Count > 0) {
1930 if (members == null)
1931 members = new ArrayList ();
1932 members.AddRange (list);
1938 Timer.StopTimer (TimerType.TcFindMembers);
1940 if (members == null)
1941 return MemberList.Empty;
1943 return new MemberList (members);
1946 public override MemberCache MemberCache {
1948 return member_cache;
1952 public static MemberList FindMembers (Type t, MemberTypes mt, BindingFlags bf,
1953 MemberFilter filter, object criteria)
1955 DeclSpace ds = TypeManager.LookupDeclSpace (t);
1958 return ds.FindMembers (mt, bf, filter, criteria);
1960 return new MemberList (t.FindMembers (mt, bf, filter, criteria));
1965 // FindMethods will look for methods not only in the type `t', but in
1966 // any interfaces implemented by the type.
1968 public static MethodInfo [] FindMethods (Type t, BindingFlags bf,
1969 MemberFilter filter, object criteria)
1975 /// Emits the values for the constants
1977 public void EmitConstants ()
1979 if (constants != null)
1980 foreach (Const con in constants)
1985 protected virtual void VerifyMembers (EmitContext ec)
1988 // Check for internal or private fields that were never assigned
1990 if (RootContext.WarningLevel >= 3) {
1991 if (fields != null){
1992 foreach (Field f in fields) {
1993 if ((f.ModFlags & Modifiers.Accessibility) != Modifiers.PRIVATE)
1996 if ((f.status & Field.Status.USED) == 0){
1997 Report.Warning (169, f.Location, "The private field '{0}' is never used", f.GetSignatureForError ());
2002 // Only report 649 on level 4
2004 if (RootContext.WarningLevel < 4)
2007 if ((f.status & Field.Status.ASSIGNED) != 0)
2010 Report.Warning (649, f.Location, "Field '{0}' is never assigned to, and will always have its default value '{1}'", f.GetSignatureForError (), "");
2017 /// Emits the code, this step is performed after all
2018 /// the types, enumerations, constructors
2020 public void EmitType ()
2022 if (OptAttributes != null)
2023 OptAttributes.Emit (ec, this);
2027 if (instance_constructors != null) {
2028 if (TypeBuilder.IsSubclassOf (TypeManager.attribute_type) && RootContext.VerifyClsCompliance && IsClsCompliaceRequired (this)) {
2029 bool has_compliant_args = false;
2031 foreach (Constructor c in instance_constructors) {
2034 if (has_compliant_args)
2037 has_compliant_args = c.HasCompliantArgs;
2039 if (!has_compliant_args)
2040 Report.Error (3015, Location, "'{0}' has no accessible constructors which use only CLS-compliant types", GetSignatureForError ());
2042 foreach (Constructor c in instance_constructors)
2049 if (default_static_constructor != null)
2050 default_static_constructor.Emit ();
2052 if (methods != null)
2053 foreach (Method m in methods)
2056 if (operators != null)
2057 foreach (Operator o in operators)
2060 if (properties != null)
2061 foreach (Property p in properties)
2064 if (indexers != null){
2069 foreach (Field f in fields)
2072 if (events != null){
2073 foreach (Event e in Events)
2077 if (delegates != null) {
2078 foreach (Delegate d in Delegates) {
2083 if (enums != null) {
2084 foreach (Enum e in enums) {
2089 if (parts != null) {
2090 foreach (ClassPart part in parts)
2094 if ((Pending != null) && !(this is ClassPart))
2095 if (Pending.VerifyPendingMethods ())
2100 if (iterators != null)
2101 foreach (Iterator iterator in iterators)
2102 iterator.EmitType ();
2104 // if (types != null)
2105 // foreach (TypeContainer tc in types)
2109 public override void CloseType ()
2111 if ((caching_flags & Flags.CloseTypeCreated) != 0)
2115 caching_flags |= Flags.CloseTypeCreated;
2116 TypeBuilder.CreateType ();
2117 } catch (TypeLoadException){
2119 // This is fine, the code still created the type
2121 // Report.Warning (-20, "Exception while creating class: " + TypeBuilder.Name);
2122 // Console.WriteLine (e.Message);
2124 Console.WriteLine ("In type: " + Name);
2129 foreach (Enum en in Enums)
2133 foreach (TypeContainer tc in Types)
2134 if (tc.Kind == Kind.Struct)
2137 foreach (TypeContainer tc in Types)
2138 if (tc.Kind != Kind.Struct)
2142 if (Delegates != null)
2143 foreach (Delegate d in Delegates)
2146 if (Iterators != null)
2147 foreach (Iterator i in Iterators)
2155 initialized_fields = null;
2156 initialized_static_fields = null;
2165 default_constructor = null;
2166 default_static_constructor = null;
2168 OptAttributes = null;
2170 parent_cache = null;
2171 member_cache = null;
2174 // TODO: make it obsolete and use GetSignatureForError
2175 public string MakeName (string n)
2177 return "`" + Name + "." + n + "'";
2181 // Performs the validation on a Method's modifiers (properties have
2182 // the same properties).
2184 public bool MethodModifiersValid (int flags, string n, Location loc)
2186 const int vao = (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE);
2187 const int va = (Modifiers.VIRTUAL | Modifiers.ABSTRACT);
2188 const int nv = (Modifiers.NEW | Modifiers.VIRTUAL);
2192 // At most one of static, virtual or override
2194 if ((flags & Modifiers.STATIC) != 0){
2195 if ((flags & vao) != 0){
2197 112, loc, "static method " + MakeName (n) + "can not be marked " +
2198 "as virtual, abstract or override");
2203 if (Kind == Kind.Struct){
2204 if ((flags & va) != 0){
2205 Modifiers.Error_InvalidModifier (loc, "virtual or abstract");
2210 if ((flags & Modifiers.OVERRIDE) != 0 && (flags & nv) != 0){
2212 113, loc, MakeName (n) +
2213 " marked as override cannot be marked as new or virtual");
2218 // If the declaration includes the abstract modifier, then the
2219 // declaration does not include static, virtual or extern
2221 if ((flags & Modifiers.ABSTRACT) != 0){
2222 if ((flags & Modifiers.EXTERN) != 0){
2224 180, loc, MakeName (n) + " can not be both abstract and extern");
2228 if ((flags & Modifiers.VIRTUAL) != 0){
2230 503, loc, MakeName (n) + " can not be both abstract and virtual");
2234 if ((ModFlags & Modifiers.ABSTRACT) == 0){
2236 513, loc, MakeName (n) +
2237 " is abstract but its container class is not");
2243 if ((flags & Modifiers.PRIVATE) != 0){
2244 if ((flags & vao) != 0){
2246 621, loc, MakeName (n) +
2247 " virtual or abstract members can not be private");
2252 if ((flags & Modifiers.SEALED) != 0){
2253 if ((flags & Modifiers.OVERRIDE) == 0){
2255 238, loc, MakeName (n) +
2256 " cannot be sealed because it is not an override");
2264 public bool UserDefinedStaticConstructor {
2266 return default_static_constructor != null;
2270 protected override bool VerifyClsCompliance (DeclSpace ds)
2272 if (!base.VerifyClsCompliance (ds))
2277 Type base_type = TypeBuilder.BaseType;
2278 if (base_type != null && !AttributeTester.IsClsCompliant (base_type)) {
2279 Report.Error (3009, Location, "'{0}': base type '{1}' is not CLS-compliant", GetSignatureForError (), TypeManager.CSharpName (base_type));
2286 /// Checks whether container name is CLS Compliant
2288 void VerifyClsName ()
2290 Hashtable parent_members = parent_cache == null ?
2292 parent_cache.GetPublicMembers ();
2293 Hashtable this_members = new Hashtable ();
2295 foreach (DictionaryEntry entry in defined_names) {
2296 MemberCore mc = (MemberCore)entry.Value;
2297 if (!mc.IsClsCompliaceRequired (this))
2300 string name = (string)entry.Key;
2301 string basename = name.Substring (name.LastIndexOf ('.') + 1);
2303 string lcase = basename.ToLower (System.Globalization.CultureInfo.InvariantCulture);
2304 object found = parent_members [lcase];
2305 if (found == null) {
2306 found = this_members [lcase];
2307 if (found == null) {
2308 this_members.Add (lcase, mc);
2313 if ((mc.ModFlags & Modifiers.OVERRIDE) != 0)
2316 if (found is MemberInfo) {
2317 if (basename == ((MemberInfo)found).Name)
2319 Report.SymbolRelatedToPreviousError ((MemberInfo)found);
2321 Report.SymbolRelatedToPreviousError ((MemberCore) found);
2323 Report.Error (3005, mc.Location, "Identifier '{0}' differing only in case is not CLS-compliant", mc.GetSignatureForError ());
2329 /// Performs checks for an explicit interface implementation. First it
2330 /// checks whether the `interface_type' is a base inteface implementation.
2331 /// Then it checks whether `name' exists in the interface type.
2333 public virtual bool VerifyImplements (Type interface_type, string full,
2334 string name, Location loc)
2338 if (ifaces != null){
2339 foreach (Type t in ifaces){
2340 if (t == interface_type){
2348 Report.Error (540, "`" + full + "': containing class does not implement interface `" + interface_type.FullName + "'");
2355 protected override void VerifyObsoleteAttribute()
2357 CheckUsageOfObsoleteAttribute (ptype);
2362 foreach (Type iface in ifaces) {
2363 CheckUsageOfObsoleteAttribute (iface);
2372 string IMemberContainer.Name {
2378 Type IMemberContainer.Type {
2384 MemberCache IMemberContainer.MemberCache {
2386 return member_cache;
2390 bool IMemberContainer.IsInterface {
2392 return Kind == Kind.Interface;
2396 MemberList IMemberContainer.GetMembers (MemberTypes mt, BindingFlags bf)
2398 return FindMembers (mt, bf | BindingFlags.DeclaredOnly, null, null);
2401 public virtual MemberCache ParentCache {
2403 return parent_cache;
2408 public class PartialContainer : TypeContainer {
2410 public readonly Namespace Namespace;
2411 public readonly int OriginalModFlags;
2412 public readonly int AllowedModifiers;
2413 public readonly TypeAttributes DefaultTypeAttributes;
2415 static PartialContainer Create (NamespaceEntry ns, TypeContainer parent,
2416 MemberName name, int mod_flags, Kind kind,
2419 PartialContainer pc;
2420 string full_name = name.GetName (true);
2421 DeclSpace ds = (DeclSpace) RootContext.Tree.Decls [full_name];
2423 pc = ds as PartialContainer;
2427 260, ds.Location, "Missing partial modifier " +
2428 "on declaration of type `{0}'; another " +
2429 "partial implementation of this type exists",
2432 Report.LocationOfPreviousError (loc);
2436 if (pc.Kind != kind) {
2438 261, loc, "Partial declarations of `{0}' " +
2439 "must be all classes, all structs or " +
2440 "all interfaces", name);
2444 if (pc.OriginalModFlags != mod_flags) {
2446 262, loc, "Partial declarations of `{0}' " +
2447 "have conflicting accessibility modifiers",
2455 pc = new PartialContainer (ns, parent, name, mod_flags, kind, loc);
2456 RootContext.Tree.RecordDecl (full_name, pc);
2457 parent.AddType (pc);
2462 public static ClassPart CreatePart (NamespaceEntry ns, TypeContainer parent,
2463 MemberName name, int mod, Attributes attrs,
2464 Kind kind, Location loc)
2466 PartialContainer pc = Create (ns, parent, name, mod, kind, loc);
2468 // An error occured; create a dummy container, but don't
2470 pc = new PartialContainer (ns, parent, name, mod, kind, loc);
2473 ClassPart part = new ClassPart (ns, pc, mod, attrs, kind, loc);
2478 protected PartialContainer (NamespaceEntry ns, TypeContainer parent,
2479 MemberName name, int mod, Kind kind, Location l)
2480 : base (ns, parent, name, null, kind, l)
2482 this.Namespace = ns.NS;
2486 AllowedModifiers = Class.AllowedModifiers;
2487 DefaultTypeAttributes = Class.DefaultTypeAttributes;
2491 AllowedModifiers = Struct.AllowedModifiers;
2492 DefaultTypeAttributes = Struct.DefaultTypeAttributes;
2495 case Kind.Interface:
2496 AllowedModifiers = Interface.AllowedModifiers;
2497 DefaultTypeAttributes = Interface.DefaultTypeAttributes;
2501 throw new InvalidOperationException ();
2505 if (parent.Parent == null)
2506 accmods = Modifiers.INTERNAL;
2508 accmods = Modifiers.PRIVATE;
2510 this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
2511 this.OriginalModFlags = mod;
2514 public override void Register ()
2516 if (Kind == Kind.Interface)
2517 Parent.AddInterface (this);
2518 else if (Kind == Kind.Class || Kind == Kind.Struct)
2519 Parent.AddClassOrStruct (this);
2521 throw new InvalidOperationException ();
2524 public override PendingImplementation GetPendingImplementations ()
2526 return PendingImplementation.GetPendingImplementations (this);
2529 public ClassPart AddPart (NamespaceEntry ns, int mod, Attributes attrs,
2532 ClassPart part = new ClassPart (ns, this, mod, attrs, Kind, l);
2537 public override TypeAttributes TypeAttr {
2539 return base.TypeAttr | DefaultTypeAttributes;
2544 public class ClassPart : TypeContainer, IMemberContainer {
2545 public readonly PartialContainer PartialContainer;
2546 public readonly bool IsPartial;
2548 public ClassPart (NamespaceEntry ns, PartialContainer parent,
2549 int mod, Attributes attrs, Kind kind, Location l)
2550 : base (ns, parent.Parent, parent.MemberName, attrs, kind, l)
2552 this.PartialContainer = parent;
2553 this.IsPartial = true;
2556 if (parent.Parent == null)
2557 accmods = Modifiers.INTERNAL;
2559 accmods = Modifiers.PRIVATE;
2561 this.ModFlags = Modifiers.Check (
2562 parent.AllowedModifiers, mod, accmods, l);
2565 public override void Register ()
2569 public override PendingImplementation GetPendingImplementations ()
2571 return PartialContainer.Pending;
2574 public override bool VerifyImplements (Type interface_type, string full,
2575 string name, Location loc)
2577 return PartialContainer.VerifyImplements (
2578 interface_type, full, name, loc);
2581 public override MemberCache ParentCache {
2583 return PartialContainer.ParentCache;
2588 public abstract class ClassOrStruct : TypeContainer {
2589 bool hasExplicitLayout = false;
2590 ListDictionary declarative_security;
2592 public ClassOrStruct (NamespaceEntry ns, TypeContainer parent,
2593 MemberName name, Attributes attrs, Kind kind,
2595 : base (ns, parent, name, attrs, kind, l)
2599 public override PendingImplementation GetPendingImplementations ()
2601 return PendingImplementation.GetPendingImplementations (this);
2604 public override bool HasExplicitLayout {
2606 return hasExplicitLayout;
2610 protected override void VerifyMembers (EmitContext ec)
2612 base.VerifyMembers (ec);
2614 if ((events != null) && (RootContext.WarningLevel >= 3)) {
2615 foreach (Event e in events){
2617 Report.Warning (67, e.Location, "The event '{0}' is never used", e.GetSignatureForError ());
2622 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
2624 if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
2625 if (declarative_security == null)
2626 declarative_security = new ListDictionary ();
2628 a.ExtractSecurityPermissionSet (declarative_security);
2632 if (a.Type == TypeManager.struct_layout_attribute_type
2633 && (LayoutKind) a.GetPositionalValue (0) == LayoutKind.Explicit)
2634 hasExplicitLayout = true;
2636 base.ApplyAttributeBuilder (a, cb);
2639 public override void Emit()
2643 if (declarative_security != null) {
2644 foreach (DictionaryEntry de in declarative_security) {
2645 TypeBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
2650 public override void Register ()
2652 Parent.AddClassOrStruct (this);
2657 /// Class handles static classes declaration
2659 public sealed class StaticClass: Class {
2660 public StaticClass (NamespaceEntry ns, TypeContainer parent, MemberName name, int mod,
2661 Attributes attrs, Location l)
2662 : base (ns, parent, name, mod & ~Modifiers.STATIC, attrs, l)
2664 if (RootContext.Version == LanguageVersion.ISO_1) {
2665 Report.FeatureIsNotStandardized (l, "static classes");
2666 Environment.Exit (1);
2670 protected override void DefineContainerMembers (MemberCoreArrayList list)
2675 foreach (MemberCore m in list) {
2676 if (m is Operator) {
2677 Report.Error (715, m.Location, "'{0}': static classes cannot contain user-defined operators", m.GetSignatureForError (this));
2681 if ((m.ModFlags & Modifiers.STATIC) != 0)
2684 if (m is Constructor) {
2685 Report.Error (710, m.Location, "'{0}': Static classes cannot have instance constructors", GetSignatureForError ());
2689 if (m is Destructor) {
2690 Report.Error (711, m.Location, "'{0}': Static class cannot contain destructor", GetSignatureForError ());
2694 Report.Error (708, m.Location, "'{0}': cannot declare instance members in a static class", m.GetSignatureForError (this));
2697 base.DefineContainerMembers (list);
2700 public override TypeBuilder DefineType()
2702 TypeBuilder tb = base.DefineType ();
2706 if (ptype != TypeManager.object_type) {
2707 Report.Error (713, Location, "Static class '{0}' cannot derive from type '{1}'. Static classes must derive from object", GetSignatureForError (), TypeManager.CSharpName (ptype));
2711 if (ifaces != null) {
2712 foreach (Type t in ifaces)
2713 Report.SymbolRelatedToPreviousError (t);
2714 Report.Error (714, Location, "'{0}': static classes cannot implement interfaces", GetSignatureForError ());
2719 public override TypeAttributes TypeAttr {
2721 return base.TypeAttr | TypeAttributes.Abstract | TypeAttributes.Sealed;
2726 public class Class : ClassOrStruct {
2728 // Modifiers allowed in a class declaration
2730 public const int AllowedModifiers =
2733 Modifiers.PROTECTED |
2734 Modifiers.INTERNAL |
2736 Modifiers.ABSTRACT |
2740 // Information in the case we are an attribute type
2741 AttributeUsageAttribute attribute_usage;
2743 public Class (NamespaceEntry ns, TypeContainer parent, MemberName name, int mod,
2744 Attributes attrs, Location l)
2745 : base (ns, parent, name, attrs, Kind.Class, l)
2749 if (parent.Parent == null)
2750 accmods = Modifiers.INTERNAL;
2752 accmods = Modifiers.PRIVATE;
2754 this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
2755 if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.SEALED)) == (Modifiers.ABSTRACT | Modifiers.SEALED)) {
2756 Report.Error (502, Location, "'{0}' cannot be both abstract and sealed", GetSignatureForError ());
2759 attribute_usage = new AttributeUsageAttribute (AttributeTargets.All);
2762 public override AttributeTargets AttributeTargets {
2764 return AttributeTargets.Class;
2768 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
2770 if (a.UsageAttribute != null) {
2771 if (ptype != TypeManager.attribute_type && !ptype.IsSubclassOf (TypeManager.attribute_type) &&
2772 TypeBuilder.FullName != "System.Attribute") {
2773 Report.Error (641, a.Location, "Attribute '{0}' is only valid on classes derived from System.Attribute", a.Name);
2775 attribute_usage = a.UsageAttribute;
2778 base.ApplyAttributeBuilder (a, cb);
2781 public AttributeUsageAttribute AttributeUsage {
2783 return attribute_usage;
2787 public const TypeAttributes DefaultTypeAttributes =
2788 TypeAttributes.AutoLayout | TypeAttributes.Class;
2791 // FIXME: How do we deal with the user specifying a different
2794 public override TypeAttributes TypeAttr {
2796 return base.TypeAttr | DefaultTypeAttributes;
2801 public class Struct : ClassOrStruct {
2803 // Modifiers allowed in a struct declaration
2805 public const int AllowedModifiers =
2808 Modifiers.PROTECTED |
2809 Modifiers.INTERNAL |
2813 public Struct (NamespaceEntry ns, TypeContainer parent, MemberName name,
2814 int mod, Attributes attrs, Location l)
2815 : base (ns, parent, name, attrs, Kind.Struct, l)
2819 if (parent.Parent == null)
2820 accmods = Modifiers.INTERNAL;
2822 accmods = Modifiers.PRIVATE;
2824 this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
2826 this.ModFlags |= Modifiers.SEALED;
2829 public override AttributeTargets AttributeTargets {
2831 return AttributeTargets.Struct;
2835 public const TypeAttributes DefaultTypeAttributes =
2836 TypeAttributes.SequentialLayout |
2837 TypeAttributes.Sealed |
2838 TypeAttributes.BeforeFieldInit;
2841 // FIXME: Allow the user to specify a different set of attributes
2842 // in some cases (Sealed for example is mandatory for a class,
2843 // but what SequentialLayout can be changed
2845 public override TypeAttributes TypeAttr {
2847 return base.TypeAttr | DefaultTypeAttributes;
2855 public class Interface : TypeContainer, IMemberContainer {
2857 /// Modifiers allowed in a class declaration
2859 public const int AllowedModifiers =
2862 Modifiers.PROTECTED |
2863 Modifiers.INTERNAL |
2867 public Interface (NamespaceEntry ns, TypeContainer parent, MemberName name, int mod,
2868 Attributes attrs, Location l)
2869 : base (ns, parent, name, attrs, Kind.Interface, l)
2873 if (parent.Parent == null)
2874 accmods = Modifiers.INTERNAL;
2876 accmods = Modifiers.PRIVATE;
2878 this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
2881 public override void Register ()
2883 Parent.AddInterface (this);
2886 public override PendingImplementation GetPendingImplementations ()
2891 public override AttributeTargets AttributeTargets {
2893 return AttributeTargets.Interface;
2897 public const TypeAttributes DefaultTypeAttributes =
2898 TypeAttributes.AutoLayout |
2899 TypeAttributes.Abstract |
2900 TypeAttributes.Interface;
2902 public override TypeAttributes TypeAttr {
2904 return base.TypeAttr | DefaultTypeAttributes;
2909 public abstract class MethodCore : MemberBase {
2910 public readonly Parameters Parameters;
2911 protected ToplevelBlock block;
2914 // Parameters, cached for semantic analysis.
2916 protected InternalParameters parameter_info;
2917 protected Type [] parameter_types;
2919 // Whether this is an operator method.
2920 public bool IsOperator;
2923 // The method we're overriding if this is an override method.
2925 protected MethodInfo parent_method = null;
2927 static string[] attribute_targets = new string [] { "method", "return" };
2929 public MethodCore (TypeContainer parent, Expression type, int mod,
2930 int allowed_mod, bool is_interface, MemberName name,
2931 Attributes attrs, Parameters parameters, Location loc)
2932 : base (parent, type, mod, allowed_mod, Modifiers.PRIVATE, name,
2935 Parameters = parameters;
2936 IsInterface = is_interface;
2940 // Returns the System.Type array for the parameters of this method
2942 public Type [] ParameterTypes {
2944 return parameter_types;
2948 public InternalParameters ParameterInfo
2951 return parameter_info;
2955 public ToplevelBlock Block {
2965 protected override bool CheckBase ()
2967 if (!base.CheckBase ())
2970 // Check whether arguments were correct.
2971 if (!DoDefineParameters ())
2974 if ((caching_flags & Flags.TestMethodDuplication) != 0 && !CheckForDuplications ())
2980 // Is null for System.Object while compiling corlib and base interfaces
2981 if (Parent.ParentCache == null) {
2982 if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) {
2983 Report.Warning (109, Location, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError (Parent));
2988 Type parent_ret_type = null;
2989 parent_method = FindOutParentMethod (Parent, ref parent_ret_type);
2991 // method is override
2992 if (parent_method != null) {
2994 if (!CheckMethodAgainstBase ())
2997 if ((ModFlags & Modifiers.NEW) == 0) {
2998 if (MemberType != TypeManager.TypeToCoreType (parent_ret_type)) {
2999 Report.SymbolRelatedToPreviousError (parent_method);
3000 Report.Error (508, Location, GetSignatureForError (Parent) + ": cannot " +
3001 "change return type when overriding inherited member");
3005 if (parent_method.IsAbstract && !IsInterface) {
3006 Report.SymbolRelatedToPreviousError (parent_method);
3007 Report.Error (533, Location, "'{0}' hides inherited abstract member", GetSignatureForError (Parent));
3012 if (parent_method.IsSpecialName && !(this is PropertyBase)) {
3013 Report.Error (561, Location, "'{0}': cannot override '{1}' because it is a special compiler-generated method", GetSignatureForError (Parent), TypeManager.GetFullNameSignature (parent_method));
3017 if (RootContext.WarningLevel > 2) {
3018 if (Name == "Equals" && parameter_types.Length == 1 && parameter_types [0] == TypeManager.object_type)
3019 Parent.Methods.HasEquals = true;
3020 else if (Name == "GetHashCode" && parameter_types.Length == 0)
3021 Parent.Methods.HasGetHashCode = true;
3024 ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (parent_method);
3026 EmitContext ec = new EmitContext (this.Parent, this.Parent, Location, null, null, ModFlags, false);
3027 if (OptAttributes == null || !OptAttributes.Contains (TypeManager.obsolete_attribute_type, ec)) {
3028 Report.SymbolRelatedToPreviousError (parent_method);
3029 Report.Warning (672, 1, Location, "Member '{0}' overrides obsolete member. Add the Obsolete attribute to '{0}'", GetSignatureForError (Parent));
3035 MemberInfo conflict_symbol = Parent.FindMemberWithSameName (Name, !(this is Property));
3036 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
3037 if (conflict_symbol != null) {
3038 Report.SymbolRelatedToPreviousError (conflict_symbol);
3039 if (this is PropertyBase)
3040 Report.Error (544, Location, "'{0}': cannot override because '{1}' is not a property", GetSignatureForError (Parent), TypeManager.GetFullNameSignature (conflict_symbol));
3042 Report.Error (505, Location, "'{0}': cannot override because '{1}' is not a method", GetSignatureForError (Parent), TypeManager.GetFullNameSignature (conflict_symbol));
3044 Report.Error (115, Location, "'{0}': no suitable methods found to override", GetSignatureForError (Parent));
3048 if (conflict_symbol == null) {
3049 if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) {
3050 Report.Warning (109, Location, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError (Parent));
3055 if ((ModFlags & Modifiers.NEW) == 0) {
3056 if (this is Method && conflict_symbol is MethodBase)
3059 Report.SymbolRelatedToPreviousError (conflict_symbol);
3060 Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent));
3068 // Performs various checks on the MethodInfo `mb' regarding the modifier flags
3069 // that have been defined.
3071 // `name' is the user visible name for reporting errors (this is used to
3072 // provide the right name regarding method names and properties)
3074 bool CheckMethodAgainstBase ()
3078 // TODO: replace with GetSignatureForError
3079 string name = parent_method.DeclaringType.Name + "." + parent_method.Name;
3081 if ((ModFlags & Modifiers.OVERRIDE) != 0){
3082 if (!(parent_method.IsAbstract || parent_method.IsVirtual)){
3084 506, Location, Parent.MakeName (Name) +
3085 ": cannot override inherited member `" +
3086 name + "' because it is not " +
3087 "virtual, abstract or override");
3091 // Now we check that the overriden method is not final
3093 if (parent_method.IsFinal) {
3094 // This happens when implementing interface methods.
3095 if (parent_method.IsHideBySig && parent_method.IsVirtual) {
3097 506, Location, Parent.MakeName (Name) +
3098 ": cannot override inherited member `" +
3099 name + "' because it is not " +
3100 "virtual, abstract or override");
3102 Report.Error (239, Location, Parent.MakeName (Name) + " : cannot " +
3103 "override inherited member `" + name +
3104 "' because it is sealed.");
3108 // Check that the permissions are not being changed
3110 MethodAttributes thisp = flags & MethodAttributes.MemberAccessMask;
3111 MethodAttributes parentp = parent_method.Attributes & MethodAttributes.MemberAccessMask;
3113 if (!CheckAccessModifiers (thisp, parentp, parent_method)) {
3114 Error_CannotChangeAccessModifiers (Parent, parent_method, name);
3119 if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0 && Name != "Finalize") {
3120 ModFlags |= Modifiers.NEW;
3121 Report.SymbolRelatedToPreviousError (parent_method);
3122 if (!IsInterface && (parent_method.IsVirtual || parent_method.IsAbstract)) {
3123 if (RootContext.WarningLevel >= 2)
3124 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));
3126 Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent));
3132 protected bool CheckAccessModifiers (MethodAttributes thisp, MethodAttributes parentp, MethodInfo base_method)
3134 if ((parentp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
3136 // when overriding protected internal, the method can be declared
3137 // protected internal only within the same assembly
3140 if ((thisp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
3141 if (Parent.TypeBuilder.Assembly != base_method.DeclaringType.Assembly){
3143 // assemblies differ - report an error
3147 } else if (thisp != parentp) {
3149 // same assembly, but other attributes differ - report an error
3154 } else if ((thisp & MethodAttributes.Family) != MethodAttributes.Family) {
3156 // if it's not "protected internal", it must be "protected"
3160 } else if (Parent.TypeBuilder.Assembly == base_method.DeclaringType.Assembly) {
3162 // protected within the same assembly - an error
3165 } else if ((thisp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem)) !=
3166 (parentp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem))) {
3168 // protected ok, but other attributes differ - report an error
3174 return (thisp == parentp);
3178 void Error_CannotChangeAccessModifiers (TypeContainer parent, MethodInfo parent_method, string name)
3181 // FIXME: report the old/new permissions?
3184 507, Location, parent.MakeName (Name) +
3185 ": can't change the access modifiers when overriding inherited " +
3186 "member `" + name + "'");
3189 protected static string Error722 {
3191 return "'{0}': static types cannot be used as return types";
3196 /// For custom member duplication search in a container
3198 protected abstract bool CheckForDuplications ();
3201 /// Gets parent method and its return type
3203 protected abstract MethodInfo FindOutParentMethod (TypeContainer container, ref Type parent_ret_type);
3205 protected virtual bool DoDefineParameters ()
3207 EmitContext ec = Parent.EmitContext;
3209 throw new InternalErrorException ("DoDefineParameters invoked too early");
3211 bool old_unsafe = ec.InUnsafe;
3212 ec.InUnsafe = InUnsafe;
3213 // Check if arguments were correct
3214 parameter_types = Parameters.GetParameterInfo (ec);
3215 ec.InUnsafe = old_unsafe;
3217 if ((parameter_types == null) ||
3218 !CheckParameters (Parent, parameter_types))
3221 parameter_info = new InternalParameters (parameter_types, Parameters);
3223 Parameter array_param = Parameters.ArrayParameter;
3224 if ((array_param != null) &&
3225 (!array_param.ParameterType.IsArray ||
3226 (array_param.ParameterType.GetArrayRank () != 1))) {
3227 Report.Error (225, Location, "params parameter has to be a single dimensional array");
3234 public override string[] ValidAttributeTargets {
3236 return attribute_targets;
3240 protected override bool VerifyClsCompliance (DeclSpace ds)
3242 if (!base.VerifyClsCompliance (ds)) {
3243 if ((ModFlags & Modifiers.ABSTRACT) != 0 && IsExposedFromAssembly (ds) && ds.IsClsCompliaceRequired (ds)) {
3244 Report.Error (3011, Location, "'{0}': only CLS-compliant members can be abstract", GetSignatureForError ());
3249 if (Parameters.HasArglist) {
3250 Report.Error (3000, Location, "Methods with variable arguments are not CLS-compliant");
3253 if (!AttributeTester.IsClsCompliant (MemberType)) {
3254 Report.Error (3002, Location, "Return type of '{0}' is not CLS-compliant", GetSignatureForError ());
3257 AttributeTester.AreParametersCompliant (Parameters.FixedParameters, Location);
3262 protected bool IsDuplicateImplementation (MethodCore method)
3264 if ((method == this) || (method.Name != Name))
3267 Type[] param_types = method.ParameterTypes;
3268 if (param_types == null)
3271 if (param_types.Length != ParameterTypes.Length)
3274 for (int i = 0; i < param_types.Length; i++)
3275 if (param_types [i] != ParameterTypes [i])
3278 // TODO: make operator compatible with MethodCore to avoid this
3279 if (this is Operator && method is Operator) {
3280 if (MemberType != method.MemberType)
3285 // Try to report 663: method only differs on out/ref
3287 ParameterData info = ParameterInfo;
3288 ParameterData other_info = method.ParameterInfo;
3289 for (int i = 0; i < info.Count; i++){
3290 if (info.ParameterModifier (i) != other_info.ParameterModifier (i)){
3291 Report.Error (663, Location, "Overload method only differs in parameter modifier");
3296 Report.SymbolRelatedToPreviousError (method);
3297 Report.Error (111, Location, TypeContainer.Error111, Parent.Name, Name);
3301 protected override void VerifyObsoleteAttribute()
3303 base.VerifyObsoleteAttribute ();
3305 if (parameter_types == null)
3308 foreach (Type type in parameter_types) {
3309 CheckUsageOfObsoleteAttribute (type);
3314 public class SourceMethod : ISourceMethod
3316 TypeContainer container;
3319 protected SourceMethod (TypeContainer container, MethodBase builder,
3320 ISourceFile file, Location start, Location end)
3322 this.container = container;
3323 this.builder = builder;
3325 CodeGen.SymbolWriter.OpenMethod (
3326 file, this, start.Row, 0, end.Row, 0);
3329 public string Name {
3330 get { return builder.Name; }
3333 public int NamespaceID {
3334 get { return container.NamespaceEntry.SymbolFileID; }
3339 if (builder is MethodBuilder)
3340 return ((MethodBuilder) builder).GetToken ().Token;
3341 else if (builder is ConstructorBuilder)
3342 return ((ConstructorBuilder) builder).GetToken ().Token;
3344 throw new NotSupportedException ();
3348 public void CloseMethod ()
3350 if (CodeGen.SymbolWriter != null)
3351 CodeGen.SymbolWriter.CloseMethod ();
3354 public static SourceMethod Create (TypeContainer parent,
3355 MethodBase builder, Block block)
3357 if (CodeGen.SymbolWriter == null)
3362 Location start_loc = block.StartLocation;
3363 if (Location.IsNull (start_loc))
3366 Location end_loc = block.EndLocation;
3367 if (Location.IsNull (end_loc))
3370 ISourceFile file = start_loc.SourceFile;
3374 return new SourceMethod (
3375 parent, builder, file, start_loc, end_loc);
3379 public class Method : MethodCore, IIteratorContainer, IMethodData {
3380 public MethodBuilder MethodBuilder;
3381 public MethodData MethodData;
3382 ReturnParameter return_attributes;
3383 ListDictionary declarative_security;
3386 /// Modifiers allowed in a class declaration
3388 const int AllowedModifiers =
3391 Modifiers.PROTECTED |
3392 Modifiers.INTERNAL |
3397 Modifiers.OVERRIDE |
3398 Modifiers.ABSTRACT |
3400 Modifiers.METHOD_YIELDS |
3403 const int AllowedInterfaceModifiers =
3404 Modifiers.NEW | Modifiers.UNSAFE;
3407 // return_type can be "null" for VOID values.
3409 public Method (TypeContainer ds, Expression return_type, int mod, bool is_iface,
3410 MemberName name, Parameters parameters, Attributes attrs,
3412 : base (ds, return_type, mod,
3413 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
3414 is_iface, name, attrs, parameters, l)
3418 public override AttributeTargets AttributeTargets {
3420 return AttributeTargets.Method;
3424 public override string GetSignatureForError()
3426 if (MethodBuilder == null) {
3427 return GetSignatureForError (Parent);
3429 return TypeManager.CSharpSignature (MethodBuilder);
3433 /// Use this method when MethodBuilder is null
3435 public override string GetSignatureForError (TypeContainer tc)
3437 // TODO: get params from somewhere
3438 if (parameter_info == null)
3439 return base.GetSignatureForError (tc);
3441 // TODO: move to parameters
3442 System.Text.StringBuilder args = new System.Text.StringBuilder ();
3443 if (parameter_info.Parameters.FixedParameters != null) {
3444 for (int i = 0; i < parameter_info.Parameters.FixedParameters.Length; ++i) {
3445 Parameter p = parameter_info.Parameters.FixedParameters [i];
3446 args.Append (p.GetSignatureForError ());
3448 if (i < parameter_info.Parameters.FixedParameters.Length - 1)
3453 return String.Concat (base.GetSignatureForError (tc), "(", args.ToString (), ")");
3456 void DuplicateEntryPoint (MethodInfo b, Location location)
3460 "Program `" + CodeGen.FileName +
3461 "' has more than one entry point defined: `" +
3462 TypeManager.CSharpSignature(b) + "'");
3465 public bool IsEntryPoint (MethodBuilder b, InternalParameters pinfo)
3467 if (b.ReturnType != TypeManager.void_type &&
3468 b.ReturnType != TypeManager.int32_type)
3471 if (pinfo.Count == 0)
3474 if (pinfo.Count > 1)
3477 Type t = pinfo.ParameterType(0);
3479 (t.GetArrayRank() == 1) &&
3480 (TypeManager.GetElementType(t) == TypeManager.string_type) &&
3481 (pinfo.ParameterModifier(0) == Parameter.Modifier.NONE))
3487 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
3489 if (a.Target == AttributeTargets.ReturnValue) {
3490 if (return_attributes == null)
3491 return_attributes = new ReturnParameter (MethodBuilder, Location);
3493 return_attributes.ApplyAttributeBuilder (a, cb);
3497 if (a.Type == TypeManager.methodimpl_attr_type && a.IsInternalCall) {
3498 MethodBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall | MethodImplAttributes.Runtime);
3501 if (a.Type == TypeManager.dllimport_type) {
3502 const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
3503 if ((ModFlags & extern_static) != extern_static) {
3504 Report.Error (601, a.Location, "The DllImport attribute must be specified on a method marked `static' and `extern'");
3510 if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
3511 if (declarative_security == null)
3512 declarative_security = new ListDictionary ();
3513 a.ExtractSecurityPermissionSet (declarative_security);
3517 if (a.Type == TypeManager.conditional_attribute_type) {
3518 if (IsOperator || IsExplicitImpl) {
3519 Report.Error (577, Location, "Conditional not valid on '{0}' because it is a destructor, operator, or explicit interface implementation", GetSignatureForError ());
3523 if (ReturnType != TypeManager.void_type) {
3524 Report.Error (578, Location, "Conditional not valid on '{0}' because its return new ErrorData ( type is not void", GetSignatureForError ());
3528 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
3529 Report.Error (243, Location, "Conditional not valid on '{0}' because it is an override method", GetSignatureForError ());
3534 Report.Error (582, Location, "Conditional not valid on interface members");
3538 if (MethodData.IsImplementing) {
3539 Report.Error (629, Location, "Conditional member '{0}' cannot implement interface member", GetSignatureForError ());
3543 for (int i = 0; i < parameter_info.Count; ++i) {
3544 if ((parameter_info.ParameterModifier (i) & Parameter.Modifier.OUT) != 0) {
3545 Report.Error (685, Location, "Conditional method '{0}' cannot have an out parameter", GetSignatureForError ());
3551 MethodBuilder.SetCustomAttribute (cb);
3554 protected override bool CheckForDuplications ()
3556 ArrayList ar = Parent.Methods;
3558 int arLen = ar.Count;
3560 for (int i = 0; i < arLen; i++) {
3561 Method m = (Method) ar [i];
3562 if (IsDuplicateImplementation (m))
3567 ar = Parent.Properties;
3569 for (int i = 0; i < ar.Count; ++i) {
3570 PropertyBase pb = (PropertyBase) ar [i];
3571 if (pb.AreAccessorsDuplicateImplementation (this))
3576 ar = Parent.Indexers;
3578 for (int i = 0; i < ar.Count; ++i) {
3579 PropertyBase pb = (PropertyBase) ar [i];
3580 if (pb.AreAccessorsDuplicateImplementation (this))
3587 for (int i = 0; i < ar.Count; ++i) {
3588 Event ev = (Event) ar [i];
3589 if (ev.AreAccessorsDuplicateImplementation (this))
3600 public override bool Define ()
3609 flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
3611 MethodData = new MethodData (this, ParameterInfo, ModFlags, flags, this);
3613 if (!MethodData.Define (Parent))
3617 // Setup iterator if we are one
3619 if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
3620 Iterator iterator = new Iterator (
3621 Parent, Name, MemberType, ParameterTypes,
3622 ParameterInfo, ModFlags, block, Location);
3624 if (!iterator.DefineIterator ())
3627 block = iterator.Block;
3630 MethodBuilder = MethodData.MethodBuilder;
3633 // This is used to track the Entry Point,
3635 if (Name == "Main" &&
3636 ((ModFlags & Modifiers.STATIC) != 0) && RootContext.NeedsEntryPoint &&
3637 (RootContext.MainClass == null ||
3638 RootContext.MainClass == Parent.TypeBuilder.FullName)){
3639 if (IsEntryPoint (MethodBuilder, ParameterInfo)) {
3640 if (RootContext.EntryPoint == null) {
3641 RootContext.EntryPoint = MethodBuilder;
3642 RootContext.EntryPointLocation = Location;
3644 DuplicateEntryPoint (RootContext.EntryPoint, RootContext.EntryPointLocation);
3645 DuplicateEntryPoint (MethodBuilder, Location);
3648 if (RootContext.WarningLevel >= 4)
3649 Report.Warning (28, Location, "'{0}' has the wrong signature to be an entry point", TypeManager.CSharpSignature(MethodBuilder));
3653 if (MemberType.IsAbstract && MemberType.IsSealed) {
3654 Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
3664 public override void Emit ()
3666 MethodData.Emit (Parent, this);
3669 if (declarative_security != null) {
3670 foreach (DictionaryEntry de in declarative_security) {
3671 MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
3679 protected override MethodInfo FindOutParentMethod (TypeContainer container, ref Type parent_ret_type)
3681 MethodInfo mi = (MethodInfo) container.ParentCache.FindMemberToOverride (
3682 container.TypeBuilder, Name, ParameterTypes, false);
3687 parent_ret_type = mi.ReturnType;
3691 protected override bool VerifyClsCompliance(DeclSpace ds)
3693 if (!base.VerifyClsCompliance (ds))
3696 if (parameter_types.Length > 0) {
3697 ArrayList al = (ArrayList)ds.MemberCache.Members [Name];
3699 ds.MemberCache.VerifyClsParameterConflict (al, this, MethodBuilder);
3706 void IIteratorContainer.SetYields ()
3708 ModFlags |= Modifiers.METHOD_YIELDS;
3711 #region IMethodData Members
3713 public CallingConventions CallingConventions {
3715 CallingConventions cc = Parameters.GetCallingConvention ();
3716 if (Parameters.HasArglist)
3717 block.HasVarargs = true;
3720 if ((ModFlags & Modifiers.STATIC) == 0)
3721 cc |= CallingConventions.HasThis;
3723 // FIXME: How is `ExplicitThis' used in C#?
3729 public Type ReturnType {
3735 public MemberName MethodName {
3741 public new Location Location {
3743 return base.Location;
3747 public EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig)
3749 return new EmitContext (
3750 tc, Parent, Location, ig, ReturnType, ModFlags, false);
3753 public ObsoleteAttribute GetObsoleteAttribute ()
3755 return GetObsoleteAttribute (Parent);
3759 /// Returns true if method has conditional attribute and the conditions is not defined (method is excluded).
3761 public bool IsExcluded (EmitContext ec)
3763 if ((caching_flags & Flags.Excluded_Undetected) == 0)
3764 return (caching_flags & Flags.Excluded) != 0;
3766 caching_flags &= ~Flags.Excluded_Undetected;
3768 if (parent_method == null) {
3769 if (OptAttributes == null)
3772 Attribute[] attrs = OptAttributes.SearchMulti (TypeManager.conditional_attribute_type, ec);
3777 foreach (Attribute a in attrs) {
3778 string condition = a.GetConditionalAttributeValue (
3780 if (RootContext.AllDefines.Contains (condition))
3784 caching_flags |= Flags.Excluded;
3788 IMethodData md = TypeManager.GetMethod (parent_method);
3790 if (AttributeTester.IsConditionalMethodExcluded (parent_method)) {
3791 caching_flags |= Flags.Excluded;
3797 if (md.IsExcluded (ec)) {
3798 caching_flags |= Flags.Excluded;
3807 public abstract class ConstructorInitializer {
3808 ArrayList argument_list;
3809 protected ConstructorInfo parent_constructor;
3810 Parameters parameters;
3813 public ConstructorInitializer (ArrayList argument_list, Parameters parameters,
3816 this.argument_list = argument_list;
3817 this.parameters = parameters;
3821 public ArrayList Arguments {
3823 return argument_list;
3827 public bool Resolve (ConstructorBuilder caller_builder, EmitContext ec)
3829 Expression parent_constructor_group;
3832 ec.CurrentBlock = new ToplevelBlock (Block.Flags.Implicit, parameters, loc);
3834 if (argument_list != null){
3835 foreach (Argument a in argument_list){
3836 if (!a.Resolve (ec, loc))
3840 ec.CurrentBlock = null;
3842 if (this is ConstructorBaseInitializer) {
3843 if (ec.ContainerType.BaseType == null)
3846 t = ec.ContainerType.BaseType;
3847 if (ec.ContainerType.IsValueType) {
3848 Report.Error (522, loc,
3849 "structs cannot call base class constructors");
3853 t = ec.ContainerType;
3855 parent_constructor_group = Expression.MemberLookup (
3856 ec, t, ".ctor", MemberTypes.Constructor,
3857 BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
3860 if (parent_constructor_group == null){
3861 parent_constructor_group = Expression.MemberLookup (
3862 ec, t, ".ctor", MemberTypes.Constructor,
3863 BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly,
3866 if (parent_constructor_group != null)
3868 112, loc, "`{0}.{1}' is inaccessible due to " +
3869 "its protection level", t.FullName, t.Name);
3872 1501, loc, "Can not find a constructor for " +
3873 "this argument list");
3877 parent_constructor = (ConstructorInfo) Invocation.OverloadResolve (
3878 ec, (MethodGroupExpr) parent_constructor_group, argument_list,
3881 if (parent_constructor == null){
3882 Report.Error (1501, loc,
3883 "Can not find a constructor for this argument list");
3887 if (parent_constructor == caller_builder){
3888 Report.Error (516, String.Format ("Constructor `{0}' can not call itself", TypeManager.CSharpSignature (caller_builder)));
3895 public void Emit (EmitContext ec)
3897 if (parent_constructor != null){
3898 ec.Mark (loc, false);
3900 Invocation.EmitCall (ec, true, true, null, parent_constructor, argument_list, loc);
3902 Invocation.EmitCall (ec, true, false, ec.GetThis (loc), parent_constructor, argument_list, loc);
3907 /// Method search for base ctor. (We do not cache it).
3909 Constructor GetOverloadedConstructor (TypeContainer tc)
3911 if (tc.InstanceConstructors == null)
3914 foreach (Constructor c in tc.InstanceConstructors) {
3915 if (Arguments == null) {
3916 if (c.ParameterTypes.Length == 0)
3924 int count = c.ParameterInfo.Count;
3926 c.ParameterInfo.ParameterModifier (count - 1) == Parameter.Modifier.PARAMS) {
3927 for (int i = 0; i < count-1; i++)
3928 if (c.ParameterTypes [i] != ((Argument)Arguments [i]).Type) {
3933 if (c.ParameterTypes.Length != Arguments.Count)
3936 for (int i = 0; i < Arguments.Count; ++i)
3937 if (c.ParameterTypes [i] != ((Argument)Arguments [i]).Type) {
3952 //TODO: implement caching when it will be necessary
3953 public virtual void CheckObsoleteAttribute (TypeContainer tc, Location loc)
3955 Constructor ctor = GetOverloadedConstructor (tc);
3959 ObsoleteAttribute oa = ctor.GetObsoleteAttribute (tc);
3963 AttributeTester.Report_ObsoleteMessage (oa, ctor.GetSignatureForError (), loc);
3967 public class ConstructorBaseInitializer : ConstructorInitializer {
3968 public ConstructorBaseInitializer (ArrayList argument_list, Parameters pars, Location l) :
3969 base (argument_list, pars, l)
3973 public override void CheckObsoleteAttribute(TypeContainer tc, Location loc) {
3974 if (parent_constructor == null)
3977 TypeContainer type_ds = TypeManager.LookupTypeContainer (tc.TypeBuilder.BaseType);
3978 if (type_ds == null) {
3979 ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (parent_constructor);
3982 AttributeTester.Report_ObsoleteMessage (oa, TypeManager.CSharpSignature (parent_constructor), loc);
3987 base.CheckObsoleteAttribute (type_ds, loc);
3992 public class ConstructorThisInitializer : ConstructorInitializer {
3993 public ConstructorThisInitializer (ArrayList argument_list, Parameters pars, Location l) :
3994 base (argument_list, pars, l)
3999 public class Constructor : MethodCore, IMethodData {
4000 public ConstructorBuilder ConstructorBuilder;
4001 public ConstructorInitializer Initializer;
4002 ListDictionary declarative_security;
4005 // Modifiers allowed for a constructor.
4007 public const int AllowedModifiers =
4009 Modifiers.PROTECTED |
4010 Modifiers.INTERNAL |
4016 bool has_compliant_args = false;
4018 // The spec claims that static is not permitted, but
4019 // my very own code has static constructors.
4021 public Constructor (TypeContainer ds, string name, int mod, Parameters args,
4022 ConstructorInitializer init, Location l)
4023 : base (ds, null, mod, AllowedModifiers, false, new MemberName (name),
4029 public override string GetSignatureForError()
4031 if (ConstructorBuilder == null)
4032 return GetSignatureForError (Parent);
4034 return TypeManager.CSharpSignature (ConstructorBuilder);
4037 public bool HasCompliantArgs {
4039 return has_compliant_args;
4043 public override AttributeTargets AttributeTargets {
4045 return AttributeTargets.Constructor;
4051 // Returns true if this is a default constructor
4053 public bool IsDefault ()
4055 if ((ModFlags & Modifiers.STATIC) != 0)
4056 return (Parameters.FixedParameters == null ? true : Parameters.Empty) &&
4057 (Parameters.ArrayParameter == null ? true : Parameters.Empty);
4060 return (Parameters.FixedParameters == null ? true : Parameters.Empty) &&
4061 (Parameters.ArrayParameter == null ? true : Parameters.Empty) &&
4062 (Initializer is ConstructorBaseInitializer) &&
4063 (Initializer.Arguments == null);
4066 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
4068 if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
4069 if (declarative_security == null) {
4070 declarative_security = new ListDictionary ();
4072 a.ExtractSecurityPermissionSet (declarative_security);
4076 ConstructorBuilder.SetCustomAttribute (cb);
4079 protected override bool CheckForDuplications ()
4081 ArrayList ar = Parent.InstanceConstructors;
4083 int arLen = ar.Count;
4085 for (int i = 0; i < arLen; i++) {
4086 Constructor m = (Constructor) ar [i];
4087 if (IsDuplicateImplementation (m))
4094 protected override bool CheckBase ()
4096 // Check whether arguments were correct.
4097 if (!DoDefineParameters ())
4100 // TODO: skip the rest for generated ctor
4101 if ((ModFlags & Modifiers.STATIC) != 0)
4104 if (!CheckForDuplications ())
4107 if (Parent.Kind == Kind.Struct) {
4108 if (ParameterTypes.Length == 0) {
4109 Report.Error (568, Location,
4110 "Structs can not contain explicit parameterless " +
4115 if ((ModFlags & Modifiers.PROTECTED) != 0) {
4116 Report.Error (666, Location, "Protected member in struct declaration");
4121 if ((RootContext.WarningLevel >= 4) && ((Parent.ModFlags & Modifiers.SEALED) != 0 && (ModFlags & Modifiers.PROTECTED) != 0)) {
4122 Report.Warning (628, Location, "'{0}': new protected member declared in sealed class", GetSignatureForError (Parent));
4129 // Creates the ConstructorBuilder
4131 public override bool Define ()
4133 MethodAttributes ca = (MethodAttributes.RTSpecialName |
4134 MethodAttributes.SpecialName);
4136 if ((ModFlags & Modifiers.STATIC) != 0) {
4137 ca |= MethodAttributes.Static | MethodAttributes.Private;
4139 ca |= MethodAttributes.HideBySig;
4141 if ((ModFlags & Modifiers.PUBLIC) != 0)
4142 ca |= MethodAttributes.Public;
4143 else if ((ModFlags & Modifiers.PROTECTED) != 0){
4144 if ((ModFlags & Modifiers.INTERNAL) != 0)
4145 ca |= MethodAttributes.FamORAssem;
4147 ca |= MethodAttributes.Family;
4148 } else if ((ModFlags & Modifiers.INTERNAL) != 0)
4149 ca |= MethodAttributes.Assembly;
4150 else if (IsDefault ())
4151 ca |= MethodAttributes.Public;
4153 ca |= MethodAttributes.Private;
4156 // Check if arguments were correct.
4160 ConstructorBuilder = Parent.TypeBuilder.DefineConstructor (
4161 ca, CallingConventions,
4164 if ((ModFlags & Modifiers.UNSAFE) != 0)
4165 ConstructorBuilder.InitLocals = false;
4167 TypeManager.AddMethod (ConstructorBuilder, this);
4170 // HACK because System.Reflection.Emit is lame
4172 TypeManager.RegisterMethod (ConstructorBuilder, ParameterInfo, ParameterTypes);
4180 public override void Emit ()
4182 EmitContext ec = CreateEmitContext (null, null);
4185 // extern methods have no bodies
4187 if ((ModFlags & Modifiers.EXTERN) != 0) {
4188 if ((block != null) && ((ModFlags & Modifiers.EXTERN) != 0)) {
4190 179, Location, "External constructor `" +
4191 TypeManager.CSharpSignature (ConstructorBuilder) +
4192 "' can not have a body");
4195 } else if (block == null) {
4197 501, Location, "Constructor `" +
4198 TypeManager.CSharpSignature (ConstructorBuilder) +
4199 "' must declare a body since it is not marked extern");
4203 if ((ModFlags & Modifiers.STATIC) == 0){
4204 if (Parent.Kind == Kind.Class && Initializer == null)
4205 Initializer = new ConstructorBaseInitializer (
4206 null, Parameters.EmptyReadOnlyParameters, Location);
4210 // Spec mandates that Initializers will not have
4214 if (Initializer != null && !Initializer.Resolve (ConstructorBuilder, ec))
4216 ec.IsStatic = false;
4219 Parameters.LabelParameters (ec, ConstructorBuilder, Location);
4221 SourceMethod source = SourceMethod.Create (
4222 Parent, ConstructorBuilder, block);
4225 // Classes can have base initializers and instance field initializers.
4227 if (Parent.Kind == Kind.Class){
4228 if ((ModFlags & Modifiers.STATIC) == 0){
4231 // If we use a "this (...)" constructor initializer, then
4232 // do not emit field initializers, they are initialized in the other constructor
4234 if (!(Initializer != null && Initializer is ConstructorThisInitializer))
4235 Parent.EmitFieldInitializers (ec);
4238 if (Initializer != null) {
4239 if (GetObsoleteAttribute (Parent) == null && Parent.GetObsoleteAttribute (Parent.Parent) == null)
4240 Initializer.CheckObsoleteAttribute (Parent, Location);
4242 ec.TestObsoleteMethodUsage = false;
4243 Initializer.Emit (ec);
4246 if ((ModFlags & Modifiers.STATIC) != 0)
4247 Parent.EmitFieldInitializers (ec);
4249 if (OptAttributes != null)
4250 OptAttributes.Emit (ec, this);
4252 // If this is a non-static `struct' constructor and doesn't have any
4253 // initializer, it must initialize all of the struct's fields.
4254 if ((Parent.Kind == Kind.Struct) &&
4255 ((ModFlags & Modifiers.STATIC) == 0) && (Initializer == null))
4256 Block.AddThisVariable (Parent, Location);
4258 ec.EmitTopBlock (block, ParameterInfo, Location);
4261 source.CloseMethod ();
4265 if (declarative_security != null) {
4266 foreach (DictionaryEntry de in declarative_security) {
4267 ConstructorBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
4274 // Is never override
4275 protected override MethodInfo FindOutParentMethod (TypeContainer container, ref Type parent_ret_type)
4280 protected override bool VerifyClsCompliance (DeclSpace ds)
4282 if (!base.VerifyClsCompliance (ds) || !IsExposedFromAssembly (ds)) {
4286 if (parameter_types.Length > 0) {
4287 ArrayList al = (ArrayList)ds.MemberCache.Members [".ctor"];
4289 ds.MemberCache.VerifyClsParameterConflict (al, this, ConstructorBuilder);
4291 if (ds.TypeBuilder.IsSubclassOf (TypeManager.attribute_type)) {
4292 foreach (Type param in parameter_types) {
4293 if (param.IsArray) {
4299 has_compliant_args = true;
4303 #region IMethodData Members
4305 public System.Reflection.CallingConventions CallingConventions {
4307 CallingConventions cc = Parameters.GetCallingConvention ();
4309 if (Parent.Kind == Kind.Class)
4310 if ((ModFlags & Modifiers.STATIC) == 0)
4311 cc |= CallingConventions.HasThis;
4313 // FIXME: How is `ExplicitThis' used in C#?
4319 public new Location Location {
4321 return base.Location;
4325 public MemberName MethodName {
4331 public Type ReturnType {
4337 public EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig)
4339 ILGenerator ig_ = ConstructorBuilder.GetILGenerator ();
4340 return new EmitContext (Parent, Location, ig_, null, ModFlags, true);
4343 public ObsoleteAttribute GetObsoleteAttribute ()
4348 public bool IsExcluded(EmitContext ec)
4357 /// Interface for MethodData class. Holds links to parent members to avoid member duplication.
4359 public interface IMethodData
4361 CallingConventions CallingConventions { get; }
4362 Location Location { get; }
4363 MemberName MethodName { get; }
4364 Type[] ParameterTypes { get; }
4365 Type ReturnType { get; }
4367 Attributes OptAttributes { get; }
4368 ToplevelBlock Block { get; }
4370 EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig);
4371 ObsoleteAttribute GetObsoleteAttribute ();
4372 string GetSignatureForError (TypeContainer tc);
4373 bool IsExcluded (EmitContext ec);
4374 bool IsClsCompliaceRequired (DeclSpace ds);
4378 // Encapsulates most of the Method's state
4380 public class MethodData {
4382 readonly IMethodData method;
4385 // The return type of this method
4387 public readonly InternalParameters ParameterInfo;
4390 // Are we implementing an interface ?
4392 public bool IsImplementing = false;
4397 protected MemberBase member;
4398 protected int modifiers;
4399 protected MethodAttributes flags;
4401 MethodBuilder builder = null;
4402 public MethodBuilder MethodBuilder {
4408 public MethodData (MemberBase member, InternalParameters parameters,
4409 int modifiers, MethodAttributes flags, IMethodData method)
4411 this.member = member;
4412 this.ParameterInfo = parameters;
4413 this.modifiers = modifiers;
4416 this.method = method;
4419 public bool Define (TypeContainer container)
4421 MethodInfo implementing = null;
4423 string name = method.MethodName.Name;
4424 string method_name = name;
4426 Type[] ParameterTypes = method.ParameterTypes;
4428 if (container.Pending != null){
4429 if (member is Indexer)
4430 implementing = container.Pending.IsInterfaceIndexer (
4431 member.InterfaceType, method.ReturnType, ParameterTypes);
4433 implementing = container.Pending.IsInterfaceMethod (
4434 member.InterfaceType, name, method.ReturnType, ParameterTypes);
4436 if (member.InterfaceType != null){
4437 if (implementing == null){
4438 Report.Error (539, method.Location,
4439 "'{0}' in explicit interface declaration is not an interface", method_name);
4442 method_name = member.InterfaceType.FullName + "." + name;
4447 // For implicit implementations, make sure we are public, for
4448 // explicit implementations, make sure we are private.
4450 if (implementing != null){
4452 // Setting null inside this block will trigger a more
4453 // verbose error reporting for missing interface implementations
4455 // The "candidate" function has been flagged already
4456 // but it wont get cleared
4458 if (member.IsExplicitImpl){
4459 if ((modifiers & (Modifiers.PUBLIC | Modifiers.ABSTRACT | Modifiers.VIRTUAL)) != 0){
4460 Modifiers.Error_InvalidModifier (method.Location, "public, virtual or abstract");
4461 implementing = null;
4463 } else if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public){
4464 if (TypeManager.IsInterfaceType (implementing.DeclaringType)){
4466 // If this is an interface method implementation,
4467 // check for public accessibility
4469 implementing = null;
4470 } else if ((flags & MethodAttributes.MemberAccessMask) == MethodAttributes.Private){
4471 // We may never be private.
4472 implementing = null;
4473 } else if ((modifiers & Modifiers.OVERRIDE) == 0){
4475 // We may be protected if we're overriding something.
4477 implementing = null;
4482 // Static is not allowed
4484 if ((modifiers & Modifiers.STATIC) != 0){
4485 implementing = null;
4486 Modifiers.Error_InvalidModifier (method.Location, "static");
4491 // If implementing is still valid, set flags
4493 if (implementing != null){
4495 // When implementing interface methods, set NewSlot
4496 // unless, we are overwriting a method.
4498 if (implementing.DeclaringType.IsInterface){
4499 if ((modifiers & Modifiers.OVERRIDE) == 0)
4500 flags |= MethodAttributes.NewSlot;
4503 MethodAttributes.Virtual |
4504 MethodAttributes.HideBySig;
4506 // Set Final unless we're virtual, abstract or already overriding a method.
4507 if ((modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE)) == 0)
4508 flags |= MethodAttributes.Final;
4510 IsImplementing = true;
4513 EmitContext ec = method.CreateEmitContext (container, null);
4515 DefineMethodBuilder (ec, container, method_name, ParameterTypes);
4517 if (builder == null)
4520 if ((modifiers & Modifiers.UNSAFE) != 0)
4521 builder.InitLocals = false;
4523 if (IsImplementing){
4525 // clear the pending implemntation flag
4527 if (member is Indexer) {
4528 container.Pending.ImplementIndexer (
4529 member.InterfaceType, builder, method.ReturnType,
4530 ParameterTypes, member.IsExplicitImpl);
4532 container.Pending.ImplementMethod (
4533 member.InterfaceType, name, method.ReturnType,
4534 ParameterTypes, member.IsExplicitImpl);
4536 if (member.IsExplicitImpl)
4537 container.TypeBuilder.DefineMethodOverride (
4538 builder, implementing);
4542 TypeManager.RegisterMethod (builder, ParameterInfo, ParameterTypes);
4543 TypeManager.AddMethod (builder, method);
4550 /// Create the MethodBuilder for the method
4552 void DefineMethodBuilder (EmitContext ec, TypeContainer container, string method_name, Type[] ParameterTypes)
4554 const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
4556 if ((modifiers & extern_static) == extern_static) {
4558 if (method.OptAttributes != null) {
4559 Attribute dllimport_attribute = method.OptAttributes.Search (TypeManager.dllimport_type, ec);
4560 if (dllimport_attribute != null) {
4561 flags |= MethodAttributes.PinvokeImpl;
4562 builder = dllimport_attribute.DefinePInvokeMethod (
4563 ec, container.TypeBuilder, method_name, flags,
4564 method.ReturnType, ParameterTypes);
4570 // for extern static method must be specified either DllImport attribute or MethodImplAttribute.
4571 // We are more strict than Microsoft and report CS0626 like error
4572 if (method.OptAttributes == null ||
4573 !method.OptAttributes.Contains (TypeManager.methodimpl_attr_type, ec)) {
4574 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));
4579 builder = container.TypeBuilder.DefineMethod (
4580 method_name, flags, method.CallingConventions,
4581 method.ReturnType, ParameterTypes);
4587 public void Emit (TypeContainer container, Attributable kind)
4590 if ((flags & MethodAttributes.PinvokeImpl) == 0)
4591 ec = method.CreateEmitContext (container, builder.GetILGenerator ());
4593 ec = method.CreateEmitContext (container, null);
4595 if (method.GetObsoleteAttribute () != null || container.GetObsoleteAttribute (container.Parent) != null)
4596 ec.TestObsoleteMethodUsage = false;
4598 Location loc = method.Location;
4599 Attributes OptAttributes = method.OptAttributes;
4601 if (OptAttributes != null)
4602 OptAttributes.Emit (ec, kind);
4604 if (member is MethodCore)
4605 ((MethodCore) member).Parameters.LabelParameters (ec, MethodBuilder, loc);
4607 SymbolWriter sw = CodeGen.SymbolWriter;
4608 ToplevelBlock block = method.Block;
4611 // abstract or extern methods have no bodies
4613 if ((modifiers & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0){
4618 // abstract or extern methods have no bodies.
4620 if ((modifiers & Modifiers.ABSTRACT) != 0)
4622 500, method.Location, "Abstract method `" +
4623 TypeManager.CSharpSignature (builder) +
4624 "' can not have a body");
4626 if ((modifiers & Modifiers.EXTERN) != 0)
4628 179, method.Location, "External method `" +
4629 TypeManager.CSharpSignature (builder) +
4630 "' can not have a body");
4636 // Methods must have a body unless they're extern or abstract
4638 if (block == null) {
4640 501, method.Location, "Method `" +
4641 TypeManager.CSharpSignature (builder) +
4642 "' must declare a body since it is not marked " +
4643 "abstract or extern");
4647 SourceMethod source = SourceMethod.Create (
4648 container, MethodBuilder, method.Block);
4651 // Handle destructors specially
4653 // FIXME: This code generates buggy code
4655 if (member is Destructor)
4656 EmitDestructor (ec, block);
4658 ec.EmitTopBlock (block, ParameterInfo, loc);
4661 source.CloseMethod ();
4664 void EmitDestructor (EmitContext ec, ToplevelBlock block)
4666 ILGenerator ig = ec.ig;
4668 Label finish = ig.DefineLabel ();
4670 block.SetDestructor ();
4672 ig.BeginExceptionBlock ();
4673 ec.ReturnLabel = finish;
4674 ec.HasReturnLabel = true;
4675 ec.EmitTopBlock (block, null, method.Location);
4677 // ig.MarkLabel (finish);
4678 ig.BeginFinallyBlock ();
4680 if (ec.ContainerType.BaseType != null) {
4681 Expression member_lookup = Expression.MemberLookup (
4682 ec, ec.ContainerType.BaseType, null, ec.ContainerType.BaseType,
4683 "Finalize", MemberTypes.Method, Expression.AllBindingFlags, method.Location);
4685 if (member_lookup != null){
4686 MethodGroupExpr parent_destructor = ((MethodGroupExpr) member_lookup);
4688 ig.Emit (OpCodes.Ldarg_0);
4689 ig.Emit (OpCodes.Call, (MethodInfo) parent_destructor.Methods [0]);
4693 ig.EndExceptionBlock ();
4694 //ig.MarkLabel (ec.ReturnLabel);
4695 ig.Emit (OpCodes.Ret);
4699 public class Destructor : Method {
4701 public Destructor (TypeContainer ds, Expression return_type, int mod,
4702 string name, Parameters parameters, Attributes attrs,
4704 : base (ds, return_type, mod, false, new MemberName (name),
4705 parameters, attrs, l)
4708 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
4710 if (a.Type == TypeManager.conditional_attribute_type) {
4711 Report.Error (577, Location, "Conditional not valid on '{0}' because it is a destructor, operator, or explicit interface implementation", GetSignatureForError ());
4715 base.ApplyAttributeBuilder (a, cb);
4719 abstract public class MemberBase : MemberCore {
4720 public Expression Type;
4722 public MethodAttributes flags;
4724 protected readonly int explicit_mod_flags;
4727 // The "short" name of this property / indexer / event. This is the
4728 // name without the explicit interface.
4730 public string ShortName;
4733 // The type of this property / indexer / event
4735 public Type MemberType;
4738 // If true, this is an explicit interface implementation
4740 public bool IsExplicitImpl = false;
4743 // The name of the interface we are explicitly implementing
4745 public MemberName ExplicitInterfaceName = null;
4748 // Whether this is an interface member.
4750 public bool IsInterface;
4753 // If true, the interface type we are explicitly implementing
4755 public Type InterfaceType = null;
4758 // The constructor is only exposed to our children
4760 protected MemberBase (TypeContainer parent, Expression type, int mod,
4761 int allowed_mod, int def_mod, MemberName name,
4762 Attributes attrs, Location loc)
4763 : base (parent, name, attrs, loc)
4765 explicit_mod_flags = mod;
4767 ModFlags = Modifiers.Check (allowed_mod, mod, def_mod, loc);
4769 // Check for explicit interface implementation
4770 if (MemberName.Left != null) {
4771 ExplicitInterfaceName = MemberName.Left;
4772 ShortName = MemberName.Name;
4773 IsExplicitImpl = true;
4778 protected virtual bool CheckBase ()
4780 if ((ModFlags & Modifiers.PROTECTED) != 0 && Parent.Kind == Kind.Struct) {
4781 Report.Error (666, Location, "Protected member in struct declaration");
4785 if ((RootContext.WarningLevel >= 4) &&
4786 ((Parent.ModFlags & Modifiers.SEALED) != 0) &&
4787 ((ModFlags & Modifiers.PROTECTED) != 0) &&
4788 ((ModFlags & Modifiers.OVERRIDE) == 0) && (Name != "Finalize")) {
4789 Report.Warning (628, Location, "'{0}': new protected member declared in sealed class", GetSignatureForError (Parent));
4794 protected virtual bool CheckParameters (DeclSpace ds, Type [] parameters)
4798 foreach (Type partype in parameters){
4799 if (partype == TypeManager.void_type) {
4801 1547, Location, "Keyword 'void' cannot " +
4802 "be used in this context");
4806 if (partype.IsPointer){
4809 if (!TypeManager.VerifyUnManaged (TypeManager.GetElementType (partype), Location))
4813 if (ds.AsAccessible (partype, ModFlags))
4816 if (this is Indexer)
4817 Report.Error (55, Location,
4818 "Inconsistent accessibility: parameter type `" +
4819 TypeManager.CSharpName (partype) + "' is less " +
4820 "accessible than indexer `" + Name + "'");
4821 else if ((this is Method) && ((Method) this).IsOperator)
4822 Report.Error (57, Location,
4823 "Inconsistent accessibility: parameter type `" +
4824 TypeManager.CSharpName (partype) + "' is less " +
4825 "accessible than operator `" + Name + "'");
4827 Report.Error (51, Location,
4828 "Inconsistent accessibility: parameter type `" +
4829 TypeManager.CSharpName (partype) + "' is less " +
4830 "accessible than method `" + Name + "'");
4837 protected virtual bool DoDefine ()
4839 EmitContext ec = Parent.EmitContext;
4841 throw new InternalErrorException ("MemberBase.DoDefine called too early");
4844 throw new InternalErrorException ();
4847 ModFlags = Modifiers.PUBLIC |
4848 Modifiers.ABSTRACT |
4849 Modifiers.VIRTUAL | (ModFlags & Modifiers.UNSAFE) | (ModFlags & Modifiers.NEW);
4851 flags = MethodAttributes.Public |
4852 MethodAttributes.Abstract |
4853 MethodAttributes.HideBySig |
4854 MethodAttributes.NewSlot |
4855 MethodAttributes.Virtual;
4857 if (!Parent.MethodModifiersValid (ModFlags, Name, Location))
4860 flags = Modifiers.MethodAttr (ModFlags);
4863 // Lookup Type, verify validity
4864 bool old_unsafe = ec.InUnsafe;
4865 ec.InUnsafe = InUnsafe;
4866 Type = Type.ResolveAsTypeTerminal (ec, false);
4867 ec.InUnsafe = old_unsafe;
4872 MemberType = Type.Type;
4874 if ((Parent.ModFlags & Modifiers.SEALED) != 0){
4875 if ((ModFlags & (Modifiers.VIRTUAL|Modifiers.ABSTRACT)) != 0){
4876 Report.Error (549, Location, "Virtual method can not be contained in sealed class");
4881 // verify accessibility
4882 if (!Parent.AsAccessible (MemberType, ModFlags)) {
4883 if (this is Property)
4884 Report.Error (53, Location,
4885 "Inconsistent accessibility: property type `" +
4886 TypeManager.CSharpName (MemberType) + "' is less " +
4887 "accessible than property `" + Name + "'");
4888 else if (this is Indexer)
4889 Report.Error (54, Location,
4890 "Inconsistent accessibility: indexer return type `" +
4891 TypeManager.CSharpName (MemberType) + "' is less " +
4892 "accessible than indexer `" + Name + "'");
4893 else if (this is Method) {
4894 if (((Method) this).IsOperator)
4895 Report.Error (56, Location,
4896 "Inconsistent accessibility: return type `" +
4897 TypeManager.CSharpName (MemberType) + "' is less " +
4898 "accessible than operator `" + Name + "'");
4900 Report.Error (50, Location,
4901 "Inconsistent accessibility: return type `" +
4902 TypeManager.CSharpName (MemberType) + "' is less " +
4903 "accessible than method `" + Name + "'");
4905 Report.Error (52, Location,
4906 "Inconsistent accessibility: field type `" +
4907 TypeManager.CSharpName (MemberType) + "' is less " +
4908 "accessible than field `" + Name + "'");
4912 if (MemberType.IsPointer && !UnsafeOK (Parent))
4915 if (IsExplicitImpl) {
4916 Expression expr = ExplicitInterfaceName.GetTypeExpression (Location);
4917 TypeExpr texpr = expr.ResolveAsTypeTerminal (ec, false);
4921 InterfaceType = texpr.ResolveType (ec);
4923 if (InterfaceType.IsClass) {
4924 Report.Error (538, Location, "'{0}' in explicit interface declaration is not an interface", ExplicitInterfaceName);
4929 // Compute the full name that we need to export.
4930 if (InterfaceType.FullName != ExplicitInterfaceName) {
4931 ExplicitInterfaceName = InterfaceType.FullName;
4932 UpdateMemberName ();
4936 if (!Parent.VerifyImplements (InterfaceType, ShortName, Name, Location))
4939 Modifiers.Check (Modifiers.AllowedExplicitImplFlags, explicit_mod_flags, 0, Location);
4946 /// The name of the member can be changed during definition (see IndexerName attribute)
4948 protected virtual void UpdateMemberName ()
4950 MemberName.Name = ShortName;
4953 public override string GetSignatureForError (TypeContainer tc)
4955 return String.Concat (tc.Name, '.', base.GetSignatureForError (tc));
4958 protected bool IsTypePermitted ()
4960 if (MemberType == TypeManager.arg_iterator_type || MemberType == TypeManager.typed_reference_type) {
4961 Report.Error (610, Location, "Field or property cannot be of type '{0}'", TypeManager.CSharpName (MemberType));
4967 protected override bool VerifyClsCompliance(DeclSpace ds)
4969 if (base.VerifyClsCompliance (ds)) {
4973 if (IsInterface && HasClsCompliantAttribute && ds.IsClsCompliaceRequired (ds)) {
4974 Report.Error (3010, Location, "'{0}': CLS-compliant interfaces must have only CLS-compliant members", GetSignatureForError ());
4979 protected override void VerifyObsoleteAttribute()
4981 CheckUsageOfObsoleteAttribute (MemberType);
4986 // Fields and Events both generate FieldBuilders, we use this to share
4987 // their common bits. This is also used to flag usage of the field
4989 abstract public class FieldBase : MemberBase {
4990 public FieldBuilder FieldBuilder;
4991 public Status status;
4994 public enum Status : byte {
4999 static string[] attribute_targets = new string [] { "field" };
5002 /// Symbol with same name in parent class/struct
5004 public MemberInfo conflict_symbol;
5007 // The constructor is only exposed to our children
5009 protected FieldBase (TypeContainer parent, Expression type, int mod,
5010 int allowed_mod, MemberName name, object init,
5011 Attributes attrs, Location loc)
5012 : base (parent, type, mod, allowed_mod, Modifiers.PRIVATE,
5018 public override AttributeTargets AttributeTargets {
5020 return AttributeTargets.Field;
5024 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
5026 if (a.Type == TypeManager.marshal_as_attr_type) {
5027 UnmanagedMarshal marshal = a.GetMarshal (this);
5028 if (marshal != null) {
5029 FieldBuilder.SetMarshal (marshal);
5034 if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
5035 a.Error_InvalidSecurityParent ();
5039 FieldBuilder.SetCustomAttribute (cb);
5043 // Whether this field has an initializer.
5045 public bool HasInitializer {
5047 return init != null;
5051 protected readonly Object init;
5054 Expression init_expr;
5055 bool init_expr_initialized = false;
5058 // Resolves and returns the field initializer.
5060 public Expression GetInitializerExpression (EmitContext ec)
5062 if (init_expr_initialized)
5066 if (init is Expression)
5067 e = (Expression) init;
5069 e = new ArrayCreation (Type, "", (ArrayList)init, Location);
5071 ec.IsFieldInitializer = true;
5072 e = e.DoResolve (ec);
5073 ec.IsFieldInitializer = false;
5076 init_expr_initialized = true;
5081 protected override bool CheckBase ()
5083 if (!base.CheckBase ())
5090 conflict_symbol = Parent.FindMemberWithSameName (Name, false);
5091 if (conflict_symbol == null) {
5092 if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) {
5093 Report.Warning (109, Location, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError (Parent));
5098 if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0) {
5099 Report.SymbolRelatedToPreviousError (conflict_symbol);
5100 Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent));
5106 protected override bool DoDefine ()
5108 if (!base.DoDefine ())
5111 if (MemberType == TypeManager.void_type) {
5112 Report.Error (1547, Location,
5113 "Keyword 'void' cannot be used in this context");
5119 public override string GetSignatureForError ()
5121 if (FieldBuilder == null) {
5122 return base.GetSignatureForError (Parent);
5124 return TypeManager.GetFullNameSignature (FieldBuilder);
5127 public override string[] ValidAttributeTargets {
5129 return attribute_targets;
5133 protected override bool VerifyClsCompliance (DeclSpace ds)
5135 if (!base.VerifyClsCompliance (ds))
5138 if (FieldBuilder == null) {
5142 if (!AttributeTester.IsClsCompliant (FieldBuilder.FieldType)) {
5143 Report.Error (3003, Location, "Type of '{0}' is not CLS-compliant", GetSignatureForError ());
5149 public void SetAssigned ()
5151 status |= Status.ASSIGNED;
5155 public abstract class FieldMember: FieldBase
5157 bool has_field_offset = false;
5159 protected FieldMember (TypeContainer parent, Expression type, int mod,
5160 int allowed_mod, MemberName name, object init, Attributes attrs, Location loc)
5161 : base (parent, type, mod, allowed_mod, name, init, attrs, loc)
5165 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
5167 if (a.Type == TypeManager.field_offset_attribute_type)
5169 has_field_offset = true;
5171 if (!Parent.HasExplicitLayout) {
5172 Report.Error (636, Location, "The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit)");
5176 if ((ModFlags & Modifiers.STATIC) != 0 || this is Const) {
5177 Report.Error (637, Location, "The FieldOffset attribute is not allowed on static or const fields");
5181 base.ApplyAttributeBuilder (a, cb);
5185 public override bool Define()
5187 EmitContext ec = Parent.EmitContext;
5189 throw new InternalErrorException ("FieldMember.Define called too early");
5191 bool old_unsafe = ec.InUnsafe;
5192 ec.InUnsafe = InUnsafe;
5193 TypeExpr texpr = Type.ResolveAsTypeTerminal (ec, false);
5197 MemberType = texpr.ResolveType (ec);
5198 ec.InUnsafe = old_unsafe;
5203 if (!Parent.AsAccessible (MemberType, ModFlags)) {
5204 Report.Error (52, Location,
5205 "Inconsistent accessibility: field type `" +
5206 TypeManager.CSharpName (MemberType) + "' is less " +
5207 "accessible than field `" + Name + "'");
5211 if (!IsTypePermitted ())
5214 if (MemberType.IsPointer && !UnsafeOK (Parent))
5220 public override void Emit ()
5222 if (Parent.HasExplicitLayout && !has_field_offset && (ModFlags & Modifiers.STATIC) == 0) {
5223 Report.Error (625, Location, "'{0}': Instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute.", GetSignatureForError ());
5231 // The Field class is used to represents class/struct fields during parsing.
5233 public class Field : FieldMember {
5235 // Modifiers allowed in a class declaration
5237 const int AllowedModifiers =
5240 Modifiers.PROTECTED |
5241 Modifiers.INTERNAL |
5244 Modifiers.VOLATILE |
5248 public Field (TypeContainer parent, Expression type, int mod, string name,
5249 Object expr_or_array_init, Attributes attrs, Location loc)
5250 : base (parent, type, mod, AllowedModifiers, new MemberName (name),
5251 expr_or_array_init, attrs, loc)
5255 public override bool Define ()
5257 if (!base.Define ())
5260 if (RootContext.WarningLevel > 1){
5261 Type ptype = Parent.TypeBuilder.BaseType;
5263 // ptype is only null for System.Object while compiling corlib.
5265 TypeContainer.FindMembers (
5266 ptype, MemberTypes.Method,
5267 BindingFlags.Public |
5268 BindingFlags.Static | BindingFlags.Instance,
5269 System.Type.FilterName, Name);
5273 if ((ModFlags & Modifiers.VOLATILE) != 0){
5274 if (!MemberType.IsClass){
5275 Type vt = MemberType;
5277 if (TypeManager.IsEnumType (vt))
5278 vt = TypeManager.EnumToUnderlying (MemberType);
5280 if (!((vt == TypeManager.bool_type) ||
5281 (vt == TypeManager.sbyte_type) ||
5282 (vt == TypeManager.byte_type) ||
5283 (vt == TypeManager.short_type) ||
5284 (vt == TypeManager.ushort_type) ||
5285 (vt == TypeManager.int32_type) ||
5286 (vt == TypeManager.uint32_type) ||
5287 (vt == TypeManager.char_type) ||
5288 (vt == TypeManager.float_type) ||
5289 (!vt.IsValueType))){
5291 677, Location, Parent.MakeName (Name) +
5292 " A volatile field can not be of type `" +
5293 TypeManager.CSharpName (vt) + "'");
5298 if ((ModFlags & Modifiers.READONLY) != 0){
5301 "A field can not be both volatile and readonly");
5306 FieldAttributes fa = Modifiers.FieldAttr (ModFlags);
5308 if (Parent.Kind == Kind.Struct &&
5309 ((fa & FieldAttributes.Static) == 0) &&
5310 MemberType == Parent.TypeBuilder &&
5311 !TypeManager.IsBuiltinType (MemberType)){
5312 Report.Error (523, Location, "Struct member `" + Parent.Name + "." + Name +
5313 "' causes a cycle in the structure layout");
5318 FieldBuilder = Parent.TypeBuilder.DefineField (
5319 Name, MemberType, Modifiers.FieldAttr (ModFlags));
5321 TypeManager.RegisterFieldBase (FieldBuilder, this);
5323 catch (ArgumentException) {
5324 Report.Warning (-24, Location, "The Microsoft runtime is unable to use [void|void*] as a field type, try using the Mono runtime.");
5331 public override void Emit ()
5333 if (OptAttributes != null) {
5334 EmitContext ec = new EmitContext (
5335 Parent, Location, null, FieldBuilder.FieldType,
5337 OptAttributes.Emit (ec, this);
5345 // `set' and `get' accessors are represented with an Accessor.
5347 public class Accessor {
5349 // Null if the accessor is empty, or a Block if not
5351 public const int AllowedModifiers =
5353 Modifiers.PROTECTED |
5354 Modifiers.INTERNAL |
5357 public ToplevelBlock Block;
5358 public Attributes Attributes;
5359 public Location Location;
5360 public int ModFlags;
5362 public Accessor (ToplevelBlock b, int mod, Attributes attrs, Location loc)
5367 ModFlags = Modifiers.Check (AllowedModifiers, mod, 0, loc);
5372 // Ooouh Martin, templates are missing here.
5373 // When it will be possible move here a lot of child code and template method type.
5374 public abstract class AbstractPropertyEventMethod: MemberCore, IMethodData {
5375 protected MethodData method_data;
5376 protected ToplevelBlock block;
5377 protected ListDictionary declarative_security;
5379 // The accessor are created event if they are not wanted.
5380 // But we need them because their names are reserved.
5381 // Field says whether accessor will be emited or not
5382 public readonly bool IsDummy;
5384 protected readonly string prefix;
5386 ReturnParameter return_attributes;
5388 public AbstractPropertyEventMethod (MemberBase member, string prefix)
5389 : base (null, SetupName (prefix, member), null, member.Location)
5391 this.prefix = prefix;
5395 public AbstractPropertyEventMethod (MemberBase member, Accessor accessor,
5397 : base (null, SetupName (prefix, member),
5398 accessor.Attributes, accessor.Location)
5400 this.prefix = prefix;
5401 this.block = accessor.Block;
5404 static MemberName SetupName (string prefix, MemberBase member)
5406 MemberName name = member.MemberName.Clone ();
5407 name.Name = prefix + member.ShortName;
5411 public void UpdateName (MemberBase member)
5413 MemberName.Name = prefix + member.ShortName;
5416 #region IMethodData Members
5418 public ToplevelBlock Block {
5428 public CallingConventions CallingConventions {
5430 return CallingConventions.Standard;
5434 public bool IsExcluded (EmitContext ec)
5439 public MemberName MethodName {
5445 public abstract ObsoleteAttribute GetObsoleteAttribute ();
5446 public abstract Type[] ParameterTypes { get; }
5447 public abstract Type ReturnType { get; }
5448 public abstract EmitContext CreateEmitContext(TypeContainer tc, ILGenerator ig);
5452 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
5454 if (a.Type == TypeManager.cls_compliant_attribute_type || a.Type == TypeManager.obsolete_attribute_type ||
5455 a.Type == TypeManager.conditional_attribute_type) {
5456 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 ());
5460 if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
5461 if (declarative_security == null)
5462 declarative_security = new ListDictionary ();
5463 a.ExtractSecurityPermissionSet (declarative_security);
5467 if (a.Target == AttributeTargets.Method) {
5468 method_data.MethodBuilder.SetCustomAttribute (cb);
5472 if (a.Target == AttributeTargets.ReturnValue) {
5473 if (return_attributes == null)
5474 return_attributes = new ReturnParameter (method_data.MethodBuilder, Location);
5476 return_attributes.ApplyAttributeBuilder (a, cb);
5480 ApplyToExtraTarget (a, cb);
5483 virtual protected void ApplyToExtraTarget (Attribute a, CustomAttributeBuilder cb)
5485 System.Diagnostics.Debug.Fail ("You forgot to define special attribute target handling");
5488 public override bool Define()
5490 throw new NotSupportedException ();
5493 public virtual void Emit (TypeContainer container)
5495 method_data.Emit (container, this);
5497 if (declarative_security != null) {
5498 foreach (DictionaryEntry de in declarative_security) {
5499 method_data.MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
5506 public override bool IsClsCompliaceRequired(DeclSpace ds)
5511 public bool IsDuplicateImplementation (MethodCore method)
5513 if (Name != method.Name)
5516 Type[] param_types = method.ParameterTypes;
5518 if (param_types.Length != ParameterTypes.Length)
5521 for (int i = 0; i < param_types.Length; i++)
5522 if (param_types [i] != ParameterTypes [i])
5525 Report.SymbolRelatedToPreviousError (method);
5526 Report.Error (111, Location, TypeContainer.Error111, method.Parent.GetSignatureForError (), Name);
5530 public new Location Location {
5532 return base.Location;
5536 protected override void VerifyObsoleteAttribute()
5543 // Properties and Indexers both generate PropertyBuilders, we use this to share
5544 // their common bits.
5546 abstract public class PropertyBase : MethodCore {
5548 public class GetMethod: PropertyMethod
5550 static string[] attribute_targets = new string [] { "method", "return" };
5552 public GetMethod (MethodCore method):
5553 base (method, "get_")
5557 public GetMethod (MethodCore method, Accessor accessor):
5558 base (method, accessor, "get_")
5562 public override MethodBuilder Define(TypeContainer container)
5564 base.Define (container);
5566 method_data = new MethodData (method, method.ParameterInfo, ModFlags, flags, this);
5568 if (!method_data.Define (container))
5571 return method_data.MethodBuilder;
5574 public override string GetSignatureForError (TypeContainer tc)
5576 return String.Concat (base.GetSignatureForError (tc), ".get");
5579 public override Type ReturnType {
5581 return method.MemberType;
5585 public override string[] ValidAttributeTargets {
5587 return attribute_targets;
5592 public class SetMethod: PropertyMethod {
5594 static string[] attribute_targets = new string [] { "method", "param", "return" };
5595 ImplicitParameter param_attr;
5597 public SetMethod (MethodCore method):
5598 base (method, "set_")
5602 public SetMethod (MethodCore method, Accessor accessor):
5603 base (method, accessor, "set_")
5607 protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
5609 if (a.Target == AttributeTargets.Parameter) {
5610 if (param_attr == null)
5611 param_attr = new ImplicitParameter (method_data.MethodBuilder);
5613 param_attr.ApplyAttributeBuilder (a, cb);
5617 base.ApplyAttributeBuilder (a, cb);
5620 protected virtual InternalParameters GetParameterInfo (EmitContext ec)
5622 Parameter [] parms = new Parameter [1];
5623 parms [0] = new Parameter (method.Type, "value", Parameter.Modifier.NONE, null);
5624 Parameters parameters = new Parameters (parms, null, method.Location);
5625 Type [] types = parameters.GetParameterInfo (ec);
5626 return new InternalParameters (types, parameters);
5629 public override MethodBuilder Define(TypeContainer container)
5631 if (container.EmitContext == null)
5632 throw new InternalErrorException ("SetMethod.Define called too early");
5634 base.Define (container);
5636 method_data = new MethodData (method, GetParameterInfo (container.EmitContext), ModFlags, flags, this);
5638 if (!method_data.Define (container))
5641 return method_data.MethodBuilder;
5644 public override string GetSignatureForError (TypeContainer tc)
5646 return String.Concat (base.GetSignatureForError (tc), ".set");
5649 public override Type[] ParameterTypes {
5651 return new Type[] { method.MemberType };
5655 public override Type ReturnType {
5657 return TypeManager.void_type;
5661 public override string[] ValidAttributeTargets {
5663 return attribute_targets;
5668 static string[] attribute_targets = new string [] { "property" };
5670 public abstract class PropertyMethod: AbstractPropertyEventMethod
5672 protected readonly MethodCore method;
5673 protected MethodAttributes flags;
5675 public PropertyMethod (MethodCore method, string prefix)
5676 : base (method, prefix)
5678 this.method = method;
5681 public PropertyMethod (MethodCore method, Accessor accessor,
5683 : base (method, accessor, prefix)
5685 this.method = method;
5686 this.ModFlags = accessor.ModFlags;
5688 if (accessor.ModFlags != 0 && RootContext.Version == LanguageVersion.ISO_1) {
5689 Report.FeatureIsNotStandardized (Location, "accessor modifiers");
5690 Environment.Exit (1);
5694 public override AttributeTargets AttributeTargets {
5696 return AttributeTargets.Method;
5700 public override bool IsClsCompliaceRequired(DeclSpace ds)
5702 return method.IsClsCompliaceRequired (ds);
5705 public InternalParameters ParameterInfo
5708 return method_data.ParameterInfo;
5712 public virtual MethodBuilder Define (TypeContainer container)
5715 // Check for custom access modifier
5717 if (ModFlags == 0) {
5718 ModFlags = method.ModFlags;
5719 flags = method.flags;
5721 CheckModifiers (container, ModFlags);
5722 ModFlags |= (method.ModFlags & (~Modifiers.Accessibility));
5723 flags = Modifiers.MethodAttr (ModFlags);
5724 flags |= (method.flags & (~MethodAttributes.MemberAccessMask));
5731 public override Type[] ParameterTypes {
5733 return TypeManager.NoTypes;
5737 public override EmitContext CreateEmitContext (TypeContainer tc,
5740 return new EmitContext (
5741 tc, method.Parent, method.Location, ig, ReturnType,
5742 method.ModFlags, false);
5745 public override ObsoleteAttribute GetObsoleteAttribute ()
5747 return method.GetObsoleteAttribute (method.Parent);
5750 public override string GetSignatureForError (TypeContainer tc)
5752 return String.Concat (tc.Name, '.', method.Name);
5755 void CheckModifiers (TypeContainer container, int modflags)
5758 int mflags = method.ModFlags & Modifiers.Accessibility;
5760 if ((mflags & Modifiers.PUBLIC) != 0) {
5761 flags |= Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE;
5763 else if ((mflags & Modifiers.PROTECTED) != 0) {
5764 if ((mflags & Modifiers.INTERNAL) != 0)
5765 flags |= Modifiers.PROTECTED | Modifiers.INTERNAL;
5767 flags |= Modifiers.PRIVATE;
5769 else if ((mflags & Modifiers.INTERNAL) != 0)
5770 flags |= Modifiers.PRIVATE;
5772 if ((mflags == modflags) || (modflags & (~flags)) != 0)
5773 Report.Error (273, Location, "{0}: accessibility modifier must be more restrictive than the property or indexer",
5774 GetSignatureForError (container));
5780 public PropertyMethod Get, Set;
5781 public PropertyBuilder PropertyBuilder;
5782 public MethodBuilder GetBuilder, SetBuilder;
5784 protected EmitContext ec;
5786 public PropertyBase (TypeContainer ds, Expression type, int mod_flags,
5787 int allowed_mod, bool is_iface, MemberName name,
5788 Parameters parameters, Attributes attrs,
5790 : base (ds, type, mod_flags, allowed_mod, is_iface, name,
5791 attrs, parameters, loc)
5795 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
5797 if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
5798 a.Error_InvalidSecurityParent ();
5802 PropertyBuilder.SetCustomAttribute (cb);
5805 public override AttributeTargets AttributeTargets {
5807 return AttributeTargets.Property;
5811 public override bool Define ()
5816 if (!IsTypePermitted ())
5822 protected override bool DoDefine ()
5824 if (!base.DoDefine ())
5828 // Accessors modifiers check
5830 if (Get.ModFlags != 0 && Set.ModFlags != 0) {
5831 Report.Error (274, Location, "'{0}': cannot specify accessibility modifiers for both accessors of the property or indexer.",
5832 GetSignatureForError ());
5836 if ((Get.IsDummy || Set.IsDummy)
5837 && (Get.ModFlags != 0 || Set.ModFlags != 0) && (ModFlags & Modifiers.OVERRIDE) == 0) {
5838 Report.Error (276, Location,
5839 "'{0}': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor.",
5840 GetSignatureForError ());
5844 if (MemberType.IsAbstract && MemberType.IsSealed) {
5845 Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
5849 ec = new EmitContext (Parent, Location, null, MemberType, ModFlags);
5853 public override string GetSignatureForError()
5855 if (PropertyBuilder == null)
5856 return GetSignatureForError (Parent);
5858 return TypeManager.CSharpSignature (PropertyBuilder, false);
5862 protected override bool CheckForDuplications ()
5864 ArrayList ar = Parent.Indexers;
5866 int arLen = ar.Count;
5868 for (int i = 0; i < arLen; i++) {
5869 Indexer m = (Indexer) ar [i];
5870 if (IsDuplicateImplementation (m))
5875 ar = Parent.Properties;
5877 int arLen = ar.Count;
5879 for (int i = 0; i < arLen; i++) {
5880 Property m = (Property) ar [i];
5881 if (IsDuplicateImplementation (m))
5889 // TODO: rename to Resolve......
5890 protected override MethodInfo FindOutParentMethod (TypeContainer container, ref Type parent_ret_type)
5892 PropertyInfo parent_property = container.ParentCache.FindMemberToOverride (
5893 container.TypeBuilder, Name, ParameterTypes, true) as PropertyInfo;
5895 if (parent_property == null)
5898 parent_ret_type = parent_property.PropertyType;
5899 MethodInfo get_accessor = parent_property.GetGetMethod (true);
5900 MethodInfo set_accessor = parent_property.GetSetMethod (true);
5901 MethodAttributes get_accessor_access, set_accessor_access;
5903 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
5904 if (Get != null && !Get.IsDummy && get_accessor == null) {
5905 Report.SymbolRelatedToPreviousError (parent_property);
5906 Report.Error (545, Location, "'{0}': cannot override because '{1}' does not have an overridable get accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (parent_property));
5909 if (Set != null && !Set.IsDummy && set_accessor == null) {
5910 Report.SymbolRelatedToPreviousError (parent_property);
5911 Report.Error (546, Location, "'{0}': cannot override because '{1}' does not have an overridable set accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (parent_property));
5916 // Check parent accessors access
5918 get_accessor_access = set_accessor_access = 0;
5919 if ((ModFlags & Modifiers.NEW) == 0) {
5920 if (get_accessor != null) {
5921 MethodAttributes get_flags = Modifiers.MethodAttr (Get.ModFlags != 0 ? Get.ModFlags : ModFlags);
5922 get_accessor_access = (get_accessor.Attributes & MethodAttributes.MemberAccessMask);
5924 if (!Get.IsDummy && !CheckAccessModifiers (get_flags & MethodAttributes.MemberAccessMask, get_accessor_access, get_accessor))
5925 Report.Error (507, Location, "'{0}' can't change the access modifiers when overriding inherited member '{1}'",
5926 GetSignatureForError (), TypeManager.GetFullNameSignature (parent_property));
5929 if (set_accessor != null) {
5930 MethodAttributes set_flags = Modifiers.MethodAttr (Set.ModFlags != 0 ? Set.ModFlags : ModFlags);
5931 set_accessor_access = (set_accessor.Attributes & MethodAttributes.MemberAccessMask);
5933 if (!Set.IsDummy && !CheckAccessModifiers (set_flags & MethodAttributes.MemberAccessMask, set_accessor_access, set_accessor))
5934 Report.Error (507, Location, "'{0}' can't change the access modifiers when overriding inherited member '{1}'",
5935 GetSignatureForError (container), TypeManager.GetFullNameSignature (parent_property));
5940 // Get the less restrictive access
5942 return get_accessor_access > set_accessor_access ? get_accessor : set_accessor;
5945 public override void Emit ()
5948 // The PropertyBuilder can be null for explicit implementations, in that
5949 // case, we do not actually emit the ".property", so there is nowhere to
5950 // put the attribute
5952 if (PropertyBuilder != null && OptAttributes != null)
5953 OptAttributes.Emit (ec, this);
5965 /// Tests whether accessors are not in collision with some method (CS0111)
5967 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
5969 return Get.IsDuplicateImplementation (mc) || Set.IsDuplicateImplementation (mc);
5972 protected override void UpdateMemberName ()
5974 base.UpdateMemberName ();
5976 Get.UpdateName (this);
5977 Set.UpdateName (this);
5981 public override string[] ValidAttributeTargets {
5983 return attribute_targets;
5988 public class Property : PropertyBase, IIteratorContainer {
5989 const int AllowedModifiers =
5992 Modifiers.PROTECTED |
5993 Modifiers.INTERNAL |
5997 Modifiers.OVERRIDE |
5998 Modifiers.ABSTRACT |
6001 Modifiers.METHOD_YIELDS |
6004 const int AllowedInterfaceModifiers =
6007 public Property (TypeContainer ds, Expression type, int mod, bool is_iface,
6008 MemberName name, Attributes attrs, Accessor get_block,
6009 Accessor set_block, Location loc)
6010 : base (ds, type, mod,
6011 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
6012 is_iface, name, Parameters.EmptyReadOnlyParameters, attrs,
6015 if (get_block == null)
6016 Get = new GetMethod (this);
6018 Get = new GetMethod (this, get_block);
6020 if (set_block == null)
6021 Set = new SetMethod (this);
6023 Set = new SetMethod (this, set_block);
6026 public override bool Define ()
6028 if (!base.Define ())
6034 flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
6038 GetBuilder = Get.Define (Parent);
6039 if (GetBuilder == null)
6043 // Setup iterator if we are one
6045 if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
6046 Iterator iterator = new Iterator (
6047 Parent, "get", MemberType,
6048 TypeManager.NoTypes, Get.ParameterInfo,
6049 ModFlags, Get.Block, Location);
6051 if (!iterator.DefineIterator ())
6053 Get.Block = iterator.Block;
6058 SetBuilder = Set.Define (Parent);
6059 if (SetBuilder == null)
6062 SetBuilder.DefineParameter (1, ParameterAttributes.None, "value");
6065 // FIXME - PropertyAttributes.HasDefault ?
6067 PropertyAttributes prop_attr = PropertyAttributes.None;
6069 prop_attr |= PropertyAttributes.RTSpecialName |
6070 PropertyAttributes.SpecialName;
6072 PropertyBuilder = Parent.TypeBuilder.DefineProperty (
6073 Name, prop_attr, MemberType, null);
6076 PropertyBuilder.SetGetMethod (GetBuilder);
6079 PropertyBuilder.SetSetMethod (SetBuilder);
6081 TypeManager.RegisterProperty (PropertyBuilder, GetBuilder, SetBuilder);
6085 public void SetYields ()
6087 ModFlags |= Modifiers.METHOD_YIELDS;
6092 /// Gigantic workaround for lameness in SRE follows :
6093 /// This class derives from EventInfo and attempts to basically
6094 /// wrap around the EventBuilder so that FindMembers can quickly
6095 /// return this in it search for members
6097 public class MyEventBuilder : EventInfo {
6100 // We use this to "point" to our Builder which is
6101 // not really a MemberInfo
6103 EventBuilder MyBuilder;
6106 // We "catch" and wrap these methods
6108 MethodInfo raise, remove, add;
6110 EventAttributes attributes;
6111 Type declaring_type, reflected_type, event_type;
6116 public MyEventBuilder (Event ev, TypeBuilder type_builder, string name, EventAttributes event_attr, Type event_type)
6118 MyBuilder = type_builder.DefineEvent (name, event_attr, event_type);
6120 // And now store the values in our own fields.
6122 declaring_type = type_builder;
6124 reflected_type = type_builder;
6126 attributes = event_attr;
6129 this.event_type = event_type;
6133 // Methods that you have to override. Note that you only need
6134 // to "implement" the variants that take the argument (those are
6135 // the "abstract" methods, the others (GetAddMethod()) are
6138 public override MethodInfo GetAddMethod (bool nonPublic)
6143 public override MethodInfo GetRemoveMethod (bool nonPublic)
6148 public override MethodInfo GetRaiseMethod (bool nonPublic)
6154 // These methods make "MyEventInfo" look like a Builder
6156 public void SetRaiseMethod (MethodBuilder raiseMethod)
6158 raise = raiseMethod;
6159 MyBuilder.SetRaiseMethod (raiseMethod);
6162 public void SetRemoveOnMethod (MethodBuilder removeMethod)
6164 remove = removeMethod;
6165 MyBuilder.SetRemoveOnMethod (removeMethod);
6168 public void SetAddOnMethod (MethodBuilder addMethod)
6171 MyBuilder.SetAddOnMethod (addMethod);
6174 public void SetCustomAttribute (CustomAttributeBuilder cb)
6176 MyBuilder.SetCustomAttribute (cb);
6179 public override object [] GetCustomAttributes (bool inherit)
6181 // FIXME : There's nothing which can be seemingly done here because
6182 // we have no way of getting at the custom attribute objects of the
6187 public override object [] GetCustomAttributes (Type t, bool inherit)
6189 // FIXME : Same here !
6193 public override bool IsDefined (Type t, bool b)
6198 public override EventAttributes Attributes {
6204 public override string Name {
6210 public override Type DeclaringType {
6212 return declaring_type;
6216 public override Type ReflectedType {
6218 return reflected_type;
6222 public Type EventType {
6228 public void SetUsed ()
6230 if (my_event != null)
6231 my_event.status = (FieldBase.Status.ASSIGNED | FieldBase.Status.USED);
6236 /// For case when event is declared like property (with add and remove accessors).
6238 public class EventProperty: Event {
6240 static string[] attribute_targets = new string [] { "event", "property" };
6242 public EventProperty (TypeContainer parent, Expression type, int mod_flags,
6243 bool is_iface, MemberName name, Object init,
6244 Attributes attrs, Accessor add, Accessor remove,
6246 : base (parent, type, mod_flags, is_iface, name, init, attrs, loc)
6248 Add = new AddDelegateMethod (this, add);
6249 Remove = new RemoveDelegateMethod (this, remove);
6252 public override string[] ValidAttributeTargets {
6254 return attribute_targets;
6260 /// Event is declared like field.
6262 public class EventField: Event {
6264 static string[] attribute_targets = new string [] { "event", "field", "method" };
6265 static string[] attribute_targets_interface = new string[] { "event", "method" };
6267 public EventField (TypeContainer parent, Expression type, int mod_flags,
6268 bool is_iface, MemberName name, Object init,
6269 Attributes attrs, Location loc)
6270 : base (parent, type, mod_flags, is_iface, name, init, attrs, loc)
6272 Add = new AddDelegateMethod (this);
6273 Remove = new RemoveDelegateMethod (this);
6276 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
6278 if (a.Target == AttributeTargets.Field) {
6279 FieldBuilder.SetCustomAttribute (cb);
6283 if (a.Target == AttributeTargets.Method) {
6284 AddBuilder.SetCustomAttribute (cb);
6285 RemoveBuilder.SetCustomAttribute (cb);
6289 base.ApplyAttributeBuilder (a, cb);
6292 public override string[] ValidAttributeTargets {
6294 return IsInterface ? attribute_targets_interface : attribute_targets;
6299 public abstract class Event : FieldBase {
6301 protected sealed class AddDelegateMethod: DelegateMethod
6304 public AddDelegateMethod (Event method):
6305 base (method, "add_")
6309 public AddDelegateMethod (Event method, Accessor accessor):
6310 base (method, accessor, "add_")
6314 protected override MethodInfo DelegateMethodInfo {
6316 return TypeManager.delegate_combine_delegate_delegate;
6322 protected sealed class RemoveDelegateMethod: DelegateMethod
6324 public RemoveDelegateMethod (Event method):
6325 base (method, "remove_")
6329 public RemoveDelegateMethod (Event method, Accessor accessor):
6330 base (method, accessor, "remove_")
6334 protected override MethodInfo DelegateMethodInfo {
6336 return TypeManager.delegate_remove_delegate_delegate;
6342 public abstract class DelegateMethod: AbstractPropertyEventMethod
6344 protected readonly Event method;
6345 ImplicitParameter param_attr;
6347 static string[] attribute_targets = new string [] { "method", "param", "return" };
6349 public DelegateMethod (Event method, string prefix)
6350 : base (method, prefix)
6352 this.method = method;
6355 public DelegateMethod (Event method, Accessor accessor, string prefix)
6356 : base (method, accessor, prefix)
6358 this.method = method;
6361 protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
6363 if (a.Target == AttributeTargets.Parameter) {
6364 if (param_attr == null)
6365 param_attr = new ImplicitParameter (method_data.MethodBuilder);
6367 param_attr.ApplyAttributeBuilder (a, cb);
6371 base.ApplyAttributeBuilder (a, cb);
6374 public override AttributeTargets AttributeTargets {
6376 return AttributeTargets.Method;
6380 public override bool IsClsCompliaceRequired(DeclSpace ds)
6382 return method.IsClsCompliaceRequired (ds);
6385 public MethodBuilder Define (TypeContainer container, InternalParameters ip)
6387 method_data = new MethodData (method, ip, method.ModFlags,
6388 method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this);
6390 if (!method_data.Define (container))
6393 MethodBuilder mb = method_data.MethodBuilder;
6394 mb.DefineParameter (1, ParameterAttributes.None, "value");
6399 public override void Emit (TypeContainer tc)
6401 if (block != null) {
6406 ILGenerator ig = method_data.MethodBuilder.GetILGenerator ();
6407 EmitContext ec = CreateEmitContext (tc, ig);
6408 FieldInfo field_info = (FieldInfo)method.FieldBuilder;
6410 method_data.MethodBuilder.SetImplementationFlags (MethodImplAttributes.Synchronized);
6411 if ((method.ModFlags & Modifiers.STATIC) != 0) {
6412 ig.Emit (OpCodes.Ldsfld, field_info);
6413 ig.Emit (OpCodes.Ldarg_0);
6414 ig.Emit (OpCodes.Call, DelegateMethodInfo);
6415 ig.Emit (OpCodes.Castclass, method.MemberType);
6416 ig.Emit (OpCodes.Stsfld, field_info);
6418 ig.Emit (OpCodes.Ldarg_0);
6419 ig.Emit (OpCodes.Ldarg_0);
6420 ig.Emit (OpCodes.Ldfld, field_info);
6421 ig.Emit (OpCodes.Ldarg_1);
6422 ig.Emit (OpCodes.Call, DelegateMethodInfo);
6423 ig.Emit (OpCodes.Castclass, method.MemberType);
6424 ig.Emit (OpCodes.Stfld, field_info);
6426 ig.Emit (OpCodes.Ret);
6429 protected abstract MethodInfo DelegateMethodInfo { get; }
6431 public override Type[] ParameterTypes {
6433 return new Type[] { method.MemberType };
6437 public override Type ReturnType {
6439 return TypeManager.void_type;
6443 public override EmitContext CreateEmitContext (TypeContainer tc,
6446 return new EmitContext (
6447 tc, method.Parent, Location, ig, ReturnType,
6448 method.ModFlags, false);
6451 public override string GetSignatureForError (TypeContainer tc)
6453 return String.Concat (tc.Name, '.', method.Name);
6456 public override ObsoleteAttribute GetObsoleteAttribute ()
6458 return method.GetObsoleteAttribute (method.Parent);
6461 public override string[] ValidAttributeTargets {
6463 return attribute_targets;
6469 const int AllowedModifiers =
6472 Modifiers.PROTECTED |
6473 Modifiers.INTERNAL |
6478 Modifiers.OVERRIDE |
6482 const int AllowedInterfaceModifiers =
6485 public DelegateMethod Add, Remove;
6486 public MyEventBuilder EventBuilder;
6487 public MethodBuilder AddBuilder, RemoveBuilder;
6489 public Event (TypeContainer parent, Expression type, int mod_flags,
6490 bool is_iface, MemberName name, Object init, Attributes attrs,
6492 : base (parent, type, mod_flags,
6493 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
6494 name, init, attrs, loc)
6496 IsInterface = is_iface;
6499 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
6501 if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
6502 a.Error_InvalidSecurityParent ();
6506 EventBuilder.SetCustomAttribute (cb);
6509 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
6511 return Add.IsDuplicateImplementation (mc) || Remove.IsDuplicateImplementation (mc);
6514 public override AttributeTargets AttributeTargets {
6516 return AttributeTargets.Event;
6520 public override bool Define ()
6522 EventAttributes e_attr;
6523 e_attr = EventAttributes.None;
6528 if (init != null && ((ModFlags & Modifiers.ABSTRACT) != 0)){
6529 Report.Error (74, Location, "'" + Parent.Name + "." + Name +
6530 "': abstract event can not have an initializer");
6534 if (!MemberType.IsSubclassOf (TypeManager.delegate_type)) {
6535 Report.Error (66, Location, "'" + Parent.Name + "." + Name +
6536 "' : event must be of a delegate type");
6540 EmitContext ec = Parent.EmitContext;
6542 throw new InternalErrorException ("Event.Define called too early?");
6543 bool old_unsafe = ec.InUnsafe;
6544 ec.InUnsafe = InUnsafe;
6546 Parameter [] parms = new Parameter [1];
6547 parms [0] = new Parameter (Type, "value", Parameter.Modifier.NONE, null);
6548 Parameters parameters = new Parameters (parms, null, Location);
6549 Type [] types = parameters.GetParameterInfo (ec);
6550 InternalParameters ip = new InternalParameters (types, parameters);
6552 ec.InUnsafe = old_unsafe;
6558 // Now define the accessors
6561 AddBuilder = Add.Define (Parent, ip);
6562 if (AddBuilder == null)
6565 RemoveBuilder = Remove.Define (Parent, ip);
6566 if (RemoveBuilder == null)
6569 EventBuilder = new MyEventBuilder (this, Parent.TypeBuilder, Name, e_attr, MemberType);
6571 if (Add.Block == null && Remove.Block == null && !IsInterface) {
6572 FieldBuilder = Parent.TypeBuilder.DefineField (
6574 FieldAttributes.Private | ((ModFlags & Modifiers.STATIC) != 0 ? FieldAttributes.Static : 0));
6575 TypeManager.RegisterPrivateFieldOfEvent (
6576 (EventInfo) EventBuilder, FieldBuilder);
6577 TypeManager.RegisterFieldBase (FieldBuilder, this);
6580 EventBuilder.SetAddOnMethod (AddBuilder);
6581 EventBuilder.SetRemoveOnMethod (RemoveBuilder);
6583 TypeManager.RegisterEvent (EventBuilder, AddBuilder, RemoveBuilder);
6587 protected override bool CheckBase ()
6589 if (!base.CheckBase ())
6592 if (conflict_symbol != null && (ModFlags & Modifiers.NEW) == 0) {
6593 if (!(conflict_symbol is EventInfo)) {
6594 Report.SymbolRelatedToPreviousError (conflict_symbol);
6595 Report.Error (72, Location, "Event '{0}' can override only event", GetSignatureForError (Parent));
6603 public override void Emit ()
6605 if (OptAttributes != null) {
6606 EmitContext ec = new EmitContext (
6607 Parent, Location, null, MemberType, ModFlags);
6608 OptAttributes.Emit (ec, this);
6613 Remove.Emit (Parent);
6619 public override string GetSignatureForError ()
6621 if (EventBuilder == null)
6622 return base.GetSignatureForError (Parent);
6624 return TypeManager.GetFullNameSignature (EventBuilder);
6629 public class Indexer : PropertyBase {
6631 class GetIndexerMethod: GetMethod
6633 public GetIndexerMethod (MethodCore method):
6638 public GetIndexerMethod (MethodCore method, Accessor accessor):
6639 base (method, accessor)
6643 public override Type[] ParameterTypes {
6645 return method.ParameterTypes;
6650 class SetIndexerMethod: SetMethod
6652 readonly Parameters parameters;
6654 public SetIndexerMethod (MethodCore method):
6659 public SetIndexerMethod (MethodCore method, Parameters parameters, Accessor accessor):
6660 base (method, accessor)
6662 this.parameters = parameters;
6665 public override Type[] ParameterTypes {
6667 int top = method.ParameterTypes.Length;
6668 Type [] set_pars = new Type [top + 1];
6669 method.ParameterTypes.CopyTo (set_pars, 0);
6670 set_pars [top] = method.MemberType;
6675 protected override InternalParameters GetParameterInfo (EmitContext ec)
6677 Parameter [] fixed_parms = parameters.FixedParameters;
6679 if (fixed_parms == null){
6680 throw new Exception ("We currently do not support only array arguments in an indexer at: " + method.Location);
6681 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
6682 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
6684 // Here is the problem: the `value' parameter has
6685 // to come *after* the array parameter in the declaration
6687 // X (object [] x, Type value)
6690 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
6691 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
6695 Parameter [] tmp = new Parameter [fixed_parms.Length + 1];
6697 fixed_parms.CopyTo (tmp, 0);
6698 tmp [fixed_parms.Length] = new Parameter (
6699 method.Type, "value", Parameter.Modifier.NONE, null);
6701 Parameters set_formal_params = new Parameters (tmp, null, method.Location);
6702 Type [] types = set_formal_params.GetParameterInfo (ec);
6704 return new InternalParameters (types, set_formal_params);
6709 const int AllowedModifiers =
6712 Modifiers.PROTECTED |
6713 Modifiers.INTERNAL |
6717 Modifiers.OVERRIDE |
6722 const int AllowedInterfaceModifiers =
6726 public Indexer (TypeContainer ds, Expression type, MemberName name, int mod,
6727 bool is_iface, Parameters parameters, Attributes attrs,
6728 Accessor get_block, Accessor set_block, Location loc)
6729 : base (ds, type, mod,
6730 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
6731 is_iface, name, parameters, attrs, loc)
6733 if (get_block == null)
6734 Get = new GetIndexerMethod (this);
6736 Get = new GetIndexerMethod (this, get_block);
6738 if (set_block == null)
6739 Set = new SetIndexerMethod (this);
6741 Set = new SetIndexerMethod (this, parameters, set_block);
6744 public override bool Define ()
6746 PropertyAttributes prop_attr =
6747 PropertyAttributes.RTSpecialName |
6748 PropertyAttributes.SpecialName;
6750 if (!base.Define ())
6753 if (OptAttributes != null) {
6754 Attribute indexer_attr = OptAttributes.GetIndexerNameAttribute (ec);
6755 if (indexer_attr != null) {
6756 ShortName = indexer_attr.GetIndexerAttributeValue (ec);
6758 if (IsExplicitImpl) {
6759 Report.Error (415, indexer_attr.Location,
6760 "The 'IndexerName' attribute is valid only on an" +
6761 "indexer that is not an explicit interface member declaration");
6765 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
6766 Report.Error (609, indexer_attr.Location,
6767 "Cannot set the 'IndexerName' attribute on an indexer marked override");
6771 if (!Tokenizer.IsValidIdentifier (ShortName)) {
6772 Report.Error (633, indexer_attr.Location,
6773 "The argument to the 'IndexerName' attribute must be a valid identifier");
6777 UpdateMemberName ();
6781 if (InterfaceType != null) {
6782 string parent_IndexerName = TypeManager.IndexerPropertyName (InterfaceType);
6783 if (parent_IndexerName != Name)
6784 ShortName = parent_IndexerName;
6785 UpdateMemberName ();
6788 if (!Parent.AddToMemberContainer (this, true) ||
6789 !Parent.AddToMemberContainer (Get, true) || !Parent.AddToMemberContainer (Set, true))
6795 flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
6797 GetBuilder = Get.Define (Parent);
6798 if (GetBuilder == null)
6803 SetBuilder = Set.Define (Parent);
6804 if (SetBuilder == null)
6809 // Now name the parameters
6811 Parameter [] p = Parameters.FixedParameters;
6813 if ((p [0].ModFlags & Parameter.Modifier.ISBYREF) != 0) {
6814 Report.Error (631, Location, "ref and out are not valid in this context");
6820 for (i = 0; i < p.Length; ++i) {
6822 GetBuilder.DefineParameter (
6823 i + 1, p [i].Attributes, p [i].Name);
6826 SetBuilder.DefineParameter (
6827 i + 1, p [i].Attributes, p [i].Name);
6831 SetBuilder.DefineParameter (
6832 i + 1, ParameterAttributes.None, "value");
6834 if (i != ParameterTypes.Length) {
6835 Parameter array_param = Parameters.ArrayParameter;
6837 SetBuilder.DefineParameter (
6838 i + 1, array_param.Attributes, array_param.Name);
6842 PropertyBuilder = Parent.TypeBuilder.DefineProperty (
6843 Name, prop_attr, MemberType, ParameterTypes);
6846 PropertyBuilder.SetGetMethod (GetBuilder);
6849 PropertyBuilder.SetSetMethod (SetBuilder);
6851 TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder, ParameterTypes);
6856 public override string GetSignatureForError ()
6858 if (PropertyBuilder == null)
6859 return GetSignatureForError (Parent);
6861 return TypeManager.CSharpSignature (PropertyBuilder, true);
6864 public override string GetSignatureForError(TypeContainer tc)
6866 return String.Concat (tc.Name, ".this[", Parameters.FixedParameters [0].TypeName.ToString (), ']');
6870 public class Operator : MethodCore, IIteratorContainer {
6872 const int AllowedModifiers =
6878 public enum OpType : byte {
6888 // Unary and Binary operators
6911 // Implicit and Explicit
6916 public readonly OpType OperatorType;
6917 public MethodBuilder OperatorMethodBuilder;
6919 public Method OperatorMethod;
6921 static string[] attribute_targets = new string [] { "method", "return" };
6923 public Operator (TypeContainer parent, OpType type, Expression ret_type,
6924 int mod_flags, Parameters parameters,
6925 ToplevelBlock block, Attributes attrs, Location loc)
6926 : base (parent, ret_type, mod_flags, AllowedModifiers, false,
6927 new MemberName ("op_" + type), attrs, parameters, loc)
6929 OperatorType = type;
6933 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
6935 OperatorMethod.ApplyAttributeBuilder (a, cb);
6938 public override AttributeTargets AttributeTargets {
6940 return AttributeTargets.Method;
6944 protected override bool CheckForDuplications()
6946 ArrayList ar = Parent.Operators;
6948 int arLen = ar.Count;
6950 for (int i = 0; i < arLen; i++) {
6951 Operator o = (Operator) ar [i];
6952 if (IsDuplicateImplementation (o))
6957 ar = Parent.Methods;
6959 int arLen = ar.Count;
6961 for (int i = 0; i < arLen; i++) {
6962 Method m = (Method) ar [i];
6963 if (IsDuplicateImplementation (m))
6971 public override bool Define ()
6974 const int RequiredModifiers = Modifiers.PUBLIC | Modifiers.STATIC;
6975 if ((ModFlags & RequiredModifiers) != RequiredModifiers){
6976 Report.Error (558, Location, "User defined operators '{0}' must be declared static and public", GetSignatureForError (Parent));
6983 OperatorMethod = new Method (
6984 Parent, Type, ModFlags, false, MemberName,
6985 Parameters, OptAttributes, Location);
6987 OperatorMethod.Block = Block;
6988 OperatorMethod.IsOperator = true;
6989 OperatorMethod.flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
6990 OperatorMethod.Define ();
6992 if (OperatorMethod.MethodBuilder == null)
6995 OperatorMethodBuilder = OperatorMethod.MethodBuilder;
6997 parameter_types = OperatorMethod.ParameterTypes;
6998 Type declaring_type = OperatorMethodBuilder.DeclaringType;
6999 Type return_type = OperatorMethod.ReturnType;
7000 Type first_arg_type = parameter_types [0];
7005 // Rules for conversion operators
7007 if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
7008 if (first_arg_type == return_type && first_arg_type == declaring_type){
7011 "User-defined conversion cannot take an object of the " +
7012 "enclosing type and convert to an object of the enclosing" +
7017 if (first_arg_type != declaring_type && return_type != declaring_type){
7020 "User-defined conversion must convert to or from the " +
7025 if (first_arg_type == TypeManager.object_type ||
7026 return_type == TypeManager.object_type){
7029 "User-defined conversion cannot convert to or from " +
7034 if (first_arg_type.IsInterface || return_type.IsInterface){
7037 "User-defined conversion cannot convert to or from an " +
7042 if (first_arg_type.IsSubclassOf (return_type)
7043 || return_type.IsSubclassOf (first_arg_type)){
7044 if (declaring_type.IsSubclassOf (return_type)) {
7045 Report.Error (553, Location, "'{0}' : user defined conversion to/from base class", GetSignatureForError ());
7048 Report.Error (554, Location, "'{0}' : user defined conversion to/from derived class", GetSignatureForError ());
7051 } else if (OperatorType == OpType.LeftShift || OperatorType == OpType.RightShift) {
7052 if (first_arg_type != declaring_type || parameter_types [1] != TypeManager.int32_type) {
7053 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");
7056 } else if (Parameters.FixedParameters.Length == 1) {
7057 // Checks for Unary operators
7059 if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
7060 if (return_type != declaring_type && !return_type.IsSubclassOf (declaring_type)) {
7061 Report.Error (448, Location,
7062 "The return type for ++ or -- operator must be the containing type or derived from the containing type");
7065 if (first_arg_type != declaring_type) {
7067 559, Location, "The parameter type for ++ or -- operator must be the containing type");
7072 if (first_arg_type != declaring_type){
7075 "The parameter of a unary operator must be the " +
7080 if (OperatorType == OpType.True || OperatorType == OpType.False) {
7081 if (return_type != TypeManager.bool_type){
7084 "The return type of operator True or False " +
7091 // Checks for Binary operators
7093 if (first_arg_type != declaring_type &&
7094 parameter_types [1] != declaring_type){
7097 "One of the parameters of a binary operator must " +
7098 "be the containing type");
7106 public override void Emit ()
7109 // abstract or extern methods have no bodies
7111 if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
7114 OperatorMethod.Emit ();
7118 // Operator cannot be override
7119 protected override MethodInfo FindOutParentMethod (TypeContainer container, ref Type parent_ret_type)
7124 public static string GetName (OpType ot)
7127 case OpType.LogicalNot:
7129 case OpType.OnesComplement:
7131 case OpType.Increment:
7133 case OpType.Decrement:
7139 case OpType.Addition:
7141 case OpType.Subtraction:
7143 case OpType.UnaryPlus:
7145 case OpType.UnaryNegation:
7147 case OpType.Multiply:
7149 case OpType.Division:
7151 case OpType.Modulus:
7153 case OpType.BitwiseAnd:
7155 case OpType.BitwiseOr:
7157 case OpType.ExclusiveOr:
7159 case OpType.LeftShift:
7161 case OpType.RightShift:
7163 case OpType.Equality:
7165 case OpType.Inequality:
7167 case OpType.GreaterThan:
7169 case OpType.LessThan:
7171 case OpType.GreaterThanOrEqual:
7173 case OpType.LessThanOrEqual:
7175 case OpType.Implicit:
7177 case OpType.Explicit:
7183 public override string GetSignatureForError (TypeContainer tc)
7185 StringBuilder sb = new StringBuilder ();
7186 sb.AppendFormat ("{0}.operator {1} {2}({3}", tc.Name, GetName (OperatorType), Type.Type == null ? Type.ToString () : TypeManager.CSharpName (Type.Type),
7187 Parameters.FixedParameters [0].GetSignatureForError ());
7189 if (Parameters.FixedParameters.Length > 1) {
7191 sb.Append (Parameters.FixedParameters [1].GetSignatureForError ());
7194 return sb.ToString ();
7197 public override string GetSignatureForError ()
7202 public override string ToString ()
7204 if (OperatorMethod == null)
7207 Type return_type = OperatorMethod.ReturnType;
7208 Type [] param_types = OperatorMethod.ParameterTypes;
7210 if (Parameters.FixedParameters.Length == 1)
7211 return String.Format (
7212 "{0} operator {1}({2})",
7213 TypeManager.CSharpName (return_type),
7214 GetName (OperatorType),
7217 return String.Format (
7218 "{0} operator {1}({2}, {3})",
7219 TypeManager.CSharpName (return_type),
7220 GetName (OperatorType),
7221 param_types [0], param_types [1]);
7224 public override string[] ValidAttributeTargets {
7226 return attribute_targets;
7230 public void SetYields ()
7232 ModFlags |= Modifiers.METHOD_YIELDS;
7237 // This is used to compare method signatures
7239 struct MethodSignature {
7241 public Type RetType;
7242 public Type [] Parameters;
7245 /// This delegate is used to extract methods which have the
7246 /// same signature as the argument
7248 public static MemberFilter method_signature_filter = new MemberFilter (MemberSignatureCompare);
7250 public MethodSignature (string name, Type ret_type, Type [] parameters)
7255 if (parameters == null)
7256 Parameters = TypeManager.NoTypes;
7258 Parameters = parameters;
7261 public override string ToString ()
7264 if (Parameters.Length != 0){
7265 System.Text.StringBuilder sb = new System.Text.StringBuilder ();
7266 for (int i = 0; i < Parameters.Length; i++){
7267 sb.Append (Parameters [i]);
7268 if (i+1 < Parameters.Length)
7271 pars = sb.ToString ();
7274 return String.Format ("{0} {1} ({2})", RetType, Name, pars);
7277 public override int GetHashCode ()
7279 return Name.GetHashCode ();
7282 public override bool Equals (Object o)
7284 MethodSignature other = (MethodSignature) o;
7286 if (other.Name != Name)
7289 if (other.RetType != RetType)
7292 if (Parameters == null){
7293 if (other.Parameters == null)
7298 if (other.Parameters == null)
7301 int c = Parameters.Length;
7302 if (other.Parameters.Length != c)
7305 for (int i = 0; i < c; i++)
7306 if (other.Parameters [i] != Parameters [i])
7312 static bool MemberSignatureCompare (MemberInfo m, object filter_criteria)
7314 MethodSignature sig = (MethodSignature) filter_criteria;
7316 if (m.Name != sig.Name)
7320 MethodInfo mi = m as MethodInfo;
7321 PropertyInfo pi = m as PropertyInfo;
7324 ReturnType = mi.ReturnType;
7325 else if (pi != null)
7326 ReturnType = pi.PropertyType;
7331 // we use sig.RetType == null to mean `do not check the
7332 // method return value.
7334 if (sig.RetType != null)
7335 if (ReturnType != sig.RetType)
7340 args = TypeManager.GetArgumentTypes (mi);
7342 args = TypeManager.GetArgumentTypes (pi);
7343 Type [] sigp = sig.Parameters;
7345 if (args.Length != sigp.Length)
7348 for (int i = args.Length; i > 0; ){
7350 if (args [i] != sigp [i])