2 // class.cs: Class and Struct handlers
4 // Authors: Miguel de Icaza (miguel@gnu.org)
5 // Martin Baulig (martin@ximian.com)
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)
11 // (C) 2004 Novell, Inc
14 // 2002-10-11 Miguel de Icaza <miguel@ximian.com>
16 // * class.cs: Following the comment from 2002-09-26 to AddMethod, I
17 // have fixed a remaining problem: not every AddXXXX was adding a
18 // fully qualified name.
20 // Now everyone registers a fully qualified name in the DeclSpace as
21 // being defined instead of the partial name.
23 // Downsides: we are slower than we need to be due to the excess
24 // copies and the names being registered this way.
26 // The reason for this is that we currently depend (on the corlib
27 // bootstrap for instance) that types are fully qualified, because
28 // we dump all the types in the namespace, and we should really have
29 // types inserted into the proper namespace, so we can only store the
30 // basenames in the defined_names array.
36 using System.Collections;
37 using System.Collections.Specialized;
38 using System.Reflection;
39 using System.Reflection.Emit;
40 using System.Runtime.CompilerServices;
41 using System.Runtime.InteropServices;
42 using System.Security;
43 using System.Security.Permissions;
46 using Mono.CompilerServices.SymbolWriter;
48 namespace Mono.CSharp {
58 /// This is the base class for structs and classes.
60 public abstract class TypeContainer : DeclSpace, IMemberContainer {
62 public class MemberCoreArrayList: ArrayList
65 /// Defines the MemberCore objects that are in this array
67 public virtual void DefineContainerMembers ()
69 foreach (MemberCore mc in this) {
74 public virtual void Emit ()
76 foreach (MemberCore mc in this)
81 public class MethodArrayList : MemberCoreArrayList
89 CachedMethods cached_method;
90 TypeContainer container;
92 public MethodArrayList (TypeContainer container)
94 this.container = container;
98 /// Method container contains Equals method
100 public bool HasEquals {
102 cached_method |= CachedMethods.Equals;
106 return (cached_method & CachedMethods.Equals) != 0;
111 /// Method container contains GetHashCode method
113 public bool HasGetHashCode {
115 cached_method |= CachedMethods.GetHashCode;
119 return (cached_method & CachedMethods.GetHashCode) != 0;
123 public override void DefineContainerMembers ()
125 base.DefineContainerMembers ();
127 if (HasEquals && !HasGetHashCode) {
128 Report.Warning (659, 3, container.Location, "`{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", container.GetSignatureForError ());
134 public sealed class IndexerArrayList : MemberCoreArrayList
137 /// The indexer name for this container
139 public string IndexerName = DefaultIndexerName;
141 bool seen_normal_indexers = false;
143 TypeContainer container;
145 public IndexerArrayList (TypeContainer container)
147 this.container = container;
151 /// Defines the indexers, and also verifies that the IndexerNameAttribute in the
152 /// class is consistent. Either it is `Item' or it is the name defined by all the
153 /// indexers with the `IndexerName' attribute.
155 /// Turns out that the IndexerNameAttribute is applied to each indexer,
156 /// but it is never emitted, instead a DefaultMember attribute is attached
159 public override void DefineContainerMembers()
161 base.DefineContainerMembers ();
163 string class_indexer_name = null;
166 // If there's both an explicit and an implicit interface implementation, the
167 // explicit one actually implements the interface while the other one is just
168 // a normal indexer. See bug #37714.
171 // Invariant maintained by AddIndexer(): All explicit interface indexers precede normal indexers
172 foreach (Indexer i in this) {
173 if (i.InterfaceType != null) {
174 if (seen_normal_indexers)
175 throw new Exception ("Internal Error: 'Indexers' array not sorted properly.");
179 seen_normal_indexers = true;
181 if (class_indexer_name == null) {
182 class_indexer_name = i.ShortName;
186 if (i.ShortName != class_indexer_name)
187 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");
190 if (class_indexer_name != null)
191 IndexerName = class_indexer_name;
194 public override void Emit ()
198 if (!seen_normal_indexers)
201 CustomAttributeBuilder cb = new CustomAttributeBuilder (TypeManager.default_member_ctor, new string [] { IndexerName });
202 container.TypeBuilder.SetCustomAttribute (cb);
206 public class OperatorArrayList: MemberCoreArrayList
208 TypeContainer container;
210 public OperatorArrayList (TypeContainer container)
212 this.container = container;
216 // Operator pair checking
221 public Type ret_type;
222 public Type type1, type2;
224 public Operator.OpType ot;
226 public OperatorEntry (int f, Operator o)
230 ret_type = o.OperatorMethod.ReturnType;
231 Type [] pt = o.OperatorMethod.ParameterTypes;
238 public override int GetHashCode ()
240 return ret_type.GetHashCode ();
243 public override bool Equals (object o)
245 OperatorEntry other = (OperatorEntry) o;
247 if (other.ret_type != ret_type)
249 if (other.type1 != type1)
251 if (other.type2 != type2)
258 // Checks that some operators come in pairs:
264 // They are matched based on the return type and the argument types
266 void CheckPairedOperators ()
268 IDictionary pairs = new HybridDictionary ();
269 Operator true_op = null;
270 Operator false_op = null;
271 bool has_equality_or_inequality = false;
273 // Register all the operators we care about.
274 foreach (Operator op in this){
277 // Skip erroneous code.
278 if (op.OperatorMethod == null)
281 switch (op.OperatorType){
282 case Operator.OpType.Equality:
284 has_equality_or_inequality = true;
286 case Operator.OpType.Inequality:
288 has_equality_or_inequality = true;
291 case Operator.OpType.True:
294 case Operator.OpType.False:
298 case Operator.OpType.GreaterThan:
300 case Operator.OpType.LessThan:
303 case Operator.OpType.GreaterThanOrEqual:
305 case Operator.OpType.LessThanOrEqual:
311 OperatorEntry oe = new OperatorEntry (reg, op);
313 object o = pairs [oe];
317 oe = (OperatorEntry) o;
322 if (true_op != null){
323 if (false_op == null)
324 Report.Error (216, true_op.Location, "The operator `{0}' requires a matching operator `false' to also be defined",
325 true_op.GetSignatureForError ());
326 } else if (false_op != null)
327 Report.Error (216, false_op.Location, "The operator `{0}' requires a matching operator `true' to also be defined",
328 false_op.GetSignatureForError ());
331 // Look for the mistakes.
333 foreach (DictionaryEntry de in pairs){
334 OperatorEntry oe = (OperatorEntry) de.Key;
341 case Operator.OpType.Equality:
344 case Operator.OpType.Inequality:
347 case Operator.OpType.GreaterThan:
350 case Operator.OpType.LessThan:
353 case Operator.OpType.GreaterThanOrEqual:
356 case Operator.OpType.LessThanOrEqual:
360 Report.Error (216, oe.op.Location,
361 "The operator `{0}' requires a matching operator `{1}' to also be defined",
362 oe.op.GetSignatureForError (), s);
365 if (has_equality_or_inequality && (RootContext.WarningLevel > 2)) {
366 if (container.Methods == null || !container.Methods.HasEquals)
367 Report.Warning (660, 2, container.Location, "`{0}' defines operator == or operator != but does not override Object.Equals(object o)", container.GetSignatureForError ());
369 if (container.Methods == null || !container.Methods.HasGetHashCode)
370 Report.Warning (661, 2, container.Location, "`{0}' defines operator == or operator != but does not override Object.GetHashCode()", container.GetSignatureForError ());
374 public override void DefineContainerMembers ()
376 base.DefineContainerMembers ();
377 CheckPairedOperators ();
382 // Whether this is a struct, class or interface
383 public readonly Kind Kind;
385 // Holds a list of classes and structures
388 // Holds the list of properties
389 MemberCoreArrayList properties;
391 // Holds the list of enumerations
392 MemberCoreArrayList enums;
394 // Holds the list of delegates
395 MemberCoreArrayList delegates;
397 // Holds the list of constructors
398 protected MemberCoreArrayList instance_constructors;
400 // Holds the list of fields
401 MemberCoreArrayList fields;
403 // Holds a list of fields that have initializers
404 protected ArrayList initialized_fields;
406 // Holds a list of static fields that have initializers
407 protected ArrayList initialized_static_fields;
409 // Holds the list of constants
410 MemberCoreArrayList constants;
413 MemberCoreArrayList interfaces;
415 // Holds the methods.
416 MethodArrayList methods;
419 protected MemberCoreArrayList events;
421 // Holds the indexers
422 IndexerArrayList indexers;
424 // Holds the operators
425 MemberCoreArrayList operators;
427 // Holds the iterators
430 // Holds the parts of a partial class;
434 // Pointers to the default constructor and the default static constructor
436 protected Constructor default_constructor;
437 protected Constructor default_static_constructor;
440 // Points to the first non-static field added to the container.
442 // This is an arbitrary choice. We are interested in looking at _some_ non-static field,
443 // and the first one's as good as any.
445 FieldBase first_nonstatic_field = null;
448 // This one is computed after we can distinguish interfaces
449 // from classes from the arraylist `type_bases'
451 string base_class_name;
453 TypeExpr[] iface_exprs;
455 ArrayList type_bases;
457 bool members_defined;
458 bool members_defined_ok;
460 // The interfaces we implement.
461 protected Type[] ifaces;
462 protected Type ptype;
464 // The base member cache and our member cache
465 MemberCache base_cache;
466 MemberCache member_cache;
468 public const string DefaultIndexerName = "Item";
471 GenericTypeParameterBuilder[] gen_params;
473 public TypeContainer (NamespaceEntry ns, TypeContainer parent, MemberName name,
474 Attributes attrs, Kind kind)
475 : base (ns, parent, name, attrs)
477 if (parent != null && parent != RootContext.Tree.Types && parent.NamespaceEntry != ns)
478 throw new InternalErrorException ("A nested type should be in the same NamespaceEntry as its enclosing class");
482 types = new ArrayList ();
484 base_class_name = null;
487 public bool AddToMemberContainer (MemberCore symbol)
489 return AddToContainer (symbol, symbol.MemberName.MethodName);
492 protected virtual bool AddToTypeContainer (DeclSpace ds)
494 return AddToContainer (ds, ds.Basename);
497 public void AddConstant (Const constant)
499 if (!AddToMemberContainer (constant))
502 if (constants == null)
503 constants = new MemberCoreArrayList ();
505 constants.Add (constant);
508 public void AddEnum (Mono.CSharp.Enum e)
510 if (!AddToTypeContainer (e))
514 enums = new MemberCoreArrayList ();
519 public bool AddClassOrStruct (TypeContainer c)
521 if (!AddToTypeContainer (c))
528 public void AddDelegate (Delegate d)
530 if (!AddToTypeContainer (d))
533 if (delegates == null)
534 delegates = new MemberCoreArrayList ();
539 public void AddMethod (Method method)
541 if (!AddToMemberContainer (method))
545 methods = new MethodArrayList (this);
547 if (method.MemberName.Left != null)
548 methods.Insert (0, method);
550 methods.Add (method);
554 // Do not use this method: use AddMethod.
556 // This is only used by iterators.
558 public void AppendMethod (Method method)
560 if (!AddToMemberContainer (method))
564 methods = new MethodArrayList (this);
566 methods.Add (method);
569 public void AddConstructor (Constructor c)
571 if (c.Name != MemberName.Name) {
572 Report.Error (1520, c.Location, "Class, struct, or interface method must have a return type");
575 bool is_static = (c.ModFlags & Modifiers.STATIC) != 0;
578 if (default_static_constructor != null) {
579 Report.SymbolRelatedToPreviousError (default_static_constructor);
580 Report.Error (111, c.Location, Error111, c.GetSignatureForError ());
584 default_static_constructor = c;
587 if (default_constructor != null) {
588 Report.SymbolRelatedToPreviousError (default_constructor);
589 Report.Error (111, c.Location, Error111, c.GetSignatureForError ());
592 default_constructor = c;
595 if (instance_constructors == null)
596 instance_constructors = new MemberCoreArrayList ();
598 instance_constructors.Add (c);
602 internal static string Error111 {
604 return "`{0}' is already defined. Rename this member or use different parameter types";
608 public bool AddInterface (TypeContainer iface)
610 if (!AddToTypeContainer (iface))
613 if (interfaces == null) {
614 interfaces = new MemberCoreArrayList ();
617 interfaces.Add (iface);
621 public void AddField (FieldMember field)
623 if (!AddToMemberContainer (field))
627 fields = new MemberCoreArrayList ();
631 if ((field.ModFlags & Modifiers.STATIC) != 0)
634 if (first_nonstatic_field == null) {
635 first_nonstatic_field = field;
639 if (Kind == Kind.Struct &&
640 first_nonstatic_field.Parent != field.Parent &&
641 RootContext.WarningLevel >= 3) {
642 Report.SymbolRelatedToPreviousError (first_nonstatic_field.Parent);
643 Report.Warning (282, 3, field.Location,
644 "struct instance field `{0}' found in different declaration from instance field `{1}'",
645 field.GetSignatureForError (), first_nonstatic_field.GetSignatureForError ());
649 public void AddProperty (Property prop)
651 if (!AddToMemberContainer (prop) ||
652 !AddToMemberContainer (prop.Get) || !AddToMemberContainer (prop.Set))
655 if (properties == null)
656 properties = new MemberCoreArrayList ();
658 if (prop.MemberName.Left != null)
659 properties.Insert (0, prop);
661 properties.Add (prop);
664 public void AddEvent (Event e)
666 if (!AddToMemberContainer (e))
669 if (e is EventProperty) {
670 if (!AddToMemberContainer (e.Add))
673 if (!AddToMemberContainer (e.Remove))
678 events = new MemberCoreArrayList ();
684 /// Indexer has special handling in constrast to other AddXXX because the name can be driven by IndexerNameAttribute
686 public void AddIndexer (Indexer i)
688 if (indexers == null)
689 indexers = new IndexerArrayList (this);
691 if (i.IsExplicitImpl)
692 indexers.Insert (0, i);
697 public void AddOperator (Operator op)
699 if (!AddToMemberContainer (op))
702 if (operators == null)
703 operators = new OperatorArrayList (this);
708 public void AddIterator (Iterator i)
710 if (iterators == null)
711 iterators = new ArrayList ();
716 public void AddType (TypeContainer tc)
721 public void AddPart (ClassPart part)
724 parts = new ArrayList ();
729 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
731 if (a.Type == TypeManager.default_member_type) {
732 if (Indexers != null) {
733 Report.Error (646, a.Location, "Cannot specify the `DefaultMember' attribute on type containing an indexer");
738 base.ApplyAttributeBuilder (a, cb);
741 public override AttributeTargets AttributeTargets {
745 return AttributeTargets.Class;
747 return AttributeTargets.Struct;
749 return AttributeTargets.Interface;
751 throw new NotSupportedException ();
756 public ArrayList Types {
762 public MethodArrayList Methods {
768 public ArrayList Constants {
774 public ArrayList Interfaces {
780 public ArrayList Iterators {
788 return base_class_name;
792 public ArrayList Bases {
802 public ArrayList Fields {
808 public ArrayList InstanceConstructors {
810 return instance_constructors;
814 public ArrayList Properties {
820 public ArrayList Events {
826 public ArrayList Enums {
832 public ArrayList Indexers {
838 public ArrayList Operators {
844 public ArrayList Delegates {
850 public ArrayList Parts {
856 protected override TypeAttributes TypeAttr {
858 return Modifiers.TypeAttr (ModFlags, this) | base.TypeAttr;
862 public string IndexerName {
864 return indexers == null ? DefaultIndexerName : indexers.IndexerName;
868 public bool IsComImport {
870 if (OptAttributes == null)
873 return OptAttributes.Contains (TypeManager.comimport_attr_type, EmitContext);
877 public virtual void RegisterFieldForInitialization (FieldBase field)
879 if ((field.ModFlags & Modifiers.STATIC) != 0){
880 if (initialized_static_fields == null)
881 initialized_static_fields = new ArrayList (4);
883 initialized_static_fields.Add (field);
885 if (initialized_fields == null)
886 initialized_fields = new ArrayList (4);
888 initialized_fields.Add (field);
893 // Emits the instance field initializers
895 public virtual bool EmitFieldInitializers (EmitContext ec)
900 fields = initialized_static_fields;
902 fields = initialized_fields;
908 foreach (FieldBase f in fields) {
909 f.EmitInitializer (ec);
915 // Defines the default constructors
917 protected void DefineDefaultConstructor (bool is_static)
921 // The default constructor is public
922 // If the class is abstract, the default constructor is protected
923 // The default static constructor is private
925 int mods = Modifiers.PUBLIC;
927 mods = Modifiers.STATIC | Modifiers.PRIVATE;
928 else if ((ModFlags & Modifiers.ABSTRACT) != 0)
929 mods = Modifiers.PROTECTED;
931 TypeContainer constructor_parent = this;
933 constructor_parent = (TypeContainer) Parts [0];
935 c = new Constructor (constructor_parent, MemberName.Name, mods,
936 Parameters.EmptyReadOnlyParameters,
937 new GeneratedBaseInitializer (Location),
942 c.Block = new ToplevelBlock (null, Location);
947 /// The pending methods that need to be implemented
948 // (interfaces or abstract methods)
950 public PendingImplementation Pending;
952 public abstract PendingImplementation GetPendingImplementations ();
954 TypeExpr[] GetPartialBases (out TypeExpr base_class)
956 ArrayList ifaces = new ArrayList ();
960 foreach (ClassPart part in parts) {
961 TypeExpr new_base_class;
962 TypeExpr[] new_ifaces;
964 new_ifaces = part.GetClassBases (out new_base_class);
965 if (new_ifaces == null && new_base_class != null)
968 if ((base_class != null) && (new_base_class != null) &&
969 !base_class.Equals (new_base_class)) {
970 Report.SymbolRelatedToPreviousError (base_class.Location, "");
971 Report.Error (263, part.Location,
972 "Partial declarations of `{0}' must " +
973 "not specify different base classes",
979 if ((base_class == null) && (new_base_class != null)) {
980 base_class = new_base_class;
983 if (new_ifaces == null)
986 foreach (TypeExpr iface in new_ifaces) {
988 foreach (TypeExpr old_iface in ifaces) {
989 if (old_iface.Equals (iface)) {
1000 TypeExpr[] retval = new TypeExpr [ifaces.Count];
1001 ifaces.CopyTo (retval, 0);
1005 TypeExpr[] GetNormalBases (out TypeExpr base_class)
1009 int count = Bases.Count;
1010 int start = 0, i, j;
1012 if (Kind == Kind.Class){
1013 TypeExpr name = ResolveBaseTypeExpr (
1014 (Expression) Bases [0], false, Location);
1020 if (!name.IsInterface) {
1021 // base_class could be a class, struct, enum, delegate.
1022 // This is validated in GetClassBases.
1028 TypeExpr [] ifaces = new TypeExpr [count-start];
1030 for (i = start, j = 0; i < count; i++, j++){
1031 TypeExpr resolved = ResolveBaseTypeExpr ((Expression) Bases [i], false, Location);
1032 if (resolved == null) {
1036 ifaces [j] = resolved;
1043 /// This function computes the Base class and also the
1044 /// list of interfaces that the class or struct @c implements.
1046 /// The return value is an array (might be null) of
1047 /// interfaces implemented (as Types).
1049 /// The @base_class argument is set to the base object or null
1050 /// if this is `System.Object'.
1052 protected virtual TypeExpr [] GetClassBases (out TypeExpr base_class)
1059 ifaces = GetPartialBases (out base_class);
1060 else if (Bases == null){
1064 ifaces = GetNormalBases (out base_class);
1069 if ((base_class != null) && (Kind == Kind.Class)){
1070 if (base_class is TypeParameterExpr){
1072 689, base_class.Location,
1073 "Cannot derive from `{0}' because it is a type parameter",
1074 base_class.GetSignatureForError ());
1079 if (base_class.Type.IsArray || base_class.Type.IsPointer) {
1080 Report.Error (1521, base_class.Location, "Invalid base type");
1084 if (base_class.IsSealed){
1085 Report.SymbolRelatedToPreviousError (base_class.Type);
1086 if (base_class.Type.IsAbstract) {
1087 Report.Error (709, Location, "`{0}': Cannot derive from static class `{1}'",
1088 GetSignatureForError (), TypeManager.CSharpName (base_class.Type));
1090 Report.Error (509, Location, "`{0}': cannot derive from sealed class `{1}'",
1091 GetSignatureForError (), TypeManager.CSharpName (base_class.Type));
1096 if (!base_class.CanInheritFrom ()){
1097 Report.Error (644, Location, "`{0}' cannot derive from special class `{1}'",
1098 GetSignatureForError (), base_class.GetSignatureForError ());
1102 if (!base_class.AsAccessible (this, ModFlags)) {
1103 Report.SymbolRelatedToPreviousError (base_class.Type);
1104 Report.Error (60, Location, "Inconsistent accessibility: base class `{0}' is less accessible than class `{1}'",
1105 TypeManager.CSharpName (base_class.Type), GetSignatureForError ());
1109 if (base_class != null)
1110 base_class_name = base_class.Name;
1115 int count = ifaces != null ? ifaces.Length : 0;
1117 for (i = 0; i < count; i++) {
1118 TypeExpr iface = (TypeExpr) ifaces [i];
1120 if (!iface.IsInterface) {
1121 if (Kind != Kind.Class) {
1122 // TODO: location of symbol related ....
1123 Error_TypeInListIsNotInterface (Location, iface.FullName);
1125 else if (base_class != null)
1126 Report.Error (1721, Location, "`{0}': Classes cannot have multiple base classes (`{1}' and `{2}')",
1127 GetSignatureForError (), base_class.GetSignatureForError (), iface.GetSignatureForError ());
1129 Report.Error (1722, Location, "`{0}': Base class `{1}' must be specified as first",
1130 GetSignatureForError (), iface.GetSignatureForError ());
1135 for (int x = 0; x < i; x++) {
1136 if (iface.Equals (ifaces [x])) {
1137 Report.Error (528, Location,
1138 "`{0}' is already listed in " +
1139 "interface list", iface.Name);
1144 if ((Kind == Kind.Interface) &&
1145 !iface.AsAccessible (Parent, ModFlags)) {
1146 Report.Error (61, Location,
1147 "Inconsistent accessibility: base " +
1148 "interface `{0}' is less accessible " +
1149 "than interface `{1}'", iface.Name,
1157 bool CheckGenericInterfaces (Type[] ifaces)
1159 ArrayList already_checked = new ArrayList ();
1161 for (int i = 0; i < ifaces.Length; i++) {
1162 Type iface = ifaces [i];
1163 foreach (Type t in already_checked) {
1167 Type[] infered = new Type [CountTypeParameters];
1168 if (!TypeManager.MayBecomeEqualGenericInstances (iface, t, infered, null))
1171 Report.Error (695, Location,
1172 "`{0}' cannot implement both `{1}' and `{2}' " +
1173 "because they may unify for some type parameter substitutions",
1174 TypeManager.CSharpName (TypeBuilder), TypeManager.CSharpName (iface),
1175 TypeManager.CSharpName (t));
1179 already_checked.Add (iface);
1187 protected void Error_TypeInListIsNotInterface (Location loc, string type)
1189 Report.Error (527, loc, "Type `{0}' in interface list is not an interface", type);
1193 // Defines the type in the appropriate ModuleBuilder or TypeBuilder.
1195 public override TypeBuilder DefineType ()
1200 if (TypeBuilder != null)
1203 TypeAttributes type_attributes = TypeAttr;
1207 if (TypeManager.NamespaceClash (Name, Location)) {
1212 ModuleBuilder builder = CodeGen.Module.Builder;
1213 Type default_parent = null;
1214 if (Kind == Kind.Struct)
1215 default_parent = TypeManager.value_type;
1216 TypeBuilder = builder.DefineType (
1217 Name, type_attributes, default_parent, null);
1219 TypeBuilder builder = Parent.TypeBuilder;
1220 if (builder == null) {
1225 TypeBuilder = builder.DefineNestedType (
1226 Basename, type_attributes, ptype, null);
1228 } catch (ArgumentException) {
1229 Report.RuntimeMissingSupport (Location, "static classes");
1234 TypeManager.AddUserType (this);
1236 if (Parts != null) {
1238 foreach (ClassPart part in Parts) {
1239 part.TypeBuilder = TypeBuilder;
1240 part.ec = new EmitContext (part, Mono.CSharp.Location.Null, null, null, ModFlags);
1241 part.ec.ContainerType = TypeBuilder;
1245 // Normally, we create the EmitContext here.
1246 // The only exception is if we're an Iterator - in this case,
1247 // we already have the `ec', so we don't want to create a new one.
1250 ec = new EmitContext (this, Mono.CSharp.Location.Null, null, null, ModFlags);
1251 ec.ContainerType = TypeBuilder;
1255 string[] param_names = new string [TypeParameters.Length];
1256 for (int i = 0; i < TypeParameters.Length; i++)
1257 param_names [i] = TypeParameters [i].Name;
1259 gen_params = TypeBuilder.DefineGenericParameters (param_names);
1261 int offset = CountTypeParameters - CurrentTypeParameters.Length;
1262 for (int i = offset; i < gen_params.Length; i++)
1263 CurrentTypeParameters [i - offset].Define (gen_params [i]);
1266 iface_exprs = GetClassBases (out base_type);
1267 if (iface_exprs == null && base_type != null) {
1273 // GetClassBases calls ResolveBaseTypeExpr() on the various type expressions involved,
1274 // which in turn should have called DefineType()s on base types if necessary.
1276 // None of the code below should trigger DefineType()s on classes that we depend on.
1277 // Thus, we are eligible to be on the topological sort `type_container_resolve_order'.
1279 // Let's do it as soon as possible, since code below can call DefineType() on classes
1280 // that depend on us to be populated before they are.
1282 if (!(this is Iterator))
1283 RootContext.RegisterOrder (this);
1285 if (base_type == null) {
1286 if (Kind == Kind.Class){
1287 if (RootContext.StdLib)
1288 base_type = TypeManager.system_object_expr;
1289 else if (Name != "System.Object")
1290 base_type = TypeManager.system_object_expr;
1291 } else if (Kind == Kind.Struct){
1293 // If we are compiling our runtime,
1294 // and we are defining ValueType, then our
1295 // base is `System.Object'.
1297 if (!RootContext.StdLib && Name == "System.ValueType")
1298 base_type = TypeManager.system_object_expr;
1299 else if (Kind == Kind.Struct)
1300 base_type = TypeManager.system_valuetype_expr;
1304 // Avoid attributes check when parent is not set
1305 TypeResolveEmitContext.TestObsoleteMethodUsage = false;
1307 if (base_type != null) {
1308 // FIXME: I think this should be ...ResolveType (Parent.EmitContext).
1309 // However, if Parent == RootContext.Tree.Types, its NamespaceEntry will be null.
1310 FullNamedExpression fne = base_type.ResolveAsTypeStep (TypeResolveEmitContext);
1311 if ((fne == null) || (fne.Type == null)) {
1318 if (IsGeneric && TypeManager.IsAttributeType (ptype)) {
1319 Report.Error (698, base_type.Location,
1320 "A generic type cannot derive from `{0}' " +
1321 "because it is an attribute class",
1328 if (!CheckRecursiveDefinition (this)) {
1333 if (ptype != null) {
1334 TypeBuilder.SetParent (ptype);
1337 // Attribute is undefined at the begining of corlib compilation
1338 if (TypeManager.obsolete_attribute_type != null) {
1339 TypeResolveEmitContext.TestObsoleteMethodUsage = GetObsoleteAttribute () == null;
1340 if (ptype != null && TypeResolveEmitContext.TestObsoleteMethodUsage) {
1341 CheckObsoleteType (base_type);
1345 // add interfaces that were not added at type creation
1346 if (iface_exprs != null) {
1347 // FIXME: I think this should be ...ExpandInterfaces (Parent.EmitContext, ...).
1348 // However, if Parent == RootContext.Tree.Types, its NamespaceEntry will be null.
1349 TypeResolveEmitContext.ContainerType = TypeBuilder;
1350 ifaces = TypeManager.ExpandInterfaces (TypeResolveEmitContext, iface_exprs);
1351 if (ifaces == null) {
1356 foreach (Type itype in ifaces)
1357 TypeBuilder.AddInterfaceImplementation (itype);
1359 if (!CheckGenericInterfaces (ifaces)) {
1364 TypeManager.RegisterBuilder (TypeBuilder, ifaces);
1367 if (this is Iterator && !ResolveType ()) {
1372 if (!DefineNestedTypes ()) {
1380 public bool ResolveType ()
1382 if ((base_type != null) &&
1383 (base_type.ResolveType (TypeResolveEmitContext) == null)) {
1391 TypeExpr current_type = null;
1392 if (Parts != null) {
1393 foreach (ClassPart part in Parts) {
1394 if (!part.DefineTypeParameters ()) {
1400 foreach (TypeParameter type_param in CurrentTypeParameters) {
1401 if (!type_param.Resolve (this)) {
1407 foreach (TypeParameter type_param in TypeParameters) {
1408 if (!type_param.DefineType (ec)) {
1414 current_type = new ConstructedType (
1415 TypeBuilder, TypeParameters, Location);
1418 foreach (TypeParameter type_param in TypeParameters)
1419 if (!type_param.CheckDependencies (ec)) {
1424 if (current_type != null) {
1425 current_type = current_type.ResolveAsTypeTerminal (ec);
1426 if (current_type == null) {
1431 CurrentType = current_type.ResolveType (ec);
1437 protected virtual bool DefineNestedTypes ()
1439 if (Interfaces != null) {
1440 foreach (TypeContainer iface in Interfaces)
1441 if (iface.DefineType () == null)
1445 if (Types != null) {
1446 foreach (TypeContainer tc in Types)
1447 if (tc.DefineType () == null)
1451 if (Delegates != null) {
1452 foreach (Delegate d in Delegates)
1453 if (d.DefineType () == null)
1457 if (Enums != null) {
1458 foreach (Enum en in Enums)
1459 if (en.DefineType () == null)
1466 TypeContainer InTransit;
1468 protected bool CheckRecursiveDefinition (TypeContainer tc)
1470 if (InTransit != null) {
1471 Report.SymbolRelatedToPreviousError (this);
1472 if (this is Interface)
1474 529, tc.Location, "Inherited interface `{0}' causes a " +
1475 "cycle in the interface hierarchy of `{1}'",
1476 GetSignatureForError (), tc.GetSignatureForError ());
1479 146, tc.Location, "Circular base class dependency " +
1480 "involving `{0}' and `{1}'",
1481 tc.GetSignatureForError (), GetSignatureForError ());
1487 Type parent = ptype;
1488 if (parent != null) {
1489 parent = TypeManager.DropGenericTypeArguments (parent);
1490 TypeContainer ptc = TypeManager.LookupTypeContainer (parent);
1491 if ((ptc != null) && !ptc.CheckRecursiveDefinition (this))
1495 if (iface_exprs != null) {
1496 foreach (TypeExpr iface in iface_exprs) {
1497 Type itype = TypeManager.DropGenericTypeArguments (iface.Type);
1498 TypeContainer ptc = TypeManager.LookupTypeContainer (itype);
1499 if ((ptc != null) && !ptc.CheckRecursiveDefinition (this))
1508 public static void Error_KeywordNotAllowed (Location loc)
1510 Report.Error (1530, loc, "Keyword `new' is not allowed on namespace elements");
1514 /// Populates our TypeBuilder with fields and methods
1516 public override bool DefineMembers ()
1518 if (members_defined)
1519 return members_defined_ok;
1521 if (!base.DefineMembers ())
1524 members_defined_ok = DoDefineMembers ();
1525 members_defined = true;
1527 return members_defined_ok;
1530 protected virtual bool DoDefineMembers ()
1532 if (iface_exprs != null) {
1533 foreach (TypeExpr iface in iface_exprs) {
1534 ConstructedType ct = iface as ConstructedType;
1535 if ((ct != null) && !ct.CheckConstraints (ec))
1540 if (base_type != null) {
1541 ConstructedType ct = base_type as ConstructedType;
1542 if ((ct != null) && !ct.CheckConstraints (ec))
1547 MemberInfo conflict_symbol = Parent.MemberCache.FindMemberWithSameName (Basename, false, TypeBuilder);
1548 if (conflict_symbol == null) {
1549 if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0))
1550 Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
1552 if ((ModFlags & Modifiers.NEW) == 0) {
1553 Report.SymbolRelatedToPreviousError (conflict_symbol);
1554 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
1555 GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
1560 DefineContainerMembers (constants);
1561 DefineContainerMembers (fields);
1563 if ((Kind == Kind.Class) && !(this is ClassPart)){
1564 if ((instance_constructors == null) &&
1565 !(this is StaticClass)) {
1566 if (default_constructor == null)
1567 DefineDefaultConstructor (false);
1570 if (initialized_static_fields != null &&
1571 default_static_constructor == null)
1572 DefineDefaultConstructor (true);
1575 if (Kind == Kind.Struct){
1577 // Structs can not have initialized instance
1580 if (initialized_static_fields != null &&
1581 default_static_constructor == null)
1582 DefineDefaultConstructor (true);
1584 if (initialized_fields != null)
1585 ReportStructInitializedInstanceError ();
1588 Pending = GetPendingImplementations ();
1590 if (parts != null) {
1591 foreach (ClassPart part in parts) {
1592 if (!part.DefineMembers ())
1598 // Constructors are not in the defined_names array
1600 DefineContainerMembers (instance_constructors);
1602 if (default_static_constructor != null)
1603 default_static_constructor.Define ();
1605 DefineContainerMembers (properties);
1606 DefineContainerMembers (events);
1607 DefineContainerMembers (indexers);
1608 DefineContainerMembers (methods);
1609 DefineContainerMembers (operators);
1610 DefineContainerMembers (enums);
1611 DefineContainerMembers (delegates);
1613 if (CurrentType != null) {
1614 GenericType = CurrentType;
1616 ec.ContainerType = GenericType;
1621 if (!(this is ClassPart))
1622 member_cache = new MemberCache (this);
1625 if (parts != null) {
1626 foreach (ClassPart part in parts)
1627 part.member_cache = member_cache;
1630 if (iterators != null) {
1631 foreach (Iterator iterator in iterators) {
1632 if (iterator.DefineType () == null)
1636 foreach (Iterator iterator in iterators) {
1637 if (!iterator.DefineMembers ())
1645 void ReportStructInitializedInstanceError ()
1647 foreach (Field f in initialized_fields){
1648 Report.Error (573, Location,
1649 "`{0}': Structs cannot have instance field initializers",
1650 f.GetSignatureForError ());
1654 protected virtual void DefineContainerMembers (MemberCoreArrayList mcal)
1657 mcal.DefineContainerMembers ();
1660 public override bool Define ()
1662 if (parts != null) {
1663 foreach (ClassPart part in parts) {
1664 if (!part.Define ())
1669 if (iterators != null) {
1670 foreach (Iterator iterator in iterators) {
1671 if (!iterator.Define ())
1679 public MemberInfo FindBaseMemberWithSameName (string name, bool ignore_methods)
1681 return BaseCache.FindMemberWithSameName (name, ignore_methods, null);
1685 /// This function is based by a delegate to the FindMembers routine
1687 static bool AlwaysAccept (MemberInfo m, object filterCriteria)
1693 /// This filter is used by FindMembers, and we just keep
1694 /// a global for the filter to `AlwaysAccept'
1696 static MemberFilter accepting_filter;
1699 static TypeContainer ()
1701 accepting_filter = new MemberFilter (AlwaysAccept);
1704 public MethodInfo[] GetMethods ()
1706 ArrayList members = new ArrayList ();
1710 if (methods != null) {
1711 int len = methods.Count;
1712 for (int i = 0; i < len; i++) {
1713 Method m = (Method) methods [i];
1715 members.Add (m.MethodBuilder);
1719 if (operators != null) {
1720 int len = operators.Count;
1721 for (int i = 0; i < len; i++) {
1722 Operator o = (Operator) operators [i];
1724 members.Add (o.OperatorMethodBuilder);
1728 if (properties != null) {
1729 int len = properties.Count;
1730 for (int i = 0; i < len; i++) {
1731 Property p = (Property) properties [i];
1733 if (p.GetBuilder != null)
1734 members.Add (p.GetBuilder);
1735 if (p.SetBuilder != null)
1736 members.Add (p.SetBuilder);
1740 if (indexers != null) {
1741 int len = indexers.Count;
1742 for (int i = 0; i < len; i++) {
1743 Indexer ix = (Indexer) indexers [i];
1745 if (ix.GetBuilder != null)
1746 members.Add (ix.GetBuilder);
1747 if (ix.SetBuilder != null)
1748 members.Add (ix.SetBuilder);
1752 if (events != null) {
1753 int len = events.Count;
1754 for (int i = 0; i < len; i++) {
1755 Event e = (Event) events [i];
1757 if (e.AddBuilder != null)
1758 members.Add (e.AddBuilder);
1759 if (e.RemoveBuilder != null)
1760 members.Add (e.RemoveBuilder);
1764 MethodInfo[] retMethods = new MethodInfo [members.Count];
1765 members.CopyTo (retMethods, 0);
1769 // Indicated whether container has StructLayout attribute set Explicit
1770 public virtual bool HasExplicitLayout {
1776 public override Type FindNestedType (string name)
1778 ArrayList [] lists = { types, enums, delegates, interfaces };
1780 for (int j = 0; j < lists.Length; ++j) {
1781 ArrayList list = lists [j];
1785 int len = list.Count;
1786 for (int i = 0; i < len; ++i) {
1787 DeclSpace ds = (DeclSpace) list [i];
1788 if (ds.Basename == name) {
1790 return ds.TypeBuilder;
1798 private void FindMembers_NestedTypes (int modflags,
1799 BindingFlags bf, MemberFilter filter, object criteria,
1800 ref ArrayList members)
1802 ArrayList [] lists = { types, enums, delegates, interfaces };
1804 for (int j = 0; j < lists.Length; ++j) {
1805 ArrayList list = lists [j];
1809 int len = list.Count;
1810 for (int i = 0; i < len; i++) {
1811 DeclSpace ds = (DeclSpace) list [i];
1813 if ((ds.ModFlags & modflags) == 0)
1816 TypeBuilder tb = ds.TypeBuilder;
1818 if (!(criteria is string) || ds.Basename.Equals (criteria))
1819 tb = ds.DefineType ();
1822 if (tb != null && (filter (tb, criteria) == true)) {
1823 if (members == null)
1824 members = new ArrayList ();
1833 /// This method returns the members of this type just like Type.FindMembers would
1834 /// Only, we need to use this for types which are _being_ defined because MS'
1835 /// implementation can't take care of that.
1838 // FIXME: return an empty static array instead of null, that cleans up
1839 // some code and is consistent with some coding conventions I just found
1843 // Notice that in various cases we check if our field is non-null,
1844 // something that would normally mean that there was a bug elsewhere.
1846 // The problem happens while we are defining p-invoke methods, as those
1847 // will trigger a FindMembers, but this happens before things are defined
1849 // Since the whole process is a no-op, it is fine to check for null here.
1851 public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
1852 MemberFilter filter, object criteria)
1854 ArrayList members = null;
1857 if ((bf & BindingFlags.Public) != 0)
1858 modflags |= Modifiers.PUBLIC | Modifiers.PROTECTED |
1860 if ((bf & BindingFlags.NonPublic) != 0)
1861 modflags |= Modifiers.PRIVATE;
1863 int static_mask = 0, static_flags = 0;
1864 switch (bf & (BindingFlags.Static | BindingFlags.Instance)) {
1865 case BindingFlags.Static:
1866 static_mask = static_flags = Modifiers.STATIC;
1869 case BindingFlags.Instance:
1870 static_mask = Modifiers.STATIC;
1875 static_mask = static_flags = 0;
1879 Timer.StartTimer (TimerType.TcFindMembers);
1882 filter = accepting_filter;
1884 if ((mt & MemberTypes.Field) != 0) {
1885 if (fields != null) {
1886 int len = fields.Count;
1887 for (int i = 0; i < len; i++) {
1888 FieldMember f = (FieldMember) fields [i];
1890 if ((f.ModFlags & modflags) == 0)
1892 if ((f.ModFlags & static_mask) != static_flags)
1895 FieldBuilder fb = f.FieldBuilder;
1896 if (fb != null && filter (fb, criteria) == true) {
1897 if (members == null)
1898 members = new ArrayList ();
1905 if (constants != null) {
1906 int len = constants.Count;
1907 for (int i = 0; i < len; i++) {
1908 Const con = (Const) constants [i];
1910 if ((con.ModFlags & modflags) == 0)
1912 if ((con.ModFlags & static_mask) != static_flags)
1915 FieldBuilder fb = con.FieldBuilder;
1918 fb = con.FieldBuilder;
1920 if (fb != null && filter (fb, criteria) == true) {
1921 if (members == null)
1922 members = new ArrayList ();
1930 if ((mt & MemberTypes.Method) != 0) {
1931 if (methods != null) {
1932 int len = methods.Count;
1933 for (int i = 0; i < len; i++) {
1934 Method m = (Method) methods [i];
1936 if ((m.ModFlags & modflags) == 0)
1938 if ((m.ModFlags & static_mask) != static_flags)
1941 MethodBuilder mb = m.MethodBuilder;
1943 if (mb != null && filter (mb, criteria) == true) {
1944 if (members == null)
1945 members = new ArrayList ();
1952 if (operators != null) {
1953 int len = operators.Count;
1954 for (int i = 0; i < len; i++) {
1955 Operator o = (Operator) operators [i];
1957 if ((o.ModFlags & modflags) == 0)
1959 if ((o.ModFlags & static_mask) != static_flags)
1962 MethodBuilder ob = o.OperatorMethodBuilder;
1963 if (ob != null && filter (ob, criteria) == true) {
1964 if (members == null)
1965 members = new ArrayList ();
1972 if (properties != null) {
1973 int len = properties.Count;
1974 for (int i = 0; i < len; i++) {
1975 Property p = (Property) properties [i];
1977 if ((p.ModFlags & modflags) == 0)
1979 if ((p.ModFlags & static_mask) != static_flags)
1985 if (b != null && filter (b, criteria) == true) {
1986 if (members == null)
1987 members = new ArrayList ();
1993 if (b != null && filter (b, criteria) == true) {
1994 if (members == null)
1995 members = new ArrayList ();
2002 if (indexers != null) {
2003 int len = indexers.Count;
2004 for (int i = 0; i < len; i++) {
2005 Indexer ix = (Indexer) indexers [i];
2007 if ((ix.ModFlags & modflags) == 0)
2009 if ((ix.ModFlags & static_mask) != static_flags)
2015 if (b != null && filter (b, criteria) == true) {
2016 if (members == null)
2017 members = new ArrayList ();
2023 if (b != null && filter (b, criteria) == true) {
2024 if (members == null)
2025 members = new ArrayList ();
2033 if ((mt & MemberTypes.Event) != 0) {
2034 if (events != null) {
2035 int len = events.Count;
2036 for (int i = 0; i < len; i++) {
2037 Event e = (Event) events [i];
2039 if ((e.ModFlags & modflags) == 0)
2041 if ((e.ModFlags & static_mask) != static_flags)
2044 MemberInfo eb = e.EventBuilder;
2045 if (eb != null && filter (eb, criteria) == true) {
2046 if (members == null)
2047 members = new ArrayList ();
2049 members.Add (e.EventBuilder);
2055 if ((mt & MemberTypes.Property) != 0){
2056 if (properties != null) {
2057 int len = properties.Count;
2058 for (int i = 0; i < len; i++) {
2059 Property p = (Property) properties [i];
2061 if ((p.ModFlags & modflags) == 0)
2063 if ((p.ModFlags & static_mask) != static_flags)
2066 MemberInfo pb = p.PropertyBuilder;
2067 if (pb != null && filter (pb, criteria) == true) {
2068 if (members == null)
2069 members = new ArrayList ();
2071 members.Add (p.PropertyBuilder);
2076 if (indexers != null) {
2077 int len = indexers.Count;
2078 for (int i = 0; i < len; i++) {
2079 Indexer ix = (Indexer) indexers [i];
2081 if ((ix.ModFlags & modflags) == 0)
2083 if ((ix.ModFlags & static_mask) != static_flags)
2086 MemberInfo ib = ix.PropertyBuilder;
2087 if (ib != null && filter (ib, criteria) == true) {
2088 if (members == null)
2089 members = new ArrayList ();
2091 members.Add (ix.PropertyBuilder);
2097 if ((mt & MemberTypes.NestedType) != 0)
2098 FindMembers_NestedTypes (modflags, bf, filter, criteria, ref members);
2100 if ((mt & MemberTypes.Constructor) != 0){
2101 if (((bf & BindingFlags.Instance) != 0) && (instance_constructors != null)){
2102 int len = instance_constructors.Count;
2103 for (int i = 0; i < len; i++) {
2104 Constructor c = (Constructor) instance_constructors [i];
2106 ConstructorBuilder cb = c.ConstructorBuilder;
2107 if (cb != null && filter (cb, criteria) == true) {
2108 if (members == null)
2109 members = new ArrayList ();
2116 if (((bf & BindingFlags.Static) != 0) && (default_static_constructor != null)){
2117 ConstructorBuilder cb =
2118 default_static_constructor.ConstructorBuilder;
2120 if (cb != null && filter (cb, criteria) == true) {
2121 if (members == null)
2122 members = new ArrayList ();
2130 // Lookup members in base if requested.
2132 if ((bf & BindingFlags.DeclaredOnly) == 0) {
2133 if (TypeBuilder.BaseType != null) {
2134 MemberList list = FindMembers (TypeBuilder.BaseType, mt, bf, filter, criteria);
2135 if (list.Count > 0) {
2136 if (members == null)
2137 members = new ArrayList ();
2139 members.AddRange (list);
2145 Timer.StopTimer (TimerType.TcFindMembers);
2147 if (members == null)
2148 return MemberList.Empty;
2150 return new MemberList (members);
2153 public override MemberCache MemberCache {
2155 return member_cache;
2159 public static MemberList FindMembers (Type t, MemberTypes mt, BindingFlags bf,
2160 MemberFilter filter, object criteria)
2162 DeclSpace ds = TypeManager.LookupDeclSpace (t);
2165 return ds.FindMembers (mt, bf, filter, criteria);
2167 return new MemberList (t.FindMembers (mt, bf, filter, criteria));
2171 // FindMethods will look for methods not only in the type `t', but in
2172 // any interfaces implemented by the type.
2174 public static MethodInfo [] FindMethods (Type t, BindingFlags bf,
2175 MemberFilter filter, object criteria)
2181 /// Emits the values for the constants
2183 public void EmitConstants ()
2185 if (constants != null)
2186 foreach (Const con in constants)
2191 void CheckMemberUsage (MemberCoreArrayList al, string member_type)
2196 foreach (MemberCore mc in al) {
2197 if ((mc.ModFlags & Modifiers.Accessibility) != Modifiers.PRIVATE)
2201 Report.Warning (169, 3, mc.Location, "The private {0} `{1}' is never used", member_type, mc.GetSignatureForError ());
2206 public virtual void VerifyMembers ()
2209 // Check for internal or private fields that were never assigned
2211 if (RootContext.WarningLevel >= 3) {
2212 CheckMemberUsage (properties, "property");
2213 CheckMemberUsage (methods, "method");
2214 CheckMemberUsage (constants, "constant");
2216 if (fields != null){
2217 foreach (FieldMember f in fields) {
2218 if ((f.ModFlags & Modifiers.Accessibility) != Modifiers.PRIVATE)
2222 if ((f.caching_flags & Flags.IsAssigned) == 0)
2223 Report.Warning (169, 3, f.Location, "The private field `{0}' is never used", f.GetSignatureForError ());
2226 const int error_code = 414;
2228 const int error_code = 169;
2230 Report.Warning (error_code, 3, f.Location, "The private field `{0}' is assigned but its value is never used",
2231 f.GetSignatureForError ());
2237 // Only report 649 on level 4
2239 if (RootContext.WarningLevel < 4)
2242 if ((f.caching_flags & Flags.IsAssigned) != 0)
2245 Report.Warning (649, 4, f.Location, "Field `{0}' is never assigned to, and will always have its default value `{1}'",
2246 f.GetSignatureForError (), f.Type.Type.IsValueType ? Activator.CreateInstance (f.Type.Type).ToString() : "null");
2253 /// Emits the code, this step is performed after all
2254 /// the types, enumerations, constructors
2256 public virtual void EmitType ()
2258 if (OptAttributes != null)
2259 OptAttributes.Emit (ec, this);
2261 if (IsGeneric && !(this is ClassPart)) {
2262 int offset = CountTypeParameters - CurrentTypeParameters.Length;
2263 for (int i = offset; i < gen_params.Length; i++)
2264 CurrentTypeParameters [i - offset].EmitAttributes (ec);
2268 // Structs with no fields need to have at least one byte.
2269 // The right thing would be to set the PackingSize in a DefineType
2270 // but there are no functions that allow interfaces *and* the size to
2274 if (Kind == Kind.Struct && first_nonstatic_field == null){
2275 FieldBuilder fb = TypeBuilder.DefineField ("$PRIVATE$", TypeManager.byte_type,
2276 FieldAttributes.Private);
2278 if (HasExplicitLayout){
2279 object [] ctor_args = new object [1];
2282 CustomAttributeBuilder cba = new CustomAttributeBuilder (
2283 TypeManager.field_offset_attribute_ctor, ctor_args);
2284 fb.SetCustomAttribute (cba);
2290 if (instance_constructors != null) {
2291 if (TypeBuilder.IsSubclassOf (TypeManager.attribute_type) && RootContext.VerifyClsCompliance && IsClsComplianceRequired (this)) {
2292 bool has_compliant_args = false;
2294 foreach (Constructor c in instance_constructors) {
2297 if (has_compliant_args)
2300 has_compliant_args = c.HasCompliantArgs;
2302 if (!has_compliant_args)
2303 Report.Error (3015, Location, "`{0}' has no accessible constructors which use only CLS-compliant types", GetSignatureForError ());
2305 foreach (Constructor c in instance_constructors)
2310 // Can not continue if constants are broken
2312 if (Report.Errors > 0)
2315 if (default_static_constructor != null)
2316 default_static_constructor.Emit ();
2318 if (methods != null){
2319 foreach (Method m in methods)
2323 if (operators != null)
2324 foreach (Operator o in operators)
2327 if (properties != null)
2328 foreach (Property p in properties)
2331 if (indexers != null){
2336 foreach (FieldMember f in fields)
2339 if (events != null){
2340 foreach (Event e in Events)
2344 if (delegates != null) {
2345 foreach (Delegate d in Delegates) {
2350 if (enums != null) {
2351 foreach (Enum e in enums) {
2356 if (parts != null) {
2357 foreach (ClassPart part in parts)
2361 if ((Pending != null) && !(this is ClassPart))
2362 if (Pending.VerifyPendingMethods ())
2365 if (iterators != null)
2366 foreach (Iterator iterator in iterators)
2367 iterator.EmitType ();
2369 // if (types != null)
2370 // foreach (TypeContainer tc in types)
2374 public override void CloseType ()
2376 if ((caching_flags & Flags.CloseTypeCreated) != 0)
2380 caching_flags |= Flags.CloseTypeCreated;
2381 TypeBuilder.CreateType ();
2382 } catch (TypeLoadException){
2384 // This is fine, the code still created the type
2386 // Report.Warning (-20, "Exception while creating class: " + TypeBuilder.Name);
2387 // Console.WriteLine (e.Message);
2389 Console.WriteLine ("In type: " + Name);
2394 foreach (Enum en in Enums)
2398 foreach (TypeContainer tc in Types)
2399 if (tc.Kind == Kind.Struct)
2402 foreach (TypeContainer tc in Types)
2403 if (tc.Kind != Kind.Struct)
2407 if (Delegates != null)
2408 foreach (Delegate d in Delegates)
2411 if (Iterators != null)
2412 foreach (Iterator i in Iterators)
2420 initialized_fields = null;
2421 initialized_static_fields = null;
2430 default_constructor = null;
2431 default_static_constructor = null;
2433 OptAttributes = null;
2436 member_cache = null;
2440 // Performs the validation on a Method's modifiers (properties have
2441 // the same properties).
2443 public bool MethodModifiersValid (MemberCore mc)
2445 const int vao = (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE);
2446 const int va = (Modifiers.VIRTUAL | Modifiers.ABSTRACT);
2447 const int nv = (Modifiers.NEW | Modifiers.VIRTUAL);
2449 int flags = mc.ModFlags;
2452 // At most one of static, virtual or override
2454 if ((flags & Modifiers.STATIC) != 0){
2455 if ((flags & vao) != 0){
2456 Report.Error (112, mc.Location, "A static member `{0}' cannot be marked as override, virtual or abstract",
2457 mc.GetSignatureForError ());
2462 if (Kind == Kind.Struct){
2463 if ((flags & va) != 0){
2464 Modifiers.Error_InvalidModifier (mc.Location, "virtual or abstract");
2469 if ((flags & Modifiers.OVERRIDE) != 0 && (flags & nv) != 0){
2470 Report.Error (113, mc.Location, "A member `{0}' marked as override cannot be marked as new or virtual",
2471 mc.GetSignatureForError ());
2476 // If the declaration includes the abstract modifier, then the
2477 // declaration does not include static, virtual or extern
2479 if ((flags & Modifiers.ABSTRACT) != 0){
2480 if ((flags & Modifiers.EXTERN) != 0){
2482 180, mc.Location, "`{0}' cannot be both extern and abstract", mc.GetSignatureForError ());
2486 if ((flags & Modifiers.SEALED) != 0) {
2487 Report.Error (502, mc.Location, "`{0}' cannot be both abstract and sealed", mc.GetSignatureForError ());
2491 if ((flags & Modifiers.VIRTUAL) != 0){
2492 Report.Error (503, mc.Location, "The abstract method `{0}' cannot be marked virtual", mc.GetSignatureForError ());
2496 if ((ModFlags & Modifiers.ABSTRACT) == 0){
2497 Report.Error (513, mc.Location, "`{0}' is abstract but it is contained in nonabstract class", mc.GetSignatureForError ());
2502 if ((flags & Modifiers.PRIVATE) != 0){
2503 if ((flags & vao) != 0){
2504 Report.Error (621, mc.Location, "`{0}': virtual or abstract members cannot be private", mc.GetSignatureForError ());
2509 if ((flags & Modifiers.SEALED) != 0){
2510 if ((flags & Modifiers.OVERRIDE) == 0){
2511 Report.Error (238, mc.Location, "`{0}' cannot be sealed because it is not an override", mc.GetSignatureForError ());
2519 public bool UserDefinedStaticConstructor {
2521 return default_static_constructor != null;
2525 public Constructor DefaultStaticConstructor {
2526 get { return default_static_constructor; }
2529 protected override bool VerifyClsCompliance (DeclSpace ds)
2531 if (!base.VerifyClsCompliance (ds))
2536 Type base_type = TypeBuilder.BaseType;
2537 if (base_type != null && !AttributeTester.IsClsCompliant (base_type)) {
2538 Report.Error (3009, Location, "`{0}': base type `{1}' is not CLS-compliant", GetSignatureForError (), TypeManager.CSharpName (base_type));
2541 if (!Parent.IsClsComplianceRequired (ds)) {
2542 Report.Error (3018, Location, "`{0}' cannot be marked as CLS-compliant because it is a member of non CLS-compliant type `{1}'",
2543 GetSignatureForError (), Parent.GetSignatureForError ());
2550 /// Checks whether container name is CLS Compliant
2552 void VerifyClsName ()
2554 Hashtable base_members = base_cache == null ?
2556 base_cache.GetPublicMembers ();
2557 Hashtable this_members = new Hashtable ();
2559 foreach (DictionaryEntry entry in defined_names) {
2560 MemberCore mc = (MemberCore)entry.Value;
2561 if (!mc.IsClsComplianceRequired (mc.Parent))
2564 string name = (string) entry.Key;
2565 string basename = name.Substring (name.LastIndexOf ('.') + 1);
2567 string lcase = basename.ToLower (System.Globalization.CultureInfo.InvariantCulture);
2568 object found = base_members [lcase];
2569 if (found == null) {
2570 found = this_members [lcase];
2571 if (found == null) {
2572 this_members.Add (lcase, mc);
2577 if ((mc.ModFlags & Modifiers.OVERRIDE) != 0)
2580 if (found is MemberInfo) {
2581 if (basename == ((MemberInfo) found).Name)
2583 Report.SymbolRelatedToPreviousError ((MemberInfo) found);
2585 Report.SymbolRelatedToPreviousError ((MemberCore) found);
2587 Report.Warning (3005, 1, mc.Location, "Identifier `{0}' differing only in case is not CLS-compliant", mc.GetSignatureForError ());
2593 /// Performs checks for an explicit interface implementation. First it
2594 /// checks whether the `interface_type' is a base inteface implementation.
2595 /// Then it checks whether `name' exists in the interface type.
2597 public virtual bool VerifyImplements (MemberBase mb)
2599 if (ifaces != null) {
2600 foreach (Type t in ifaces){
2601 if (t == mb.InterfaceType)
2606 Report.Error (540, mb.Location, "`{0}': containing type does not implement interface `{1}'",
2607 mb.GetSignatureForError (), TypeManager.CSharpName (mb.InterfaceType));
2611 public virtual void Mark_HasEquals ()
2613 Methods.HasEquals = true;
2616 public virtual void Mark_HasGetHashCode ()
2618 Methods.HasGetHashCode = true;
2625 string IMemberContainer.Name {
2631 Type IMemberContainer.Type {
2637 MemberCache IMemberContainer.MemberCache {
2639 return member_cache;
2643 bool IMemberContainer.IsInterface {
2645 return Kind == Kind.Interface;
2649 MemberList IMemberContainer.GetMembers (MemberTypes mt, BindingFlags bf)
2651 BindingFlags new_bf = bf | BindingFlags.DeclaredOnly;
2653 if (GenericType != null)
2654 return TypeManager.FindMembers (GenericType, mt, new_bf,
2657 return FindMembers (mt, new_bf, null, null);
2661 // Generates xml doc comments (if any), and if required,
2662 // handle warning report.
2664 internal override void GenerateDocComment (DeclSpace ds)
2666 DocUtil.GenerateTypeDocComment (this, ds);
2669 public override string DocCommentHeader {
2670 get { return "T:"; }
2673 public virtual MemberCache BaseCache {
2675 if (base_cache != null)
2677 if (TypeBuilder.BaseType != null)
2678 base_cache = TypeManager.LookupMemberCache (TypeBuilder.BaseType);
2679 if (TypeBuilder.IsInterface)
2680 base_cache = TypeManager.LookupBaseInterfacesCache (TypeBuilder);
2687 public class PartialContainer : TypeContainer {
2689 public readonly Namespace Namespace;
2690 public readonly int OriginalModFlags;
2691 public readonly int AllowedModifiers;
2692 public readonly TypeAttributes DefaultTypeAttributes;
2693 public ListDictionary DeclarativeSecurity;
2695 static PartialContainer Create (NamespaceEntry ns, TypeContainer parent,
2696 MemberName member_name, int mod_flags, Kind kind)
2699 if (!CheckModFlags (0, mod_flags, member_name))
2702 PartialContainer pc = RootContext.Tree.GetDecl (member_name) as PartialContainer;
2704 if (pc.Kind != kind) {
2706 261, member_name.Location,
2707 "Partial declarations of `{0}' must be all classes, " +
2708 "all structs or all interfaces",
2709 member_name.GetTypeName ());
2713 if (!CheckModFlags (pc.OriginalModFlags, mod_flags, member_name))
2715 pc.ModFlags |= (mod_flags & pc.AllowedModifiers);
2718 if (pc.CountTypeParameters != member_name.CountTypeArguments) {
2720 264, member_name.Location,
2721 "Partial declarations of `{0}' must have the " +
2722 "same type parameter names in the same order",
2723 member_name.GetTypeName ());
2727 TypeParameterName[] pc_names = pc.MemberName.TypeArguments.GetDeclarations ();
2728 TypeParameterName[] names = member_name.TypeArguments.GetDeclarations ();
2730 for (int i = 0; i < pc.CountTypeParameters; i++) {
2731 if (pc_names [i].Name == names [i].Name)
2735 264, member_name.Location,
2736 "Partial declarations of `{0}' must have the " +
2737 "same type parameter names in the same order",
2738 member_name.GetTypeName ());
2746 if (parent is ClassPart)
2747 parent = ((ClassPart) parent).PartialContainer;
2749 pc = new PartialContainer (ns.NS, parent, member_name, mod_flags, kind);
2751 if (kind == Kind.Interface) {
2752 if (!parent.AddInterface (pc))
2754 } else if (kind == Kind.Class || kind == Kind.Struct) {
2755 if (!parent.AddClassOrStruct (pc))
2758 throw new InvalidOperationException ();
2760 RootContext.Tree.RecordDecl (ns.NS, member_name, pc);
2761 // This is needed to define our type parameters; we define the constraints later.
2762 pc.SetParameterInfo (null);
2766 static bool CheckModFlags (int flags_org, int flags, MemberName member_name)
2768 // Check (abstract|static|sealed) sanity.
2769 int tmp = (flags_org | flags) & (Modifiers.ABSTRACT | Modifiers.SEALED | Modifiers.STATIC);
2770 if ((tmp & Modifiers.ABSTRACT) != 0) {
2771 if ((tmp & (Modifiers.STATIC | Modifiers.SEALED)) != 0) {
2773 418, member_name.Location,
2774 "`{0}': an abstract class cannot be sealed or static", member_name.ToString ());
2777 } else if (tmp == (Modifiers.SEALED | Modifiers.STATIC)) {
2778 Report.Error (441, member_name.Location, "`{0}': a class cannot be both static and sealed", member_name.ToString ());
2786 if (0 != ((flags_org ^ flags) & (0xFFFFFFFF ^ (Modifiers.SEALED | Modifiers.ABSTRACT)))) {
2788 262, member_name.Location, "Partial declarations of `{0}' " +
2789 "have conflicting accessibility modifiers",
2790 member_name.GetName ());
2796 public static ClassPart CreatePart (NamespaceEntry ns, TypeContainer parent,
2797 MemberName name, int mod, Attributes attrs,
2798 Kind kind, Location loc)
2800 PartialContainer pc = Create (ns, parent, name, mod, kind);
2802 // An error occured; create a dummy container, but don't
2804 pc = new PartialContainer (ns.NS, parent, name, mod, kind);
2807 ClassPart part = new ClassPart (ns, pc, parent, mod, attrs, kind);
2812 protected PartialContainer (Namespace ns, TypeContainer parent,
2813 MemberName name, int mod, Kind kind)
2814 : base (null, parent, name, null, kind)
2816 this.Namespace = ns;
2820 AllowedModifiers = Class.AllowedModifiers;
2821 DefaultTypeAttributes = Class.DefaultTypeAttributes;
2825 AllowedModifiers = Struct.AllowedModifiers;
2826 DefaultTypeAttributes = Struct.DefaultTypeAttributes;
2829 case Kind.Interface:
2830 AllowedModifiers = Interface.AllowedModifiers;
2831 DefaultTypeAttributes = Interface.DefaultTypeAttributes;
2835 throw new InvalidOperationException ();
2839 if (parent.Parent == null)
2840 accmods = Modifiers.INTERNAL;
2842 accmods = Modifiers.PRIVATE;
2844 // FIXME: remove this nasty fix for bug #77370 when
2845 // we get good AllowModifiersProp implementation.
2846 if ((mod & Modifiers.STATIC) != 0) {
2847 AllowedModifiers |= Modifiers.STATIC;
2848 AllowedModifiers &= ~ (Modifiers.ABSTRACT | Modifiers.SEALED);
2851 this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, Location);
2852 this.OriginalModFlags = mod;
2855 public override void EmitType ()
2859 if (DeclarativeSecurity != null) {
2860 foreach (DictionaryEntry de in DeclarativeSecurity) {
2861 TypeBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
2866 public override PendingImplementation GetPendingImplementations ()
2868 return PendingImplementation.GetPendingImplementations (this);
2871 public override bool MarkForDuplicationCheck ()
2876 protected override TypeAttributes TypeAttr {
2878 return base.TypeAttr | DefaultTypeAttributes;
2883 public class ClassPart : TypeContainer, IMemberContainer {
2884 public readonly PartialContainer PartialContainer;
2885 public readonly bool IsPartial;
2887 Constraints[] constraints;
2889 public ClassPart (NamespaceEntry ns, PartialContainer pc, TypeContainer parent,
2890 int mod, Attributes attrs, Kind kind)
2891 : base (ns, parent, pc.MemberName, attrs, kind)
2893 this.PartialContainer = pc;
2894 this.IsPartial = true;
2897 if (parent == null || parent == RootContext.Tree.Types)
2898 accmods = Modifiers.INTERNAL;
2900 accmods = Modifiers.PRIVATE;
2902 this.ModFlags = Modifiers.Check (pc.AllowedModifiers, mod, accmods, pc.MemberName.Location);
2905 constraints = new Constraints [pc.CountCurrentTypeParameters];
2908 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
2910 if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
2911 if (PartialContainer.DeclarativeSecurity == null)
2912 PartialContainer.DeclarativeSecurity = new ListDictionary ();
2914 a.ExtractSecurityPermissionSet (PartialContainer.DeclarativeSecurity);
2918 base.ApplyAttributeBuilder (a, cb);
2921 public override PendingImplementation GetPendingImplementations ()
2923 return PartialContainer.Pending;
2926 public override bool VerifyImplements (MemberBase mb)
2928 return PartialContainer.VerifyImplements (mb);
2931 public override void SetParameterInfo (ArrayList constraints_list)
2933 if (constraints_list == null)
2936 TypeParameter[] current_params = PartialContainer.CurrentTypeParameters;
2937 for (int i = 0; i < constraints.Length; i++) {
2938 foreach (Constraints constraint in constraints_list) {
2939 if (constraint.TypeParameter == current_params [i].Name) {
2940 constraints [i] = constraint;
2947 public bool DefineTypeParameters ()
2949 TypeParameter[] current_params = PartialContainer.CurrentTypeParameters;
2951 for (int i = 0; i < current_params.Length; i++) {
2952 Constraints new_constraints = constraints [i];
2953 if (new_constraints == null)
2956 if (!current_params [i].UpdateConstraints (ec, new_constraints)) {
2957 Report.Error (265, Location, "Partial declarations of `{0}' have " +
2958 "inconsistent constraints for type parameter `{1}'.",
2959 MemberName.GetTypeName (), current_params [i].Name);
2964 for (int i = 0; i < current_params.Length; i++) {
2965 if (!current_params [i].Resolve (this))
2969 foreach (TypeParameter type_param in PartialContainer.TypeParameters) {
2970 if (!type_param.DefineType (ec))
2977 public override void RegisterFieldForInitialization (FieldBase field)
2979 PartialContainer.RegisterFieldForInitialization (field);
2982 public override bool EmitFieldInitializers (EmitContext ec)
2984 return PartialContainer.EmitFieldInitializers (ec);
2987 public override Type FindNestedType (string name)
2989 return PartialContainer.FindNestedType (name);
2992 public override MemberCache BaseCache {
2994 return PartialContainer.BaseCache;
2998 public override TypeBuilder DefineType ()
3000 throw new InternalErrorException ("Should not get here");
3003 public override void Mark_HasEquals ()
3005 PartialContainer.Mark_HasEquals ();
3008 public override void Mark_HasGetHashCode ()
3010 PartialContainer.Mark_HasGetHashCode ();
3014 public abstract class ClassOrStruct : TypeContainer {
3015 bool has_explicit_layout = false;
3016 ListDictionary declarative_security;
3018 public ClassOrStruct (NamespaceEntry ns, TypeContainer parent,
3019 MemberName name, Attributes attrs, Kind kind)
3020 : base (ns, parent, name, attrs, kind)
3024 public override PendingImplementation GetPendingImplementations ()
3026 return PendingImplementation.GetPendingImplementations (this);
3029 public override bool HasExplicitLayout {
3031 return has_explicit_layout;
3035 public override void VerifyMembers ()
3037 base.VerifyMembers ();
3039 if ((events != null) && (RootContext.WarningLevel >= 3)) {
3040 foreach (Event e in events){
3041 if ((e.caching_flags & Flags.IsAssigned) == 0)
3042 Report.Warning (67, 3, e.Location, "The event `{0}' is never used", e.GetSignatureForError ());
3047 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
3049 if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
3050 if (declarative_security == null)
3051 declarative_security = new ListDictionary ();
3053 a.ExtractSecurityPermissionSet (declarative_security);
3057 if (a.Type == TypeManager.struct_layout_attribute_type && a.GetLayoutKindValue () == LayoutKind.Explicit)
3058 has_explicit_layout = true;
3060 base.ApplyAttributeBuilder (a, cb);
3063 public override void Emit()
3067 if (declarative_security != null) {
3068 foreach (DictionaryEntry de in declarative_security) {
3069 TypeBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
3076 /// Class handles static classes declaration
3078 public sealed class StaticClass: Class {
3079 public StaticClass (NamespaceEntry ns, TypeContainer parent, MemberName name, int mod,
3081 : base (ns, parent, name, mod, attrs)
3083 if (RootContext.Version == LanguageVersion.ISO_1) {
3084 Report.FeatureIsNotStandardized (Location, "static classes");
3088 protected override int AllowedModifiersProp {
3090 return Modifiers.NEW | Modifiers.PUBLIC | Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE |
3091 Modifiers.STATIC | Modifiers.UNSAFE;
3095 protected override void DefineContainerMembers (MemberCoreArrayList list)
3100 foreach (MemberCore m in list) {
3101 if (m is Operator) {
3102 Report.Error (715, m.Location, "`{0}': Static classes cannot contain user-defined operators", m.GetSignatureForError ());
3106 if (m is Destructor) {
3107 Report.Error (711, m.Location, "`{0}': Static classes cannot contain destructor", GetSignatureForError ());
3111 if ((m.ModFlags & Modifiers.PROTECTED) != 0) {
3112 Report.Error (1057, m.Location, "`{0}': Static classes cannot contain protected members", m.GetSignatureForError ());
3117 Report.Error (720, m.Location, "`{0}': cannot declare indexers in a static class", m.GetSignatureForError ());
3121 if ((m.ModFlags & Modifiers.STATIC) != 0 || m is Enum || m is Delegate)
3124 if (m is Constructor) {
3125 Report.Error (710, m.Location, "`{0}': Static classes cannot have instance constructors", GetSignatureForError ());
3129 Report.Error (708, m.Location, "`{0}': cannot declare instance members in a static class", m.GetSignatureForError ());
3132 base.DefineContainerMembers (list);
3135 public override TypeBuilder DefineType()
3137 if ((ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) == (Modifiers.SEALED | Modifiers.STATIC)) {
3138 Report.Error (441, Location, "`{0}': a class cannot be both static and sealed", GetSignatureForError ());
3142 TypeBuilder tb = base.DefineType ();
3146 if (ptype != TypeManager.object_type) {
3147 Report.Error (713, Location, "Static class `{0}' cannot derive from type `{1}'. Static classes must derive from object", GetSignatureForError (), TypeManager.CSharpName (ptype));
3151 if (ifaces != null) {
3152 foreach (Type t in ifaces)
3153 Report.SymbolRelatedToPreviousError (t);
3154 Report.Error (714, Location, "`{0}': static classes cannot implement interfaces", GetSignatureForError ());
3159 protected override TypeAttributes TypeAttr {
3161 return base.TypeAttr | TypeAttributes.Abstract | TypeAttributes.Sealed;
3166 public class Class : ClassOrStruct {
3167 // TODO: remove this and use only AllowedModifiersProp to fix partial classes bugs
3168 public const int AllowedModifiers =
3171 Modifiers.PROTECTED |
3172 Modifiers.INTERNAL |
3174 Modifiers.ABSTRACT |
3178 public Class (NamespaceEntry ns, TypeContainer parent, MemberName name, int mod,
3180 : base (ns, parent, name, attrs, Kind.Class)
3182 this.ModFlags = mod;
3185 virtual protected int AllowedModifiersProp {
3187 return AllowedModifiers;
3191 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
3193 if (a.Type == TypeManager.attribute_usage_type) {
3194 if (ptype != TypeManager.attribute_type &&
3195 !ptype.IsSubclassOf (TypeManager.attribute_type) &&
3196 TypeBuilder.FullName != "System.Attribute") {
3197 Report.Error (641, a.Location, "Attribute `{0}' is only valid on classes derived from System.Attribute", a.GetSignatureForError ());
3201 if (a.Type == TypeManager.conditional_attribute_type &&
3202 !(ptype == TypeManager.attribute_type || ptype.IsSubclassOf (TypeManager.attribute_type))) {
3203 Report.Error (1689, a.Location, "Attribute 'System.Diagnostics.ConditionalAttribute' is only valid on methods or attribute classes");
3207 if (AttributeTester.IsAttributeExcluded (a.Type))
3210 base.ApplyAttributeBuilder (a, cb);
3213 public const TypeAttributes DefaultTypeAttributes =
3214 TypeAttributes.AutoLayout | TypeAttributes.Class;
3216 public override TypeBuilder DefineType()
3218 if ((ModFlags & Modifiers.ABSTRACT) == Modifiers.ABSTRACT && (ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) != 0) {
3219 Report.Error (418, Location, "`{0}': an abstract class cannot be sealed or static", GetSignatureForError ());
3223 int accmods = Parent.Parent == null ? Modifiers.INTERNAL : Modifiers.PRIVATE;
3224 ModFlags = Modifiers.Check (AllowedModifiersProp, ModFlags, accmods, Location);
3226 return base.DefineType ();
3229 /// Search for at least one defined condition in ConditionalAttribute of attribute class
3230 /// Valid only for attribute classes.
3231 public bool IsExcluded ()
3233 if ((caching_flags & Flags.Excluded_Undetected) == 0)
3234 return (caching_flags & Flags.Excluded) != 0;
3236 caching_flags &= ~Flags.Excluded_Undetected;
3238 if (OptAttributes == null)
3241 Attribute[] attrs = OptAttributes.SearchMulti (TypeManager.conditional_attribute_type, ec);
3246 foreach (Attribute a in attrs) {
3247 string condition = a.GetConditionalAttributeValue (Parent.EmitContext);
3248 if (RootContext.AllDefines.Contains (condition))
3252 caching_flags |= Flags.Excluded;
3257 // FIXME: How do we deal with the user specifying a different
3260 protected override TypeAttributes TypeAttr {
3262 return base.TypeAttr | DefaultTypeAttributes;
3267 public class Struct : ClassOrStruct {
3269 // Modifiers allowed in a struct declaration
3271 public const int AllowedModifiers =
3274 Modifiers.PROTECTED |
3275 Modifiers.INTERNAL |
3279 public Struct (NamespaceEntry ns, TypeContainer parent, MemberName name,
3280 int mod, Attributes attrs)
3281 : base (ns, parent, name, attrs, Kind.Struct)
3285 if (parent.Parent == null)
3286 accmods = Modifiers.INTERNAL;
3288 accmods = Modifiers.PRIVATE;
3290 this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, Location);
3292 this.ModFlags |= Modifiers.SEALED;
3295 public const TypeAttributes DefaultTypeAttributes =
3296 TypeAttributes.SequentialLayout |
3297 TypeAttributes.Sealed |
3298 TypeAttributes.BeforeFieldInit;
3301 // FIXME: Allow the user to specify a different set of attributes
3302 // in some cases (Sealed for example is mandatory for a class,
3303 // but what SequentialLayout can be changed
3305 protected override TypeAttributes TypeAttr {
3307 return base.TypeAttr | DefaultTypeAttributes;
3315 public class Interface : TypeContainer, IMemberContainer {
3318 /// Modifiers allowed in a class declaration
3320 public const int AllowedModifiers =
3323 Modifiers.PROTECTED |
3324 Modifiers.INTERNAL |
3328 public Interface (NamespaceEntry ns, TypeContainer parent, MemberName name, int mod,
3330 : base (ns, parent, name, attrs, Kind.Interface)
3334 if (parent.Parent == null)
3335 accmods = Modifiers.INTERNAL;
3337 accmods = Modifiers.PRIVATE;
3339 this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, name.Location);
3342 public override PendingImplementation GetPendingImplementations ()
3347 public const TypeAttributes DefaultTypeAttributes =
3348 TypeAttributes.AutoLayout |
3349 TypeAttributes.Abstract |
3350 TypeAttributes.Interface;
3352 protected override TypeAttributes TypeAttr {
3354 return base.TypeAttr | DefaultTypeAttributes;
3358 protected override bool VerifyClsCompliance (DeclSpace ds)
3360 if (!base.VerifyClsCompliance (ds))
3363 if (ifaces != null) {
3364 foreach (Type t in ifaces) {
3365 if (AttributeTester.IsClsCompliant (t))
3368 Report.SymbolRelatedToPreviousError (t);
3369 Report.Warning (3027, 1, Location, "`{0}' is not CLS-compliant because base interface `{1}' is not CLS-compliant",
3370 GetSignatureForError (), TypeManager.CSharpName (t));
3378 public abstract class MethodCore : MemberBase {
3379 public readonly Parameters Parameters;
3380 protected ToplevelBlock block;
3382 // Whether this is an operator method.
3383 public Operator IsOperator;
3386 // The method we're overriding if this is an override method.
3388 protected MethodInfo base_method = null;
3390 static string[] attribute_targets = new string [] { "method", "return" };
3392 public MethodCore (TypeContainer parent, GenericMethod generic,
3393 Expression type, int mod, int allowed_mod, bool is_iface,
3394 MemberName name, Attributes attrs, Parameters parameters)
3395 : base (parent, generic, type, mod, allowed_mod, Modifiers.PRIVATE,
3398 Parameters = parameters;
3399 IsInterface = is_iface;
3403 // Returns the System.Type array for the parameters of this method
3405 public Type [] ParameterTypes {
3407 return Parameters.Types;
3411 public Parameters ParameterInfo
3418 public override EmitContext EmitContext {
3419 get { return ds.EmitContext; }
3422 public ToplevelBlock Block {
3432 public void SetYields ()
3434 ModFlags |= Modifiers.METHOD_YIELDS;
3437 protected override bool CheckBase ()
3439 if (!base.CheckBase ())
3442 // Check whether arguments were correct.
3443 if (!DoDefineParameters ())
3446 if ((caching_flags & Flags.TestMethodDuplication) != 0 && !CheckForDuplications ())
3452 // Is null for System.Object while compiling corlib and base interfaces
3453 if (Parent.BaseCache == null) {
3454 if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) {
3455 Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
3460 Type base_ret_type = null;
3461 base_method = FindOutBaseMethod (Parent, ref base_ret_type);
3463 // method is override
3464 if (base_method != null) {
3466 if (!CheckMethodAgainstBase ())
3469 if ((ModFlags & Modifiers.NEW) == 0) {
3470 if (!TypeManager.IsEqual (MemberType, TypeManager.TypeToCoreType (base_ret_type))) {
3471 Report.SymbolRelatedToPreviousError (base_method);
3472 if (this is PropertyBase) {
3473 Report.Error (1715, Location, "`{0}': type must be `{1}' to match overridden member `{2}'",
3474 GetSignatureForError (), TypeManager.CSharpName (base_ret_type), TypeManager.CSharpSignature (base_method));
3477 Report.Error (508, Location, "`{0}': return type must be `{1}' to match overridden member `{2}'",
3478 GetSignatureForError (), TypeManager.CSharpName (base_ret_type), TypeManager.CSharpSignature (base_method));
3483 if (base_method.IsAbstract && !IsInterface) {
3484 Report.SymbolRelatedToPreviousError (base_method);
3485 Report.Error (533, Location, "`{0}' hides inherited abstract member `{1}'",
3486 GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3491 if (base_method.IsSpecialName && !(this is PropertyBase)) {
3492 Report.Error (115, Location, "`{0}': no suitable method found to override", GetSignatureForError ());
3496 if (Name == "Equals" && Parameters.Count == 1 && ParameterTypes [0] == TypeManager.object_type)
3497 Parent.Mark_HasEquals ();
3498 else if (Name == "GetHashCode" && Parameters.Empty)
3499 Parent.Mark_HasGetHashCode ();
3501 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
3502 ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (base_method);
3504 EmitContext ec = new EmitContext (this.Parent, this.Parent, Location, null, null, ModFlags, false);
3505 if (OptAttributes == null || !OptAttributes.Contains (TypeManager.obsolete_attribute_type, ec)) {
3506 Report.SymbolRelatedToPreviousError (base_method);
3507 Report.Warning (672, 1, Location, "Member `{0}' overrides obsolete member `{1}'. Add the Obsolete attribute to `{0}'",
3508 GetSignatureForError (), TypeManager.CSharpSignature (base_method) );
3515 MemberInfo conflict_symbol = Parent.FindBaseMemberWithSameName (Name, !(this is Property));
3516 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
3517 if (conflict_symbol != null) {
3518 Report.SymbolRelatedToPreviousError (conflict_symbol);
3519 if (this is PropertyBase)
3520 Report.Error (544, Location, "`{0}': cannot override because `{1}' is not a property", GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
3522 Report.Error (505, Location, "`{0}': cannot override because `{1}' is not a method", GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
3524 Report.Error (115, Location, "`{0}': no suitable method found to override", GetSignatureForError ());
3528 if (conflict_symbol == null) {
3529 if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) {
3530 Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
3535 if ((ModFlags & Modifiers.NEW) == 0) {
3536 if (this is Method && conflict_symbol is MethodBase)
3539 Report.SymbolRelatedToPreviousError (conflict_symbol);
3540 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
3541 GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
3548 // Performs various checks on the MethodInfo `mb' regarding the modifier flags
3549 // that have been defined.
3551 // `name' is the user visible name for reporting errors (this is used to
3552 // provide the right name regarding method names and properties)
3554 bool CheckMethodAgainstBase ()
3558 if ((ModFlags & Modifiers.OVERRIDE) != 0){
3559 if (!(base_method.IsAbstract || base_method.IsVirtual)){
3560 Report.Error (506, Location,
3561 "`{0}': cannot override inherited member `{1}' because it is not marked virtual, abstract or override",
3562 GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3566 // Now we check that the overriden method is not final
3568 if (base_method.IsFinal) {
3569 Report.SymbolRelatedToPreviousError (base_method);
3570 Report.Error (239, Location, "`{0}': cannot override inherited member `{1}' because it is sealed",
3571 GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3575 // Check that the permissions are not being changed
3577 MethodAttributes thisp = flags & MethodAttributes.MemberAccessMask;
3578 MethodAttributes base_classp = base_method.Attributes & MethodAttributes.MemberAccessMask;
3580 if (!CheckAccessModifiers (thisp, base_classp, base_method)) {
3581 Error_CannotChangeAccessModifiers (base_method, base_classp, null);
3586 if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0 && Name != "Finalize") {
3587 ModFlags |= Modifiers.NEW;
3588 Report.SymbolRelatedToPreviousError (base_method);
3589 if (!IsInterface && (base_method.IsVirtual || base_method.IsAbstract)) {
3590 Report.Warning (114, 2, Location, "`{0}' hides inherited member `{1}'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword",
3591 GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3593 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
3594 GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3601 protected bool CheckAccessModifiers (MethodAttributes thisp, MethodAttributes base_classp, MethodInfo base_method)
3603 if ((base_classp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
3605 // when overriding protected internal, the method can be declared
3606 // protected internal only within the same assembly
3609 if ((thisp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
3610 if (Parent.TypeBuilder.Assembly != base_method.DeclaringType.Assembly){
3612 // assemblies differ - report an error
3616 } else if (thisp != base_classp) {
3618 // same assembly, but other attributes differ - report an error
3623 } else if ((thisp & MethodAttributes.Family) != MethodAttributes.Family) {
3625 // if it's not "protected internal", it must be "protected"
3629 } else if (Parent.TypeBuilder.Assembly == base_method.DeclaringType.Assembly) {
3631 // protected within the same assembly - an error
3634 } else if ((thisp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem)) !=
3635 (base_classp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem))) {
3637 // protected ok, but other attributes differ - report an error
3643 return (thisp == base_classp);
3647 public bool CheckAbstractAndExtern (bool has_block)
3649 if (Parent.Kind == Kind.Interface)
3653 if ((ModFlags & Modifiers.EXTERN) != 0) {
3654 Report.Error (179, Location, "`{0}' cannot declare a body because it is marked extern",
3655 GetSignatureForError ());
3659 if ((ModFlags & Modifiers.ABSTRACT) != 0) {
3660 Report.Error (500, Location, "`{0}' cannot declare a body because it is marked abstract",
3661 GetSignatureForError ());
3665 if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) == 0) {
3666 Report.Error (501, Location, "`{0}' must declare a body because it is not marked abstract or extern",
3667 GetSignatureForError ());
3675 protected void Error_CannotChangeAccessModifiers (MemberInfo base_method, MethodAttributes ma, string suffix)
3677 Report.SymbolRelatedToPreviousError (base_method);
3678 string base_name = TypeManager.GetFullNameSignature (base_method);
3679 string this_name = GetSignatureForError ();
3680 if (suffix != null) {
3681 base_name += suffix;
3682 this_name += suffix;
3685 Report.Error (507, Location, "`{0}': cannot change access modifiers when overriding `{1}' inherited member `{2}'",
3686 this_name, Modifiers.GetDescription (ma), base_name);
3689 protected static string Error722 {
3691 return "`{0}': static types cannot be used as return types";
3696 /// For custom member duplication search in a container
3698 protected abstract bool CheckForDuplications ();
3701 /// Gets base method and its return type
3703 protected abstract MethodInfo FindOutBaseMethod (TypeContainer container, ref Type base_ret_type);
3705 protected bool DoDefineParameters ()
3707 EmitContext ec = ds.EmitContext;
3709 throw new InternalErrorException ("DoDefineParameters invoked too early");
3711 bool old_unsafe = ec.InUnsafe;
3712 ec.InUnsafe = InUnsafe;
3713 ec.ResolvingGenericMethod = GenericMethod != null;
3715 bool old_obsolete = ec.TestObsoleteMethodUsage;
3716 if (GetObsoleteAttribute () != null || Parent.GetObsoleteAttribute () != null)
3717 ec.TestObsoleteMethodUsage = false;
3719 // Check if arguments were correct
3720 if (!Parameters.Resolve (ec))
3723 ec.ResolvingGenericMethod = false;
3724 ec.InUnsafe = old_unsafe;
3725 ec.TestObsoleteMethodUsage = old_obsolete;
3727 return CheckParameters (ParameterTypes);
3730 bool CheckParameters (Type [] parameters)
3734 foreach (Type partype in parameters){
3735 if (partype == TypeManager.void_type) {
3737 1547, Location, "Keyword 'void' cannot " +
3738 "be used in this context");
3742 if (partype.IsPointer){
3745 if (!TypeManager.VerifyUnManaged (TypeManager.GetElementType (partype), Location))
3749 if (ds.AsAccessible (partype, ModFlags))
3752 if (this is Indexer)
3753 Report.Error (55, Location,
3754 "Inconsistent accessibility: parameter type `" +
3755 TypeManager.CSharpName (partype) + "' is less " +
3756 "accessible than indexer `" + GetSignatureForError () + "'");
3757 else if ((this is Method) && ((Method) this).IsOperator != null)
3758 Report.Error (57, Location,
3759 "Inconsistent accessibility: parameter type `" +
3760 TypeManager.CSharpName (partype) + "' is less " +
3761 "accessible than operator `" + GetSignatureForError () + "'");
3763 Report.Error (51, Location,
3764 "Inconsistent accessibility: parameter type `" +
3765 TypeManager.CSharpName (partype) + "' is less " +
3766 "accessible than method `" + GetSignatureForError () + "'");
3773 public override string[] ValidAttributeTargets {
3775 return attribute_targets;
3779 protected override bool VerifyClsCompliance (DeclSpace ds)
3781 if (!base.VerifyClsCompliance (ds)) {
3782 if ((ModFlags & Modifiers.ABSTRACT) != 0 && IsExposedFromAssembly (ds) && ds.IsClsComplianceRequired (ds)) {
3783 Report.Error (3011, Location, "`{0}': only CLS-compliant members can be abstract", GetSignatureForError ());
3788 if (Parameters.HasArglist) {
3789 Report.Error (3000, Location, "Methods with variable arguments are not CLS-compliant");
3792 if (!AttributeTester.IsClsCompliant (MemberType)) {
3793 if (this is PropertyBase)
3794 Report.Error (3003, Location, "Type of `{0}' is not CLS-compliant",
3795 GetSignatureForError ());
3797 Report.Error (3002, Location, "Return type of `{0}' is not CLS-compliant",
3798 GetSignatureForError ());
3801 Parameters.VerifyClsCompliance ();
3806 protected bool IsDuplicateImplementation (MethodCore method)
3808 if (method == this || !(method.MemberName.Equals (MemberName)))
3811 Type[] param_types = method.ParameterTypes;
3812 // This never happen. Rewrite this as Equal
3813 if (param_types == null && ParameterTypes == null)
3815 if (param_types == null || ParameterTypes == null)
3818 if (param_types.Length != ParameterTypes.Length)
3821 if (method.Parameters.HasArglist != Parameters.HasArglist)
3826 for (int i = 0; i < param_types.Length; i++) {
3827 if (param_types [i] != ParameterTypes [i])
3831 if (IsExplicitImpl && (method.InterfaceType != InterfaceType))
3834 // TODO: make operator compatible with MethodCore to avoid this
3835 if (this is Operator && method is Operator) {
3836 if (MemberType != method.MemberType)
3842 // Try to report 663: method only differs on out/ref
3844 Parameters info = ParameterInfo;
3845 Parameters other_info = method.ParameterInfo;
3846 for (int i = 0; i < info.Count; i++){
3848 if (info.ParameterModifier (i) != other_info.ParameterModifier (i)){
3849 Report.SymbolRelatedToPreviousError (method);
3850 Report.Error (663, Location, "`{0}': Methods cannot differ only on their use of ref and out on a parameters",
3851 GetSignatureForError ());
3854 Console.WriteLine ("Method is: {0} {1}", method.Location, method);
3855 Console.WriteLine ("this is: {0} {1}", Location, this);
3859 Report.SymbolRelatedToPreviousError (method);
3860 if (this is Operator && method is Operator)
3861 Report.Error (557, Location, "Duplicate user-defined conversion in type `{0}'", Parent.Name);
3863 Report.Error (111, Location, TypeContainer.Error111, GetSignatureForError ());
3871 public override bool IsUsed {
3872 get { return IsExplicitImpl || base.IsUsed; }
3876 // Returns a string that represents the signature for this
3877 // member which should be used in XML documentation.
3879 public override string GetDocCommentName (DeclSpace ds)
3881 return DocUtil.GetMethodDocCommentName (this, ds);
3885 // Raised (and passed an XmlElement that contains the comment)
3886 // when GenerateDocComment is writing documentation expectedly.
3888 // FIXME: with a few effort, it could be done with XmlReader,
3889 // that means removal of DOM use.
3891 internal override void OnGenerateDocComment (DeclSpace ds, XmlElement el)
3893 DocUtil.OnMethodGenerateDocComment (this, ds, el);
3897 // Represents header string for documentation comment.
3899 public override string DocCommentHeader {
3900 get { return "M:"; }
3905 public class SourceMethod : ISourceMethod
3907 TypeContainer container;
3910 protected SourceMethod (TypeContainer container, MethodBase builder,
3911 ISourceFile file, Location start, Location end)
3913 this.container = container;
3914 this.builder = builder;
3916 CodeGen.SymbolWriter.OpenMethod (
3917 file, this, start.Row, start.Column, end.Row, start.Column);
3920 public string Name {
3921 get { return builder.Name; }
3924 public int NamespaceID {
3925 get { return container.NamespaceEntry.SymbolFileID; }
3930 if (builder is MethodBuilder)
3931 return ((MethodBuilder) builder).GetToken ().Token;
3932 else if (builder is ConstructorBuilder)
3933 return ((ConstructorBuilder) builder).GetToken ().Token;
3935 throw new NotSupportedException ();
3939 public void CloseMethod ()
3941 if (CodeGen.SymbolWriter != null)
3942 CodeGen.SymbolWriter.CloseMethod ();
3945 public static SourceMethod Create (TypeContainer parent,
3946 MethodBase builder, Block block)
3948 if (CodeGen.SymbolWriter == null)
3953 Location start_loc = block.StartLocation;
3954 if (start_loc.IsNull)
3957 Location end_loc = block.EndLocation;
3961 ISourceFile file = start_loc.SourceFile;
3965 return new SourceMethod (
3966 parent, builder, file, start_loc, end_loc);
3970 public class Method : MethodCore, IIteratorContainer, IMethodData {
3971 public MethodBuilder MethodBuilder;
3972 public MethodData MethodData;
3973 ReturnParameter return_attributes;
3974 ListDictionary declarative_security;
3977 /// Modifiers allowed in a class declaration
3979 const int AllowedModifiers =
3982 Modifiers.PROTECTED |
3983 Modifiers.INTERNAL |
3988 Modifiers.OVERRIDE |
3989 Modifiers.ABSTRACT |
3991 Modifiers.METHOD_YIELDS |
3994 const int AllowedInterfaceModifiers =
3995 Modifiers.NEW | Modifiers.UNSAFE;
3998 // return_type can be "null" for VOID values.
4000 public Method (TypeContainer parent, GenericMethod generic,
4001 Expression return_type, int mod, bool is_iface,
4002 MemberName name, Parameters parameters, Attributes attrs)
4003 : base (parent, generic, return_type, mod,
4004 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
4005 is_iface, name, attrs, parameters)
4009 public override AttributeTargets AttributeTargets {
4011 return AttributeTargets.Method;
4015 public override string GetSignatureForError()
4017 if (IsOperator != null)
4018 return IsOperator.GetSignatureForError ();
4020 return base.GetSignatureForError () + Parameters.GetSignatureForError ();
4023 void DuplicateEntryPoint (MethodInfo b, Location location)
4027 "Program `" + CodeGen.FileName +
4028 "' has more than one entry point defined: `" +
4029 TypeManager.CSharpSignature(b) + "'");
4032 bool IsEntryPoint (MethodBuilder b, Parameters pinfo)
4034 if (b.ReturnType != TypeManager.void_type &&
4035 b.ReturnType != TypeManager.int32_type)
4038 if (pinfo.Count == 0)
4041 if (pinfo.Count > 1)
4044 Type t = pinfo.ParameterType(0);
4046 (t.GetArrayRank() == 1) &&
4047 (TypeManager.GetElementType(t) == TypeManager.string_type) &&
4048 (pinfo.ParameterModifier(0) == Parameter.Modifier.NONE))
4054 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
4056 if (a.Target == AttributeTargets.ReturnValue) {
4057 if (return_attributes == null)
4058 return_attributes = new ReturnParameter (MethodBuilder, Location);
4060 return_attributes.ApplyAttributeBuilder (a, cb);
4064 if (a.Type == TypeManager.methodimpl_attr_type &&
4065 (a.GetMethodImplOptions () & MethodImplOptions.InternalCall) != 0) {
4066 MethodBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall | MethodImplAttributes.Runtime);
4069 if (a.Type == TypeManager.dllimport_type) {
4070 const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
4071 if ((ModFlags & extern_static) != extern_static) {
4072 Report.Error (601, a.Location, "The DllImport attribute must be specified on a method marked `static' and `extern'");
4078 if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
4079 if (declarative_security == null)
4080 declarative_security = new ListDictionary ();
4081 a.ExtractSecurityPermissionSet (declarative_security);
4085 if (a.Type == TypeManager.conditional_attribute_type) {
4086 if (IsOperator != null || IsExplicitImpl) {
4087 Report.Error (577, Location, "Conditional not valid on `{0}' because it is a constructor, destructor, operator or explicit interface implementation",
4088 GetSignatureForError ());
4092 if (ReturnType != TypeManager.void_type) {
4093 Report.Error (578, Location, "Conditional not valid on `{0}' because its return type is not void", GetSignatureForError ());
4097 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
4098 Report.Error (243, Location, "Conditional not valid on `{0}' because it is an override method", GetSignatureForError ());
4103 Report.Error (582, Location, "Conditional not valid on interface members");
4107 if (MethodData.implementing != null) {
4108 Report.Error (629, Location, "Conditional member `{0}' cannot implement interface member `{1}'",
4109 GetSignatureForError (), TypeManager.CSharpSignature (MethodData.implementing));
4113 for (int i = 0; i < ParameterInfo.Count; ++i) {
4114 if ((ParameterInfo.ParameterModifier (i) & Parameter.Modifier.OUTMASK) != 0) {
4115 Report.Error (685, Location, "Conditional method `{0}' cannot have an out parameter", GetSignatureForError ());
4121 MethodBuilder.SetCustomAttribute (cb);
4124 protected override bool CheckForDuplications ()
4126 ArrayList ar = Parent.Methods;
4128 int arLen = ar.Count;
4130 for (int i = 0; i < arLen; i++) {
4131 Method m = (Method) ar [i];
4132 if (IsDuplicateImplementation (m))
4137 ar = Parent.Properties;
4139 for (int i = 0; i < ar.Count; ++i) {
4140 PropertyBase pb = (PropertyBase) ar [i];
4141 if (pb.AreAccessorsDuplicateImplementation (this))
4146 ar = Parent.Indexers;
4148 for (int i = 0; i < ar.Count; ++i) {
4149 PropertyBase pb = (PropertyBase) ar [i];
4150 if (pb.AreAccessorsDuplicateImplementation (this))
4157 for (int i = 0; i < ar.Count; ++i) {
4158 Event ev = (Event) ar [i];
4159 if (ev.AreAccessorsDuplicateImplementation (this))
4170 public override bool Define ()
4172 if (!DoDefineBase ())
4175 MethodBuilder mb = null;
4176 if (GenericMethod != null) {
4177 string method_name = MemberName.Name;
4179 if (IsExplicitImpl) {
4180 method_name = TypeManager.CSharpName (InterfaceType) +
4184 mb = Parent.TypeBuilder.DefineGenericMethod (method_name, flags);
4185 if (!GenericMethod.Define (mb))
4192 if (!CheckAbstractAndExtern (block != null))
4195 if (RootContext.StdLib && (ReturnType == TypeManager.arg_iterator_type || ReturnType == TypeManager.typed_reference_type)) {
4196 Error1599 (Location, ReturnType);
4203 if (IsOperator != null)
4204 flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
4206 MethodData = new MethodData (this, ModFlags, flags, this, mb, GenericMethod, base_method);
4208 if (!MethodData.Define (Parent))
4211 if (ReturnType == TypeManager.void_type && ParameterTypes.Length == 0 &&
4212 Name == "Finalize" && !(this is Destructor)) {
4213 Report.Warning (465, 1, Location, "Introducing a 'Finalize' method can interfere with destructor invocation. Did you intend to declare a destructor?");
4217 // Setup iterator if we are one
4219 if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
4220 Iterator iterator = new Iterator (
4221 this, Parent, GenericMethod, ModFlags);
4223 if (!iterator.DefineIterator ())
4227 MethodBuilder = MethodData.MethodBuilder;
4230 // This is used to track the Entry Point,
4232 if (Name == "Main" &&
4233 ((ModFlags & Modifiers.STATIC) != 0) && RootContext.NeedsEntryPoint &&
4234 (RootContext.MainClass == null ||
4235 RootContext.MainClass == Parent.TypeBuilder.FullName)){
4236 if (IsEntryPoint (MethodBuilder, ParameterInfo)) {
4237 IMethodData md = TypeManager.GetMethod (MethodBuilder);
4238 md.SetMemberIsUsed ();
4240 if (RootContext.EntryPoint == null) {
4241 if (Parent.IsGeneric){
4242 Report.Error (-201, Location,
4243 "Entry point can not be defined in a generic class");
4246 RootContext.EntryPoint = MethodBuilder;
4247 RootContext.EntryPointLocation = Location;
4249 DuplicateEntryPoint (RootContext.EntryPoint, RootContext.EntryPointLocation);
4250 DuplicateEntryPoint (MethodBuilder, Location);
4253 if (RootContext.WarningLevel >= 4)
4254 Report.Warning (28, 4, Location, "`{0}' has the wrong signature to be an entry point", TypeManager.CSharpSignature(MethodBuilder));
4258 if (MemberType.IsAbstract && MemberType.IsSealed) {
4259 Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
4269 public override void Emit ()
4271 MethodData.Emit (Parent, this);
4274 if (declarative_security != null) {
4275 foreach (DictionaryEntry de in declarative_security) {
4276 MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
4284 public static void Error1599 (Location loc, Type t)
4286 Report.Error (1599, loc, "Method or delegate cannot return type `{0}'", TypeManager.CSharpName (t));
4289 protected override MethodInfo FindOutBaseMethod (TypeContainer container, ref Type base_ret_type)
4291 MethodInfo mi = (MethodInfo) container.BaseCache.FindMemberToOverride (
4292 container.TypeBuilder, Name, ParameterTypes, GenericMethod, false);
4297 base_ret_type = mi.ReturnType;
4301 public override bool MarkForDuplicationCheck ()
4303 caching_flags |= Flags.TestMethodDuplication;
4307 protected override bool VerifyClsCompliance(DeclSpace ds)
4309 if (!base.VerifyClsCompliance (ds))
4312 if (ParameterInfo.Count > 0) {
4313 ArrayList al = (ArrayList)ds.MemberCache.Members [Name];
4315 ds.MemberCache.VerifyClsParameterConflict (al, this, MethodBuilder);
4321 #region IMethodData Members
4323 public CallingConventions CallingConventions {
4325 CallingConventions cc = Parameters.CallingConvention;
4326 if (Parameters.HasArglist)
4327 block.HasVarargs = true;
4330 if ((ModFlags & Modifiers.STATIC) == 0)
4331 cc |= CallingConventions.HasThis;
4333 // FIXME: How is `ExplicitThis' used in C#?
4339 public Type ReturnType {
4345 public MemberName MethodName {
4351 public new Location Location {
4353 return base.Location;
4357 protected override bool CheckBase() {
4358 if (!base.CheckBase ())
4361 // TODO: Destructor should derive from MethodCore
4362 if (base_method != null && (ModFlags & Modifiers.OVERRIDE) != 0 && Name == "Finalize" &&
4363 base_method.DeclaringType == TypeManager.object_type && !(this is Destructor)) {
4364 Report.Error (249, Location, "Do not override object.Finalize. Instead, provide a destructor");
4371 public EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig)
4373 EmitContext ec = new EmitContext (
4374 tc, ds, Location, ig, ReturnType, ModFlags, false);
4376 Iterator iterator = tc as Iterator;
4377 if (iterator != null)
4378 ec.CurrentAnonymousMethod = iterator.Host;
4384 /// Returns true if method has conditional attribute and the conditions is not defined (method is excluded).
4386 public bool IsExcluded (EmitContext ec)
4388 if ((caching_flags & Flags.Excluded_Undetected) == 0)
4389 return (caching_flags & Flags.Excluded) != 0;
4391 caching_flags &= ~Flags.Excluded_Undetected;
4393 if (base_method == null) {
4394 if (OptAttributes == null)
4397 Attribute[] attrs = OptAttributes.SearchMulti (TypeManager.conditional_attribute_type, ec);
4402 foreach (Attribute a in attrs) {
4403 string condition = a.GetConditionalAttributeValue (Parent.EmitContext);
4404 if (RootContext.AllDefines.Contains (condition))
4408 caching_flags |= Flags.Excluded;
4412 IMethodData md = TypeManager.GetMethod (base_method);
4414 if (AttributeTester.IsConditionalMethodExcluded (base_method)) {
4415 caching_flags |= Flags.Excluded;
4421 if (md.IsExcluded (ec)) {
4422 caching_flags |= Flags.Excluded;
4428 GenericMethod IMethodData.GenericMethod {
4430 return GenericMethod;
4437 public abstract class ConstructorInitializer {
4438 ArrayList argument_list;
4439 protected ConstructorInfo base_constructor;
4442 public ConstructorInitializer (ArrayList argument_list, Location loc)
4444 this.argument_list = argument_list;
4448 public ArrayList Arguments {
4450 return argument_list;
4454 public bool Resolve (ConstructorBuilder caller_builder, Block block, EmitContext ec)
4456 Expression base_constructor_group;
4460 ec.CurrentBlock = block;
4462 if (argument_list != null){
4463 foreach (Argument a in argument_list){
4464 if (!a.Resolve (ec, loc))
4468 ec.CurrentBlock = null;
4470 if (this is ConstructorBaseInitializer) {
4471 if (ec.ContainerType.BaseType == null)
4474 t = ec.ContainerType.BaseType;
4475 if (ec.ContainerType.IsValueType) {
4476 Report.Error (522, loc,
4477 "`{0}': Struct constructors cannot call base constructors", TypeManager.CSharpSignature (caller_builder));
4481 t = ec.ContainerType;
4483 base_constructor_group = Expression.MemberLookup (
4484 ec, t, ".ctor", MemberTypes.Constructor,
4485 BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
4488 if (base_constructor_group == null){
4490 base_constructor_group = Expression.MemberLookup (
4491 ec, t, null, t, ".ctor", MemberTypes.Constructor,
4492 BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly,
4496 int errors = Report.Errors;
4497 if (base_constructor_group != null)
4498 base_constructor = (ConstructorInfo) Invocation.OverloadResolve (
4499 ec, (MethodGroupExpr) base_constructor_group, argument_list,
4502 if (base_constructor == null) {
4503 if (errors == Report.Errors)
4504 Invocation.Error_WrongNumArguments (loc, TypeManager.CSharpSignature (caller_builder),
4505 argument_list.Count);
4510 Expression.ErrorIsInaccesible (loc, TypeManager.CSharpSignature (base_constructor));
4511 base_constructor = null;
4515 if (base_constructor == caller_builder){
4516 Report.Error (516, loc, "Constructor `{0}' cannot call itself", TypeManager.CSharpSignature (caller_builder));
4523 public virtual void Emit (EmitContext ec)
4525 if (base_constructor != null){
4526 ec.Mark (loc, false);
4528 Invocation.EmitCall (ec, true, true, null, base_constructor, argument_list, loc);
4530 Invocation.EmitCall (ec, true, false, ec.GetThis (loc), base_constructor, argument_list, loc);
4535 public class ConstructorBaseInitializer : ConstructorInitializer {
4536 public ConstructorBaseInitializer (ArrayList argument_list, Location l) :
4537 base (argument_list, l)
4542 class GeneratedBaseInitializer: ConstructorBaseInitializer {
4543 public GeneratedBaseInitializer (Location loc):
4548 public override void Emit(EmitContext ec)
4550 bool old = ec.TestObsoleteMethodUsage;
4551 ec.TestObsoleteMethodUsage = false;
4553 ec.TestObsoleteMethodUsage = old;
4557 public class ConstructorThisInitializer : ConstructorInitializer {
4558 public ConstructorThisInitializer (ArrayList argument_list, Location l) :
4559 base (argument_list, l)
4564 public class Constructor : MethodCore, IMethodData {
4565 public ConstructorBuilder ConstructorBuilder;
4566 public ConstructorInitializer Initializer;
4567 ListDictionary declarative_security;
4570 // Modifiers allowed for a constructor.
4572 public const int AllowedModifiers =
4574 Modifiers.PROTECTED |
4575 Modifiers.INTERNAL |
4581 bool has_compliant_args = false;
4583 // The spec claims that static is not permitted, but
4584 // my very own code has static constructors.
4586 public Constructor (TypeContainer ds, string name, int mod, Parameters args,
4587 ConstructorInitializer init, Location loc)
4588 : base (ds, null, null, mod, AllowedModifiers, false,
4589 new MemberName (name, loc), null, args)
4594 public bool HasCompliantArgs {
4596 return has_compliant_args;
4600 public override AttributeTargets AttributeTargets {
4602 return AttributeTargets.Constructor;
4608 // Returns true if this is a default constructor
4610 public bool IsDefault ()
4612 if ((ModFlags & Modifiers.STATIC) != 0)
4613 return Parameters.Empty;
4615 return Parameters.Empty &&
4616 (Initializer is ConstructorBaseInitializer) &&
4617 (Initializer.Arguments == null);
4620 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
4622 if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
4623 if (declarative_security == null) {
4624 declarative_security = new ListDictionary ();
4626 a.ExtractSecurityPermissionSet (declarative_security);
4630 ConstructorBuilder.SetCustomAttribute (cb);
4633 protected override bool CheckForDuplications ()
4635 ArrayList ar = Parent.InstanceConstructors;
4637 int arLen = ar.Count;
4639 for (int i = 0; i < arLen; i++) {
4640 Constructor m = (Constructor) ar [i];
4641 if (IsDuplicateImplementation (m))
4648 protected override bool CheckBase ()
4650 // Check whether arguments were correct.
4651 if (!DoDefineParameters ())
4654 // TODO: skip the rest for generated ctor
4655 if ((ModFlags & Modifiers.STATIC) != 0)
4658 if (!CheckForDuplications ())
4661 if (Parent.Kind == Kind.Struct) {
4662 if (ParameterTypes.Length == 0) {
4663 Report.Error (568, Location,
4664 "Structs cannot contain explicit parameterless constructors");
4668 if ((ModFlags & Modifiers.PROTECTED) != 0) {
4669 Report.Error (666, Location, "`{0}': new protected member declared in struct", GetSignatureForError ());
4674 if ((RootContext.WarningLevel >= 4) && ((Parent.ModFlags & Modifiers.SEALED) != 0 && (ModFlags & Modifiers.PROTECTED) != 0)) {
4675 Report.Warning (628, 4, Location, "`{0}': new protected member declared in sealed class", GetSignatureForError ());
4682 // Creates the ConstructorBuilder
4684 public override bool Define ()
4686 if (ConstructorBuilder != null)
4689 MethodAttributes ca = (MethodAttributes.RTSpecialName |
4690 MethodAttributes.SpecialName);
4692 if ((ModFlags & Modifiers.STATIC) != 0){
4693 ca |= MethodAttributes.Static | MethodAttributes.Private;
4695 ca |= MethodAttributes.HideBySig;
4697 if ((ModFlags & Modifiers.PUBLIC) != 0)
4698 ca |= MethodAttributes.Public;
4699 else if ((ModFlags & Modifiers.PROTECTED) != 0){
4700 if ((ModFlags & Modifiers.INTERNAL) != 0)
4701 ca |= MethodAttributes.FamORAssem;
4703 ca |= MethodAttributes.Family;
4704 } else if ((ModFlags & Modifiers.INTERNAL) != 0)
4705 ca |= MethodAttributes.Assembly;
4706 else if (IsDefault ())
4707 ca |= MethodAttributes.Public;
4709 ca |= MethodAttributes.Private;
4712 if (!CheckAbstractAndExtern (block != null))
4715 // Check if arguments were correct.
4719 ConstructorBuilder = Parent.TypeBuilder.DefineConstructor (
4720 ca, CallingConventions,
4723 if ((ModFlags & Modifiers.UNSAFE) != 0)
4724 ConstructorBuilder.InitLocals = false;
4726 if (Parent.IsComImport) {
4727 if (!IsDefault ()) {
4728 Report.Error (669, Location, "`{0}': A class with the ComImport attribute cannot have a user-defined constructor",
4729 Parent.GetSignatureForError ());
4732 ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall);
4735 TypeManager.AddMethod (ConstructorBuilder, this);
4743 public override void Emit ()
4745 EmitContext ec = CreateEmitContext (null, null);
4746 if (GetObsoleteAttribute () != null || Parent.GetObsoleteAttribute () != null)
4747 ec.TestObsoleteMethodUsage = false;
4749 // If this is a non-static `struct' constructor and doesn't have any
4750 // initializer, it must initialize all of the struct's fields.
4751 if ((Parent.Kind == Kind.Struct) &&
4752 ((ModFlags & Modifiers.STATIC) == 0) && (Initializer == null))
4753 Block.AddThisVariable (Parent, Location);
4755 if (block != null) {
4756 if (!block.ResolveMeta (ec, ParameterInfo))
4760 if ((ModFlags & Modifiers.STATIC) == 0){
4761 if (Parent.Kind == Kind.Class && Initializer == null)
4762 Initializer = new GeneratedBaseInitializer (Location);
4766 // Spec mandates that Initializers will not have
4770 if ((Initializer != null) &&
4771 !Initializer.Resolve (ConstructorBuilder, block, ec))
4773 ec.IsStatic = false;
4776 Parameters.ApplyAttributes (ec, ConstructorBuilder);
4778 SourceMethod source = SourceMethod.Create (
4779 Parent, ConstructorBuilder, block);
4782 // Classes can have base initializers and instance field initializers.
4784 if (Parent.Kind == Kind.Class){
4785 if ((ModFlags & Modifiers.STATIC) == 0){
4788 // If we use a "this (...)" constructor initializer, then
4789 // do not emit field initializers, they are initialized in the other constructor
4791 if (!(Initializer != null && Initializer is ConstructorThisInitializer))
4792 Parent.EmitFieldInitializers (ec);
4795 if (Initializer != null) {
4796 Initializer.Emit (ec);
4799 if ((ModFlags & Modifiers.STATIC) != 0)
4800 Parent.EmitFieldInitializers (ec);
4802 if (OptAttributes != null)
4803 OptAttributes.Emit (ec, this);
4805 ec.EmitTopBlock (this, block);
4808 source.CloseMethod ();
4812 if (declarative_security != null) {
4813 foreach (DictionaryEntry de in declarative_security) {
4814 ConstructorBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
4821 // Is never override
4822 protected override MethodInfo FindOutBaseMethod (TypeContainer container, ref Type base_ret_type)
4827 public override string GetSignatureForError()
4829 return base.GetSignatureForError () + Parameters.GetSignatureForError ();
4832 protected override bool VerifyClsCompliance (DeclSpace ds)
4834 if (!base.VerifyClsCompliance (ds) || !IsExposedFromAssembly (ds)) {
4838 if (ParameterInfo.Count > 0) {
4839 ArrayList al = (ArrayList)ds.MemberCache.Members [".ctor"];
4841 ds.MemberCache.VerifyClsParameterConflict (al, this, ConstructorBuilder);
4843 if (ds.TypeBuilder.IsSubclassOf (TypeManager.attribute_type)) {
4844 foreach (Type param in ParameterTypes) {
4845 if (param.IsArray) {
4851 has_compliant_args = true;
4855 #region IMethodData Members
4857 public System.Reflection.CallingConventions CallingConventions {
4859 CallingConventions cc = Parameters.CallingConvention;
4861 if (Parent.Kind == Kind.Class)
4862 if ((ModFlags & Modifiers.STATIC) == 0)
4863 cc |= CallingConventions.HasThis;
4865 // FIXME: How is `ExplicitThis' used in C#?
4871 public new Location Location {
4873 return base.Location;
4877 public MemberName MethodName {
4883 public Type ReturnType {
4889 public EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig)
4891 ILGenerator ig_ = ConstructorBuilder.GetILGenerator ();
4892 return new EmitContext (Parent, Location, ig_, null, ModFlags, true);
4895 public bool IsExcluded(EmitContext ec)
4900 GenericMethod IMethodData.GenericMethod {
4910 /// Interface for MethodData class. Holds links to parent members to avoid member duplication.
4912 public interface IMethodData
4914 CallingConventions CallingConventions { get; }
4915 Location Location { get; }
4916 MemberName MethodName { get; }
4917 Type ReturnType { get; }
4918 GenericMethod GenericMethod { get; }
4919 Parameters ParameterInfo { get; }
4921 Attributes OptAttributes { get; }
4922 ToplevelBlock Block { get; set; }
4924 EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig);
4925 ObsoleteAttribute GetObsoleteAttribute ();
4926 string GetSignatureForError ();
4927 bool IsExcluded (EmitContext ec);
4928 bool IsClsComplianceRequired (DeclSpace ds);
4929 void SetMemberIsUsed ();
4933 // Encapsulates most of the Method's state
4935 public class MethodData {
4937 readonly IMethodData method;
4939 public readonly GenericMethod GenericMethod;
4942 // Are we implementing an interface ?
4944 public MethodInfo implementing;
4949 protected MemberBase member;
4950 protected int modifiers;
4951 protected MethodAttributes flags;
4952 protected Type declaring_type;
4953 protected MethodInfo parent_method;
4955 MethodBuilder builder = null;
4956 public MethodBuilder MethodBuilder {
4962 public Type DeclaringType {
4964 return declaring_type;
4968 public MethodData (MemberBase member,
4969 int modifiers, MethodAttributes flags, IMethodData method)
4971 this.member = member;
4972 this.modifiers = modifiers;
4975 this.method = method;
4978 public MethodData (MemberBase member,
4979 int modifiers, MethodAttributes flags,
4980 IMethodData method, MethodBuilder builder,
4981 GenericMethod generic, MethodInfo parent_method)
4982 : this (member, modifiers, flags, method)
4984 this.builder = builder;
4985 this.GenericMethod = generic;
4986 this.parent_method = parent_method;
4989 public bool Define (TypeContainer container)
4991 string name = method.MethodName.Basename;
4992 string method_name = method.MethodName.FullName;
4994 if (container.Pending != null){
4995 if (member is Indexer) // TODO: test it, but it should work without this IF
4996 implementing = container.Pending.IsInterfaceIndexer (
4997 member.InterfaceType, method.ReturnType, method.ParameterInfo);
4999 implementing = container.Pending.IsInterfaceMethod (
5000 member.InterfaceType, name, method.ReturnType, method.ParameterInfo);
5002 if (member.InterfaceType != null){
5003 if (implementing == null){
5004 if (member is PropertyBase) {
5005 Report.Error (550, method.Location, "`{0}' is an accessor not found in interface member `{1}{2}'",
5006 method.GetSignatureForError (), TypeManager.CSharpName (member.InterfaceType),
5007 member.GetSignatureForError ().Substring (member.GetSignatureForError ().LastIndexOf ('.')));
5010 Report.Error (539, method.Location,
5011 "`{0}.{1}' in explicit interface declaration is not a member of interface",
5012 TypeManager.CSharpName (member.InterfaceType), member.ShortName);
5016 if (implementing.IsSpecialName && !(method is AbstractPropertyEventMethod)) {
5017 Report.SymbolRelatedToPreviousError (implementing);
5018 Report.Error (683, method.Location, "`{0}' explicit method implementation cannot implement `{1}' because it is an accessor",
5019 member.GetSignatureForError (), TypeManager.CSharpSignature (implementing));
5023 method_name = TypeManager.GetFullName (member.InterfaceType) +
5026 if (implementing != null) {
5027 AbstractPropertyEventMethod prop_method = method as AbstractPropertyEventMethod;
5028 if (prop_method != null) {
5029 if (!implementing.IsSpecialName) {
5030 Report.SymbolRelatedToPreviousError (implementing);
5031 Report.Error (686, method.Location, "Accessor `{0}' cannot implement interface member `{1}' for type `{2}'. Use an explicit interface implementation",
5032 method.GetSignatureForError (), TypeManager.CSharpSignature (implementing), container.GetSignatureForError ());
5035 PropertyBase.PropertyMethod pm = prop_method as PropertyBase.PropertyMethod;
5036 if (pm != null && pm.HasCustomAccessModifier && (pm.ModFlags & Modifiers.PUBLIC) == 0) {
5037 Report.SymbolRelatedToPreviousError (implementing);
5038 Report.Error (277, method.Location, "Accessor `{0}' must be declared public to implement interface member `{1}'",
5039 method.GetSignatureForError (), TypeManager.CSharpSignature (implementing, true));
5048 // For implicit implementations, make sure we are public, for
5049 // explicit implementations, make sure we are private.
5051 if (implementing != null){
5053 // Setting null inside this block will trigger a more
5054 // verbose error reporting for missing interface implementations
5056 // The "candidate" function has been flagged already
5057 // but it wont get cleared
5059 if (member.IsExplicitImpl){
5060 if ((modifiers & (Modifiers.PUBLIC | Modifiers.ABSTRACT | Modifiers.VIRTUAL)) != 0){
5061 Modifiers.Error_InvalidModifier (method.Location, "public, virtual or abstract");
5062 implementing = null;
5064 } else if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public){
5065 if (TypeManager.IsInterfaceType (implementing.DeclaringType)){
5067 // If this is an interface method implementation,
5068 // check for public accessibility
5070 implementing = null;
5071 } else if ((flags & MethodAttributes.MemberAccessMask) == MethodAttributes.Private){
5072 // We may never be private.
5073 implementing = null;
5074 } else if ((modifiers & Modifiers.OVERRIDE) == 0){
5076 // We may be protected if we're overriding something.
5078 implementing = null;
5083 // Static is not allowed
5085 if ((modifiers & Modifiers.STATIC) != 0){
5086 implementing = null;
5091 // If implementing is still valid, set flags
5093 if (implementing != null){
5095 // When implementing interface methods, set NewSlot
5096 // unless, we are overwriting a method.
5098 if (implementing.DeclaringType.IsInterface){
5099 if ((modifiers & Modifiers.OVERRIDE) == 0)
5100 flags |= MethodAttributes.NewSlot;
5103 MethodAttributes.Virtual |
5104 MethodAttributes.HideBySig;
5106 // Set Final unless we're virtual, abstract or already overriding a method.
5107 if ((modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE)) == 0)
5108 flags |= MethodAttributes.Final;
5111 EmitContext ec = method.CreateEmitContext (container, null);
5112 if (method.GetObsoleteAttribute () != null || container.GetObsoleteAttribute () != null)
5113 ec.TestObsoleteMethodUsage = false;
5115 DefineMethodBuilder (ec, container, method_name, method.ParameterInfo.Types);
5117 if (builder == null)
5120 if (container.CurrentType != null)
5121 declaring_type = container.CurrentType;
5123 declaring_type = container.TypeBuilder;
5125 if ((modifiers & Modifiers.UNSAFE) != 0)
5126 builder.InitLocals = false;
5128 if (implementing != null){
5130 // clear the pending implemntation flag
5132 if (member is Indexer) {
5133 container.Pending.ImplementIndexer (
5134 member.InterfaceType, builder, method.ReturnType,
5135 method.ParameterInfo, member.IsExplicitImpl);
5137 container.Pending.ImplementMethod (
5138 member.InterfaceType, name, method.ReturnType,
5139 method.ParameterInfo, member.IsExplicitImpl);
5141 if (member.IsExplicitImpl)
5142 container.TypeBuilder.DefineMethodOverride (
5143 builder, implementing);
5146 TypeManager.AddMethod (builder, method);
5148 if (GenericMethod != null) {
5149 bool is_override = member.IsExplicitImpl |
5150 ((modifiers & Modifiers.OVERRIDE) != 0);
5152 if (implementing != null)
5153 parent_method = implementing;
5155 if (!GenericMethod.DefineType (ec, builder, parent_method, is_override))
5163 /// Create the MethodBuilder for the method
5165 void DefineMethodBuilder (EmitContext ec, TypeContainer container, string method_name, Type[] ParameterTypes)
5167 const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
5169 if ((modifiers & extern_static) == extern_static) {
5171 if (method.OptAttributes != null) {
5172 Attribute dllimport_attribute = method.OptAttributes.Search (TypeManager.dllimport_type, ec);
5173 if (dllimport_attribute != null) {
5174 flags |= MethodAttributes.PinvokeImpl;
5175 builder = dllimport_attribute.DefinePInvokeMethod (
5176 ec, container.TypeBuilder, method_name, flags,
5177 method.ReturnType, ParameterTypes);
5183 // for extern static method must be specified either DllImport attribute or MethodImplAttribute.
5184 // We are more strict than Microsoft and report CS0626 like error
5185 if (method.OptAttributes == null ||
5186 !method.OptAttributes.Contains (TypeManager.methodimpl_attr_type, ec)) {
5187 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",
5188 method.GetSignatureForError ());
5193 if (builder == null)
5194 builder = container.TypeBuilder.DefineMethod (
5195 method_name, flags, method.CallingConventions,
5196 method.ReturnType, ParameterTypes);
5198 builder.SetGenericMethodSignature (
5199 flags, method.CallingConventions,
5200 method.ReturnType, ParameterTypes);
5206 public void Emit (TypeContainer container, Attributable kind)
5209 if ((flags & MethodAttributes.PinvokeImpl) == 0)
5210 ec = method.CreateEmitContext (container, builder.GetILGenerator ());
5212 ec = method.CreateEmitContext (container, null);
5214 if (method.GetObsoleteAttribute () != null || container.GetObsoleteAttribute () != null)
5215 ec.TestObsoleteMethodUsage = false;
5217 method.ParameterInfo.ApplyAttributes (ec, MethodBuilder);
5219 Attributes OptAttributes = method.OptAttributes;
5221 if (OptAttributes != null)
5222 OptAttributes.Emit (ec, kind);
5224 if (GenericMethod != null)
5225 GenericMethod.EmitAttributes (ec);
5227 ToplevelBlock block = method.Block;
5229 SourceMethod source = SourceMethod.Create (
5230 container, MethodBuilder, method.Block);
5233 // Handle destructors specially
5235 // FIXME: This code generates buggy code
5237 if (member is Destructor)
5238 EmitDestructor (ec, block);
5240 ec.EmitTopBlock (method, block);
5243 source.CloseMethod ();
5246 void EmitDestructor (EmitContext ec, ToplevelBlock block)
5248 ILGenerator ig = ec.ig;
5250 Label finish = ig.DefineLabel ();
5252 block.SetDestructor ();
5254 ig.BeginExceptionBlock ();
5255 ec.ReturnLabel = finish;
5256 ec.HasReturnLabel = true;
5257 ec.EmitTopBlock (method, block);
5259 // ig.MarkLabel (finish);
5260 ig.BeginFinallyBlock ();
5262 if (ec.ContainerType.BaseType != null) {
5263 Expression member_lookup = Expression.MemberLookup (
5264 ec, ec.ContainerType.BaseType, null, ec.ContainerType.BaseType,
5265 "Finalize", MemberTypes.Method, Expression.AllBindingFlags, method.Location);
5267 if (member_lookup != null){
5268 MethodGroupExpr base_destructor = ((MethodGroupExpr) member_lookup);
5270 ig.Emit (OpCodes.Ldarg_0);
5271 ig.Emit (OpCodes.Call, (MethodInfo) base_destructor.Methods [0]);
5275 ig.EndExceptionBlock ();
5276 //ig.MarkLabel (ec.ReturnLabel);
5277 ig.Emit (OpCodes.Ret);
5281 // TODO: Should derive from MethodCore
5282 public class Destructor : Method {
5284 public Destructor (TypeContainer ds, Expression return_type, int mod,
5285 string name, Parameters parameters, Attributes attrs,
5287 : base (ds, null, return_type, mod, false, new MemberName (name, l),
5291 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
5293 if (a.Type == TypeManager.conditional_attribute_type) {
5294 Report.Error (577, Location, "Conditional not valid on `{0}' because it is a constructor, destructor, operator or explicit interface implementation",
5295 GetSignatureForError ());
5299 base.ApplyAttributeBuilder (a, cb);
5302 public override string GetSignatureForError ()
5304 return Parent.GetSignatureForError () + ".~" + Parent.MemberName.Name + "()";
5309 abstract public class MemberBase : MemberCore {
5310 public Expression Type;
5312 public MethodAttributes flags;
5313 public readonly DeclSpace ds;
5314 public readonly GenericMethod GenericMethod;
5316 protected readonly int explicit_mod_flags;
5319 // The "short" name of this property / indexer / event. This is the
5320 // name without the explicit interface.
5322 public string ShortName {
5323 get { return MemberName.Name; }
5324 set { SetMemberName (new MemberName (MemberName.Left, value, Location)); }
5327 public new TypeContainer Parent {
5328 get { return (TypeContainer) base.Parent; }
5332 // The type of this property / indexer / event
5334 protected Type member_type;
5335 public Type MemberType {
5337 if (member_type == null && Type != null) {
5338 EmitContext ec = ds.EmitContext;
5339 bool old_unsafe = ec.InUnsafe;
5340 ec.InUnsafe = InUnsafe;
5341 ec.ResolvingGenericMethod = GenericMethod != null;
5342 Type = Type.ResolveAsTypeTerminal (ec);
5343 ec.ResolvingGenericMethod = false;
5344 ec.InUnsafe = old_unsafe;
5346 member_type = Type.Type;
5354 // Whether this is an interface member.
5356 public bool IsInterface;
5359 // If true, this is an explicit interface implementation
5361 public bool IsExplicitImpl;
5364 // The interface type we are explicitly implementing
5366 public Type InterfaceType = null;
5369 // The constructor is only exposed to our children
5371 protected MemberBase (TypeContainer parent, GenericMethod generic,
5372 Expression type, int mod, int allowed_mod, int def_mod,
5373 MemberName name, Attributes attrs)
5374 : base (parent, name, attrs)
5376 this.ds = generic != null ? generic : (DeclSpace) parent;
5377 explicit_mod_flags = mod;
5379 ModFlags = Modifiers.Check (allowed_mod, mod, def_mod, Location);
5380 IsExplicitImpl = (MemberName.Left != null);
5381 GenericMethod = generic;
5384 protected virtual bool CheckBase ()
5386 if ((ModFlags & Modifiers.PROTECTED) != 0 && Parent.Kind == Kind.Struct) {
5387 Report.Error (666, Location, "`{0}': new protected member declared in struct", GetSignatureForError ());
5391 if ((RootContext.WarningLevel >= 4) &&
5392 ((Parent.ModFlags & Modifiers.SEALED) != 0) &&
5393 ((ModFlags & Modifiers.PROTECTED) != 0) &&
5394 ((ModFlags & Modifiers.OVERRIDE) == 0) && (Name != "Finalize")) {
5395 Report.Warning (628, 4, Location, "`{0}': new protected member declared in sealed class", GetSignatureForError ());
5400 protected virtual bool DoDefineBase ()
5402 EmitContext ec = Parent.EmitContext;
5404 throw new InternalErrorException ("MemberBase.DoDefine called too early");
5407 throw new InternalErrorException ();
5410 ModFlags = Modifiers.PUBLIC |
5411 Modifiers.ABSTRACT |
5412 Modifiers.VIRTUAL | (ModFlags & Modifiers.UNSAFE) | (ModFlags & Modifiers.NEW);
5414 flags = MethodAttributes.Public |
5415 MethodAttributes.Abstract |
5416 MethodAttributes.HideBySig |
5417 MethodAttributes.NewSlot |
5418 MethodAttributes.Virtual;
5420 if (!Parent.MethodModifiersValid (this))
5423 flags = Modifiers.MethodAttr (ModFlags);
5426 if (IsExplicitImpl) {
5427 Expression expr = MemberName.Left.GetTypeExpression ();
5428 TypeExpr iface_texpr = expr.ResolveAsTypeTerminal (ec);
5429 if (iface_texpr == null)
5432 InterfaceType = iface_texpr.ResolveType (ec);
5434 if (!InterfaceType.IsInterface) {
5435 Report.Error (538, Location, "'{0}' in explicit interface declaration is not an interface", TypeManager.CSharpName (InterfaceType));
5439 if (!Parent.VerifyImplements (this))
5442 Modifiers.Check (Modifiers.AllowedExplicitImplFlags, explicit_mod_flags, 0, Location);
5448 protected virtual bool DoDefine ()
5450 EmitContext ec = ds.EmitContext;
5452 throw new InternalErrorException ("MemberBase.DoDefine called too early");
5454 ec.InUnsafe = InUnsafe;
5456 if (MemberType == null)
5459 CheckObsoleteType (Type);
5461 if ((Parent.ModFlags & Modifiers.SEALED) != 0 &&
5462 (ModFlags & (Modifiers.VIRTUAL|Modifiers.ABSTRACT)) != 0) {
5463 Report.Error (549, Location, "New virtual member `{0}' is declared in a sealed class `{1}'",
5464 GetSignatureForError (), Parent.GetSignatureForError ());
5468 // verify accessibility
5469 if (!Parent.AsAccessible (MemberType, ModFlags)) {
5470 Report.SymbolRelatedToPreviousError (MemberType);
5471 if (this is Property)
5472 Report.Error (53, Location,
5473 "Inconsistent accessibility: property type `" +
5474 TypeManager.CSharpName (MemberType) + "' is less " +
5475 "accessible than property `" + GetSignatureForError () + "'");
5476 else if (this is Indexer)
5477 Report.Error (54, Location,
5478 "Inconsistent accessibility: indexer return type `" +
5479 TypeManager.CSharpName (MemberType) + "' is less " +
5480 "accessible than indexer `" + GetSignatureForError () + "'");
5481 else if (this is MethodCore) {
5482 if (this is Operator)
5483 Report.Error (56, Location,
5484 "Inconsistent accessibility: return type `" +
5485 TypeManager.CSharpName (MemberType) + "' is less " +
5486 "accessible than operator `" + GetSignatureForError () + "'");
5488 Report.Error (50, Location,
5489 "Inconsistent accessibility: return type `" +
5490 TypeManager.CSharpName (MemberType) + "' is less " +
5491 "accessible than method `" + GetSignatureForError () + "'");
5493 Report.Error (52, Location,
5494 "Inconsistent accessibility: field type `" +
5495 TypeManager.CSharpName (MemberType) + "' is less " +
5496 "accessible than field `" + GetSignatureForError () + "'");
5501 if (MemberType.IsPointer && !UnsafeOK (Parent))
5504 if (IsExplicitImpl) {
5505 Expression expr = MemberName.Left.GetTypeExpression ();
5506 TypeExpr texpr = expr.ResolveAsTypeTerminal (ec);
5510 InterfaceType = texpr.ResolveType (ec);
5512 if (!InterfaceType.IsInterface) {
5513 Report.Error (538, Location, "`{0}' in explicit interface declaration is not an interface", TypeManager.CSharpName (InterfaceType));
5517 if (!Parent.VerifyImplements (this))
5520 Modifiers.Check (Modifiers.AllowedExplicitImplFlags, explicit_mod_flags, 0, Location);
5526 protected bool IsTypePermitted ()
5528 if (MemberType == TypeManager.arg_iterator_type || MemberType == TypeManager.typed_reference_type) {
5529 Report.Error (610, Location, "Field or property cannot be of type `{0}'", TypeManager.CSharpName (MemberType));
5535 protected override bool VerifyClsCompliance(DeclSpace ds)
5537 if (base.VerifyClsCompliance (ds)) {
5541 if (IsInterface && HasClsCompliantAttribute && ds.IsClsComplianceRequired (ds)) {
5542 Report.Error (3010, Location, "`{0}': CLS-compliant interfaces must have only CLS-compliant members", GetSignatureForError ());
5550 // Fields and Events both generate FieldBuilders, we use this to share
5551 // their common bits. This is also used to flag usage of the field
5553 abstract public class FieldBase : MemberBase {
5554 public FieldBuilder FieldBuilder;
5555 public Status status;
5556 protected Expression initializer;
5559 public enum Status : byte {
5560 HAS_OFFSET = 4 // Used by FieldMember.
5563 static string[] attribute_targets = new string [] { "field" };
5566 /// Symbol with same name in base class/struct
5568 public MemberInfo conflict_symbol;
5570 protected FieldBase (TypeContainer parent, Expression type, int mod,
5571 int allowed_mod, MemberName name, Attributes attrs)
5572 : base (parent, null, type, mod, allowed_mod, Modifiers.PRIVATE,
5577 public override AttributeTargets AttributeTargets {
5579 return AttributeTargets.Field;
5583 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
5585 if (a.Type == TypeManager.marshal_as_attr_type) {
5586 UnmanagedMarshal marshal = a.GetMarshal (this);
5587 if (marshal != null) {
5588 FieldBuilder.SetMarshal (marshal);
5593 if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
5594 a.Error_InvalidSecurityParent ();
5598 FieldBuilder.SetCustomAttribute (cb);
5601 public void EmitInitializer (EmitContext ec)
5603 // Replace DeclSpace because of partial classes
5604 ec.DeclSpace = EmitContext.DeclSpace;
5606 ec.IsFieldInitializer = true;
5607 initializer = initializer.Resolve (ec);
5608 ec.IsFieldInitializer = false;
5609 if (initializer == null)
5611 FieldExpr fe = new FieldExpr (FieldBuilder, Location, true);
5612 if ((ModFlags & Modifiers.STATIC) == 0)
5613 fe.InstanceExpression = new This (Location).Resolve (ec);
5615 ExpressionStatement a = new Assign (fe, initializer, Location);
5617 a = a.ResolveStatement (ec);
5621 Constant c = initializer as Constant;
5622 if (c != null && CanElideInitializer (c))
5625 a.EmitStatement (ec);
5628 bool CanElideInitializer (Constant c)
5630 if (MemberType == c.Type)
5631 return c.IsDefaultValue;
5633 if (c.Type == TypeManager.null_type)
5639 protected override bool CheckBase ()
5641 if (!base.CheckBase ())
5648 conflict_symbol = Parent.FindBaseMemberWithSameName (Name, false);
5649 if (conflict_symbol == null) {
5650 if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) {
5651 Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
5656 if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0) {
5657 Report.SymbolRelatedToPreviousError (conflict_symbol);
5658 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
5659 GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
5665 public Expression Initializer {
5667 if (value != null) {
5668 this.initializer = value;
5669 Parent.RegisterFieldForInitialization (this);
5674 protected virtual bool IsFieldClsCompliant {
5676 if (FieldBuilder == null)
5679 return AttributeTester.IsClsCompliant (FieldBuilder.FieldType);
5683 public override string[] ValidAttributeTargets {
5685 return attribute_targets;
5689 protected override bool VerifyClsCompliance (DeclSpace ds)
5691 if (!base.VerifyClsCompliance (ds))
5694 if (!IsFieldClsCompliant) {
5695 Report.Error (3003, Location, "Type of `{0}' is not CLS-compliant", GetSignatureForError ());
5701 public void SetAssigned ()
5703 caching_flags |= Flags.IsAssigned;
5707 public abstract class FieldMember : FieldBase
5709 protected FieldMember (TypeContainer parent, Expression type, int mod,
5710 int allowed_mod, MemberName name, Attributes attrs)
5711 : base (parent, type, mod, allowed_mod | Modifiers.ABSTRACT, name, attrs)
5713 if ((mod & Modifiers.ABSTRACT) != 0)
5714 Report.Error (681, Location, "The modifier 'abstract' is not valid on fields. Try using a property instead");
5717 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
5719 if (a.Type == TypeManager.field_offset_attribute_type)
5721 status |= Status.HAS_OFFSET;
5723 if (!Parent.HasExplicitLayout) {
5724 Report.Error (636, Location, "The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit)");
5728 if ((ModFlags & Modifiers.STATIC) != 0 || this is Const) {
5729 Report.Error (637, Location, "The FieldOffset attribute is not allowed on static or const fields");
5734 if (a.Type == TypeManager.fixed_buffer_attr_type) {
5735 Report.Error (1716, Location, "Do not use 'System.Runtime.CompilerServices.FixedBuffer' attribute. Use the 'fixed' field modifier instead");
5739 base.ApplyAttributeBuilder (a, cb);
5743 public override bool Define()
5745 EmitContext ec = Parent.EmitContext;
5747 throw new InternalErrorException ("FieldMember.Define called too early");
5749 if (MemberType == null || Type == null)
5752 CheckObsoleteType (Type);
5754 if (MemberType == TypeManager.void_type) {
5755 Report.Error (1547, Location, "Keyword 'void' cannot be used in this context");
5762 if (!Parent.AsAccessible (MemberType, ModFlags)) {
5763 Report.Error (52, Location,
5764 "Inconsistent accessibility: field type `" +
5765 TypeManager.CSharpName (MemberType) + "' is less " +
5766 "accessible than field `" + GetSignatureForError () + "'");
5770 if (!IsTypePermitted ())
5773 if (MemberType.IsPointer && !UnsafeOK (Parent))
5779 public override void Emit ()
5781 if (OptAttributes != null) {
5782 EmitContext ec = new EmitContext (Parent, Location, null, FieldBuilder.FieldType, ModFlags);
5783 OptAttributes.Emit (ec, this);
5786 if (Parent.HasExplicitLayout && ((status & Status.HAS_OFFSET) == 0) && (ModFlags & Modifiers.STATIC) == 0) {
5787 Report.Error (625, Location, "`{0}': Instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute.", GetSignatureForError ());
5794 // Represents header string for documentation comment.
5796 public override string DocCommentHeader {
5797 get { return "F:"; }
5801 interface IFixedBuffer
5803 FieldInfo Element { get; }
5804 Type ElementType { get; }
5807 public class FixedFieldExternal: IFixedBuffer
5809 FieldInfo element_field;
5811 public FixedFieldExternal (FieldInfo fi)
5813 element_field = fi.FieldType.GetField (FixedField.FixedElementName);
5816 #region IFixedField Members
5818 public FieldInfo Element {
5820 return element_field;
5824 public Type ElementType {
5826 return element_field.FieldType;
5834 /// Fixed buffer implementation
5836 public class FixedField : FieldMember, IFixedBuffer
5838 public const string FixedElementName = "FixedElementField";
5839 static int GlobalCounter = 0;
5840 static object[] ctor_args = new object[] { (short)LayoutKind.Sequential };
5841 static FieldInfo[] fi;
5843 TypeBuilder fixed_buffer_type;
5844 FieldBuilder element;
5845 Expression size_expr;
5848 const int AllowedModifiers =
5851 Modifiers.PROTECTED |
5852 Modifiers.INTERNAL |
5855 public FixedField (TypeContainer parent, Expression type, int mod, string name,
5856 Expression size_expr, Attributes attrs, Location loc):
5857 base (parent, type, mod, AllowedModifiers, new MemberName (name, loc), attrs)
5859 if (RootContext.Version == LanguageVersion.ISO_1)
5860 Report.FeatureIsNotStandardized (loc, "fixed size buffers");
5862 this.size_expr = size_expr;
5865 public override bool Define()
5868 if ((ModFlags & (Modifiers.PUBLIC | Modifiers.PROTECTED)) != 0)
5869 Report.Warning (-23, 1, Location, "Only private or internal fixed sized buffers are supported by .NET 1.x");
5872 if (Parent.Kind != Kind.Struct) {
5873 Report.Error (1642, Location, "`{0}': Fixed size buffer fields may only be members of structs",
5874 GetSignatureForError ());
5878 if (!base.Define ())
5881 if (!TypeManager.IsPrimitiveType (MemberType)) {
5882 Report.Error (1663, Location, "`{0}': Fixed size buffers type must be one of the following: bool, byte, short, int, long, char, sbyte, ushort, uint, ulong, float or double",
5883 GetSignatureForError ());
5887 Constant c = size_expr.ResolveAsConstant (Parent.EmitContext, this);
5891 IntConstant buffer_size_const = c.ToInt (Location);
5892 if (buffer_size_const == null)
5895 buffer_size = buffer_size_const.Value;
5897 if (buffer_size <= 0) {
5898 Report.Error (1665, Location, "`{0}': Fixed size buffers must have a length greater than zero", GetSignatureForError ());
5902 int type_size = Expression.GetTypeSize (MemberType);
5904 if (buffer_size > int.MaxValue / type_size) {
5905 Report.Error (1664, Location, "Fixed size buffer `{0}' of length `{1}' and type `{2}' exceeded 2^31 limit",
5906 GetSignatureForError (), buffer_size.ToString (), TypeManager.CSharpName (MemberType));
5910 buffer_size *= type_size;
5913 string name = String.Format ("<{0}>__FixedBuffer{1}", Name, GlobalCounter++);
5915 fixed_buffer_type = Parent.TypeBuilder.DefineNestedType (name,
5916 TypeAttributes.NestedPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, TypeManager.value_type);
5917 element = fixed_buffer_type.DefineField (FixedElementName, MemberType, FieldAttributes.Public);
5918 RootContext.RegisterCompilerGeneratedType (fixed_buffer_type);
5920 FieldBuilder = Parent.TypeBuilder.DefineField (Name, fixed_buffer_type, Modifiers.FieldAttr (ModFlags));
5921 TypeManager.RegisterFieldBase (FieldBuilder, this);
5926 public override void Emit()
5929 fi = new FieldInfo [] { TypeManager.struct_layout_attribute_type.GetField ("Size") };
5931 object[] fi_val = new object[1];
5932 fi_val [0] = buffer_size;
5934 CustomAttributeBuilder cab = new CustomAttributeBuilder (TypeManager.struct_layout_attribute_ctor,
5935 ctor_args, fi, fi_val);
5936 fixed_buffer_type.SetCustomAttribute (cab);
5938 cab = new CustomAttributeBuilder (TypeManager.fixed_buffer_attr_ctor, new object[] { MemberType, buffer_size } );
5939 FieldBuilder.SetCustomAttribute (cab);
5943 protected override bool IsFieldClsCompliant {
5949 #region IFixedField Members
5951 public FieldInfo Element {
5957 public Type ElementType {
5967 // The Field class is used to represents class/struct fields during parsing.
5969 public class Field : FieldMember {
5971 // Modifiers allowed in a class declaration
5973 const int AllowedModifiers =
5976 Modifiers.PROTECTED |
5977 Modifiers.INTERNAL |
5980 Modifiers.VOLATILE |
5984 public Field (TypeContainer parent, Expression type, int mod, string name,
5985 Attributes attrs, Location loc)
5986 : base (parent, type, mod, AllowedModifiers, new MemberName (name, loc),
5991 public override bool Define ()
5993 if (!base.Define ())
5996 if (RootContext.WarningLevel > 1){
5997 Type ptype = Parent.TypeBuilder.BaseType;
5999 // ptype is only null for System.Object while compiling corlib.
6001 TypeContainer.FindMembers (
6002 ptype, MemberTypes.Method,
6003 BindingFlags.Public |
6004 BindingFlags.Static | BindingFlags.Instance,
6005 System.Type.FilterName, Name);
6009 if ((ModFlags & Modifiers.VOLATILE) != 0){
6010 if (!MemberType.IsClass){
6011 Type vt = MemberType;
6013 if (TypeManager.IsEnumType (vt))
6014 vt = TypeManager.EnumToUnderlying (MemberType);
6016 if (!((vt == TypeManager.bool_type) ||
6017 (vt == TypeManager.sbyte_type) ||
6018 (vt == TypeManager.byte_type) ||
6019 (vt == TypeManager.short_type) ||
6020 (vt == TypeManager.ushort_type) ||
6021 (vt == TypeManager.int32_type) ||
6022 (vt == TypeManager.uint32_type) ||
6023 (vt == TypeManager.char_type) ||
6024 (vt == TypeManager.float_type) ||
6025 (!vt.IsValueType))){
6026 Report.Error (677, Location, "`{0}': A volatile field cannot be of the type `{1}'",
6027 GetSignatureForError (), TypeManager.CSharpName (vt));
6032 if ((ModFlags & Modifiers.READONLY) != 0){
6033 Report.Error (678, Location, "`{0}': A field cannot be both volatile and readonly",
6034 GetSignatureForError ());
6039 FieldAttributes fa = Modifiers.FieldAttr (ModFlags);
6041 if (Parent.Kind == Kind.Struct &&
6042 ((fa & FieldAttributes.Static) == 0) &&
6043 MemberType == Parent.TypeBuilder &&
6044 !TypeManager.IsBuiltinType (MemberType)){
6045 Report.Error (523, Location, "Struct member `" + Parent.Name + "." + Name +
6046 "' causes a cycle in the structure layout");
6051 FieldBuilder = Parent.TypeBuilder.DefineField (
6052 Name, MemberType, Modifiers.FieldAttr (ModFlags));
6054 TypeManager.RegisterFieldBase (FieldBuilder, this);
6056 catch (ArgumentException) {
6057 Report.Warning (-24, 1, Location, "The Microsoft runtime is unable to use [void|void*] as a field type, try using the Mono runtime.");
6064 protected override bool VerifyClsCompliance (DeclSpace ds)
6066 if (!base.VerifyClsCompliance (ds))
6069 if ((ModFlags & Modifiers.VOLATILE) != 0) {
6070 Report.Warning (3026, 1, Location, "CLS-compliant field `{0}' cannot be volatile", GetSignatureForError ());
6078 // `set' and `get' accessors are represented with an Accessor.
6080 public class Accessor : IIteratorContainer {
6082 // Null if the accessor is empty, or a Block if not
6084 public const int AllowedModifiers =
6086 Modifiers.PROTECTED |
6087 Modifiers.INTERNAL |
6090 public ToplevelBlock Block;
6091 public Attributes Attributes;
6092 public Location Location;
6093 public int ModFlags;
6096 public Accessor (ToplevelBlock b, int mod, Attributes attrs, Location loc)
6101 ModFlags = Modifiers.Check (AllowedModifiers, mod, 0, loc);
6104 public void SetYields ()
6110 // Ooouh Martin, templates are missing here.
6111 // When it will be possible move here a lot of child code and template method type.
6112 public abstract class AbstractPropertyEventMethod : MemberCore, IMethodData {
6113 protected MethodData method_data;
6114 protected ToplevelBlock block;
6115 protected ListDictionary declarative_security;
6117 // The accessor are created event if they are not wanted.
6118 // But we need them because their names are reserved.
6119 // Field says whether accessor will be emited or not
6120 public readonly bool IsDummy;
6122 protected readonly string prefix;
6124 ReturnParameter return_attributes;
6126 public AbstractPropertyEventMethod (MemberBase member, string prefix)
6127 : base (member.Parent, SetupName (prefix, member, member.Location), null)
6129 this.prefix = prefix;
6133 public AbstractPropertyEventMethod (MemberBase member, Accessor accessor,
6135 : base (member.Parent, SetupName (prefix, member, accessor.Location),
6136 accessor.Attributes)
6138 this.prefix = prefix;
6139 this.block = accessor.Block;
6142 static MemberName SetupName (string prefix, MemberBase member, Location loc)
6144 return new MemberName (member.MemberName.Left, prefix + member.ShortName, loc);
6147 public void UpdateName (MemberBase member)
6149 SetMemberName (SetupName (prefix, member, Location));
6152 #region IMethodData Members
6154 public ToplevelBlock Block {
6164 public CallingConventions CallingConventions {
6166 return CallingConventions.Standard;
6170 public bool IsExcluded (EmitContext ec)
6175 GenericMethod IMethodData.GenericMethod {
6181 public MemberName MethodName {
6187 public Type[] ParameterTypes {
6189 return ParameterInfo.Types;
6193 public abstract Parameters ParameterInfo { get ; }
6194 public abstract Type ReturnType { get; }
6195 public abstract EmitContext CreateEmitContext(TypeContainer tc, ILGenerator ig);
6199 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
6201 if (a.Type == TypeManager.cls_compliant_attribute_type || a.Type == TypeManager.obsolete_attribute_type ||
6202 a.Type == TypeManager.conditional_attribute_type) {
6203 Report.Error (1667, a.Location,
6204 "Attribute `{0}' is not valid on property or event accessors. It is valid on `{1}' declarations only",
6205 TypeManager.CSharpName (a.Type), a.GetValidTargets ());
6209 if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
6210 if (declarative_security == null)
6211 declarative_security = new ListDictionary ();
6212 a.ExtractSecurityPermissionSet (declarative_security);
6216 if (a.Target == AttributeTargets.Method) {
6217 method_data.MethodBuilder.SetCustomAttribute (cb);
6221 if (a.Target == AttributeTargets.ReturnValue) {
6222 if (return_attributes == null)
6223 return_attributes = new ReturnParameter (method_data.MethodBuilder, Location);
6225 return_attributes.ApplyAttributeBuilder (a, cb);
6229 ApplyToExtraTarget (a, cb);
6232 virtual protected void ApplyToExtraTarget (Attribute a, CustomAttributeBuilder cb)
6234 System.Diagnostics.Debug.Fail ("You forgot to define special attribute target handling");
6237 public override bool Define()
6239 throw new NotSupportedException ();
6242 public virtual void Emit (TypeContainer container)
6244 EmitMethod (container);
6246 if (declarative_security != null) {
6247 foreach (DictionaryEntry de in declarative_security) {
6248 method_data.MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
6255 protected virtual void EmitMethod (TypeContainer container)
6257 method_data.Emit (container, this);
6260 public override bool IsClsComplianceRequired(DeclSpace ds)
6265 public bool IsDuplicateImplementation (MethodCore method)
6267 if (!MemberName.Equals (method.MemberName))
6270 Type[] param_types = method.ParameterTypes;
6272 if (param_types.Length != ParameterTypes.Length)
6275 for (int i = 0; i < param_types.Length; i++)
6276 if (param_types [i] != ParameterTypes [i])
6279 Report.SymbolRelatedToPreviousError (method);
6280 Report.Error (111, Location, TypeContainer.Error111, method.GetSignatureForError ());
6284 public override bool IsUsed
6294 public new Location Location {
6296 return base.Location;
6301 // Represents header string for documentation comment.
6303 public override string DocCommentHeader {
6304 get { throw new InvalidOperationException ("Unexpected attempt to get doc comment from " + this.GetType () + "."); }
6310 // Properties and Indexers both generate PropertyBuilders, we use this to share
6311 // their common bits.
6313 abstract public class PropertyBase : MethodCore {
6315 public class GetMethod : PropertyMethod
6317 static string[] attribute_targets = new string [] { "method", "return" };
6319 public GetMethod (MethodCore method):
6320 base (method, "get_")
6324 public GetMethod (MethodCore method, Accessor accessor):
6325 base (method, accessor, "get_")
6329 public override MethodBuilder Define(TypeContainer container)
6331 base.Define (container);
6333 method_data = new MethodData (method, ModFlags, flags, this);
6335 if (!method_data.Define (container))
6338 return method_data.MethodBuilder;
6341 public override Type ReturnType {
6343 return method.MemberType;
6347 public override Parameters ParameterInfo {
6349 return Parameters.EmptyReadOnlyParameters;
6353 public override string[] ValidAttributeTargets {
6355 return attribute_targets;
6360 public class SetMethod : PropertyMethod {
6362 static string[] attribute_targets = new string [] { "method", "param", "return" };
6363 ImplicitParameter param_attr;
6364 protected Parameters parameters;
6366 public SetMethod (MethodCore method):
6367 base (method, "set_")
6371 public SetMethod (MethodCore method, Accessor accessor):
6372 base (method, accessor, "set_")
6376 protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
6378 if (a.Target == AttributeTargets.Parameter) {
6379 if (param_attr == null)
6380 param_attr = new ImplicitParameter (method_data.MethodBuilder, method.Location);
6382 param_attr.ApplyAttributeBuilder (a, cb);
6386 base.ApplyAttributeBuilder (a, cb);
6389 public override Parameters ParameterInfo {
6395 protected virtual void DefineParameters ()
6397 Parameter [] parms = new Parameter [1];
6398 parms [0] = new Parameter (method.MemberType, "value", Parameter.Modifier.NONE, null, Location);
6399 parameters = new Parameters (parms);
6400 parameters.Resolve (null);
6403 public override MethodBuilder Define (TypeContainer container)
6405 if (container.EmitContext == null)
6406 throw new InternalErrorException ("SetMethod.Define called too early");
6408 DefineParameters ();
6412 base.Define (container);
6414 method_data = new MethodData (method, ModFlags, flags, this);
6416 if (!method_data.Define (container))
6419 return method_data.MethodBuilder;
6422 public override Type ReturnType {
6424 return TypeManager.void_type;
6428 public override string[] ValidAttributeTargets {
6430 return attribute_targets;
6435 static string[] attribute_targets = new string [] { "property" };
6437 public abstract class PropertyMethod : AbstractPropertyEventMethod {
6438 protected readonly MethodCore method;
6439 protected MethodAttributes flags;
6442 public PropertyMethod (MethodCore method, string prefix)
6443 : base (method, prefix)
6445 this.method = method;
6448 public PropertyMethod (MethodCore method, Accessor accessor, string prefix)
6449 : base (method, accessor, prefix)
6451 this.method = method;
6452 this.ModFlags = accessor.ModFlags;
6453 yields = accessor.Yields;
6455 if (accessor.ModFlags != 0 && RootContext.Version == LanguageVersion.ISO_1) {
6456 Report.FeatureIsNotStandardized (Location, "access modifiers on properties");
6460 public override AttributeTargets AttributeTargets {
6462 return AttributeTargets.Method;
6466 public override bool IsClsComplianceRequired(DeclSpace ds)
6468 return method.IsClsComplianceRequired (ds);
6471 public virtual MethodBuilder Define (TypeContainer container)
6473 if (!method.CheckAbstractAndExtern (block != null))
6477 // Check for custom access modifier
6479 if (ModFlags == 0) {
6480 ModFlags = method.ModFlags;
6481 flags = method.flags;
6483 if (container.Kind == Kind.Interface)
6484 Report.Error (275, Location, "`{0}': accessibility modifiers may not be used on accessors in an interface",
6485 GetSignatureForError ());
6487 if ((method.ModFlags & Modifiers.ABSTRACT) != 0 && (ModFlags & Modifiers.PRIVATE) != 0) {
6488 Report.Error (442, Location, "`{0}': abstract properties cannot have private accessors", GetSignatureForError ());
6491 CheckModifiers (container, ModFlags);
6492 ModFlags |= (method.ModFlags & (~Modifiers.Accessibility));
6493 ModFlags |= Modifiers.PROPERTY_CUSTOM;
6494 flags = Modifiers.MethodAttr (ModFlags);
6495 flags |= (method.flags & (~MethodAttributes.MemberAccessMask));
6499 // Setup iterator if we are one
6502 Iterator iterator = new Iterator (this, Parent as TypeContainer, null, ModFlags);
6504 if (!iterator.DefineIterator ())
6511 public bool HasCustomAccessModifier
6514 return (ModFlags & Modifiers.PROPERTY_CUSTOM) != 0;
6518 public override EmitContext CreateEmitContext (TypeContainer tc,
6521 return new EmitContext (
6522 tc, method.ds, method.Location, ig, ReturnType,
6523 method.ModFlags, false);
6526 public override ObsoleteAttribute GetObsoleteAttribute ()
6528 return method.GetObsoleteAttribute ();
6531 public override string GetSignatureForError()
6533 return method.GetSignatureForError () + '.' + prefix.Substring (0, 3);
6536 void CheckModifiers (TypeContainer container, int modflags)
6539 int mflags = method.ModFlags & Modifiers.Accessibility;
6541 if ((mflags & Modifiers.PUBLIC) != 0) {
6542 flags |= Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE;
6544 else if ((mflags & Modifiers.PROTECTED) != 0) {
6545 if ((mflags & Modifiers.INTERNAL) != 0)
6546 flags |= Modifiers.PROTECTED | Modifiers.INTERNAL;
6548 flags |= Modifiers.PRIVATE;
6550 else if ((mflags & Modifiers.INTERNAL) != 0)
6551 flags |= Modifiers.PRIVATE;
6553 if ((mflags == modflags) || (modflags & (~flags)) != 0) {
6554 Report.Error (273, Location,
6555 "The accessibility modifier of the `{0}' accessor must be more restrictive than the modifier of the property or indexer `{1}'",
6556 GetSignatureForError (), method.GetSignatureForError ());
6560 public override bool MarkForDuplicationCheck ()
6562 caching_flags |= Flags.TestMethodDuplication;
6567 public PropertyMethod Get, Set;
6568 public PropertyBuilder PropertyBuilder;
6569 public MethodBuilder GetBuilder, SetBuilder;
6571 protected EmitContext ec;
6573 public PropertyBase (TypeContainer parent, Expression type, int mod_flags,
6574 int allowed_mod, bool is_iface, MemberName name,
6575 Parameters parameters, Attributes attrs)
6576 : base (parent, null, type, mod_flags, allowed_mod, is_iface, name,
6581 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
6583 if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
6584 a.Error_InvalidSecurityParent ();
6588 PropertyBuilder.SetCustomAttribute (cb);
6591 public override AttributeTargets AttributeTargets {
6593 return AttributeTargets.Property;
6597 public override bool Define ()
6602 if (!IsTypePermitted ())
6608 protected override bool DoDefine ()
6610 if (!base.DoDefine ())
6614 // Accessors modifiers check
6616 if (Get.ModFlags != 0 && Set.ModFlags != 0) {
6617 Report.Error (274, Location, "`{0}': Cannot specify accessibility modifiers for both accessors of the property or indexer",
6618 GetSignatureForError ());
6622 if ((Get.IsDummy || Set.IsDummy)
6623 && (Get.ModFlags != 0 || Set.ModFlags != 0) && (ModFlags & Modifiers.OVERRIDE) == 0) {
6624 Report.Error (276, Location,
6625 "`{0}': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor",
6626 GetSignatureForError ());
6630 if (MemberType.IsAbstract && MemberType.IsSealed) {
6631 Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
6635 ec = new EmitContext (Parent, Location, null, MemberType, ModFlags);
6639 protected override bool CheckForDuplications ()
6641 ArrayList ar = Parent.Indexers;
6643 int arLen = ar.Count;
6645 for (int i = 0; i < arLen; i++) {
6646 Indexer m = (Indexer) ar [i];
6647 if (IsDuplicateImplementation (m))
6652 ar = Parent.Properties;
6654 int arLen = ar.Count;
6656 for (int i = 0; i < arLen; i++) {
6657 Property m = (Property) ar [i];
6658 if (IsDuplicateImplementation (m))
6666 // TODO: rename to Resolve......
6667 protected override MethodInfo FindOutBaseMethod (TypeContainer container, ref Type base_ret_type)
6669 PropertyInfo base_property = container.BaseCache.FindMemberToOverride (
6670 container.TypeBuilder, Name, ParameterTypes, null, true) as PropertyInfo;
6672 if (base_property == null)
6675 base_ret_type = base_property.PropertyType;
6676 MethodInfo get_accessor = base_property.GetGetMethod (true);
6677 MethodInfo set_accessor = base_property.GetSetMethod (true);
6678 MethodAttributes get_accessor_access, set_accessor_access;
6680 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
6681 if (Get != null && !Get.IsDummy && get_accessor == null) {
6682 Report.SymbolRelatedToPreviousError (base_property);
6683 Report.Error (545, Location, "`{0}.get': cannot override because `{1}' does not have an overridable get accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
6686 if (Set != null && !Set.IsDummy && set_accessor == null) {
6687 Report.SymbolRelatedToPreviousError (base_property);
6688 Report.Error (546, Location, "`{0}.set': cannot override because `{1}' does not have an overridable set accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
6693 // Check base class accessors access
6696 // TODO: rewrite to reuse Get|Set.CheckAccessModifiers and share code there
6697 get_accessor_access = set_accessor_access = 0;
6698 if ((ModFlags & Modifiers.NEW) == 0) {
6699 if (get_accessor != null) {
6700 MethodAttributes get_flags = Modifiers.MethodAttr (Get.ModFlags != 0 ? Get.ModFlags : ModFlags);
6701 get_accessor_access = (get_accessor.Attributes & MethodAttributes.MemberAccessMask);
6703 if (!Get.IsDummy && !CheckAccessModifiers (get_flags & MethodAttributes.MemberAccessMask, get_accessor_access, get_accessor))
6704 Error_CannotChangeAccessModifiers (get_accessor, get_accessor_access, ".get");
6707 if (set_accessor != null) {
6708 MethodAttributes set_flags = Modifiers.MethodAttr (Set.ModFlags != 0 ? Set.ModFlags : ModFlags);
6709 set_accessor_access = (set_accessor.Attributes & MethodAttributes.MemberAccessMask);
6711 if (!Set.IsDummy && !CheckAccessModifiers (set_flags & MethodAttributes.MemberAccessMask, set_accessor_access, set_accessor))
6712 Error_CannotChangeAccessModifiers (set_accessor, set_accessor_access, ".set");
6717 // Get the less restrictive access
6719 return get_accessor_access > set_accessor_access ? get_accessor : set_accessor;
6722 public override void Emit ()
6725 // The PropertyBuilder can be null for explicit implementations, in that
6726 // case, we do not actually emit the ".property", so there is nowhere to
6727 // put the attribute
6729 if (PropertyBuilder != null && OptAttributes != null)
6730 OptAttributes.Emit (ec, this);
6742 /// Tests whether accessors are not in collision with some method (CS0111)
6744 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
6746 return Get.IsDuplicateImplementation (mc) || Set.IsDuplicateImplementation (mc);
6749 public override bool IsUsed
6755 return Get.IsUsed | Set.IsUsed;
6759 protected override void SetMemberName (MemberName new_name)
6761 base.SetMemberName (new_name);
6763 Get.UpdateName (this);
6764 Set.UpdateName (this);
6767 public override string[] ValidAttributeTargets {
6769 return attribute_targets;
6774 // Represents header string for documentation comment.
6776 public override string DocCommentHeader {
6777 get { return "P:"; }
6781 public class Property : PropertyBase {
6782 const int AllowedModifiers =
6785 Modifiers.PROTECTED |
6786 Modifiers.INTERNAL |
6790 Modifiers.OVERRIDE |
6791 Modifiers.ABSTRACT |
6794 Modifiers.METHOD_YIELDS |
6797 const int AllowedInterfaceModifiers =
6800 public Property (TypeContainer ds, Expression type, int mod, bool is_iface,
6801 MemberName name, Attributes attrs, Accessor get_block,
6803 : base (ds, type, mod,
6804 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
6805 is_iface, name, Parameters.EmptyReadOnlyParameters, attrs)
6807 if (get_block == null)
6808 Get = new GetMethod (this);
6810 Get = new GetMethod (this, get_block);
6812 if (set_block == null)
6813 Set = new SetMethod (this);
6815 Set = new SetMethod (this, set_block);
6818 public override bool Define ()
6820 if (!DoDefineBase ())
6823 if (!base.Define ())
6829 flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
6832 GetBuilder = Get.Define (Parent);
6833 if (GetBuilder == null)
6837 SetBuilder = Set.Define (Parent);
6839 if (SetBuilder == null)
6843 // FIXME - PropertyAttributes.HasDefault ?
6845 PropertyBuilder = Parent.TypeBuilder.DefineProperty (
6846 MemberName.ToString (), PropertyAttributes.None, MemberType, null);
6849 PropertyBuilder.SetGetMethod (GetBuilder);
6852 PropertyBuilder.SetSetMethod (SetBuilder);
6859 /// Gigantic workaround for lameness in SRE follows :
6860 /// This class derives from EventInfo and attempts to basically
6861 /// wrap around the EventBuilder so that FindMembers can quickly
6862 /// return this in it search for members
6864 public class MyEventBuilder : EventInfo {
6867 // We use this to "point" to our Builder which is
6868 // not really a MemberInfo
6870 EventBuilder MyBuilder;
6873 // We "catch" and wrap these methods
6875 MethodInfo raise, remove, add;
6877 EventAttributes attributes;
6878 Type declaring_type, reflected_type, event_type;
6883 public MyEventBuilder (Event ev, TypeBuilder type_builder, string name, EventAttributes event_attr, Type event_type)
6885 MyBuilder = type_builder.DefineEvent (name, event_attr, event_type);
6887 // And now store the values in our own fields.
6889 declaring_type = type_builder;
6891 reflected_type = type_builder;
6893 attributes = event_attr;
6896 this.event_type = event_type;
6900 // Methods that you have to override. Note that you only need
6901 // to "implement" the variants that take the argument (those are
6902 // the "abstract" methods, the others (GetAddMethod()) are
6905 public override MethodInfo GetAddMethod (bool nonPublic)
6910 public override MethodInfo GetRemoveMethod (bool nonPublic)
6915 public override MethodInfo GetRaiseMethod (bool nonPublic)
6921 // These methods make "MyEventInfo" look like a Builder
6923 public void SetRaiseMethod (MethodBuilder raiseMethod)
6925 raise = raiseMethod;
6926 MyBuilder.SetRaiseMethod (raiseMethod);
6929 public void SetRemoveOnMethod (MethodBuilder removeMethod)
6931 remove = removeMethod;
6932 MyBuilder.SetRemoveOnMethod (removeMethod);
6935 public void SetAddOnMethod (MethodBuilder addMethod)
6938 MyBuilder.SetAddOnMethod (addMethod);
6941 public void SetCustomAttribute (CustomAttributeBuilder cb)
6943 MyBuilder.SetCustomAttribute (cb);
6946 public override object [] GetCustomAttributes (bool inherit)
6948 // FIXME : There's nothing which can be seemingly done here because
6949 // we have no way of getting at the custom attribute objects of the
6954 public override object [] GetCustomAttributes (Type t, bool inherit)
6956 // FIXME : Same here !
6960 public override bool IsDefined (Type t, bool b)
6965 public override EventAttributes Attributes {
6971 public override string Name {
6977 public override Type DeclaringType {
6979 return declaring_type;
6983 public override Type ReflectedType {
6985 return reflected_type;
6989 public Type EventType {
6995 public void SetUsed ()
6997 if (my_event != null) {
6998 my_event.SetAssigned ();
6999 my_event.SetMemberIsUsed ();
7005 /// For case when event is declared like property (with add and remove accessors).
7007 public class EventProperty: Event {
7009 static string[] attribute_targets = new string [] { "event" }; // "property" target was disabled for 2.0 version
7011 public EventProperty (TypeContainer parent, Expression type, int mod_flags,
7012 bool is_iface, MemberName name,
7013 Attributes attrs, Accessor add, Accessor remove)
7014 : base (parent, type, mod_flags, is_iface, name, attrs)
7016 Add = new AddDelegateMethod (this, add);
7017 Remove = new RemoveDelegateMethod (this, remove);
7019 // For this event syntax we don't report error CS0067
7020 // because it is hard to do it.
7024 public override string[] ValidAttributeTargets {
7026 return attribute_targets;
7032 /// Event is declared like field.
7034 public class EventField : Event {
7036 static string[] attribute_targets = new string [] { "event", "field", "method" };
7037 static string[] attribute_targets_interface = new string[] { "event", "method" };
7039 public EventField (TypeContainer parent, Expression type, int mod_flags,
7040 bool is_iface, MemberName name,
7042 : base (parent, type, mod_flags, is_iface, name, attrs)
7044 Add = new AddDelegateMethod (this);
7045 Remove = new RemoveDelegateMethod (this);
7048 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
7050 if (a.Target == AttributeTargets.Field) {
7051 FieldBuilder.SetCustomAttribute (cb);
7055 if (a.Target == AttributeTargets.Method) {
7056 Add.ApplyAttributeBuilder (a, cb);
7057 Remove.ApplyAttributeBuilder (a, cb);
7061 base.ApplyAttributeBuilder (a, cb);
7064 public override bool Define()
7066 if (!base.Define ())
7069 if (initializer != null) {
7070 if (((ModFlags & Modifiers.ABSTRACT) != 0)) {
7071 Report.Error (74, Location, "`{0}': abstract event cannot have an initializer",
7072 GetSignatureForError ());
7080 public override string[] ValidAttributeTargets {
7082 return IsInterface ? attribute_targets_interface : attribute_targets;
7087 public abstract class Event : FieldBase {
7089 protected sealed class AddDelegateMethod: DelegateMethod
7092 public AddDelegateMethod (Event method):
7093 base (method, "add_")
7097 public AddDelegateMethod (Event method, Accessor accessor):
7098 base (method, accessor, "add_")
7102 protected override MethodInfo DelegateMethodInfo {
7104 return TypeManager.delegate_combine_delegate_delegate;
7110 protected sealed class RemoveDelegateMethod: DelegateMethod
7112 public RemoveDelegateMethod (Event method):
7113 base (method, "remove_")
7117 public RemoveDelegateMethod (Event method, Accessor accessor):
7118 base (method, accessor, "remove_")
7122 protected override MethodInfo DelegateMethodInfo {
7124 return TypeManager.delegate_remove_delegate_delegate;
7130 public abstract class DelegateMethod: AbstractPropertyEventMethod
7132 protected readonly Event method;
7133 ImplicitParameter param_attr;
7135 static string[] attribute_targets = new string [] { "method", "param", "return" };
7137 public DelegateMethod (Event method, string prefix)
7138 : base (method, prefix)
7140 this.method = method;
7143 public DelegateMethod (Event method, Accessor accessor, string prefix)
7144 : base (method, accessor, prefix)
7146 this.method = method;
7149 protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
7151 if (a.Target == AttributeTargets.Parameter) {
7152 if (param_attr == null)
7153 param_attr = new ImplicitParameter (method_data.MethodBuilder, method.Location);
7155 param_attr.ApplyAttributeBuilder (a, cb);
7159 base.ApplyAttributeBuilder (a, cb);
7162 public override AttributeTargets AttributeTargets {
7164 return AttributeTargets.Method;
7168 public override bool IsClsComplianceRequired(DeclSpace ds)
7170 return method.IsClsComplianceRequired (ds);
7173 public MethodBuilder Define (TypeContainer container)
7175 method_data = new MethodData (method, method.ModFlags,
7176 method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this);
7178 if (!method_data.Define (container))
7181 MethodBuilder mb = method_data.MethodBuilder;
7182 ParameterInfo.ApplyAttributes (Parent.EmitContext, mb);
7187 protected override void EmitMethod (TypeContainer tc)
7189 if (block != null) {
7190 base.EmitMethod (tc);
7194 if ((method.ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
7197 ILGenerator ig = method_data.MethodBuilder.GetILGenerator ();
7198 FieldInfo field_info = (FieldInfo)method.FieldBuilder;
7200 method_data.MethodBuilder.SetImplementationFlags (MethodImplAttributes.Synchronized);
7201 if ((method.ModFlags & Modifiers.STATIC) != 0) {
7202 ig.Emit (OpCodes.Ldsfld, field_info);
7203 ig.Emit (OpCodes.Ldarg_0);
7204 ig.Emit (OpCodes.Call, DelegateMethodInfo);
7205 ig.Emit (OpCodes.Castclass, method.MemberType);
7206 ig.Emit (OpCodes.Stsfld, field_info);
7208 ig.Emit (OpCodes.Ldarg_0);
7209 ig.Emit (OpCodes.Ldarg_0);
7210 ig.Emit (OpCodes.Ldfld, field_info);
7211 ig.Emit (OpCodes.Ldarg_1);
7212 ig.Emit (OpCodes.Call, DelegateMethodInfo);
7213 ig.Emit (OpCodes.Castclass, method.MemberType);
7214 ig.Emit (OpCodes.Stfld, field_info);
7216 ig.Emit (OpCodes.Ret);
7219 protected abstract MethodInfo DelegateMethodInfo { get; }
7221 public override Type ReturnType {
7223 return TypeManager.void_type;
7227 public override EmitContext CreateEmitContext (TypeContainer tc,
7230 return new EmitContext (
7231 tc, method.Parent, Location, ig, ReturnType,
7232 method.ModFlags, false);
7235 public override ObsoleteAttribute GetObsoleteAttribute ()
7237 return method.GetObsoleteAttribute ();
7240 public override string[] ValidAttributeTargets {
7242 return attribute_targets;
7246 public override Parameters ParameterInfo {
7248 return method.parameters;
7255 const int AllowedModifiers =
7258 Modifiers.PROTECTED |
7259 Modifiers.INTERNAL |
7264 Modifiers.OVERRIDE |
7268 const int AllowedInterfaceModifiers =
7271 public DelegateMethod Add, Remove;
7272 public MyEventBuilder EventBuilder;
7273 public MethodBuilder AddBuilder, RemoveBuilder;
7274 Parameters parameters;
7276 protected Event (TypeContainer parent, Expression type, int mod_flags,
7277 bool is_iface, MemberName name, Attributes attrs)
7278 : base (parent, type, mod_flags,
7279 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
7282 IsInterface = is_iface;
7285 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
7287 if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
7288 a.Error_InvalidSecurityParent ();
7292 EventBuilder.SetCustomAttribute (cb);
7295 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
7297 return Add.IsDuplicateImplementation (mc) || Remove.IsDuplicateImplementation (mc);
7300 public override AttributeTargets AttributeTargets {
7302 return AttributeTargets.Event;
7306 public override bool Define ()
7308 EventAttributes e_attr;
7309 e_attr = EventAttributes.None;
7311 if (!DoDefineBase ())
7317 if (!TypeManager.IsDelegateType (MemberType)) {
7318 Report.Error (66, Location, "`{0}': event must be of a delegate type", GetSignatureForError ());
7322 EmitContext ec = Parent.EmitContext;
7324 throw new InternalErrorException ("Event.Define called too early?");
7325 bool old_unsafe = ec.InUnsafe;
7326 ec.InUnsafe = InUnsafe;
7328 Parameter [] parms = new Parameter [1];
7329 parms [0] = new Parameter (MemberType, "value", Parameter.Modifier.NONE, null, Location);
7330 parameters = new Parameters (parms);
7331 parameters.Resolve (null);
7333 ec.InUnsafe = old_unsafe;
7339 // Now define the accessors
7342 AddBuilder = Add.Define (Parent);
7343 if (AddBuilder == null)
7346 RemoveBuilder = Remove.Define (Parent);
7347 if (RemoveBuilder == null)
7350 EventBuilder = new MyEventBuilder (this, Parent.TypeBuilder, Name, e_attr, MemberType);
7352 if (Add.Block == null && Remove.Block == null && !IsInterface) {
7353 FieldBuilder = Parent.TypeBuilder.DefineField (
7355 FieldAttributes.Private | ((ModFlags & Modifiers.STATIC) != 0 ? FieldAttributes.Static : 0));
7356 TypeManager.RegisterPrivateFieldOfEvent (
7357 (EventInfo) EventBuilder, FieldBuilder);
7358 TypeManager.RegisterFieldBase (FieldBuilder, this);
7361 EventBuilder.SetAddOnMethod (AddBuilder);
7362 EventBuilder.SetRemoveOnMethod (RemoveBuilder);
7364 TypeManager.RegisterEvent (EventBuilder, AddBuilder, RemoveBuilder);
7368 protected override bool CheckBase ()
7370 if (!base.CheckBase ())
7373 if (conflict_symbol != null && (ModFlags & Modifiers.NEW) == 0) {
7374 if (!(conflict_symbol is EventInfo)) {
7375 Report.SymbolRelatedToPreviousError (conflict_symbol);
7376 Report.Error (72, Location, "Event `{0}' can override only event", GetSignatureForError ());
7384 public override void Emit ()
7386 if (OptAttributes != null) {
7387 EmitContext ec = new EmitContext (
7388 Parent, Location, null, MemberType, ModFlags);
7389 OptAttributes.Emit (ec, this);
7393 Remove.Emit (Parent);
7398 public override string GetSignatureForError ()
7400 return base.GetSignatureForError ();
7404 // Represents header string for documentation comment.
7406 public override string DocCommentHeader {
7407 get { return "E:"; }
7412 public class Indexer : PropertyBase, IIteratorContainer {
7414 class GetIndexerMethod : GetMethod
7416 public GetIndexerMethod (MethodCore method):
7421 public GetIndexerMethod (MethodCore method, Accessor accessor):
7422 base (method, accessor)
7426 public override Parameters ParameterInfo {
7428 return method.ParameterInfo;
7433 class SetIndexerMethod: SetMethod
7435 public SetIndexerMethod (MethodCore method):
7440 public SetIndexerMethod (MethodCore method, Accessor accessor):
7441 base (method, accessor)
7445 protected override void DefineParameters ()
7447 Parameter [] fixed_parms = method.Parameters.FixedParameters;
7448 Parameter [] tmp = new Parameter [fixed_parms.Length + 1];
7450 fixed_parms.CopyTo (tmp, 0);
7451 tmp [fixed_parms.Length] = new Parameter (
7452 method.MemberType, "value", Parameter.Modifier.NONE, null, method.Location);
7454 parameters = new Parameters (tmp);
7455 parameters.Resolve (null);
7459 const int AllowedModifiers =
7462 Modifiers.PROTECTED |
7463 Modifiers.INTERNAL |
7467 Modifiers.OVERRIDE |
7472 const int AllowedInterfaceModifiers =
7476 // Are we implementing an interface ?
7478 public Indexer (TypeContainer parent, Expression type, MemberName name, int mod,
7479 bool is_iface, Parameters parameters, Attributes attrs,
7480 Accessor get_block, Accessor set_block)
7481 : base (parent, type, mod,
7482 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
7483 is_iface, name, parameters, attrs)
7485 if (get_block == null)
7486 Get = new GetIndexerMethod (this);
7488 Get = new GetIndexerMethod (this, get_block);
7490 if (set_block == null)
7491 Set = new SetIndexerMethod (this);
7493 Set = new SetIndexerMethod (this, set_block);
7496 public override bool Define ()
7498 if (!DoDefineBase ())
7501 if (!base.Define ())
7504 if (MemberType == TypeManager.void_type) {
7505 Report.Error (620, Location, "Indexers cannot have void type");
7509 if (OptAttributes != null) {
7510 Attribute indexer_attr = OptAttributes.Search (TypeManager.indexer_name_type, ec);
7511 if (indexer_attr != null) {
7512 // Remove the attribute from the list because it is not emitted
7513 OptAttributes.Attrs.Remove (indexer_attr);
7515 ShortName = indexer_attr.GetIndexerAttributeValue (ec);
7517 if (IsExplicitImpl) {
7518 Report.Error (415, indexer_attr.Location,
7519 "The `IndexerName' attribute is valid only on an " +
7520 "indexer that is not an explicit interface member declaration");
7524 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
7525 Report.Error (609, indexer_attr.Location,
7526 "Cannot set the `IndexerName' attribute on an indexer marked override");
7530 if (!Tokenizer.IsValidIdentifier (ShortName)) {
7531 Report.Error (633, indexer_attr.Location,
7532 "The argument to the `IndexerName' attribute must be a valid identifier");
7538 if (InterfaceType != null) {
7539 string base_IndexerName = TypeManager.IndexerPropertyName (InterfaceType);
7540 if (base_IndexerName != Name)
7541 ShortName = base_IndexerName;
7544 if (!Parent.AddToMemberContainer (this) ||
7545 !Parent.AddToMemberContainer (Get) || !Parent.AddToMemberContainer (Set))
7551 flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
7553 GetBuilder = Get.Define (Parent);
7554 if (GetBuilder == null)
7558 // Setup iterator if we are one
7560 if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
7561 Iterator iterator = new Iterator (
7562 Get, Parent, null, ModFlags);
7564 if (!iterator.DefineIterator ())
7569 SetBuilder = Set.Define (Parent);
7571 if (SetBuilder == null)
7576 // Now name the parameters
7578 Parameter [] p = Parameters.FixedParameters;
7580 // TODO: should be done in parser and it needs to do cycle
7581 if ((p [0].ModFlags & Parameter.Modifier.ISBYREF) != 0) {
7582 Report.Error (631, Location, "ref and out are not valid in this context");
7587 PropertyBuilder = Parent.TypeBuilder.DefineProperty (
7588 Name, PropertyAttributes.None, MemberType, ParameterTypes);
7591 PropertyBuilder.SetGetMethod (GetBuilder);
7594 PropertyBuilder.SetSetMethod (SetBuilder);
7596 TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder, ParameterTypes);
7601 public override string GetSignatureForError ()
7603 StringBuilder sb = new StringBuilder (Parent.GetSignatureForError ());
7604 if (MemberName.Left != null) {
7606 sb.Append (MemberName.Left);
7609 sb.Append (".this");
7610 sb.Append (Parameters.GetSignatureForError ().Replace ('(', '[').Replace (')', ']'));
7611 return sb.ToString ();
7614 public override bool MarkForDuplicationCheck ()
7616 caching_flags |= Flags.TestMethodDuplication;
7621 public class Operator : MethodCore, IIteratorContainer {
7623 const int AllowedModifiers =
7629 public enum OpType : byte {
7639 // Unary and Binary operators
7662 // Implicit and Explicit
7666 // Just because of enum
7670 public readonly OpType OperatorType;
7671 public MethodBuilder OperatorMethodBuilder;
7673 public Method OperatorMethod;
7675 static string[] attribute_targets = new string [] { "method", "return" };
7677 public Operator (TypeContainer parent, OpType type, Expression ret_type,
7678 int mod_flags, Parameters parameters,
7679 ToplevelBlock block, Attributes attrs, Location loc)
7680 : base (parent, null, ret_type, mod_flags, AllowedModifiers, false,
7681 new MemberName ("op_" + type, loc), attrs, parameters)
7683 OperatorType = type;
7687 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
7689 OperatorMethod.ApplyAttributeBuilder (a, cb);
7692 public override AttributeTargets AttributeTargets {
7694 return AttributeTargets.Method;
7698 protected override bool CheckForDuplications()
7700 ArrayList ar = Parent.Operators;
7702 int arLen = ar.Count;
7704 for (int i = 0; i < arLen; i++) {
7705 Operator o = (Operator) ar [i];
7706 if (IsDuplicateImplementation (o))
7711 ar = Parent.Methods;
7713 int arLen = ar.Count;
7715 for (int i = 0; i < arLen; i++) {
7716 Method m = (Method) ar [i];
7717 if (IsDuplicateImplementation (m))
7725 public override bool Define ()
7727 const int RequiredModifiers = Modifiers.PUBLIC | Modifiers.STATIC;
7728 if ((ModFlags & RequiredModifiers) != RequiredModifiers){
7729 Report.Error (558, Location, "User-defined operator `{0}' must be declared static and public", GetSignatureForError ());
7736 if (MemberType == TypeManager.void_type) {
7737 Report.Error (590, Location, "User-defined operators cannot return void");
7741 OperatorMethod = new Method (
7742 Parent, null, Type, ModFlags, false, MemberName,
7743 Parameters, OptAttributes);
7745 OperatorMethod.Block = Block;
7746 OperatorMethod.IsOperator = this;
7747 OperatorMethod.flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
7748 OperatorMethod.Define ();
7750 if (OperatorMethod.MethodBuilder == null)
7753 OperatorMethodBuilder = OperatorMethod.MethodBuilder;
7755 Type[] parameter_types = OperatorMethod.ParameterTypes;
7756 Type declaring_type = OperatorMethod.MethodData.DeclaringType;
7757 Type return_type = OperatorMethod.ReturnType;
7758 Type first_arg_type = parameter_types [0];
7763 // Rules for conversion operators
7765 if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
7766 if (first_arg_type == return_type && first_arg_type == declaring_type){
7767 Report.Error (555, Location,
7768 "User-defined operator cannot take an object of the enclosing type and convert to an object of the enclosing type");
7772 if (first_arg_type != declaring_type && return_type != declaring_type){
7775 "User-defined conversion must convert to or from the " +
7780 if (first_arg_type == TypeManager.object_type ||
7781 return_type == TypeManager.object_type){
7784 "User-defined conversion cannot convert to or from " +
7789 if (first_arg_type.IsInterface || return_type.IsInterface){
7790 Report.Error (552, Location, "User-defined conversion `{0}' cannot convert to or from an interface type",
7791 GetSignatureForError ());
7795 if (first_arg_type.IsSubclassOf (return_type)
7796 || return_type.IsSubclassOf (first_arg_type)){
7797 if (declaring_type.IsSubclassOf (return_type)) {
7798 Report.Error (553, Location, "User-defined conversion `{0}' cannot convert to or from base class",
7799 GetSignatureForError ());
7802 Report.Error (554, Location, "User-defined conversion `{0}' cannot convert to or from derived class",
7803 GetSignatureForError ());
7806 } else if (OperatorType == OpType.LeftShift || OperatorType == OpType.RightShift) {
7807 if (first_arg_type != declaring_type || parameter_types [1] != TypeManager.int32_type) {
7808 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");
7811 } else if (Parameters.Count == 1) {
7812 // Checks for Unary operators
7814 if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
7815 if (return_type != declaring_type && !return_type.IsSubclassOf (declaring_type)) {
7816 Report.Error (448, Location,
7817 "The return type for ++ or -- operator must be the containing type or derived from the containing type");
7820 if (first_arg_type != declaring_type){
7822 559, Location, "The parameter type for ++ or -- operator must be the containing type");
7827 if (first_arg_type != declaring_type){
7830 "The parameter of a unary operator must be the " +
7835 if (OperatorType == OpType.True || OperatorType == OpType.False) {
7836 if (return_type != TypeManager.bool_type){
7839 "The return type of operator True or False " +
7846 // Checks for Binary operators
7848 if (first_arg_type != declaring_type &&
7849 parameter_types [1] != declaring_type){
7852 "One of the parameters of a binary operator must " +
7853 "be the containing type");
7861 public override void Emit ()
7864 // abstract or extern methods have no bodies
7866 if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
7869 OperatorMethod.Emit ();
7873 // Operator cannot be override
7874 protected override MethodInfo FindOutBaseMethod (TypeContainer container, ref Type base_ret_type)
7879 public static string GetName (OpType ot)
7882 case OpType.LogicalNot:
7884 case OpType.OnesComplement:
7886 case OpType.Increment:
7888 case OpType.Decrement:
7894 case OpType.Addition:
7896 case OpType.Subtraction:
7898 case OpType.UnaryPlus:
7900 case OpType.UnaryNegation:
7902 case OpType.Multiply:
7904 case OpType.Division:
7906 case OpType.Modulus:
7908 case OpType.BitwiseAnd:
7910 case OpType.BitwiseOr:
7912 case OpType.ExclusiveOr:
7914 case OpType.LeftShift:
7916 case OpType.RightShift:
7918 case OpType.Equality:
7920 case OpType.Inequality:
7922 case OpType.GreaterThan:
7924 case OpType.LessThan:
7926 case OpType.GreaterThanOrEqual:
7928 case OpType.LessThanOrEqual:
7930 case OpType.Implicit:
7932 case OpType.Explicit:
7938 public static OpType GetOperatorType (string name)
7940 if (name.StartsWith ("op_")){
7941 for (int i = 0; i < Unary.oper_names.Length; ++i) {
7942 if (Unary.oper_names [i] == name)
7946 for (int i = 0; i < Binary.oper_names.Length; ++i) {
7947 if (Binary.oper_names [i] == name)
7954 public override string GetSignatureForError ()
7956 StringBuilder sb = new StringBuilder ();
7957 if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
7958 sb.AppendFormat ("{0}.{1} operator {2}", Parent.GetSignatureForError (), GetName (OperatorType), Type.Type == null ? Type.ToString () : TypeManager.CSharpName (Type.Type));
7961 sb.AppendFormat ("{0}.operator {1}", Parent.GetSignatureForError (), GetName (OperatorType));
7964 sb.Append (Parameters.GetSignatureForError ());
7965 return sb.ToString ();
7968 public override bool MarkForDuplicationCheck ()
7970 caching_flags |= Flags.TestMethodDuplication;
7974 public override string[] ValidAttributeTargets {
7976 return attribute_targets;
7982 // This is used to compare method signatures
7984 struct MethodSignature {
7986 public Type RetType;
7987 public Type [] Parameters;
7990 /// This delegate is used to extract methods which have the
7991 /// same signature as the argument
7993 public static MemberFilter method_signature_filter = new MemberFilter (MemberSignatureCompare);
7995 public MethodSignature (string name, Type ret_type, Type [] parameters)
8000 if (parameters == null)
8001 Parameters = Type.EmptyTypes;
8003 Parameters = parameters;
8006 public override string ToString ()
8009 if (Parameters.Length != 0){
8010 System.Text.StringBuilder sb = new System.Text.StringBuilder ();
8011 for (int i = 0; i < Parameters.Length; i++){
8012 sb.Append (Parameters [i]);
8013 if (i+1 < Parameters.Length)
8016 pars = sb.ToString ();
8019 return String.Format ("{0} {1} ({2})", RetType, Name, pars);
8022 public override int GetHashCode ()
8024 return Name.GetHashCode ();
8027 public override bool Equals (Object o)
8029 MethodSignature other = (MethodSignature) o;
8031 if (other.Name != Name)
8034 if (other.RetType != RetType)
8037 if (Parameters == null){
8038 if (other.Parameters == null)
8043 if (other.Parameters == null)
8046 int c = Parameters.Length;
8047 if (other.Parameters.Length != c)
8050 for (int i = 0; i < c; i++)
8051 if (other.Parameters [i] != Parameters [i])
8057 static bool MemberSignatureCompare (MemberInfo m, object filter_criteria)
8059 MethodSignature sig = (MethodSignature) filter_criteria;
8061 if (m.Name != sig.Name)
8065 MethodInfo mi = m as MethodInfo;
8066 PropertyInfo pi = m as PropertyInfo;
8069 ReturnType = mi.ReturnType;
8070 else if (pi != null)
8071 ReturnType = pi.PropertyType;
8076 // we use sig.RetType == null to mean `do not check the
8077 // method return value.
8079 if (sig.RetType != null)
8080 if (ReturnType != sig.RetType)
8085 args = TypeManager.GetParameterData (mi).Types;
8087 args = TypeManager.GetArgumentTypes (pi);
8088 Type [] sigp = sig.Parameters;
8090 if (args.Length != sigp.Length)
8093 for (int i = args.Length; i > 0; ){
8095 if (args [i] != sigp [i])