2 // class.cs: Class and Struct handlers
4 // Authors: Miguel de Icaza (miguel@gnu.org)
5 // Martin Baulig (martin@gnome.org)
6 // Marek Safar (marek.safar@seznam.cz)
8 // Licensed under the terms of the GNU GPL
10 // (C) 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
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.
35 using System.Collections;
36 using System.Collections.Specialized;
37 using System.Reflection;
38 using System.Reflection.Emit;
39 using System.Runtime.CompilerServices;
40 using System.Runtime.InteropServices;
41 using System.Security;
42 using System.Security.Permissions;
45 #if BOOTSTRAP_WITH_OLDLIB
46 using XmlElement = System.Object;
51 using Mono.CompilerServices.SymbolWriter;
53 namespace Mono.CSharp {
63 /// This is the base class for structs and classes.
65 public abstract class TypeContainer : DeclSpace, IMemberContainer {
67 public class MemberCoreArrayList: ArrayList
70 /// Defines the MemberCore objects that are in this array
72 public virtual void DefineContainerMembers ()
74 foreach (MemberCore mc in this) {
79 public virtual void Emit ()
81 foreach (MemberCore mc in this)
86 public class MethodArrayList: MemberCoreArrayList
94 CachedMethods cached_method;
95 TypeContainer container;
97 public MethodArrayList (TypeContainer container)
99 this.container = container;
103 /// Method container contains Equals method
105 public bool HasEquals {
107 cached_method |= CachedMethods.Equals;
111 return (cached_method & CachedMethods.Equals) != 0;
116 /// Method container contains GetHashCode method
118 public bool HasGetHashCode {
120 cached_method |= CachedMethods.GetHashCode;
124 return (cached_method & CachedMethods.GetHashCode) != 0;
128 public override void DefineContainerMembers ()
130 base.DefineContainerMembers ();
132 if ((RootContext.WarningLevel >= 3) && HasEquals && !HasGetHashCode) {
133 Report.Warning (659, container.Location, "'{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", container.GetSignatureForError ());
139 public sealed class IndexerArrayList: MemberCoreArrayList
142 /// The indexer name for this container
144 public string IndexerName = DefaultIndexerName;
146 bool seen_normal_indexers = false;
148 TypeContainer container;
150 public IndexerArrayList (TypeContainer container)
152 this.container = container;
156 /// Defines the indexers, and also verifies that the IndexerNameAttribute in the
157 /// class is consistent. Either it is `Item' or it is the name defined by all the
158 /// indexers with the `IndexerName' attribute.
160 /// Turns out that the IndexerNameAttribute is applied to each indexer,
161 /// but it is never emitted, instead a DefaultMember attribute is attached
164 public override void DefineContainerMembers()
166 base.DefineContainerMembers ();
168 string class_indexer_name = null;
171 // If there's both an explicit and an implicit interface implementation, the
172 // explicit one actually implements the interface while the other one is just
173 // a normal indexer. See bug #37714.
176 // Invariant maintained by AddIndexer(): All explicit interface indexers precede normal indexers
177 foreach (Indexer i in this) {
178 if (i.InterfaceType != null) {
179 if (seen_normal_indexers)
180 throw new Exception ("Internal Error: 'Indexers' array not sorted properly.");
184 seen_normal_indexers = true;
186 if (class_indexer_name == null) {
187 class_indexer_name = i.ShortName;
191 if (i.ShortName != class_indexer_name)
192 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");
195 if (class_indexer_name != null)
196 IndexerName = class_indexer_name;
199 public override void Emit ()
203 if (!seen_normal_indexers)
206 CustomAttributeBuilder cb = new CustomAttributeBuilder (TypeManager.default_member_ctor, new string [] { IndexerName });
207 container.TypeBuilder.SetCustomAttribute (cb);
211 public class OperatorArrayList: MemberCoreArrayList
213 TypeContainer container;
215 public OperatorArrayList (TypeContainer container)
217 this.container = container;
221 // Operator pair checking
226 public Type ret_type;
227 public Type type1, type2;
229 public Operator.OpType ot;
231 public OperatorEntry (int f, Operator o)
235 ret_type = o.OperatorMethod.ReturnType;
236 Type [] pt = o.OperatorMethod.ParameterTypes;
243 public override int GetHashCode ()
245 return ret_type.GetHashCode ();
248 public override bool Equals (object o)
250 OperatorEntry other = (OperatorEntry) o;
252 if (other.ret_type != ret_type)
254 if (other.type1 != type1)
256 if (other.type2 != type2)
263 // Checks that some operators come in pairs:
269 // They are matched based on the return type and the argument types
271 void CheckPairedOperators ()
273 Hashtable pairs = new Hashtable (null, null);
274 Operator true_op = null;
275 Operator false_op = null;
276 bool has_equality_or_inequality = false;
278 // Register all the operators we care about.
279 foreach (Operator op in this){
282 switch (op.OperatorType){
283 case Operator.OpType.Equality:
285 has_equality_or_inequality = true;
287 case Operator.OpType.Inequality:
289 has_equality_or_inequality = true;
292 case Operator.OpType.True:
295 case Operator.OpType.False:
299 case Operator.OpType.GreaterThan:
301 case Operator.OpType.LessThan:
304 case Operator.OpType.GreaterThanOrEqual:
306 case Operator.OpType.LessThanOrEqual:
312 OperatorEntry oe = new OperatorEntry (reg, op);
314 object o = pairs [oe];
318 oe = (OperatorEntry) o;
323 if (true_op != null){
324 if (false_op == null)
325 Report.Error (216, true_op.Location, "operator true requires a matching operator false");
326 } else if (false_op != null)
327 Report.Error (216, false_op.Location, "operator false requires a matching operator true");
330 // Look for the mistakes.
332 foreach (DictionaryEntry de in pairs){
333 OperatorEntry oe = (OperatorEntry) de.Key;
340 case Operator.OpType.Equality:
343 case Operator.OpType.Inequality:
346 case Operator.OpType.GreaterThan:
349 case Operator.OpType.LessThan:
352 case Operator.OpType.GreaterThanOrEqual:
355 case Operator.OpType.LessThanOrEqual:
359 Report.Error (216, oe.op.Location,
360 "The operator `" + oe.op + "' requires a matching operator `" + s + "' to also be defined");
363 if (has_equality_or_inequality && (RootContext.WarningLevel > 2)) {
364 if (container.Methods == null || !container.Methods.HasEquals)
365 Report.Warning (660, container.Location, "'{0}' defines operator == or operator != but does not override Object.Equals(object o)", container.GetSignatureForError ());
367 if (container.Methods == null || !container.Methods.HasGetHashCode)
368 Report.Warning (661, container.Location, "'{0}' defines operator == or operator != but does not override Object.GetHashCode()", container.GetSignatureForError ());
372 public override void DefineContainerMembers ()
374 base.DefineContainerMembers ();
375 CheckPairedOperators ();
380 // Whether this is a struct, class or interface
381 public readonly Kind Kind;
383 // Holds a list of classes and structures
386 // Holds the list of properties
387 MemberCoreArrayList properties;
389 // Holds the list of enumerations
390 MemberCoreArrayList enums;
392 // Holds the list of delegates
393 MemberCoreArrayList delegates;
395 // Holds the list of constructors
396 protected MemberCoreArrayList instance_constructors;
398 // Holds the list of fields
399 MemberCoreArrayList fields;
401 // Holds a list of fields that have initializers
402 protected ArrayList initialized_fields;
404 // Holds a list of static fields that have initializers
405 protected ArrayList initialized_static_fields;
407 // Holds the list of constants
408 MemberCoreArrayList constants;
411 MemberCoreArrayList interfaces;
413 // Holds the methods.
414 MethodArrayList methods;
417 protected MemberCoreArrayList events;
419 // Holds the indexers
420 IndexerArrayList indexers;
422 // Holds the operators
423 MemberCoreArrayList operators;
425 // Holds the iterators
428 // Holds the parts of a partial class;
431 // The emit context for toplevel objects.
434 public EmitContext EmitContext {
439 // Pointers to the default constructor and the default static constructor
441 protected Constructor default_constructor;
442 protected Constructor default_static_constructor;
445 // Whether we have at least one non-static field
447 bool have_nonstatic_fields = false;
450 // This one is computed after we can distinguish interfaces
451 // from classes from the arraylist `type_bases'
453 string base_class_name;
454 TypeExpr parent_type;
456 ArrayList type_bases;
458 bool members_defined;
459 bool members_defined_ok;
461 // The interfaces we implement.
462 protected Type [] ifaces;
463 protected Type ptype;
465 // The parent member cache and our member cache
466 MemberCache parent_cache;
467 MemberCache member_cache;
469 public const string DefaultIndexerName = "Item";
471 public TypeContainer (NamespaceEntry ns, TypeContainer parent, MemberName name,
472 Attributes attrs, Kind kind, Location l)
473 : base (ns, parent, name, attrs, l)
477 types = new ArrayList ();
479 base_class_name = null;
482 public bool AddToMemberContainer (MemberCore symbol, bool is_method)
484 return AddToContainer (symbol, is_method, String.Concat (Name, '.', symbol.Name), symbol.Name);
487 bool AddToTypeContainer (DeclSpace ds)
489 return AddToContainer (ds, false, ds.Name, ds.Basename);
492 public void AddConstant (Const constant)
494 if (!AddToMemberContainer (constant, false))
497 if (constants == null)
498 constants = new MemberCoreArrayList ();
500 constants.Add (constant);
503 public void AddEnum (Mono.CSharp.Enum e)
505 if (!AddToTypeContainer (e))
509 enums = new MemberCoreArrayList ();
514 public void AddClassOrStruct (TypeContainer c)
516 if (!AddToTypeContainer (c))
522 public void AddDelegate (Delegate d)
524 if (!AddToTypeContainer (d))
527 if (delegates == null)
528 delegates = new MemberCoreArrayList ();
533 public void AddMethod (Method method)
535 if (!AddToMemberContainer (method, true))
539 methods = new MethodArrayList (this);
541 if (method.Name.IndexOf ('.') != -1)
542 methods.Insert (0, method);
544 methods.Add (method);
547 public void AddConstructor (Constructor c)
549 if (c.Name != Basename) {
550 Report.Error (1520, c.Location, "Class, struct, or interface method must have a return type");
553 bool is_static = (c.ModFlags & Modifiers.STATIC) != 0;
556 if (default_static_constructor != null) {
557 Report.SymbolRelatedToPreviousError (default_static_constructor);
558 Report.Error (111, c.Location, Error111, Name, c.Name);
562 default_static_constructor = c;
565 if (default_constructor != null) {
566 Report.SymbolRelatedToPreviousError (default_constructor);
567 Report.Error (111, c.Location, Error111, c.Location, Name, c.Name);
570 default_constructor = c;
573 if (instance_constructors == null)
574 instance_constructors = new MemberCoreArrayList ();
576 instance_constructors.Add (c);
580 internal static string Error111 {
582 return "Type '{0}' already defines a member called '{1}' with the same parameter types";
586 public void AddInterface (TypeContainer iface)
588 if (!AddToTypeContainer (iface))
591 if (interfaces == null) {
592 interfaces = new MemberCoreArrayList ();
595 interfaces.Add (iface);
598 public void AddField (Field field)
600 if (!AddToMemberContainer (field, false))
604 fields = new MemberCoreArrayList ();
608 if (field.HasInitializer){
609 if ((field.ModFlags & Modifiers.STATIC) != 0){
610 if (initialized_static_fields == null)
611 initialized_static_fields = new ArrayList ();
613 initialized_static_fields.Add (field);
615 if (initialized_fields == null)
616 initialized_fields = new ArrayList ();
618 initialized_fields.Add (field);
622 if ((field.ModFlags & Modifiers.STATIC) == 0)
623 have_nonstatic_fields = true;
626 public void AddProperty (Property prop)
628 if (!AddToMemberContainer (prop, false) ||
629 !AddToMemberContainer (prop.Get, true) || !AddToMemberContainer (prop.Set, true))
632 if (properties == null)
633 properties = new MemberCoreArrayList ();
635 if (prop.Name.IndexOf ('.') != -1)
636 properties.Insert (0, prop);
638 properties.Add (prop);
641 public void AddEvent (Event e)
643 if (!AddToMemberContainer (e, false))
646 if (e is EventProperty) {
647 if (!AddToMemberContainer (e.Add, true))
650 if (!AddToMemberContainer (e.Remove, true))
655 events = new MemberCoreArrayList ();
662 /// Indexer has special handling in constrast to other AddXXX because the name can be driven by IndexerNameAttribute
664 public void AddIndexer (Indexer i)
666 if (indexers == null)
667 indexers = new IndexerArrayList (this);
669 if (i.IsExplicitImpl)
670 indexers.Insert (0, i);
675 public void AddOperator (Operator op)
677 if (!AddToMemberContainer (op, true))
680 if (operators == null)
681 operators = new OperatorArrayList (this);
686 public void AddIterator (Iterator i)
688 if (iterators == null)
689 iterators = new ArrayList ();
694 public void AddType (TypeContainer tc)
699 public void AddPart (ClassPart part)
702 parts = new ArrayList ();
707 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
709 if (a.Type == TypeManager.default_member_type) {
710 if (Indexers != null) {
711 Report.Error (646, a.Location,
712 "Cannot specify the DefaultMember attribute on" +
713 " a type containing an indexer");
718 base.ApplyAttributeBuilder (a, cb);
721 public override AttributeTargets AttributeTargets {
723 throw new NotSupportedException ();
727 public ArrayList Types {
733 public MethodArrayList Methods {
739 public ArrayList Constants {
745 public ArrayList Interfaces {
751 public ArrayList Iterators {
759 return base_class_name;
763 public ArrayList Bases {
773 public ArrayList Fields {
779 public ArrayList InstanceConstructors {
781 return instance_constructors;
785 public ArrayList Properties {
791 public ArrayList Events {
797 public ArrayList Enums {
803 public ArrayList Indexers {
809 public ArrayList Operators {
815 public ArrayList Delegates {
821 public ArrayList Parts {
827 public virtual TypeAttributes TypeAttr {
829 return Modifiers.TypeAttr (ModFlags, this);
833 public string IndexerName {
835 return indexers == null ? DefaultIndexerName : indexers.IndexerName;
840 // Emits the instance field initializers
842 public bool EmitFieldInitializers (EmitContext ec)
845 Expression instance_expr;
848 fields = initialized_static_fields;
849 instance_expr = null;
851 fields = initialized_fields;
852 instance_expr = new This (Location.Null).Resolve (ec);
858 foreach (Field f in fields){
859 Expression e = f.GetInitializerExpression (ec);
863 Location l = f.Location;
864 FieldExpr fe = new FieldExpr (f.FieldBuilder, l);
865 fe.InstanceExpression = instance_expr;
866 ExpressionStatement a = new Assign (fe, e, l);
868 a = a.ResolveStatement (ec);
872 a.EmitStatement (ec);
879 // Defines the default constructors
881 protected void DefineDefaultConstructor (bool is_static)
885 // The default constructor is public
886 // If the class is abstract, the default constructor is protected
887 // The default static constructor is private
889 int mods = Modifiers.PUBLIC;
891 mods = Modifiers.STATIC | Modifiers.PRIVATE;
892 else if ((ModFlags & Modifiers.ABSTRACT) != 0)
893 mods = Modifiers.PROTECTED;
895 c = new Constructor (this, Basename, mods, Parameters.EmptyReadOnlyParameters,
896 new ConstructorBaseInitializer (
897 null, Parameters.EmptyReadOnlyParameters,
903 c.Block = new ToplevelBlock (null, Location);
908 /// The pending methods that need to be implemented
909 // (interfaces or abstract methods)
911 public PendingImplementation Pending;
913 public abstract void Register ();
915 public abstract PendingImplementation GetPendingImplementations ();
917 TypeExpr[] GetPartialBases (out TypeExpr parent, out bool error)
919 ArrayList ifaces = new ArrayList ();
922 Location parent_loc = Location.Null;
924 foreach (ClassPart part in parts) {
926 TypeExpr[] new_ifaces;
928 new_ifaces = part.GetClassBases (out new_parent, out error);
932 if ((parent != null) && (new_parent != null) &&
933 !parent.Equals (new_parent)) {
934 Report.Error (263, part.Location,
935 "Partial declarations of `{0}' must " +
936 "not specify different base classes",
939 if (!Location.IsNull (parent_loc))
940 Report.LocationOfPreviousError (parent_loc);
946 if ((parent == null) && (new_parent != null)) {
948 parent_loc = part.Location;
951 if (new_ifaces == null)
954 foreach (TypeExpr iface in new_ifaces) {
956 foreach (TypeExpr old_iface in ifaces) {
957 if (old_iface.Equals (iface)) {
970 TypeExpr[] retval = new TypeExpr [ifaces.Count];
971 ifaces.CopyTo (retval, 0);
975 TypeExpr[] GetNormalBases (out TypeExpr parent, out bool error)
979 int count = Bases.Count;
982 if (Kind == Kind.Class){
983 TypeExpr name = ResolveTypeExpr (
984 (Expression) Bases [0], false, Location);
1001 TypeExpr [] ifaces = new TypeExpr [count-start];
1003 for (i = start, j = 0; i < count; i++, j++){
1004 Expression name = (Expression) Bases [i];
1005 TypeExpr resolved = ResolveTypeExpr (name, false, Location);
1006 if (resolved == null) {
1011 ifaces [j] = resolved;
1019 /// This function computes the Base class and also the
1020 /// list of interfaces that the class or struct @c implements.
1022 /// The return value is an array (might be null) of
1023 /// interfaces implemented (as Types).
1025 /// The @parent argument is set to the parent object or null
1026 /// if this is `System.Object'.
1028 TypeExpr [] GetClassBases (out TypeExpr parent, out bool error)
1037 ifaces = GetPartialBases (out parent, out error);
1038 else if (Bases == null){
1042 ifaces = GetNormalBases (out parent, out error);
1047 if ((parent != null) && (Kind == Kind.Class)){
1048 if (parent.IsSealed){
1050 Report.SymbolRelatedToPreviousError (parent.Type);
1051 if (parent.Type.IsAbstract) {
1052 Report.Error (709, Location, "'{0}': Cannot derive from static class", GetSignatureForError ());
1054 Report.Error (509, Location, "'{0}': Cannot derive from sealed class", GetSignatureForError ());
1059 if (!parent.CanInheritFrom ()){
1060 Report.Error (644, Location,
1061 "`{0}' cannot inherit from special class `{1}'",
1067 if (!parent.AsAccessible (this, ModFlags)) {
1068 Report.SymbolRelatedToPreviousError (parent.Type);
1069 Report.Error (60, Location, "Inconsistent accessibility: base class '{0}' is less accessible than class '{1}'",
1070 TypeManager.CSharpName (parent.Type), GetSignatureForError ());
1075 base_class_name = parent.Name;
1080 int count = ifaces != null ? ifaces.Length : 0;
1082 for (i = 0; i < count; i++) {
1083 TypeExpr iface = (TypeExpr) ifaces [i];
1085 if ((Kind != Kind.Class) && !iface.IsInterface){
1086 string what = Kind == Kind.Struct ?
1087 "Struct" : "Interface";
1089 Report.Error (527, Location,
1090 "In {0} `{1}', type `{2}' is not "+
1091 "an interface", what, Name, iface.Name);
1095 if (iface.IsClass) {
1097 Report.Error (1721, Location,
1098 "In Class `{0}', `{1}' is not an interface, and a base class has already been defined",
1101 Report.Error (1722, Location,
1102 "In Class `{0}', `{1}' is not " +
1103 "an interface, a base class must be listed first", Name, iface.Name);
1109 for (int x = 0; x < i; x++) {
1110 if (iface.Equals (ifaces [x])) {
1111 Report.Error (528, Location,
1112 "`{0}' is already listed in " +
1113 "interface list", iface.Name);
1119 if ((Kind == Kind.Interface) &&
1120 !iface.AsAccessible (Parent, ModFlags))
1121 Report.Error (61, Location,
1122 "Inconsistent accessibility: base " +
1123 "interface `{0}' is less accessible " +
1124 "than interface `{1}'", iface.Name,
1134 // Defines the type in the appropriate ModuleBuilder or TypeBuilder.
1136 public override TypeBuilder DefineType ()
1138 if (TypeBuilder != null)
1145 Report.Error (146, Location, "Class definition is circular: `{0}'", Name);
1152 ec = new EmitContext (this, Mono.CSharp.Location.Null, null, null, ModFlags);
1154 TypeExpr[] iface_exprs = GetClassBases (out parent_type, out error);
1158 if (parent_type == null) {
1159 if (Kind == Kind.Class){
1160 if (RootContext.StdLib)
1161 parent_type = TypeManager.system_object_expr;
1162 else if (Name != "System.Object")
1163 parent_type = TypeManager.system_object_expr;
1164 } else if (Kind == Kind.Struct) {
1166 // If we are compiling our runtime,
1167 // and we are defining ValueType, then our
1168 // parent is `System.Object'.
1170 if (!RootContext.StdLib && Name == "System.ValueType")
1171 parent_type = TypeManager.system_object_expr;
1173 parent_type = TypeManager.system_valuetype_expr;
1177 if ((Kind == Kind.Struct) && TypeManager.value_type == null)
1178 throw new Exception ();
1180 TypeAttributes type_attributes = TypeAttr;
1182 if (parent_type != null) {
1183 ptype = parent_type.ResolveType (ec);
1184 if (ptype == null) {
1192 if (TypeManager.NamespaceClash (Name, Location)) {
1197 ModuleBuilder builder = CodeGen.Module.Builder;
1198 TypeBuilder = builder.DefineType (
1199 Name, type_attributes, ptype, null);
1202 TypeBuilder builder = Parent.DefineType ();
1203 if (builder == null)
1206 TypeBuilder = builder.DefineNestedType (
1207 Basename, type_attributes, ptype, null);
1210 catch (ArgumentException) {
1211 Report.RuntimeMissingSupport (Location, "static classes");
1216 // Structs with no fields need to have at least one byte.
1217 // The right thing would be to set the PackingSize in a DefineType
1218 // but there are no functions that allow interfaces *and* the size to
1222 if ((Kind == Kind.Struct) && !have_nonstatic_fields){
1223 TypeBuilder.DefineField ("$PRIVATE$", TypeManager.byte_type,
1224 FieldAttributes.Private);
1227 // add interfaces that were not added at type creation
1228 if (iface_exprs != null) {
1229 ifaces = TypeManager.ExpandInterfaces (ec, iface_exprs);
1230 if (ifaces == null) {
1235 foreach (Type itype in ifaces)
1236 TypeBuilder.AddInterfaceImplementation (itype);
1238 TypeManager.RegisterBuilder (TypeBuilder, ifaces);
1242 // Finish the setup for the EmitContext
1244 ec.ContainerType = TypeBuilder;
1246 TypeManager.AddUserType (Name, TypeBuilder, this);
1248 if ((parent_type != null) && parent_type.IsAttribute) {
1249 RootContext.RegisterAttribute (this);
1250 } else if (!(this is Iterator))
1251 RootContext.RegisterOrder (this);
1253 if (!DefineNestedTypes ()) {
1262 protected virtual bool DefineNestedTypes ()
1264 if (Interfaces != null) {
1265 foreach (TypeContainer iface in Interfaces)
1266 if (iface.DefineType () == null)
1270 if (Types != null) {
1271 foreach (TypeContainer tc in Types)
1272 if (tc.DefineType () == null)
1276 if (Delegates != null) {
1277 foreach (Delegate d in Delegates)
1278 if (d.DefineType () == null)
1282 if (Enums != null) {
1283 foreach (Enum en in Enums)
1284 if (en.DefineType () == null)
1288 if (Parts != null) {
1289 foreach (ClassPart part in Parts) {
1290 part.TypeBuilder = TypeBuilder;
1292 part.ec = new EmitContext (part, Mono.CSharp.Location.Null, null, null, ModFlags);
1299 static void Error_KeywordNotAllowed (Location loc)
1301 Report.Error (1530, loc, "Keyword new not allowed for namespace elements");
1305 /// Populates our TypeBuilder with fields and methods
1307 public override bool DefineMembers (TypeContainer container)
1309 if (members_defined)
1310 return members_defined_ok;
1312 members_defined_ok = DoDefineMembers ();
1313 members_defined = true;
1315 return members_defined_ok;
1318 bool DoDefineMembers ()
1321 // We need to be able to use the member cache while we are checking/defining
1323 if (TypeBuilder.BaseType != null)
1324 parent_cache = TypeManager.LookupMemberCache (TypeBuilder.BaseType);
1326 if (TypeBuilder.IsInterface)
1327 parent_cache = TypeManager.LookupParentInterfacesCache (TypeBuilder);
1330 if ((ModFlags & Modifiers.NEW) != 0)
1331 Error_KeywordNotAllowed (Location);
1333 // HACK: missing implemenation
1334 // This is not fully functional. Better way how to handle this is to have recursive definition of containers
1335 // instead of flat as we have now.
1336 // Now we are not able to check inner attribute class because its parent had not been defined.
1338 // TODO: remove this if
1339 if (Parent.MemberCache != null) {
1340 MemberInfo conflict_symbol = Parent.MemberCache.FindMemberWithSameName (Basename, false, TypeBuilder);
1341 if (conflict_symbol == null) {
1342 if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0))
1343 Report.Warning (109, Location, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
1345 if ((ModFlags & Modifiers.NEW) == 0) {
1346 Report.SymbolRelatedToPreviousError (conflict_symbol);
1347 Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError ());
1353 DefineContainerMembers (constants);
1354 DefineContainerMembers (fields);
1356 if ((Kind == Kind.Class) && !(this is ClassPart) && !(this is StaticClass)){
1357 if ((instance_constructors == null) &&
1358 !(this is StaticClass)) {
1359 if (default_constructor == null)
1360 DefineDefaultConstructor (false);
1363 if (initialized_static_fields != null &&
1364 default_static_constructor == null)
1365 DefineDefaultConstructor (true);
1368 if (Kind == Kind.Struct){
1370 // Structs can not have initialized instance
1373 if (initialized_static_fields != null &&
1374 default_static_constructor == null)
1375 DefineDefaultConstructor (true);
1377 if (initialized_fields != null)
1378 ReportStructInitializedInstanceError ();
1381 Pending = GetPendingImplementations ();
1383 if (parts != null) {
1384 foreach (ClassPart part in parts) {
1385 if (!part.DefineMembers (this))
1391 // Constructors are not in the defined_names array
1393 DefineContainerMembers (instance_constructors);
1395 if (default_static_constructor != null)
1396 default_static_constructor.Define ();
1398 DefineContainerMembers (properties);
1399 DefineContainerMembers (events);
1400 DefineContainerMembers (indexers);
1401 DefineContainerMembers (methods);
1402 DefineContainerMembers (operators);
1403 DefineContainerMembers (enums);
1404 DefineContainerMembers (delegates);
1407 if (!(this is ClassPart))
1408 member_cache = new MemberCache (this);
1411 if (parts != null) {
1412 foreach (ClassPart part in parts)
1413 part.member_cache = member_cache;
1416 if (iterators != null) {
1417 foreach (Iterator iterator in iterators) {
1418 if (iterator.DefineType () == null)
1422 foreach (Iterator iterator in iterators) {
1423 if (!iterator.DefineMembers (this))
1431 void ReportStructInitializedInstanceError ()
1433 string n = TypeBuilder.FullName;
1435 foreach (Field f in initialized_fields){
1438 "`" + n + "." + f.Name + "': can not have " +
1439 "instance field initializers in structs");
1443 protected virtual void DefineContainerMembers (MemberCoreArrayList mcal)
1446 mcal.DefineContainerMembers ();
1449 public override bool Define ()
1451 if (parts != null) {
1452 foreach (ClassPart part in parts) {
1453 if (!part.Define ())
1461 public MemberInfo FindMemberWithSameName (string name, bool ignore_methods)
1463 return ParentCache.FindMemberWithSameName (name, ignore_methods, null);
1467 /// This function is based by a delegate to the FindMembers routine
1469 static bool AlwaysAccept (MemberInfo m, object filterCriteria)
1475 /// This filter is used by FindMembers, and we just keep
1476 /// a global for the filter to `AlwaysAccept'
1478 static MemberFilter accepting_filter;
1481 static TypeContainer ()
1483 accepting_filter = new MemberFilter (AlwaysAccept);
1486 public MethodInfo[] GetMethods ()
1488 ArrayList members = new ArrayList ();
1490 DefineMembers (null);
1492 if (methods != null) {
1493 int len = methods.Count;
1494 for (int i = 0; i < len; i++) {
1495 Method m = (Method) methods [i];
1497 members.Add (m.MethodBuilder);
1501 if (operators != null) {
1502 int len = operators.Count;
1503 for (int i = 0; i < len; i++) {
1504 Operator o = (Operator) operators [i];
1506 members.Add (o.OperatorMethodBuilder);
1510 if (properties != null) {
1511 int len = properties.Count;
1512 for (int i = 0; i < len; i++) {
1513 Property p = (Property) properties [i];
1515 if (p.GetBuilder != null)
1516 members.Add (p.GetBuilder);
1517 if (p.SetBuilder != null)
1518 members.Add (p.SetBuilder);
1522 if (indexers != null) {
1523 int len = indexers.Count;
1524 for (int i = 0; i < len; i++) {
1525 Indexer ix = (Indexer) indexers [i];
1527 if (ix.GetBuilder != null)
1528 members.Add (ix.GetBuilder);
1529 if (ix.SetBuilder != null)
1530 members.Add (ix.SetBuilder);
1534 if (events != null) {
1535 int len = events.Count;
1536 for (int i = 0; i < len; i++) {
1537 Event e = (Event) events [i];
1539 if (e.AddBuilder != null)
1540 members.Add (e.AddBuilder);
1541 if (e.RemoveBuilder != null)
1542 members.Add (e.RemoveBuilder);
1546 MethodInfo[] retMethods = new MethodInfo [members.Count];
1547 members.CopyTo (retMethods, 0);
1551 // Indicated whether container has StructLayout attribute set Explicit
1552 public virtual bool HasExplicitLayout {
1559 /// This method returns the members of this type just like Type.FindMembers would
1560 /// Only, we need to use this for types which are _being_ defined because MS'
1561 /// implementation can't take care of that.
1564 // FIXME: return an empty static array instead of null, that cleans up
1565 // some code and is consistent with some coding conventions I just found
1569 // Notice that in various cases we check if our field is non-null,
1570 // something that would normally mean that there was a bug elsewhere.
1572 // The problem happens while we are defining p-invoke methods, as those
1573 // will trigger a FindMembers, but this happens before things are defined
1575 // Since the whole process is a no-op, it is fine to check for null here.
1577 public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
1578 MemberFilter filter, object criteria)
1580 ArrayList members = null;
1583 if ((bf & BindingFlags.Public) != 0)
1584 modflags |= Modifiers.PUBLIC | Modifiers.PROTECTED |
1586 if ((bf & BindingFlags.NonPublic) != 0)
1587 modflags |= Modifiers.PRIVATE;
1589 int static_mask = 0, static_flags = 0;
1590 switch (bf & (BindingFlags.Static | BindingFlags.Instance)) {
1591 case BindingFlags.Static:
1592 static_mask = static_flags = Modifiers.STATIC;
1595 case BindingFlags.Instance:
1596 static_mask = Modifiers.STATIC;
1601 static_mask = static_flags = 0;
1605 Timer.StartTimer (TimerType.TcFindMembers);
1608 filter = accepting_filter;
1610 if ((mt & MemberTypes.Field) != 0) {
1611 if (fields != null) {
1612 int len = fields.Count;
1613 for (int i = 0; i < len; i++) {
1614 Field f = (Field) fields [i];
1616 if ((f.ModFlags & modflags) == 0)
1618 if ((f.ModFlags & static_mask) != static_flags)
1621 FieldBuilder fb = f.FieldBuilder;
1622 if (fb != null && filter (fb, criteria) == true) {
1623 if (members == null)
1624 members = new ArrayList ();
1631 if (constants != null) {
1632 int len = constants.Count;
1633 for (int i = 0; i < len; i++) {
1634 Const con = (Const) constants [i];
1636 if ((con.ModFlags & modflags) == 0)
1638 if ((con.ModFlags & static_mask) != static_flags)
1641 FieldBuilder fb = con.FieldBuilder;
1642 if (fb != null && filter (fb, criteria) == true) {
1643 if (members == null)
1644 members = new ArrayList ();
1652 if ((mt & MemberTypes.Method) != 0) {
1653 if (methods != null) {
1654 int len = methods.Count;
1655 for (int i = 0; i < len; i++) {
1656 Method m = (Method) methods [i];
1658 if ((m.ModFlags & modflags) == 0)
1660 if ((m.ModFlags & static_mask) != static_flags)
1663 MethodBuilder mb = m.MethodBuilder;
1665 if (mb != null && filter (mb, criteria) == true) {
1666 if (members == null)
1667 members = new ArrayList ();
1674 if (operators != null) {
1675 int len = operators.Count;
1676 for (int i = 0; i < len; i++) {
1677 Operator o = (Operator) operators [i];
1679 if ((o.ModFlags & modflags) == 0)
1681 if ((o.ModFlags & static_mask) != static_flags)
1684 MethodBuilder ob = o.OperatorMethodBuilder;
1685 if (ob != null && filter (ob, criteria) == true) {
1686 if (members == null)
1687 members = new ArrayList ();
1694 if (properties != null) {
1695 int len = properties.Count;
1696 for (int i = 0; i < len; i++) {
1697 Property p = (Property) properties [i];
1699 if ((p.ModFlags & modflags) == 0)
1701 if ((p.ModFlags & static_mask) != static_flags)
1707 if (b != null && filter (b, criteria) == true) {
1708 if (members == null)
1709 members = new ArrayList ();
1715 if (b != null && filter (b, criteria) == true) {
1716 if (members == null)
1717 members = new ArrayList ();
1724 if (indexers != null) {
1725 int len = indexers.Count;
1726 for (int i = 0; i < len; i++) {
1727 Indexer ix = (Indexer) indexers [i];
1729 if ((ix.ModFlags & modflags) == 0)
1731 if ((ix.ModFlags & static_mask) != static_flags)
1737 if (b != null && filter (b, criteria) == true) {
1738 if (members == null)
1739 members = new ArrayList ();
1745 if (b != null && filter (b, criteria) == true) {
1746 if (members == null)
1747 members = new ArrayList ();
1755 if ((mt & MemberTypes.Event) != 0) {
1756 if (events != null) {
1757 int len = events.Count;
1758 for (int i = 0; i < len; i++) {
1759 Event e = (Event) events [i];
1761 if ((e.ModFlags & modflags) == 0)
1763 if ((e.ModFlags & static_mask) != static_flags)
1766 MemberInfo eb = e.EventBuilder;
1767 if (eb != null && filter (eb, criteria) == true) {
1768 if (members == null)
1769 members = new ArrayList ();
1771 members.Add (e.EventBuilder);
1777 if ((mt & MemberTypes.Property) != 0){
1778 if (properties != null) {
1779 int len = properties.Count;
1780 for (int i = 0; i < len; i++) {
1781 Property p = (Property) properties [i];
1783 if ((p.ModFlags & modflags) == 0)
1785 if ((p.ModFlags & static_mask) != static_flags)
1788 MemberInfo pb = p.PropertyBuilder;
1789 if (pb != null && filter (pb, criteria) == true) {
1790 if (members == null)
1791 members = new ArrayList ();
1793 members.Add (p.PropertyBuilder);
1798 if (indexers != null) {
1799 int len = indexers.Count;
1800 for (int i = 0; i < len; i++) {
1801 Indexer ix = (Indexer) indexers [i];
1803 if ((ix.ModFlags & modflags) == 0)
1805 if ((ix.ModFlags & static_mask) != static_flags)
1808 MemberInfo ib = ix.PropertyBuilder;
1809 if (ib != null && filter (ib, criteria) == true) {
1810 if (members == null)
1811 members = new ArrayList ();
1813 members.Add (ix.PropertyBuilder);
1819 if ((mt & MemberTypes.NestedType) != 0) {
1820 if (types != null) {
1821 int len = types.Count;
1822 for (int i = 0; i < len; i++) {
1823 TypeContainer t = (TypeContainer) types [i];
1825 if ((t.ModFlags & modflags) == 0)
1828 TypeBuilder tb = t.TypeBuilder;
1829 if (tb != null && (filter (tb, criteria) == true)) {
1830 if (members == null)
1831 members = new ArrayList ();
1838 if (enums != null) {
1839 int len = enums.Count;
1840 for (int i = 0; i < len; i++) {
1841 Enum en = (Enum) enums [i];
1843 if ((en.ModFlags & modflags) == 0)
1846 TypeBuilder tb = en.TypeBuilder;
1847 if (tb != null && (filter (tb, criteria) == true)) {
1848 if (members == null)
1849 members = new ArrayList ();
1856 if (delegates != null) {
1857 int len = delegates.Count;
1858 for (int i = 0; i < len; i++) {
1859 Delegate d = (Delegate) delegates [i];
1861 if ((d.ModFlags & modflags) == 0)
1864 TypeBuilder tb = d.TypeBuilder;
1865 if (tb != null && (filter (tb, criteria) == true)) {
1866 if (members == null)
1867 members = new ArrayList ();
1874 if (interfaces != null) {
1875 int len = interfaces.Count;
1876 for (int i = 0; i < len; i++) {
1877 TypeContainer iface = (TypeContainer) interfaces [i];
1879 if ((iface.ModFlags & modflags) == 0)
1882 TypeBuilder tb = iface.TypeBuilder;
1883 if (tb != null && (filter (tb, criteria) == true)) {
1884 if (members == null)
1885 members = new ArrayList ();
1893 if ((mt & MemberTypes.Constructor) != 0){
1894 if (((bf & BindingFlags.Instance) != 0) && (instance_constructors != null)){
1895 int len = instance_constructors.Count;
1896 for (int i = 0; i < len; i++) {
1897 Constructor c = (Constructor) instance_constructors [i];
1899 ConstructorBuilder cb = c.ConstructorBuilder;
1900 if (cb != null && filter (cb, criteria) == true) {
1901 if (members == null)
1902 members = new ArrayList ();
1909 if (((bf & BindingFlags.Static) != 0) && (default_static_constructor != null)){
1910 ConstructorBuilder cb =
1911 default_static_constructor.ConstructorBuilder;
1913 if (cb != null && filter (cb, criteria) == true) {
1914 if (members == null)
1915 members = new ArrayList ();
1923 // Lookup members in parent if requested.
1925 if ((bf & BindingFlags.DeclaredOnly) == 0) {
1926 if (TypeBuilder.BaseType != null) {
1927 MemberList list = FindMembers (TypeBuilder.BaseType, mt, bf, filter, criteria);
1928 if (list.Count > 0) {
1929 if (members == null)
1930 members = new ArrayList ();
1932 members.AddRange (list);
1935 if (ifaces != null) {
1936 foreach (Type base_type in ifaces) {
1937 MemberList list = TypeContainer.FindMembers (base_type, mt, bf, filter, criteria);
1939 if (list.Count > 0) {
1940 if (members == null)
1941 members = new ArrayList ();
1942 members.AddRange (list);
1948 Timer.StopTimer (TimerType.TcFindMembers);
1950 if (members == null)
1951 return MemberList.Empty;
1953 return new MemberList (members);
1956 public override MemberCache MemberCache {
1958 return member_cache;
1962 public static MemberList FindMembers (Type t, MemberTypes mt, BindingFlags bf,
1963 MemberFilter filter, object criteria)
1965 DeclSpace ds = TypeManager.LookupDeclSpace (t);
1968 return ds.FindMembers (mt, bf, filter, criteria);
1970 return new MemberList (t.FindMembers (mt, bf, filter, criteria));
1975 // FindMethods will look for methods not only in the type `t', but in
1976 // any interfaces implemented by the type.
1978 public static MethodInfo [] FindMethods (Type t, BindingFlags bf,
1979 MemberFilter filter, object criteria)
1985 /// Emits the values for the constants
1987 public void EmitConstants ()
1989 if (constants != null)
1990 foreach (Const con in constants)
1995 protected virtual void VerifyMembers (EmitContext ec)
1998 // Check for internal or private fields that were never assigned
2000 if (RootContext.WarningLevel >= 3) {
2001 if (fields != null){
2002 foreach (Field f in fields) {
2003 if ((f.ModFlags & Modifiers.Accessibility) != Modifiers.PRIVATE)
2006 if ((f.status & Field.Status.USED) == 0){
2007 Report.Warning (169, f.Location, "The private field '{0}' is never used", f.GetSignatureForError ());
2012 // Only report 649 on level 4
2014 if (RootContext.WarningLevel < 4)
2017 if ((f.status & Field.Status.ASSIGNED) != 0)
2020 Report.Warning (649, f.Location, "Field '{0}' is never assigned to, and will always have its default value '{1}'", f.GetSignatureForError (), "");
2027 /// Emits the code, this step is performed after all
2028 /// the types, enumerations, constructors
2030 public void EmitType ()
2032 if (OptAttributes != null)
2033 OptAttributes.Emit (ec, this);
2037 if (instance_constructors != null) {
2038 if (TypeBuilder.IsSubclassOf (TypeManager.attribute_type) && RootContext.VerifyClsCompliance && IsClsCompliaceRequired (this)) {
2039 bool has_compliant_args = false;
2041 foreach (Constructor c in instance_constructors) {
2044 if (has_compliant_args)
2047 has_compliant_args = c.HasCompliantArgs;
2049 if (!has_compliant_args)
2050 Report.Error (3015, Location, "'{0}' has no accessible constructors which use only CLS-compliant types", GetSignatureForError ());
2052 foreach (Constructor c in instance_constructors)
2059 if (default_static_constructor != null)
2060 default_static_constructor.Emit ();
2062 if (methods != null)
2063 foreach (Method m in methods)
2066 if (operators != null)
2067 foreach (Operator o in operators)
2070 if (properties != null)
2071 foreach (Property p in properties)
2074 if (indexers != null){
2079 foreach (Field f in fields)
2082 if (events != null){
2083 foreach (Event e in Events)
2087 if (delegates != null) {
2088 foreach (Delegate d in Delegates) {
2093 if (enums != null) {
2094 foreach (Enum e in enums) {
2099 if (parts != null) {
2100 foreach (ClassPart part in parts)
2104 if ((Pending != null) && !(this is ClassPart))
2105 if (Pending.VerifyPendingMethods ())
2110 if (iterators != null)
2111 foreach (Iterator iterator in iterators)
2112 iterator.EmitType ();
2114 // if (types != null)
2115 // foreach (TypeContainer tc in types)
2119 public override void CloseType ()
2121 if ((caching_flags & Flags.CloseTypeCreated) != 0)
2125 caching_flags |= Flags.CloseTypeCreated;
2126 TypeBuilder.CreateType ();
2127 } catch (TypeLoadException){
2129 // This is fine, the code still created the type
2131 // Report.Warning (-20, "Exception while creating class: " + TypeBuilder.Name);
2132 // Console.WriteLine (e.Message);
2134 Console.WriteLine ("In type: " + Name);
2139 foreach (Enum en in Enums)
2143 foreach (TypeContainer tc in Types)
2144 if (tc.Kind == Kind.Struct)
2147 foreach (TypeContainer tc in Types)
2148 if (tc.Kind != Kind.Struct)
2152 if (Delegates != null)
2153 foreach (Delegate d in Delegates)
2156 if (Iterators != null)
2157 foreach (Iterator i in Iterators)
2165 initialized_fields = null;
2166 initialized_static_fields = null;
2175 default_constructor = null;
2176 default_static_constructor = null;
2178 OptAttributes = null;
2180 parent_cache = null;
2181 member_cache = null;
2184 // TODO: make it obsolete and use GetSignatureForError
2185 public string MakeName (string n)
2187 return "`" + Name + "." + n + "'";
2191 // Performs the validation on a Method's modifiers (properties have
2192 // the same properties).
2194 public bool MethodModifiersValid (int flags, string n, Location loc)
2196 const int vao = (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE);
2197 const int va = (Modifiers.VIRTUAL | Modifiers.ABSTRACT);
2198 const int nv = (Modifiers.NEW | Modifiers.VIRTUAL);
2202 // At most one of static, virtual or override
2204 if ((flags & Modifiers.STATIC) != 0){
2205 if ((flags & vao) != 0){
2207 112, loc, "static method " + MakeName (n) + "can not be marked " +
2208 "as virtual, abstract or override");
2213 if (Kind == Kind.Struct){
2214 if ((flags & va) != 0){
2215 Modifiers.Error_InvalidModifier (loc, "virtual or abstract");
2220 if ((flags & Modifiers.OVERRIDE) != 0 && (flags & nv) != 0){
2222 113, loc, MakeName (n) +
2223 " marked as override cannot be marked as new or virtual");
2228 // If the declaration includes the abstract modifier, then the
2229 // declaration does not include static, virtual or extern
2231 if ((flags & Modifiers.ABSTRACT) != 0){
2232 if ((flags & Modifiers.EXTERN) != 0){
2234 180, loc, MakeName (n) + " can not be both abstract and extern");
2238 if ((flags & Modifiers.VIRTUAL) != 0){
2240 503, loc, MakeName (n) + " can not be both abstract and virtual");
2244 if ((ModFlags & Modifiers.ABSTRACT) == 0){
2246 513, loc, MakeName (n) +
2247 " is abstract but its container class is not");
2253 if ((flags & Modifiers.PRIVATE) != 0){
2254 if ((flags & vao) != 0){
2256 621, loc, MakeName (n) +
2257 " virtual or abstract members can not be private");
2262 if ((flags & Modifiers.SEALED) != 0){
2263 if ((flags & Modifiers.OVERRIDE) == 0){
2265 238, loc, MakeName (n) +
2266 " cannot be sealed because it is not an override");
2274 public bool UserDefinedStaticConstructor {
2276 return default_static_constructor != null;
2280 public Constructor DefaultStaticConstructor {
2281 get { return default_static_constructor; }
2284 protected override bool VerifyClsCompliance (DeclSpace ds)
2286 if (!base.VerifyClsCompliance (ds))
2291 Type base_type = TypeBuilder.BaseType;
2292 if (base_type != null && !AttributeTester.IsClsCompliant (base_type)) {
2293 Report.Error (3009, Location, "'{0}': base type '{1}' is not CLS-compliant", GetSignatureForError (), TypeManager.CSharpName (base_type));
2300 /// Checks whether container name is CLS Compliant
2302 void VerifyClsName ()
2304 Hashtable parent_members = parent_cache == null ?
2306 parent_cache.GetPublicMembers ();
2307 Hashtable this_members = new Hashtable ();
2309 foreach (DictionaryEntry entry in defined_names) {
2310 MemberCore mc = (MemberCore)entry.Value;
2311 if (!mc.IsClsCompliaceRequired (this))
2314 string name = (string)entry.Key;
2315 string basename = name.Substring (name.LastIndexOf ('.') + 1);
2317 string lcase = basename.ToLower (System.Globalization.CultureInfo.InvariantCulture);
2318 object found = parent_members [lcase];
2319 if (found == null) {
2320 found = this_members [lcase];
2321 if (found == null) {
2322 this_members.Add (lcase, mc);
2327 if ((mc.ModFlags & Modifiers.OVERRIDE) != 0)
2330 if (found is MemberInfo) {
2331 if (basename == ((MemberInfo)found).Name)
2333 Report.SymbolRelatedToPreviousError ((MemberInfo)found);
2335 Report.SymbolRelatedToPreviousError ((MemberCore) found);
2337 Report.Error (3005, mc.Location, "Identifier '{0}' differing only in case is not CLS-compliant", mc.GetSignatureForError ());
2343 /// Performs checks for an explicit interface implementation. First it
2344 /// checks whether the `interface_type' is a base inteface implementation.
2345 /// Then it checks whether `name' exists in the interface type.
2347 public virtual bool VerifyImplements (Type interface_type, string full,
2348 string name, Location loc)
2352 if (ifaces != null){
2353 foreach (Type t in ifaces){
2354 if (t == interface_type){
2362 Report.Error (540, loc, "`{0}': containing class does not implement interface `{1}'",
2363 full, interface_type.FullName);
2370 protected override void VerifyObsoleteAttribute()
2372 CheckUsageOfObsoleteAttribute (ptype);
2377 foreach (Type iface in ifaces) {
2378 CheckUsageOfObsoleteAttribute (iface);
2387 string IMemberContainer.Name {
2393 Type IMemberContainer.Type {
2399 MemberCache IMemberContainer.MemberCache {
2401 return member_cache;
2405 bool IMemberContainer.IsInterface {
2407 return Kind == Kind.Interface;
2411 MemberList IMemberContainer.GetMembers (MemberTypes mt, BindingFlags bf)
2413 return FindMembers (mt, bf | BindingFlags.DeclaredOnly, null, null);
2417 // Generates xml doc comments (if any), and if required,
2418 // handle warning report.
2420 internal override void GenerateDocComment (DeclSpace ds)
2422 DocUtil.GenerateTypeDocComment (this, ds);
2425 public override string DocCommentHeader {
2426 get { return "T:"; }
2429 public virtual MemberCache ParentCache {
2431 return parent_cache;
2436 public class PartialContainer : TypeContainer {
2438 public readonly Namespace Namespace;
2439 public readonly int OriginalModFlags;
2440 public readonly int AllowedModifiers;
2441 public readonly TypeAttributes DefaultTypeAttributes;
2443 static PartialContainer Create (NamespaceEntry ns, TypeContainer parent,
2444 MemberName member_name, int mod_flags, Kind kind,
2447 PartialContainer pc;
2448 string full_name = member_name.GetName (true);
2449 DeclSpace ds = (DeclSpace) RootContext.Tree.Decls [full_name];
2451 pc = ds as PartialContainer;
2455 260, ds.Location, "Missing partial modifier " +
2456 "on declaration of type `{0}'; another " +
2457 "partial implementation of this type exists",
2458 member_name.GetPartialName());
2460 Report.LocationOfPreviousError (loc);
2464 if (pc.Kind != kind) {
2466 261, loc, "Partial declarations of `{0}' " +
2467 "must be all classes, all structs or " +
2468 "all interfaces", member_name.GetPartialName ());
2472 if (pc.OriginalModFlags != mod_flags) {
2474 262, loc, "Partial declarations of `{0}' " +
2475 "have conflicting accessibility modifiers",
2476 member_name.GetPartialName ());
2483 pc = new PartialContainer (ns, parent, member_name, mod_flags, kind, loc);
2484 RootContext.Tree.RecordDecl (full_name, pc);
2485 parent.AddType (pc);
2490 public static ClassPart CreatePart (NamespaceEntry ns, TypeContainer parent,
2491 MemberName name, int mod, Attributes attrs,
2492 Kind kind, Location loc)
2494 PartialContainer pc = Create (ns, parent, name, mod, kind, loc);
2496 // An error occured; create a dummy container, but don't
2498 pc = new PartialContainer (ns, parent, name, mod, kind, loc);
2501 ClassPart part = new ClassPart (ns, pc, mod, attrs, kind, loc);
2506 protected PartialContainer (NamespaceEntry ns, TypeContainer parent,
2507 MemberName name, int mod, Kind kind, Location l)
2508 : base (ns, parent, name, null, kind, l)
2510 this.Namespace = ns.NS;
2514 AllowedModifiers = Class.AllowedModifiers;
2515 DefaultTypeAttributes = Class.DefaultTypeAttributes;
2519 AllowedModifiers = Struct.AllowedModifiers;
2520 DefaultTypeAttributes = Struct.DefaultTypeAttributes;
2523 case Kind.Interface:
2524 AllowedModifiers = Interface.AllowedModifiers;
2525 DefaultTypeAttributes = Interface.DefaultTypeAttributes;
2529 throw new InvalidOperationException ();
2533 if (parent.Parent == null)
2534 accmods = Modifiers.INTERNAL;
2536 accmods = Modifiers.PRIVATE;
2538 this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
2539 this.OriginalModFlags = mod;
2542 public override void Register ()
2544 if (Kind == Kind.Interface)
2545 Parent.AddInterface (this);
2546 else if (Kind == Kind.Class || Kind == Kind.Struct)
2547 Parent.AddClassOrStruct (this);
2549 throw new InvalidOperationException ();
2552 public override PendingImplementation GetPendingImplementations ()
2554 return PendingImplementation.GetPendingImplementations (this);
2557 public ClassPart AddPart (NamespaceEntry ns, int mod, Attributes attrs,
2560 ClassPart part = new ClassPart (ns, this, mod, attrs, Kind, l);
2565 public override TypeAttributes TypeAttr {
2567 return base.TypeAttr | DefaultTypeAttributes;
2572 public class ClassPart : TypeContainer, IMemberContainer {
2573 public readonly PartialContainer PartialContainer;
2574 public readonly bool IsPartial;
2576 public ClassPart (NamespaceEntry ns, PartialContainer parent,
2577 int mod, Attributes attrs, Kind kind, Location l)
2578 : base (ns, parent.Parent, parent.MemberName, attrs, kind, l)
2580 this.PartialContainer = parent;
2581 this.IsPartial = true;
2584 if (parent.Parent == null)
2585 accmods = Modifiers.INTERNAL;
2587 accmods = Modifiers.PRIVATE;
2589 this.ModFlags = Modifiers.Check (
2590 parent.AllowedModifiers, mod, accmods, l);
2593 public override void Register ()
2597 public override PendingImplementation GetPendingImplementations ()
2599 return PartialContainer.Pending;
2602 public override bool VerifyImplements (Type interface_type, string full,
2603 string name, Location loc)
2605 return PartialContainer.VerifyImplements (
2606 interface_type, full, name, loc);
2609 public override MemberCache ParentCache {
2611 return PartialContainer.ParentCache;
2616 public abstract class ClassOrStruct : TypeContainer {
2617 bool hasExplicitLayout = false;
2618 ListDictionary declarative_security;
2620 public ClassOrStruct (NamespaceEntry ns, TypeContainer parent,
2621 MemberName name, Attributes attrs, Kind kind,
2623 : base (ns, parent, name, attrs, kind, l)
2627 public override PendingImplementation GetPendingImplementations ()
2629 return PendingImplementation.GetPendingImplementations (this);
2632 public override bool HasExplicitLayout {
2634 return hasExplicitLayout;
2638 protected override void VerifyMembers (EmitContext ec)
2640 base.VerifyMembers (ec);
2642 if ((events != null) && (RootContext.WarningLevel >= 3)) {
2643 foreach (Event e in events){
2645 Report.Warning (67, e.Location, "The event '{0}' is never used", e.GetSignatureForError ());
2650 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
2652 if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
2653 if (declarative_security == null)
2654 declarative_security = new ListDictionary ();
2656 a.ExtractSecurityPermissionSet (declarative_security);
2660 if (a.Type == TypeManager.struct_layout_attribute_type
2661 && (LayoutKind) a.GetPositionalValue (0) == LayoutKind.Explicit)
2662 hasExplicitLayout = true;
2664 base.ApplyAttributeBuilder (a, cb);
2667 public override void Emit()
2671 if (declarative_security != null) {
2672 foreach (DictionaryEntry de in declarative_security) {
2673 TypeBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
2678 public override void Register ()
2680 Parent.AddClassOrStruct (this);
2685 /// Class handles static classes declaration
2687 public sealed class StaticClass: Class {
2688 public StaticClass (NamespaceEntry ns, TypeContainer parent, MemberName name, int mod,
2689 Attributes attrs, Location l)
2690 : base (ns, parent, name, mod & ~Modifiers.STATIC, attrs, l)
2692 if (RootContext.Version == LanguageVersion.ISO_1) {
2693 Report.FeatureIsNotStandardized (l, "static classes");
2694 Environment.Exit (1);
2698 protected override void DefineContainerMembers (MemberCoreArrayList list)
2703 foreach (MemberCore m in list) {
2704 if (m is Operator) {
2705 Report.Error (715, m.Location, "'{0}': static classes cannot contain user-defined operators", m.GetSignatureForError (this));
2709 if ((m.ModFlags & Modifiers.STATIC) != 0)
2712 if (m is Constructor) {
2713 Report.Error (710, m.Location, "'{0}': Static classes cannot have instance constructors", GetSignatureForError ());
2717 if (m is Destructor) {
2718 Report.Error (711, m.Location, "'{0}': Static class cannot contain destructor", GetSignatureForError ());
2722 Report.Error (708, m.Location, "'{0}': cannot declare instance members in a static class", m.GetSignatureForError (this));
2725 base.DefineContainerMembers (list);
2728 public override TypeBuilder DefineType()
2730 TypeBuilder tb = base.DefineType ();
2734 if (ptype != TypeManager.object_type) {
2735 Report.Error (713, Location, "Static class '{0}' cannot derive from type '{1}'. Static classes must derive from object", GetSignatureForError (), TypeManager.CSharpName (ptype));
2739 if (ifaces != null) {
2740 foreach (Type t in ifaces)
2741 Report.SymbolRelatedToPreviousError (t);
2742 Report.Error (714, Location, "'{0}': static classes cannot implement interfaces", GetSignatureForError ());
2747 public override TypeAttributes TypeAttr {
2749 return base.TypeAttr | TypeAttributes.Abstract | TypeAttributes.Sealed;
2754 public class Class : ClassOrStruct {
2756 // Modifiers allowed in a class declaration
2758 public const int AllowedModifiers =
2761 Modifiers.PROTECTED |
2762 Modifiers.INTERNAL |
2764 Modifiers.ABSTRACT |
2768 // Information in the case we are an attribute type
2769 AttributeUsageAttribute attribute_usage;
2771 public Class (NamespaceEntry ns, TypeContainer parent, MemberName name, int mod,
2772 Attributes attrs, Location l)
2773 : base (ns, parent, name, attrs, Kind.Class, l)
2777 if (parent.Parent == null)
2778 accmods = Modifiers.INTERNAL;
2780 accmods = Modifiers.PRIVATE;
2782 this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
2783 if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.SEALED)) == (Modifiers.ABSTRACT | Modifiers.SEALED)) {
2784 Report.Error (502, Location, "'{0}' cannot be both abstract and sealed", GetSignatureForError ());
2787 attribute_usage = new AttributeUsageAttribute (AttributeTargets.All);
2790 public override AttributeTargets AttributeTargets {
2792 return AttributeTargets.Class;
2796 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
2798 if (a.UsageAttribute != null) {
2799 if (ptype != TypeManager.attribute_type && !ptype.IsSubclassOf (TypeManager.attribute_type) &&
2800 TypeBuilder.FullName != "System.Attribute") {
2801 Report.Error (641, a.Location, "Attribute '{0}' is only valid on classes derived from System.Attribute", a.Name);
2803 attribute_usage = a.UsageAttribute;
2806 base.ApplyAttributeBuilder (a, cb);
2809 public AttributeUsageAttribute AttributeUsage {
2811 return attribute_usage;
2815 public const TypeAttributes DefaultTypeAttributes =
2816 TypeAttributes.AutoLayout | TypeAttributes.Class;
2819 // FIXME: How do we deal with the user specifying a different
2822 public override TypeAttributes TypeAttr {
2824 return base.TypeAttr | DefaultTypeAttributes;
2829 public class Struct : ClassOrStruct {
2831 // Modifiers allowed in a struct declaration
2833 public const int AllowedModifiers =
2836 Modifiers.PROTECTED |
2837 Modifiers.INTERNAL |
2841 public Struct (NamespaceEntry ns, TypeContainer parent, MemberName name,
2842 int mod, Attributes attrs, Location l)
2843 : base (ns, parent, name, attrs, Kind.Struct, l)
2847 if (parent.Parent == null)
2848 accmods = Modifiers.INTERNAL;
2850 accmods = Modifiers.PRIVATE;
2852 this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
2854 this.ModFlags |= Modifiers.SEALED;
2857 public override AttributeTargets AttributeTargets {
2859 return AttributeTargets.Struct;
2863 public const TypeAttributes DefaultTypeAttributes =
2864 TypeAttributes.SequentialLayout |
2865 TypeAttributes.Sealed |
2866 TypeAttributes.BeforeFieldInit;
2869 // FIXME: Allow the user to specify a different set of attributes
2870 // in some cases (Sealed for example is mandatory for a class,
2871 // but what SequentialLayout can be changed
2873 public override TypeAttributes TypeAttr {
2875 return base.TypeAttr | DefaultTypeAttributes;
2883 public class Interface : TypeContainer, IMemberContainer {
2885 /// Modifiers allowed in a class declaration
2887 public const int AllowedModifiers =
2890 Modifiers.PROTECTED |
2891 Modifiers.INTERNAL |
2895 public Interface (NamespaceEntry ns, TypeContainer parent, MemberName name, int mod,
2896 Attributes attrs, Location l)
2897 : base (ns, parent, name, attrs, Kind.Interface, l)
2901 if (parent.Parent == null)
2902 accmods = Modifiers.INTERNAL;
2904 accmods = Modifiers.PRIVATE;
2906 this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
2909 public override void Register ()
2911 Parent.AddInterface (this);
2914 public override PendingImplementation GetPendingImplementations ()
2919 public override AttributeTargets AttributeTargets {
2921 return AttributeTargets.Interface;
2925 public const TypeAttributes DefaultTypeAttributes =
2926 TypeAttributes.AutoLayout |
2927 TypeAttributes.Abstract |
2928 TypeAttributes.Interface;
2930 public override TypeAttributes TypeAttr {
2932 return base.TypeAttr | DefaultTypeAttributes;
2937 public abstract class MethodCore : MemberBase {
2938 public readonly Parameters Parameters;
2939 protected ToplevelBlock block;
2942 // Parameters, cached for semantic analysis.
2944 protected InternalParameters parameter_info;
2945 protected Type [] parameter_types;
2947 // Whether this is an operator method.
2948 public bool IsOperator;
2951 // The method we're overriding if this is an override method.
2953 protected MethodInfo parent_method = null;
2955 static string[] attribute_targets = new string [] { "method", "return" };
2957 public MethodCore (TypeContainer parent, Expression type, int mod,
2958 int allowed_mod, bool is_interface, MemberName name,
2959 Attributes attrs, Parameters parameters, Location loc)
2960 : base (parent, type, mod, allowed_mod, Modifiers.PRIVATE, name,
2963 Parameters = parameters;
2964 IsInterface = is_interface;
2968 // Returns the System.Type array for the parameters of this method
2970 public Type [] ParameterTypes {
2972 return parameter_types;
2976 public InternalParameters ParameterInfo
2979 return parameter_info;
2983 public ToplevelBlock Block {
2993 protected override bool CheckBase ()
2995 if (!base.CheckBase ())
2998 // Check whether arguments were correct.
2999 if (!DoDefineParameters ())
3002 if ((caching_flags & Flags.TestMethodDuplication) != 0 && !CheckForDuplications ())
3008 // Is null for System.Object while compiling corlib and base interfaces
3009 if (Parent.ParentCache == null) {
3010 if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) {
3011 Report.Warning (109, Location, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError (Parent));
3016 Type parent_ret_type = null;
3017 parent_method = FindOutParentMethod (Parent, ref parent_ret_type);
3019 // method is override
3020 if (parent_method != null) {
3022 if (!CheckMethodAgainstBase ())
3025 if ((ModFlags & Modifiers.NEW) == 0) {
3026 if (MemberType != TypeManager.TypeToCoreType (parent_ret_type)) {
3027 Report.SymbolRelatedToPreviousError (parent_method);
3028 Report.Error (508, Location, GetSignatureForError (Parent) + ": cannot " +
3029 "change return type when overriding inherited member");
3033 if (parent_method.IsAbstract && !IsInterface) {
3034 Report.SymbolRelatedToPreviousError (parent_method);
3035 Report.Error (533, Location, "'{0}' hides inherited abstract member", GetSignatureForError (Parent));
3040 if (parent_method.IsSpecialName && !(this is PropertyBase)) {
3041 Report.Error (561, Location, "'{0}': cannot override '{1}' because it is a special compiler-generated method", GetSignatureForError (Parent), TypeManager.GetFullNameSignature (parent_method));
3045 if (RootContext.WarningLevel > 2) {
3046 if (Name == "Equals" && parameter_types.Length == 1 && parameter_types [0] == TypeManager.object_type)
3047 Parent.Methods.HasEquals = true;
3048 else if (Name == "GetHashCode" && parameter_types.Length == 0)
3049 Parent.Methods.HasGetHashCode = true;
3052 ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (parent_method);
3054 EmitContext ec = new EmitContext (this.Parent, this.Parent, Location, null, null, ModFlags, false);
3055 if (OptAttributes == null || !OptAttributes.Contains (TypeManager.obsolete_attribute_type, ec)) {
3056 Report.SymbolRelatedToPreviousError (parent_method);
3057 Report.Warning (672, 1, Location, "Member '{0}' overrides obsolete member. Add the Obsolete attribute to '{0}'", GetSignatureForError (Parent));
3063 MemberInfo conflict_symbol = Parent.FindMemberWithSameName (Name, !(this is Property));
3064 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
3065 if (conflict_symbol != null) {
3066 Report.SymbolRelatedToPreviousError (conflict_symbol);
3067 if (this is PropertyBase)
3068 Report.Error (544, Location, "'{0}': cannot override because '{1}' is not a property", GetSignatureForError (Parent), TypeManager.GetFullNameSignature (conflict_symbol));
3070 Report.Error (505, Location, "'{0}': cannot override because '{1}' is not a method", GetSignatureForError (Parent), TypeManager.GetFullNameSignature (conflict_symbol));
3072 Report.Error (115, Location, "'{0}': no suitable methods found to override", GetSignatureForError (Parent));
3076 if (conflict_symbol == null) {
3077 if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) {
3078 Report.Warning (109, Location, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError (Parent));
3083 if ((ModFlags & Modifiers.NEW) == 0) {
3084 if (this is Method && conflict_symbol is MethodBase)
3087 Report.SymbolRelatedToPreviousError (conflict_symbol);
3088 Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent));
3096 // Performs various checks on the MethodInfo `mb' regarding the modifier flags
3097 // that have been defined.
3099 // `name' is the user visible name for reporting errors (this is used to
3100 // provide the right name regarding method names and properties)
3102 bool CheckMethodAgainstBase ()
3106 // TODO: replace with GetSignatureForError
3107 string name = parent_method.DeclaringType.Name + "." + parent_method.Name;
3109 if ((ModFlags & Modifiers.OVERRIDE) != 0){
3110 if (!(parent_method.IsAbstract || parent_method.IsVirtual)){
3112 506, Location, Parent.MakeName (Name) +
3113 ": cannot override inherited member `" +
3114 name + "' because it is not " +
3115 "virtual, abstract or override");
3119 // Now we check that the overriden method is not final
3121 if (parent_method.IsFinal) {
3122 // This happens when implementing interface methods.
3123 if (parent_method.IsHideBySig && parent_method.IsVirtual) {
3125 506, Location, Parent.MakeName (Name) +
3126 ": cannot override inherited member `" +
3127 name + "' because it is not " +
3128 "virtual, abstract or override");
3130 Report.Error (239, Location, Parent.MakeName (Name) + " : cannot " +
3131 "override inherited member `" + name +
3132 "' because it is sealed.");
3136 // Check that the permissions are not being changed
3138 MethodAttributes thisp = flags & MethodAttributes.MemberAccessMask;
3139 MethodAttributes parentp = parent_method.Attributes & MethodAttributes.MemberAccessMask;
3141 if (!CheckAccessModifiers (thisp, parentp, parent_method)) {
3142 Error_CannotChangeAccessModifiers (Parent, parent_method, name);
3147 if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0 && Name != "Finalize") {
3148 ModFlags |= Modifiers.NEW;
3149 Report.SymbolRelatedToPreviousError (parent_method);
3150 if (!IsInterface && (parent_method.IsVirtual || parent_method.IsAbstract)) {
3151 if (RootContext.WarningLevel >= 2)
3152 Report.Warning (114, Location, "'{0}' hides inherited member '{1}'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword", GetSignatureForError (Parent), TypeManager.CSharpSignature (parent_method));
3154 Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent));
3160 protected bool CheckAccessModifiers (MethodAttributes thisp, MethodAttributes parentp, MethodInfo base_method)
3162 if ((parentp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
3164 // when overriding protected internal, the method can be declared
3165 // protected internal only within the same assembly
3168 if ((thisp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
3169 if (Parent.TypeBuilder.Assembly != base_method.DeclaringType.Assembly){
3171 // assemblies differ - report an error
3175 } else if (thisp != parentp) {
3177 // same assembly, but other attributes differ - report an error
3182 } else if ((thisp & MethodAttributes.Family) != MethodAttributes.Family) {
3184 // if it's not "protected internal", it must be "protected"
3188 } else if (Parent.TypeBuilder.Assembly == base_method.DeclaringType.Assembly) {
3190 // protected within the same assembly - an error
3193 } else if ((thisp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem)) !=
3194 (parentp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem))) {
3196 // protected ok, but other attributes differ - report an error
3202 return (thisp == parentp);
3206 void Error_CannotChangeAccessModifiers (TypeContainer parent, MethodInfo parent_method, string name)
3209 // FIXME: report the old/new permissions?
3212 507, Location, parent.MakeName (Name) +
3213 ": can't change the access modifiers when overriding inherited " +
3214 "member `" + name + "'");
3217 protected static string Error722 {
3219 return "'{0}': static types cannot be used as return types";
3224 /// For custom member duplication search in a container
3226 protected abstract bool CheckForDuplications ();
3229 /// Gets parent method and its return type
3231 protected abstract MethodInfo FindOutParentMethod (TypeContainer container, ref Type parent_ret_type);
3233 protected virtual bool DoDefineParameters ()
3235 EmitContext ec = Parent.EmitContext;
3237 throw new InternalErrorException ("DoDefineParameters invoked too early");
3239 bool old_unsafe = ec.InUnsafe;
3240 ec.InUnsafe = InUnsafe;
3241 // Check if arguments were correct
3242 parameter_types = Parameters.GetParameterInfo (ec);
3243 ec.InUnsafe = old_unsafe;
3245 if ((parameter_types == null) ||
3246 !CheckParameters (Parent, parameter_types))
3249 parameter_info = new InternalParameters (parameter_types, Parameters);
3251 Parameter array_param = Parameters.ArrayParameter;
3252 if ((array_param != null) &&
3253 (!array_param.ParameterType.IsArray ||
3254 (array_param.ParameterType.GetArrayRank () != 1))) {
3255 Report.Error (225, Location, "params parameter has to be a single dimensional array");
3262 public override string[] ValidAttributeTargets {
3264 return attribute_targets;
3268 protected override bool VerifyClsCompliance (DeclSpace ds)
3270 if (!base.VerifyClsCompliance (ds)) {
3271 if ((ModFlags & Modifiers.ABSTRACT) != 0 && IsExposedFromAssembly (ds) && ds.IsClsCompliaceRequired (ds)) {
3272 Report.Error (3011, Location, "'{0}': only CLS-compliant members can be abstract", GetSignatureForError ());
3277 if (Parameters.HasArglist) {
3278 Report.Error (3000, Location, "Methods with variable arguments are not CLS-compliant");
3281 if (!AttributeTester.IsClsCompliant (MemberType)) {
3282 Report.Error (3002, Location, "Return type of '{0}' is not CLS-compliant", GetSignatureForError ());
3285 AttributeTester.AreParametersCompliant (Parameters.FixedParameters, Location);
3290 protected bool IsDuplicateImplementation (MethodCore method)
3292 if ((method == this) || (method.Name != Name))
3295 Type[] param_types = method.ParameterTypes;
3296 if (param_types == null)
3299 if (param_types.Length != ParameterTypes.Length)
3302 for (int i = 0; i < param_types.Length; i++)
3303 if (param_types [i] != ParameterTypes [i])
3306 // TODO: make operator compatible with MethodCore to avoid this
3307 if (this is Operator && method is Operator) {
3308 if (MemberType != method.MemberType)
3313 // Try to report 663: method only differs on out/ref
3315 ParameterData info = ParameterInfo;
3316 ParameterData other_info = method.ParameterInfo;
3317 for (int i = 0; i < info.Count; i++){
3318 if (info.ParameterModifier (i) != other_info.ParameterModifier (i)){
3319 Report.Error (663, Location, "Overload method only differs in parameter modifier");
3324 Report.SymbolRelatedToPreviousError (method);
3325 Report.Error (111, Location, TypeContainer.Error111, Parent.Name, Name);
3330 // Returns a string that represents the signature for this
3331 // member which should be used in XML documentation.
3333 public override string GetDocCommentName (DeclSpace ds)
3335 return DocUtil.GetMethodDocCommentName (this, ds);
3339 // Raised (and passed an XmlElement that contains the comment)
3340 // when GenerateDocComment is writing documentation expectedly.
3342 // FIXME: with a few effort, it could be done with XmlReader,
3343 // that means removal of DOM use.
3345 internal override void OnGenerateDocComment (DeclSpace ds, XmlElement el)
3347 DocUtil.OnMethodGenerateDocComment (this, ds, el);
3351 // Represents header string for documentation comment.
3353 public override string DocCommentHeader {
3354 get { return "M:"; }
3357 protected override void VerifyObsoleteAttribute()
3359 base.VerifyObsoleteAttribute ();
3361 if (parameter_types == null)
3364 foreach (Type type in parameter_types) {
3365 CheckUsageOfObsoleteAttribute (type);
3370 public class SourceMethod : ISourceMethod
3372 TypeContainer container;
3375 protected SourceMethod (TypeContainer container, MethodBase builder,
3376 ISourceFile file, Location start, Location end)
3378 this.container = container;
3379 this.builder = builder;
3381 CodeGen.SymbolWriter.OpenMethod (
3382 file, this, start.Row, 0, end.Row, 0);
3385 public string Name {
3386 get { return builder.Name; }
3389 public int NamespaceID {
3390 get { return container.NamespaceEntry.SymbolFileID; }
3395 if (builder is MethodBuilder)
3396 return ((MethodBuilder) builder).GetToken ().Token;
3397 else if (builder is ConstructorBuilder)
3398 return ((ConstructorBuilder) builder).GetToken ().Token;
3400 throw new NotSupportedException ();
3404 public void CloseMethod ()
3406 if (CodeGen.SymbolWriter != null)
3407 CodeGen.SymbolWriter.CloseMethod ();
3410 public static SourceMethod Create (TypeContainer parent,
3411 MethodBase builder, Block block)
3413 if (CodeGen.SymbolWriter == null)
3418 Location start_loc = block.StartLocation;
3419 if (Location.IsNull (start_loc))
3422 Location end_loc = block.EndLocation;
3423 if (Location.IsNull (end_loc))
3426 ISourceFile file = start_loc.SourceFile;
3430 return new SourceMethod (
3431 parent, builder, file, start_loc, end_loc);
3435 public class Method : MethodCore, IIteratorContainer, IMethodData {
3436 public MethodBuilder MethodBuilder;
3437 public MethodData MethodData;
3438 ReturnParameter return_attributes;
3439 ListDictionary declarative_security;
3442 /// Modifiers allowed in a class declaration
3444 const int AllowedModifiers =
3447 Modifiers.PROTECTED |
3448 Modifiers.INTERNAL |
3453 Modifiers.OVERRIDE |
3454 Modifiers.ABSTRACT |
3456 Modifiers.METHOD_YIELDS |
3459 const int AllowedInterfaceModifiers =
3460 Modifiers.NEW | Modifiers.UNSAFE;
3463 // return_type can be "null" for VOID values.
3465 public Method (TypeContainer ds, Expression return_type, int mod, bool is_iface,
3466 MemberName name, Parameters parameters, Attributes attrs,
3468 : base (ds, return_type, mod,
3469 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
3470 is_iface, name, attrs, parameters, l)
3474 public override AttributeTargets AttributeTargets {
3476 return AttributeTargets.Method;
3480 public override string GetSignatureForError()
3482 if (MethodBuilder == null) {
3483 return GetSignatureForError (Parent);
3485 return TypeManager.CSharpSignature (MethodBuilder);
3489 /// Use this method when MethodBuilder is null
3491 public override string GetSignatureForError (TypeContainer tc)
3493 // TODO: get params from somewhere
3494 if (parameter_info == null)
3495 return base.GetSignatureForError (tc);
3497 // TODO: move to parameters
3498 System.Text.StringBuilder args = new System.Text.StringBuilder ();
3499 if (parameter_info.Parameters.FixedParameters != null) {
3500 for (int i = 0; i < parameter_info.Parameters.FixedParameters.Length; ++i) {
3501 Parameter p = parameter_info.Parameters.FixedParameters [i];
3502 args.Append (p.GetSignatureForError ());
3504 if (i < parameter_info.Parameters.FixedParameters.Length - 1)
3509 return String.Concat (base.GetSignatureForError (tc), "(", args.ToString (), ")");
3512 void DuplicateEntryPoint (MethodInfo b, Location location)
3516 "Program `" + CodeGen.FileName +
3517 "' has more than one entry point defined: `" +
3518 TypeManager.CSharpSignature(b) + "'");
3521 public bool IsEntryPoint (MethodBuilder b, InternalParameters pinfo)
3523 if (b.ReturnType != TypeManager.void_type &&
3524 b.ReturnType != TypeManager.int32_type)
3527 if (pinfo.Count == 0)
3530 if (pinfo.Count > 1)
3533 Type t = pinfo.ParameterType(0);
3535 (t.GetArrayRank() == 1) &&
3536 (TypeManager.GetElementType(t) == TypeManager.string_type) &&
3537 (pinfo.ParameterModifier(0) == Parameter.Modifier.NONE))
3543 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
3545 if (a.Target == AttributeTargets.ReturnValue) {
3546 if (return_attributes == null)
3547 return_attributes = new ReturnParameter (MethodBuilder, Location);
3549 return_attributes.ApplyAttributeBuilder (a, cb);
3553 if (a.Type == TypeManager.methodimpl_attr_type && a.IsInternalCall) {
3554 MethodBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall | MethodImplAttributes.Runtime);
3557 if (a.Type == TypeManager.dllimport_type) {
3558 const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
3559 if ((ModFlags & extern_static) != extern_static) {
3560 Report.Error (601, a.Location, "The DllImport attribute must be specified on a method marked `static' and `extern'");
3566 if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
3567 if (declarative_security == null)
3568 declarative_security = new ListDictionary ();
3569 a.ExtractSecurityPermissionSet (declarative_security);
3573 if (a.Type == TypeManager.conditional_attribute_type) {
3574 if (IsOperator || IsExplicitImpl) {
3575 Report.Error (577, Location, "Conditional not valid on '{0}' because it is a destructor, operator, or explicit interface implementation", GetSignatureForError ());
3579 if (ReturnType != TypeManager.void_type) {
3580 Report.Error (578, Location, "Conditional not valid on '{0}' because its return new ErrorData ( type is not void", GetSignatureForError ());
3584 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
3585 Report.Error (243, Location, "Conditional not valid on '{0}' because it is an override method", GetSignatureForError ());
3590 Report.Error (582, Location, "Conditional not valid on interface members");
3594 if (MethodData.IsImplementing) {
3595 Report.Error (629, Location, "Conditional member '{0}' cannot implement interface member", GetSignatureForError ());
3599 for (int i = 0; i < parameter_info.Count; ++i) {
3600 if ((parameter_info.ParameterModifier (i) & Parameter.Modifier.OUT) != 0) {
3601 Report.Error (685, Location, "Conditional method '{0}' cannot have an out parameter", GetSignatureForError ());
3607 MethodBuilder.SetCustomAttribute (cb);
3610 protected override bool CheckForDuplications ()
3612 ArrayList ar = Parent.Methods;
3614 int arLen = ar.Count;
3616 for (int i = 0; i < arLen; i++) {
3617 Method m = (Method) ar [i];
3618 if (IsDuplicateImplementation (m))
3623 ar = Parent.Properties;
3625 for (int i = 0; i < ar.Count; ++i) {
3626 PropertyBase pb = (PropertyBase) ar [i];
3627 if (pb.AreAccessorsDuplicateImplementation (this))
3632 ar = Parent.Indexers;
3634 for (int i = 0; i < ar.Count; ++i) {
3635 PropertyBase pb = (PropertyBase) ar [i];
3636 if (pb.AreAccessorsDuplicateImplementation (this))
3643 for (int i = 0; i < ar.Count; ++i) {
3644 Event ev = (Event) ar [i];
3645 if (ev.AreAccessorsDuplicateImplementation (this))
3656 public override bool Define ()
3665 flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
3667 MethodData = new MethodData (this, ParameterInfo, ModFlags, flags, this);
3669 if (!MethodData.Define (Parent))
3673 // Setup iterator if we are one
3675 if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
3676 Iterator iterator = new Iterator (
3677 Parent, Name, MemberType, ParameterTypes,
3678 ParameterInfo, ModFlags, block, Location);
3680 if (!iterator.DefineIterator ())
3683 block = iterator.Block;
3686 MethodBuilder = MethodData.MethodBuilder;
3689 // This is used to track the Entry Point,
3691 if (Name == "Main" &&
3692 ((ModFlags & Modifiers.STATIC) != 0) && RootContext.NeedsEntryPoint &&
3693 (RootContext.MainClass == null ||
3694 RootContext.MainClass == Parent.TypeBuilder.FullName)){
3695 if (IsEntryPoint (MethodBuilder, ParameterInfo)) {
3696 if (RootContext.EntryPoint == null) {
3697 RootContext.EntryPoint = MethodBuilder;
3698 RootContext.EntryPointLocation = Location;
3700 DuplicateEntryPoint (RootContext.EntryPoint, RootContext.EntryPointLocation);
3701 DuplicateEntryPoint (MethodBuilder, Location);
3704 if (RootContext.WarningLevel >= 4)
3705 Report.Warning (28, Location, "'{0}' has the wrong signature to be an entry point", TypeManager.CSharpSignature(MethodBuilder));
3709 if (MemberType.IsAbstract && MemberType.IsSealed) {
3710 Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
3720 public override void Emit ()
3722 MethodData.Emit (Parent, this);
3725 if (declarative_security != null) {
3726 foreach (DictionaryEntry de in declarative_security) {
3727 MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
3735 protected override MethodInfo FindOutParentMethod (TypeContainer container, ref Type parent_ret_type)
3737 MethodInfo mi = (MethodInfo) container.ParentCache.FindMemberToOverride (
3738 container.TypeBuilder, Name, ParameterTypes, false);
3743 parent_ret_type = mi.ReturnType;
3747 protected override bool VerifyClsCompliance(DeclSpace ds)
3749 if (!base.VerifyClsCompliance (ds))
3752 if (parameter_types.Length > 0) {
3753 ArrayList al = (ArrayList)ds.MemberCache.Members [Name];
3755 ds.MemberCache.VerifyClsParameterConflict (al, this, MethodBuilder);
3762 void IIteratorContainer.SetYields ()
3764 ModFlags |= Modifiers.METHOD_YIELDS;
3767 #region IMethodData Members
3769 public CallingConventions CallingConventions {
3771 CallingConventions cc = Parameters.GetCallingConvention ();
3772 if (Parameters.HasArglist)
3773 block.HasVarargs = true;
3776 if ((ModFlags & Modifiers.STATIC) == 0)
3777 cc |= CallingConventions.HasThis;
3779 // FIXME: How is `ExplicitThis' used in C#?
3785 public Type ReturnType {
3791 public MemberName MethodName {
3797 public new Location Location {
3799 return base.Location;
3803 public EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig)
3805 return new EmitContext (
3806 tc, Parent, Location, ig, ReturnType, ModFlags, false);
3809 public ObsoleteAttribute GetObsoleteAttribute ()
3811 return GetObsoleteAttribute (Parent);
3815 /// Returns true if method has conditional attribute and the conditions is not defined (method is excluded).
3817 public bool IsExcluded (EmitContext ec)
3819 if ((caching_flags & Flags.Excluded_Undetected) == 0)
3820 return (caching_flags & Flags.Excluded) != 0;
3822 caching_flags &= ~Flags.Excluded_Undetected;
3824 if (parent_method == null) {
3825 if (OptAttributes == null)
3828 Attribute[] attrs = OptAttributes.SearchMulti (TypeManager.conditional_attribute_type, ec);
3833 foreach (Attribute a in attrs) {
3834 string condition = a.GetConditionalAttributeValue (
3836 if (RootContext.AllDefines.Contains (condition))
3840 caching_flags |= Flags.Excluded;
3844 IMethodData md = TypeManager.GetMethod (parent_method);
3846 if (AttributeTester.IsConditionalMethodExcluded (parent_method)) {
3847 caching_flags |= Flags.Excluded;
3853 if (md.IsExcluded (ec)) {
3854 caching_flags |= Flags.Excluded;
3863 public abstract class ConstructorInitializer {
3864 ArrayList argument_list;
3865 protected ConstructorInfo parent_constructor;
3866 Parameters parameters;
3869 public ConstructorInitializer (ArrayList argument_list, Parameters parameters,
3872 this.argument_list = argument_list;
3873 this.parameters = parameters;
3877 public ArrayList Arguments {
3879 return argument_list;
3883 public bool Resolve (ConstructorBuilder caller_builder, EmitContext ec)
3885 Expression parent_constructor_group;
3888 ec.CurrentBlock = new ToplevelBlock (Block.Flags.Implicit, parameters, loc);
3890 if (argument_list != null){
3891 foreach (Argument a in argument_list){
3892 if (!a.Resolve (ec, loc))
3896 ec.CurrentBlock = null;
3898 if (this is ConstructorBaseInitializer) {
3899 if (ec.ContainerType.BaseType == null)
3902 t = ec.ContainerType.BaseType;
3903 if (ec.ContainerType.IsValueType) {
3904 Report.Error (522, loc,
3905 "structs cannot call base class constructors");
3909 t = ec.ContainerType;
3911 parent_constructor_group = Expression.MemberLookup (
3912 ec, t, ".ctor", MemberTypes.Constructor,
3913 BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
3916 if (parent_constructor_group == null){
3917 parent_constructor_group = Expression.MemberLookup (
3918 ec, t, ".ctor", MemberTypes.Constructor,
3919 BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly,
3922 if (parent_constructor_group != null)
3924 112, loc, "`{0}.{1}' is inaccessible due to " +
3925 "its protection level", t.FullName, t.Name);
3928 1501, loc, "Can not find a constructor for " +
3929 "this argument list");
3933 parent_constructor = (ConstructorInfo) Invocation.OverloadResolve (
3934 ec, (MethodGroupExpr) parent_constructor_group, argument_list,
3937 if (parent_constructor == null){
3938 Report.Error (1501, loc,
3939 "Can not find a constructor for this argument list");
3943 if (parent_constructor == caller_builder){
3944 Report.Error (516, String.Format ("Constructor `{0}' can not call itself", TypeManager.CSharpSignature (caller_builder)));
3951 public void Emit (EmitContext ec)
3953 if (parent_constructor != null){
3954 ec.Mark (loc, false);
3956 Invocation.EmitCall (ec, true, true, null, parent_constructor, argument_list, loc);
3958 Invocation.EmitCall (ec, true, false, ec.GetThis (loc), parent_constructor, argument_list, loc);
3963 /// Method search for base ctor. (We do not cache it).
3965 Constructor GetOverloadedConstructor (TypeContainer tc)
3967 if (tc.InstanceConstructors == null)
3970 foreach (Constructor c in tc.InstanceConstructors) {
3971 if (Arguments == null) {
3972 if (c.ParameterTypes.Length == 0)
3980 int count = c.ParameterInfo.Count;
3982 c.ParameterInfo.ParameterModifier (count - 1) == Parameter.Modifier.PARAMS) {
3983 for (int i = 0; i < count-1; i++)
3984 if (c.ParameterTypes [i] != ((Argument)Arguments [i]).Type) {
3989 if (c.ParameterTypes.Length != Arguments.Count)
3992 for (int i = 0; i < Arguments.Count; ++i)
3993 if (c.ParameterTypes [i] != ((Argument)Arguments [i]).Type) {
4008 //TODO: implement caching when it will be necessary
4009 public virtual void CheckObsoleteAttribute (TypeContainer tc, Location loc)
4011 Constructor ctor = GetOverloadedConstructor (tc);
4015 ObsoleteAttribute oa = ctor.GetObsoleteAttribute (tc);
4019 AttributeTester.Report_ObsoleteMessage (oa, ctor.GetSignatureForError (), loc);
4023 public class ConstructorBaseInitializer : ConstructorInitializer {
4024 public ConstructorBaseInitializer (ArrayList argument_list, Parameters pars, Location l) :
4025 base (argument_list, pars, l)
4029 public override void CheckObsoleteAttribute(TypeContainer tc, Location loc) {
4030 if (parent_constructor == null)
4033 TypeContainer type_ds = TypeManager.LookupTypeContainer (tc.TypeBuilder.BaseType);
4034 if (type_ds == null) {
4035 ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (parent_constructor);
4038 AttributeTester.Report_ObsoleteMessage (oa, TypeManager.CSharpSignature (parent_constructor), loc);
4043 base.CheckObsoleteAttribute (type_ds, loc);
4048 public class ConstructorThisInitializer : ConstructorInitializer {
4049 public ConstructorThisInitializer (ArrayList argument_list, Parameters pars, Location l) :
4050 base (argument_list, pars, l)
4055 public class Constructor : MethodCore, IMethodData {
4056 public ConstructorBuilder ConstructorBuilder;
4057 public ConstructorInitializer Initializer;
4058 ListDictionary declarative_security;
4061 // Modifiers allowed for a constructor.
4063 public const int AllowedModifiers =
4065 Modifiers.PROTECTED |
4066 Modifiers.INTERNAL |
4072 bool has_compliant_args = false;
4074 // The spec claims that static is not permitted, but
4075 // my very own code has static constructors.
4077 public Constructor (TypeContainer ds, string name, int mod, Parameters args,
4078 ConstructorInitializer init, Location l)
4079 : base (ds, null, mod, AllowedModifiers, false, new MemberName (name),
4085 public override string GetSignatureForError()
4087 if (ConstructorBuilder == null)
4088 return GetSignatureForError (Parent);
4090 return TypeManager.CSharpSignature (ConstructorBuilder);
4093 public bool HasCompliantArgs {
4095 return has_compliant_args;
4099 public override AttributeTargets AttributeTargets {
4101 return AttributeTargets.Constructor;
4107 // Returns true if this is a default constructor
4109 public bool IsDefault ()
4111 if ((ModFlags & Modifiers.STATIC) != 0)
4112 return (Parameters.FixedParameters == null ? true : Parameters.Empty) &&
4113 (Parameters.ArrayParameter == null ? true : Parameters.Empty);
4116 return (Parameters.FixedParameters == null ? true : Parameters.Empty) &&
4117 (Parameters.ArrayParameter == null ? true : Parameters.Empty) &&
4118 (Initializer is ConstructorBaseInitializer) &&
4119 (Initializer.Arguments == null);
4122 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
4124 if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
4125 if (declarative_security == null) {
4126 declarative_security = new ListDictionary ();
4128 a.ExtractSecurityPermissionSet (declarative_security);
4132 ConstructorBuilder.SetCustomAttribute (cb);
4135 protected override bool CheckForDuplications ()
4137 ArrayList ar = Parent.InstanceConstructors;
4139 int arLen = ar.Count;
4141 for (int i = 0; i < arLen; i++) {
4142 Constructor m = (Constructor) ar [i];
4143 if (IsDuplicateImplementation (m))
4150 protected override bool CheckBase ()
4152 // Check whether arguments were correct.
4153 if (!DoDefineParameters ())
4156 // TODO: skip the rest for generated ctor
4157 if ((ModFlags & Modifiers.STATIC) != 0)
4160 if (!CheckForDuplications ())
4163 if (Parent.Kind == Kind.Struct) {
4164 if (ParameterTypes.Length == 0) {
4165 Report.Error (568, Location,
4166 "Structs can not contain explicit parameterless " +
4171 if ((ModFlags & Modifiers.PROTECTED) != 0) {
4172 Report.Error (666, Location, "Protected member in struct declaration");
4177 if ((RootContext.WarningLevel >= 4) && ((Parent.ModFlags & Modifiers.SEALED) != 0 && (ModFlags & Modifiers.PROTECTED) != 0)) {
4178 Report.Warning (628, Location, "'{0}': new protected member declared in sealed class", GetSignatureForError (Parent));
4185 // Creates the ConstructorBuilder
4187 public override bool Define ()
4189 MethodAttributes ca = (MethodAttributes.RTSpecialName |
4190 MethodAttributes.SpecialName);
4192 if ((ModFlags & Modifiers.STATIC) != 0) {
4193 ca |= MethodAttributes.Static | MethodAttributes.Private;
4195 ca |= MethodAttributes.HideBySig;
4197 if ((ModFlags & Modifiers.PUBLIC) != 0)
4198 ca |= MethodAttributes.Public;
4199 else if ((ModFlags & Modifiers.PROTECTED) != 0){
4200 if ((ModFlags & Modifiers.INTERNAL) != 0)
4201 ca |= MethodAttributes.FamORAssem;
4203 ca |= MethodAttributes.Family;
4204 } else if ((ModFlags & Modifiers.INTERNAL) != 0)
4205 ca |= MethodAttributes.Assembly;
4206 else if (IsDefault ())
4207 ca |= MethodAttributes.Public;
4209 ca |= MethodAttributes.Private;
4212 // Check if arguments were correct.
4216 ConstructorBuilder = Parent.TypeBuilder.DefineConstructor (
4217 ca, CallingConventions,
4220 if ((ModFlags & Modifiers.UNSAFE) != 0)
4221 ConstructorBuilder.InitLocals = false;
4223 TypeManager.AddMethod (ConstructorBuilder, this);
4226 // HACK because System.Reflection.Emit is lame
4228 TypeManager.RegisterMethod (ConstructorBuilder, ParameterInfo, ParameterTypes);
4236 public override void Emit ()
4238 EmitContext ec = CreateEmitContext (null, null);
4241 // extern methods have no bodies
4243 if ((ModFlags & Modifiers.EXTERN) != 0) {
4244 if ((block != null) && ((ModFlags & Modifiers.EXTERN) != 0)) {
4246 179, Location, "External constructor `" +
4247 TypeManager.CSharpSignature (ConstructorBuilder) +
4248 "' can not have a body");
4251 } else if (block == null) {
4253 501, Location, "Constructor `" +
4254 TypeManager.CSharpSignature (ConstructorBuilder) +
4255 "' must declare a body since it is not marked extern");
4259 if ((ModFlags & Modifiers.STATIC) == 0){
4260 if (Parent.Kind == Kind.Class && Initializer == null)
4261 Initializer = new ConstructorBaseInitializer (
4262 null, Parameters.EmptyReadOnlyParameters, Location);
4266 // Spec mandates that Initializers will not have
4270 if (Initializer != null && !Initializer.Resolve (ConstructorBuilder, ec))
4272 ec.IsStatic = false;
4275 Parameters.LabelParameters (ec, ConstructorBuilder, Location);
4277 SourceMethod source = SourceMethod.Create (
4278 Parent, ConstructorBuilder, block);
4281 // Classes can have base initializers and instance field initializers.
4283 if (Parent.Kind == Kind.Class){
4284 if ((ModFlags & Modifiers.STATIC) == 0){
4287 // If we use a "this (...)" constructor initializer, then
4288 // do not emit field initializers, they are initialized in the other constructor
4290 if (!(Initializer != null && Initializer is ConstructorThisInitializer))
4291 Parent.EmitFieldInitializers (ec);
4294 if (Initializer != null) {
4295 if (GetObsoleteAttribute (Parent) == null && Parent.GetObsoleteAttribute (Parent.Parent) == null)
4296 Initializer.CheckObsoleteAttribute (Parent, Location);
4298 ec.TestObsoleteMethodUsage = false;
4299 Initializer.Emit (ec);
4302 if ((ModFlags & Modifiers.STATIC) != 0)
4303 Parent.EmitFieldInitializers (ec);
4305 if (OptAttributes != null)
4306 OptAttributes.Emit (ec, this);
4308 // If this is a non-static `struct' constructor and doesn't have any
4309 // initializer, it must initialize all of the struct's fields.
4310 if ((Parent.Kind == Kind.Struct) &&
4311 ((ModFlags & Modifiers.STATIC) == 0) && (Initializer == null))
4312 Block.AddThisVariable (Parent, Location);
4314 ec.EmitTopBlock (block, ParameterInfo, Location);
4317 source.CloseMethod ();
4321 if (declarative_security != null) {
4322 foreach (DictionaryEntry de in declarative_security) {
4323 ConstructorBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
4330 // Is never override
4331 protected override MethodInfo FindOutParentMethod (TypeContainer container, ref Type parent_ret_type)
4336 protected override bool VerifyClsCompliance (DeclSpace ds)
4338 if (!base.VerifyClsCompliance (ds) || !IsExposedFromAssembly (ds)) {
4342 if (parameter_types.Length > 0) {
4343 ArrayList al = (ArrayList)ds.MemberCache.Members [".ctor"];
4345 ds.MemberCache.VerifyClsParameterConflict (al, this, ConstructorBuilder);
4347 if (ds.TypeBuilder.IsSubclassOf (TypeManager.attribute_type)) {
4348 foreach (Type param in parameter_types) {
4349 if (param.IsArray) {
4355 has_compliant_args = true;
4359 #region IMethodData Members
4361 public System.Reflection.CallingConventions CallingConventions {
4363 CallingConventions cc = Parameters.GetCallingConvention ();
4365 if (Parent.Kind == Kind.Class)
4366 if ((ModFlags & Modifiers.STATIC) == 0)
4367 cc |= CallingConventions.HasThis;
4369 // FIXME: How is `ExplicitThis' used in C#?
4375 public new Location Location {
4377 return base.Location;
4381 public MemberName MethodName {
4387 public Type ReturnType {
4393 public EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig)
4395 ILGenerator ig_ = ConstructorBuilder.GetILGenerator ();
4396 return new EmitContext (Parent, Location, ig_, null, ModFlags, true);
4399 public ObsoleteAttribute GetObsoleteAttribute ()
4404 public bool IsExcluded(EmitContext ec)
4413 /// Interface for MethodData class. Holds links to parent members to avoid member duplication.
4415 public interface IMethodData
4417 CallingConventions CallingConventions { get; }
4418 Location Location { get; }
4419 MemberName MethodName { get; }
4420 Type[] ParameterTypes { get; }
4421 Type ReturnType { get; }
4423 Attributes OptAttributes { get; }
4424 ToplevelBlock Block { get; }
4426 EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig);
4427 ObsoleteAttribute GetObsoleteAttribute ();
4428 string GetSignatureForError (TypeContainer tc);
4429 bool IsExcluded (EmitContext ec);
4430 bool IsClsCompliaceRequired (DeclSpace ds);
4434 // Encapsulates most of the Method's state
4436 public class MethodData {
4438 readonly IMethodData method;
4441 // The return type of this method
4443 public readonly InternalParameters ParameterInfo;
4446 // Are we implementing an interface ?
4448 public bool IsImplementing = false;
4453 protected MemberBase member;
4454 protected int modifiers;
4455 protected MethodAttributes flags;
4457 MethodBuilder builder = null;
4458 public MethodBuilder MethodBuilder {
4464 public MethodData (MemberBase member, InternalParameters parameters,
4465 int modifiers, MethodAttributes flags, IMethodData method)
4467 this.member = member;
4468 this.ParameterInfo = parameters;
4469 this.modifiers = modifiers;
4472 this.method = method;
4475 public bool Define (TypeContainer container)
4477 MethodInfo implementing = null;
4479 string name = method.MethodName.Name;
4480 string method_name = name;
4482 Type[] ParameterTypes = method.ParameterTypes;
4484 if (container.Pending != null){
4485 if (member is Indexer)
4486 implementing = container.Pending.IsInterfaceIndexer (
4487 member.InterfaceType, method.ReturnType, ParameterTypes);
4489 implementing = container.Pending.IsInterfaceMethod (
4490 member.InterfaceType, name, method.ReturnType, ParameterTypes);
4492 if (member.InterfaceType != null){
4493 if (implementing == null){
4494 Report.Error (539, method.Location,
4495 "'{0}' in explicit interface declaration is not an interface", method_name);
4498 method_name = member.InterfaceType.FullName + "." + name;
4503 // For implicit implementations, make sure we are public, for
4504 // explicit implementations, make sure we are private.
4506 if (implementing != null){
4508 // Setting null inside this block will trigger a more
4509 // verbose error reporting for missing interface implementations
4511 // The "candidate" function has been flagged already
4512 // but it wont get cleared
4514 if (member.IsExplicitImpl){
4515 if ((modifiers & (Modifiers.PUBLIC | Modifiers.ABSTRACT | Modifiers.VIRTUAL)) != 0){
4516 Modifiers.Error_InvalidModifier (method.Location, "public, virtual or abstract");
4517 implementing = null;
4519 } else if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public){
4520 if (TypeManager.IsInterfaceType (implementing.DeclaringType)){
4522 // If this is an interface method implementation,
4523 // check for public accessibility
4525 implementing = null;
4526 } else if ((flags & MethodAttributes.MemberAccessMask) == MethodAttributes.Private){
4527 // We may never be private.
4528 implementing = null;
4529 } else if ((modifiers & Modifiers.OVERRIDE) == 0){
4531 // We may be protected if we're overriding something.
4533 implementing = null;
4538 // Static is not allowed
4540 if ((modifiers & Modifiers.STATIC) != 0){
4541 implementing = null;
4542 Modifiers.Error_InvalidModifier (method.Location, "static");
4547 // If implementing is still valid, set flags
4549 if (implementing != null){
4551 // When implementing interface methods, set NewSlot
4552 // unless, we are overwriting a method.
4554 if (implementing.DeclaringType.IsInterface){
4555 if ((modifiers & Modifiers.OVERRIDE) == 0)
4556 flags |= MethodAttributes.NewSlot;
4559 MethodAttributes.Virtual |
4560 MethodAttributes.HideBySig;
4562 // Set Final unless we're virtual, abstract or already overriding a method.
4563 if ((modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE)) == 0)
4564 flags |= MethodAttributes.Final;
4566 IsImplementing = true;
4569 EmitContext ec = method.CreateEmitContext (container, null);
4571 DefineMethodBuilder (ec, container, method_name, ParameterTypes);
4573 if (builder == null)
4576 if ((modifiers & Modifiers.UNSAFE) != 0)
4577 builder.InitLocals = false;
4579 if (IsImplementing){
4581 // clear the pending implemntation flag
4583 if (member is Indexer) {
4584 container.Pending.ImplementIndexer (
4585 member.InterfaceType, builder, method.ReturnType,
4586 ParameterTypes, member.IsExplicitImpl);
4588 container.Pending.ImplementMethod (
4589 member.InterfaceType, name, method.ReturnType,
4590 ParameterTypes, member.IsExplicitImpl);
4592 if (member.IsExplicitImpl)
4593 container.TypeBuilder.DefineMethodOverride (
4594 builder, implementing);
4598 TypeManager.RegisterMethod (builder, ParameterInfo, ParameterTypes);
4599 TypeManager.AddMethod (builder, method);
4606 /// Create the MethodBuilder for the method
4608 void DefineMethodBuilder (EmitContext ec, TypeContainer container, string method_name, Type[] ParameterTypes)
4610 const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
4612 if ((modifiers & extern_static) == extern_static) {
4614 if (method.OptAttributes != null) {
4615 Attribute dllimport_attribute = method.OptAttributes.Search (TypeManager.dllimport_type, ec);
4616 if (dllimport_attribute != null) {
4617 flags |= MethodAttributes.PinvokeImpl;
4618 builder = dllimport_attribute.DefinePInvokeMethod (
4619 ec, container.TypeBuilder, method_name, flags,
4620 method.ReturnType, ParameterTypes);
4626 // for extern static method must be specified either DllImport attribute or MethodImplAttribute.
4627 // We are more strict than Microsoft and report CS0626 like error
4628 if (method.OptAttributes == null ||
4629 !method.OptAttributes.Contains (TypeManager.methodimpl_attr_type, ec)) {
4630 Report.Error (626, method.Location, "Method, operator, or accessor '{0}' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation", method.GetSignatureForError (container));
4635 builder = container.TypeBuilder.DefineMethod (
4636 method_name, flags, method.CallingConventions,
4637 method.ReturnType, ParameterTypes);
4643 public void Emit (TypeContainer container, Attributable kind)
4646 if ((flags & MethodAttributes.PinvokeImpl) == 0)
4647 ec = method.CreateEmitContext (container, builder.GetILGenerator ());
4649 ec = method.CreateEmitContext (container, null);
4651 if (method.GetObsoleteAttribute () != null || container.GetObsoleteAttribute (container.Parent) != null)
4652 ec.TestObsoleteMethodUsage = false;
4654 Location loc = method.Location;
4655 Attributes OptAttributes = method.OptAttributes;
4657 if (OptAttributes != null)
4658 OptAttributes.Emit (ec, kind);
4660 if (member is MethodCore)
4661 ((MethodCore) member).Parameters.LabelParameters (ec, MethodBuilder, loc);
4663 SymbolWriter sw = CodeGen.SymbolWriter;
4664 ToplevelBlock block = method.Block;
4667 // abstract or extern methods have no bodies
4669 if ((modifiers & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0){
4674 // abstract or extern methods have no bodies.
4676 if ((modifiers & Modifiers.ABSTRACT) != 0)
4678 500, method.Location, "Abstract method `" +
4679 TypeManager.CSharpSignature (builder) +
4680 "' can not have a body");
4682 if ((modifiers & Modifiers.EXTERN) != 0)
4684 179, method.Location, "External method `" +
4685 TypeManager.CSharpSignature (builder) +
4686 "' can not have a body");
4692 // Methods must have a body unless they're extern or abstract
4694 if (block == null) {
4696 501, method.Location, "Method `" +
4697 TypeManager.CSharpSignature (builder) +
4698 "' must declare a body since it is not marked " +
4699 "abstract or extern");
4703 SourceMethod source = SourceMethod.Create (
4704 container, MethodBuilder, method.Block);
4707 // Handle destructors specially
4709 // FIXME: This code generates buggy code
4711 if (member is Destructor)
4712 EmitDestructor (ec, block);
4714 ec.EmitTopBlock (block, ParameterInfo, loc);
4717 source.CloseMethod ();
4720 void EmitDestructor (EmitContext ec, ToplevelBlock block)
4722 ILGenerator ig = ec.ig;
4724 Label finish = ig.DefineLabel ();
4726 block.SetDestructor ();
4728 ig.BeginExceptionBlock ();
4729 ec.ReturnLabel = finish;
4730 ec.HasReturnLabel = true;
4731 ec.EmitTopBlock (block, null, method.Location);
4733 // ig.MarkLabel (finish);
4734 ig.BeginFinallyBlock ();
4736 if (ec.ContainerType.BaseType != null) {
4737 Expression member_lookup = Expression.MemberLookup (
4738 ec, ec.ContainerType.BaseType, null, ec.ContainerType.BaseType,
4739 "Finalize", MemberTypes.Method, Expression.AllBindingFlags, method.Location);
4741 if (member_lookup != null){
4742 MethodGroupExpr parent_destructor = ((MethodGroupExpr) member_lookup);
4744 ig.Emit (OpCodes.Ldarg_0);
4745 ig.Emit (OpCodes.Call, (MethodInfo) parent_destructor.Methods [0]);
4749 ig.EndExceptionBlock ();
4750 //ig.MarkLabel (ec.ReturnLabel);
4751 ig.Emit (OpCodes.Ret);
4755 public class Destructor : Method {
4757 public Destructor (TypeContainer ds, Expression return_type, int mod,
4758 string name, Parameters parameters, Attributes attrs,
4760 : base (ds, return_type, mod, false, new MemberName (name),
4761 parameters, attrs, l)
4764 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
4766 if (a.Type == TypeManager.conditional_attribute_type) {
4767 Report.Error (577, Location, "Conditional not valid on '{0}' because it is a destructor, operator, or explicit interface implementation", GetSignatureForError ());
4771 base.ApplyAttributeBuilder (a, cb);
4775 abstract public class MemberBase : MemberCore {
4776 public Expression Type;
4778 public MethodAttributes flags;
4780 protected readonly int explicit_mod_flags;
4783 // The "short" name of this property / indexer / event. This is the
4784 // name without the explicit interface.
4786 public string ShortName;
4789 // The type of this property / indexer / event
4791 public Type MemberType;
4794 // If true, this is an explicit interface implementation
4796 public bool IsExplicitImpl = false;
4799 // The name of the interface we are explicitly implementing
4801 public MemberName ExplicitInterfaceName = null;
4804 // Whether this is an interface member.
4806 public bool IsInterface;
4809 // If true, the interface type we are explicitly implementing
4811 public Type InterfaceType = null;
4814 // The constructor is only exposed to our children
4816 protected MemberBase (TypeContainer parent, Expression type, int mod,
4817 int allowed_mod, int def_mod, MemberName name,
4818 Attributes attrs, Location loc)
4819 : base (parent, name, attrs, loc)
4821 explicit_mod_flags = mod;
4823 ModFlags = Modifiers.Check (allowed_mod, mod, def_mod, loc);
4825 // Check for explicit interface implementation
4826 if (MemberName.Left != null) {
4827 ExplicitInterfaceName = MemberName.Left;
4828 ShortName = MemberName.Name;
4829 IsExplicitImpl = true;
4834 protected virtual bool CheckBase ()
4836 if ((ModFlags & Modifiers.PROTECTED) != 0 && Parent.Kind == Kind.Struct) {
4837 Report.Error (666, Location, "Protected member in struct declaration");
4841 if ((RootContext.WarningLevel >= 4) &&
4842 ((Parent.ModFlags & Modifiers.SEALED) != 0) &&
4843 ((ModFlags & Modifiers.PROTECTED) != 0) &&
4844 ((ModFlags & Modifiers.OVERRIDE) == 0) && (Name != "Finalize")) {
4845 Report.Warning (628, Location, "'{0}': new protected member declared in sealed class", GetSignatureForError (Parent));
4850 protected virtual bool CheckParameters (DeclSpace ds, Type [] parameters)
4854 foreach (Type partype in parameters){
4855 if (partype == TypeManager.void_type) {
4857 1547, Location, "Keyword 'void' cannot " +
4858 "be used in this context");
4862 if (partype.IsPointer){
4865 if (!TypeManager.VerifyUnManaged (TypeManager.GetElementType (partype), Location))
4869 if (ds.AsAccessible (partype, ModFlags))
4872 if (this is Indexer)
4873 Report.Error (55, Location,
4874 "Inconsistent accessibility: parameter type `" +
4875 TypeManager.CSharpName (partype) + "' is less " +
4876 "accessible than indexer `" + Name + "'");
4877 else if ((this is Method) && ((Method) this).IsOperator)
4878 Report.Error (57, Location,
4879 "Inconsistent accessibility: parameter type `" +
4880 TypeManager.CSharpName (partype) + "' is less " +
4881 "accessible than operator `" + Name + "'");
4883 Report.Error (51, Location,
4884 "Inconsistent accessibility: parameter type `" +
4885 TypeManager.CSharpName (partype) + "' is less " +
4886 "accessible than method `" + Name + "'");
4893 protected virtual bool DoDefine ()
4895 EmitContext ec = Parent.EmitContext;
4897 throw new InternalErrorException ("MemberBase.DoDefine called too early");
4900 throw new InternalErrorException ();
4903 ModFlags = Modifiers.PUBLIC |
4904 Modifiers.ABSTRACT |
4905 Modifiers.VIRTUAL | (ModFlags & Modifiers.UNSAFE) | (ModFlags & Modifiers.NEW);
4907 flags = MethodAttributes.Public |
4908 MethodAttributes.Abstract |
4909 MethodAttributes.HideBySig |
4910 MethodAttributes.NewSlot |
4911 MethodAttributes.Virtual;
4913 if (!Parent.MethodModifiersValid (ModFlags, Name, Location))
4916 flags = Modifiers.MethodAttr (ModFlags);
4919 // Lookup Type, verify validity
4920 bool old_unsafe = ec.InUnsafe;
4921 ec.InUnsafe = InUnsafe;
4922 Type = Type.ResolveAsTypeTerminal (ec, false);
4923 ec.InUnsafe = old_unsafe;
4928 MemberType = Type.Type;
4930 if ((Parent.ModFlags & Modifiers.SEALED) != 0){
4931 if ((ModFlags & (Modifiers.VIRTUAL|Modifiers.ABSTRACT)) != 0){
4932 Report.Error (549, Location, "Virtual method can not be contained in sealed class");
4937 // verify accessibility
4938 if (!Parent.AsAccessible (MemberType, ModFlags)) {
4939 if (this is Property)
4940 Report.Error (53, Location,
4941 "Inconsistent accessibility: property type `" +
4942 TypeManager.CSharpName (MemberType) + "' is less " +
4943 "accessible than property `" + Name + "'");
4944 else if (this is Indexer)
4945 Report.Error (54, Location,
4946 "Inconsistent accessibility: indexer return type `" +
4947 TypeManager.CSharpName (MemberType) + "' is less " +
4948 "accessible than indexer `" + Name + "'");
4949 else if (this is MethodCore) {
4950 if (this is Operator)
4951 Report.Error (56, Location,
4952 "Inconsistent accessibility: return type `" +
4953 TypeManager.CSharpName (MemberType) + "' is less " +
4954 "accessible than operator `" + Name + "'");
4956 Report.Error (50, Location,
4957 "Inconsistent accessibility: return type `" +
4958 TypeManager.CSharpName (MemberType) + "' is less " +
4959 "accessible than method `" + Name + "'");
4961 Report.Error (52, Location,
4962 "Inconsistent accessibility: field type `" +
4963 TypeManager.CSharpName (MemberType) + "' is less " +
4964 "accessible than field `" + Name + "'");
4969 if (MemberType.IsPointer && !UnsafeOK (Parent))
4972 if (IsExplicitImpl) {
4973 Expression expr = ExplicitInterfaceName.GetTypeExpression (Location);
4974 TypeExpr texpr = expr.ResolveAsTypeTerminal (ec, false);
4978 InterfaceType = texpr.ResolveType (ec);
4980 if (!InterfaceType.IsInterface) {
4981 Report.Error (538, Location, "'{0}' in explicit interface declaration is not an interface", TypeManager.CSharpName (InterfaceType));
4986 // Compute the full name that we need to export.
4987 if (InterfaceType.FullName != ExplicitInterfaceName) {
4988 ExplicitInterfaceName = InterfaceType.FullName;
4989 UpdateMemberName ();
4993 if (!Parent.VerifyImplements (InterfaceType, ShortName, Name, Location))
4996 Modifiers.Check (Modifiers.AllowedExplicitImplFlags, explicit_mod_flags, 0, Location);
5003 /// The name of the member can be changed during definition (see IndexerName attribute)
5005 protected virtual void UpdateMemberName ()
5007 MemberName.Name = ShortName;
5010 public override string GetSignatureForError (TypeContainer tc)
5012 return String.Concat (tc.Name, '.', base.GetSignatureForError (tc));
5015 protected bool IsTypePermitted ()
5017 if (MemberType == TypeManager.arg_iterator_type || MemberType == TypeManager.typed_reference_type) {
5018 Report.Error (610, Location, "Field or property cannot be of type '{0}'", TypeManager.CSharpName (MemberType));
5024 protected override bool VerifyClsCompliance(DeclSpace ds)
5026 if (base.VerifyClsCompliance (ds)) {
5030 if (IsInterface && HasClsCompliantAttribute && ds.IsClsCompliaceRequired (ds)) {
5031 Report.Error (3010, Location, "'{0}': CLS-compliant interfaces must have only CLS-compliant members", GetSignatureForError ());
5036 protected override void VerifyObsoleteAttribute()
5038 CheckUsageOfObsoleteAttribute (MemberType);
5043 // Fields and Events both generate FieldBuilders, we use this to share
5044 // their common bits. This is also used to flag usage of the field
5046 abstract public class FieldBase : MemberBase {
5047 public FieldBuilder FieldBuilder;
5048 public Status status;
5051 public enum Status : byte {
5054 HAS_OFFSET = 4 // Used by FieldMember.
5057 static string[] attribute_targets = new string [] { "field" };
5060 /// Symbol with same name in parent class/struct
5062 public MemberInfo conflict_symbol;
5065 // The constructor is only exposed to our children
5067 protected FieldBase (TypeContainer parent, Expression type, int mod,
5068 int allowed_mod, MemberName name, object init,
5069 Attributes attrs, Location loc)
5070 : base (parent, type, mod, allowed_mod, Modifiers.PRIVATE,
5076 public override AttributeTargets AttributeTargets {
5078 return AttributeTargets.Field;
5082 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
5084 if (a.Type == TypeManager.marshal_as_attr_type) {
5085 UnmanagedMarshal marshal = a.GetMarshal (this);
5086 if (marshal != null) {
5087 FieldBuilder.SetMarshal (marshal);
5092 if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
5093 a.Error_InvalidSecurityParent ();
5097 FieldBuilder.SetCustomAttribute (cb);
5101 // Whether this field has an initializer.
5103 public bool HasInitializer {
5105 return init != null;
5109 protected readonly Object init;
5112 Expression init_expr;
5113 bool init_expr_initialized = false;
5116 // Resolves and returns the field initializer.
5118 public Expression GetInitializerExpression (EmitContext ec)
5120 if (init_expr_initialized)
5124 if (init is Expression)
5125 e = (Expression) init;
5127 e = new ArrayCreation (Type, "", (ArrayList)init, Location);
5129 ec.IsFieldInitializer = true;
5130 e = e.DoResolve (ec);
5131 ec.IsFieldInitializer = false;
5134 init_expr_initialized = true;
5139 protected override bool CheckBase ()
5141 if (!base.CheckBase ())
5148 conflict_symbol = Parent.FindMemberWithSameName (Name, false);
5149 if (conflict_symbol == null) {
5150 if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) {
5151 Report.Warning (109, Location, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError (Parent));
5156 if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0) {
5157 Report.SymbolRelatedToPreviousError (conflict_symbol);
5158 Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent));
5164 protected override bool DoDefine ()
5166 if (!base.DoDefine ())
5169 if (MemberType == TypeManager.void_type) {
5170 Report.Error (1547, Location,
5171 "Keyword 'void' cannot be used in this context");
5177 public override string GetSignatureForError ()
5179 if (FieldBuilder == null) {
5180 return base.GetSignatureForError (Parent);
5182 return TypeManager.GetFullNameSignature (FieldBuilder);
5185 public override string[] ValidAttributeTargets {
5187 return attribute_targets;
5191 protected override bool VerifyClsCompliance (DeclSpace ds)
5193 if (!base.VerifyClsCompliance (ds))
5196 if (FieldBuilder == null) {
5200 if (!AttributeTester.IsClsCompliant (FieldBuilder.FieldType)) {
5201 Report.Error (3003, Location, "Type of '{0}' is not CLS-compliant", GetSignatureForError ());
5207 public void SetAssigned ()
5209 status |= Status.ASSIGNED;
5213 public abstract class FieldMember: FieldBase
5217 protected FieldMember (TypeContainer parent, Expression type, int mod,
5218 int allowed_mod, MemberName name, object init, Attributes attrs, Location loc)
5219 : base (parent, type, mod, allowed_mod, name, init, attrs, loc)
5223 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
5225 if (a.Type == TypeManager.field_offset_attribute_type)
5227 status |= Status.HAS_OFFSET;
5229 if (!Parent.HasExplicitLayout) {
5230 Report.Error (636, Location, "The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit)");
5234 if ((ModFlags & Modifiers.STATIC) != 0 || this is Const) {
5235 Report.Error (637, Location, "The FieldOffset attribute is not allowed on static or const fields");
5239 base.ApplyAttributeBuilder (a, cb);
5243 public override bool Define()
5245 EmitContext ec = Parent.EmitContext;
5247 throw new InternalErrorException ("FieldMember.Define called too early");
5249 bool old_unsafe = ec.InUnsafe;
5250 ec.InUnsafe = InUnsafe;
5251 TypeExpr texpr = Type.ResolveAsTypeTerminal (ec, false);
5255 MemberType = texpr.ResolveType (ec);
5256 ec.InUnsafe = old_unsafe;
5261 if (!Parent.AsAccessible (MemberType, ModFlags)) {
5262 Report.Error (52, Location,
5263 "Inconsistent accessibility: field type `" +
5264 TypeManager.CSharpName (MemberType) + "' is less " +
5265 "accessible than field `" + Name + "'");
5269 if (!IsTypePermitted ())
5272 if (MemberType.IsPointer && !UnsafeOK (Parent))
5278 public override void Emit ()
5280 if (Parent.HasExplicitLayout && ((status & Status.HAS_OFFSET) == 0) && (ModFlags & Modifiers.STATIC) == 0) {
5281 Report.Error (625, Location, "'{0}': Instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute.", GetSignatureForError ());
5288 // Represents header string for documentation comment.
5290 public override string DocCommentHeader {
5291 get { return "F:"; }
5296 // The Field class is used to represents class/struct fields during parsing.
5298 public class Field : FieldMember {
5300 // Modifiers allowed in a class declaration
5302 const int AllowedModifiers =
5305 Modifiers.PROTECTED |
5306 Modifiers.INTERNAL |
5309 Modifiers.VOLATILE |
5313 public Field (TypeContainer parent, Expression type, int mod, string name,
5314 Object expr_or_array_init, Attributes attrs, Location loc)
5315 : base (parent, type, mod, AllowedModifiers, new MemberName (name),
5316 expr_or_array_init, attrs, loc)
5320 public override bool Define ()
5322 if (!base.Define ())
5325 if (RootContext.WarningLevel > 1){
5326 Type ptype = Parent.TypeBuilder.BaseType;
5328 // ptype is only null for System.Object while compiling corlib.
5330 TypeContainer.FindMembers (
5331 ptype, MemberTypes.Method,
5332 BindingFlags.Public |
5333 BindingFlags.Static | BindingFlags.Instance,
5334 System.Type.FilterName, Name);
5338 if ((ModFlags & Modifiers.VOLATILE) != 0){
5339 if (!MemberType.IsClass){
5340 Type vt = MemberType;
5342 if (TypeManager.IsEnumType (vt))
5343 vt = TypeManager.EnumToUnderlying (MemberType);
5345 if (!((vt == TypeManager.bool_type) ||
5346 (vt == TypeManager.sbyte_type) ||
5347 (vt == TypeManager.byte_type) ||
5348 (vt == TypeManager.short_type) ||
5349 (vt == TypeManager.ushort_type) ||
5350 (vt == TypeManager.int32_type) ||
5351 (vt == TypeManager.uint32_type) ||
5352 (vt == TypeManager.char_type) ||
5353 (vt == TypeManager.float_type) ||
5354 (!vt.IsValueType))){
5356 677, Location, Parent.MakeName (Name) +
5357 " A volatile field can not be of type `" +
5358 TypeManager.CSharpName (vt) + "'");
5363 if ((ModFlags & Modifiers.READONLY) != 0){
5366 "A field can not be both volatile and readonly");
5371 FieldAttributes fa = Modifiers.FieldAttr (ModFlags);
5373 if (Parent.Kind == Kind.Struct &&
5374 ((fa & FieldAttributes.Static) == 0) &&
5375 MemberType == Parent.TypeBuilder &&
5376 !TypeManager.IsBuiltinType (MemberType)){
5377 Report.Error (523, Location, "Struct member `" + Parent.Name + "." + Name +
5378 "' causes a cycle in the structure layout");
5383 FieldBuilder = Parent.TypeBuilder.DefineField (
5384 Name, MemberType, Modifiers.FieldAttr (ModFlags));
5386 TypeManager.RegisterFieldBase (FieldBuilder, this);
5388 catch (ArgumentException) {
5389 Report.Warning (-24, Location, "The Microsoft runtime is unable to use [void|void*] as a field type, try using the Mono runtime.");
5396 public override void Emit ()
5398 if (OptAttributes != null) {
5399 EmitContext ec = new EmitContext (
5400 Parent, Location, null, FieldBuilder.FieldType,
5402 OptAttributes.Emit (ec, this);
5410 // `set' and `get' accessors are represented with an Accessor.
5412 public class Accessor {
5414 // Null if the accessor is empty, or a Block if not
5416 public const int AllowedModifiers =
5418 Modifiers.PROTECTED |
5419 Modifiers.INTERNAL |
5422 public ToplevelBlock Block;
5423 public Attributes Attributes;
5424 public Location Location;
5425 public int ModFlags;
5427 public Accessor (ToplevelBlock b, int mod, Attributes attrs, Location loc)
5432 ModFlags = Modifiers.Check (AllowedModifiers, mod, 0, loc);
5437 // Ooouh Martin, templates are missing here.
5438 // When it will be possible move here a lot of child code and template method type.
5439 public abstract class AbstractPropertyEventMethod: MemberCore, IMethodData {
5440 protected MethodData method_data;
5441 protected ToplevelBlock block;
5442 protected ListDictionary declarative_security;
5444 // The accessor are created event if they are not wanted.
5445 // But we need them because their names are reserved.
5446 // Field says whether accessor will be emited or not
5447 public readonly bool IsDummy;
5449 protected readonly string prefix;
5451 ReturnParameter return_attributes;
5453 public AbstractPropertyEventMethod (MemberBase member, string prefix)
5454 : base (null, SetupName (prefix, member), null, member.Location)
5456 this.prefix = prefix;
5460 public AbstractPropertyEventMethod (MemberBase member, Accessor accessor,
5462 : base (null, SetupName (prefix, member),
5463 accessor.Attributes, accessor.Location)
5465 this.prefix = prefix;
5466 this.block = accessor.Block;
5469 static MemberName SetupName (string prefix, MemberBase member)
5471 MemberName name = member.MemberName.Clone ();
5472 name.Name = prefix + member.ShortName;
5476 public void UpdateName (MemberBase member)
5478 MemberName.Name = prefix + member.ShortName;
5481 #region IMethodData Members
5483 public ToplevelBlock Block {
5493 public CallingConventions CallingConventions {
5495 return CallingConventions.Standard;
5499 public bool IsExcluded (EmitContext ec)
5504 public MemberName MethodName {
5510 public abstract ObsoleteAttribute GetObsoleteAttribute ();
5511 public abstract Type[] ParameterTypes { get; }
5512 public abstract Type ReturnType { get; }
5513 public abstract EmitContext CreateEmitContext(TypeContainer tc, ILGenerator ig);
5517 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
5519 if (a.Type == TypeManager.cls_compliant_attribute_type || a.Type == TypeManager.obsolete_attribute_type ||
5520 a.Type == TypeManager.conditional_attribute_type) {
5521 Report.Error (1667, a.Location, "'{0}' is not valid on property or event accessors. It is valid on {1} declarations only", TypeManager.CSharpName (a.Type), a.GetValidTargets ());
5525 if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
5526 if (declarative_security == null)
5527 declarative_security = new ListDictionary ();
5528 a.ExtractSecurityPermissionSet (declarative_security);
5532 if (a.Target == AttributeTargets.Method) {
5533 method_data.MethodBuilder.SetCustomAttribute (cb);
5537 if (a.Target == AttributeTargets.ReturnValue) {
5538 if (return_attributes == null)
5539 return_attributes = new ReturnParameter (method_data.MethodBuilder, Location);
5541 return_attributes.ApplyAttributeBuilder (a, cb);
5545 ApplyToExtraTarget (a, cb);
5548 virtual protected void ApplyToExtraTarget (Attribute a, CustomAttributeBuilder cb)
5550 System.Diagnostics.Debug.Fail ("You forgot to define special attribute target handling");
5553 public override bool Define()
5555 throw new NotSupportedException ();
5558 public virtual void Emit (TypeContainer container)
5560 method_data.Emit (container, this);
5562 if (declarative_security != null) {
5563 foreach (DictionaryEntry de in declarative_security) {
5564 method_data.MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
5571 public override bool IsClsCompliaceRequired(DeclSpace ds)
5576 public bool IsDuplicateImplementation (MethodCore method)
5578 if (Name != method.Name)
5581 Type[] param_types = method.ParameterTypes;
5583 if (param_types.Length != ParameterTypes.Length)
5586 for (int i = 0; i < param_types.Length; i++)
5587 if (param_types [i] != ParameterTypes [i])
5590 Report.SymbolRelatedToPreviousError (method);
5591 Report.Error (111, Location, TypeContainer.Error111, method.Parent.GetSignatureForError (), Name);
5595 public new Location Location {
5597 return base.Location;
5602 // Represents header string for documentation comment.
5604 public override string DocCommentHeader {
5605 get { throw new InvalidOperationException ("Unexpected attempt to get doc comment from " + this.GetType () + "."); }
5608 protected override void VerifyObsoleteAttribute()
5615 // Properties and Indexers both generate PropertyBuilders, we use this to share
5616 // their common bits.
5618 abstract public class PropertyBase : MethodCore {
5620 public class GetMethod: PropertyMethod
5622 static string[] attribute_targets = new string [] { "method", "return" };
5624 public GetMethod (MethodCore method):
5625 base (method, "get_")
5629 public GetMethod (MethodCore method, Accessor accessor):
5630 base (method, accessor, "get_")
5634 public override MethodBuilder Define(TypeContainer container)
5636 base.Define (container);
5638 method_data = new MethodData (method, method.ParameterInfo, ModFlags, flags, this);
5640 if (!method_data.Define (container))
5643 return method_data.MethodBuilder;
5646 public override string GetSignatureForError (TypeContainer tc)
5648 return String.Concat (base.GetSignatureForError (tc), ".get");
5651 public override Type ReturnType {
5653 return method.MemberType;
5657 public override string[] ValidAttributeTargets {
5659 return attribute_targets;
5664 public class SetMethod: PropertyMethod {
5666 static string[] attribute_targets = new string [] { "method", "param", "return" };
5667 ImplicitParameter param_attr;
5669 public SetMethod (MethodCore method):
5670 base (method, "set_")
5674 public SetMethod (MethodCore method, Accessor accessor):
5675 base (method, accessor, "set_")
5679 protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
5681 if (a.Target == AttributeTargets.Parameter) {
5682 if (param_attr == null)
5683 param_attr = new ImplicitParameter (method_data.MethodBuilder);
5685 param_attr.ApplyAttributeBuilder (a, cb);
5689 base.ApplyAttributeBuilder (a, cb);
5692 protected virtual InternalParameters GetParameterInfo (EmitContext ec)
5694 Parameter [] parms = new Parameter [1];
5695 parms [0] = new Parameter (method.Type, "value", Parameter.Modifier.NONE, null);
5696 Parameters parameters = new Parameters (parms, null, method.Location);
5697 Type [] types = parameters.GetParameterInfo (ec);
5698 return new InternalParameters (types, parameters);
5701 public override MethodBuilder Define(TypeContainer container)
5703 if (container.EmitContext == null)
5704 throw new InternalErrorException ("SetMethod.Define called too early");
5706 base.Define (container);
5708 method_data = new MethodData (method, GetParameterInfo (container.EmitContext), ModFlags, flags, this);
5710 if (!method_data.Define (container))
5713 return method_data.MethodBuilder;
5716 public override string GetSignatureForError (TypeContainer tc)
5718 return String.Concat (base.GetSignatureForError (tc), ".set");
5721 public override Type[] ParameterTypes {
5723 return new Type[] { method.MemberType };
5727 public override Type ReturnType {
5729 return TypeManager.void_type;
5733 public override string[] ValidAttributeTargets {
5735 return attribute_targets;
5740 static string[] attribute_targets = new string [] { "property" };
5742 public abstract class PropertyMethod: AbstractPropertyEventMethod
5744 protected readonly MethodCore method;
5745 protected MethodAttributes flags;
5747 public PropertyMethod (MethodCore method, string prefix)
5748 : base (method, prefix)
5750 this.method = method;
5753 public PropertyMethod (MethodCore method, Accessor accessor,
5755 : base (method, accessor, prefix)
5757 this.method = method;
5758 this.ModFlags = accessor.ModFlags;
5760 if (accessor.ModFlags != 0 && RootContext.Version == LanguageVersion.ISO_1) {
5761 Report.FeatureIsNotStandardized (Location, "accessor modifiers");
5762 Environment.Exit (1);
5766 public override AttributeTargets AttributeTargets {
5768 return AttributeTargets.Method;
5772 public override bool IsClsCompliaceRequired(DeclSpace ds)
5774 return method.IsClsCompliaceRequired (ds);
5777 public InternalParameters ParameterInfo
5780 return method_data.ParameterInfo;
5784 public virtual MethodBuilder Define (TypeContainer container)
5787 // Check for custom access modifier
5789 if (ModFlags == 0) {
5790 ModFlags = method.ModFlags;
5791 flags = method.flags;
5793 CheckModifiers (container, ModFlags);
5794 ModFlags |= (method.ModFlags & (~Modifiers.Accessibility));
5795 flags = Modifiers.MethodAttr (ModFlags);
5796 flags |= (method.flags & (~MethodAttributes.MemberAccessMask));
5803 public override Type[] ParameterTypes {
5805 return TypeManager.NoTypes;
5809 public override EmitContext CreateEmitContext (TypeContainer tc,
5812 return new EmitContext (
5813 tc, method.Parent, method.Location, ig, ReturnType,
5814 method.ModFlags, false);
5817 public override ObsoleteAttribute GetObsoleteAttribute ()
5819 return method.GetObsoleteAttribute (method.Parent);
5822 public override string GetSignatureForError (TypeContainer tc)
5824 return String.Concat (tc.Name, '.', method.Name);
5827 void CheckModifiers (TypeContainer container, int modflags)
5830 int mflags = method.ModFlags & Modifiers.Accessibility;
5832 if ((mflags & Modifiers.PUBLIC) != 0) {
5833 flags |= Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE;
5835 else if ((mflags & Modifiers.PROTECTED) != 0) {
5836 if ((mflags & Modifiers.INTERNAL) != 0)
5837 flags |= Modifiers.PROTECTED | Modifiers.INTERNAL;
5839 flags |= Modifiers.PRIVATE;
5841 else if ((mflags & Modifiers.INTERNAL) != 0)
5842 flags |= Modifiers.PRIVATE;
5844 if ((mflags == modflags) || (modflags & (~flags)) != 0)
5845 Report.Error (273, Location, "{0}: accessibility modifier must be more restrictive than the property or indexer",
5846 GetSignatureForError (container));
5852 public PropertyMethod Get, Set;
5853 public PropertyBuilder PropertyBuilder;
5854 public MethodBuilder GetBuilder, SetBuilder;
5856 protected EmitContext ec;
5858 public PropertyBase (TypeContainer ds, Expression type, int mod_flags,
5859 int allowed_mod, bool is_iface, MemberName name,
5860 Parameters parameters, Attributes attrs,
5862 : base (ds, type, mod_flags, allowed_mod, is_iface, name,
5863 attrs, parameters, loc)
5867 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
5869 if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
5870 a.Error_InvalidSecurityParent ();
5874 PropertyBuilder.SetCustomAttribute (cb);
5877 public override AttributeTargets AttributeTargets {
5879 return AttributeTargets.Property;
5883 public override bool Define ()
5888 if (!IsTypePermitted ())
5894 protected override bool DoDefine ()
5896 if (!base.DoDefine ())
5900 // Accessors modifiers check
5902 if (Get.ModFlags != 0 && Set.ModFlags != 0) {
5903 Report.Error (274, Location, "'{0}': cannot specify accessibility modifiers for both accessors of the property or indexer.",
5904 GetSignatureForError ());
5908 if ((Get.IsDummy || Set.IsDummy)
5909 && (Get.ModFlags != 0 || Set.ModFlags != 0) && (ModFlags & Modifiers.OVERRIDE) == 0) {
5910 Report.Error (276, Location,
5911 "'{0}': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor.",
5912 GetSignatureForError ());
5916 if (MemberType.IsAbstract && MemberType.IsSealed) {
5917 Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
5921 ec = new EmitContext (Parent, Location, null, MemberType, ModFlags);
5925 public override string GetSignatureForError()
5927 if (PropertyBuilder == null)
5928 return GetSignatureForError (Parent);
5930 return TypeManager.CSharpSignature (PropertyBuilder, false);
5934 protected override bool CheckForDuplications ()
5936 ArrayList ar = Parent.Indexers;
5938 int arLen = ar.Count;
5940 for (int i = 0; i < arLen; i++) {
5941 Indexer m = (Indexer) ar [i];
5942 if (IsDuplicateImplementation (m))
5947 ar = Parent.Properties;
5949 int arLen = ar.Count;
5951 for (int i = 0; i < arLen; i++) {
5952 Property m = (Property) ar [i];
5953 if (IsDuplicateImplementation (m))
5961 // TODO: rename to Resolve......
5962 protected override MethodInfo FindOutParentMethod (TypeContainer container, ref Type parent_ret_type)
5964 PropertyInfo parent_property = container.ParentCache.FindMemberToOverride (
5965 container.TypeBuilder, Name, ParameterTypes, true) as PropertyInfo;
5967 if (parent_property == null)
5970 parent_ret_type = parent_property.PropertyType;
5971 MethodInfo get_accessor = parent_property.GetGetMethod (true);
5972 MethodInfo set_accessor = parent_property.GetSetMethod (true);
5973 MethodAttributes get_accessor_access, set_accessor_access;
5975 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
5976 if (Get != null && !Get.IsDummy && get_accessor == null) {
5977 Report.SymbolRelatedToPreviousError (parent_property);
5978 Report.Error (545, Location, "'{0}': cannot override because '{1}' does not have an overridable get accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (parent_property));
5981 if (Set != null && !Set.IsDummy && set_accessor == null) {
5982 Report.SymbolRelatedToPreviousError (parent_property);
5983 Report.Error (546, Location, "'{0}': cannot override because '{1}' does not have an overridable set accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (parent_property));
5988 // Check parent accessors access
5990 get_accessor_access = set_accessor_access = 0;
5991 if ((ModFlags & Modifiers.NEW) == 0) {
5992 if (get_accessor != null) {
5993 MethodAttributes get_flags = Modifiers.MethodAttr (Get.ModFlags != 0 ? Get.ModFlags : ModFlags);
5994 get_accessor_access = (get_accessor.Attributes & MethodAttributes.MemberAccessMask);
5996 if (!Get.IsDummy && !CheckAccessModifiers (get_flags & MethodAttributes.MemberAccessMask, get_accessor_access, get_accessor))
5997 Report.Error (507, Location, "'{0}' can't change the access modifiers when overriding inherited member '{1}'",
5998 GetSignatureForError (), TypeManager.GetFullNameSignature (parent_property));
6001 if (set_accessor != null) {
6002 MethodAttributes set_flags = Modifiers.MethodAttr (Set.ModFlags != 0 ? Set.ModFlags : ModFlags);
6003 set_accessor_access = (set_accessor.Attributes & MethodAttributes.MemberAccessMask);
6005 if (!Set.IsDummy && !CheckAccessModifiers (set_flags & MethodAttributes.MemberAccessMask, set_accessor_access, set_accessor))
6006 Report.Error (507, Location, "'{0}' can't change the access modifiers when overriding inherited member '{1}'",
6007 GetSignatureForError (container), TypeManager.GetFullNameSignature (parent_property));
6012 // Get the less restrictive access
6014 return get_accessor_access > set_accessor_access ? get_accessor : set_accessor;
6017 public override void Emit ()
6020 // The PropertyBuilder can be null for explicit implementations, in that
6021 // case, we do not actually emit the ".property", so there is nowhere to
6022 // put the attribute
6024 if (PropertyBuilder != null && OptAttributes != null)
6025 OptAttributes.Emit (ec, this);
6037 /// Tests whether accessors are not in collision with some method (CS0111)
6039 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
6041 return Get.IsDuplicateImplementation (mc) || Set.IsDuplicateImplementation (mc);
6044 protected override void UpdateMemberName ()
6046 base.UpdateMemberName ();
6048 Get.UpdateName (this);
6049 Set.UpdateName (this);
6053 public override string[] ValidAttributeTargets {
6055 return attribute_targets;
6060 // Represents header string for documentation comment.
6062 public override string DocCommentHeader {
6063 get { return "P:"; }
6067 public class Property : PropertyBase, IIteratorContainer {
6068 const int AllowedModifiers =
6071 Modifiers.PROTECTED |
6072 Modifiers.INTERNAL |
6076 Modifiers.OVERRIDE |
6077 Modifiers.ABSTRACT |
6080 Modifiers.METHOD_YIELDS |
6083 const int AllowedInterfaceModifiers =
6086 public Property (TypeContainer ds, Expression type, int mod, bool is_iface,
6087 MemberName name, Attributes attrs, Accessor get_block,
6088 Accessor set_block, Location loc)
6089 : base (ds, type, mod,
6090 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
6091 is_iface, name, Parameters.EmptyReadOnlyParameters, attrs,
6094 if (get_block == null)
6095 Get = new GetMethod (this);
6097 Get = new GetMethod (this, get_block);
6099 if (set_block == null)
6100 Set = new SetMethod (this);
6102 Set = new SetMethod (this, set_block);
6105 public override bool Define ()
6107 if (!base.Define ())
6113 flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
6117 GetBuilder = Get.Define (Parent);
6118 if (GetBuilder == null)
6122 // Setup iterator if we are one
6124 if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
6125 Iterator iterator = new Iterator (
6126 Parent, "get", MemberType,
6127 TypeManager.NoTypes, Get.ParameterInfo,
6128 ModFlags, Get.Block, Location);
6130 if (!iterator.DefineIterator ())
6132 Get.Block = iterator.Block;
6137 SetBuilder = Set.Define (Parent);
6138 if (SetBuilder == null)
6141 SetBuilder.DefineParameter (1, ParameterAttributes.None, "value");
6144 // FIXME - PropertyAttributes.HasDefault ?
6146 PropertyAttributes prop_attr = PropertyAttributes.None;
6148 prop_attr |= PropertyAttributes.RTSpecialName |
6149 PropertyAttributes.SpecialName;
6151 PropertyBuilder = Parent.TypeBuilder.DefineProperty (
6152 Name, prop_attr, MemberType, null);
6155 PropertyBuilder.SetGetMethod (GetBuilder);
6158 PropertyBuilder.SetSetMethod (SetBuilder);
6160 TypeManager.RegisterProperty (PropertyBuilder, GetBuilder, SetBuilder);
6164 public void SetYields ()
6166 ModFlags |= Modifiers.METHOD_YIELDS;
6171 /// Gigantic workaround for lameness in SRE follows :
6172 /// This class derives from EventInfo and attempts to basically
6173 /// wrap around the EventBuilder so that FindMembers can quickly
6174 /// return this in it search for members
6176 public class MyEventBuilder : EventInfo {
6179 // We use this to "point" to our Builder which is
6180 // not really a MemberInfo
6182 EventBuilder MyBuilder;
6185 // We "catch" and wrap these methods
6187 MethodInfo raise, remove, add;
6189 EventAttributes attributes;
6190 Type declaring_type, reflected_type, event_type;
6195 public MyEventBuilder (Event ev, TypeBuilder type_builder, string name, EventAttributes event_attr, Type event_type)
6197 MyBuilder = type_builder.DefineEvent (name, event_attr, event_type);
6199 // And now store the values in our own fields.
6201 declaring_type = type_builder;
6203 reflected_type = type_builder;
6205 attributes = event_attr;
6208 this.event_type = event_type;
6212 // Methods that you have to override. Note that you only need
6213 // to "implement" the variants that take the argument (those are
6214 // the "abstract" methods, the others (GetAddMethod()) are
6217 public override MethodInfo GetAddMethod (bool nonPublic)
6222 public override MethodInfo GetRemoveMethod (bool nonPublic)
6227 public override MethodInfo GetRaiseMethod (bool nonPublic)
6233 // These methods make "MyEventInfo" look like a Builder
6235 public void SetRaiseMethod (MethodBuilder raiseMethod)
6237 raise = raiseMethod;
6238 MyBuilder.SetRaiseMethod (raiseMethod);
6241 public void SetRemoveOnMethod (MethodBuilder removeMethod)
6243 remove = removeMethod;
6244 MyBuilder.SetRemoveOnMethod (removeMethod);
6247 public void SetAddOnMethod (MethodBuilder addMethod)
6250 MyBuilder.SetAddOnMethod (addMethod);
6253 public void SetCustomAttribute (CustomAttributeBuilder cb)
6255 MyBuilder.SetCustomAttribute (cb);
6258 public override object [] GetCustomAttributes (bool inherit)
6260 // FIXME : There's nothing which can be seemingly done here because
6261 // we have no way of getting at the custom attribute objects of the
6266 public override object [] GetCustomAttributes (Type t, bool inherit)
6268 // FIXME : Same here !
6272 public override bool IsDefined (Type t, bool b)
6277 public override EventAttributes Attributes {
6283 public override string Name {
6289 public override Type DeclaringType {
6291 return declaring_type;
6295 public override Type ReflectedType {
6297 return reflected_type;
6301 public Type EventType {
6307 public void SetUsed ()
6309 if (my_event != null)
6310 my_event.status = (FieldBase.Status.ASSIGNED | FieldBase.Status.USED);
6315 /// For case when event is declared like property (with add and remove accessors).
6317 public class EventProperty: Event {
6319 static string[] attribute_targets = new string [] { "event", "property" };
6321 public EventProperty (TypeContainer parent, Expression type, int mod_flags,
6322 bool is_iface, MemberName name, Object init,
6323 Attributes attrs, Accessor add, Accessor remove,
6325 : base (parent, type, mod_flags, is_iface, name, init, attrs, loc)
6327 Add = new AddDelegateMethod (this, add);
6328 Remove = new RemoveDelegateMethod (this, remove);
6330 // For this event syntax we don't report error CS0067
6331 // because it is hard to do it.
6335 public override string[] ValidAttributeTargets {
6337 return attribute_targets;
6343 /// Event is declared like field.
6345 public class EventField: Event {
6347 static string[] attribute_targets = new string [] { "event", "field", "method" };
6348 static string[] attribute_targets_interface = new string[] { "event", "method" };
6350 public EventField (TypeContainer parent, Expression type, int mod_flags,
6351 bool is_iface, MemberName name, Object init,
6352 Attributes attrs, Location loc)
6353 : base (parent, type, mod_flags, is_iface, name, init, attrs, loc)
6355 Add = new AddDelegateMethod (this);
6356 Remove = new RemoveDelegateMethod (this);
6359 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
6361 if (a.Target == AttributeTargets.Field) {
6362 FieldBuilder.SetCustomAttribute (cb);
6366 if (a.Target == AttributeTargets.Method) {
6367 Add.ApplyAttributeBuilder (a, cb);
6368 Remove.ApplyAttributeBuilder (a, cb);
6372 base.ApplyAttributeBuilder (a, cb);
6375 public override string[] ValidAttributeTargets {
6377 return IsInterface ? attribute_targets_interface : attribute_targets;
6382 public abstract class Event : FieldBase {
6384 protected sealed class AddDelegateMethod: DelegateMethod
6387 public AddDelegateMethod (Event method):
6388 base (method, "add_")
6392 public AddDelegateMethod (Event method, Accessor accessor):
6393 base (method, accessor, "add_")
6397 protected override MethodInfo DelegateMethodInfo {
6399 return TypeManager.delegate_combine_delegate_delegate;
6405 protected sealed class RemoveDelegateMethod: DelegateMethod
6407 public RemoveDelegateMethod (Event method):
6408 base (method, "remove_")
6412 public RemoveDelegateMethod (Event method, Accessor accessor):
6413 base (method, accessor, "remove_")
6417 protected override MethodInfo DelegateMethodInfo {
6419 return TypeManager.delegate_remove_delegate_delegate;
6425 public abstract class DelegateMethod: AbstractPropertyEventMethod
6427 protected readonly Event method;
6428 ImplicitParameter param_attr;
6430 static string[] attribute_targets = new string [] { "method", "param", "return" };
6432 public DelegateMethod (Event method, string prefix)
6433 : base (method, prefix)
6435 this.method = method;
6438 public DelegateMethod (Event method, Accessor accessor, string prefix)
6439 : base (method, accessor, prefix)
6441 this.method = method;
6444 protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
6446 if (a.Target == AttributeTargets.Parameter) {
6447 if (param_attr == null)
6448 param_attr = new ImplicitParameter (method_data.MethodBuilder);
6450 param_attr.ApplyAttributeBuilder (a, cb);
6454 base.ApplyAttributeBuilder (a, cb);
6457 public override AttributeTargets AttributeTargets {
6459 return AttributeTargets.Method;
6463 public override bool IsClsCompliaceRequired(DeclSpace ds)
6465 return method.IsClsCompliaceRequired (ds);
6468 public MethodBuilder Define (TypeContainer container, InternalParameters ip)
6470 method_data = new MethodData (method, ip, method.ModFlags,
6471 method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this);
6473 if (!method_data.Define (container))
6476 MethodBuilder mb = method_data.MethodBuilder;
6477 mb.DefineParameter (1, ParameterAttributes.None, "value");
6482 public override void Emit (TypeContainer tc)
6484 if (block != null) {
6489 ILGenerator ig = method_data.MethodBuilder.GetILGenerator ();
6490 EmitContext ec = CreateEmitContext (tc, ig);
6491 FieldInfo field_info = (FieldInfo)method.FieldBuilder;
6493 method_data.MethodBuilder.SetImplementationFlags (MethodImplAttributes.Synchronized);
6494 if ((method.ModFlags & Modifiers.STATIC) != 0) {
6495 ig.Emit (OpCodes.Ldsfld, field_info);
6496 ig.Emit (OpCodes.Ldarg_0);
6497 ig.Emit (OpCodes.Call, DelegateMethodInfo);
6498 ig.Emit (OpCodes.Castclass, method.MemberType);
6499 ig.Emit (OpCodes.Stsfld, field_info);
6501 ig.Emit (OpCodes.Ldarg_0);
6502 ig.Emit (OpCodes.Ldarg_0);
6503 ig.Emit (OpCodes.Ldfld, field_info);
6504 ig.Emit (OpCodes.Ldarg_1);
6505 ig.Emit (OpCodes.Call, DelegateMethodInfo);
6506 ig.Emit (OpCodes.Castclass, method.MemberType);
6507 ig.Emit (OpCodes.Stfld, field_info);
6509 ig.Emit (OpCodes.Ret);
6512 protected abstract MethodInfo DelegateMethodInfo { get; }
6514 public override Type[] ParameterTypes {
6516 return new Type[] { method.MemberType };
6520 public override Type ReturnType {
6522 return TypeManager.void_type;
6526 public override EmitContext CreateEmitContext (TypeContainer tc,
6529 return new EmitContext (
6530 tc, method.Parent, Location, ig, ReturnType,
6531 method.ModFlags, false);
6534 public override string GetSignatureForError (TypeContainer tc)
6536 return String.Concat (tc.Name, '.', method.Name);
6539 public override ObsoleteAttribute GetObsoleteAttribute ()
6541 return method.GetObsoleteAttribute (method.Parent);
6544 public override string[] ValidAttributeTargets {
6546 return attribute_targets;
6552 const int AllowedModifiers =
6555 Modifiers.PROTECTED |
6556 Modifiers.INTERNAL |
6561 Modifiers.OVERRIDE |
6565 const int AllowedInterfaceModifiers =
6568 public DelegateMethod Add, Remove;
6569 public MyEventBuilder EventBuilder;
6570 public MethodBuilder AddBuilder, RemoveBuilder;
6572 public Event (TypeContainer parent, Expression type, int mod_flags,
6573 bool is_iface, MemberName name, Object init, Attributes attrs,
6575 : base (parent, type, mod_flags,
6576 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
6577 name, init, attrs, loc)
6579 IsInterface = is_iface;
6582 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
6584 if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
6585 a.Error_InvalidSecurityParent ();
6589 EventBuilder.SetCustomAttribute (cb);
6592 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
6594 return Add.IsDuplicateImplementation (mc) || Remove.IsDuplicateImplementation (mc);
6597 public override AttributeTargets AttributeTargets {
6599 return AttributeTargets.Event;
6603 public override bool Define ()
6605 EventAttributes e_attr;
6606 e_attr = EventAttributes.None;
6611 if (init != null && ((ModFlags & Modifiers.ABSTRACT) != 0)){
6612 Report.Error (74, Location, "'" + Parent.Name + "." + Name +
6613 "': abstract event can not have an initializer");
6617 if (!MemberType.IsSubclassOf (TypeManager.delegate_type)) {
6618 Report.Error (66, Location, "'" + Parent.Name + "." + Name +
6619 "' : event must be of a delegate type");
6623 EmitContext ec = Parent.EmitContext;
6625 throw new InternalErrorException ("Event.Define called too early?");
6626 bool old_unsafe = ec.InUnsafe;
6627 ec.InUnsafe = InUnsafe;
6629 Parameter [] parms = new Parameter [1];
6630 parms [0] = new Parameter (Type, "value", Parameter.Modifier.NONE, null);
6631 Parameters parameters = new Parameters (parms, null, Location);
6632 Type [] types = parameters.GetParameterInfo (ec);
6633 InternalParameters ip = new InternalParameters (types, parameters);
6635 ec.InUnsafe = old_unsafe;
6641 // Now define the accessors
6644 AddBuilder = Add.Define (Parent, ip);
6645 if (AddBuilder == null)
6648 RemoveBuilder = Remove.Define (Parent, ip);
6649 if (RemoveBuilder == null)
6652 EventBuilder = new MyEventBuilder (this, Parent.TypeBuilder, Name, e_attr, MemberType);
6654 if (Add.Block == null && Remove.Block == null && !IsInterface) {
6655 FieldBuilder = Parent.TypeBuilder.DefineField (
6657 FieldAttributes.Private | ((ModFlags & Modifiers.STATIC) != 0 ? FieldAttributes.Static : 0));
6658 TypeManager.RegisterPrivateFieldOfEvent (
6659 (EventInfo) EventBuilder, FieldBuilder);
6660 TypeManager.RegisterFieldBase (FieldBuilder, this);
6663 EventBuilder.SetAddOnMethod (AddBuilder);
6664 EventBuilder.SetRemoveOnMethod (RemoveBuilder);
6666 TypeManager.RegisterEvent (EventBuilder, AddBuilder, RemoveBuilder);
6670 protected override bool CheckBase ()
6672 if (!base.CheckBase ())
6675 if (conflict_symbol != null && (ModFlags & Modifiers.NEW) == 0) {
6676 if (!(conflict_symbol is EventInfo)) {
6677 Report.SymbolRelatedToPreviousError (conflict_symbol);
6678 Report.Error (72, Location, "Event '{0}' can override only event", GetSignatureForError (Parent));
6686 public override void Emit ()
6688 if (OptAttributes != null) {
6689 EmitContext ec = new EmitContext (
6690 Parent, Location, null, MemberType, ModFlags);
6691 OptAttributes.Emit (ec, this);
6696 Remove.Emit (Parent);
6702 public override string GetSignatureForError ()
6704 if (EventBuilder == null)
6705 return base.GetSignatureForError (Parent);
6707 return TypeManager.GetFullNameSignature (EventBuilder);
6711 // Represents header string for documentation comment.
6713 public override string DocCommentHeader {
6714 get { return "E:"; }
6719 public class Indexer : PropertyBase {
6721 class GetIndexerMethod: GetMethod
6723 public GetIndexerMethod (MethodCore method):
6728 public GetIndexerMethod (MethodCore method, Accessor accessor):
6729 base (method, accessor)
6733 public override Type[] ParameterTypes {
6735 return method.ParameterTypes;
6740 class SetIndexerMethod: SetMethod
6742 readonly Parameters parameters;
6744 public SetIndexerMethod (MethodCore method):
6749 public SetIndexerMethod (MethodCore method, Parameters parameters, Accessor accessor):
6750 base (method, accessor)
6752 this.parameters = parameters;
6755 public override Type[] ParameterTypes {
6757 int top = method.ParameterTypes.Length;
6758 Type [] set_pars = new Type [top + 1];
6759 method.ParameterTypes.CopyTo (set_pars, 0);
6760 set_pars [top] = method.MemberType;
6765 protected override InternalParameters GetParameterInfo (EmitContext ec)
6767 Parameter [] fixed_parms = parameters.FixedParameters;
6769 if (fixed_parms == null){
6770 throw new Exception ("We currently do not support only array arguments in an indexer at: " + method.Location);
6771 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
6772 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
6774 // Here is the problem: the `value' parameter has
6775 // to come *after* the array parameter in the declaration
6777 // X (object [] x, Type value)
6780 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
6781 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
6785 Parameter [] tmp = new Parameter [fixed_parms.Length + 1];
6787 fixed_parms.CopyTo (tmp, 0);
6788 tmp [fixed_parms.Length] = new Parameter (
6789 method.Type, "value", Parameter.Modifier.NONE, null);
6791 Parameters set_formal_params = new Parameters (tmp, null, method.Location);
6792 Type [] types = set_formal_params.GetParameterInfo (ec);
6794 return new InternalParameters (types, set_formal_params);
6799 const int AllowedModifiers =
6802 Modifiers.PROTECTED |
6803 Modifiers.INTERNAL |
6807 Modifiers.OVERRIDE |
6812 const int AllowedInterfaceModifiers =
6816 public Indexer (TypeContainer ds, Expression type, MemberName name, int mod,
6817 bool is_iface, Parameters parameters, Attributes attrs,
6818 Accessor get_block, Accessor set_block, Location loc)
6819 : base (ds, type, mod,
6820 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
6821 is_iface, name, parameters, attrs, loc)
6823 if (get_block == null)
6824 Get = new GetIndexerMethod (this);
6826 Get = new GetIndexerMethod (this, get_block);
6828 if (set_block == null)
6829 Set = new SetIndexerMethod (this);
6831 Set = new SetIndexerMethod (this, parameters, set_block);
6834 public override bool Define ()
6836 PropertyAttributes prop_attr =
6837 PropertyAttributes.RTSpecialName |
6838 PropertyAttributes.SpecialName;
6840 if (!base.Define ())
6843 if (OptAttributes != null) {
6844 Attribute indexer_attr = OptAttributes.Search (TypeManager.indexer_name_type, ec);
6845 if (indexer_attr != null) {
6846 // Remove the attribute from the list because it is not emitted
6847 OptAttributes.Attrs.Remove (indexer_attr);
6849 ShortName = indexer_attr.GetIndexerAttributeValue (ec);
6851 if (IsExplicitImpl) {
6852 Report.Error (415, indexer_attr.Location,
6853 "The 'IndexerName' attribute is valid only on an" +
6854 "indexer that is not an explicit interface member declaration");
6858 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
6859 Report.Error (609, indexer_attr.Location,
6860 "Cannot set the 'IndexerName' attribute on an indexer marked override");
6864 if (!Tokenizer.IsValidIdentifier (ShortName)) {
6865 Report.Error (633, indexer_attr.Location,
6866 "The argument to the 'IndexerName' attribute must be a valid identifier");
6870 UpdateMemberName ();
6874 if (InterfaceType != null) {
6875 string parent_IndexerName = TypeManager.IndexerPropertyName (InterfaceType);
6876 if (parent_IndexerName != Name)
6877 ShortName = parent_IndexerName;
6878 UpdateMemberName ();
6881 if (!Parent.AddToMemberContainer (this, true) ||
6882 !Parent.AddToMemberContainer (Get, true) || !Parent.AddToMemberContainer (Set, true))
6888 flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
6890 GetBuilder = Get.Define (Parent);
6891 if (GetBuilder == null)
6896 SetBuilder = Set.Define (Parent);
6897 if (SetBuilder == null)
6902 // Now name the parameters
6904 Parameter [] p = Parameters.FixedParameters;
6906 if ((p [0].ModFlags & Parameter.Modifier.ISBYREF) != 0) {
6907 Report.Error (631, Location, "ref and out are not valid in this context");
6913 for (i = 0; i < p.Length; ++i) {
6915 GetBuilder.DefineParameter (
6916 i + 1, p [i].Attributes, p [i].Name);
6919 SetBuilder.DefineParameter (
6920 i + 1, p [i].Attributes, p [i].Name);
6924 SetBuilder.DefineParameter (
6925 i + 1, ParameterAttributes.None, "value");
6927 if (i != ParameterTypes.Length) {
6928 Parameter array_param = Parameters.ArrayParameter;
6930 SetBuilder.DefineParameter (
6931 i + 1, array_param.Attributes, array_param.Name);
6935 PropertyBuilder = Parent.TypeBuilder.DefineProperty (
6936 Name, prop_attr, MemberType, ParameterTypes);
6939 PropertyBuilder.SetGetMethod (GetBuilder);
6942 PropertyBuilder.SetSetMethod (SetBuilder);
6944 TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder, ParameterTypes);
6949 public override string GetSignatureForError ()
6951 if (PropertyBuilder == null)
6952 return GetSignatureForError (Parent);
6954 return TypeManager.CSharpSignature (PropertyBuilder, true);
6957 public override string GetSignatureForError(TypeContainer tc)
6959 return String.Concat (tc.Name, ".this[", Parameters.FixedParameters [0].TypeName.ToString (), ']');
6963 public class Operator : MethodCore, IIteratorContainer {
6965 const int AllowedModifiers =
6971 public enum OpType : byte {
6981 // Unary and Binary operators
7004 // Implicit and Explicit
7009 public readonly OpType OperatorType;
7010 public MethodBuilder OperatorMethodBuilder;
7012 public Method OperatorMethod;
7014 static string[] attribute_targets = new string [] { "method", "return" };
7016 public Operator (TypeContainer parent, OpType type, Expression ret_type,
7017 int mod_flags, Parameters parameters,
7018 ToplevelBlock block, Attributes attrs, Location loc)
7019 : base (parent, ret_type, mod_flags, AllowedModifiers, false,
7020 new MemberName ("op_" + type), attrs, parameters, loc)
7022 OperatorType = type;
7026 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
7028 OperatorMethod.ApplyAttributeBuilder (a, cb);
7031 public override AttributeTargets AttributeTargets {
7033 return AttributeTargets.Method;
7037 protected override bool CheckForDuplications()
7039 ArrayList ar = Parent.Operators;
7041 int arLen = ar.Count;
7043 for (int i = 0; i < arLen; i++) {
7044 Operator o = (Operator) ar [i];
7045 if (IsDuplicateImplementation (o))
7050 ar = Parent.Methods;
7052 int arLen = ar.Count;
7054 for (int i = 0; i < arLen; i++) {
7055 Method m = (Method) ar [i];
7056 if (IsDuplicateImplementation (m))
7064 public override bool Define ()
7067 const int RequiredModifiers = Modifiers.PUBLIC | Modifiers.STATIC;
7068 if ((ModFlags & RequiredModifiers) != RequiredModifiers){
7069 Report.Error (558, Location, "User defined operators '{0}' must be declared static and public", GetSignatureForError (Parent));
7076 OperatorMethod = new Method (
7077 Parent, Type, ModFlags, false, MemberName,
7078 Parameters, OptAttributes, Location);
7080 OperatorMethod.Block = Block;
7081 OperatorMethod.IsOperator = true;
7082 OperatorMethod.flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
7083 OperatorMethod.Define ();
7085 if (OperatorMethod.MethodBuilder == null)
7088 OperatorMethodBuilder = OperatorMethod.MethodBuilder;
7090 parameter_types = OperatorMethod.ParameterTypes;
7091 Type declaring_type = OperatorMethodBuilder.DeclaringType;
7092 Type return_type = OperatorMethod.ReturnType;
7093 Type first_arg_type = parameter_types [0];
7098 // Rules for conversion operators
7100 if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
7101 if (first_arg_type == return_type && first_arg_type == declaring_type){
7104 "User-defined conversion cannot take an object of the " +
7105 "enclosing type and convert to an object of the enclosing" +
7110 if (first_arg_type != declaring_type && return_type != declaring_type){
7113 "User-defined conversion must convert to or from the " +
7118 if (first_arg_type == TypeManager.object_type ||
7119 return_type == TypeManager.object_type){
7122 "User-defined conversion cannot convert to or from " +
7127 if (first_arg_type.IsInterface || return_type.IsInterface){
7130 "User-defined conversion cannot convert to or from an " +
7135 if (first_arg_type.IsSubclassOf (return_type)
7136 || return_type.IsSubclassOf (first_arg_type)){
7137 if (declaring_type.IsSubclassOf (return_type)) {
7138 Report.Error (553, Location, "'{0}' : user defined conversion to/from base class", GetSignatureForError ());
7141 Report.Error (554, Location, "'{0}' : user defined conversion to/from derived class", GetSignatureForError ());
7144 } else if (OperatorType == OpType.LeftShift || OperatorType == OpType.RightShift) {
7145 if (first_arg_type != declaring_type || parameter_types [1] != TypeManager.int32_type) {
7146 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");
7149 } else if (Parameters.FixedParameters.Length == 1) {
7150 // Checks for Unary operators
7152 if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
7153 if (return_type != declaring_type && !return_type.IsSubclassOf (declaring_type)) {
7154 Report.Error (448, Location,
7155 "The return type for ++ or -- operator must be the containing type or derived from the containing type");
7158 if (first_arg_type != declaring_type) {
7160 559, Location, "The parameter type for ++ or -- operator must be the containing type");
7165 if (first_arg_type != declaring_type){
7168 "The parameter of a unary operator must be the " +
7173 if (OperatorType == OpType.True || OperatorType == OpType.False) {
7174 if (return_type != TypeManager.bool_type){
7177 "The return type of operator True or False " +
7184 // Checks for Binary operators
7186 if (first_arg_type != declaring_type &&
7187 parameter_types [1] != declaring_type){
7190 "One of the parameters of a binary operator must " +
7191 "be the containing type");
7199 public override void Emit ()
7202 // abstract or extern methods have no bodies
7204 if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
7207 OperatorMethod.Emit ();
7211 // Operator cannot be override
7212 protected override MethodInfo FindOutParentMethod (TypeContainer container, ref Type parent_ret_type)
7217 public static string GetName (OpType ot)
7220 case OpType.LogicalNot:
7222 case OpType.OnesComplement:
7224 case OpType.Increment:
7226 case OpType.Decrement:
7232 case OpType.Addition:
7234 case OpType.Subtraction:
7236 case OpType.UnaryPlus:
7238 case OpType.UnaryNegation:
7240 case OpType.Multiply:
7242 case OpType.Division:
7244 case OpType.Modulus:
7246 case OpType.BitwiseAnd:
7248 case OpType.BitwiseOr:
7250 case OpType.ExclusiveOr:
7252 case OpType.LeftShift:
7254 case OpType.RightShift:
7256 case OpType.Equality:
7258 case OpType.Inequality:
7260 case OpType.GreaterThan:
7262 case OpType.LessThan:
7264 case OpType.GreaterThanOrEqual:
7266 case OpType.LessThanOrEqual:
7268 case OpType.Implicit:
7270 case OpType.Explicit:
7276 public override string GetSignatureForError (TypeContainer tc)
7278 StringBuilder sb = new StringBuilder ();
7279 sb.AppendFormat ("{0}.operator {1} {2}({3}", tc.Name, GetName (OperatorType), Type.Type == null ? Type.ToString () : TypeManager.CSharpName (Type.Type),
7280 Parameters.FixedParameters [0].GetSignatureForError ());
7282 if (Parameters.FixedParameters.Length > 1) {
7284 sb.Append (Parameters.FixedParameters [1].GetSignatureForError ());
7287 return sb.ToString ();
7290 public override string GetSignatureForError ()
7295 public override string ToString ()
7297 if (OperatorMethod == null)
7300 Type return_type = OperatorMethod.ReturnType;
7301 Type [] param_types = OperatorMethod.ParameterTypes;
7303 if (Parameters.FixedParameters.Length == 1)
7304 return String.Format (
7305 "{0} operator {1}({2})",
7306 TypeManager.CSharpName (return_type),
7307 GetName (OperatorType),
7310 return String.Format (
7311 "{0} operator {1}({2}, {3})",
7312 TypeManager.CSharpName (return_type),
7313 GetName (OperatorType),
7314 param_types [0], param_types [1]);
7317 public override string[] ValidAttributeTargets {
7319 return attribute_targets;
7323 public void SetYields ()
7325 ModFlags |= Modifiers.METHOD_YIELDS;
7330 // This is used to compare method signatures
7332 struct MethodSignature {
7334 public Type RetType;
7335 public Type [] Parameters;
7338 /// This delegate is used to extract methods which have the
7339 /// same signature as the argument
7341 public static MemberFilter method_signature_filter = new MemberFilter (MemberSignatureCompare);
7343 public MethodSignature (string name, Type ret_type, Type [] parameters)
7348 if (parameters == null)
7349 Parameters = TypeManager.NoTypes;
7351 Parameters = parameters;
7354 public override string ToString ()
7357 if (Parameters.Length != 0){
7358 System.Text.StringBuilder sb = new System.Text.StringBuilder ();
7359 for (int i = 0; i < Parameters.Length; i++){
7360 sb.Append (Parameters [i]);
7361 if (i+1 < Parameters.Length)
7364 pars = sb.ToString ();
7367 return String.Format ("{0} {1} ({2})", RetType, Name, pars);
7370 public override int GetHashCode ()
7372 return Name.GetHashCode ();
7375 public override bool Equals (Object o)
7377 MethodSignature other = (MethodSignature) o;
7379 if (other.Name != Name)
7382 if (other.RetType != RetType)
7385 if (Parameters == null){
7386 if (other.Parameters == null)
7391 if (other.Parameters == null)
7394 int c = Parameters.Length;
7395 if (other.Parameters.Length != c)
7398 for (int i = 0; i < c; i++)
7399 if (other.Parameters [i] != Parameters [i])
7405 static bool MemberSignatureCompare (MemberInfo m, object filter_criteria)
7407 MethodSignature sig = (MethodSignature) filter_criteria;
7409 if (m.Name != sig.Name)
7413 MethodInfo mi = m as MethodInfo;
7414 PropertyInfo pi = m as PropertyInfo;
7417 ReturnType = mi.ReturnType;
7418 else if (pi != null)
7419 ReturnType = pi.PropertyType;
7424 // we use sig.RetType == null to mean `do not check the
7425 // method return value.
7427 if (sig.RetType != null)
7428 if (ReturnType != sig.RetType)
7433 args = TypeManager.GetArgumentTypes (mi);
7435 args = TypeManager.GetArgumentTypes (pi);
7436 Type [] sigp = sig.Parameters;
7438 if (args.Length != sigp.Length)
7441 for (int i = args.Length; i > 0; ){
7443 if (args [i] != sigp [i])