3 // class.cs: Class and Struct handlers
5 // Authors: Miguel de Icaza (miguel@gnu.org)
6 // Martin Baulig (martin@gnome.org)
8 // Licensed under the terms of the GNU GPL
10 // (C) 2001, 2002 Ximian, Inc (http://www.ximian.com)
15 using System.Collections;
16 using System.Reflection;
17 using System.Reflection.Emit;
18 using System.Runtime.CompilerServices;
19 using System.Diagnostics.SymbolStore;
21 namespace Mono.CSharp {
24 /// This is the base class for structs and classes.
26 public class TypeContainer : DeclSpace, IMemberFinder {
27 // Holds a list of classes and structures
30 // Holds the list of properties
33 // Holds the list of enumerations
36 // Holds the list of delegates
39 // Holds the list of constructors
40 ArrayList instance_constructors;
42 // Holds the list of fields
45 // Holds a list of fields that have initializers
46 ArrayList initialized_fields;
48 // Holds a list of static fields that have initializers
49 ArrayList initialized_static_fields;
51 // Holds the list of constants
57 // Holds order in which interfaces must be closed
58 ArrayList interface_order;
69 // Holds the operators
72 // The emit context for toplevel objects.
76 // Pointers to the default constructor and the default static constructor
78 Constructor default_constructor;
79 Constructor default_static_constructor;
82 // Whether we have seen a static constructor for this class or not
84 bool have_static_constructor = false;
87 // Whether we have at least one non-static field
89 bool have_nonstatic_fields = false;
92 // This one is computed after we can distinguish interfaces
93 // from classes from the arraylist `type_bases'
95 string base_class_name;
99 // Attributes for this type
100 protected Attributes attributes;
102 // Information in the case we are an attribute type
104 public AttributeTargets Targets = AttributeTargets.All;
105 public bool AllowMultiple = false;
106 public bool Inherited;
108 // The interfaces we implement.
112 // The indexer name for this class
114 public string IndexerName;
116 public TypeContainer (TypeContainer parent, string name, Location l)
117 : base (parent, name, l)
120 types = new ArrayList ();
127 base_class_name = null;
129 //Console.WriteLine ("New class " + name + " inside " + n);
132 public AdditionResult AddConstant (Const constant)
135 string name = constant.Name;
137 if ((res = IsValid (name)) != AdditionResult.Success)
140 if (constants == null)
141 constants = new ArrayList ();
143 constants.Add (constant);
144 DefineName (name, constant);
146 return AdditionResult.Success;
149 public AdditionResult AddEnum (Mono.CSharp.Enum e)
152 string name = e.Name;
154 if ((res = IsValid (name)) != AdditionResult.Success)
158 enums = new ArrayList ();
161 DefineName (name, e);
163 return AdditionResult.Success;
166 public AdditionResult AddClass (Class c)
169 string name = c.Name;
172 if ((res = IsValid (name)) != AdditionResult.Success)
175 DefineName (name, c);
178 return AdditionResult.Success;
181 public AdditionResult AddStruct (Struct s)
184 string name = s.Name;
186 if ((res = IsValid (name)) != AdditionResult.Success)
189 DefineName (name, s);
192 return AdditionResult.Success;
195 public AdditionResult AddDelegate (Delegate d)
198 string name = d.Name;
200 if ((res = IsValid (name)) != AdditionResult.Success)
203 if (delegates == null)
204 delegates = new ArrayList ();
206 DefineName (name, d);
209 return AdditionResult.Success;
212 public AdditionResult AddMethod (Method method)
214 string name = method.Name;
215 Object value = defined_names [name];
217 if (value != null && (!(value is Method)))
218 return AdditionResult.NameExists;
220 if (name == Basename)
221 return AdditionResult.EnclosingClash;
224 methods = new ArrayList ();
226 if (method.Name.IndexOf (".") != -1)
227 methods.Insert (0, method);
229 methods.Add (method);
232 DefineName (name, method);
234 return AdditionResult.Success;
237 public AdditionResult AddConstructor (Constructor c)
239 if (c.Name != Basename)
240 return AdditionResult.NotAConstructor;
242 bool is_static = (c.ModFlags & Modifiers.STATIC) != 0;
245 have_static_constructor = true;
246 if (default_static_constructor != null){
247 Console.WriteLine ("I have a static constructor already");
248 Console.WriteLine (" " + default_static_constructor);
249 return AdditionResult.MethodExists;
252 default_static_constructor = c;
255 if (default_constructor != null)
256 return AdditionResult.MethodExists;
257 default_constructor = c;
260 if (instance_constructors == null)
261 instance_constructors = new ArrayList ();
263 instance_constructors.Add (c);
266 return AdditionResult.Success;
269 public AdditionResult AddInterface (Interface iface)
272 string name = iface.Name;
274 if ((res = IsValid (name)) != AdditionResult.Success)
277 if (interfaces == null)
278 interfaces = new ArrayList ();
279 interfaces.Add (iface);
280 DefineName (name, iface);
282 return AdditionResult.Success;
285 public AdditionResult AddField (Field field)
288 string name = field.Name;
290 if ((res = IsValid (name)) != AdditionResult.Success)
294 fields = new ArrayList ();
298 if (field.HasInitializer){
299 if ((field.ModFlags & Modifiers.STATIC) != 0){
300 if (initialized_static_fields == null)
301 initialized_static_fields = new ArrayList ();
303 initialized_static_fields.Add (field);
306 // We have not seen a static constructor,
307 // but we will provide static initialization of fields
309 have_static_constructor = true;
311 if (initialized_fields == null)
312 initialized_fields = new ArrayList ();
314 initialized_fields.Add (field);
318 if ((field.ModFlags & Modifiers.STATIC) == 0)
319 have_nonstatic_fields = true;
321 DefineName (name, field);
322 return AdditionResult.Success;
325 public AdditionResult AddProperty (Property prop)
328 string name = prop.Name;
330 if ((res = IsValid (name)) != AdditionResult.Success)
333 if (properties == null)
334 properties = new ArrayList ();
336 if (prop.Name.IndexOf (".") != -1)
337 properties.Insert (0, prop);
339 properties.Add (prop);
340 DefineName (name, prop);
342 return AdditionResult.Success;
345 public AdditionResult AddEvent (Event e)
348 string name = e.Name;
350 if ((res = IsValid (name)) != AdditionResult.Success)
354 events = new ArrayList ();
357 DefineName (name, e);
359 return AdditionResult.Success;
362 public AdditionResult AddIndexer (Indexer i)
364 if (indexers == null)
365 indexers = new ArrayList ();
367 if (i.InterfaceType != null)
368 indexers.Insert (0, i);
372 return AdditionResult.Success;
375 public AdditionResult AddOperator (Operator op)
377 if (operators == null)
378 operators = new ArrayList ();
382 return AdditionResult.Success;
385 public void RegisterOrder (Interface iface)
387 if (interface_order == null)
388 interface_order = new ArrayList ();
390 interface_order.Add (iface);
393 public ArrayList Types {
399 public ArrayList Methods {
405 public ArrayList Constants {
411 public ArrayList Interfaces {
419 return base_class_name;
423 public ArrayList Bases {
433 public ArrayList Fields {
443 public ArrayList InstanceConstructors {
445 return instance_constructors;
449 public ArrayList Properties {
455 public ArrayList Events {
461 public ArrayList Enums {
467 public ArrayList Indexers {
473 public ArrayList Operators {
479 public ArrayList Delegates {
485 public Attributes OptAttributes {
491 public bool HaveStaticConstructor {
493 return have_static_constructor;
497 public virtual TypeAttributes TypeAttr {
499 return Modifiers.TypeAttr (ModFlags, this);
504 // Emits the instance field initializers
506 public bool EmitFieldInitializers (EmitContext ec)
509 ILGenerator ig = ec.ig;
510 Expression instance_expr;
513 fields = initialized_static_fields;
514 instance_expr = null;
516 fields = initialized_fields;
517 instance_expr = new This (Location.Null).Resolve (ec);
523 foreach (Field f in fields){
524 Expression e = f.GetInitializerExpression (ec);
528 Location l = f.Location;
529 FieldExpr fe = new FieldExpr (f.FieldBuilder, l);
530 fe.InstanceExpression = instance_expr;
531 Expression a = new Assign (fe, e, l);
537 if (a is ExpressionStatement)
538 ((ExpressionStatement) a).EmitStatement (ec);
540 throw new Exception ("Assign.Resolve returned a non ExpressionStatement");
548 // Defines the default constructors
550 void DefineDefaultConstructor (bool is_static)
555 c = new Constructor (Basename, Parameters.EmptyReadOnlyParameters,
556 new ConstructorBaseInitializer (
557 null, Parameters.EmptyReadOnlyParameters,
562 mods = Modifiers.STATIC;
568 c.Block = new Block (null);
572 public void ReportStructInitializedInstanceError ()
574 string n = TypeBuilder.FullName;
576 foreach (Field f in initialized_fields){
579 "`" + n + "." + f.Name + "': can not have " +
580 "instance field initializers in structs");
585 /// The pending methods that need to be implemented (interfaces or abstract methods)
587 public PendingImplementation Pending;
590 /// This function computes the Base class and also the
591 /// list of interfaces that the class or struct @c implements.
593 /// The return value is an array (might be null) of
594 /// interfaces implemented (as Types).
596 /// The @parent argument is set to the parent object or null
597 /// if this is `System.Object'.
599 Type [] GetClassBases (bool is_class, out Type parent, out bool error)
601 ArrayList bases = Bases;
610 parent = TypeManager.value_type;
614 if (RootContext.StdLib)
615 parent = TypeManager.object_type;
616 else if (Name != "System.Object")
617 parent = TypeManager.object_type;
620 // If we are compiling our runtime,
621 // and we are defining ValueType, then our
622 // parent is `System.Object'.
624 if (!RootContext.StdLib && Name == "System.ValueType")
625 parent = TypeManager.object_type;
632 // Bases should be null if there are no bases at all
637 Expression name = (Expression) bases [0];
638 name = ResolveTypeExpr (name, false, Location);
645 Type first = name.Type;
651 parent = TypeManager.object_type;
655 if (!AsAccessible (parent, ModFlags))
656 Report.Error (60, Location,
657 "Inconsistent accessibility: base class `" +
658 TypeManager.CSharpName (parent) + "' is less " +
659 "accessible than class `" +
666 Type [] ifaces = new Type [count-start];
668 for (i = start, j = 0; i < count; i++, j++){
669 Expression name = (Expression) bases [i];
670 Expression resolved = ResolveTypeExpr (name, false, Location);
671 bases [i] = resolved;
672 Type t = resolved.Type;
679 if (is_class == false && !t.IsInterface){
680 Report.Error (527, "In Struct `" + Name + "', type `"+
681 name +"' is not an interface");
690 detail = " (a class can not inherit from a struct/enum)";
692 Report.Error (509, "class `"+ Name +
693 "': Cannot inherit from sealed class `"+
694 bases [i]+"'"+detail);
701 Report.Error (527, "In Class `" + Name + "', type `"+
702 name+"' is not an interface");
708 for (int x = 0; x < j; x++) {
709 if (t == ifaces [x]) {
710 Report.Error (528, "`" + name + "' is already listed in interface list");
719 return TypeManager.ExpandInterfaces (ifaces);
723 // Defines the type in the appropriate ModuleBuilder or TypeBuilder.
725 public override TypeBuilder DefineType ()
731 if (TypeBuilder != null)
744 ec = new EmitContext (this, Mono.CSharp.Location.Null, null, null, ModFlags);
746 ifaces = GetClassBases (is_class, out parent, out error);
751 if (is_class && parent != null){
752 if (parent == TypeManager.enum_type ||
753 (parent == TypeManager.value_type && RootContext.StdLib) ||
754 parent == TypeManager.delegate_type ||
755 parent == TypeManager.array_type){
757 644, Location, "`" + Name + "' cannot inherit from " +
758 "special class `" + TypeManager.CSharpName (parent) + "'");
763 if (!is_class && TypeManager.value_type == null)
764 throw new Exception ();
766 TypeAttributes type_attributes = TypeAttr;
768 // if (parent_builder is ModuleBuilder) {
770 ModuleBuilder builder = CodeGen.ModuleBuilder;
773 // Structs with no fields need to have a ".size 1"
777 if (!is_class && !have_nonstatic_fields)
778 TypeBuilder = builder.DefineType (Name,
781 PackingSize.Unspecified, 1);
784 // classes or structs with fields
786 TypeBuilder = builder.DefineType (Name,
791 TypeBuilder builder = Parent.TypeBuilder;
794 // Structs with no fields need to have a ".size 1"
797 if (!is_class && !have_nonstatic_fields)
798 TypeBuilder = builder.DefineNestedType (Basename,
801 PackingSize.Unspecified);
804 // classes or structs with fields
806 TypeBuilder = builder.DefineNestedType (Basename,
813 // add interfaces that were not added at type creation (weird API issue)
814 if (!is_class && !have_nonstatic_fields && (ifaces != null)) {
815 foreach (Type i in ifaces)
816 TypeBuilder.AddInterfaceImplementation (i);
820 // Finish the setup for the EmitContext
822 ec.ContainerType = TypeBuilder;
824 TypeManager.AddUserType (Name, TypeBuilder, this, ifaces);
826 if ((parent != null) &&
827 (parent == TypeManager.attribute_type ||
828 parent.IsSubclassOf (TypeManager.attribute_type))) {
829 RootContext.RegisterAttribute (this);
830 TypeManager.RegisterAttrType (TypeBuilder, this);
832 RootContext.RegisterOrder (this);
834 if (Interfaces != null) {
835 foreach (Interface iface in Interfaces)
840 foreach (TypeContainer tc in Types)
844 if (Delegates != null) {
845 foreach (Delegate d in Delegates)
850 foreach (Enum en in Enums)
860 /// Defines the MemberCore objects that are in the `list' Arraylist
862 /// The `defined_names' array contains a list of members defined in
865 static ArrayList remove_list = new ArrayList ();
866 void DefineMembers (ArrayList list, MemberInfo [] defined_names)
870 remove_list.Clear ();
872 foreach (MemberCore mc in list){
873 if (!mc.Define (this)){
874 remove_list.Add (mc);
878 if (defined_names == null)
881 idx = Array.BinarySearch (defined_names, mc.Name, mif_compare);
883 if (RootContext.WarningLevel >= 4){
884 if ((mc.ModFlags & Modifiers.NEW) != 0)
885 Warning_KewywordNewNotRequired (mc.Location, mc);
890 MemberInfo match = defined_names [idx];
892 if (match is PropertyInfo && ((mc.ModFlags & Modifiers.OVERRIDE) != 0))
896 // If we are both methods, let the method resolution emit warnings
898 if (match is MethodBase && mc is MethodCore)
901 if ((mc.ModFlags & Modifiers.NEW) == 0)
902 Warning_KeywordNewRequired (mc.Location, defined_names [idx]);
905 foreach (object o in remove_list)
908 remove_list.Clear ();
912 // Defines the indexers, and also verifies that the IndexerNameAttribute in the
913 // class is consisten. Either it is `Item' or it is the name defined by all the
914 // indexers with the `IndexerName' attribute.
916 // Turns out that the IndexerNameAttribute is applied to each indexer,
917 // but it is never emitted, instead a DefaultName attribute is attached
920 void DefineIndexers ()
922 string class_indexer_name = null;
924 foreach (Indexer i in Indexers){
929 name = i.IndexerName;
931 if (i.InterfaceType != null)
934 if (class_indexer_name == null){
935 class_indexer_name = name;
939 if (name == class_indexer_name)
943 668, "Two indexers have different names, " +
944 " you should use the same name for all your indexers");
946 if (class_indexer_name == null)
947 class_indexer_name = "Item";
948 IndexerName = class_indexer_name;
951 static void Report1530 (Location loc)
953 Report.Error (1530, loc, "Keyword new not allowed for namespace elements");
957 /// Populates our TypeBuilder with fields and methods
959 public override bool Define (TypeContainer parent)
961 MemberInfo [] defined_names = null;
963 if (interface_order != null){
964 foreach (Interface iface in interface_order)
965 if ((iface.ModFlags & Modifiers.NEW) == 0)
968 Report1530 (iface.Location);
971 if (RootContext.WarningLevel > 1){
975 // This code throws an exception in the comparer
976 // I guess the string is not an object?
978 ptype = TypeBuilder.BaseType;
980 defined_names = (MemberInfo []) FindMembers (
981 ptype, MemberTypes.All & ~MemberTypes.Constructor,
982 BindingFlags.Public | BindingFlags.Instance |
983 BindingFlags.Static, null, null);
985 Array.Sort (defined_names, mif_compare);
989 if (constants != null)
990 DefineMembers (constants, defined_names);
993 DefineMembers (fields, defined_names);
996 if (instance_constructors == null){
997 if (default_constructor == null)
998 DefineDefaultConstructor (false);
1001 if (initialized_static_fields != null &&
1002 default_static_constructor == null)
1003 DefineDefaultConstructor (true);
1006 if (this is Struct){
1008 // Structs can not have initialized instance
1011 if (initialized_static_fields != null &&
1012 default_static_constructor == null)
1013 DefineDefaultConstructor (true);
1015 if (initialized_fields != null)
1016 ReportStructInitializedInstanceError ();
1019 Pending = PendingImplementation.GetPendingImplementations (this);
1022 // Constructors are not in the defined_names array
1024 if (instance_constructors != null)
1025 DefineMembers (instance_constructors, null);
1027 if (default_static_constructor != null)
1028 default_static_constructor.Define (this);
1030 if (methods != null)
1031 DefineMembers (methods, defined_names);
1033 if (properties != null)
1034 DefineMembers (properties, defined_names);
1037 DefineMembers (events, defined_names);
1039 if (indexers != null) {
1042 IndexerName = "Item";
1044 if (operators != null)
1045 DefineMembers (operators, null);
1048 DefineMembers (enums, defined_names);
1050 if (delegates != null)
1051 DefineMembers (delegates, defined_names);
1057 /// This function is based by a delegate to the FindMembers routine
1059 static bool AlwaysAccept (MemberInfo m, object filterCriteria)
1065 /// This filter is used by FindMembers, and we just keep
1066 /// a global for the filter to `AlwaysAccept'
1068 static MemberFilter accepting_filter;
1072 /// A member comparission method based on name only
1074 static IComparer mif_compare;
1076 static TypeContainer ()
1078 accepting_filter = new MemberFilter (AlwaysAccept);
1079 mif_compare = new MemberInfoCompare ();
1083 /// This method returns the members of this type just like Type.FindMembers would
1084 /// Only, we need to use this for types which are _being_ defined because MS'
1085 /// implementation can't take care of that.
1088 // FIXME: return an empty static array instead of null, that cleans up
1089 // some code and is consistent with some coding conventions I just found
1093 // Notice that in various cases we check if our field is non-null,
1094 // something that would normally mean that there was a bug elsewhere.
1096 // The problem happens while we are defining p-invoke methods, as those
1097 // will trigger a FindMembers, but this happens before things are defined
1099 // Since the whole process is a no-op, it is fine to check for null here.
1101 public MemberList FindMembers (MemberTypes mt, BindingFlags bf,
1102 MemberFilter filter, object criteria)
1104 ArrayList members = new ArrayList ();
1105 bool priv = (bf & BindingFlags.NonPublic) != 0;
1108 filter = accepting_filter;
1110 if ((mt & MemberTypes.Field) != 0) {
1111 if (fields != null) {
1112 foreach (Field f in fields) {
1113 if ((f.ModFlags & Modifiers.PRIVATE) != 0)
1117 FieldBuilder fb = f.FieldBuilder;
1118 if (fb != null && filter (fb, criteria) == true)
1123 if (constants != null) {
1124 foreach (Const con in constants) {
1125 if ((con.ModFlags & Modifiers.PRIVATE) != 0)
1129 FieldBuilder fb = con.FieldBuilder;
1130 if (fb != null && filter (fb, criteria) == true)
1136 if ((mt & MemberTypes.Method) != 0) {
1137 if (methods != null) {
1138 foreach (Method m in methods) {
1139 if ((m.ModFlags & Modifiers.PRIVATE) != 0)
1143 MethodBuilder mb = m.MethodBuilder;
1145 if (mb != null && filter (mb, criteria) == true)
1150 if (operators != null){
1151 foreach (Operator o in operators) {
1152 if ((o.ModFlags & Modifiers.PRIVATE) != 0)
1156 MethodBuilder ob = o.OperatorMethodBuilder;
1157 if (ob != null && filter (ob, criteria) == true)
1162 if (properties != null){
1163 foreach (Property p in properties){
1164 if ((p.ModFlags & Modifiers.PRIVATE) != 0)
1171 if (b != null && filter (b, criteria) == true)
1175 if (b != null && filter (b, criteria) == true)
1181 if ((mt & MemberTypes.Event) != 0) {
1183 foreach (Event e in events) {
1184 if ((e.ModFlags & Modifiers.PRIVATE) != 0)
1188 MemberInfo eb = e.EventBuilder;
1189 if (eb != null && filter (eb, criteria) == true)
1190 members.Add (e.EventBuilder);
1194 if ((mt & MemberTypes.Property) != 0){
1195 if (properties != null)
1196 foreach (Property p in properties) {
1197 if ((p.ModFlags & Modifiers.PRIVATE) != 0)
1201 MemberInfo pb = p.PropertyBuilder;
1202 if (pb != null && filter (pb, criteria) == true) {
1203 members.Add (p.PropertyBuilder);
1207 if (indexers != null)
1208 foreach (Indexer ix in indexers) {
1209 if ((ix.ModFlags & Modifiers.PRIVATE) != 0)
1213 MemberInfo ib = ix.PropertyBuilder;
1214 if (ib != null && filter (ib, criteria) == true) {
1215 members.Add (ix.PropertyBuilder);
1220 if ((mt & MemberTypes.NestedType) != 0) {
1222 foreach (TypeContainer t in types) {
1223 TypeBuilder tb = t.TypeBuilder;
1225 if (tb != null && (filter (tb, criteria) == true))
1231 foreach (Enum en in enums){
1232 TypeBuilder tb = en.TypeBuilder;
1234 if (tb != null && (filter (tb, criteria) == true))
1239 if (delegates != null){
1240 foreach (Delegate d in delegates){
1241 TypeBuilder tb = d.TypeBuilder;
1243 if (tb != null && (filter (tb, criteria) == true))
1249 if ((mt & MemberTypes.Constructor) != 0){
1250 if (instance_constructors != null){
1251 foreach (Constructor c in instance_constructors){
1252 ConstructorBuilder cb = c.ConstructorBuilder;
1255 if (filter (cb, criteria) == true)
1260 if (default_static_constructor != null){
1261 ConstructorBuilder cb =
1262 default_static_constructor.ConstructorBuilder;
1265 if (filter (cb, criteria) == true)
1271 // Lookup members in parent if requested.
1273 if (((bf & BindingFlags.DeclaredOnly) == 0) && (TypeBuilder.BaseType != null)) {
1274 MemberList list = FindMembers (TypeBuilder.BaseType, mt, bf, filter, criteria);
1275 members.AddRange (list);
1278 return new MemberList (members);
1283 public static MemberList FindMembers (Type t, MemberTypes mt, BindingFlags bf,
1284 MemberFilter filter, object criteria)
1286 TypeContainer tc = TypeManager.LookupTypeContainer (t);
1289 return tc.FindMembers (mt, bf, filter, criteria);
1291 return new MemberList (t.FindMembers (mt, bf, filter, criteria));
1295 // FindMethods will look for methods not only in the type `t', but in
1296 // any interfaces implemented by the type.
1298 public static MethodInfo [] FindMethods (Type t, BindingFlags bf,
1299 MemberFilter filter, object criteria)
1305 /// Emits the values for the constants
1307 public void EmitConstants ()
1309 if (constants != null)
1310 foreach (Const con in constants)
1311 con.EmitConstant (this);
1316 /// Emits the code, this step is performed after all
1317 /// the types, enumerations, constructors
1321 if (instance_constructors != null)
1322 foreach (Constructor c in instance_constructors)
1325 if (default_static_constructor != null)
1326 default_static_constructor.Emit (this);
1328 if (methods != null)
1329 foreach (Method m in methods)
1332 if (operators != null)
1333 foreach (Operator o in operators)
1336 if (properties != null)
1337 foreach (Property p in properties)
1340 if (indexers != null){
1341 foreach (Indexer ix in indexers)
1344 CustomAttributeBuilder cb = Interface.EmitDefaultMemberAttr (
1345 this, IndexerName, ModFlags, Location);
1346 TypeBuilder.SetCustomAttribute (cb);
1350 foreach (Field f in fields)
1353 if (events != null){
1354 foreach (Event e in Events)
1358 if (Pending != null)
1359 if (Pending.VerifyPendingMethods ())
1362 Attribute.ApplyAttributes (ec, TypeBuilder, this, OptAttributes, Location);
1365 // Check for internal or private fields that were never assigned
1367 if (fields != null && RootContext.WarningLevel >= 3) {
1368 foreach (Field f in fields) {
1369 if ((f.ModFlags & Modifiers.PUBLIC) != 0)
1374 169, f.Location, "Private field " +
1375 MakeName (f.Name) + " is never used");
1380 // Only report 649 on level 4
1382 if (RootContext.WarningLevel < 4)
1385 if ((f.status & Field.Status.ASSIGNED) != 0)
1390 "Field " + MakeName (f.Name) + " is never assigned " +
1391 " to and will always have its default value");
1395 // if (types != null)
1396 // foreach (TypeContainer tc in types)
1400 public override void CloseType ()
1405 TypeBuilder.CreateType ();
1407 } catch (TypeLoadException){
1409 // This is fine, the code still created the type
1411 // Report.Warning (-20, "Exception while creating class: " + TypeBuilder.Name);
1412 // Console.WriteLine (e.Message);
1414 Console.WriteLine ("In type: " + Name);
1419 foreach (Enum en in Enums)
1422 if (interface_order != null){
1423 foreach (Interface iface in interface_order)
1428 foreach (TypeContainer tc in Types)
1432 foreach (TypeContainer tc in Types)
1433 if (!(tc is Struct))
1437 if (Delegates != null)
1438 foreach (Delegate d in Delegates)
1442 public string MakeName (string n)
1444 return "`" + Name + "." + n + "'";
1447 public void Warning_KeywordNewRequired (Location l, MemberInfo mi)
1450 108, l, "The keyword new is required on " +
1451 MakeName (mi.Name) + " because it hides `" +
1452 mi.ReflectedType.Name + "." + mi.Name + "'");
1455 public void Warning_KewywordNewNotRequired (Location l, MemberCore mc)
1458 109, l, "The member " + MakeName (mc.Name) + " does not hide an " +
1459 "inherited member, the keyword new is not required");
1462 public static int CheckMember (string name, MemberInfo mi, int ModFlags)
1468 // Performs the validation on a Method's modifiers (properties have
1469 // the same properties).
1471 public bool MethodModifiersValid (int flags, string n, Location loc)
1473 const int vao = (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE);
1474 const int va = (Modifiers.VIRTUAL | Modifiers.ABSTRACT);
1475 const int nv = (Modifiers.NEW | Modifiers.VIRTUAL);
1477 string name = MakeName (n);
1480 // At most one of static, virtual or override
1482 if ((flags & Modifiers.STATIC) != 0){
1483 if ((flags & vao) != 0){
1485 112, loc, "static method " + name + "can not be marked " +
1486 "as virtual, abstract or override");
1491 if (this is Struct){
1492 if ((flags & va) != 0){
1493 Modifiers.Error_InvalidModifier (loc, "virtual or abstract");
1498 if ((flags & Modifiers.OVERRIDE) != 0 && (flags & nv) != 0){
1501 " marked as override cannot be marked as new or virtual");
1506 // If the declaration includes the abstract modifier, then the
1507 // declaration does not include static, virtual or extern
1509 if ((flags & Modifiers.ABSTRACT) != 0){
1510 if ((flags & Modifiers.EXTERN) != 0){
1512 180, loc, name + " can not be both abstract and extern");
1516 if ((flags & Modifiers.VIRTUAL) != 0){
1518 503, loc, name + " can not be both abstract and virtual");
1522 if ((ModFlags & Modifiers.ABSTRACT) == 0){
1525 " is abstract but its container class is not");
1531 if ((flags & Modifiers.PRIVATE) != 0){
1532 if ((flags & vao) != 0){
1535 " virtual or abstract members can not be private");
1540 if ((flags & Modifiers.SEALED) != 0){
1541 if ((flags & Modifiers.OVERRIDE) == 0){
1544 " cannot be sealed because it is not an override");
1552 // Access level of a type.
1555 ProtectedInternal = 1,
1561 // Check whether `flags' denotes a more restricted access than `level'
1562 // and return the new level.
1563 static AccessLevel CheckAccessLevel (AccessLevel level, int flags)
1565 AccessLevel old_level = level;
1567 if ((flags & Modifiers.INTERNAL) != 0) {
1568 if ((flags & Modifiers.PROTECTED) != 0) {
1569 if ((int) level < (int) AccessLevel.ProtectedInternal)
1570 level = AccessLevel.ProtectedInternal;
1572 if ((int) level < (int) AccessLevel.Internal)
1573 level = AccessLevel.Internal;
1575 } else if ((flags & Modifiers.PROTECTED) != 0) {
1576 if ((int) level < (int) AccessLevel.Protected)
1577 level = AccessLevel.Protected;
1578 } else if ((flags & Modifiers.PRIVATE) != 0)
1579 level = AccessLevel.Private;
1584 // Return the access level for a new member which is defined in the current
1585 // TypeContainer with access modifiers `flags'.
1586 AccessLevel GetAccessLevel (int flags)
1588 if ((flags & Modifiers.PRIVATE) != 0)
1589 return AccessLevel.Private;
1592 if (!IsTopLevel && (Parent != null))
1593 level = Parent.GetAccessLevel (flags);
1595 level = AccessLevel.Public;
1597 return CheckAccessLevel (CheckAccessLevel (level, flags), ModFlags);
1600 // Return the access level for type `t', but don't give more access than `flags'.
1601 static AccessLevel GetAccessLevel (Type t, int flags)
1603 if (((flags & Modifiers.PRIVATE) != 0) || t.IsNestedPrivate)
1604 return AccessLevel.Private;
1607 if (TypeManager.IsBuiltinType (t))
1608 return AccessLevel.Public;
1609 else if ((t.DeclaringType != null) && (t != t.DeclaringType))
1610 level = GetAccessLevel (t.DeclaringType, flags);
1612 level = CheckAccessLevel (AccessLevel.Public, flags);
1615 if (t.IsNestedPublic)
1618 if (t.IsNestedAssembly || t.IsNotPublic) {
1619 if ((int) level < (int) AccessLevel.Internal)
1620 level = AccessLevel.Internal;
1623 if (t.IsNestedFamily) {
1624 if ((int) level < (int) AccessLevel.Protected)
1625 level = AccessLevel.Protected;
1628 if (t.IsNestedFamORAssem) {
1629 if ((int) level < (int) AccessLevel.ProtectedInternal)
1630 level = AccessLevel.ProtectedInternal;
1637 // Returns true if `parent' is as accessible as the flags `flags'
1638 // given for this member.
1640 public bool AsAccessible (Type parent, int flags)
1642 while (parent.IsArray || parent.IsPointer || parent.IsByRef)
1643 parent = parent.GetElementType ();
1645 AccessLevel level = GetAccessLevel (flags);
1646 AccessLevel level2 = GetAccessLevel (parent, flags);
1648 return (int) level >= (int) level2;
1651 Hashtable builder_and_args;
1653 public bool RegisterMethod (MethodBuilder mb, InternalParameters ip, Type [] args)
1655 if (builder_and_args == null)
1656 builder_and_args = new Hashtable ();
1661 /// Performs checks for an explicit interface implementation. First it
1662 /// checks whether the `interface_type' is a base inteface implementation.
1663 /// Then it checks whether `name' exists in the interface type.
1665 public bool VerifyImplements (Type interface_type, string full, string name, Location loc)
1669 if (ifaces != null){
1670 foreach (Type t in ifaces){
1671 if (t == interface_type){
1679 Report.Error (540, "`" + full + "': containing class does not implement interface `" + interface_type.FullName + "'");
1686 public static void Error_ExplicitInterfaceNotMemberInterface (Location loc, string name)
1688 Report.Error (539, loc, "Explicit implementation: `" + name + "' is not a member of the interface");
1692 public class Class : TypeContainer {
1694 // Modifiers allowed in a class declaration
1696 public const int AllowedModifiers =
1699 Modifiers.PROTECTED |
1700 Modifiers.INTERNAL |
1702 Modifiers.ABSTRACT |
1706 public Class (TypeContainer parent, string name, int mod, Attributes attrs, Location l)
1707 : base (parent, name, l)
1711 if (parent.Parent == null)
1712 accmods = Modifiers.INTERNAL;
1714 accmods = Modifiers.PRIVATE;
1716 this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
1717 this.attributes = attrs;
1721 // FIXME: How do we deal with the user specifying a different
1724 public override TypeAttributes TypeAttr {
1726 return base.TypeAttr | TypeAttributes.AutoLayout | TypeAttributes.Class;
1731 public class Struct : TypeContainer {
1733 // Modifiers allowed in a struct declaration
1735 public const int AllowedModifiers =
1738 Modifiers.PROTECTED |
1739 Modifiers.INTERNAL |
1743 public Struct (TypeContainer parent, string name, int mod, Attributes attrs, Location l)
1744 : base (parent, name, l)
1748 if (parent.Parent == null)
1749 accmods = Modifiers.INTERNAL;
1751 accmods = Modifiers.PRIVATE;
1753 this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
1755 this.ModFlags |= Modifiers.SEALED;
1756 this.attributes = attrs;
1761 // FIXME: Allow the user to specify a different set of attributes
1762 // in some cases (Sealed for example is mandatory for a class,
1763 // but what SequentialLayout can be changed
1765 public override TypeAttributes TypeAttr {
1767 return base.TypeAttr |
1768 TypeAttributes.SequentialLayout |
1769 TypeAttributes.Sealed |
1770 TypeAttributes.BeforeFieldInit;
1775 public abstract class MethodCore : MemberBase {
1776 public readonly Parameters Parameters;
1780 // Parameters, cached for semantic analysis.
1782 protected InternalParameters parameter_info;
1783 protected Type [] parameter_types;
1785 public MethodCore (Expression type, int mod, int allowed_mod, string name,
1786 Attributes attrs, Parameters parameters, Location loc)
1787 : base (type, mod, allowed_mod, name, attrs, loc)
1789 Parameters = parameters;
1793 // Returns the System.Type array for the parameters of this method
1795 public Type [] ParameterTypes {
1797 return parameter_types;
1801 public InternalParameters ParameterInfo
1804 return parameter_info;
1808 public Block Block {
1818 protected virtual bool DoDefineParameters (TypeContainer parent)
1820 // Check if arguments were correct
1821 parameter_types = Parameters.GetParameterInfo (parent);
1822 if ((parameter_types == null) || !CheckParameters (parent, parameter_types))
1825 parameter_info = new InternalParameters (parent, Parameters);
1830 public CallingConventions GetCallingConvention (bool is_class)
1832 CallingConventions cc = 0;
1834 cc = Parameters.GetCallingConvention ();
1837 if ((ModFlags & Modifiers.STATIC) == 0)
1838 cc |= CallingConventions.HasThis;
1840 // FIXME: How is `ExplicitThis' used in C#?
1845 public void LabelParameters (EmitContext ec, Type [] parameters, MethodBase builder)
1848 // Define each type attribute (in/out/ref) and
1849 // the argument names.
1851 Parameter [] p = Parameters.FixedParameters;
1854 MethodBuilder mb = null;
1855 ConstructorBuilder cb = null;
1857 if (builder is MethodBuilder)
1858 mb = (MethodBuilder) builder;
1860 cb = (ConstructorBuilder) builder;
1863 for (i = 0; i < p.Length; i++) {
1864 ParameterBuilder pb;
1867 pb = cb.DefineParameter (
1868 i + 1, p [i].Attributes, p [i].Name);
1870 pb = mb.DefineParameter (
1871 i + 1, p [i].Attributes, p [i].Name);
1873 Attributes attr = p [i].OptAttributes;
1875 Attribute.ApplyAttributes (ec, pb, pb, attr, Location);
1879 if (Parameters.ArrayParameter != null){
1880 ParameterBuilder pb;
1881 Parameter array_param = Parameters.ArrayParameter;
1884 pb = cb.DefineParameter (
1885 i + 1, array_param.Attributes,
1888 pb = mb.DefineParameter (
1889 i + 1, array_param.Attributes,
1892 CustomAttributeBuilder a = new CustomAttributeBuilder (
1893 TypeManager.cons_param_array_attribute, new object [0]);
1895 pb.SetCustomAttribute (a);
1900 public class Method : MethodCore {
1901 public MethodBuilder MethodBuilder;
1902 public MethodData MethodData;
1905 /// Modifiers allowed in a class declaration
1907 const int AllowedModifiers =
1910 Modifiers.PROTECTED |
1911 Modifiers.INTERNAL |
1916 Modifiers.OVERRIDE |
1917 Modifiers.ABSTRACT |
1922 // return_type can be "null" for VOID values.
1924 public Method (Expression return_type, int mod, string name, Parameters parameters,
1925 Attributes attrs, Location l)
1926 : base (return_type, mod, AllowedModifiers, name, attrs, parameters, l)
1930 // Returns the `System.Type' for the ReturnType of this
1931 // function. Provides a nice cache. (used between semantic analysis
1932 // and actual code generation
1934 public Type GetReturnType (TypeContainer parent)
1939 // Whether this is an operator method.
1940 public bool IsOperator;
1942 void DuplicateEntryPoint (MethodInfo b, Location location)
1946 "Program `" + CodeGen.FileName +
1947 "' has more than one entry point defined: `" +
1948 TypeManager.CSharpSignature(b) + "'");
1951 void Report28 (MethodInfo b)
1953 if (RootContext.WarningLevel < 4)
1958 "`" + TypeManager.CSharpSignature(b) +
1959 "' has the wrong signature to be an entry point");
1962 public bool IsEntryPoint (MethodBuilder b, InternalParameters pinfo)
1964 if (b.ReturnType != TypeManager.void_type &&
1965 b.ReturnType != TypeManager.int32_type)
1968 if (pinfo.Count == 0)
1971 if (pinfo.Count > 1)
1974 Type t = pinfo.ParameterType(0);
1976 (t.GetArrayRank() == 1) &&
1977 (t.GetElementType() == TypeManager.string_type) &&
1978 (pinfo.ParameterModifier(0) == Parameter.Modifier.NONE))
1985 // Checks our base implementation if any
1987 protected override bool CheckBase (TypeContainer parent)
1989 // Check whether arguments were correct.
1990 if (!DoDefineParameters (parent))
1993 MethodSignature ms = new MethodSignature (Name, null, ParameterTypes);
1997 mi_this = TypeContainer.FindMembers (
1998 parent.TypeBuilder, MemberTypes.Method,
1999 BindingFlags.NonPublic | BindingFlags.Public |
2000 BindingFlags.Static | BindingFlags.Instance |
2001 BindingFlags.DeclaredOnly,
2002 MethodSignature.method_signature_filter, ms);
2004 if (mi_this.Count > 0) {
2005 Report.Error (111, Location, "Class `" + parent.Name + "' " +
2006 "already defines a member called `" + Name + "' " +
2007 "with the same parameter types");
2013 // Verify if the parent has a type with the same name, and then
2014 // check whether we have to create a new slot for it or not.
2016 Type ptype = parent.TypeBuilder.BaseType;
2018 // ptype is only null for System.Object while compiling corlib.
2020 MemberList mi, mi_static, mi_instance;
2022 mi_static = TypeContainer.FindMembers (
2023 ptype, MemberTypes.Method,
2024 BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static,
2025 MethodSignature.inheritable_method_signature_filter, ms);
2027 mi_instance = TypeContainer.FindMembers (
2028 ptype, MemberTypes.Method,
2029 BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance,
2030 MethodSignature.inheritable_method_signature_filter,
2033 if (mi_instance.Count > 0){
2035 } else if (mi_static.Count > 0)
2040 if (mi != null && mi.Count > 0){
2041 parent_method = (MethodInfo) mi [0];
2042 string name = parent_method.DeclaringType.Name + "." +
2045 if (!CheckMethodAgainstBase (parent, flags, parent_method, name))
2048 if ((ModFlags & Modifiers.NEW) == 0) {
2049 Type parent_ret = TypeManager.TypeToCoreType (
2050 parent_method.ReturnType);
2052 if (parent_ret != MemberType) {
2054 508, parent.MakeName (Name) + ": cannot " +
2055 "change return type when overriding " +
2056 "inherited member " + name);
2061 if ((ModFlags & Modifiers.NEW) != 0)
2062 WarningNotHiding (parent);
2064 if ((ModFlags & Modifiers.OVERRIDE) != 0){
2065 Report.Error (115, Location,
2066 parent.MakeName (Name) +
2067 " no suitable methods found to override");
2070 } else if ((ModFlags & Modifiers.NEW) != 0)
2071 WarningNotHiding (parent);
2079 public override bool Define (TypeContainer parent)
2081 if (!DoDefine (parent))
2084 if (!CheckBase (parent))
2087 CallingConventions cc = GetCallingConvention (parent is Class);
2089 MethodData = new MethodData (this, null, MemberType, ParameterTypes,
2090 ParameterInfo, cc, OptAttributes,
2091 ModFlags, flags, true);
2093 if (!MethodData.Define (parent))
2096 MethodBuilder = MethodData.MethodBuilder;
2099 // This is used to track the Entry Point,
2101 if (Name == "Main" &&
2102 ((ModFlags & Modifiers.STATIC) != 0) &&
2103 (RootContext.MainClass == null ||
2104 RootContext.MainClass == parent.TypeBuilder.FullName)){
2105 if (IsEntryPoint (MethodBuilder, ParameterInfo)) {
2106 if (RootContext.EntryPoint == null) {
2107 RootContext.EntryPoint = MethodBuilder;
2108 RootContext.EntryPointLocation = Location;
2110 DuplicateEntryPoint (RootContext.EntryPoint, RootContext.EntryPointLocation);
2111 DuplicateEntryPoint (MethodBuilder, Location);
2114 Report28(MethodBuilder);
2123 public void Emit (TypeContainer parent)
2125 MethodData.Emit (parent, Block, this);
2129 public abstract class ConstructorInitializer {
2130 ArrayList argument_list;
2131 ConstructorInfo parent_constructor;
2132 Parameters parameters;
2135 public ConstructorInitializer (ArrayList argument_list, Parameters parameters,
2138 this.argument_list = argument_list;
2139 this.parameters = parameters;
2143 public ArrayList Arguments {
2145 return argument_list;
2149 public bool Resolve (EmitContext ec)
2151 Expression parent_constructor_group;
2154 ec.CurrentBlock = new Block (null, true, parameters);
2156 if (argument_list != null){
2157 foreach (Argument a in argument_list){
2158 if (!a.Resolve (ec, loc))
2163 ec.CurrentBlock = null;
2165 if (this is ConstructorBaseInitializer) {
2166 if (ec.ContainerType.BaseType == null)
2169 t = ec.ContainerType.BaseType;
2170 if (ec.ContainerType.IsValueType) {
2171 Report.Error (522, loc,
2172 "structs cannot call base class constructors");
2176 t = ec.ContainerType;
2178 parent_constructor_group = Expression.MemberLookup (
2180 MemberTypes.Constructor,
2181 BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
2184 if (parent_constructor_group == null){
2185 Report.Error (1501, loc,
2186 "Can not find a constructor for this argument list");
2190 parent_constructor = (ConstructorInfo) Invocation.OverloadResolve (ec,
2191 (MethodGroupExpr) parent_constructor_group, argument_list, loc);
2193 if (parent_constructor == null){
2194 Report.Error (1501, loc,
2195 "Can not find a constructor for this argument list");
2202 public void Emit (EmitContext ec)
2204 if (parent_constructor != null)
2205 ec.ig.Emit (OpCodes.Ldarg_0);
2206 if (argument_list != null)
2207 Invocation.EmitArguments (ec, null, argument_list);
2208 if (parent_constructor != null)
2209 ec.ig.Emit (OpCodes.Call, parent_constructor);
2213 public class ConstructorBaseInitializer : ConstructorInitializer {
2214 public ConstructorBaseInitializer (ArrayList argument_list, Parameters pars, Location l) :
2215 base (argument_list, pars, l)
2220 public class ConstructorThisInitializer : ConstructorInitializer {
2221 public ConstructorThisInitializer (ArrayList argument_list, Parameters pars, Location l) :
2222 base (argument_list, pars, l)
2227 public class Constructor : MethodCore {
2228 public ConstructorBuilder ConstructorBuilder;
2229 public ConstructorInitializer Initializer;
2230 new public Attributes OptAttributes;
2233 // Modifiers allowed for a constructor.
2235 const int AllowedModifiers =
2237 Modifiers.PROTECTED |
2238 Modifiers.INTERNAL |
2244 // The spec claims that static is not permitted, but
2245 // my very own code has static constructors.
2247 public Constructor (string name, Parameters args, ConstructorInitializer init, Location l)
2248 : base (null, 0, AllowedModifiers, name, null, args, l)
2254 // Returns true if this is a default constructor
2256 public bool IsDefault ()
2258 if ((ModFlags & Modifiers.STATIC) != 0)
2259 return (Parameters.FixedParameters == null ? true : Parameters.Empty) &&
2260 (Parameters.ArrayParameter == null ? true : Parameters.Empty);
2263 return (Parameters.FixedParameters == null ? true : Parameters.Empty) &&
2264 (Parameters.ArrayParameter == null ? true : Parameters.Empty) &&
2265 (Initializer is ConstructorBaseInitializer) &&
2266 (Initializer.Arguments == null);
2270 // Creates the ConstructorBuilder
2272 public override bool Define (TypeContainer parent)
2274 MethodAttributes ca = (MethodAttributes.RTSpecialName |
2275 MethodAttributes.SpecialName);
2277 // Check if arguments were correct.
2278 if (!DoDefineParameters (parent))
2281 if ((ModFlags & Modifiers.STATIC) != 0)
2282 ca |= MethodAttributes.Static;
2284 if (parent is Struct && ParameterTypes.Length == 0){
2287 "Structs can not contain explicit parameterless " +
2291 ca |= MethodAttributes.Public | MethodAttributes.HideBySig;
2294 ConstructorBuilder = parent.TypeBuilder.DefineConstructor (
2295 ca, GetCallingConvention (parent is Class), ParameterTypes);
2298 // HACK because System.Reflection.Emit is lame
2300 if (!TypeManager.RegisterMethod (ConstructorBuilder, ParameterInfo, ParameterTypes)) {
2303 "Class `" +parent.Name+ "' already contains a definition with the " +
2304 "same return value and parameter types for constructor `" + Name
2315 public void Emit (TypeContainer parent)
2317 ILGenerator ig = ConstructorBuilder.GetILGenerator ();
2318 EmitContext ec = new EmitContext (parent, Location, ig, null, ModFlags, true);
2320 if ((ModFlags & Modifiers.STATIC) == 0){
2321 if (parent is Class && Initializer == null)
2322 Initializer = new ConstructorBaseInitializer (
2323 null, Parameters.EmptyReadOnlyParameters, parent.Location);
2327 // Spec mandates that Initializers will not have
2331 if (Initializer != null && !Initializer.Resolve (ec))
2333 ec.IsStatic = false;
2336 LabelParameters (ec, ParameterTypes, ConstructorBuilder);
2339 // Classes can have base initializers and instance field initializers.
2341 if (parent is Class){
2342 if ((ModFlags & Modifiers.STATIC) == 0)
2343 parent.EmitFieldInitializers (ec);
2345 if (Initializer != null)
2346 Initializer.Emit (ec);
2348 if ((ModFlags & Modifiers.STATIC) != 0)
2349 parent.EmitFieldInitializers (ec);
2351 Attribute.ApplyAttributes (ec, ConstructorBuilder, this, OptAttributes, Location);
2353 // If this is a non-static `struct' constructor and doesn't have any
2354 // initializer, it must initialize all of the struct's fields.
2355 if ((parent is Struct) && ((ModFlags & Modifiers.STATIC) == 0) &&
2356 (Initializer == null))
2357 Block.AddThisVariable (parent, Location);
2359 ec.EmitTopBlock (Block, ParameterInfo, Location);
2363 public class MethodData {
2365 // The return type of this method
2367 public readonly Type ReturnType;
2368 public readonly Type[] ParameterTypes;
2369 public readonly InternalParameters ParameterInfo;
2370 public readonly CallingConventions CallingConventions;
2371 public readonly Attributes OptAttributes;
2372 public readonly Location Location;
2375 // Are we implementing an interface ?
2377 public bool IsImplementing = false;
2382 protected MemberBase member;
2383 protected int modifiers;
2384 protected MethodAttributes flags;
2385 protected bool is_method;
2386 protected string accessor_name;
2387 ArrayList conditionals;
2389 MethodBuilder builder = null;
2390 public MethodBuilder MethodBuilder {
2396 public MethodData (MemberBase member, string name, Type return_type,
2397 Type [] parameter_types, InternalParameters parameters,
2398 CallingConventions cc, Attributes opt_attrs,
2399 int modifiers, MethodAttributes flags, bool is_method)
2401 this.member = member;
2402 this.accessor_name = name;
2403 this.ReturnType = return_type;
2404 this.ParameterTypes = parameter_types;
2405 this.ParameterInfo = parameters;
2406 this.CallingConventions = cc;
2407 this.OptAttributes = opt_attrs;
2408 this.modifiers = modifiers;
2410 this.is_method = is_method;
2411 this.Location = member.Location;
2412 this.conditionals = new ArrayList ();
2418 Attribute dllimport_attribute = null;
2419 string obsolete = null;
2420 bool obsolete_error = false;
2422 public virtual bool ApplyAttributes (Attributes opt_attrs, bool is_method)
2424 if ((opt_attrs == null) || (opt_attrs.AttributeSections == null))
2427 foreach (AttributeSection asec in opt_attrs.AttributeSections) {
2428 if (asec.Attributes == null)
2431 foreach (Attribute a in asec.Attributes) {
2432 if (a.Name == "Conditional") {
2433 if (!ApplyConditionalAttribute (a))
2435 } else if (a.Name == "Obsolete") {
2436 if (!ApplyObsoleteAttribute (a))
2438 } else if (a.Name.IndexOf ("DllImport") != -1) {
2440 a.Type = TypeManager.dllimport_type;
2441 Attribute.Error_AttributeNotValidForElement (a, Location);
2444 if (!ApplyDllImportAttribute (a))
2454 // Applies the `DllImport' attribute to the method.
2456 protected virtual bool ApplyDllImportAttribute (Attribute a)
2458 const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
2459 if ((modifiers & extern_static) != extern_static) {
2460 Report.Error (601, Location,
2461 "The DllImport attribute must be specified on a method " +
2462 "marked `static' and `extern'.");
2466 flags |= MethodAttributes.PinvokeImpl;
2467 dllimport_attribute = a;
2472 // Applies the `Obsolete' attribute to the method.
2474 protected virtual bool ApplyObsoleteAttribute (Attribute a)
2476 if (obsolete != null) {
2477 Report.Error (579, Location, "Duplicate `Obsolete' attribute");
2481 obsolete = a.Obsolete_GetObsoleteMessage (out obsolete_error);
2482 return obsolete != null;
2486 // Applies the `Conditional' attribute to the method.
2488 protected virtual bool ApplyConditionalAttribute (Attribute a)
2490 // The Conditional attribute is only valid on methods.
2492 Attribute.Error_AttributeNotValidForElement (a, Location);
2496 string condition = a.Conditional_GetConditionName ();
2498 if (condition == null)
2501 if (ReturnType != TypeManager.void_type) {
2502 Report.Error (578, Location,
2503 "Conditional not valid on `" + member.Name + "' " +
2504 "because its return type is not void");
2508 if ((modifiers & Modifiers.OVERRIDE) != 0) {
2509 Report.Error (243, Location,
2510 "Conditional not valid on `" + member.Name + "' " +
2511 "because it is an override method");
2515 if (member.IsExplicitImpl) {
2516 Report.Error (577, Location,
2517 "Conditional not valid on `" + member.Name + "' " +
2518 "because it is an explicit interface implementation");
2522 if (IsImplementing) {
2523 Report.Error (623, Location,
2524 "Conditional not valid on `" + member.Name + "' " +
2525 "because it is an interface method");
2529 conditionals.Add (condition);
2535 // Checks whether this method should be ignored due to its Conditional attributes.
2537 bool ShouldIgnore (Location loc)
2539 // When we're overriding a virtual method, we implicitly inherit the
2540 // Conditional attributes from our parent.
2541 if (member.ParentMethod != null) {
2542 TypeManager.MethodFlags flags = TypeManager.GetMethodFlags (
2543 member.ParentMethod, loc);
2545 if ((flags & TypeManager.MethodFlags.ShouldIgnore) != 0)
2549 foreach (string condition in conditionals)
2550 if (RootContext.AllDefines [condition] == null)
2557 // Returns the TypeManager.MethodFlags for this method.
2558 // This emits an error 619 / warning 618 if the method is obsolete.
2559 // In the former case, TypeManager.MethodFlags.IsObsoleteError is returned.
2561 public virtual TypeManager.MethodFlags GetMethodFlags (Location loc)
2563 TypeManager.MethodFlags flags = 0;
2565 if (obsolete != null) {
2566 if (obsolete_error) {
2567 Report.Error (619, loc, "Method `" + member.Name +
2568 "' is obsolete: `" + obsolete + "'");
2569 return TypeManager.MethodFlags.IsObsoleteError;
2571 Report.Warning (618, loc, "Method `" + member.Name +
2572 "' is obsolete: `" + obsolete + "'");
2574 flags |= TypeManager.MethodFlags.IsObsolete;
2577 if (ShouldIgnore (loc))
2578 flags |= TypeManager.MethodFlags.ShouldIgnore;
2583 public virtual bool Define (TypeContainer parent)
2585 MethodInfo implementing = null;
2586 string method_name, name, prefix;
2588 if (OptAttributes != null)
2589 if (!ApplyAttributes (OptAttributes, is_method))
2592 if (member.IsExplicitImpl)
2593 prefix = member.InterfaceType.FullName + ".";
2597 if (accessor_name != null)
2598 name = accessor_name + "_" + member.ShortName;
2600 name = member.ShortName;
2601 method_name = prefix + name;
2603 if (parent.Pending != null){
2604 if (member is Indexer)
2605 implementing = parent.Pending.IsInterfaceIndexer (
2606 member.InterfaceType, ReturnType, ParameterTypes);
2608 implementing = parent.Pending.IsInterfaceMethod (
2609 member.InterfaceType, name, ReturnType, ParameterTypes);
2611 if (member.InterfaceType != null && implementing == null){
2612 TypeContainer.Error_ExplicitInterfaceNotMemberInterface (
2619 // For implicit implementations, make sure we are public, for
2620 // explicit implementations, make sure we are private.
2622 if (implementing != null){
2624 // Setting null inside this block will trigger a more
2625 // verbose error reporting for missing interface implementations
2627 // The "candidate" function has been flagged already
2628 // but it wont get cleared
2630 if (!member.IsExplicitImpl){
2632 // We already catch different accessibility settings
2633 // so we just need to check that we are not private
2635 if ((modifiers & Modifiers.PRIVATE) != 0)
2636 implementing = null;
2639 // Static is not allowed
2641 if ((modifiers & Modifiers.STATIC) != 0)
2642 implementing = null;
2644 if ((modifiers & (Modifiers.PUBLIC | Modifiers.ABSTRACT | Modifiers.VIRTUAL)) != 0){
2645 Modifiers.Error_InvalidModifier (Location, "public, virtual or abstract");
2646 implementing = null;
2652 // If implementing is still valid, set flags
2654 if (implementing != null){
2656 // When implementing interface methods, set NewSlot.
2658 if (implementing.DeclaringType.IsInterface)
2659 flags |= MethodAttributes.NewSlot;
2662 MethodAttributes.Virtual |
2663 MethodAttributes.HideBySig;
2665 // Get the method name from the explicit interface.
2666 if (member.InterfaceType != null) {
2667 name = implementing.Name;
2668 method_name = prefix + name;
2671 IsImplementing = true;
2675 // Create the MethodBuilder for the method
2677 if ((flags & MethodAttributes.PinvokeImpl) != 0) {
2678 if ((modifiers & Modifiers.STATIC) == 0) {
2679 Report.Error (601, Location,
2680 "The DllImport attribute must be specified on " +
2681 "a method marked 'static' and 'extern'.");
2685 EmitContext ec = new EmitContext (
2686 parent, Location, null, ReturnType, modifiers);
2688 builder = dllimport_attribute.DefinePInvokeMethod (
2689 ec, parent.TypeBuilder, method_name, flags,
2690 ReturnType, ParameterTypes);
2692 builder = parent.TypeBuilder.DefineMethod (
2693 method_name, flags, CallingConventions,
2694 ReturnType, ParameterTypes);
2696 if (builder == null)
2699 if (IsImplementing) {
2701 // clear the pending implemntation flag
2703 if (member is Indexer) {
2704 parent.Pending.ImplementIndexer (
2705 member.InterfaceType, builder, ReturnType,
2706 ParameterTypes, true);
2708 parent.Pending.ImplementMethod (
2709 member.InterfaceType, name, ReturnType,
2710 ParameterTypes, member.IsExplicitImpl);
2712 if (member.IsExplicitImpl)
2713 parent.TypeBuilder.DefineMethodOverride (
2714 builder, implementing);
2717 if (!TypeManager.RegisterMethod (builder, ParameterInfo, ParameterTypes)) {
2718 Report.Error (111, Location,
2719 "Class `" + parent.Name +
2720 "' already contains a definition with the " +
2721 "same return value and parameter types as the " +
2722 "'get' method of property `" + member.Name + "'");
2726 TypeManager.AddMethod (builder, this);
2734 public virtual void Emit (TypeContainer parent, Block block, object kind)
2739 if ((flags & MethodAttributes.PinvokeImpl) == 0)
2740 ig = builder.GetILGenerator ();
2744 ec = new EmitContext (parent, Location, ig, ReturnType, modifiers);
2746 if (OptAttributes != null)
2747 Attribute.ApplyAttributes (ec, builder, kind, OptAttributes, Location);
2749 if (member is MethodCore)
2750 ((MethodCore) member).LabelParameters (ec, ParameterTypes, MethodBuilder);
2753 // abstract or extern methods have no bodies
2755 if ((modifiers & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0){
2760 // abstract or extern methods have no bodies.
2762 if ((modifiers & Modifiers.ABSTRACT) != 0)
2764 500, Location, "Abstract method `" +
2765 TypeManager.CSharpSignature (builder) +
2766 "' can not have a body");
2768 if ((modifiers & Modifiers.EXTERN) != 0)
2770 179, Location, "External method `" +
2771 TypeManager.CSharpSignature (builder) +
2772 "' can not have a body");
2778 // Methods must have a body unless they're extern or abstract
2780 if (block == null) {
2782 501, Location, "Method `" +
2783 TypeManager.CSharpSignature (builder) +
2784 "' must declare a body since it is not marked " +
2785 "abstract or extern");
2790 // Handle destructors specially
2792 // FIXME: This code generates buggy code
2794 if (member.Name == "Finalize" && ReturnType == TypeManager.void_type)
2795 EmitDestructor (ec, block);
2797 ISymbolWriter sw = CodeGen.SymbolWriter;
2799 if ((sw != null) && !Location.IsNull (Location) &&
2800 !Location.IsNull (block.EndLocation)) {
2801 Location end = block.EndLocation;
2802 MethodToken token = MethodBuilder.GetToken ();
2803 sw.OpenMethod (new SymbolToken (token.Token));
2804 sw.SetMethodSourceRange (Location.SymbolDocument,
2809 ec.EmitTopBlock (block, ParameterInfo, Location);
2813 ec.EmitTopBlock (block, ParameterInfo, Location);
2817 void EmitDestructor (EmitContext ec, Block block)
2819 ILGenerator ig = ec.ig;
2821 Label finish = ig.DefineLabel ();
2822 bool old_in_try = ec.InTry;
2824 ig.BeginExceptionBlock ();
2826 ec.ReturnLabel = finish;
2827 ec.HasReturnLabel = true;
2828 ec.EmitTopBlock (block, null, Location);
2829 ec.InTry = old_in_try;
2831 // ig.MarkLabel (finish);
2832 bool old_in_finally = ec.InFinally;
2833 ec.InFinally = true;
2834 ig.BeginFinallyBlock ();
2836 if (ec.ContainerType.BaseType != null) {
2837 Expression member_lookup = Expression.MemberLookup (
2838 ec, ec.ContainerType.BaseType, "Finalize",
2839 MemberTypes.Method, Expression.AllBindingFlags, Location);
2841 if (member_lookup != null){
2842 MethodGroupExpr parent_destructor = ((MethodGroupExpr) member_lookup);
2844 ig.Emit (OpCodes.Ldarg_0);
2845 ig.Emit (OpCodes.Call, (MethodInfo) parent_destructor.Methods [0]);
2848 ec.InFinally = old_in_finally;
2850 ig.EndExceptionBlock ();
2851 //ig.MarkLabel (ec.ReturnLabel);
2852 ig.Emit (OpCodes.Ret);
2856 abstract public class MemberBase : MemberCore {
2857 public Expression Type;
2858 public readonly Attributes OptAttributes;
2860 protected MethodAttributes flags;
2863 // The "short" name of this property / indexer / event. This is the
2864 // name without the explicit interface.
2866 public string ShortName;
2869 // The type of this property / indexer / event
2871 public Type MemberType;
2874 // If true, this is an explicit interface implementation
2876 public bool IsExplicitImpl = false;
2879 // The name of the interface we are explicitly implementing
2881 public string ExplicitInterfaceName = null;
2884 // If true, the interface type we are explicitly implementing
2886 public Type InterfaceType = null;
2889 // The method we're overriding if this is an override method.
2891 protected MethodInfo parent_method = null;
2892 public MethodInfo ParentMethod {
2894 return parent_method;
2899 // The constructor is only exposed to our children
2901 protected MemberBase (Expression type, int mod, int allowed_mod, string name,
2902 Attributes attrs, Location loc)
2906 ModFlags = Modifiers.Check (allowed_mod, mod, Modifiers.PRIVATE, loc);
2907 OptAttributes = attrs;
2910 protected virtual bool CheckBase (TypeContainer parent)
2915 protected virtual bool CheckParameters (TypeContainer parent, Type [] parameters)
2919 foreach (Type partype in parameters){
2920 if (partype.IsPointer && !UnsafeOK (parent))
2923 if (parent.AsAccessible (partype, ModFlags))
2926 if (this is Indexer)
2927 Report.Error (55, Location,
2928 "Inconsistent accessibility: parameter type `" +
2929 TypeManager.CSharpName (partype) + "' is less " +
2930 "accessible than indexer `" + Name + "'");
2932 Report.Error (51, Location,
2933 "Inconsistent accessibility: parameter type `" +
2934 TypeManager.CSharpName (partype) + "' is less " +
2935 "accessible than method `" + Name + "'");
2942 protected virtual bool DoDefine (TypeContainer parent)
2947 if (!parent.MethodModifiersValid (ModFlags, Name, Location))
2950 flags = Modifiers.MethodAttr (ModFlags);
2952 // Lookup Type, verify validity
2953 MemberType = parent.ResolveType (Type, false, Location);
2954 if (MemberType == null)
2957 // verify accessibility
2958 if (!parent.AsAccessible (MemberType, ModFlags)) {
2959 if (this is Property)
2960 Report.Error (53, Location,
2961 "Inconsistent accessibility: property type `" +
2962 TypeManager.CSharpName (MemberType) + "' is less " +
2963 "accessible than property `" + Name + "'");
2964 else if (this is Indexer)
2965 Report.Error (54, Location,
2966 "Inconsistent accessibility: indexer return type `" +
2967 TypeManager.CSharpName (MemberType) + "' is less " +
2968 "accessible than indexer `" + Name + "'");
2969 else if (this is Method)
2970 Report.Error (50, Location,
2971 "Inconsistent accessibility: return type `" +
2972 TypeManager.CSharpName (MemberType) + "' is less " +
2973 "accessible than method `" + Name + "'");
2975 Report.Error (52, Location,
2976 "Inconsistent accessibility: field type `" +
2977 TypeManager.CSharpName (MemberType) + "' is less " +
2978 "accessible than field `" + Name + "'");
2982 if (MemberType.IsPointer && !UnsafeOK (parent))
2986 // Check for explicit interface implementation
2988 if ((ExplicitInterfaceName == null) && (Name.IndexOf (".") != -1)){
2989 int pos = Name.LastIndexOf (".");
2991 ExplicitInterfaceName = Name.Substring (0, pos);
2992 ShortName = Name.Substring (pos + 1);
2996 if (ExplicitInterfaceName != null) {
2997 InterfaceType = RootContext.LookupType (
2998 parent, ExplicitInterfaceName, false, Location);
2999 if (InterfaceType == null)
3002 // Compute the full name that we need to export.
3003 Name = InterfaceType.FullName + "." + ShortName;
3005 if (!parent.VerifyImplements (InterfaceType, ShortName, Name, Location))
3008 IsExplicitImpl = true;
3010 IsExplicitImpl = false;
3017 // Fields and Events both generate FieldBuilders, we use this to share
3018 // their common bits. This is also used to flag usage of the field
3020 abstract public class FieldBase : MemberBase {
3021 public FieldBuilder FieldBuilder;
3022 public Status status;
3025 public enum Status : byte { ASSIGNED = 1, USED = 2 }
3028 // The constructor is only exposed to our children
3030 protected FieldBase (Expression type, int mod, int allowed_mod, string name,
3031 object init, Attributes attrs, Location loc)
3032 : base (type, mod, allowed_mod, name, attrs, loc)
3038 // Whether this field has an initializer.
3040 public bool HasInitializer {
3042 return init != null;
3047 readonly Object init;
3048 Expression init_expr;
3049 bool init_expr_initialized = false;
3052 // Resolves and returns the field initializer.
3054 public Expression GetInitializerExpression (EmitContext ec)
3056 if (init_expr_initialized)
3060 if (init is Expression)
3061 e = (Expression) init;
3063 e = new ArrayCreation (Type, "", (ArrayList)init, Location);
3065 ec.IsFieldInitializer = true;
3066 e = e.DoResolve (ec);
3067 ec.IsFieldInitializer = false;
3070 init_expr_initialized = true;
3077 // The Field class is used to represents class/struct fields during parsing.
3079 public class Field : FieldBase {
3081 // Modifiers allowed in a class declaration
3083 const int AllowedModifiers =
3086 Modifiers.PROTECTED |
3087 Modifiers.INTERNAL |
3090 Modifiers.VOLATILE |
3094 public Field (Expression type, int mod, string name, Object expr_or_array_init,
3095 Attributes attrs, Location loc)
3096 : base (type, mod, AllowedModifiers, name, expr_or_array_init, attrs, loc)
3100 public override bool Define (TypeContainer parent)
3102 Type t = parent.ResolveType (Type, false, Location);
3107 if (!parent.AsAccessible (t, ModFlags)) {
3108 Report.Error (52, Location,
3109 "Inconsistent accessibility: field type `" +
3110 TypeManager.CSharpName (t) + "' is less " +
3111 "accessible than field `" + Name + "'");
3115 if (t.IsPointer && !UnsafeOK (parent))
3118 if (RootContext.WarningLevel > 1){
3119 Type ptype = parent.TypeBuilder.BaseType;
3121 // ptype is only null for System.Object while compiling corlib.
3123 TypeContainer.FindMembers (
3124 ptype, MemberTypes.Method,
3125 BindingFlags.Public |
3126 BindingFlags.Static | BindingFlags.Instance,
3127 System.Type.FilterName, Name);
3131 if ((ModFlags & Modifiers.VOLATILE) != 0){
3133 if (TypeManager.IsEnumType (t))
3134 t = TypeManager.EnumToUnderlying (t);
3136 if (!((t == TypeManager.bool_type) ||
3137 (t == TypeManager.sbyte_type) ||
3138 (t == TypeManager.byte_type) ||
3139 (t == TypeManager.short_type) ||
3140 (t == TypeManager.ushort_type) ||
3141 (t == TypeManager.int32_type) ||
3142 (t == TypeManager.uint32_type) ||
3143 (t == TypeManager.char_type) ||
3144 (t == TypeManager.float_type))){
3146 677, Location, parent.MakeName (Name) +
3147 " A volatile field can not be of type `" +
3148 TypeManager.CSharpName (t) + "'");
3154 FieldBuilder = parent.TypeBuilder.DefineField (
3155 Name, t, Modifiers.FieldAttr (ModFlags));
3157 TypeManager.RegisterFieldBase (FieldBuilder, this);
3161 public void Emit (TypeContainer tc)
3163 EmitContext ec = new EmitContext (tc, Location, null,
3164 FieldBuilder.FieldType, ModFlags);
3166 Attribute.ApplyAttributes (ec, FieldBuilder, this, OptAttributes, Location);
3171 // `set' and `get' accessors are represented with an Accessor.
3173 public class Accessor {
3175 // Null if the accessor is empty, or a Block if not
3178 public Attributes OptAttributes;
3180 public Accessor (Block b, Attributes attrs)
3183 OptAttributes = attrs;
3188 // Properties and Indexers both generate PropertyBuilders, we use this to share
3189 // their common bits.
3191 abstract public class PropertyBase : MethodCore {
3192 public Accessor Get, Set;
3193 public PropertyBuilder PropertyBuilder;
3194 public MethodBuilder GetBuilder, SetBuilder;
3195 public MethodData GetData, SetData;
3197 protected EmitContext ec;
3199 public PropertyBase (Expression type, string name, int mod_flags, int allowed_mod,
3200 Parameters parameters, Accessor get_block, Accessor set_block,
3201 Attributes attrs, Location loc)
3202 : base (type, mod_flags, allowed_mod, name, attrs, parameters, loc)
3208 protected override bool DoDefine (TypeContainer parent)
3210 if (!base.DoDefine (parent))
3213 ec = new EmitContext (parent, Location, null, MemberType, ModFlags);
3219 // Checks our base implementation if any
3221 protected override bool CheckBase (TypeContainer parent)
3223 // Check whether arguments were correct.
3224 if (!DoDefineParameters (parent))
3227 MethodSignature ms = new MethodSignature (Name, null, ParameterTypes);
3228 MemberList props_this;
3230 props_this = TypeContainer.FindMembers (
3231 parent.TypeBuilder, MemberTypes.Property,
3232 BindingFlags.NonPublic | BindingFlags.Public |
3233 BindingFlags.Static | BindingFlags.Instance |
3234 BindingFlags.DeclaredOnly,
3235 MethodSignature.method_signature_filter, ms);
3237 if (props_this.Count > 0) {
3238 Report.Error (111, Location, "Class `" + parent.Name + "' " +
3239 "already defines a member called `" + Name + "' " +
3240 "with the same parameter types");
3245 // Find properties with the same name on the base class
3248 MemberList props_static = TypeContainer.FindMembers (
3249 parent.TypeBuilder.BaseType, MemberTypes.Property,
3250 BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static,
3251 MethodSignature.inheritable_property_signature_filter, ms);
3253 MemberList props_instance = TypeContainer.FindMembers (
3254 parent.TypeBuilder.BaseType, MemberTypes.Property,
3255 BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance,
3256 MethodSignature.inheritable_property_signature_filter,
3260 // Find if we have anything
3262 if (props_static.Count > 0)
3263 props = props_static;
3264 else if (props_instance.Count > 0)
3265 props = props_instance;
3270 // If we have something on the base.
3271 if (props != null && props.Count > 0){
3272 PropertyInfo pi = (PropertyInfo) props [0];
3274 MethodInfo inherited_get = TypeManager.GetPropertyGetter (pi);
3275 MethodInfo inherited_set = TypeManager.GetPropertySetter (pi);
3277 MethodInfo reference = inherited_get == null ?
3278 inherited_set : inherited_get;
3280 if (reference != null) {
3281 string name = reference.DeclaringType.Name + "." + Name;
3283 if (!CheckMethodAgainstBase (parent, flags, reference, name))
3287 if (((ModFlags & Modifiers.NEW) == 0) && (pi.PropertyType != MemberType)) {
3288 Report.Error (508, parent.MakeName (Name) + ": cannot " +
3289 "change return type when overriding inherited " +
3290 "member `" + pi.DeclaringType + "." + pi.Name + "'");
3294 if ((ModFlags & Modifiers.NEW) != 0)
3295 WarningNotHiding (parent);
3297 if ((ModFlags & Modifiers.OVERRIDE) != 0){
3298 if (this is Indexer)
3299 Report.Error (115, Location,
3300 parent.MakeName (Name) +
3301 " no suitable indexers found to override");
3303 Report.Error (115, Location,
3304 parent.MakeName (Name) +
3305 " no suitable properties found to override");
3312 public void Emit (TypeContainer tc)
3315 // The PropertyBuilder can be null for explicit implementations, in that
3316 // case, we do not actually emit the ".property", so there is nowhere to
3317 // put the attribute
3319 if (PropertyBuilder != null)
3320 Attribute.ApplyAttributes (ec, PropertyBuilder, this, OptAttributes, Location);
3322 if (GetData != null)
3323 GetData.Emit (tc, Get.Block, Get);
3325 if (SetData != null)
3326 SetData.Emit (tc, Set.Block, Set);
3330 public class Property : PropertyBase {
3331 const int AllowedModifiers =
3334 Modifiers.PROTECTED |
3335 Modifiers.INTERNAL |
3339 Modifiers.OVERRIDE |
3340 Modifiers.ABSTRACT |
3345 public Property (Expression type, string name, int mod_flags,
3346 Accessor get_block, Accessor set_block,
3347 Attributes attrs, Location loc)
3348 : base (type, name, mod_flags, AllowedModifiers,
3349 Parameters.EmptyReadOnlyParameters,
3350 get_block, set_block, attrs, loc)
3354 public override bool Define (TypeContainer parent)
3356 if (!DoDefine (parent))
3359 if (!CheckBase (parent))
3362 flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
3365 Type [] parameters = TypeManager.NoTypes;
3367 InternalParameters ip = new InternalParameters (
3368 parent, Parameters.EmptyReadOnlyParameters);
3370 GetData = new MethodData (this, "get", MemberType,
3371 parameters, ip, CallingConventions.Standard,
3372 Get.OptAttributes, ModFlags, flags, false);
3374 if (!GetData.Define (parent))
3377 GetBuilder = GetData.MethodBuilder;
3381 Type [] parameters = new Type [1];
3382 parameters [0] = MemberType;
3384 Parameter [] parms = new Parameter [1];
3385 parms [0] = new Parameter (Type, "value", Parameter.Modifier.NONE, null);
3386 InternalParameters ip = new InternalParameters (
3387 parent, new Parameters (parms, null, Location));
3389 SetData = new MethodData (this, "set", TypeManager.void_type,
3390 parameters, ip, CallingConventions.Standard,
3391 Set.OptAttributes, ModFlags, flags, false);
3393 if (!SetData.Define (parent))
3396 SetBuilder = SetData.MethodBuilder;
3397 SetBuilder.DefineParameter (1, ParameterAttributes.None, "value");
3400 // FIXME - PropertyAttributes.HasDefault ?
3402 PropertyAttributes prop_attr =
3403 PropertyAttributes.RTSpecialName |
3404 PropertyAttributes.SpecialName;
3406 if (!IsExplicitImpl){
3407 PropertyBuilder = parent.TypeBuilder.DefineProperty (
3408 Name, prop_attr, MemberType, null);
3411 PropertyBuilder.SetGetMethod (GetBuilder);
3414 PropertyBuilder.SetSetMethod (SetBuilder);
3417 // HACK for the reasons exposed above
3419 if (!TypeManager.RegisterProperty (PropertyBuilder, GetBuilder, SetBuilder)) {
3422 "Class `" + parent.Name +
3423 "' already contains a definition for the property `" +
3433 /// Gigantic workaround for lameness in SRE follows :
3434 /// This class derives from EventInfo and attempts to basically
3435 /// wrap around the EventBuilder so that FindMembers can quickly
3436 /// return this in it search for members
3438 public class MyEventBuilder : EventInfo {
3441 // We use this to "point" to our Builder which is
3442 // not really a MemberInfo
3444 EventBuilder MyBuilder;
3447 // We "catch" and wrap these methods
3449 MethodInfo raise, remove, add;
3451 EventAttributes attributes;
3452 Type declaring_type, reflected_type, event_type;
3455 public MyEventBuilder (TypeBuilder type_builder, string name, EventAttributes event_attr, Type event_type)
3457 MyBuilder = type_builder.DefineEvent (name, event_attr, event_type);
3459 // And now store the values in our own fields.
3461 declaring_type = type_builder;
3463 reflected_type = type_builder;
3465 attributes = event_attr;
3467 this.event_type = event_type;
3471 // Methods that you have to override. Note that you only need
3472 // to "implement" the variants that take the argument (those are
3473 // the "abstract" methods, the others (GetAddMethod()) are
3476 public override MethodInfo GetAddMethod (bool nonPublic)
3481 public override MethodInfo GetRemoveMethod (bool nonPublic)
3486 public override MethodInfo GetRaiseMethod (bool nonPublic)
3492 // These methods make "MyEventInfo" look like a Builder
3494 public void SetRaiseMethod (MethodBuilder raiseMethod)
3496 raise = raiseMethod;
3497 MyBuilder.SetRaiseMethod (raiseMethod);
3500 public void SetRemoveOnMethod (MethodBuilder removeMethod)
3502 remove = removeMethod;
3503 MyBuilder.SetRemoveOnMethod (removeMethod);
3506 public void SetAddOnMethod (MethodBuilder addMethod)
3509 MyBuilder.SetAddOnMethod (addMethod);
3512 public void SetCustomAttribute (CustomAttributeBuilder cb)
3514 MyBuilder.SetCustomAttribute (cb);
3517 public override object [] GetCustomAttributes (bool inherit)
3519 // FIXME : There's nothing which can be seemingly done here because
3520 // we have no way of getting at the custom attribute objects of the
3525 public override object [] GetCustomAttributes (Type t, bool inherit)
3527 // FIXME : Same here !
3531 public override bool IsDefined (Type t, bool b)
3536 public override EventAttributes Attributes {
3542 public override string Name {
3548 public override Type DeclaringType {
3550 return declaring_type;
3554 public override Type ReflectedType {
3556 return reflected_type;
3560 public Type EventType {
3567 public class Event : FieldBase {
3568 const int AllowedModifiers =
3571 Modifiers.PROTECTED |
3572 Modifiers.INTERNAL |
3577 Modifiers.OVERRIDE |
3581 public readonly Accessor Add;
3582 public readonly Accessor Remove;
3583 public MyEventBuilder EventBuilder;
3585 MethodBuilder AddBuilder, RemoveBuilder;
3586 MethodData AddData, RemoveData;
3588 public Event (Expression type, string name, Object init, int mod, Accessor add,
3589 Accessor remove, Attributes attrs, Location loc)
3590 : base (type, mod, AllowedModifiers, name, init, attrs, loc)
3596 public override bool Define (TypeContainer parent)
3598 EventAttributes e_attr = EventAttributes.RTSpecialName | EventAttributes.SpecialName;
3600 if (!DoDefine (parent))
3603 if (!MemberType.IsSubclassOf (TypeManager.delegate_type)) {
3604 Report.Error (66, Location, "'" + parent.Name + "." + Name +
3605 "' : event must be of a delegate type");
3609 Type [] parameter_types = new Type [1];
3610 parameter_types [0] = MemberType;
3612 Parameter [] parms = new Parameter [1];
3613 parms [0] = new Parameter (Type, "value", Parameter.Modifier.NONE, null);
3614 InternalParameters ip = new InternalParameters (
3615 parent, new Parameters (parms, null, Location));
3617 if (!CheckBase (parent))
3621 // Now define the accessors
3623 AddData = new MethodData (this, "add", TypeManager.void_type,
3624 parameter_types, ip, CallingConventions.Standard,
3625 (Add != null) ? Add.OptAttributes : null,
3626 ModFlags, flags, false);
3628 if (!AddData.Define (parent))
3631 AddBuilder = AddData.MethodBuilder;
3632 AddBuilder.DefineParameter (1, ParameterAttributes.None, "value");
3634 RemoveData = new MethodData (this, "remove", TypeManager.void_type,
3635 parameter_types, ip, CallingConventions.Standard,
3636 (Remove != null) ? Remove.OptAttributes : null,
3637 ModFlags, flags, false);
3639 if (!RemoveData.Define (parent))
3642 RemoveBuilder = RemoveData.MethodBuilder;
3643 RemoveBuilder.DefineParameter (1, ParameterAttributes.None, "value");
3645 if (!IsExplicitImpl){
3646 EventBuilder = new MyEventBuilder (
3647 parent.TypeBuilder, Name, e_attr, MemberType);
3649 if (Add == null && Remove == null) {
3650 FieldBuilder = parent.TypeBuilder.DefineField (
3651 Name, MemberType, FieldAttributes.FamANDAssem);
3652 TypeManager.RegisterPrivateFieldOfEvent (
3653 (EventInfo) EventBuilder, FieldBuilder);
3654 TypeManager.RegisterFieldBase (FieldBuilder, this);
3657 EventBuilder.SetAddOnMethod (AddBuilder);
3658 EventBuilder.SetRemoveOnMethod (RemoveBuilder);
3660 if (!TypeManager.RegisterEvent (EventBuilder, AddBuilder, RemoveBuilder)) {
3661 Report.Error (111, Location,
3662 "Class `" + parent.Name +
3663 "' already contains a definition for the event `" +
3672 void EmitDefaultMethod (EmitContext ec, bool is_add)
3674 ILGenerator ig = ec.ig;
3675 MethodInfo method = null;
3678 method = TypeManager.delegate_combine_delegate_delegate;
3680 method = TypeManager.delegate_remove_delegate_delegate;
3682 if ((ModFlags & Modifiers.STATIC) != 0) {
3683 ig.Emit (OpCodes.Ldsfld, (FieldInfo) FieldBuilder);
3684 ig.Emit (OpCodes.Ldarg_0);
3685 ig.Emit (OpCodes.Call, method);
3686 ig.Emit (OpCodes.Castclass, MemberType);
3687 ig.Emit (OpCodes.Stsfld, (FieldInfo) FieldBuilder);
3689 ig.Emit (OpCodes.Ldarg_0);
3690 ig.Emit (OpCodes.Ldarg_0);
3691 ig.Emit (OpCodes.Ldfld, (FieldInfo) FieldBuilder);
3692 ig.Emit (OpCodes.Ldarg_1);
3693 ig.Emit (OpCodes.Call, method);
3694 ig.Emit (OpCodes.Castclass, MemberType);
3695 ig.Emit (OpCodes.Stfld, (FieldInfo) FieldBuilder);
3697 ig.Emit (OpCodes.Ret);
3700 public void Emit (TypeContainer tc)
3704 ec = new EmitContext (tc, Location, null, MemberType, ModFlags);
3705 Attribute.ApplyAttributes (ec, EventBuilder, this, OptAttributes, Location);
3708 AddData.Emit (tc, Add.Block, Add);
3710 ILGenerator ig = AddData.MethodBuilder.GetILGenerator ();
3711 ec = new EmitContext (tc, Location, ig, TypeManager.void_type, ModFlags);
3712 EmitDefaultMethod (ec, true);
3716 RemoveData.Emit (tc, Remove.Block, Remove);
3718 ILGenerator ig = RemoveData.MethodBuilder.GetILGenerator ();
3719 ec = new EmitContext (tc, Location, ig, TypeManager.void_type, ModFlags);
3720 EmitDefaultMethod (ec, false);
3727 // FIXME: This does not handle:
3729 // int INTERFACENAME [ args ]
3734 // int this [ args ]
3736 public class Indexer : PropertyBase {
3738 const int AllowedModifiers =
3741 Modifiers.PROTECTED |
3742 Modifiers.INTERNAL |
3746 Modifiers.OVERRIDE |
3751 public string IndexerName;
3752 public string InterfaceIndexerName;
3755 // Are we implementing an interface ?
3757 bool IsImplementing = false;
3759 public Indexer (Expression type, string int_type, int flags, Parameters parameters,
3760 Accessor get_block, Accessor set_block, Attributes attrs, Location loc)
3761 : base (type, "", flags, AllowedModifiers, parameters, get_block, set_block,
3764 ExplicitInterfaceName = int_type;
3767 public override bool Define (TypeContainer parent)
3769 PropertyAttributes prop_attr =
3770 PropertyAttributes.RTSpecialName |
3771 PropertyAttributes.SpecialName;
3773 if (!DoDefine (parent))
3776 IndexerName = Attribute.ScanForIndexerName (ec, OptAttributes);
3777 if (IndexerName == null)
3778 IndexerName = "Item";
3779 else if (IsExplicitImpl)
3780 Report.Error (592, Location,
3781 "Attribute 'IndexerName' is not valid on this declaration " +
3782 "type. It is valid on `property' declarations only.");
3784 ShortName = IndexerName;
3785 if (IsExplicitImpl) {
3786 InterfaceIndexerName = TypeManager.IndexerPropertyName (InterfaceType);
3787 Name = InterfaceType.FullName + "." + IndexerName;
3789 InterfaceIndexerName = IndexerName;
3793 if (!CheckBase (parent))
3797 InternalParameters ip = new InternalParameters (parent, Parameters);
3799 GetData = new MethodData (this, "get", MemberType,
3800 ParameterTypes, ip, CallingConventions.Standard,
3801 Get.OptAttributes, ModFlags, flags, false);
3803 if (!GetData.Define (parent))
3806 GetBuilder = GetData.MethodBuilder;
3810 int top = ParameterTypes.Length;
3811 Type [] set_pars = new Type [top + 1];
3812 ParameterTypes.CopyTo (set_pars, 0);
3813 set_pars [top] = MemberType;
3815 Parameter [] fixed_parms = Parameters.FixedParameters;
3817 if (fixed_parms == null){
3818 throw new Exception ("We currently do not support only array arguments in an indexer");
3819 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
3820 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
3822 // Here is the problem: the `value' parameter has
3823 // to come *after* the array parameter in the declaration
3825 // X (object [] x, Type value)
3828 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
3829 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
3833 Parameter [] tmp = new Parameter [fixed_parms.Length + 1];
3836 fixed_parms.CopyTo (tmp, 0);
3837 tmp [fixed_parms.Length] = new Parameter (
3838 Type, "value", Parameter.Modifier.NONE, null);
3840 Parameters set_formal_params = new Parameters (tmp, null, Location);
3842 InternalParameters ip = new InternalParameters (parent, set_formal_params);
3844 SetData = new MethodData (this, "set", TypeManager.void_type,
3845 set_pars, ip, CallingConventions.Standard,
3846 Set.OptAttributes, ModFlags, flags, false);
3848 if (!SetData.Define (parent))
3851 SetBuilder = SetData.MethodBuilder;
3855 // Now name the parameters
3857 Parameter [] p = Parameters.FixedParameters;
3861 for (i = 0; i < p.Length; ++i) {
3863 GetBuilder.DefineParameter (
3864 i + 1, p [i].Attributes, p [i].Name);
3867 SetBuilder.DefineParameter (
3868 i + 1, p [i].Attributes, p [i].Name);
3872 SetBuilder.DefineParameter (
3873 i + 1, ParameterAttributes.None, "value");
3875 if (i != ParameterTypes.Length) {
3876 Parameter array_param = Parameters.ArrayParameter;
3877 SetBuilder.DefineParameter (
3878 i + 1, array_param.Attributes, array_param.Name);
3882 if (GetData != null)
3883 IsImplementing = GetData.IsImplementing;
3884 else if (SetData != null)
3885 IsImplementing = SetData.IsImplementing;
3888 // Define the PropertyBuilder if one of the following conditions are met:
3889 // a) we're not implementing an interface indexer.
3890 // b) the indexer has a different IndexerName and this is no
3891 // explicit interface implementation.
3893 if (!IsExplicitImpl) {
3894 PropertyBuilder = parent.TypeBuilder.DefineProperty (
3895 IndexerName, prop_attr, MemberType, ParameterTypes);
3897 if (GetData != null)
3898 PropertyBuilder.SetGetMethod (GetBuilder);
3900 if (SetData != null)
3901 PropertyBuilder.SetSetMethod (SetBuilder);
3903 TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder,
3911 public class Operator : MemberCore {
3913 const int AllowedModifiers =
3919 const int RequiredModifiers =
3923 public enum OpType : byte {
3933 // Unary and Binary operators
3956 // Implicit and Explicit
3961 public readonly OpType OperatorType;
3962 public readonly Expression ReturnType;
3963 public readonly Expression FirstArgType, SecondArgType;
3964 public readonly string FirstArgName, SecondArgName;
3965 public readonly Block Block;
3966 public Attributes OptAttributes;
3967 public MethodBuilder OperatorMethodBuilder;
3969 public string MethodName;
3970 public Method OperatorMethod;
3972 public Operator (OpType type, Expression ret_type, int flags,
3973 Expression arg1type, string arg1name,
3974 Expression arg2type, string arg2name,
3975 Block block, Attributes attrs, Location loc)
3978 OperatorType = type;
3979 ReturnType = ret_type;
3980 ModFlags = Modifiers.Check (AllowedModifiers, flags, Modifiers.PUBLIC, loc);
3981 FirstArgType = arg1type;
3982 FirstArgName = arg1name;
3983 SecondArgType = arg2type;
3984 SecondArgName = arg2name;
3986 OptAttributes = attrs;
3989 string Prototype (TypeContainer parent)
3991 return parent.Name + ".operator " + OperatorType + " (" + FirstArgType + "," +
3992 SecondArgType + ")";
3995 public override bool Define (TypeContainer parent)
3998 MethodName = "op_" + OperatorType;
4000 if (SecondArgType != null)
4003 Parameter [] param_list = new Parameter [length];
4005 if ((ModFlags & RequiredModifiers) != RequiredModifiers){
4008 "User defined operators `" +
4009 Prototype (parent) +
4010 "' must be declared static and public");
4014 param_list[0] = new Parameter (FirstArgType, FirstArgName,
4015 Parameter.Modifier.NONE, null);
4016 if (SecondArgType != null)
4017 param_list[1] = new Parameter (SecondArgType, SecondArgName,
4018 Parameter.Modifier.NONE, null);
4020 OperatorMethod = new Method (ReturnType, ModFlags, MethodName,
4021 new Parameters (param_list, null, Location),
4022 OptAttributes, Mono.CSharp.Location.Null);
4024 OperatorMethod.IsOperator = true;
4025 OperatorMethod.Define (parent);
4027 if (OperatorMethod.MethodBuilder == null)
4030 OperatorMethodBuilder = OperatorMethod.MethodBuilder;
4032 Type [] param_types = OperatorMethod.ParameterTypes;
4033 Type declaring_type = OperatorMethodBuilder.DeclaringType;
4034 Type return_type = OperatorMethod.GetReturnType (parent);
4035 Type first_arg_type = param_types [0];
4037 // Rules for conversion operators
4039 if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
4040 if (first_arg_type == return_type && first_arg_type == declaring_type){
4043 "User-defined conversion cannot take an object of the " +
4044 "enclosing type and convert to an object of the enclosing" +
4049 if (first_arg_type != declaring_type && return_type != declaring_type){
4052 "User-defined conversion must convert to or from the " +
4057 if (first_arg_type == TypeManager.object_type ||
4058 return_type == TypeManager.object_type){
4061 "User-defined conversion cannot convert to or from " +
4066 if (first_arg_type.IsInterface || return_type.IsInterface){
4069 "User-defined conversion cannot convert to or from an " +
4074 if (first_arg_type.IsSubclassOf (return_type) ||
4075 return_type.IsSubclassOf (first_arg_type)){
4078 "User-defined conversion cannot convert between types " +
4079 "that derive from each other");
4082 } else if (SecondArgType == null) {
4083 // Checks for Unary operators
4085 if (first_arg_type != declaring_type){
4088 "The parameter of a unary operator must be the " +
4093 if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
4094 if (return_type != declaring_type){
4097 "The parameter and return type for ++ and -- " +
4098 "must be the containing type");
4104 if (OperatorType == OpType.True || OperatorType == OpType.False) {
4105 if (return_type != TypeManager.bool_type){
4108 "The return type of operator True or False " +
4115 // Checks for Binary operators
4117 if (first_arg_type != declaring_type &&
4118 param_types [1] != declaring_type){
4121 "One of the parameters of a binary operator must " +
4122 "be the containing type");
4130 public void Emit (TypeContainer parent)
4132 EmitContext ec = new EmitContext (parent, Location, null, null, ModFlags);
4133 Attribute.ApplyAttributes (ec, OperatorMethodBuilder, this, OptAttributes, Location);
4136 // abstract or extern methods have no bodies
4138 if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
4141 OperatorMethod.Block = Block;
4142 OperatorMethod.Emit (parent);
4147 // This is used to compare method signatures
4149 struct MethodSignature {
4151 public Type RetType;
4152 public Type [] Parameters;
4155 /// This delegate is used to extract methods which have the
4156 /// same signature as the argument
4158 public static MemberFilter method_signature_filter;
4161 /// This delegate is used to extract inheritable methods which
4162 /// have the same signature as the argument. By inheritable,
4163 /// this means that we have permissions to override the method
4164 /// from the current assembly and class
4166 public static MemberFilter inheritable_method_signature_filter;
4169 /// This delegate is used to extract inheritable methods which
4170 /// have the same signature as the argument. By inheritable,
4171 /// this means that we have permissions to override the method
4172 /// from the current assembly and class
4174 public static MemberFilter inheritable_property_signature_filter;
4176 static MethodSignature ()
4178 method_signature_filter = new MemberFilter (MemberSignatureCompare);
4179 inheritable_method_signature_filter = new MemberFilter (
4180 InheritableMemberSignatureCompare);
4181 inheritable_property_signature_filter = new MemberFilter (
4182 InheritablePropertySignatureCompare);
4185 public MethodSignature (string name, Type ret_type, Type [] parameters)
4190 if (parameters == null)
4191 Parameters = TypeManager.NoTypes;
4193 Parameters = parameters;
4196 public override int GetHashCode ()
4198 return Name.GetHashCode ();
4201 public override bool Equals (Object o)
4203 MethodSignature other = (MethodSignature) o;
4205 if (other.Name != Name)
4208 if (other.RetType != RetType)
4211 if (Parameters == null){
4212 if (other.Parameters == null)
4217 if (other.Parameters == null)
4220 int c = Parameters.Length;
4221 if (other.Parameters.Length != c)
4224 for (int i = 0; i < c; i++)
4225 if (other.Parameters [i] != Parameters [i])
4231 static bool MemberSignatureCompare (MemberInfo m, object filter_criteria)
4233 MethodSignature sig = (MethodSignature) filter_criteria;
4235 if (m.Name != sig.Name)
4239 MethodInfo mi = m as MethodInfo;
4240 PropertyInfo pi = m as PropertyInfo;
4243 ReturnType = mi.ReturnType;
4244 else if (pi != null)
4245 ReturnType = pi.PropertyType;
4250 // we use sig.RetType == null to mean `do not check the
4251 // method return value.
4253 if (sig.RetType != null)
4254 if (ReturnType != sig.RetType)
4259 args = TypeManager.GetArgumentTypes (mi);
4261 args = TypeManager.GetArgumentTypes (pi);
4262 Type [] sigp = sig.Parameters;
4264 if (args.Length != sigp.Length)
4267 for (int i = args.Length; i > 0; ){
4269 if (args [i] != sigp [i])
4276 // This filter should be used when we are requesting methods that
4277 // we want to override.
4279 // This makes a number of assumptions, for example
4280 // that the methods being extracted are of a parent
4281 // class (this means we know implicitly that we are
4282 // being called to find out about members by a derived
4285 static bool InheritableMemberSignatureCompare (MemberInfo m, object filter_criteria)
4287 if (MemberSignatureCompare (m, filter_criteria)){
4288 MethodInfo mi = (MethodInfo) m;
4289 MethodAttributes prot = mi.Attributes & MethodAttributes.MemberAccessMask;
4291 // If only accessible to the current class.
4292 if (prot == MethodAttributes.Private)
4295 // If only accessible to the defining assembly or
4296 if (prot == MethodAttributes.FamANDAssem ||
4297 prot == MethodAttributes.Assembly){
4298 if (m.DeclaringType.Assembly == CodeGen.AssemblyBuilder)
4304 // Anything else (FamOrAssembly and Public) is fine
4311 // This filter should be used when we are requesting properties that
4312 // we want to override.
4314 // This makes a number of assumptions, for example
4315 // that the methods being extracted are of a parent
4316 // class (this means we know implicitly that we are
4317 // being called to find out about members by a derived
4320 static bool InheritablePropertySignatureCompare (MemberInfo m, object filter_criteria)
4322 if (MemberSignatureCompare (m, filter_criteria)){
4323 PropertyInfo pi = (PropertyInfo) m;
4325 MethodInfo inherited_get = TypeManager.GetPropertyGetter (pi);
4326 MethodInfo inherited_set = TypeManager.GetPropertySetter (pi);
4328 MethodInfo mi = inherited_get == null ? inherited_set : inherited_get;
4330 MethodAttributes prot = mi.Attributes & MethodAttributes.MemberAccessMask;
4332 // If only accessible to the current class.
4333 if (prot == MethodAttributes.Private)
4336 // If only accessible to the defining assembly or
4337 if (prot == MethodAttributes.FamANDAssem ||
4338 prot == MethodAttributes.Assembly){
4339 if (m.DeclaringType.Assembly == CodeGen.AssemblyBuilder)
4345 // Anything else (FamOrAssembly and Public) is fine