2 // class.cs: Class and Struct handlers
4 // Authors: Miguel de Icaza (miguel@gnu.org)
5 // Martin Baulig (martin@ximian.com)
6 // Marek Safar (marek.safar@seznam.cz)
8 // Licensed under the terms of the GNU GPL
10 // (C) 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
11 // (C) 2004 Novell, Inc
14 // 2002-10-11 Miguel de Icaza <miguel@ximian.com>
16 // * class.cs: Following the comment from 2002-09-26 to AddMethod, I
17 // have fixed a remaining problem: not every AddXXXX was adding a
18 // fully qualified name.
20 // Now everyone registers a fully qualified name in the DeclSpace as
21 // being defined instead of the partial name.
23 // Downsides: we are slower than we need to be due to the excess
24 // copies and the names being registered this way.
26 // The reason for this is that we currently depend (on the corlib
27 // bootstrap for instance) that types are fully qualified, because
28 // we dump all the types in the namespace, and we should really have
29 // types inserted into the proper namespace, so we can only store the
30 // basenames in the defined_names array.
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 {
64 /// This is the base class for structs and classes.
66 public abstract class TypeContainer : DeclSpace, IMemberContainer {
68 public class MemberCoreArrayList: ArrayList
71 /// Defines the MemberCore objects that are in this array
73 public virtual void DefineContainerMembers ()
75 foreach (MemberCore mc in this) {
78 } catch (Exception e) {
79 throw new InternalErrorException (mc, e);
84 public virtual void Emit ()
86 foreach (MemberCore mc in this)
91 public class MethodArrayList : MemberCoreArrayList
99 CachedMethods cached_method;
100 TypeContainer container;
102 public MethodArrayList (TypeContainer container)
104 this.container = container;
108 /// Method container contains Equals method
110 public bool HasEquals {
112 cached_method |= CachedMethods.Equals;
116 return (cached_method & CachedMethods.Equals) != 0;
121 /// Method container contains GetHashCode method
123 public bool HasGetHashCode {
125 cached_method |= CachedMethods.GetHashCode;
129 return (cached_method & CachedMethods.GetHashCode) != 0;
133 public override void DefineContainerMembers ()
135 base.DefineContainerMembers ();
137 if (HasEquals && !HasGetHashCode) {
138 Report.Warning (659, 3, container.Location, "`{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", container.GetSignatureForError ());
143 public sealed class IndexerArrayList : MemberCoreArrayList
146 /// The indexer name for this container
148 public string IndexerName = DefaultIndexerName;
150 bool seen_normal_indexers = false;
152 TypeContainer container;
154 public IndexerArrayList (TypeContainer container)
156 this.container = container;
160 /// Defines the indexers, and also verifies that the IndexerNameAttribute in the
161 /// class is consistent. Either it is `Item' or it is the name defined by all the
162 /// indexers with the `IndexerName' attribute.
164 /// Turns out that the IndexerNameAttribute is applied to each indexer,
165 /// but it is never emitted, instead a DefaultMember attribute is attached
168 public override void DefineContainerMembers()
170 base.DefineContainerMembers ();
172 string class_indexer_name = null;
175 // If there's both an explicit and an implicit interface implementation, the
176 // explicit one actually implements the interface while the other one is just
177 // a normal indexer. See bug #37714.
180 // Invariant maintained by AddIndexer(): All explicit interface indexers precede normal indexers
181 foreach (Indexer i in this) {
182 if (i.InterfaceType != null) {
183 if (seen_normal_indexers)
184 throw new Exception ("Internal Error: 'Indexers' array not sorted properly.");
188 seen_normal_indexers = true;
190 if (class_indexer_name == null) {
191 class_indexer_name = i.ShortName;
195 if (i.ShortName != class_indexer_name)
196 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");
199 if (class_indexer_name != null)
200 IndexerName = class_indexer_name;
203 public override void Emit ()
207 if (!seen_normal_indexers)
210 CustomAttributeBuilder cb = new CustomAttributeBuilder (TypeManager.default_member_ctor, new string [] { IndexerName });
211 container.TypeBuilder.SetCustomAttribute (cb);
215 public class OperatorArrayList: MemberCoreArrayList
217 TypeContainer container;
219 public OperatorArrayList (TypeContainer container)
221 this.container = container;
225 // Operator pair checking
230 public Type ret_type;
231 public Type type1, type2;
233 public Operator.OpType ot;
235 public OperatorEntry (int f, Operator o)
239 ret_type = o.MemberType;
240 Type [] pt = o.ParameterTypes;
247 public override int GetHashCode ()
249 return ret_type.GetHashCode ();
252 public override bool Equals (object o)
254 OperatorEntry other = (OperatorEntry) o;
256 if (other.ret_type != ret_type)
258 if (other.type1 != type1)
260 if (other.type2 != type2)
267 // Checks that some operators come in pairs:
273 // They are matched based on the return type and the argument types
275 void CheckPairedOperators ()
277 IDictionary pairs = new HybridDictionary ();
278 Operator true_op = null;
279 Operator false_op = null;
280 bool has_equality_or_inequality = false;
282 // Register all the operators we care about.
283 foreach (Operator op in this){
286 // Skip erroneous code.
287 if (op.MethodBuilder == null)
290 switch (op.OperatorType){
291 case Operator.OpType.Equality:
293 has_equality_or_inequality = true;
295 case Operator.OpType.Inequality:
297 has_equality_or_inequality = true;
300 case Operator.OpType.True:
303 case Operator.OpType.False:
307 case Operator.OpType.GreaterThan:
309 case Operator.OpType.LessThan:
312 case Operator.OpType.GreaterThanOrEqual:
314 case Operator.OpType.LessThanOrEqual:
320 OperatorEntry oe = new OperatorEntry (reg, op);
322 object o = pairs [oe];
326 oe = (OperatorEntry) o;
331 if (true_op != null){
332 if (false_op == null)
333 Report.Error (216, true_op.Location, "The operator `{0}' requires a matching operator `false' to also be defined",
334 true_op.GetSignatureForError ());
335 } else if (false_op != null)
336 Report.Error (216, false_op.Location, "The operator `{0}' requires a matching operator `true' to also be defined",
337 false_op.GetSignatureForError ());
340 // Look for the mistakes.
342 foreach (DictionaryEntry de in pairs){
343 OperatorEntry oe = (OperatorEntry) de.Key;
350 case Operator.OpType.Equality:
353 case Operator.OpType.Inequality:
356 case Operator.OpType.GreaterThan:
359 case Operator.OpType.LessThan:
362 case Operator.OpType.GreaterThanOrEqual:
365 case Operator.OpType.LessThanOrEqual:
369 Report.Error (216, oe.op.Location,
370 "The operator `{0}' requires a matching operator `{1}' to also be defined",
371 oe.op.GetSignatureForError (), s);
374 if (has_equality_or_inequality && (RootContext.WarningLevel > 2)) {
375 if (container.Methods == null || !container.Methods.HasEquals)
376 Report.Warning (660, 2, container.Location, "`{0}' defines operator == or operator != but does not override Object.Equals(object o)", container.GetSignatureForError ());
378 if (container.Methods == null || !container.Methods.HasGetHashCode)
379 Report.Warning (661, 2, container.Location, "`{0}' defines operator == or operator != but does not override Object.GetHashCode()", container.GetSignatureForError ());
383 public override void DefineContainerMembers ()
385 base.DefineContainerMembers ();
386 CheckPairedOperators ();
391 // Whether this is a struct, class or interface
392 public readonly Kind Kind;
394 // Holds a list of classes and structures
395 protected ArrayList types;
397 // Holds the list of properties
398 MemberCoreArrayList properties;
400 // Holds the list of delegates
401 MemberCoreArrayList delegates;
403 // Holds the list of constructors
404 protected MemberCoreArrayList instance_constructors;
406 // Holds the list of fields
407 MemberCoreArrayList fields;
409 // Holds a list of fields that have initializers
410 protected ArrayList initialized_fields;
412 // Holds a list of static fields that have initializers
413 protected ArrayList initialized_static_fields;
415 // Holds the list of constants
416 MemberCoreArrayList constants;
418 // Holds the methods.
419 MethodArrayList methods;
422 protected MemberCoreArrayList events;
424 // Holds the indexers
425 IndexerArrayList indexers;
427 // Holds the operators
428 MemberCoreArrayList operators;
430 // Holds the compiler generated classes
431 ArrayList compiler_generated;
434 // Pointers to the default constructor and the default static constructor
436 protected Constructor default_constructor;
437 protected Constructor default_static_constructor;
440 // Points to the first non-static field added to the container.
442 // This is an arbitrary choice. We are interested in looking at _some_ non-static field,
443 // and the first one's as good as any.
445 FieldBase first_nonstatic_field = null;
448 // This one is computed after we can distinguish interfaces
449 // from classes from the arraylist `type_bases'
452 TypeExpr[] iface_exprs;
455 ArrayList type_bases;
457 bool members_resolved;
458 bool members_resolved_ok;
459 bool members_defined;
460 bool members_defined_ok;
462 // The interfaces we implement.
463 protected Type[] ifaces;
465 // The base member cache and our member cache
466 MemberCache base_cache;
467 MemberCache member_cache;
469 public const string DefaultIndexerName = "Item";
472 GenericTypeParameterBuilder[] gen_params;
475 ArrayList partial_parts;
478 /// The pending methods that need to be implemented
479 // (interfaces or abstract methods)
481 PendingImplementation pending;
483 public TypeContainer (NamespaceEntry ns, DeclSpace parent, MemberName name,
484 Attributes attrs, Kind kind)
485 : base (ns, parent, name, attrs)
487 if (parent != null && parent.NamespaceEntry != ns)
488 throw new InternalErrorException ("A nested type should be in the same NamespaceEntry as its enclosing class");
491 this.PartialContainer = this;
494 public bool AddMember (MemberCore symbol)
496 return AddToContainer (symbol, symbol.MemberName.MethodName);
499 protected virtual bool AddMemberType (DeclSpace ds)
501 return AddToContainer (ds, ds.Basename);
504 public void AddConstant (Const constant)
506 if (!AddMember (constant))
509 if (constants == null)
510 constants = new MemberCoreArrayList ();
512 constants.Add (constant);
515 public TypeContainer AddTypeContainer (TypeContainer tc)
517 if (!AddMemberType (tc))
521 types = new MemberCoreArrayList ();
527 public virtual TypeContainer AddPartial (TypeContainer nextPart)
529 return AddPartial (nextPart, nextPart.Basename);
532 protected TypeContainer AddPartial (TypeContainer nextPart, string name)
534 nextPart.ModFlags |= Modifiers.PARTIAL;
535 TypeContainer tc = defined_names [name] as TypeContainer;
538 return AddTypeContainer (nextPart);
540 if ((tc.ModFlags & Modifiers.PARTIAL) == 0) {
541 Report.SymbolRelatedToPreviousError (tc);
542 Error_MissingPartialModifier (nextPart);
546 if (tc.Kind != nextPart.Kind) {
547 Report.SymbolRelatedToPreviousError (tc);
548 Report.Error (261, nextPart.Location,
549 "Partial declarations of `{0}' must be all classes, all structs or all interfaces",
550 nextPart.GetSignatureForError ());
554 if ((tc.ModFlags & Modifiers.Accessibility) != (nextPart.ModFlags & Modifiers.Accessibility) &&
555 ((tc.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0 &&
556 (nextPart.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0)) {
557 Report.SymbolRelatedToPreviousError (tc);
558 Report.Error (262, nextPart.Location,
559 "Partial declarations of `{0}' have conflicting accessibility modifiers",
560 nextPart.GetSignatureForError ());
564 if (tc.MemberName.IsGeneric) {
565 TypeParameter[] tc_names = tc.TypeParameters;
566 TypeParameterName[] part_names = nextPart.MemberName.TypeArguments.GetDeclarations ();
568 for (int i = 0; i < tc_names.Length; ++i) {
569 if (tc_names[i].Name == part_names[i].Name)
572 Report.SymbolRelatedToPreviousError (part_names[i].Location, "");
573 Report.Error (264, tc.Location, "Partial declarations of `{0}' must have the same type parameter names in the same order",
574 tc.GetSignatureForError ());
579 if (tc.partial_parts == null)
580 tc.partial_parts = new ArrayList (1);
582 tc.ModFlags |= nextPart.ModFlags;
583 if (nextPart.attributes != null) {
584 if (tc.attributes == null)
585 tc.attributes = nextPart.attributes;
587 tc.attributes.AddAttributes (nextPart.attributes.Attrs);
590 nextPart.PartialContainer = tc;
591 tc.partial_parts.Add (nextPart);
595 public void AddDelegate (Delegate d)
597 if (!AddMemberType (d))
600 if (delegates == null)
601 delegates = new MemberCoreArrayList ();
606 public void AddMethod (Method method)
608 if (!AddMember (method))
612 methods = new MethodArrayList (this);
614 if (method.MemberName.Left != null)
615 methods.Insert (0, method);
617 methods.Add (method);
621 // Do not use this method: use AddMethod.
623 // This is only used by iterators.
625 public void AppendMethod (Method method)
627 if (!AddMember (method))
631 methods = new MethodArrayList (this);
633 methods.Add (method);
636 public void AddConstructor (Constructor c)
638 if (c.Name != MemberName.Name) {
639 Report.Error (1520, c.Location, "Class, struct, or interface method must have a return type");
642 bool is_static = (c.ModFlags & Modifiers.STATIC) != 0;
645 if (default_static_constructor != null) {
646 Report.SymbolRelatedToPreviousError (default_static_constructor);
647 Report.Error (111, c.Location, Error111, c.GetSignatureForError ());
651 default_static_constructor = c;
653 if (c.Parameters.Empty){
654 if (default_constructor != null) {
655 Report.SymbolRelatedToPreviousError (default_constructor);
656 Report.Error (111, c.Location, Error111, c.GetSignatureForError ());
659 default_constructor = c;
662 if (instance_constructors == null)
663 instance_constructors = new MemberCoreArrayList ();
665 instance_constructors.Add (c);
669 internal static string Error111 {
671 return "`{0}' is already defined. Rename this member or use different parameter types";
675 public void AddField (FieldBase field)
677 if (!AddMember (field))
681 fields = new MemberCoreArrayList ();
685 if ((field.ModFlags & Modifiers.STATIC) != 0)
688 if (first_nonstatic_field == null) {
689 first_nonstatic_field = field;
693 if (Kind == Kind.Struct &&
694 first_nonstatic_field.Parent != field.Parent &&
695 RootContext.WarningLevel >= 3) {
696 Report.SymbolRelatedToPreviousError (first_nonstatic_field.Parent);
697 Report.Warning (282, 3, field.Location,
698 "struct instance field `{0}' found in different declaration from instance field `{1}'",
699 field.GetSignatureForError (), first_nonstatic_field.GetSignatureForError ());
703 public void AddProperty (Property prop)
705 if (!AddMember (prop) ||
706 !AddMember (prop.Get) || !AddMember (prop.Set))
709 if (properties == null)
710 properties = new MemberCoreArrayList ();
712 if (prop.MemberName.Left != null)
713 properties.Insert (0, prop);
715 properties.Add (prop);
718 public void AddEvent (Event e)
723 if (e is EventProperty) {
724 if (!AddMember (e.Add))
727 if (!AddMember (e.Remove))
732 events = new MemberCoreArrayList ();
738 /// Indexer has special handling in constrast to other AddXXX because the name can be driven by IndexerNameAttribute
740 public void AddIndexer (Indexer i)
742 if (indexers == null)
743 indexers = new IndexerArrayList (this);
745 if (i.IsExplicitImpl)
746 indexers.Insert (0, i);
751 public void AddOperator (Operator op)
756 if (operators == null)
757 operators = new OperatorArrayList (this);
762 public void AddCompilerGeneratedClass (CompilerGeneratedClass c)
764 Report.Debug (64, "ADD COMPILER GENERATED CLASS", this, c);
766 if (compiler_generated == null)
767 compiler_generated = new ArrayList ();
769 compiler_generated.Add (c);
772 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
774 if (a.Type == TypeManager.default_member_type) {
775 if (Indexers != null) {
776 Report.Error (646, a.Location, "Cannot specify the `DefaultMember' attribute on type containing an indexer");
781 base.ApplyAttributeBuilder (a, cb);
784 public override AttributeTargets AttributeTargets {
786 throw new NotSupportedException ();
790 public ArrayList Types {
796 public MethodArrayList Methods {
802 public ArrayList Constants {
808 public ArrayList CompilerGenerated {
810 return compiler_generated;
814 protected Type BaseType {
816 return TypeBuilder.BaseType;
820 public ArrayList Bases {
830 public ArrayList Fields {
836 public ArrayList InstanceConstructors {
838 return instance_constructors;
842 public ArrayList Properties {
848 public ArrayList Events {
854 public ArrayList Indexers {
860 public ArrayList Operators {
866 public ArrayList Delegates {
872 protected override TypeAttributes TypeAttr {
874 return Modifiers.TypeAttr (ModFlags, IsTopLevel) | base.TypeAttr;
878 public string IndexerName {
880 return indexers == null ? DefaultIndexerName : indexers.IndexerName;
884 public bool IsComImport {
886 if (OptAttributes == null)
889 return OptAttributes.Contains (TypeManager.comimport_attr_type);
893 public virtual void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression)
895 if ((field.ModFlags & Modifiers.STATIC) != 0){
896 if (initialized_static_fields == null)
897 initialized_static_fields = new ArrayList (4);
899 initialized_static_fields.Add (expression);
901 if (initialized_fields == null)
902 initialized_fields = new ArrayList (4);
904 initialized_fields.Add (expression);
909 // Emits the instance field initializers
911 public bool EmitFieldInitializers (EmitContext ec)
916 fields = initialized_static_fields;
918 fields = initialized_fields;
924 foreach (FieldInitializer f in fields) {
925 f.EmitStatement (ec);
930 public override string DocComment {
942 public PendingImplementation PendingImplementations {
943 get { return pending; }
946 public override bool GetClsCompliantAttributeValue ()
948 if (PartialContainer != this)
949 return PartialContainer.GetClsCompliantAttributeValue ();
951 return base.GetClsCompliantAttributeValue ();
954 public void AddBasesForPart (DeclSpace part, ArrayList bases)
956 // FIXME: get rid of partial_parts and store lists of bases of each part here
957 // assumed, not verified: 'part' is in 'partial_parts'
958 ((TypeContainer) part).Bases = bases;
961 TypeExpr[] GetNormalBases (out TypeExpr base_class)
967 int count = Bases.Count;
970 if (Kind == Kind.Class){
971 TypeExpr name = ((Expression) Bases [0]).ResolveAsBaseTerminal (this, false);
977 if (!name.IsInterface) {
978 // base_class could be a class, struct, enum, delegate.
979 // This is validated in GetClassBases.
985 TypeExpr [] ifaces = new TypeExpr [count-start];
987 for (i = start, j = 0; i < count; i++, j++){
988 TypeExpr resolved = ((Expression) Bases [i]).ResolveAsBaseTerminal (this, false);
989 if (resolved == null) {
993 ifaces [j] = resolved;
996 return ifaces.Length == 0 ? null : ifaces;
1000 TypeExpr[] GetNormalPartialBases (ref TypeExpr base_class)
1002 ArrayList ifaces = new ArrayList (0);
1003 if (iface_exprs != null)
1004 ifaces.AddRange (iface_exprs);
1006 foreach (TypeContainer part in partial_parts) {
1007 TypeExpr new_base_class;
1008 TypeExpr[] new_ifaces = part.GetClassBases (out new_base_class);
1009 if (new_base_class != TypeManager.system_object_expr) {
1010 if (base_class == TypeManager.system_object_expr)
1011 base_class = new_base_class;
1013 if (new_base_class != null && !new_base_class.Equals (base_class)) {
1014 Report.SymbolRelatedToPreviousError (base_class.Location, "");
1015 Report.Error (263, part.Location,
1016 "Partial declarations of `{0}' must not specify different base classes",
1017 part.GetSignatureForError ());
1024 if (new_ifaces == null)
1027 foreach (TypeExpr iface in new_ifaces) {
1028 if (ifaces.Contains (iface))
1035 if (ifaces.Count == 0)
1038 return (TypeExpr[])ifaces.ToArray (typeof (TypeExpr));
1042 /// This function computes the Base class and also the
1043 /// list of interfaces that the class or struct @c implements.
1045 /// The return value is an array (might be null) of
1046 /// interfaces implemented (as Types).
1048 /// The @base_class argument is set to the base object or null
1049 /// if this is `System.Object'.
1051 public virtual TypeExpr [] GetClassBases (out TypeExpr base_class)
1053 TypeExpr[] ifaces = GetNormalBases (out base_class);
1058 int count = ifaces.Length;
1060 for (int i = 0; i < count; i++) {
1061 TypeExpr iface = (TypeExpr) ifaces [i];
1063 if (!iface.IsInterface) {
1064 if (Kind != Kind.Class) {
1065 // TODO: location of symbol related ....
1066 Error_TypeInListIsNotInterface (Location, iface.GetSignatureForError ());
1068 else if (base_class != null)
1069 Report.Error (1721, Location, "`{0}': Classes cannot have multiple base classes (`{1}' and `{2}')",
1070 GetSignatureForError (), base_class.GetSignatureForError (), iface.GetSignatureForError ());
1072 Report.Error (1722, Location, "`{0}': Base class `{1}' must be specified as first",
1073 GetSignatureForError (), iface.GetSignatureForError ());
1078 for (int x = 0; x < i; x++) {
1079 if (iface.Equals (ifaces [x])) {
1080 Report.Error (528, Location,
1081 "`{0}' is already listed in " +
1082 "interface list", iface.GetSignatureForError ());
1087 if ((Kind == Kind.Interface) &&
1088 !iface.AsAccessible (Parent, ModFlags)) {
1089 Report.Error (61, Location,
1090 "Inconsistent accessibility: base " +
1091 "interface `{0}' is less accessible " +
1092 "than interface `{1}'", iface.Name,
1100 bool CheckGenericInterfaces (Type[] ifaces)
1103 ArrayList already_checked = new ArrayList ();
1105 for (int i = 0; i < ifaces.Length; i++) {
1106 Type iface = ifaces [i];
1107 foreach (Type t in already_checked) {
1111 Type[] inferred = new Type [CountTypeParameters];
1112 if (!TypeManager.MayBecomeEqualGenericInstances (iface, t, inferred, null))
1115 Report.Error (695, Location,
1116 "`{0}' cannot implement both `{1}' and `{2}' " +
1117 "because they may unify for some type parameter substitutions",
1118 TypeManager.CSharpName (TypeBuilder), TypeManager.CSharpName (iface),
1119 TypeManager.CSharpName (t));
1123 already_checked.Add (iface);
1132 protected void Error_TypeInListIsNotInterface (Location loc, string type)
1134 Report.Error (527, loc, "Type `{0}' in interface list is not an interface", type);
1137 bool CreateTypeBuilder ()
1140 Type default_parent = null;
1141 if (Kind == Kind.Struct)
1142 default_parent = TypeManager.value_type;
1143 else if (Kind == Kind.Enum)
1144 default_parent = TypeManager.enum_type;
1147 if (TypeManager.NamespaceClash (Name, Location)) {
1151 ModuleBuilder builder = CodeGen.Module.Builder;
1152 TypeBuilder = builder.DefineType (
1153 Name, TypeAttr, default_parent, null);
1155 TypeBuilder builder = Parent.TypeBuilder;
1157 TypeBuilder = builder.DefineNestedType (
1158 Basename, TypeAttr, default_parent, null);
1160 } catch (ArgumentException) {
1161 Report.RuntimeMissingSupport (Location, "static classes");
1165 TypeManager.AddUserType (this);
1169 string[] param_names = new string [TypeParameters.Length];
1170 for (int i = 0; i < TypeParameters.Length; i++)
1171 param_names [i] = TypeParameters [i].Name;
1173 gen_params = TypeBuilder.DefineGenericParameters (param_names);
1175 int offset = CountTypeParameters - CurrentTypeParameters.Length;
1176 for (int i = offset; i < gen_params.Length; i++)
1177 CurrentTypeParameters [i - offset].Define (gen_params [i]);
1184 bool DefineBaseTypes ()
1186 iface_exprs = GetClassBases (out base_type);
1187 if (partial_parts != null) {
1188 iface_exprs = GetNormalPartialBases (ref base_type);
1192 // GetClassBases calls ResolveBaseTypeExpr() on the various type expressions involved,
1193 // which in turn should have called DefineType()s on base types if necessary.
1195 // None of the code below should trigger DefineType()s on classes that we depend on.
1196 // Thus, we are eligible to be on the topological sort `type_container_resolve_order'.
1198 // Let's do it as soon as possible, since code below can call DefineType() on classes
1199 // that depend on us to be populated before they are.
1201 if (!(this is CompilerGeneratedClass))
1202 RootContext.RegisterOrder (this);
1204 if (IsGeneric && base_type != null && TypeManager.IsAttributeType (base_type.Type)) {
1205 Report.Error (698, base_type.Location,
1206 "A generic type cannot derive from `{0}' because it is an attribute class",
1211 if (!CheckRecursiveDefinition (this))
1214 if (base_type != null) {
1215 TypeBuilder.SetParent (base_type.Type);
1217 ObsoleteAttribute obsolete_attr = AttributeTester.GetObsoleteAttribute (base_type.Type);
1218 if (obsolete_attr != null && !IsInObsoleteScope)
1219 AttributeTester.Report_ObsoleteMessage (obsolete_attr, base_type.GetSignatureForError (), Location);
1222 // add interfaces that were not added at type creation
1223 if (iface_exprs != null) {
1224 ifaces = TypeManager.ExpandInterfaces (iface_exprs);
1228 foreach (Type itype in ifaces)
1229 TypeBuilder.AddInterfaceImplementation (itype);
1231 foreach (TypeExpr ie in iface_exprs) {
1232 ObsoleteAttribute oa = AttributeTester.GetObsoleteAttribute (ie.Type);
1233 if ((oa != null) && !IsInObsoleteScope)
1234 AttributeTester.Report_ObsoleteMessage (
1235 oa, ie.GetSignatureForError (), Location);
1238 if (!CheckGenericInterfaces (ifaces))
1241 TypeManager.RegisterBuilder (TypeBuilder, ifaces);
1248 // Defines the type in the appropriate ModuleBuilder or TypeBuilder.
1250 public TypeBuilder CreateType ()
1252 if (TypeBuilder != null)
1258 if (!CreateTypeBuilder ()) {
1263 if (partial_parts != null) {
1264 foreach (TypeContainer part in partial_parts)
1265 part.TypeBuilder = TypeBuilder;
1268 if (Types != null) {
1269 foreach (TypeContainer tc in Types) {
1270 if (tc.CreateType () == null) {
1282 public override TypeBuilder DefineType ()
1289 type_defined = true;
1291 if (CreateType () == null) {
1296 if (!DefineBaseTypes ()) {
1301 if (!(this is CompilerGeneratedClass)) {
1302 if (!ResolveMembers ()) {
1308 if (!DefineNestedTypes ()) {
1316 public bool ResolveMembers ()
1318 if (members_resolved)
1319 return members_resolved_ok;
1321 members_resolved_ok = DoResolveMembers ();
1322 members_resolved = true;
1324 return members_resolved_ok;
1327 protected virtual bool DoResolveMembers ()
1329 if (methods != null) {
1330 foreach (Method method in methods) {
1331 if (!method.ResolveMembers ())
1336 if (instance_constructors != null) {
1337 foreach (Constructor c in instance_constructors) {
1338 if (!c.ResolveMembers ())
1343 if (default_static_constructor != null) {
1344 if (!default_static_constructor.ResolveMembers ())
1348 if (operators != null) {
1349 foreach (Operator o in operators) {
1350 if (!o.ResolveMembers ())
1355 if (properties != null) {
1356 foreach (PropertyBase p in properties) {
1357 if (!p.Get.IsDummy && !p.Get.ResolveMembers ())
1359 if (!p.Set.IsDummy && !p.Set.ResolveMembers ())
1364 if (indexers != null) {
1365 foreach (PropertyBase p in indexers) {
1366 if (!p.Get.IsDummy && !p.Get.ResolveMembers ())
1368 if (!p.Set.IsDummy && !p.Set.ResolveMembers ())
1373 if (events != null) {
1374 foreach (Event e in events) {
1375 if (!e.Add.ResolveMembers ())
1377 if (!e.Remove.ResolveMembers ())
1382 if (compiler_generated != null) {
1383 foreach (CompilerGeneratedClass c in compiler_generated) {
1384 if (c.DefineType () == null)
1392 Constraints [] constraints;
1393 public override void SetParameterInfo (ArrayList constraints_list)
1395 if (PartialContainer == this) {
1396 base.SetParameterInfo (constraints_list);
1400 if (constraints_list == null)
1403 constraints = new Constraints [PartialContainer.CountCurrentTypeParameters];
1405 TypeParameter[] current_params = PartialContainer.CurrentTypeParameters;
1406 for (int i = 0; i < constraints.Length; i++) {
1407 foreach (Constraints constraint in constraints_list) {
1408 if (constraint.TypeParameter == current_params [i].Name) {
1409 constraints [i] = constraint;
1416 bool UpdateTypeParameterConstraints ()
1418 if (constraints == null)
1421 TypeParameter[] current_params = PartialContainer.CurrentTypeParameters;
1422 for (int i = 0; i < current_params.Length; i++) {
1423 if (!current_params [i].UpdateConstraints (this, constraints [i])) {
1424 Report.SymbolRelatedToPreviousError (Location, "");
1425 Report.Error (265, PartialContainer.Location,
1426 "Partial declarations of `{0}' have inconsistent constraints for type parameter `{1}'",
1427 PartialContainer.GetSignatureForError (), current_params [i].Name);
1435 public bool ResolveType ()
1437 if (!DoResolveType ())
1440 if (compiler_generated != null) {
1441 foreach (CompilerGeneratedClass c in compiler_generated)
1442 if (!c.ResolveType ())
1449 protected virtual bool DoResolveType ()
1451 if ((base_type != null) &&
1452 (base_type.ResolveAsTypeTerminal (this, false) == null)) {
1460 if (PartialContainer != this)
1461 throw new InternalErrorException ();
1463 TypeExpr current_type = null;
1465 foreach (TypeParameter type_param in CurrentTypeParameters) {
1466 if (!type_param.Resolve (this)) {
1472 if (partial_parts != null) {
1473 foreach (TypeContainer part in partial_parts) {
1474 if (!part.UpdateTypeParameterConstraints ()) {
1481 foreach (TypeParameter type_param in TypeParameters) {
1482 if (!type_param.DefineType (this)) {
1488 current_type = new ConstructedType (TypeBuilder, TypeParameters, Location);
1490 foreach (TypeParameter type_param in TypeParameters)
1491 if (!type_param.CheckDependencies ()) {
1496 if (current_type != null) {
1497 current_type = current_type.ResolveAsTypeTerminal (this, false);
1498 if (current_type == null) {
1503 CurrentType = current_type.Type;
1509 protected virtual bool DefineNestedTypes ()
1511 if (Types != null) {
1512 foreach (TypeContainer tc in Types)
1513 if (tc.DefineType () == null)
1517 if (Delegates != null) {
1518 foreach (Delegate d in Delegates)
1519 if (d.DefineType () == null)
1526 TypeContainer InTransit;
1528 protected bool CheckRecursiveDefinition (TypeContainer tc)
1530 if (InTransit != null) {
1531 Report.SymbolRelatedToPreviousError (this);
1532 if (this is Interface)
1534 529, tc.Location, "Inherited interface `{0}' causes a " +
1535 "cycle in the interface hierarchy of `{1}'",
1536 GetSignatureForError (), tc.GetSignatureForError ());
1539 146, tc.Location, "Circular base class dependency " +
1540 "involving `{0}' and `{1}'",
1541 tc.GetSignatureForError (), GetSignatureForError ());
1547 if (base_type != null) {
1548 Type t = TypeManager.DropGenericTypeArguments (base_type.Type);
1549 TypeContainer ptc = TypeManager.LookupTypeContainer (t);
1550 if ((ptc != null) && !ptc.CheckRecursiveDefinition (this))
1554 if (iface_exprs != null) {
1555 foreach (TypeExpr iface in iface_exprs) {
1556 Type itype = TypeManager.DropGenericTypeArguments (iface.Type);
1557 TypeContainer ptc = TypeManager.LookupTypeContainer (itype);
1558 if ((ptc != null) && !ptc.CheckRecursiveDefinition (this))
1563 if (!IsTopLevel && !Parent.PartialContainer.CheckRecursiveDefinition (this))
1570 public static void Error_KeywordNotAllowed (Location loc)
1572 Report.Error (1530, loc, "Keyword `new' is not allowed on namespace elements");
1576 /// Populates our TypeBuilder with fields and methods
1578 public override bool DefineMembers ()
1580 if (members_defined)
1581 return members_defined_ok;
1583 if (!base.DefineMembers ())
1586 members_defined_ok = DoDefineMembers ();
1587 members_defined = true;
1589 return members_defined_ok;
1592 protected virtual bool DoDefineMembers ()
1594 if (iface_exprs != null) {
1595 foreach (TypeExpr iface in iface_exprs) {
1596 ConstructedType ct = iface as ConstructedType;
1597 if ((ct != null) && !ct.CheckConstraints (this))
1602 if (base_type != null) {
1603 ConstructedType ct = base_type as ConstructedType;
1604 if ((ct != null) && !ct.CheckConstraints (this))
1609 MemberInfo conflict_symbol = Parent.PartialContainer.FindBaseMemberWithSameName (Basename, false);
1610 if (conflict_symbol == null) {
1611 if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0))
1612 Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
1614 if ((ModFlags & Modifiers.NEW) == 0) {
1615 Report.SymbolRelatedToPreviousError (conflict_symbol);
1616 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
1617 GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
1622 DefineContainerMembers (constants);
1623 DefineContainerMembers (fields);
1625 if (Kind == Kind.Struct || Kind == Kind.Class) {
1626 pending = PendingImplementation.GetPendingImplementations (this);
1630 // Constructors are not in the defined_names array
1632 DefineContainerMembers (instance_constructors);
1634 DefineContainerMembers (properties);
1635 DefineContainerMembers (events);
1636 DefineContainerMembers (indexers);
1637 DefineContainerMembers (methods);
1638 DefineContainerMembers (operators);
1639 DefineContainerMembers (delegates);
1641 if (CurrentType != null) {
1642 GenericType = CurrentType;
1646 member_cache = new MemberCache (this);
1647 if (partial_parts != null) {
1648 foreach (TypeContainer part in partial_parts)
1649 part.member_cache = member_cache;
1656 protected virtual void DefineContainerMembers (MemberCoreArrayList mcal)
1659 mcal.DefineContainerMembers ();
1662 public override bool Define ()
1664 if (compiler_generated != null) {
1665 foreach (CompilerGeneratedClass c in compiler_generated) {
1674 public MemberInfo FindBaseMemberWithSameName (string name, bool ignore_methods)
1676 return BaseCache == null ? null : BaseCache.FindMemberWithSameName (name, ignore_methods, null);
1680 /// This function is based by a delegate to the FindMembers routine
1682 static bool AlwaysAccept (MemberInfo m, object filterCriteria)
1688 /// This filter is used by FindMembers, and we just keep
1689 /// a global for the filter to `AlwaysAccept'
1691 static MemberFilter accepting_filter;
1694 static TypeContainer ()
1696 accepting_filter = new MemberFilter (AlwaysAccept);
1699 public MethodInfo[] GetMethods ()
1701 ArrayList members = new ArrayList ();
1705 if (methods != null) {
1706 int len = methods.Count;
1707 for (int i = 0; i < len; i++) {
1708 Method m = (Method) methods [i];
1710 members.Add (m.MethodBuilder);
1714 if (operators != null) {
1715 int len = operators.Count;
1716 for (int i = 0; i < len; i++) {
1717 Operator o = (Operator) operators [i];
1719 members.Add (o.MethodBuilder);
1723 if (properties != null) {
1724 int len = properties.Count;
1725 for (int i = 0; i < len; i++) {
1726 Property p = (Property) properties [i];
1728 if (p.GetBuilder != null)
1729 members.Add (p.GetBuilder);
1730 if (p.SetBuilder != null)
1731 members.Add (p.SetBuilder);
1735 if (indexers != null) {
1736 int len = indexers.Count;
1737 for (int i = 0; i < len; i++) {
1738 Indexer ix = (Indexer) indexers [i];
1740 if (ix.GetBuilder != null)
1741 members.Add (ix.GetBuilder);
1742 if (ix.SetBuilder != null)
1743 members.Add (ix.SetBuilder);
1747 if (events != null) {
1748 int len = events.Count;
1749 for (int i = 0; i < len; i++) {
1750 Event e = (Event) events [i];
1752 if (e.AddBuilder != null)
1753 members.Add (e.AddBuilder);
1754 if (e.RemoveBuilder != null)
1755 members.Add (e.RemoveBuilder);
1759 MethodInfo[] retMethods = new MethodInfo [members.Count];
1760 members.CopyTo (retMethods, 0);
1764 // Indicated whether container has StructLayout attribute set Explicit
1765 public bool HasExplicitLayout {
1766 get { return (caching_flags & Flags.HasExplicitLayout) != 0; }
1767 set { caching_flags |= Flags.HasExplicitLayout; }
1771 // Return the nested type with name @name. Ensures that the nested type
1772 // is defined if necessary. Do _not_ use this when you have a MemberCache handy.
1774 public Type FindNestedType (string name)
1776 if (PartialContainer != this)
1777 throw new InternalErrorException ("should not happen");
1779 ArrayList [] lists = { types, delegates };
1781 for (int j = 0; j < lists.Length; ++j) {
1782 ArrayList list = lists [j];
1786 int len = list.Count;
1787 for (int i = 0; i < len; ++i) {
1788 DeclSpace ds = (DeclSpace) list [i];
1789 if (ds.Basename == name) {
1790 return ds.DefineType ();
1798 private void FindMembers_NestedTypes (int modflags,
1799 BindingFlags bf, MemberFilter filter, object criteria,
1800 ref ArrayList members)
1802 ArrayList [] lists = { types, delegates };
1804 for (int j = 0; j < lists.Length; ++j) {
1805 ArrayList list = lists [j];
1809 int len = list.Count;
1810 for (int i = 0; i < len; i++) {
1811 DeclSpace ds = (DeclSpace) list [i];
1813 if ((ds.ModFlags & modflags) == 0)
1816 TypeBuilder tb = ds.TypeBuilder;
1818 if (!(criteria is string) || ds.Basename.Equals (criteria))
1819 tb = ds.DefineType ();
1822 if (tb != null && (filter (tb, criteria) == true)) {
1823 if (members == null)
1824 members = new ArrayList ();
1833 /// This method returns the members of this type just like Type.FindMembers would
1834 /// Only, we need to use this for types which are _being_ defined because MS'
1835 /// implementation can't take care of that.
1838 // FIXME: return an empty static array instead of null, that cleans up
1839 // some code and is consistent with some coding conventions I just found
1843 // Notice that in various cases we check if our field is non-null,
1844 // something that would normally mean that there was a bug elsewhere.
1846 // The problem happens while we are defining p-invoke methods, as those
1847 // will trigger a FindMembers, but this happens before things are defined
1849 // Since the whole process is a no-op, it is fine to check for null here.
1851 public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
1852 MemberFilter filter, object criteria)
1854 ArrayList members = null;
1857 if ((bf & BindingFlags.Public) != 0)
1858 modflags |= Modifiers.PUBLIC | Modifiers.PROTECTED |
1860 if ((bf & BindingFlags.NonPublic) != 0)
1861 modflags |= Modifiers.PRIVATE;
1863 int static_mask = 0, static_flags = 0;
1864 switch (bf & (BindingFlags.Static | BindingFlags.Instance)) {
1865 case BindingFlags.Static:
1866 static_mask = static_flags = Modifiers.STATIC;
1869 case BindingFlags.Instance:
1870 static_mask = Modifiers.STATIC;
1875 static_mask = static_flags = 0;
1879 Timer.StartTimer (TimerType.TcFindMembers);
1882 filter = accepting_filter;
1884 if ((mt & MemberTypes.Field) != 0) {
1885 if (fields != null) {
1886 int len = fields.Count;
1887 for (int i = 0; i < len; i++) {
1888 FieldBase f = (FieldBase) fields [i];
1890 if ((f.ModFlags & modflags) == 0)
1892 if ((f.ModFlags & static_mask) != static_flags)
1895 FieldBuilder fb = f.FieldBuilder;
1896 if (fb != null && filter (fb, criteria) == true) {
1897 if (members == null)
1898 members = new ArrayList ();
1905 if (constants != null) {
1906 int len = constants.Count;
1907 for (int i = 0; i < len; i++) {
1908 Const con = (Const) constants [i];
1910 if ((con.ModFlags & modflags) == 0)
1912 if ((con.ModFlags & static_mask) != static_flags)
1915 FieldBuilder fb = con.FieldBuilder;
1918 fb = con.FieldBuilder;
1920 if (fb != null && filter (fb, criteria) == true) {
1921 if (members == null)
1922 members = new ArrayList ();
1930 if ((mt & MemberTypes.Method) != 0) {
1931 if (methods != null) {
1932 int len = methods.Count;
1933 for (int i = 0; i < len; i++) {
1934 Method m = (Method) methods [i];
1936 if ((m.ModFlags & modflags) == 0)
1938 if ((m.ModFlags & static_mask) != static_flags)
1941 MethodBuilder mb = m.MethodBuilder;
1943 if (mb != null && filter (mb, criteria) == true) {
1944 if (members == null)
1945 members = new ArrayList ();
1952 if (operators != null) {
1953 int len = operators.Count;
1954 for (int i = 0; i < len; i++) {
1955 Operator o = (Operator) operators [i];
1957 if ((o.ModFlags & modflags) == 0)
1959 if ((o.ModFlags & static_mask) != static_flags)
1962 MethodBuilder ob = o.MethodBuilder;
1963 if (ob != null && filter (ob, criteria) == true) {
1964 if (members == null)
1965 members = new ArrayList ();
1972 if (events != null) {
1973 foreach (Event e in events) {
1974 if ((e.ModFlags & modflags) == 0)
1976 if ((e.ModFlags & static_mask) != static_flags)
1979 MethodBuilder b = e.AddBuilder;
1980 if (b != null && filter (b, criteria)) {
1981 if (members == null)
1982 members = new ArrayList (4);
1987 b = e.RemoveBuilder;
1988 if (b != null && filter (b, criteria)) {
1989 if (members == null)
1990 members = new ArrayList (4);
1997 if (properties != null) {
1998 int len = properties.Count;
1999 for (int i = 0; i < len; i++) {
2000 Property p = (Property) properties [i];
2002 if ((p.ModFlags & modflags) == 0)
2004 if ((p.ModFlags & static_mask) != static_flags)
2010 if (b != null && filter (b, criteria) == true) {
2011 if (members == null)
2012 members = new ArrayList ();
2018 if (b != null && filter (b, criteria) == true) {
2019 if (members == null)
2020 members = new ArrayList ();
2027 if (indexers != null) {
2028 int len = indexers.Count;
2029 for (int i = 0; i < len; i++) {
2030 Indexer ix = (Indexer) indexers [i];
2032 if ((ix.ModFlags & modflags) == 0)
2034 if ((ix.ModFlags & static_mask) != static_flags)
2040 if (b != null && filter (b, criteria) == true) {
2041 if (members == null)
2042 members = new ArrayList ();
2048 if (b != null && filter (b, criteria) == true) {
2049 if (members == null)
2050 members = new ArrayList ();
2058 if ((mt & MemberTypes.Event) != 0) {
2059 if (events != null) {
2060 int len = events.Count;
2061 for (int i = 0; i < len; i++) {
2062 Event e = (Event) events [i];
2064 if ((e.ModFlags & modflags) == 0)
2066 if ((e.ModFlags & static_mask) != static_flags)
2069 MemberInfo eb = e.EventBuilder;
2070 if (eb != null && filter (eb, criteria) == true) {
2071 if (members == null)
2072 members = new ArrayList ();
2074 members.Add (e.EventBuilder);
2080 if ((mt & MemberTypes.Property) != 0){
2081 if (properties != null) {
2082 int len = properties.Count;
2083 for (int i = 0; i < len; i++) {
2084 Property p = (Property) properties [i];
2086 if ((p.ModFlags & modflags) == 0)
2088 if ((p.ModFlags & static_mask) != static_flags)
2091 MemberInfo pb = p.PropertyBuilder;
2092 if (pb != null && filter (pb, criteria) == true) {
2093 if (members == null)
2094 members = new ArrayList ();
2096 members.Add (p.PropertyBuilder);
2101 if (indexers != null) {
2102 int len = indexers.Count;
2103 for (int i = 0; i < len; i++) {
2104 Indexer ix = (Indexer) indexers [i];
2106 if ((ix.ModFlags & modflags) == 0)
2108 if ((ix.ModFlags & static_mask) != static_flags)
2111 MemberInfo ib = ix.PropertyBuilder;
2112 if (ib != null && filter (ib, criteria) == true) {
2113 if (members == null)
2114 members = new ArrayList ();
2116 members.Add (ix.PropertyBuilder);
2122 if ((mt & MemberTypes.NestedType) != 0)
2123 FindMembers_NestedTypes (modflags, bf, filter, criteria, ref members);
2125 if ((mt & MemberTypes.Constructor) != 0){
2126 if (((bf & BindingFlags.Instance) != 0) && (instance_constructors != null)){
2127 int len = instance_constructors.Count;
2128 for (int i = 0; i < len; i++) {
2129 Constructor c = (Constructor) instance_constructors [i];
2131 ConstructorBuilder cb = c.ConstructorBuilder;
2132 if (cb != null && filter (cb, criteria) == true) {
2133 if (members == null)
2134 members = new ArrayList ();
2141 if (((bf & BindingFlags.Static) != 0) && (default_static_constructor != null)){
2142 ConstructorBuilder cb =
2143 default_static_constructor.ConstructorBuilder;
2145 if (cb != null && filter (cb, criteria) == true) {
2146 if (members == null)
2147 members = new ArrayList ();
2155 // Lookup members in base if requested.
2157 if ((bf & BindingFlags.DeclaredOnly) == 0) {
2158 if (TypeBuilder.BaseType != null) {
2159 MemberList list = FindMembers (TypeBuilder.BaseType, mt, bf, filter, criteria);
2160 if (list.Count > 0) {
2161 if (members == null)
2162 members = new ArrayList ();
2164 members.AddRange (list);
2169 Timer.StopTimer (TimerType.TcFindMembers);
2171 if (members == null)
2172 return MemberList.Empty;
2174 return new MemberList (members);
2177 public override MemberCache MemberCache {
2179 return member_cache;
2183 public static MemberList FindMembers (Type t, MemberTypes mt, BindingFlags bf,
2184 MemberFilter filter, object criteria)
2186 DeclSpace ds = TypeManager.LookupDeclSpace (t);
2189 return ds.FindMembers (mt, bf, filter, criteria);
2191 return new MemberList (t.FindMembers (mt, bf, filter, criteria));
2195 /// Emits the values for the constants
2197 public void EmitConstants ()
2199 if (constants != null)
2200 foreach (Const con in constants)
2205 static void CheckMemberUsage (MemberCoreArrayList al, string member_type)
2210 foreach (MemberCore mc in al) {
2211 if ((mc.ModFlags & Modifiers.Accessibility) != Modifiers.PRIVATE)
2215 Report.Warning (169, 3, mc.Location, "The private {0} `{1}' is never used", member_type, mc.GetSignatureForError ());
2220 public virtual void VerifyMembers ()
2223 // Check for internal or private fields that were never assigned
2225 if (RootContext.WarningLevel >= 3) {
2226 CheckMemberUsage (properties, "property");
2227 CheckMemberUsage (methods, "method");
2228 CheckMemberUsage (constants, "constant");
2230 if (fields != null){
2231 foreach (FieldBase f in fields) {
2232 if ((f.ModFlags & Modifiers.Accessibility) != Modifiers.PRIVATE)
2236 if ((f.caching_flags & Flags.IsAssigned) == 0)
2237 Report.Warning (169, 3, f.Location, "The private field `{0}' is never used", f.GetSignatureForError ());
2240 const int error_code = 414;
2242 const int error_code = 169;
2244 Report.Warning (error_code, 3, f.Location, "The private field `{0}' is assigned but its value is never used",
2245 f.GetSignatureForError ());
2251 // Only report 649 on level 4
2253 if (RootContext.WarningLevel < 4)
2256 if ((f.caching_flags & Flags.IsAssigned) != 0)
2259 Constant c = New.Constantify (f.Type.Type);
2260 Report.Warning (649, 4, f.Location, "Field `{0}' is never assigned to, and will always have its default value `{1}'",
2261 f.GetSignatureForError (), c == null ? "null" : c.AsString ());
2267 // TODO: move to ClassOrStruct
2268 void EmitConstructors ()
2270 if (instance_constructors == null)
2273 if (TypeBuilder.IsSubclassOf (TypeManager.attribute_type) && RootContext.VerifyClsCompliance && IsClsComplianceRequired ()) {
2274 bool has_compliant_args = false;
2276 foreach (Constructor c in instance_constructors) {
2280 catch (Exception e) {
2281 throw new InternalErrorException (c, e);
2284 if (has_compliant_args)
2287 has_compliant_args = c.HasCompliantArgs;
2289 if (!has_compliant_args)
2290 Report.Error (3015, Location, "`{0}' has no accessible constructors which use only CLS-compliant types", GetSignatureForError ());
2292 foreach (Constructor c in instance_constructors) {
2296 catch (Exception e) {
2297 throw new InternalErrorException (c, e);
2304 /// Emits the code, this step is performed after all
2305 /// the types, enumerations, constructors
2307 public virtual void EmitType ()
2309 if (OptAttributes != null)
2310 OptAttributes.Emit ();
2314 int offset = CountTypeParameters - CurrentTypeParameters.Length;
2315 for (int i = offset; i < gen_params.Length; i++)
2316 CurrentTypeParameters [i - offset].EmitAttributes ();
2321 // Structs with no fields need to have at least one byte.
2322 // The right thing would be to set the PackingSize in a DefineType
2323 // but there are no functions that allow interfaces *and* the size to
2327 if (Kind == Kind.Struct && first_nonstatic_field == null){
2328 FieldBuilder fb = TypeBuilder.DefineField ("$PRIVATE$", TypeManager.byte_type,
2329 FieldAttributes.Private);
2331 if (HasExplicitLayout){
2332 object [] ctor_args = new object [1];
2335 CustomAttributeBuilder cba = new CustomAttributeBuilder (
2336 TypeManager.field_offset_attribute_ctor, ctor_args);
2337 fb.SetCustomAttribute (cba);
2343 EmitConstructors ();
2345 // Can not continue if constants are broken
2347 if (Report.Errors > 0)
2350 if (default_static_constructor != null)
2351 default_static_constructor.Emit ();
2353 if (methods != null){
2354 foreach (Method m in methods)
2358 if (operators != null)
2359 foreach (Operator o in operators)
2362 if (properties != null)
2363 foreach (Property p in properties)
2366 if (indexers != null){
2371 foreach (FieldBase f in fields)
2374 if (events != null){
2375 foreach (Event e in Events)
2379 if (delegates != null) {
2380 foreach (Delegate d in Delegates) {
2385 if (pending != null)
2386 if (pending.VerifyPendingMethods ())
2389 if (Report.Errors > 0)
2392 if (compiler_generated != null) {
2393 foreach (CompilerGeneratedClass c in compiler_generated) {
2394 if (!c.DefineMembers ())
2395 throw new InternalErrorException ();
2397 foreach (CompilerGeneratedClass c in compiler_generated)
2402 public override void CloseType ()
2404 if ((caching_flags & Flags.CloseTypeCreated) != 0)
2408 caching_flags |= Flags.CloseTypeCreated;
2409 TypeBuilder.CreateType ();
2410 } catch (TypeLoadException){
2412 // This is fine, the code still created the type
2414 // Report.Warning (-20, "Exception while creating class: " + TypeBuilder.Name);
2415 // Console.WriteLine (e.Message);
2416 } catch (Exception e) {
2417 throw new InternalErrorException (this, e);
2421 foreach (TypeContainer tc in Types)
2422 if (tc.Kind == Kind.Struct)
2425 foreach (TypeContainer tc in Types)
2426 if (tc.Kind != Kind.Struct)
2430 if (Delegates != null)
2431 foreach (Delegate d in Delegates)
2434 if (CompilerGenerated != null)
2435 foreach (CompilerGeneratedClass c in CompilerGenerated)
2442 initialized_fields = null;
2443 initialized_static_fields = null;
2449 compiler_generated = null;
2450 default_constructor = null;
2451 default_static_constructor = null;
2453 OptAttributes = null;
2456 member_cache = null;
2460 // Performs the validation on a Method's modifiers (properties have
2461 // the same properties).
2463 public bool MethodModifiersValid (MemberCore mc)
2465 const int vao = (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE);
2466 const int va = (Modifiers.VIRTUAL | Modifiers.ABSTRACT);
2467 const int nv = (Modifiers.NEW | Modifiers.VIRTUAL);
2469 int flags = mc.ModFlags;
2472 // At most one of static, virtual or override
2474 if ((flags & Modifiers.STATIC) != 0){
2475 if ((flags & vao) != 0){
2476 Report.Error (112, mc.Location, "A static member `{0}' cannot be marked as override, virtual or abstract",
2477 mc.GetSignatureForError ());
2482 if (Kind == Kind.Struct){
2483 if ((flags & va) != 0){
2484 Modifiers.Error_InvalidModifier (mc.Location, "virtual or abstract");
2489 if ((flags & Modifiers.OVERRIDE) != 0 && (flags & nv) != 0){
2490 Report.Error (113, mc.Location, "A member `{0}' marked as override cannot be marked as new or virtual",
2491 mc.GetSignatureForError ());
2496 // If the declaration includes the abstract modifier, then the
2497 // declaration does not include static, virtual or extern
2499 if ((flags & Modifiers.ABSTRACT) != 0){
2500 if ((flags & Modifiers.EXTERN) != 0){
2502 180, mc.Location, "`{0}' cannot be both extern and abstract", mc.GetSignatureForError ());
2506 if ((flags & Modifiers.SEALED) != 0) {
2507 Report.Error (502, mc.Location, "`{0}' cannot be both abstract and sealed", mc.GetSignatureForError ());
2511 if ((flags & Modifiers.VIRTUAL) != 0){
2512 Report.Error (503, mc.Location, "The abstract method `{0}' cannot be marked virtual", mc.GetSignatureForError ());
2516 if ((ModFlags & Modifiers.ABSTRACT) == 0){
2517 Report.SymbolRelatedToPreviousError (this);
2518 Report.Error (513, mc.Location, "`{0}' is abstract but it is declared in the non-abstract class `{1}'",
2519 mc.GetSignatureForError (), GetSignatureForError ());
2524 if ((flags & Modifiers.PRIVATE) != 0){
2525 if ((flags & vao) != 0){
2526 Report.Error (621, mc.Location, "`{0}': virtual or abstract members cannot be private", mc.GetSignatureForError ());
2531 if ((flags & Modifiers.SEALED) != 0){
2532 if ((flags & Modifiers.OVERRIDE) == 0){
2533 Report.Error (238, mc.Location, "`{0}' cannot be sealed because it is not an override", mc.GetSignatureForError ());
2541 public Constructor DefaultStaticConstructor {
2542 get { return default_static_constructor; }
2545 protected override bool VerifyClsCompliance ()
2547 if (!base.VerifyClsCompliance ())
2552 Type base_type = TypeBuilder.BaseType;
2553 if (base_type != null && !AttributeTester.IsClsCompliant (base_type)) {
2554 Report.Error (3009, Location, "`{0}': base type `{1}' is not CLS-compliant", GetSignatureForError (), TypeManager.CSharpName (base_type));
2561 /// Checks whether container name is CLS Compliant
2563 void VerifyClsName ()
2565 Hashtable base_members = base_cache == null ?
2567 base_cache.GetPublicMembers ();
2568 Hashtable this_members = new Hashtable ();
2570 foreach (DictionaryEntry entry in defined_names) {
2571 MemberCore mc = (MemberCore)entry.Value;
2572 if (!mc.IsClsComplianceRequired ())
2575 string name = (string) entry.Key;
2576 string basename = name.Substring (name.LastIndexOf ('.') + 1);
2578 string lcase = basename.ToLower (System.Globalization.CultureInfo.InvariantCulture);
2579 object found = base_members [lcase];
2580 if (found == null) {
2581 found = this_members [lcase];
2582 if (found == null) {
2583 this_members.Add (lcase, mc);
2588 if ((mc.ModFlags & Modifiers.OVERRIDE) != 0)
2591 if (found is MemberInfo) {
2592 if (basename == ((MemberInfo) found).Name)
2594 Report.SymbolRelatedToPreviousError ((MemberInfo) found);
2596 Report.SymbolRelatedToPreviousError ((MemberCore) found);
2599 Report.Warning (3005, 1, mc.Location, "Identifier `{0}' differing only in case is not CLS-compliant", mc.GetSignatureForError ());
2601 Report.Error (3005, mc.Location, "Identifier `{0}' differing only in case is not CLS-compliant", mc.GetSignatureForError ());
2608 /// Performs checks for an explicit interface implementation. First it
2609 /// checks whether the `interface_type' is a base inteface implementation.
2610 /// Then it checks whether `name' exists in the interface type.
2612 public virtual bool VerifyImplements (InterfaceMemberBase mb)
2614 if (ifaces != null) {
2615 foreach (Type t in ifaces){
2616 if (t == mb.InterfaceType)
2621 Report.SymbolRelatedToPreviousError (mb.InterfaceType);
2622 Report.Error (540, mb.Location, "`{0}': containing type does not implement interface `{1}'",
2623 mb.GetSignatureForError (), TypeManager.CSharpName (mb.InterfaceType));
2627 public override Type LookupAnyGeneric (string typeName)
2629 if (types != null) {
2630 foreach (TypeContainer tc in types) {
2634 int pos = tc.Basename.LastIndexOf ('`');
2635 if (pos == typeName.Length && String.Compare (typeName, 0, tc.Basename, 0, pos) == 0)
2636 return tc.TypeBuilder;
2640 return base.LookupAnyGeneric (typeName);
2643 public void Mark_HasEquals ()
2645 Methods.HasEquals = true;
2648 public void Mark_HasGetHashCode ()
2650 Methods.HasGetHashCode = true;
2657 string IMemberContainer.Name {
2663 Type IMemberContainer.Type {
2669 MemberCache IMemberContainer.MemberCache {
2671 return member_cache;
2675 bool IMemberContainer.IsInterface {
2677 return Kind == Kind.Interface;
2681 MemberList IMemberContainer.GetMembers (MemberTypes mt, BindingFlags bf)
2683 BindingFlags new_bf = bf | BindingFlags.DeclaredOnly;
2685 if (GenericType != null)
2686 return TypeManager.FindMembers (GenericType, mt, new_bf,
2689 return FindMembers (mt, new_bf, null, null);
2693 // Generates xml doc comments (if any), and if required,
2694 // handle warning report.
2696 internal override void GenerateDocComment (DeclSpace ds)
2698 DocUtil.GenerateTypeDocComment (this, ds);
2701 public override string DocCommentHeader {
2702 get { return "T:"; }
2705 public virtual MemberCache BaseCache {
2707 if (base_cache != null)
2709 if (TypeBuilder.BaseType != null)
2710 base_cache = TypeManager.LookupMemberCache (TypeBuilder.BaseType);
2711 if (TypeBuilder.IsInterface)
2712 base_cache = TypeManager.LookupBaseInterfacesCache (TypeBuilder);
2718 public abstract class ClassOrStruct : TypeContainer {
2719 ListDictionary declarative_security;
2721 public ClassOrStruct (NamespaceEntry ns, DeclSpace parent,
2722 MemberName name, Attributes attrs, Kind kind)
2723 : base (ns, parent, name, attrs, kind)
2727 protected override bool AddToContainer (MemberCore symbol, string name)
2729 if (name == MemberName.Name) {
2730 if (symbol is TypeParameter) {
2731 Report.Error (694, symbol.Location,
2732 "Type parameter `{0}' has same name as " +
2733 "containing type, or method", name);
2737 Report.SymbolRelatedToPreviousError (this);
2738 Report.Error (542, symbol.Location, "`{0}': member names cannot be the same as their enclosing type",
2739 symbol.GetSignatureForError ());
2743 return base.AddToContainer (symbol, name);
2746 public override void VerifyMembers ()
2748 base.VerifyMembers ();
2750 if ((events != null) && (RootContext.WarningLevel >= 3)) {
2751 foreach (Event e in events){
2752 if ((e.ModFlags & Modifiers.Accessibility) != Modifiers.PRIVATE)
2755 if ((e.caching_flags & Flags.IsUsed) == 0)
2756 Report.Warning (67, 3, e.Location, "The event `{0}' is never used", e.GetSignatureForError ());
2761 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
2763 if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
2764 if (declarative_security == null)
2765 declarative_security = new ListDictionary ();
2767 a.ExtractSecurityPermissionSet (declarative_security);
2771 if (a.Type == TypeManager.struct_layout_attribute_type && a.GetLayoutKindValue () == LayoutKind.Explicit) {
2772 HasExplicitLayout = true;
2775 base.ApplyAttributeBuilder (a, cb);
2779 /// Defines the default constructors
2781 protected void DefineDefaultConstructor (bool is_static)
2783 // The default instance constructor is public
2784 // If the class is abstract, the default constructor is protected
2785 // The default static constructor is private
2789 mods = Modifiers.STATIC | Modifiers.PRIVATE;
2791 mods = ((ModFlags & Modifiers.ABSTRACT) != 0) ? Modifiers.PROTECTED : Modifiers.PUBLIC;
2794 Constructor c = new Constructor (this, MemberName.Name, mods,
2795 Parameters.EmptyReadOnlyParameters,
2796 new GeneratedBaseInitializer (Location),
2800 c.Block = new ToplevelBlock (null, Location);
2803 void DefineFieldInitializers ()
2805 if (initialized_fields != null) {
2806 for (int i = 0; i < initialized_fields.Count; ++i) {
2807 FieldInitializer fi = (FieldInitializer)initialized_fields[i];
2809 EmitContext ec = new EmitContext (fi.TypeContainer, fi.TypeContainer,
2810 Location, null, null, ModFlags);
2811 ec.IsFieldInitializer = true;
2813 fi.ResolveStatement (ec);
2814 if (fi.IsDefaultInitializer && RootContext.Optimize) {
2815 // Field is re-initialized to its default value => removed
2816 initialized_fields.RemoveAt (i);
2822 if (initialized_static_fields != null) {
2823 bool has_complex_initializer = false;
2825 foreach (FieldInitializer fi in initialized_static_fields) {
2826 EmitContext ec = new EmitContext (fi.TypeContainer, fi.TypeContainer,
2827 Location, null, null, ModFlags);
2829 ec.IsFieldInitializer = true;
2831 fi.ResolveStatement (ec);
2832 if (!fi.IsComplexInitializer)
2835 has_complex_initializer = true;
2838 // Need special check to not optimize code like this
2839 // static int a = b = 5;
2840 // static int b = 0;
2841 if (!has_complex_initializer && RootContext.Optimize) {
2842 for (int i = 0; i < initialized_static_fields.Count; ++i) {
2843 FieldInitializer fi = (FieldInitializer)initialized_static_fields[i];
2844 if (fi.IsDefaultInitializer) {
2845 initialized_static_fields.RemoveAt (i);
2851 if (default_static_constructor == null && initialized_static_fields.Count > 0) {
2852 DefineDefaultConstructor (true);
2858 public override bool Define ()
2860 DefineFieldInitializers ();
2862 if (default_static_constructor != null)
2863 default_static_constructor.Define ();
2865 return base.Define ();
2868 public override void Emit ()
2872 if (declarative_security != null) {
2873 foreach (DictionaryEntry de in declarative_security) {
2874 TypeBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
2879 public override ExtensionMethodGroupExpr LookupExtensionMethod (Type extensionType, string name)
2881 return NamespaceEntry.LookupExtensionMethod (extensionType, true, name);
2884 protected override TypeAttributes TypeAttr {
2886 if (default_static_constructor == null)
2887 return base.TypeAttr | TypeAttributes.BeforeFieldInit;
2889 return base.TypeAttr;
2895 // TODO: should be sealed
2896 public class Class : ClassOrStruct {
2897 const int AllowedModifiers =
2900 Modifiers.PROTECTED |
2901 Modifiers.INTERNAL |
2903 Modifiers.ABSTRACT |
2908 public const TypeAttributes StaticClassAttribute = TypeAttributes.Abstract | TypeAttributes.Sealed;
2910 public Class (NamespaceEntry ns, DeclSpace parent, MemberName name, int mod,
2912 : base (ns, parent, name, attrs, Kind.Class)
2914 int accmods = Parent.Parent == null ? Modifiers.INTERNAL : Modifiers.PRIVATE;
2915 this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, Location);
2917 if (IsStatic && RootContext.Version == LanguageVersion.ISO_1) {
2918 Report.FeatureIsNotISO1 (Location, "static classes");
2922 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
2924 if (a.Type == TypeManager.attribute_usage_type) {
2925 if (BaseType != TypeManager.attribute_type && !BaseType.IsSubclassOf (TypeManager.attribute_type) &&
2926 TypeBuilder.FullName != "System.Attribute") {
2927 Report.Error (641, a.Location, "Attribute `{0}' is only valid on classes derived from System.Attribute", a.GetSignatureForError ());
2931 if (a.Type == TypeManager.conditional_attribute_type &&
2932 !(BaseType == TypeManager.attribute_type || BaseType.IsSubclassOf (TypeManager.attribute_type))) {
2933 Report.Error (1689, a.Location, "Attribute `System.Diagnostics.ConditionalAttribute' is only valid on methods or attribute classes");
2937 if (a.Type == TypeManager.comimport_attr_type &&
2938 !attributes.Contains (TypeManager.guid_attr_type)) {
2939 a.Error_MissingGuidAttribute ();
2943 if (a.Type == TypeManager.extension_attribute_type) {
2944 a.Error_MisusedExtensionAttribute ();
2948 if (AttributeTester.IsAttributeExcluded (a.Type))
2951 base.ApplyAttributeBuilder (a, cb);
2954 public override AttributeTargets AttributeTargets {
2956 return AttributeTargets.Class;
2960 protected override void DefineContainerMembers (MemberCoreArrayList list)
2966 base.DefineContainerMembers (list);
2970 foreach (MemberCore m in list) {
2971 if (m is Operator) {
2972 Report.Error (715, m.Location, "`{0}': Static classes cannot contain user-defined operators", m.GetSignatureForError ());
2976 if (m is Destructor) {
2977 Report.Error (711, m.Location, "`{0}': Static classes cannot contain destructor", GetSignatureForError ());
2981 if ((m.ModFlags & Modifiers.PROTECTED) != 0) {
2982 Report.Error (1057, m.Location, "`{0}': Static classes cannot contain protected members", m.GetSignatureForError ());
2987 Report.Error (720, m.Location, "`{0}': cannot declare indexers in a static class", m.GetSignatureForError ());
2991 if ((m.ModFlags & Modifiers.STATIC) != 0 || m is Enum || m is Delegate)
2994 if (m is Constructor) {
2995 Report.Error (710, m.Location, "`{0}': Static classes cannot have instance constructors", GetSignatureForError ());
2999 Method method = m as Method;
3000 if (method != null && method.Parameters.HasExtensionMethodType) {
3001 Report.Error (1105, m.Location, "`{0}': Extension methods must be declared static", m.GetSignatureForError ());
3005 Report.Error (708, m.Location, "`{0}': cannot declare instance members in a static class", m.GetSignatureForError ());
3008 base.DefineContainerMembers (list);
3011 public override TypeBuilder DefineType ()
3013 if ((ModFlags & Modifiers.ABSTRACT) == Modifiers.ABSTRACT && (ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) != 0) {
3014 Report.Error (418, Location, "`{0}': an abstract class cannot be sealed or static", GetSignatureForError ());
3018 if ((ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) == (Modifiers.SEALED | Modifiers.STATIC)) {
3019 Report.Error (441, Location, "`{0}': a class cannot be both static and sealed", GetSignatureForError ());
3023 return base.DefineType ();
3026 protected override bool DoDefineMembers ()
3028 if (InstanceConstructors == null && !IsStatic)
3029 DefineDefaultConstructor (false);
3031 return base.DoDefineMembers ();
3034 public override void Emit ()
3038 if ((ModFlags & Modifiers.METHOD_EXTENSION) != 0)
3039 TypeBuilder.SetCustomAttribute (TypeManager.extension_attribute_attr);
3042 public override TypeExpr[] GetClassBases (out TypeExpr base_class)
3044 TypeExpr[] ifaces = base.GetClassBases (out base_class);
3046 if (base_class == null) {
3047 if (RootContext.StdLib)
3048 base_class = TypeManager.system_object_expr;
3049 else if (Name != "System.Object")
3050 base_class = TypeManager.system_object_expr;
3052 if (Kind == Kind.Class && base_class is TypeParameterExpr){
3054 689, base_class.Location,
3055 "Cannot derive from `{0}' because it is a type parameter",
3056 base_class.GetSignatureForError ());
3060 if (base_class.Type.IsArray || base_class.Type.IsPointer) {
3061 Report.Error (1521, base_class.Location, "Invalid base type");
3065 if (base_class.IsSealed){
3066 Report.SymbolRelatedToPreviousError (base_class.Type);
3067 if (base_class.Type.IsAbstract) {
3068 Report.Error (709, Location, "`{0}': Cannot derive from static class `{1}'",
3069 GetSignatureForError (), TypeManager.CSharpName (base_class.Type));
3071 Report.Error (509, Location, "`{0}': cannot derive from sealed class `{1}'",
3072 GetSignatureForError (), TypeManager.CSharpName (base_class.Type));
3077 if (!base_class.CanInheritFrom ()){
3078 Report.Error (644, Location, "`{0}' cannot derive from special class `{1}'",
3079 GetSignatureForError (), base_class.GetSignatureForError ());
3083 if (!base_class.AsAccessible (this, ModFlags)) {
3084 Report.SymbolRelatedToPreviousError (base_class.Type);
3085 Report.Error (60, Location, "Inconsistent accessibility: base class `{0}' is less accessible than class `{1}'",
3086 TypeManager.CSharpName (base_class.Type), GetSignatureForError ());
3091 if (base_class != TypeManager.system_object_expr) {
3092 Report.Error (713, Location, "Static class `{0}' cannot derive from type `{1}'. Static classes must derive from object",
3093 GetSignatureForError (), base_class.GetSignatureForError ());
3097 if (ifaces != null) {
3098 foreach (TypeExpr t in ifaces)
3099 Report.SymbolRelatedToPreviousError (t.Type);
3100 Report.Error (714, Location, "`{0}': static classes cannot implement interfaces", GetSignatureForError ());
3107 /// Search for at least one defined condition in ConditionalAttribute of attribute class
3108 /// Valid only for attribute classes.
3109 public bool IsExcluded ()
3111 if ((caching_flags & Flags.Excluded_Undetected) == 0)
3112 return (caching_flags & Flags.Excluded) != 0;
3114 caching_flags &= ~Flags.Excluded_Undetected;
3116 if (OptAttributes == null)
3119 Attribute[] attrs = OptAttributes.SearchMulti (TypeManager.conditional_attribute_type);
3124 foreach (Attribute a in attrs) {
3125 string condition = a.GetConditionalAttributeValue ();
3126 if (RootContext.AllDefines.Contains (condition))
3130 caching_flags |= Flags.Excluded;
3136 return (ModFlags & Modifiers.STATIC) != 0;
3141 // FIXME: How do we deal with the user specifying a different
3144 protected override TypeAttributes TypeAttr {
3146 TypeAttributes ta = base.TypeAttr | TypeAttributes.AutoLayout | TypeAttributes.Class;
3148 ta |= StaticClassAttribute;
3154 public sealed class Struct : ClassOrStruct {
3156 // Modifiers allowed in a struct declaration
3158 const int AllowedModifiers =
3161 Modifiers.PROTECTED |
3162 Modifiers.INTERNAL |
3166 public Struct (NamespaceEntry ns, DeclSpace parent, MemberName name,
3167 int mod, Attributes attrs)
3168 : base (ns, parent, name, attrs, Kind.Struct)
3172 if (parent.Parent == null)
3173 accmods = Modifiers.INTERNAL;
3175 accmods = Modifiers.PRIVATE;
3177 this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, Location);
3179 this.ModFlags |= Modifiers.SEALED;
3182 public override AttributeTargets AttributeTargets {
3184 return AttributeTargets.Struct;
3188 const TypeAttributes DefaultTypeAttributes =
3189 TypeAttributes.SequentialLayout |
3190 TypeAttributes.Sealed |
3191 TypeAttributes.BeforeFieldInit;
3194 public override TypeExpr[] GetClassBases (out TypeExpr base_class)
3196 TypeExpr[] ifaces = base.GetClassBases (out base_class);
3198 // If we are compiling our runtime,
3199 // and we are defining ValueType, then our
3200 // base is `System.Object'.
3202 if (base_class == null) {
3203 if (!RootContext.StdLib && Name == "System.ValueType")
3204 base_class = TypeManager.system_object_expr;
3206 base_class = TypeManager.system_valuetype_expr;
3213 // FIXME: Allow the user to specify a different set of attributes
3214 // in some cases (Sealed for example is mandatory for a class,
3215 // but what SequentialLayout can be changed
3217 protected override TypeAttributes TypeAttr {
3219 return base.TypeAttr | DefaultTypeAttributes;
3223 public override void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression)
3225 if ((field.ModFlags & Modifiers.STATIC) == 0) {
3226 Report.Error (573, field.Location, "`{0}': Structs cannot have instance field initializers",
3227 field.GetSignatureForError ());
3230 base.RegisterFieldForInitialization (field, expression);
3238 public sealed class Interface : TypeContainer, IMemberContainer {
3241 /// Modifiers allowed in a class declaration
3243 public const int AllowedModifiers =
3246 Modifiers.PROTECTED |
3247 Modifiers.INTERNAL |
3251 public Interface (NamespaceEntry ns, DeclSpace parent, MemberName name, int mod,
3253 : base (ns, parent, name, attrs, Kind.Interface)
3257 if (parent.Parent == null)
3258 accmods = Modifiers.INTERNAL;
3260 accmods = Modifiers.PRIVATE;
3262 this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, name.Location);
3265 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
3267 if (a.Type == TypeManager.comimport_attr_type &&
3268 !attributes.Contains (TypeManager.guid_attr_type)) {
3269 a.Error_MissingGuidAttribute ();
3272 base.ApplyAttributeBuilder (a, cb);
3276 public override AttributeTargets AttributeTargets {
3278 return AttributeTargets.Interface;
3282 const TypeAttributes DefaultTypeAttributes =
3283 TypeAttributes.AutoLayout |
3284 TypeAttributes.Abstract |
3285 TypeAttributes.Interface;
3287 protected override TypeAttributes TypeAttr {
3289 return base.TypeAttr | DefaultTypeAttributes;
3293 protected override bool VerifyClsCompliance ()
3295 if (!base.VerifyClsCompliance ())
3298 if (ifaces != null) {
3299 foreach (Type t in ifaces) {
3300 if (AttributeTester.IsClsCompliant (t))
3303 Report.SymbolRelatedToPreviousError (t);
3304 Report.Warning (3027, 1, Location, "`{0}' is not CLS-compliant because base interface `{1}' is not CLS-compliant",
3305 GetSignatureForError (), TypeManager.CSharpName (t));
3313 // It is used as a base class for all property based members
3314 // This includes properties, indexers, and events
3315 public abstract class PropertyBasedMember : InterfaceMemberBase
3317 public PropertyBasedMember (DeclSpace parent, GenericMethod generic,
3318 Expression type, int mod, int allowed_mod, bool is_iface,
3319 MemberName name, Attributes attrs)
3320 : base (parent, generic, type, mod, allowed_mod, is_iface, name, attrs)
3324 protected override bool CheckForDuplications ()
3326 throw new NotSupportedException ();
3329 protected override bool VerifyClsCompliance ()
3331 if (!base.VerifyClsCompliance ())
3334 if (!AttributeTester.IsClsCompliant (MemberType)) {
3335 Report.Error (3003, Location, "Type of `{0}' is not CLS-compliant",
3336 GetSignatureForError ());
3344 public abstract class MethodCore : InterfaceMemberBase
3346 public readonly Parameters Parameters;
3347 protected ToplevelBlock block;
3349 public MethodCore (DeclSpace parent, GenericMethod generic,
3350 Expression type, int mod, int allowed_mod, bool is_iface,
3351 MemberName name, Attributes attrs, Parameters parameters)
3352 : base (parent, generic, type, mod, allowed_mod, is_iface, name, attrs)
3354 Parameters = parameters;
3358 // Returns the System.Type array for the parameters of this method
3360 public Type [] ParameterTypes {
3362 return Parameters.Types;
3366 public Parameters ParameterInfo
3373 public ToplevelBlock Block {
3383 protected override bool CheckBase ()
3385 // Check whether arguments were correct.
3386 if (!DefineParameters (Parameters))
3389 if (!base.CheckBase ())
3395 // TODO: create a special method for operators only to make code better
3396 protected bool IsDuplicateImplementation (MethodCore method)
3401 Operator op2 = null;
3402 Operator op1 = null;
3404 if (!(method.MemberName.Equals (MemberName)))
3406 op1 = this as Operator;
3407 if (op1 == null || !(op1.OperatorType == Operator.OpType.Explicit || op1.OperatorType == Operator.OpType.Implicit))
3410 op2 = method as Operator;
3411 if (op2 == null || !(op2.OperatorType == Operator.OpType.Explicit || op2.OperatorType == Operator.OpType.Implicit))
3414 op1 = this as Operator;
3415 op2 = method as Operator;
3418 Type[] param_types = method.ParameterTypes;
3419 // This never happen. Rewrite this as Equal
3420 if (param_types == null && ParameterTypes == null)
3422 if (param_types == null || ParameterTypes == null)
3425 if (param_types.Length != ParameterTypes.Length)
3428 if (method.Parameters.HasArglist != Parameters.HasArglist)
3433 for (int i = 0; i < param_types.Length; i++) {
3434 if (param_types [i] != ParameterTypes [i])
3438 if (IsExplicitImpl && (method.InterfaceType != InterfaceType))
3441 // TODO: make operator compatible with MethodCore to avoid this
3442 if (op1 != null && op2 != null) {
3443 if (MemberType != method.MemberType)
3449 // Try to report 663: method only differs on out/ref
3451 Parameters info = ParameterInfo;
3452 Parameters other_info = method.ParameterInfo;
3453 for (int i = 0; i < info.Count; i++){
3454 if (info.ParameterModifier (i) != other_info.ParameterModifier (i)){
3455 Report.SymbolRelatedToPreviousError (method);
3456 Report.Error (663, Location, "`{0}': Methods cannot differ only on their use of ref and out on a parameters",
3457 GetSignatureForError ());
3462 Report.SymbolRelatedToPreviousError (method);
3463 if (this is Operator && method is Operator)
3464 Report.Error (557, Location, "Duplicate user-defined conversion in type `{0}'", Parent.Name);
3466 Report.Error (111, Location, TypeContainer.Error111, GetSignatureForError ());
3475 // Returns a string that represents the signature for this
3476 // member which should be used in XML documentation.
3478 public override string GetDocCommentName (DeclSpace ds)
3480 return DocUtil.GetMethodDocCommentName (this, Parameters, ds);
3484 // Raised (and passed an XmlElement that contains the comment)
3485 // when GenerateDocComment is writing documentation expectedly.
3487 // FIXME: with a few effort, it could be done with XmlReader,
3488 // that means removal of DOM use.
3490 internal override void OnGenerateDocComment (XmlElement el)
3492 DocUtil.OnMethodGenerateDocComment (this, el);
3496 // Represents header string for documentation comment.
3498 public override string DocCommentHeader
3500 get { return "M:"; }
3503 public virtual void SetYields ()
3505 ModFlags |= Modifiers.METHOD_YIELDS;
3508 protected override bool VerifyClsCompliance ()
3510 if (!base.VerifyClsCompliance ())
3513 if (Parameters.HasArglist) {
3514 Report.Error (3000, Location, "Methods with variable arguments are not CLS-compliant");
3517 if (!AttributeTester.IsClsCompliant (MemberType)) {
3518 Report.Error (3002, Location, "Return type of `{0}' is not CLS-compliant",
3519 GetSignatureForError ());
3522 Parameters.VerifyClsCompliance ();
3528 public abstract class InterfaceMemberBase : MemberBase {
3530 // Whether this is an interface member.
3532 public bool IsInterface;
3535 // If true, this is an explicit interface implementation
3537 public bool IsExplicitImpl;
3539 protected bool is_external_implementation;
3542 // The interface type we are explicitly implementing
3544 public Type InterfaceType;
3547 // The method we're overriding if this is an override method.
3549 protected MethodInfo base_method;
3551 readonly int explicit_mod_flags;
3552 public MethodAttributes flags;
3554 public InterfaceMemberBase (DeclSpace parent, GenericMethod generic,
3555 Expression type, int mod, int allowed_mod, bool is_iface,
3556 MemberName name, Attributes attrs)
3557 : base (parent, generic, type, mod, allowed_mod, Modifiers.PRIVATE,
3560 IsInterface = is_iface;
3561 IsExplicitImpl = (MemberName.Left != null);
3562 explicit_mod_flags = mod;
3565 protected override bool CheckBase ()
3567 if (!base.CheckBase ())
3570 if ((caching_flags & Flags.TestMethodDuplication) != 0 && !CheckForDuplications ())
3576 // Is null for System.Object while compiling corlib and base interfaces
3577 if (Parent.PartialContainer.BaseCache == null) {
3578 if ((ModFlags & Modifiers.NEW) != 0) {
3579 Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
3584 Type base_ret_type = null;
3585 base_method = FindOutBaseMethod (ref base_ret_type);
3587 // method is override
3588 if (base_method != null) {
3589 if (!CheckMethodAgainstBase (base_ret_type))
3592 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
3593 ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (base_method);
3595 if (OptAttributes == null || !OptAttributes.Contains (TypeManager.obsolete_attribute_type)) {
3596 Report.SymbolRelatedToPreviousError (base_method);
3597 Report.Warning (672, 1, Location, "Member `{0}' overrides obsolete member `{1}'. Add the Obsolete attribute to `{0}'",
3598 GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3601 if (OptAttributes != null && OptAttributes.Contains (TypeManager.obsolete_attribute_type)) {
3602 Report.Warning (809, 1, Location, "Obsolete member `{0}' overrides non-obsolete member `{1}'",
3603 GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3610 MemberInfo conflict_symbol = Parent.PartialContainer.FindBaseMemberWithSameName (Name, !((this is Event) || (this is Property)));
3611 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
3612 if (conflict_symbol != null) {
3613 Report.SymbolRelatedToPreviousError (conflict_symbol);
3615 Report.Error (72, Location, "`{0}': cannot override because `{1}' is not an event", GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
3616 else if (this is PropertyBase)
3617 Report.Error (544, Location, "`{0}': cannot override because `{1}' is not a property", GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
3619 Report.Error (505, Location, "`{0}': cannot override because `{1}' is not a method", GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
3621 Report.Error (115, Location, "`{0}' is marked as an override but no suitable {1} found to override",
3622 GetSignatureForError (), SimpleName.GetMemberType (this));
3627 if (conflict_symbol == null) {
3628 if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) {
3629 Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
3634 if ((ModFlags & Modifiers.NEW) == 0) {
3635 if (this is Method && conflict_symbol is MethodBase)
3638 Report.SymbolRelatedToPreviousError (conflict_symbol);
3639 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
3640 GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
3647 // Performs various checks on the MethodInfo `mb' regarding the modifier flags
3648 // that have been defined.
3650 // `name' is the user visible name for reporting errors (this is used to
3651 // provide the right name regarding method names and properties)
3653 bool CheckMethodAgainstBase (Type baseMethodType)
3657 if ((ModFlags & Modifiers.OVERRIDE) != 0){
3658 if (!(base_method.IsAbstract || base_method.IsVirtual)){
3659 Report.Error (506, Location,
3660 "`{0}': cannot override inherited member `{1}' because it is not marked virtual, abstract or override",
3661 GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3665 // Now we check that the overriden method is not final
3667 if (base_method.IsFinal) {
3668 Report.SymbolRelatedToPreviousError (base_method);
3669 Report.Error (239, Location, "`{0}': cannot override inherited member `{1}' because it is sealed",
3670 GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3674 // Check that the permissions are not being changed
3676 MethodAttributes thisp = flags & MethodAttributes.MemberAccessMask;
3677 MethodAttributes base_classp = base_method.Attributes & MethodAttributes.MemberAccessMask;
3679 if (!CheckAccessModifiers (thisp, base_classp, base_method)) {
3680 Error_CannotChangeAccessModifiers (base_method, base_classp, null);
3684 if (!TypeManager.IsEqual (MemberType, TypeManager.TypeToCoreType (baseMethodType))) {
3685 Report.SymbolRelatedToPreviousError (base_method);
3686 if (this is PropertyBasedMember) {
3687 Report.Error (1715, Location, "`{0}': type must be `{1}' to match overridden member `{2}'",
3688 GetSignatureForError (), TypeManager.CSharpName (baseMethodType), TypeManager.CSharpSignature (base_method));
3691 Report.Error (508, Location, "`{0}': return type must be `{1}' to match overridden member `{2}'",
3692 GetSignatureForError (), TypeManager.CSharpName (baseMethodType), TypeManager.CSharpSignature (base_method));
3698 if ((ModFlags & Modifiers.NEW) == 0) {
3699 if ((ModFlags & Modifiers.OVERRIDE) == 0 && Name != "Finalize") {
3700 ModFlags |= Modifiers.NEW;
3701 Report.SymbolRelatedToPreviousError (base_method);
3702 if (!IsInterface && (base_method.IsVirtual || base_method.IsAbstract)) {
3703 Report.Warning (114, 2, Location, "`{0}' hides inherited member `{1}'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword",
3704 GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3706 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
3707 GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3711 if (base_method.IsAbstract && !IsInterface) {
3712 Report.SymbolRelatedToPreviousError (base_method);
3713 Report.Error (533, Location, "`{0}' hides inherited abstract member `{1}'",
3714 GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3722 protected bool CheckAccessModifiers (MethodAttributes thisp, MethodAttributes base_classp, MethodInfo base_method)
3724 if ((base_classp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
3726 // when overriding protected internal, the method can be declared
3727 // protected internal only within the same assembly
3730 if ((thisp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
3731 if (Parent.TypeBuilder.Assembly != base_method.DeclaringType.Assembly){
3733 // assemblies differ - report an error
3737 } else if (thisp != base_classp) {
3739 // same assembly, but other attributes differ - report an error
3744 } else if ((thisp & MethodAttributes.Family) != MethodAttributes.Family) {
3746 // if it's not "protected internal", it must be "protected"
3750 } else if (Parent.TypeBuilder.Assembly == base_method.DeclaringType.Assembly) {
3752 // protected within the same assembly - an error
3755 } else if ((thisp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem)) !=
3756 (base_classp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem))) {
3758 // protected ok, but other attributes differ - report an error
3764 return (thisp == base_classp);
3768 public bool CheckAbstractAndExtern (bool has_block)
3770 if (Parent.PartialContainer.Kind == Kind.Interface)
3774 if ((ModFlags & Modifiers.EXTERN) != 0) {
3775 Report.Error (179, Location, "`{0}' cannot declare a body because it is marked extern",
3776 GetSignatureForError ());
3780 if ((ModFlags & Modifiers.ABSTRACT) != 0) {
3781 Report.Error (500, Location, "`{0}' cannot declare a body because it is marked abstract",
3782 GetSignatureForError ());
3786 if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) == 0) {
3787 Report.Error (501, Location, "`{0}' must declare a body because it is not marked abstract or extern",
3788 GetSignatureForError ());
3796 protected bool DefineParameters (Parameters parameters)
3798 IResolveContext rc = GenericMethod == null ? this : (IResolveContext)ds;
3800 if (!parameters.Resolve (rc))
3804 foreach (Parameter p in parameters.FixedParameters) {
3805 if (p.CheckAccessibility (this))
3808 Report.SymbolRelatedToPreviousError (p.ParameterType);
3809 if (this is Indexer)
3810 Report.Error (55, Location,
3811 "Inconsistent accessibility: parameter type `" +
3812 TypeManager.CSharpName (p.ParameterType) + "' is less " +
3813 "accessible than indexer `" + GetSignatureForError () + "'");
3814 else if (this is Operator)
3815 Report.Error (57, Location,
3816 "Inconsistent accessibility: parameter type `" +
3817 TypeManager.CSharpName (p.ParameterType) + "' is less " +
3818 "accessible than operator `" + GetSignatureForError () + "'");
3820 Report.Error (51, Location,
3821 "Inconsistent accessibility: parameter type `{0}' is less accessible than method `{1}'",
3822 TypeManager.CSharpName (p.ParameterType), GetSignatureForError ());
3828 protected override bool DoDefine()
3830 if (!base.DoDefine ())
3833 if (IsExplicitImpl) {
3834 Expression expr = MemberName.Left.GetTypeExpression ();
3835 TypeExpr texpr = expr.ResolveAsTypeTerminal (this, false);
3839 InterfaceType = texpr.Type;
3841 if (!InterfaceType.IsInterface) {
3842 Report.Error (538, Location, "`{0}' in explicit interface declaration is not an interface", TypeManager.CSharpName (InterfaceType));
3846 if (!Parent.PartialContainer.VerifyImplements (this))
3853 protected virtual bool DoDefineBase ()
3856 throw new InternalErrorException ();
3859 ModFlags = Modifiers.PUBLIC |
3860 Modifiers.ABSTRACT |
3861 Modifiers.VIRTUAL | (ModFlags & Modifiers.UNSAFE) | (ModFlags & Modifiers.NEW);
3863 flags = MethodAttributes.Public |
3864 MethodAttributes.Abstract |
3865 MethodAttributes.HideBySig |
3866 MethodAttributes.NewSlot |
3867 MethodAttributes.Virtual;
3869 if (!Parent.PartialContainer.MethodModifiersValid (this))
3872 flags = Modifiers.MethodAttr (ModFlags);
3875 if (IsExplicitImpl) {
3876 Expression expr = MemberName.Left.GetTypeExpression ();
3877 TypeExpr iface_texpr = expr.ResolveAsTypeTerminal (this, false);
3878 if (iface_texpr == null)
3881 InterfaceType = iface_texpr.Type;
3883 if (!InterfaceType.IsInterface) {
3884 Report.Error (538, Location, "'{0}' in explicit interface declaration is not an interface", TypeManager.CSharpName (InterfaceType));
3888 if (!Parent.PartialContainer.VerifyImplements (this))
3891 Modifiers.Check (Modifiers.AllowedExplicitImplFlags, explicit_mod_flags, 0, Location);
3897 public override void Emit()
3899 // for extern static method must be specified either DllImport attribute or MethodImplAttribute.
3900 // We are more strict than Microsoft and report CS0626 as error
3901 if ((ModFlags & Modifiers.EXTERN) != 0 && !is_external_implementation) {
3902 Report.Error (626, Location,
3903 "`{0}' is marked as an external but has no DllImport attribute. Consider adding a DllImport attribute to specify the external implementation",
3904 GetSignatureForError ());
3910 protected void Error_CannotChangeAccessModifiers (MemberInfo base_method, MethodAttributes ma, string suffix)
3912 Report.SymbolRelatedToPreviousError (base_method);
3913 string base_name = TypeManager.GetFullNameSignature (base_method);
3914 string this_name = GetSignatureForError ();
3915 if (suffix != null) {
3916 base_name += suffix;
3917 this_name += suffix;
3920 Report.Error (507, Location, "`{0}': cannot change access modifiers when overriding `{1}' inherited member `{2}'",
3921 this_name, Modifiers.GetDescription (ma), base_name);
3924 protected static string Error722 {
3926 return "`{0}': static types cannot be used as return types";
3931 /// For custom member duplication search in a container
3933 protected abstract bool CheckForDuplications ();
3936 /// Gets base method and its return type
3938 protected abstract MethodInfo FindOutBaseMethod (ref Type base_ret_type);
3941 // The "short" name of this property / indexer / event. This is the
3942 // name without the explicit interface.
3944 public string ShortName
3946 get { return MemberName.Name; }
3947 set { SetMemberName (new MemberName (MemberName.Left, value, Location)); }
3950 protected override bool VerifyClsCompliance ()
3952 if (!base.VerifyClsCompliance ()) {
3953 if (IsInterface && HasClsCompliantAttribute && Parent.IsClsComplianceRequired ()) {
3954 Report.Error (3010, Location, "`{0}': CLS-compliant interfaces must have only CLS-compliant members", GetSignatureForError ());
3957 if ((ModFlags & Modifiers.ABSTRACT) != 0 && Parent.TypeBuilder.IsClass && IsExposedFromAssembly () && Parent.IsClsComplianceRequired ()) {
3958 Report.Error (3011, Location, "`{0}': only CLS-compliant members can be abstract", GetSignatureForError ());
3963 if (GenericMethod != null)
3964 GenericMethod.VerifyClsCompliance ();
3969 public override bool IsUsed
3971 get { return IsExplicitImpl || base.IsUsed; }
3976 public abstract class MethodOrOperator : MethodCore, IMethodData
3978 public MethodBuilder MethodBuilder;
3979 ReturnParameter return_attributes;
3980 ListDictionary declarative_security;
3981 protected MethodData MethodData;
3984 ArrayList anonymous_methods;
3986 static string[] attribute_targets = new string [] { "method", "return" };
3988 protected MethodOrOperator (DeclSpace parent, GenericMethod generic, Expression type, int mod,
3989 int allowed_mod, bool is_interface, MemberName name,
3990 Attributes attrs, Parameters parameters)
3991 : base (parent, generic, type, mod, allowed_mod, is_interface, name,
3996 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
3998 if (a.Target == AttributeTargets.ReturnValue) {
3999 if (return_attributes == null)
4000 return_attributes = new ReturnParameter (MethodBuilder, Location);
4002 return_attributes.ApplyAttributeBuilder (a, cb);
4006 if (a.IsInternalMethodImplAttribute) {
4007 is_external_implementation = true;
4010 if (a.Type == TypeManager.dllimport_type) {
4011 const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
4012 if ((ModFlags & extern_static) != extern_static) {
4013 Report.Error (601, a.Location, "The DllImport attribute must be specified on a method marked `static' and `extern'");
4015 is_external_implementation = true;
4018 if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
4019 if (declarative_security == null)
4020 declarative_security = new ListDictionary ();
4021 a.ExtractSecurityPermissionSet (declarative_security);
4025 MethodBuilder.SetCustomAttribute (cb);
4028 public override AttributeTargets AttributeTargets {
4030 return AttributeTargets.Method;
4034 public virtual EmitContext CreateEmitContext (DeclSpace tc, ILGenerator ig)
4036 return new EmitContext (
4037 this, tc, this.ds, Location, ig, MemberType, ModFlags, false);
4040 public void AddAnonymousMethod (AnonymousMethodExpression anonymous)
4042 if (anonymous_methods == null)
4043 anonymous_methods = new ArrayList ();
4044 anonymous_methods.Add (anonymous);
4047 protected bool DefineGenericMethod ()
4049 if (!DoDefineBase ())
4053 if (GenericMethod != null) {
4054 string method_name = MemberName.Name;
4056 if (IsExplicitImpl) {
4057 method_name = TypeManager.CSharpName (InterfaceType) +
4062 MethodBuilder = Parent.TypeBuilder.DefineMethod (method_name, flags, ReturnType, null);
4064 MethodBuilder = Parent.TypeBuilder.DefineMethod (method_name, flags);
4067 if (!GenericMethod.Define (MethodBuilder, block))
4075 public bool ResolveMembers ()
4077 if (!DefineGenericMethod ())
4080 if ((ModFlags & Modifiers.METHOD_YIELDS) != 0) {
4081 iterator = Iterator.CreateIterator (this, Parent, GenericMethod, ModFlags);
4082 if (iterator == null)
4086 if (anonymous_methods != null) {
4087 foreach (AnonymousMethodExpression ame in anonymous_methods) {
4088 if (!ame.CreateAnonymousHelpers ())
4096 public override bool Define ()
4101 if (!CheckAbstractAndExtern (block != null))
4107 MethodData = new MethodData (
4108 this, ModFlags, flags, this, MethodBuilder, GenericMethod, base_method);
4110 if (!MethodData.Define (Parent.PartialContainer))
4113 MethodBuilder = MethodData.MethodBuilder;
4115 if (!TypeManager.IsGenericParameter (MemberType)) {
4116 if (MemberType.IsAbstract && MemberType.IsSealed) {
4117 Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
4125 public override void Emit ()
4127 if (OptAttributes != null)
4128 OptAttributes.Emit ();
4130 if (declarative_security != null) {
4131 foreach (DictionaryEntry de in declarative_security) {
4132 MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
4139 protected void Error_ConditionalAttributeIsNotValid ()
4141 Report.Error (577, Location,
4142 "Conditional not valid on `{0}' because it is a constructor, destructor, operator or explicit interface implementation",
4143 GetSignatureForError ());
4146 public override bool MarkForDuplicationCheck ()
4148 caching_flags |= Flags.TestMethodDuplication;
4152 public override string[] ValidAttributeTargets {
4154 return attribute_targets;
4158 #region IMethodData Members
4160 public CallingConventions CallingConventions {
4162 CallingConventions cc = Parameters.CallingConvention;
4163 if (Parameters.HasArglist && block != null)
4164 block.HasVarargs = true;
4167 if ((ModFlags & Modifiers.STATIC) == 0)
4168 cc |= CallingConventions.HasThis;
4170 // FIXME: How is `ExplicitThis' used in C#?
4176 public Type ReturnType {
4182 public MemberName MethodName {
4188 public Iterator Iterator {
4189 get { return iterator; }
4192 public new Location Location {
4194 return base.Location;
4198 protected override bool CheckBase ()
4200 if (!base.CheckBase ())
4203 // TODO: Destructor should derive from MethodCore
4204 if (base_method != null && (ModFlags & Modifiers.OVERRIDE) != 0 && Name == "Finalize" &&
4205 base_method.DeclaringType == TypeManager.object_type && !(this is Destructor)) {
4206 Report.Error (249, Location, "Do not override object.Finalize. Instead, provide a destructor");
4214 /// Returns true if method has conditional attribute and the conditions is not defined (method is excluded).
4216 public bool IsExcluded () {
4217 if ((caching_flags & Flags.Excluded_Undetected) == 0)
4218 return (caching_flags & Flags.Excluded) != 0;
4220 caching_flags &= ~Flags.Excluded_Undetected;
4222 if (base_method == null) {
4223 if (OptAttributes == null)
4226 Attribute[] attrs = OptAttributes.SearchMulti (TypeManager.conditional_attribute_type);
4231 foreach (Attribute a in attrs) {
4232 string condition = a.GetConditionalAttributeValue ();
4233 if (condition == null)
4236 if (RootContext.AllDefines.Contains (condition))
4240 caching_flags |= Flags.Excluded;
4244 IMethodData md = TypeManager.GetMethod (base_method);
4246 if (AttributeTester.IsConditionalMethodExcluded (base_method)) {
4247 caching_flags |= Flags.Excluded;
4253 if (md.IsExcluded ()) {
4254 caching_flags |= Flags.Excluded;
4260 GenericMethod IMethodData.GenericMethod {
4262 return GenericMethod;
4270 public class SourceMethod : ISourceMethod
4275 protected SourceMethod (DeclSpace parent, MethodBase builder,
4276 ISourceFile file, Location start, Location end)
4278 this.parent = parent;
4279 this.builder = builder;
4281 CodeGen.SymbolWriter.OpenMethod (file, this, start.Row, start.Column, end.Row, start.Column);
4284 public string Name {
4285 get { return builder.Name; }
4288 public int NamespaceID {
4289 get { return parent.NamespaceEntry.SymbolFileID; }
4294 if (builder is MethodBuilder)
4295 return ((MethodBuilder) builder).GetToken ().Token;
4296 else if (builder is ConstructorBuilder)
4297 return ((ConstructorBuilder) builder).GetToken ().Token;
4299 throw new NotSupportedException ();
4303 public void CloseMethod ()
4305 if (CodeGen.SymbolWriter != null)
4306 CodeGen.SymbolWriter.CloseMethod ();
4309 public static SourceMethod Create (DeclSpace parent, MethodBase builder, Block block)
4311 if (CodeGen.SymbolWriter == null)
4316 Location start_loc = block.StartLocation;
4317 if (start_loc.IsNull)
4320 Location end_loc = block.EndLocation;
4324 ISourceFile file = start_loc.SourceFile;
4328 return new SourceMethod (
4329 parent, builder, file, start_loc, end_loc);
4333 public class Method : MethodOrOperator, IAnonymousHost {
4336 /// Modifiers allowed in a class declaration
4338 const int AllowedModifiers =
4341 Modifiers.PROTECTED |
4342 Modifiers.INTERNAL |
4347 Modifiers.OVERRIDE |
4348 Modifiers.ABSTRACT |
4350 Modifiers.METHOD_YIELDS |
4353 const int AllowedInterfaceModifiers =
4354 Modifiers.NEW | Modifiers.UNSAFE;
4357 // return_type can be "null" for VOID values.
4359 public Method (DeclSpace parent, GenericMethod generic,
4360 Expression return_type, int mod, bool is_iface,
4361 MemberName name, Parameters parameters, Attributes attrs)
4362 : base (parent, generic, return_type, mod,
4363 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
4364 is_iface, name, attrs, parameters)
4368 public override string GetSignatureForError()
4370 return base.GetSignatureForError () + Parameters.GetSignatureForError ();
4373 void Error_DuplicateEntryPoint (MethodInfo b, Location location)
4375 Report.Error (17, location,
4376 "Program `{0}' has more than one entry point defined: `{1}'",
4377 CodeGen.FileName, TypeManager.CSharpSignature(b));
4380 bool IsEntryPoint ()
4382 if (ReturnType != TypeManager.void_type &&
4383 ReturnType != TypeManager.int32_type)
4386 if (Parameters.Count == 0)
4389 if (Parameters.Count > 1)
4392 Type t = Parameters.ParameterType (0);
4393 return t.IsArray && t.GetArrayRank () == 1 &&
4394 TypeManager.GetElementType (t) == TypeManager.string_type &&
4395 (Parameters[0].ModFlags & ~Parameter.Modifier.PARAMS) == Parameter.Modifier.NONE;
4398 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
4400 if (a.Type == TypeManager.conditional_attribute_type) {
4401 if (IsExplicitImpl) {
4402 Error_ConditionalAttributeIsNotValid ();
4406 if (ReturnType != TypeManager.void_type) {
4407 Report.Error (578, Location, "Conditional not valid on `{0}' because its return type is not void", GetSignatureForError ());
4411 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
4412 Report.Error (243, Location, "Conditional not valid on `{0}' because it is an override method", GetSignatureForError ());
4417 Report.Error (582, Location, "Conditional not valid on interface members");
4421 if (MethodData.implementing != null) {
4422 Report.Error (629, Location, "Conditional member `{0}' cannot implement interface member `{1}'",
4423 GetSignatureForError (), TypeManager.CSharpSignature (MethodData.implementing));
4427 for (int i = 0; i < Parameters.Count; ++i) {
4428 if ((Parameters.ParameterModifier (i) & Parameter.Modifier.OUTMASK) != 0) {
4429 Report.Error (685, Location, "Conditional method `{0}' cannot have an out parameter", GetSignatureForError ());
4435 if (a.Type == TypeManager.extension_attribute_type) {
4436 a.Error_MisusedExtensionAttribute ();
4440 base.ApplyAttributeBuilder (a, cb);
4443 protected override bool CheckForDuplications ()
4445 ArrayList ar = Parent.PartialContainer.Methods;
4447 int arLen = ar.Count;
4449 for (int i = 0; i < arLen; i++) {
4450 Method m = (Method) ar [i];
4451 if (IsDuplicateImplementation (m))
4456 ar = Parent.PartialContainer.Properties;
4458 for (int i = 0; i < ar.Count; ++i) {
4459 PropertyBase pb = (PropertyBase) ar [i];
4460 if (pb.AreAccessorsDuplicateImplementation (this))
4465 ar = Parent.PartialContainer.Indexers;
4467 for (int i = 0; i < ar.Count; ++i) {
4468 PropertyBase pb = (PropertyBase) ar [i];
4469 if (pb.AreAccessorsDuplicateImplementation (this))
4474 ar = Parent.PartialContainer.Events;
4476 for (int i = 0; i < ar.Count; ++i) {
4477 Event ev = (Event) ar [i];
4478 if (ev.AreAccessorsDuplicateImplementation (this))
4489 public override bool Define ()
4491 if (!base.Define ())
4494 if (RootContext.StdLib && (ReturnType == TypeManager.arg_iterator_type || ReturnType == TypeManager.typed_reference_type)) {
4495 Error1599 (Location, ReturnType);
4499 if (ReturnType == TypeManager.void_type && ParameterTypes.Length == 0 &&
4500 Name == "Finalize" && !(this is Destructor)) {
4501 Report.Warning (465, 1, Location, "Introducing a 'Finalize' method can interfere with destructor invocation. Did you intend to declare a destructor?");
4504 if (base_method != null && (ModFlags & Modifiers.NEW) == 0) {
4505 if (Parameters.Count == 1 && ParameterTypes [0] == TypeManager.object_type && Name == "Equals")
4506 Parent.PartialContainer.Mark_HasEquals ();
4507 else if (Parameters.Empty && Name == "GetHashCode")
4508 Parent.PartialContainer.Mark_HasGetHashCode ();
4511 if ((ModFlags & Modifiers.STATIC) == 0)
4514 if (Parameters.HasExtensionMethodType) {
4515 if (Parent.IsStaticClass && !Parent.IsGeneric) {
4516 if (!Parent.IsTopLevel)
4517 Report.Error (1109, Location, "`{0}': Extension methods cannot be defined in a nested class",
4518 GetSignatureForError ());
4520 if (TypeManager.extension_attribute_type == null)
4521 Report.Error (1110, Location,
4522 "`{0}': Extension methods cannot be declared without a reference to System.Core.dll assembly. Add the assembly reference or remove `this' modifer from the first parameter",
4523 GetSignatureForError ());
4525 ModFlags |= Modifiers.METHOD_EXTENSION;
4526 Parent.ModFlags |= Modifiers.METHOD_EXTENSION;
4527 CodeGen.Assembly.HasExtensionMethods = true;
4529 Report.Error (1106, Location, "`{0}': Extension methods must be defined in a non-generic static class",
4530 GetSignatureForError ());
4535 // This is used to track the Entry Point,
4537 if (RootContext.NeedsEntryPoint &&
4539 (RootContext.MainClass == null ||
4540 RootContext.MainClass == Parent.TypeBuilder.FullName)){
4541 if (IsEntryPoint ()) {
4543 if (RootContext.EntryPoint == null) {
4544 if (Parent.IsGeneric || MemberName.IsGeneric) {
4545 Report.Warning (402, 4, Location, "`{0}': an entry point cannot be generic or in a generic type",
4546 GetSignatureForError ());
4548 IMethodData md = TypeManager.GetMethod (MethodBuilder);
4549 md.SetMemberIsUsed ();
4551 RootContext.EntryPoint = MethodBuilder;
4552 RootContext.EntryPointLocation = Location;
4555 Error_DuplicateEntryPoint (RootContext.EntryPoint, RootContext.EntryPointLocation);
4556 Error_DuplicateEntryPoint (MethodBuilder, Location);
4559 Report.Warning (28, 4, Location, "`{0}' has the wrong signature to be an entry point",
4560 GetSignatureForError ());
4570 public override void Emit ()
4572 Report.Debug (64, "METHOD EMIT", this, MethodBuilder, Location, Block, MethodData);
4573 MethodData.Emit (Parent);
4576 if ((ModFlags & Modifiers.METHOD_EXTENSION) != 0)
4577 MethodBuilder.SetCustomAttribute (TypeManager.extension_attribute_attr);
4583 public static void Error1599 (Location loc, Type t)
4585 Report.Error (1599, loc, "Method or delegate cannot return type `{0}'", TypeManager.CSharpName (t));
4588 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
4590 MethodInfo mi = (MethodInfo) Parent.PartialContainer.BaseCache.FindMemberToOverride (
4591 Parent.TypeBuilder, Name, ParameterTypes, GenericMethod, false);
4596 if (mi.IsSpecialName)
4599 base_ret_type = mi.ReturnType;
4603 protected override bool VerifyClsCompliance ()
4605 if (!base.VerifyClsCompliance ())
4608 if (ParameterInfo.Count > 0) {
4609 ArrayList al = (ArrayList)Parent.PartialContainer.MemberCache.Members [Name];
4611 MemberCache.VerifyClsParameterConflict (al, this, MethodBuilder);
4618 public abstract class ConstructorInitializer {
4619 ArrayList argument_list;
4620 protected ConstructorInfo base_constructor;
4623 public ConstructorInitializer (ArrayList argument_list, Location loc)
4625 this.argument_list = argument_list;
4629 public ArrayList Arguments {
4631 return argument_list;
4635 public bool Resolve (ConstructorBuilder caller_builder, Block block, EmitContext ec)
4637 Expression base_constructor_group;
4641 ec.CurrentBlock = block;
4643 if (argument_list != null){
4644 foreach (Argument a in argument_list){
4645 if (!a.Resolve (ec, loc))
4649 ec.CurrentBlock = null;
4651 if (this is ConstructorBaseInitializer) {
4652 if (ec.ContainerType.BaseType == null)
4655 t = ec.ContainerType.BaseType;
4656 if (ec.ContainerType.IsValueType) {
4657 Report.Error (522, loc,
4658 "`{0}': Struct constructors cannot call base constructors", TypeManager.CSharpSignature (caller_builder));
4663 // It is legal to have "this" initializers that take no arguments
4664 // in structs, they are just no-ops.
4666 // struct D { public D (int a) : this () {}
4668 if (ec.ContainerType.IsValueType && argument_list == null)
4671 t = ec.ContainerType;
4674 base_constructor_group = Expression.MemberLookup (
4675 ec.ContainerType, t, ".ctor", MemberTypes.Constructor,
4676 BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
4679 if (base_constructor_group == null){
4681 base_constructor_group = Expression.MemberLookup (
4682 t, null, t, ".ctor", MemberTypes.Constructor,
4683 BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly,
4687 int errors = Report.Errors;
4688 if (base_constructor_group != null)
4689 base_constructor = (ConstructorInfo)
4690 ((MethodGroupExpr) base_constructor_group).OverloadResolve (
4694 if (base_constructor == null) {
4695 if (errors == Report.Errors)
4696 Invocation.Error_WrongNumArguments (loc, TypeManager.CSharpSignature (caller_builder),
4697 argument_list == null ? 0 : argument_list.Count);
4702 Report.SymbolRelatedToPreviousError (base_constructor);
4703 Expression.ErrorIsInaccesible (loc, TypeManager.CSharpSignature (base_constructor));
4704 base_constructor = null;
4708 if (base_constructor == caller_builder){
4709 Report.Error (516, loc, "Constructor `{0}' cannot call itself", TypeManager.CSharpSignature (caller_builder));
4716 public virtual void Emit (EmitContext ec)
4718 if (base_constructor != null){
4719 ec.Mark (loc, false);
4721 Invocation.EmitCall (ec, true, true, null, base_constructor, argument_list, loc);
4723 Invocation.EmitCall (ec, true, false, ec.GetThis (loc), base_constructor, argument_list, loc);
4728 public class ConstructorBaseInitializer : ConstructorInitializer {
4729 public ConstructorBaseInitializer (ArrayList argument_list, Location l) :
4730 base (argument_list, l)
4735 class GeneratedBaseInitializer: ConstructorBaseInitializer {
4736 public GeneratedBaseInitializer (Location loc):
4742 public class ConstructorThisInitializer : ConstructorInitializer {
4743 public ConstructorThisInitializer (ArrayList argument_list, Location l) :
4744 base (argument_list, l)
4749 public class Constructor : MethodCore, IMethodData, IAnonymousHost {
4750 public ConstructorBuilder ConstructorBuilder;
4751 public ConstructorInitializer Initializer;
4752 ListDictionary declarative_security;
4753 ArrayList anonymous_methods;
4756 // Modifiers allowed for a constructor.
4758 public const int AllowedModifiers =
4760 Modifiers.PROTECTED |
4761 Modifiers.INTERNAL |
4767 static string[] attribute_targets = new string [] { "method" };
4769 public Iterator Iterator {
4770 get { return null; }
4773 bool has_compliant_args = false;
4775 // The spec claims that static is not permitted, but
4776 // my very own code has static constructors.
4778 public Constructor (DeclSpace parent, string name, int mod, Parameters args,
4779 ConstructorInitializer init, Location loc)
4780 : base (parent, null, null, mod, AllowedModifiers, false,
4781 new MemberName (name, loc), null, args)
4786 public bool HasCompliantArgs {
4787 get { return has_compliant_args; }
4790 public override AttributeTargets AttributeTargets {
4791 get { return AttributeTargets.Constructor; }
4796 // Returns true if this is a default constructor
4798 public bool IsDefault ()
4800 if ((ModFlags & Modifiers.STATIC) != 0)
4801 return Parameters.Empty;
4803 return Parameters.Empty &&
4804 (Initializer is ConstructorBaseInitializer) &&
4805 (Initializer.Arguments == null);
4808 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
4810 if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
4811 if (declarative_security == null) {
4812 declarative_security = new ListDictionary ();
4814 a.ExtractSecurityPermissionSet (declarative_security);
4818 if (a.IsInternalMethodImplAttribute) {
4819 is_external_implementation = true;
4822 ConstructorBuilder.SetCustomAttribute (cb);
4825 public void AddAnonymousMethod (AnonymousMethodExpression anonymous)
4827 if (anonymous_methods == null)
4828 anonymous_methods = new ArrayList ();
4829 anonymous_methods.Add (anonymous);
4832 public bool ResolveMembers ()
4834 if (anonymous_methods != null) {
4835 foreach (AnonymousMethodExpression ame in anonymous_methods) {
4836 if (!ame.CreateAnonymousHelpers ())
4844 protected override bool CheckForDuplications ()
4846 ArrayList ar = Parent.PartialContainer.InstanceConstructors;
4848 int arLen = ar.Count;
4850 for (int i = 0; i < arLen; i++) {
4851 Constructor m = (Constructor) ar [i];
4852 if (IsDuplicateImplementation (m))
4859 protected override bool CheckBase ()
4861 if ((ModFlags & Modifiers.STATIC) != 0) {
4862 if (!Parameters.Empty) {
4863 Report.Error (132, Location, "`{0}': The static constructor must be parameterless",
4864 GetSignatureForError ());
4868 // the rest can be ignored
4872 // Check whether arguments were correct.
4873 if (!DefineParameters (Parameters))
4876 if (!CheckForDuplications ())
4879 if (Parent.PartialContainer.Kind == Kind.Struct) {
4880 if (ParameterTypes.Length == 0) {
4881 Report.Error (568, Location,
4882 "Structs cannot contain explicit parameterless constructors");
4886 if ((ModFlags & Modifiers.PROTECTED) != 0) {
4887 Report.Error (666, Location, "`{0}': new protected member declared in struct", GetSignatureForError ());
4892 if ((RootContext.WarningLevel >= 4) && ((Parent.ModFlags & Modifiers.SEALED) != 0 && (ModFlags & Modifiers.PROTECTED) != 0)) {
4893 Report.Warning (628, 4, Location, "`{0}': new protected member declared in sealed class", GetSignatureForError ());
4900 // Creates the ConstructorBuilder
4902 public override bool Define ()
4904 if (ConstructorBuilder != null)
4907 MethodAttributes ca = (MethodAttributes.RTSpecialName |
4908 MethodAttributes.SpecialName);
4910 if ((ModFlags & Modifiers.STATIC) != 0) {
4911 ca |= MethodAttributes.Static | MethodAttributes.Private;
4913 ca |= MethodAttributes.HideBySig;
4915 if ((ModFlags & Modifiers.PUBLIC) != 0)
4916 ca |= MethodAttributes.Public;
4917 else if ((ModFlags & Modifiers.PROTECTED) != 0){
4918 if ((ModFlags & Modifiers.INTERNAL) != 0)
4919 ca |= MethodAttributes.FamORAssem;
4921 ca |= MethodAttributes.Family;
4922 } else if ((ModFlags & Modifiers.INTERNAL) != 0)
4923 ca |= MethodAttributes.Assembly;
4925 ca |= MethodAttributes.Private;
4928 if (!CheckAbstractAndExtern (block != null))
4931 // Check if arguments were correct.
4935 ConstructorBuilder = Parent.TypeBuilder.DefineConstructor (
4936 ca, CallingConventions,
4939 if ((ModFlags & Modifiers.UNSAFE) != 0)
4940 ConstructorBuilder.InitLocals = false;
4942 if (Parent.PartialContainer.IsComImport) {
4943 if (!IsDefault ()) {
4944 Report.Error (669, Location, "`{0}': A class with the ComImport attribute cannot have a user-defined constructor",
4945 Parent.GetSignatureForError ());
4948 ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall);
4951 TypeManager.AddMethod (ConstructorBuilder, this);
4959 public override void Emit ()
4961 if (OptAttributes != null)
4962 OptAttributes.Emit ();
4964 EmitContext ec = CreateEmitContext (null, null);
4966 if (block != null) {
4967 // If this is a non-static `struct' constructor and doesn't have any
4968 // initializer, it must initialize all of the struct's fields.
4969 if ((Parent.PartialContainer.Kind == Kind.Struct) &&
4970 ((ModFlags & Modifiers.STATIC) == 0) && (Initializer == null))
4971 block.AddThisVariable (Parent, Location);
4973 if (!block.ResolveMeta (ec, ParameterInfo))
4977 if ((ModFlags & Modifiers.STATIC) == 0){
4978 if (Parent.PartialContainer.Kind == Kind.Class && Initializer == null)
4979 Initializer = new GeneratedBaseInitializer (Location);
4983 // Spec mandates that Initializers will not have
4987 if ((Initializer != null) &&
4988 !Initializer.Resolve (ConstructorBuilder, block, ec))
4990 ec.IsStatic = false;
4993 Parameters.ApplyAttributes (ConstructorBuilder);
4995 SourceMethod source = SourceMethod.Create (
4996 Parent, ConstructorBuilder, block);
4999 // Classes can have base initializers and instance field initializers.
5001 if (Parent.PartialContainer.Kind == Kind.Class){
5002 if ((ModFlags & Modifiers.STATIC) == 0){
5005 // If we use a "this (...)" constructor initializer, then
5006 // do not emit field initializers, they are initialized in the other constructor
5008 if (!(Initializer != null && Initializer is ConstructorThisInitializer))
5009 Parent.PartialContainer.EmitFieldInitializers (ec);
5013 bool unreachable = false;
5014 if (block != null) {
5015 if (!ec.ResolveTopBlock (null, block, ParameterInfo, this, out unreachable))
5017 ec.EmitMeta (block);
5019 if (block.ScopeInfo != null) {
5020 ExpressionStatement init = block.ScopeInfo.GetScopeInitializer (ec);
5021 init.EmitStatement (ec);
5025 if (Initializer != null) {
5026 Initializer.Emit (ec);
5029 if ((ModFlags & Modifiers.STATIC) != 0)
5030 Parent.PartialContainer.EmitFieldInitializers (ec);
5033 ec.EmitResolvedTopBlock (block, unreachable);
5036 source.CloseMethod ();
5040 if (declarative_security != null) {
5041 foreach (DictionaryEntry de in declarative_security) {
5042 ConstructorBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
5049 // Is never override
5050 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
5055 public override string GetSignatureForError()
5057 return base.GetSignatureForError () + Parameters.GetSignatureForError ();
5060 public override string[] ValidAttributeTargets {
5062 return attribute_targets;
5066 protected override bool VerifyClsCompliance ()
5068 if (!base.VerifyClsCompliance () || !IsExposedFromAssembly ()) {
5072 if (ParameterInfo.Count > 0) {
5073 ArrayList al = (ArrayList)Parent.MemberCache.Members [".ctor"];
5075 MemberCache.VerifyClsParameterConflict (al, this, ConstructorBuilder);
5077 if (Parent.TypeBuilder.IsSubclassOf (TypeManager.attribute_type)) {
5078 foreach (Type param in ParameterTypes) {
5079 if (param.IsArray) {
5085 has_compliant_args = true;
5089 #region IMethodData Members
5091 public System.Reflection.CallingConventions CallingConventions {
5093 CallingConventions cc = Parameters.CallingConvention;
5095 if (Parent.PartialContainer.Kind == Kind.Class)
5096 if ((ModFlags & Modifiers.STATIC) == 0)
5097 cc |= CallingConventions.HasThis;
5099 // FIXME: How is `ExplicitThis' used in C#?
5105 public new Location Location {
5107 return base.Location;
5111 public MemberName MethodName {
5117 public Type ReturnType {
5123 public EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig)
5125 ILGenerator ig_ = ConstructorBuilder.GetILGenerator ();
5126 return new EmitContext (this, Parent, Location, ig_, null, ModFlags, true);
5129 public bool IsExcluded()
5134 GenericMethod IMethodData.GenericMethod {
5144 /// Interface for MethodData class. Holds links to parent members to avoid member duplication.
5146 public interface IMethodData
5148 CallingConventions CallingConventions { get; }
5149 Location Location { get; }
5150 MemberName MethodName { get; }
5151 Type ReturnType { get; }
5152 GenericMethod GenericMethod { get; }
5153 Parameters ParameterInfo { get; }
5155 Iterator Iterator { get; }
5157 Attributes OptAttributes { get; }
5158 ToplevelBlock Block { get; set; }
5160 EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig);
5161 ObsoleteAttribute GetObsoleteAttribute ();
5162 string GetSignatureForError ();
5164 bool IsClsComplianceRequired ();
5165 void SetMemberIsUsed ();
5169 // Encapsulates most of the Method's state
5171 public class MethodData {
5173 readonly IMethodData method;
5175 public readonly GenericMethod GenericMethod;
5178 // Are we implementing an interface ?
5180 public MethodInfo implementing;
5185 protected InterfaceMemberBase member;
5186 protected int modifiers;
5187 protected MethodAttributes flags;
5188 protected Type declaring_type;
5189 protected MethodInfo parent_method;
5191 MethodBuilder builder = null;
5192 public MethodBuilder MethodBuilder {
5198 public Type DeclaringType {
5200 return declaring_type;
5204 public MethodData (InterfaceMemberBase member,
5205 int modifiers, MethodAttributes flags, IMethodData method)
5207 this.member = member;
5208 this.modifiers = modifiers;
5211 this.method = method;
5214 public MethodData (InterfaceMemberBase member,
5215 int modifiers, MethodAttributes flags,
5216 IMethodData method, MethodBuilder builder,
5217 GenericMethod generic, MethodInfo parent_method)
5218 : this (member, modifiers, flags, method)
5220 this.builder = builder;
5221 this.GenericMethod = generic;
5222 this.parent_method = parent_method;
5225 public bool Define (DeclSpace parent)
5227 string name = method.MethodName.Basename;
5228 string method_name = method.MethodName.FullName;
5230 TypeContainer container = parent.PartialContainer;
5232 PendingImplementation pending = container.PendingImplementations;
5233 if (pending != null){
5234 if (member is Indexer) // TODO: test it, but it should work without this IF
5235 implementing = pending.IsInterfaceIndexer (
5236 member.InterfaceType, method.ReturnType, method.ParameterInfo);
5238 implementing = pending.IsInterfaceMethod (
5239 member.InterfaceType, name, method.ReturnType, method.ParameterInfo);
5241 if (member.InterfaceType != null){
5242 if (implementing == null){
5243 if (member is PropertyBase) {
5244 Report.Error (550, method.Location, "`{0}' is an accessor not found in interface member `{1}{2}'",
5245 method.GetSignatureForError (), TypeManager.CSharpName (member.InterfaceType),
5246 member.GetSignatureForError ().Substring (member.GetSignatureForError ().LastIndexOf ('.')));
5249 Report.Error (539, method.Location,
5250 "`{0}.{1}' in explicit interface declaration is not a member of interface",
5251 TypeManager.CSharpName (member.InterfaceType), member.ShortName);
5255 if (implementing.IsSpecialName && !(method is AbstractPropertyEventMethod)) {
5256 Report.SymbolRelatedToPreviousError (implementing);
5257 Report.Error (683, method.Location, "`{0}' explicit method implementation cannot implement `{1}' because it is an accessor",
5258 member.GetSignatureForError (), TypeManager.CSharpSignature (implementing));
5262 method_name = member.InterfaceType.FullName +
5265 if (implementing != null) {
5266 AbstractPropertyEventMethod prop_method = method as AbstractPropertyEventMethod;
5267 if (prop_method == null) {
5268 if (implementing.IsSpecialName) {
5269 Report.SymbolRelatedToPreviousError (implementing);
5270 Report.Error (470, method.Location, "Method `{0}' cannot implement interface accessor `{1}.{2}'",
5271 method.GetSignatureForError (), TypeManager.CSharpSignature (implementing),
5272 implementing.Name.StartsWith ("get_") ? "get" : "set");
5275 } else if (implementing.DeclaringType.IsInterface) {
5276 if (!implementing.IsSpecialName) {
5277 Report.SymbolRelatedToPreviousError (implementing);
5278 Report.Error (686, method.Location, "Accessor `{0}' cannot implement interface member `{1}' for type `{2}'. Use an explicit interface implementation",
5279 method.GetSignatureForError (), TypeManager.CSharpSignature (implementing), container.GetSignatureForError ());
5282 PropertyBase.PropertyMethod pm = prop_method as PropertyBase.PropertyMethod;
5283 if (pm != null && pm.HasCustomAccessModifier && (pm.ModFlags & Modifiers.PUBLIC) == 0) {
5284 Report.SymbolRelatedToPreviousError (implementing);
5285 Report.Error (277, method.Location, "Accessor `{0}' must be declared public to implement interface member `{1}'",
5286 method.GetSignatureForError (), TypeManager.CSharpSignature (implementing, true));
5295 // For implicit implementations, make sure we are public, for
5296 // explicit implementations, make sure we are private.
5298 if (implementing != null){
5300 // Setting null inside this block will trigger a more
5301 // verbose error reporting for missing interface implementations
5303 // The "candidate" function has been flagged already
5304 // but it wont get cleared
5306 if (member.IsExplicitImpl){
5307 if (method.ParameterInfo.HasParams && !TypeManager.GetParameterData (implementing).HasParams) {
5308 Report.SymbolRelatedToPreviousError (implementing);
5309 Report.Error (466, method.Location, "`{0}': the explicit interface implementation cannot introduce the params modifier",
5310 method.GetSignatureForError ());
5314 if (implementing.DeclaringType.IsInterface) {
5316 // If this is an interface method implementation,
5317 // check for public accessibility
5319 if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public)
5321 implementing = null;
5323 } else if ((flags & MethodAttributes.MemberAccessMask) == MethodAttributes.Private){
5324 // We may never be private.
5325 implementing = null;
5327 } else if ((modifiers & Modifiers.OVERRIDE) == 0){
5329 // We may be protected if we're overriding something.
5331 implementing = null;
5336 // Static is not allowed
5338 if ((modifiers & Modifiers.STATIC) != 0){
5339 implementing = null;
5344 // If implementing is still valid, set flags
5346 if (implementing != null){
5348 // When implementing interface methods, set NewSlot
5349 // unless, we are overwriting a method.
5351 if (implementing.DeclaringType.IsInterface){
5352 if ((modifiers & Modifiers.OVERRIDE) == 0)
5353 flags |= MethodAttributes.NewSlot;
5356 MethodAttributes.Virtual |
5357 MethodAttributes.HideBySig;
5359 // Set Final unless we're virtual, abstract or already overriding a method.
5360 if ((modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE)) == 0)
5361 flags |= MethodAttributes.Final;
5364 EmitContext ec = method.CreateEmitContext (container, null);
5366 DefineMethodBuilder (container, method_name, method.ParameterInfo.Types);
5368 if (builder == null)
5371 if (container.CurrentType != null)
5372 declaring_type = container.CurrentType;
5374 declaring_type = container.TypeBuilder;
5376 if ((modifiers & Modifiers.UNSAFE) != 0)
5377 builder.InitLocals = false;
5380 if (implementing != null){
5382 // clear the pending implemntation flag
5384 if (member is Indexer) {
5385 pending.ImplementIndexer (
5386 member.InterfaceType, builder, method.ReturnType,
5387 method.ParameterInfo, member.IsExplicitImpl);
5389 pending.ImplementMethod (
5390 member.InterfaceType, name, method.ReturnType,
5391 method.ParameterInfo, member.IsExplicitImpl);
5393 if (member.IsExplicitImpl)
5394 container.TypeBuilder.DefineMethodOverride (
5395 builder, implementing);
5398 TypeManager.AddMethod (builder, method);
5400 if (GenericMethod != null) {
5401 bool is_override = member.IsExplicitImpl |
5402 ((modifiers & Modifiers.OVERRIDE) != 0);
5404 if (implementing != null)
5405 parent_method = implementing;
5407 if (!GenericMethod.DefineType (ec, builder, parent_method, is_override))
5416 /// Create the MethodBuilder for the method
5418 void DefineMethodBuilder (TypeContainer container, string method_name, Type[] ParameterTypes)
5420 if (builder == null) {
5421 builder = container.TypeBuilder.DefineMethod (
5422 method_name, flags, method.CallingConventions,
5423 method.ReturnType, ParameterTypes);
5427 #if GMCS_SOURCE && !MS_COMPATIBLE
5428 builder.SetGenericMethodSignature (
5429 flags, method.CallingConventions,
5430 method.ReturnType, ParameterTypes);
5437 public void Emit (DeclSpace parent)
5439 ToplevelBlock block = method.Block;
5443 ec = method.CreateEmitContext (parent, builder.GetILGenerator ());
5445 ec = method.CreateEmitContext (parent, null);
5447 method.ParameterInfo.ApplyAttributes (MethodBuilder);
5449 if (GenericMethod != null)
5450 GenericMethod.EmitAttributes ();
5452 SourceMethod source = SourceMethod.Create (parent, MethodBuilder, method.Block);
5455 // Handle destructors specially
5457 // FIXME: This code generates buggy code
5459 if (member is Destructor)
5460 EmitDestructor (ec, block);
5462 ec.EmitTopBlock (method, block);
5465 source.CloseMethod ();
5468 void EmitDestructor (EmitContext ec, ToplevelBlock block)
5470 ILGenerator ig = ec.ig;
5472 Label finish = ig.DefineLabel ();
5474 block.SetDestructor ();
5476 ig.BeginExceptionBlock ();
5477 ec.ReturnLabel = finish;
5478 ec.HasReturnLabel = true;
5479 ec.EmitTopBlock (method, block);
5481 // ig.MarkLabel (finish);
5482 ig.BeginFinallyBlock ();
5484 if (ec.ContainerType.BaseType != null) {
5485 Expression member_lookup = Expression.MemberLookup (
5486 ec.ContainerType.BaseType, null, ec.ContainerType.BaseType,
5487 "Finalize", MemberTypes.Method, Expression.AllBindingFlags, method.Location);
5489 if (member_lookup != null){
5490 MethodGroupExpr base_destructor = ((MethodGroupExpr) member_lookup);
5492 ig.Emit (OpCodes.Ldarg_0);
5493 ig.Emit (OpCodes.Call, (MethodInfo) base_destructor.Methods [0]);
5497 ig.EndExceptionBlock ();
5498 //ig.MarkLabel (ec.ReturnLabel);
5499 ig.Emit (OpCodes.Ret);
5503 // TODO: Should derive from MethodCore
5504 public class Destructor : Method {
5506 static string[] attribute_targets = new string [] { "method" };
5508 public Destructor (DeclSpace parent, Expression return_type, int mod,
5509 string name, Parameters parameters, Attributes attrs,
5511 : base (parent, null, return_type, mod, false, new MemberName (name, l),
5515 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
5517 if (a.Type == TypeManager.conditional_attribute_type) {
5518 Error_ConditionalAttributeIsNotValid ();
5522 base.ApplyAttributeBuilder (a, cb);
5525 public override string GetSignatureForError ()
5527 return Parent.GetSignatureForError () + ".~" + Parent.MemberName.Name + "()";
5530 public override string[] ValidAttributeTargets {
5532 return attribute_targets;
5537 abstract public class MemberBase : MemberCore {
5538 public Expression Type;
5539 public readonly DeclSpace ds;
5540 public readonly GenericMethod GenericMethod;
5543 // The type of this property / indexer / event
5545 protected Type member_type;
5546 public Type MemberType {
5548 if (member_type == null && Type != null) {
5549 IResolveContext rc = GenericMethod == null ? this : (IResolveContext)ds;
5550 Type = Type.ResolveAsTypeTerminal (rc, false);
5552 member_type = Type.Type;
5560 // The constructor is only exposed to our children
5562 protected MemberBase (DeclSpace parent, GenericMethod generic,
5563 Expression type, int mod, int allowed_mod, int def_mod,
5564 MemberName name, Attributes attrs)
5565 : base (parent, name, attrs)
5567 this.ds = generic != null ? generic : (DeclSpace) parent;
5569 ModFlags = Modifiers.Check (allowed_mod, mod, def_mod, Location);
5570 GenericMethod = generic;
5571 if (GenericMethod != null)
5572 GenericMethod.ModFlags = ModFlags;
5575 protected virtual bool CheckBase ()
5577 if ((ModFlags & Modifiers.PROTECTED) != 0 && Parent.PartialContainer.Kind == Kind.Struct) {
5578 Report.Error (666, Location, "`{0}': new protected member declared in struct", GetSignatureForError ());
5582 if ((RootContext.WarningLevel >= 4) &&
5583 ((Parent.ModFlags & Modifiers.SEALED) != 0) &&
5584 ((ModFlags & Modifiers.PROTECTED) != 0) &&
5585 ((ModFlags & Modifiers.OVERRIDE) == 0) && (Name != "Finalize")) {
5586 Report.Warning (628, 4, Location, "`{0}': new protected member declared in sealed class", GetSignatureForError ());
5591 protected virtual bool DoDefine ()
5593 if (MemberType == null)
5596 if ((Parent.ModFlags & Modifiers.SEALED) != 0 &&
5597 (ModFlags & (Modifiers.VIRTUAL|Modifiers.ABSTRACT)) != 0) {
5598 Report.Error (549, Location, "New virtual member `{0}' is declared in a sealed class `{1}'",
5599 GetSignatureForError (), Parent.GetSignatureForError ());
5603 // verify accessibility
5604 if (!Parent.AsAccessible (MemberType, ModFlags)) {
5605 Report.SymbolRelatedToPreviousError (MemberType);
5606 if (this is Property)
5607 Report.Error (53, Location,
5608 "Inconsistent accessibility: property type `" +
5609 TypeManager.CSharpName (MemberType) + "' is less " +
5610 "accessible than property `" + GetSignatureForError () + "'");
5611 else if (this is Indexer)
5612 Report.Error (54, Location,
5613 "Inconsistent accessibility: indexer return type `" +
5614 TypeManager.CSharpName (MemberType) + "' is less " +
5615 "accessible than indexer `" + GetSignatureForError () + "'");
5616 else if (this is MethodCore) {
5617 if (this is Operator)
5618 Report.Error (56, Location,
5619 "Inconsistent accessibility: return type `" +
5620 TypeManager.CSharpName (MemberType) + "' is less " +
5621 "accessible than operator `" + GetSignatureForError () + "'");
5623 Report.Error (50, Location,
5624 "Inconsistent accessibility: return type `" +
5625 TypeManager.CSharpName (MemberType) + "' is less " +
5626 "accessible than method `" + GetSignatureForError () + "'");
5628 Report.Error (52, Location,
5629 "Inconsistent accessibility: field type `" +
5630 TypeManager.CSharpName (MemberType) + "' is less " +
5631 "accessible than field `" + GetSignatureForError () + "'");
5639 protected bool IsTypePermitted ()
5641 if (MemberType == TypeManager.arg_iterator_type || MemberType == TypeManager.typed_reference_type) {
5642 Report.Error (610, Location, "Field or property cannot be of type `{0}'", TypeManager.CSharpName (MemberType));
5650 // Abstract class for all fields
5652 abstract public class FieldBase : MemberBase {
5653 public FieldBuilder FieldBuilder;
5654 public Status status;
5655 protected Expression initializer;
5658 public enum Status : byte {
5659 HAS_OFFSET = 4 // Used by FieldMember.
5662 static readonly string[] attribute_targets = new string [] { "field" };
5664 protected FieldBase (DeclSpace parent, Expression type, int mod,
5665 int allowed_mod, MemberName name, Attributes attrs)
5666 : base (parent, null, type, mod, allowed_mod | Modifiers.ABSTRACT, Modifiers.PRIVATE,
5669 if ((mod & Modifiers.ABSTRACT) != 0)
5670 Report.Error (681, Location, "The modifier 'abstract' is not valid on fields. Try using a property instead");
5673 public override AttributeTargets AttributeTargets {
5675 return AttributeTargets.Field;
5679 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
5681 if (a.Type == TypeManager.field_offset_attribute_type) {
5682 status |= Status.HAS_OFFSET;
5684 if (!Parent.PartialContainer.HasExplicitLayout) {
5685 Report.Error (636, Location, "The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit)");
5689 if ((ModFlags & Modifiers.STATIC) != 0 || this is Const) {
5690 Report.Error (637, Location, "The FieldOffset attribute is not allowed on static or const fields");
5696 if (a.Type == TypeManager.fixed_buffer_attr_type) {
5697 Report.Error (1716, Location, "Do not use 'System.Runtime.CompilerServices.FixedBuffer' attribute. Use the 'fixed' field modifier instead");
5702 if (a.Type == TypeManager.marshal_as_attr_type) {
5703 UnmanagedMarshal marshal = a.GetMarshal (this);
5704 if (marshal != null) {
5705 FieldBuilder.SetMarshal (marshal);
5710 if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
5711 a.Error_InvalidSecurityParent ();
5715 FieldBuilder.SetCustomAttribute (cb);
5718 protected override bool CheckBase ()
5720 if (!base.CheckBase ())
5723 MemberInfo conflict_symbol = Parent.PartialContainer.FindBaseMemberWithSameName (Name, false);
5724 if (conflict_symbol == null) {
5725 if ((ModFlags & Modifiers.NEW) != 0) {
5726 Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
5731 if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0) {
5732 Report.SymbolRelatedToPreviousError (conflict_symbol);
5733 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
5734 GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
5740 public override bool Define()
5742 if (MemberType == null || Type == null)
5745 if (TypeManager.IsGenericParameter (MemberType))
5748 if (MemberType == TypeManager.void_type) {
5749 // TODO: wrong location
5750 Expression.Error_VoidInvalidInTheContext (Location);
5754 if (MemberType.IsSealed && MemberType.IsAbstract) {
5755 Error_VariableOfStaticClass (Location, GetSignatureForError (), MemberType);
5762 if (!Parent.AsAccessible (MemberType, ModFlags)) {
5763 Report.Error (52, Location,
5764 "Inconsistent accessibility: field type `" +
5765 TypeManager.CSharpName (MemberType) + "' is less " +
5766 "accessible than field `" + GetSignatureForError () + "'");
5770 if (!IsTypePermitted ())
5777 // Represents header string for documentation comment.
5779 public override string DocCommentHeader {
5780 get { return "F:"; }
5783 public override void Emit ()
5785 if (OptAttributes != null) {
5786 OptAttributes.Emit ();
5789 if (((status & Status.HAS_OFFSET) == 0) && (ModFlags & Modifiers.STATIC) == 0 && Parent.PartialContainer.HasExplicitLayout) {
5790 Report.Error (625, Location, "`{0}': Instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute.", GetSignatureForError ());
5796 public static void Error_VariableOfStaticClass (Location loc, string variableName, Type staticClass)
5798 Report.SymbolRelatedToPreviousError (staticClass);
5799 Report.Error (723, loc, "`{0}': cannot declare variables of static types",
5803 public Expression Initializer {
5805 if (value != null) {
5806 this.initializer = value;
5811 protected virtual bool IsFieldClsCompliant {
5813 if (FieldBuilder == null)
5816 return AttributeTester.IsClsCompliant (FieldBuilder.FieldType);
5820 public override string[] ValidAttributeTargets
5823 return attribute_targets;
5827 protected override bool VerifyClsCompliance ()
5829 if (!base.VerifyClsCompliance ())
5832 if (!IsFieldClsCompliant) {
5833 Report.Error (3003, Location, "Type of `{0}' is not CLS-compliant", GetSignatureForError ());
5838 public void SetAssigned ()
5840 caching_flags |= Flags.IsAssigned;
5844 interface IFixedBuffer
5846 FieldInfo Element { get; }
5847 Type ElementType { get; }
5850 public class FixedFieldExternal: IFixedBuffer
5852 FieldInfo element_field;
5854 public FixedFieldExternal (FieldInfo fi)
5856 element_field = fi.FieldType.GetField (FixedField.FixedElementName);
5859 #region IFixedField Members
5861 public FieldInfo Element {
5863 return element_field;
5867 public Type ElementType {
5869 return element_field.FieldType;
5877 /// Fixed buffer implementation
5879 public class FixedField : FieldBase, IFixedBuffer
5881 public const string FixedElementName = "FixedElementField";
5882 static int GlobalCounter = 0;
5883 static object[] ctor_args = new object[] { (short)LayoutKind.Sequential };
5884 static FieldInfo[] fi;
5886 TypeBuilder fixed_buffer_type;
5887 FieldBuilder element;
5888 Expression size_expr;
5891 const int AllowedModifiers =
5894 Modifiers.PROTECTED |
5895 Modifiers.INTERNAL |
5898 public FixedField (DeclSpace parent, Expression type, int mod, string name,
5899 Expression size_expr, Attributes attrs, Location loc):
5900 base (parent, type, mod, AllowedModifiers, new MemberName (name, loc), attrs)
5902 if (RootContext.Version == LanguageVersion.ISO_1)
5903 Report.FeatureIsNotISO1 (loc, "fixed size buffers");
5905 this.size_expr = size_expr;
5908 public override bool Define()
5911 if ((ModFlags & (Modifiers.PUBLIC | Modifiers.PROTECTED)) != 0)
5912 Report.Warning (-23, 1, Location, "Only private or internal fixed sized buffers are supported by .NET 1.x");
5915 if (Parent.PartialContainer.Kind != Kind.Struct) {
5916 Report.Error (1642, Location, "`{0}': Fixed size buffer fields may only be members of structs",
5917 GetSignatureForError ());
5921 if (!base.Define ())
5924 if (!TypeManager.IsPrimitiveType (MemberType)) {
5925 Report.Error (1663, Location, "`{0}': Fixed size buffers type must be one of the following: bool, byte, short, int, long, char, sbyte, ushort, uint, ulong, float or double",
5926 GetSignatureForError ());
5930 EmitContext ec = new EmitContext (this, Parent, Location, null, null, ModFlags);
5931 Constant c = size_expr.ResolveAsConstant (ec, this);
5935 IntConstant buffer_size_const = c.ImplicitConversionRequired (TypeManager.int32_type, Location) as IntConstant;
5936 if (buffer_size_const == null)
5939 buffer_size = buffer_size_const.Value;
5941 if (buffer_size <= 0) {
5942 Report.Error (1665, Location, "`{0}': Fixed size buffers must have a length greater than zero", GetSignatureForError ());
5946 int type_size = Expression.GetTypeSize (MemberType);
5948 if (buffer_size > int.MaxValue / type_size) {
5949 Report.Error (1664, Location, "Fixed size buffer `{0}' of length `{1}' and type `{2}' exceeded 2^31 limit",
5950 GetSignatureForError (), buffer_size.ToString (), TypeManager.CSharpName (MemberType));
5954 buffer_size *= type_size;
5957 string name = String.Format ("<{0}>__FixedBuffer{1}", Name, GlobalCounter++);
5959 fixed_buffer_type = Parent.TypeBuilder.DefineNestedType (name,
5960 TypeAttributes.NestedPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, TypeManager.value_type);
5961 element = fixed_buffer_type.DefineField (FixedElementName, MemberType, FieldAttributes.Public);
5962 RootContext.RegisterCompilerGeneratedType (fixed_buffer_type);
5964 FieldBuilder = Parent.TypeBuilder.DefineField (Name, fixed_buffer_type, Modifiers.FieldAttr (ModFlags));
5965 TypeManager.RegisterFieldBase (FieldBuilder, this);
5970 public override void Emit()
5973 fi = new FieldInfo [] { TypeManager.struct_layout_attribute_type.GetField ("Size") };
5975 object[] fi_val = new object[1];
5976 fi_val [0] = buffer_size;
5978 CustomAttributeBuilder cab = new CustomAttributeBuilder (TypeManager.struct_layout_attribute_ctor,
5979 ctor_args, fi, fi_val);
5980 fixed_buffer_type.SetCustomAttribute (cab);
5983 cab = new CustomAttributeBuilder (TypeManager.fixed_buffer_attr_ctor, new object[] { MemberType, buffer_size } );
5984 FieldBuilder.SetCustomAttribute (cab);
5989 protected override bool IsFieldClsCompliant {
5995 #region IFixedField Members
5997 public FieldInfo Element {
6003 public Type ElementType {
6013 // The Field class is used to represents class/struct fields during parsing.
6015 public class Field : FieldBase {
6017 // Modifiers allowed in a class declaration
6019 const int AllowedModifiers =
6022 Modifiers.PROTECTED |
6023 Modifiers.INTERNAL |
6026 Modifiers.VOLATILE |
6030 public Field (DeclSpace parent, Expression type, int mod, string name,
6031 Attributes attrs, Location loc)
6032 : base (parent, type, mod, AllowedModifiers, new MemberName (name, loc),
6037 public override bool Define ()
6039 if (!base.Define ())
6042 if (RootContext.WarningLevel > 1){
6043 Type ptype = Parent.TypeBuilder.BaseType;
6045 // ptype is only null for System.Object while compiling corlib.
6047 TypeContainer.FindMembers (
6048 ptype, MemberTypes.Method,
6049 BindingFlags.Public |
6050 BindingFlags.Static | BindingFlags.Instance,
6051 System.Type.FilterName, Name);
6055 if ((ModFlags & Modifiers.VOLATILE) != 0){
6056 if (!MemberType.IsClass){
6057 Type vt = MemberType;
6059 if (TypeManager.IsEnumType (vt))
6060 vt = TypeManager.EnumToUnderlying (MemberType);
6062 if (!((vt == TypeManager.bool_type) ||
6063 (vt == TypeManager.sbyte_type) ||
6064 (vt == TypeManager.byte_type) ||
6065 (vt == TypeManager.short_type) ||
6066 (vt == TypeManager.ushort_type) ||
6067 (vt == TypeManager.int32_type) ||
6068 (vt == TypeManager.uint32_type) ||
6069 (vt == TypeManager.char_type) ||
6070 (vt == TypeManager.float_type) ||
6071 (!vt.IsValueType))){
6072 Report.Error (677, Location, "`{0}': A volatile field cannot be of the type `{1}'",
6073 GetSignatureForError (), TypeManager.CSharpName (vt));
6078 if ((ModFlags & Modifiers.READONLY) != 0){
6079 Report.Error (678, Location, "`{0}': A field cannot be both volatile and readonly",
6080 GetSignatureForError ());
6085 FieldAttributes fa = Modifiers.FieldAttr (ModFlags);
6087 if (Parent.PartialContainer.Kind == Kind.Struct &&
6088 ((fa & FieldAttributes.Static) == 0) &&
6089 MemberType == Parent.TypeBuilder &&
6090 !TypeManager.IsBuiltinType (MemberType)){
6091 Report.Error (523, Location, "Struct member `" + Parent.Name + "." + Name +
6092 "' causes a cycle in the structure layout");
6097 FieldBuilder = Parent.TypeBuilder.DefineField (
6098 Name, MemberType, Modifiers.FieldAttr (ModFlags));
6100 TypeManager.RegisterFieldBase (FieldBuilder, this);
6102 catch (ArgumentException) {
6103 Report.Warning (-24, 1, Location, "The Microsoft runtime is unable to use [void|void*] as a field type, try using the Mono runtime.");
6107 if (initializer != null)
6108 Parent.PartialContainer.RegisterFieldForInitialization (this,
6109 new FieldInitializer (FieldBuilder, initializer, Parent));
6114 protected override bool VerifyClsCompliance ()
6116 if (!base.VerifyClsCompliance ())
6119 if ((ModFlags & Modifiers.VOLATILE) != 0) {
6120 Report.Warning (3026, 1, Location, "CLS-compliant field `{0}' cannot be volatile", GetSignatureForError ());
6128 // `set' and `get' accessors are represented with an Accessor.
6130 public class Accessor : IAnonymousHost {
6132 // Null if the accessor is empty, or a Block if not
6134 public const int AllowedModifiers =
6136 Modifiers.PROTECTED |
6137 Modifiers.INTERNAL |
6140 public ToplevelBlock Block;
6141 public Attributes Attributes;
6142 public Location Location;
6143 public int ModFlags;
6145 public ArrayList AnonymousMethods;
6147 public Accessor (ToplevelBlock b, int mod, Attributes attrs, Location loc)
6152 ModFlags = Modifiers.Check (AllowedModifiers, mod, 0, loc);
6155 public void SetYields ()
6160 public void AddAnonymousMethod (AnonymousMethodExpression ame)
6162 if (AnonymousMethods == null)
6163 AnonymousMethods = new ArrayList ();
6164 AnonymousMethods.Add (ame);
6168 // Ooouh Martin, templates are missing here.
6169 // When it will be possible move here a lot of child code and template method type.
6170 public abstract class AbstractPropertyEventMethod : MemberCore, IMethodData {
6171 protected MethodData method_data;
6172 protected ToplevelBlock block;
6173 protected ListDictionary declarative_security;
6175 // The accessor are created event if they are not wanted.
6176 // But we need them because their names are reserved.
6177 // Field says whether accessor will be emited or not
6178 public readonly bool IsDummy;
6180 protected readonly string prefix;
6182 ReturnParameter return_attributes;
6184 public AbstractPropertyEventMethod (PropertyBasedMember member, string prefix)
6185 : base (member.Parent, SetupName (prefix, member, member.Location), null)
6187 this.prefix = prefix;
6191 public AbstractPropertyEventMethod (InterfaceMemberBase member, Accessor accessor,
6193 : base (member.Parent, SetupName (prefix, member, accessor.Location),
6194 accessor.Attributes)
6196 this.prefix = prefix;
6197 this.block = accessor.Block;
6200 static MemberName SetupName (string prefix, InterfaceMemberBase member, Location loc)
6202 return new MemberName (member.MemberName.Left, prefix + member.ShortName, loc);
6205 public void UpdateName (InterfaceMemberBase member)
6207 SetMemberName (SetupName (prefix, member, Location));
6210 #region IMethodData Members
6212 public abstract Iterator Iterator {
6216 public ToplevelBlock Block {
6226 public CallingConventions CallingConventions {
6228 return CallingConventions.Standard;
6232 public bool IsExcluded ()
6237 GenericMethod IMethodData.GenericMethod {
6243 public MemberName MethodName {
6249 public Type[] ParameterTypes {
6251 return ParameterInfo.Types;
6255 public abstract Parameters ParameterInfo { get ; }
6256 public abstract Type ReturnType { get; }
6257 public abstract EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig);
6261 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
6263 if (a.Type == TypeManager.cls_compliant_attribute_type || a.Type == TypeManager.obsolete_attribute_type ||
6264 a.Type == TypeManager.conditional_attribute_type) {
6265 Report.Error (1667, a.Location,
6266 "Attribute `{0}' is not valid on property or event accessors. It is valid on `{1}' declarations only",
6267 TypeManager.CSharpName (a.Type), a.GetValidTargets ());
6271 if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
6272 if (declarative_security == null)
6273 declarative_security = new ListDictionary ();
6274 a.ExtractSecurityPermissionSet (declarative_security);
6278 if (a.Target == AttributeTargets.Method) {
6279 method_data.MethodBuilder.SetCustomAttribute (cb);
6283 if (a.Target == AttributeTargets.ReturnValue) {
6284 if (return_attributes == null)
6285 return_attributes = new ReturnParameter (method_data.MethodBuilder, Location);
6287 return_attributes.ApplyAttributeBuilder (a, cb);
6291 ApplyToExtraTarget (a, cb);
6294 virtual protected void ApplyToExtraTarget (Attribute a, CustomAttributeBuilder cb)
6296 System.Diagnostics.Debug.Fail ("You forgot to define special attribute target handling");
6299 // It is not supported for the accessors
6300 public sealed override bool Define()
6302 throw new NotSupportedException ();
6305 public void Emit (DeclSpace parent)
6307 EmitMethod (parent);
6309 if (OptAttributes != null)
6310 OptAttributes.Emit ();
6312 if (declarative_security != null) {
6313 foreach (DictionaryEntry de in declarative_security) {
6314 method_data.MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
6321 protected virtual void EmitMethod (DeclSpace parent)
6323 method_data.Emit (parent);
6326 public override bool IsClsComplianceRequired()
6331 public bool IsDuplicateImplementation (MethodCore method)
6333 if (!MemberName.Equals (method.MemberName))
6336 Type[] param_types = method.ParameterTypes;
6338 if (param_types.Length != ParameterTypes.Length)
6341 for (int i = 0; i < param_types.Length; i++)
6342 if (param_types [i] != ParameterTypes [i])
6345 Report.SymbolRelatedToPreviousError (method);
6346 Report.Error (111, Location, TypeContainer.Error111, method.GetSignatureForError ());
6350 public override bool IsUsed
6360 public new Location Location {
6362 return base.Location;
6366 public virtual bool ResolveMembers ()
6372 // Represents header string for documentation comment.
6374 public override string DocCommentHeader {
6375 get { throw new InvalidOperationException ("Unexpected attempt to get doc comment from " + this.GetType () + "."); }
6381 // Properties and Indexers both generate PropertyBuilders, we use this to share
6382 // their common bits.
6384 abstract public class PropertyBase : PropertyBasedMember {
6386 public class GetMethod : PropertyMethod
6388 static string[] attribute_targets = new string [] { "method", "return" };
6390 public GetMethod (PropertyBase method):
6391 base (method, "get_")
6395 public GetMethod (PropertyBase method, Accessor accessor):
6396 base (method, accessor, "get_")
6400 public override MethodBuilder Define (DeclSpace parent)
6402 base.Define (parent);
6404 method_data = new MethodData (method, ModFlags, flags, this);
6406 if (!method_data.Define (parent))
6409 return method_data.MethodBuilder;
6412 public override Type ReturnType {
6414 return method.MemberType;
6418 public override Parameters ParameterInfo {
6420 return Parameters.EmptyReadOnlyParameters;
6424 public override string[] ValidAttributeTargets {
6426 return attribute_targets;
6431 public class SetMethod : PropertyMethod {
6433 static string[] attribute_targets = new string [] { "method", "param", "return" };
6434 ImplicitParameter param_attr;
6435 protected Parameters parameters;
6437 public SetMethod (PropertyBase method):
6438 base (method, "set_")
6442 public SetMethod (PropertyBase method, Accessor accessor):
6443 base (method, accessor, "set_")
6447 protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
6449 if (a.Target == AttributeTargets.Parameter) {
6450 if (param_attr == null)
6451 param_attr = new ImplicitParameter (method_data.MethodBuilder);
6453 param_attr.ApplyAttributeBuilder (a, cb);
6457 base.ApplyAttributeBuilder (a, cb);
6460 public override Parameters ParameterInfo {
6462 if (parameters == null)
6463 DefineParameters ();
6468 protected virtual void DefineParameters ()
6470 parameters = new Parameters (
6471 new Parameter[] { new Parameter (method.MemberType, "value", Parameter.Modifier.NONE, null, Location) },
6472 new Type[] { method.MemberType });
6475 public override MethodBuilder Define (DeclSpace parent)
6480 base.Define (parent);
6482 method_data = new MethodData (method, ModFlags, flags, this);
6484 if (!method_data.Define (parent))
6487 return method_data.MethodBuilder;
6490 public override Type ReturnType {
6492 return TypeManager.void_type;
6496 public override string[] ValidAttributeTargets {
6498 return attribute_targets;
6503 static string[] attribute_targets = new string [] { "property" };
6505 public abstract class PropertyMethod : AbstractPropertyEventMethod
6507 protected readonly PropertyBase method;
6508 protected MethodAttributes flags;
6510 ArrayList anonymous_methods;
6513 public PropertyMethod (PropertyBase method, string prefix)
6514 : base (method, prefix)
6516 this.method = method;
6519 public PropertyMethod (PropertyBase method, Accessor accessor,
6521 : base (method, accessor, prefix)
6523 this.method = method;
6524 this.ModFlags = accessor.ModFlags;
6525 yields = accessor.Yields;
6526 anonymous_methods = accessor.AnonymousMethods;
6528 if (accessor.ModFlags != 0 && RootContext.Version == LanguageVersion.ISO_1) {
6529 Report.FeatureIsNotISO1 (Location, "access modifiers on properties");
6533 public override Iterator Iterator {
6534 get { return iterator; }
6537 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
6539 if (a.IsInternalMethodImplAttribute) {
6540 method.is_external_implementation = true;
6543 base.ApplyAttributeBuilder (a, cb);
6546 public override AttributeTargets AttributeTargets {
6548 return AttributeTargets.Method;
6552 public override bool IsClsComplianceRequired ()
6554 return method.IsClsComplianceRequired ();
6557 public override bool ResolveMembers ()
6560 iterator = Iterator.CreateIterator (this, Parent, null, ModFlags);
6561 if (iterator == null)
6565 if (anonymous_methods != null) {
6566 foreach (AnonymousMethodExpression ame in anonymous_methods) {
6567 if (!ame.CreateAnonymousHelpers ())
6575 public virtual MethodBuilder Define (DeclSpace parent)
6577 if (!method.CheckAbstractAndExtern (block != null))
6580 TypeContainer container = parent.PartialContainer;
6583 // Check for custom access modifier
6585 if (ModFlags == 0) {
6586 ModFlags = method.ModFlags;
6587 flags = method.flags;
6589 if (container.Kind == Kind.Interface)
6590 Report.Error (275, Location, "`{0}': accessibility modifiers may not be used on accessors in an interface",
6591 GetSignatureForError ());
6593 if ((method.ModFlags & Modifiers.ABSTRACT) != 0 && (ModFlags & Modifiers.PRIVATE) != 0) {
6594 Report.Error (442, Location, "`{0}': abstract properties cannot have private accessors", GetSignatureForError ());
6597 CheckModifiers (ModFlags);
6598 ModFlags |= (method.ModFlags & (~Modifiers.Accessibility));
6599 ModFlags |= Modifiers.PROPERTY_CUSTOM;
6600 flags = Modifiers.MethodAttr (ModFlags);
6601 flags |= (method.flags & (~MethodAttributes.MemberAccessMask));
6607 public bool HasCustomAccessModifier
6610 return (ModFlags & Modifiers.PROPERTY_CUSTOM) != 0;
6614 public override EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig)
6616 return new EmitContext (method,
6617 ds, method.ds, method.Location, ig, ReturnType,
6618 method.ModFlags, false);
6621 public override ObsoleteAttribute GetObsoleteAttribute ()
6623 return method.GetObsoleteAttribute ();
6626 public override string GetSignatureForError()
6628 return method.GetSignatureForError () + '.' + prefix.Substring (0, 3);
6631 void CheckModifiers (int modflags)
6634 int mflags = method.ModFlags & Modifiers.Accessibility;
6636 if ((mflags & Modifiers.PUBLIC) != 0) {
6637 flags |= Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE;
6639 else if ((mflags & Modifiers.PROTECTED) != 0) {
6640 if ((mflags & Modifiers.INTERNAL) != 0)
6641 flags |= Modifiers.PROTECTED | Modifiers.INTERNAL;
6643 flags |= Modifiers.PRIVATE;
6645 else if ((mflags & Modifiers.INTERNAL) != 0)
6646 flags |= Modifiers.PRIVATE;
6648 if ((mflags == modflags) || (modflags & (~flags)) != 0) {
6649 Report.Error (273, Location,
6650 "The accessibility modifier of the `{0}' accessor must be more restrictive than the modifier of the property or indexer `{1}'",
6651 GetSignatureForError (), method.GetSignatureForError ());
6655 public override bool MarkForDuplicationCheck ()
6657 caching_flags |= Flags.TestMethodDuplication;
6662 public PropertyMethod Get, Set;
6663 public PropertyBuilder PropertyBuilder;
6664 public MethodBuilder GetBuilder, SetBuilder;
6666 protected bool define_set_first = false;
6668 public PropertyBase (DeclSpace parent, Expression type, int mod_flags,
6669 int allowed_mod, bool is_iface, MemberName name,
6670 Attributes attrs, bool define_set_first)
6671 : base (parent, null, type, mod_flags, allowed_mod, is_iface, name, attrs)
6673 this.define_set_first = define_set_first;
6676 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
6678 if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
6679 a.Error_InvalidSecurityParent ();
6683 PropertyBuilder.SetCustomAttribute (cb);
6686 public override AttributeTargets AttributeTargets {
6688 return AttributeTargets.Property;
6692 public override bool Define ()
6697 if (!IsTypePermitted ())
6703 protected override bool DoDefine ()
6705 if (!base.DoDefine ())
6709 // Accessors modifiers check
6711 if (Get.ModFlags != 0 && Set.ModFlags != 0) {
6712 Report.Error (274, Location, "`{0}': Cannot specify accessibility modifiers for both accessors of the property or indexer",
6713 GetSignatureForError ());
6717 if ((Get.IsDummy || Set.IsDummy)
6718 && (Get.ModFlags != 0 || Set.ModFlags != 0) && (ModFlags & Modifiers.OVERRIDE) == 0) {
6719 Report.Error (276, Location,
6720 "`{0}': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor",
6721 GetSignatureForError ());
6725 if (MemberType.IsAbstract && MemberType.IsSealed) {
6726 Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
6738 GetBuilder = Get.Define (Parent);
6739 return GetBuilder != null;
6742 bool DefineSet (bool define)
6744 if (!define || Set.IsDummy)
6747 SetBuilder = Set.Define (Parent);
6748 return SetBuilder != null;
6751 protected bool DefineAccessors ()
6753 return DefineSet (define_set_first) &&
6755 DefineSet (!define_set_first);
6758 protected abstract PropertyInfo ResolveBaseProperty ();
6760 // TODO: rename to Resolve......
6761 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
6763 PropertyInfo base_property = ResolveBaseProperty ();
6764 if (base_property == null)
6767 base_ret_type = base_property.PropertyType;
6768 MethodInfo get_accessor = base_property.GetGetMethod (true);
6769 MethodInfo set_accessor = base_property.GetSetMethod (true);
6770 MethodAttributes get_accessor_access, set_accessor_access;
6772 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
6773 if (Get != null && !Get.IsDummy && get_accessor == null) {
6774 Report.SymbolRelatedToPreviousError (base_property);
6775 Report.Error (545, Location, "`{0}.get': cannot override because `{1}' does not have an overridable get accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
6778 if (Set != null && !Set.IsDummy && set_accessor == null) {
6779 Report.SymbolRelatedToPreviousError (base_property);
6780 Report.Error (546, Location, "`{0}.set': cannot override because `{1}' does not have an overridable set accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
6785 // Check base class accessors access
6788 // TODO: rewrite to reuse Get|Set.CheckAccessModifiers and share code there
6789 get_accessor_access = set_accessor_access = 0;
6790 if ((ModFlags & Modifiers.NEW) == 0) {
6791 if (get_accessor != null) {
6792 MethodAttributes get_flags = Modifiers.MethodAttr (Get.ModFlags != 0 ? Get.ModFlags : ModFlags);
6793 get_accessor_access = (get_accessor.Attributes & MethodAttributes.MemberAccessMask);
6795 if (!Get.IsDummy && !CheckAccessModifiers (get_flags & MethodAttributes.MemberAccessMask, get_accessor_access, get_accessor))
6796 Error_CannotChangeAccessModifiers (get_accessor, get_accessor_access, ".get");
6799 if (set_accessor != null) {
6800 MethodAttributes set_flags = Modifiers.MethodAttr (Set.ModFlags != 0 ? Set.ModFlags : ModFlags);
6801 set_accessor_access = (set_accessor.Attributes & MethodAttributes.MemberAccessMask);
6803 if (!Set.IsDummy && !CheckAccessModifiers (set_flags & MethodAttributes.MemberAccessMask, set_accessor_access, set_accessor))
6804 Error_CannotChangeAccessModifiers (set_accessor, set_accessor_access, ".set");
6808 // When one accessor does not exist and property hides base one
6809 // we need to propagate this upwards
6810 if (set_accessor == null)
6811 set_accessor = get_accessor;
6814 // Get the less restrictive access
6816 return get_accessor_access > set_accessor_access ? get_accessor : set_accessor;
6819 public override void Emit ()
6822 // The PropertyBuilder can be null for explicit implementations, in that
6823 // case, we do not actually emit the ".property", so there is nowhere to
6824 // put the attribute
6826 if (PropertyBuilder != null && OptAttributes != null)
6827 OptAttributes.Emit ();
6839 /// Tests whether accessors are not in collision with some method (CS0111)
6841 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
6843 return Get.IsDuplicateImplementation (mc) || Set.IsDuplicateImplementation (mc);
6846 public override bool IsUsed
6852 return Get.IsUsed | Set.IsUsed;
6856 protected override void SetMemberName (MemberName new_name)
6858 base.SetMemberName (new_name);
6860 Get.UpdateName (this);
6861 Set.UpdateName (this);
6864 public override string[] ValidAttributeTargets {
6866 return attribute_targets;
6871 // Represents header string for documentation comment.
6873 public override string DocCommentHeader {
6874 get { return "P:"; }
6878 public class Property : PropertyBase {
6879 const int AllowedModifiers =
6882 Modifiers.PROTECTED |
6883 Modifiers.INTERNAL |
6887 Modifiers.OVERRIDE |
6888 Modifiers.ABSTRACT |
6891 Modifiers.METHOD_YIELDS |
6894 const int AllowedInterfaceModifiers =
6897 public Property (DeclSpace parent, Expression type, int mod, bool is_iface,
6898 MemberName name, Attributes attrs, Accessor get_block,
6899 Accessor set_block, bool define_set_first)
6900 : base (parent, type, mod,
6901 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
6902 is_iface, name, attrs, define_set_first)
6904 if (get_block == null)
6905 Get = new GetMethod (this);
6907 Get = new GetMethod (this, get_block);
6909 if (set_block == null)
6910 Set = new SetMethod (this);
6912 Set = new SetMethod (this, set_block);
6915 public override bool Define ()
6917 if (!DoDefineBase ())
6920 if (!base.Define ())
6926 flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
6928 if (!DefineAccessors ())
6931 // FIXME - PropertyAttributes.HasDefault ?
6933 PropertyBuilder = Parent.TypeBuilder.DefineProperty (
6934 MemberName.ToString (), PropertyAttributes.None, MemberType, null);
6937 PropertyBuilder.SetGetMethod (GetBuilder);
6940 PropertyBuilder.SetSetMethod (SetBuilder);
6942 TypeManager.RegisterProperty (PropertyBuilder, this);
6946 protected override PropertyInfo ResolveBaseProperty ()
6948 return Parent.PartialContainer.BaseCache.FindMemberToOverride (
6949 Parent.TypeBuilder, Name, Parameters.EmptyReadOnlyParameters.Types, null, true) as PropertyInfo;
6954 /// Gigantic workaround for lameness in SRE follows :
6955 /// This class derives from EventInfo and attempts to basically
6956 /// wrap around the EventBuilder so that FindMembers can quickly
6957 /// return this in it search for members
6959 public class MyEventBuilder : EventInfo {
6962 // We use this to "point" to our Builder which is
6963 // not really a MemberInfo
6965 EventBuilder MyBuilder;
6968 // We "catch" and wrap these methods
6970 MethodInfo raise, remove, add;
6972 EventAttributes attributes;
6973 Type declaring_type, reflected_type, event_type;
6978 public MyEventBuilder (Event ev, TypeBuilder type_builder, string name, EventAttributes event_attr, Type event_type)
6980 MyBuilder = type_builder.DefineEvent (name, event_attr, event_type);
6982 // And now store the values in our own fields.
6984 declaring_type = type_builder;
6986 reflected_type = type_builder;
6988 attributes = event_attr;
6991 this.event_type = event_type;
6995 // Methods that you have to override. Note that you only need
6996 // to "implement" the variants that take the argument (those are
6997 // the "abstract" methods, the others (GetAddMethod()) are
7000 public override MethodInfo GetAddMethod (bool nonPublic)
7005 public override MethodInfo GetRemoveMethod (bool nonPublic)
7010 public override MethodInfo GetRaiseMethod (bool nonPublic)
7016 // These methods make "MyEventInfo" look like a Builder
7018 public void SetRaiseMethod (MethodBuilder raiseMethod)
7020 raise = raiseMethod;
7021 MyBuilder.SetRaiseMethod (raiseMethod);
7024 public void SetRemoveOnMethod (MethodBuilder removeMethod)
7026 remove = removeMethod;
7027 MyBuilder.SetRemoveOnMethod (removeMethod);
7030 public void SetAddOnMethod (MethodBuilder addMethod)
7033 MyBuilder.SetAddOnMethod (addMethod);
7036 public void SetCustomAttribute (CustomAttributeBuilder cb)
7038 MyBuilder.SetCustomAttribute (cb);
7041 public override object [] GetCustomAttributes (bool inherit)
7043 // FIXME : There's nothing which can be seemingly done here because
7044 // we have no way of getting at the custom attribute objects of the
7049 public override object [] GetCustomAttributes (Type t, bool inherit)
7051 // FIXME : Same here !
7055 public override bool IsDefined (Type t, bool b)
7060 public override EventAttributes Attributes {
7066 public override string Name {
7072 public override Type DeclaringType {
7074 return declaring_type;
7078 public override Type ReflectedType {
7080 return reflected_type;
7084 public Type EventType {
7090 public void SetUsed ()
7092 if (my_event != null) {
7093 // my_event.SetAssigned ();
7094 my_event.SetMemberIsUsed ();
7100 /// For case when event is declared like property (with add and remove accessors).
7102 public class EventProperty: Event {
7103 abstract class AEventPropertyAccessor : AEventAccessor
7105 readonly ArrayList anonymous_methods;
7107 public AEventPropertyAccessor (Event method, Accessor accessor, string prefix):
7108 base (method, accessor, prefix)
7110 this.anonymous_methods = accessor.AnonymousMethods;
7113 public override MethodBuilder Define (DeclSpace ds)
7115 method.CheckAbstractAndExtern (block != null);
7116 return base.Define (ds);
7119 public override bool ResolveMembers ()
7121 if (anonymous_methods == null)
7124 foreach (AnonymousMethodExpression ame in anonymous_methods) {
7125 if (!ame.CreateAnonymousHelpers ())
7134 sealed class AddDelegateMethod: AEventPropertyAccessor
7136 public AddDelegateMethod (Event method, Accessor accessor):
7137 base (method, accessor, "add_")
7141 protected override MethodInfo DelegateMethodInfo {
7143 return TypeManager.delegate_combine_delegate_delegate;
7148 sealed class RemoveDelegateMethod: AEventPropertyAccessor
7150 public RemoveDelegateMethod (Event method, Accessor accessor):
7151 base (method, accessor, "remove_")
7155 protected override MethodInfo DelegateMethodInfo {
7157 return TypeManager.delegate_remove_delegate_delegate;
7163 static readonly string[] attribute_targets = new string [] { "event" }; // "property" target was disabled for 2.0 version
7165 public EventProperty (DeclSpace parent, Expression type, int mod_flags,
7166 bool is_iface, MemberName name,
7167 Attributes attrs, Accessor add, Accessor remove)
7168 : base (parent, type, mod_flags, is_iface, name, attrs)
7170 Add = new AddDelegateMethod (this, add);
7171 Remove = new RemoveDelegateMethod (this, remove);
7174 public override bool Define()
7176 if (!base.Define ())
7185 public override string[] ValidAttributeTargets {
7187 return attribute_targets;
7193 /// Event is declared like field.
7195 public class EventField : Event {
7196 abstract class EventFieldAccessor : AEventAccessor
7198 protected EventFieldAccessor (Event method, string prefix)
7199 : base (method, prefix)
7203 protected override void EmitMethod(DeclSpace parent)
7205 if ((method.ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
7208 MethodBuilder mb = method_data.MethodBuilder;
7209 ILGenerator ig = mb.GetILGenerator ();
7211 // TODO: because we cannot use generics yet
7212 FieldInfo field_info = ((EventField)method).FieldBuilder;
7214 mb.SetImplementationFlags (mb.GetMethodImplementationFlags () | MethodImplAttributes.Synchronized);
7215 if ((method.ModFlags & Modifiers.STATIC) != 0) {
7216 ig.Emit (OpCodes.Ldsfld, field_info);
7217 ig.Emit (OpCodes.Ldarg_0);
7218 ig.Emit (OpCodes.Call, DelegateMethodInfo);
7219 ig.Emit (OpCodes.Castclass, method.MemberType);
7220 ig.Emit (OpCodes.Stsfld, field_info);
7222 ig.Emit (OpCodes.Ldarg_0);
7223 ig.Emit (OpCodes.Ldarg_0);
7224 ig.Emit (OpCodes.Ldfld, field_info);
7225 ig.Emit (OpCodes.Ldarg_1);
7226 ig.Emit (OpCodes.Call, DelegateMethodInfo);
7227 ig.Emit (OpCodes.Castclass, method.MemberType);
7228 ig.Emit (OpCodes.Stfld, field_info);
7230 ig.Emit (OpCodes.Ret);
7234 sealed class AddDelegateMethod: EventFieldAccessor
7236 public AddDelegateMethod (Event method):
7237 base (method, "add_")
7241 protected override MethodInfo DelegateMethodInfo {
7243 return TypeManager.delegate_combine_delegate_delegate;
7248 sealed class RemoveDelegateMethod: EventFieldAccessor
7250 public RemoveDelegateMethod (Event method):
7251 base (method, "remove_")
7255 protected override MethodInfo DelegateMethodInfo {
7257 return TypeManager.delegate_remove_delegate_delegate;
7263 static readonly string[] attribute_targets = new string [] { "event", "field", "method" };
7264 static readonly string[] attribute_targets_interface = new string[] { "event", "method" };
7266 public FieldBuilder FieldBuilder;
7267 public Expression Initializer;
7269 public EventField (DeclSpace parent, Expression type, int mod_flags,
7270 bool is_iface, MemberName name,
7272 : base (parent, type, mod_flags, is_iface, name, attrs)
7274 Add = new AddDelegateMethod (this);
7275 Remove = new RemoveDelegateMethod (this);
7278 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
7280 if (a.Target == AttributeTargets.Field) {
7281 FieldBuilder.SetCustomAttribute (cb);
7285 if (a.Target == AttributeTargets.Method) {
7286 int errors = Report.Errors;
7287 Add.ApplyAttributeBuilder (a, cb);
7288 if (errors == Report.Errors)
7289 Remove.ApplyAttributeBuilder (a, cb);
7293 base.ApplyAttributeBuilder (a, cb);
7296 public override bool Define()
7298 if (!base.Define ())
7304 // FIXME: We are unable to detect whether generic event is used because
7305 // we are using FieldExpr instead of EventExpr for event access in that
7306 // case. When this issue will be fixed this hack can be removed.
7307 if (TypeManager.IsGenericType (MemberType))
7310 FieldBuilder = Parent.TypeBuilder.DefineField (
7312 FieldAttributes.Private | ((ModFlags & Modifiers.STATIC) != 0 ? FieldAttributes.Static : 0));
7313 TypeManager.RegisterEventField (EventBuilder, this);
7315 if (Initializer != null) {
7316 if (((ModFlags & Modifiers.ABSTRACT) != 0)) {
7317 Report.Error (74, Location, "`{0}': abstract event cannot have an initializer",
7318 GetSignatureForError ());
7322 Parent.PartialContainer.RegisterFieldForInitialization (this,
7323 new FieldInitializer (FieldBuilder, Initializer, Parent));
7329 public override string[] ValidAttributeTargets
7332 return IsInterface ? attribute_targets_interface : attribute_targets;
7337 public abstract class Event : PropertyBasedMember {
7338 public abstract class AEventAccessor : AbstractPropertyEventMethod
7340 protected readonly Event method;
7341 ImplicitParameter param_attr;
7343 static readonly string[] attribute_targets = new string [] { "method", "param", "return" };
7345 protected AEventAccessor (Event method, string prefix)
7346 : base (method, prefix)
7348 this.method = method;
7351 protected AEventAccessor (Event method, Accessor accessor, string prefix)
7352 : base (method, accessor, prefix)
7354 this.method = method;
7357 public override Iterator Iterator {
7358 get { return null; }
7361 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
7363 if (a.IsInternalMethodImplAttribute) {
7364 method.is_external_implementation = true;
7367 base.ApplyAttributeBuilder (a, cb);
7370 protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
7372 if (a.Target == AttributeTargets.Parameter) {
7373 if (param_attr == null)
7374 param_attr = new ImplicitParameter (method_data.MethodBuilder);
7376 param_attr.ApplyAttributeBuilder (a, cb);
7380 base.ApplyAttributeBuilder (a, cb);
7383 public override AttributeTargets AttributeTargets {
7385 return AttributeTargets.Method;
7389 public override bool IsClsComplianceRequired ()
7391 return method.IsClsComplianceRequired ();
7394 public virtual MethodBuilder Define (DeclSpace parent)
7396 method_data = new MethodData (method, method.ModFlags,
7397 method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this);
7399 if (!method_data.Define (parent))
7402 MethodBuilder mb = method_data.MethodBuilder;
7403 ParameterInfo.ApplyAttributes (mb);
7407 protected abstract MethodInfo DelegateMethodInfo { get; }
7409 public override Type ReturnType {
7411 return TypeManager.void_type;
7415 public override EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig)
7417 return new EmitContext (
7418 ds, method.Parent, Location, ig, ReturnType,
7419 method.ModFlags, false);
7422 public override ObsoleteAttribute GetObsoleteAttribute ()
7424 return method.GetObsoleteAttribute ();
7427 public override string[] ValidAttributeTargets {
7429 return attribute_targets;
7433 public override Parameters ParameterInfo {
7435 return method.parameters;
7441 const int AllowedModifiers =
7444 Modifiers.PROTECTED |
7445 Modifiers.INTERNAL |
7450 Modifiers.OVERRIDE |
7452 Modifiers.ABSTRACT |
7455 const int AllowedInterfaceModifiers =
7458 public AEventAccessor Add, Remove;
7459 public MyEventBuilder EventBuilder;
7460 public MethodBuilder AddBuilder, RemoveBuilder;
7462 Parameters parameters;
7464 protected Event (DeclSpace parent, Expression type, int mod_flags,
7465 bool is_iface, MemberName name, Attributes attrs)
7466 : base (parent, null, type, mod_flags,
7467 is_iface ? AllowedInterfaceModifiers : AllowedModifiers, is_iface,
7472 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
7474 if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
7475 a.Error_InvalidSecurityParent ();
7479 EventBuilder.SetCustomAttribute (cb);
7482 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
7484 return Add.IsDuplicateImplementation (mc) || Remove.IsDuplicateImplementation (mc);
7487 public override AttributeTargets AttributeTargets {
7489 return AttributeTargets.Event;
7493 public override bool Define ()
7495 if (!DoDefineBase ())
7501 if (!TypeManager.IsDelegateType (MemberType)) {
7502 Report.Error (66, Location, "`{0}': event must be of a delegate type", GetSignatureForError ());
7506 parameters = new Parameters (
7507 new Parameter[] { new Parameter (MemberType, "value", Parameter.Modifier.NONE, null, Location) },
7508 new Type[] { MemberType } );
7514 // Now define the accessors
7517 AddBuilder = Add.Define (Parent);
7518 if (AddBuilder == null)
7521 RemoveBuilder = Remove.Define (Parent);
7522 if (RemoveBuilder == null)
7525 EventBuilder = new MyEventBuilder (this, Parent.TypeBuilder, Name, EventAttributes.None, MemberType);
7526 EventBuilder.SetAddOnMethod (AddBuilder);
7527 EventBuilder.SetRemoveOnMethod (RemoveBuilder);
7531 public override void Emit ()
7533 if (OptAttributes != null) {
7534 OptAttributes.Emit ();
7538 Remove.Emit (Parent);
7543 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
7545 MethodInfo mi = (MethodInfo) Parent.PartialContainer.BaseCache.FindBaseEvent (
7546 Parent.TypeBuilder, Name);
7551 ParameterData pd = TypeManager.GetParameterData (mi);
7552 base_ret_type = pd.ParameterType (0);
7557 // Represents header string for documentation comment.
7559 public override string DocCommentHeader {
7560 get { return "E:"; }
7565 public class Indexer : PropertyBase {
7567 class GetIndexerMethod : GetMethod
7569 public GetIndexerMethod (PropertyBase method):
7574 public GetIndexerMethod (PropertyBase method, Accessor accessor):
7575 base (method, accessor)
7579 public override Parameters ParameterInfo {
7581 return ((Indexer)method).parameters;
7586 class SetIndexerMethod: SetMethod
7588 public SetIndexerMethod (PropertyBase method):
7593 public SetIndexerMethod (PropertyBase method, Accessor accessor):
7594 base (method, accessor)
7598 protected override void DefineParameters ()
7600 parameters = Parameters.MergeGenerated (((Indexer)method).parameters,
7601 new Parameter (method.MemberType, "value", Parameter.Modifier.NONE, null, method.Location));
7605 const int AllowedModifiers =
7608 Modifiers.PROTECTED |
7609 Modifiers.INTERNAL |
7613 Modifiers.OVERRIDE |
7618 const int AllowedInterfaceModifiers =
7621 public readonly Parameters parameters;
7623 public Indexer (DeclSpace parent, Expression type, MemberName name, int mod,
7624 bool is_iface, Parameters parameters, Attributes attrs,
7625 Accessor get_block, Accessor set_block, bool define_set_first)
7626 : base (parent, type, mod,
7627 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
7628 is_iface, name, attrs, define_set_first)
7630 this.parameters = parameters;
7632 if (get_block == null)
7633 Get = new GetIndexerMethod (this);
7635 Get = new GetIndexerMethod (this, get_block);
7637 if (set_block == null)
7638 Set = new SetIndexerMethod (this);
7640 Set = new SetIndexerMethod (this, set_block);
7643 protected override bool CheckForDuplications ()
7645 ArrayList ar = Parent.PartialContainer.Indexers;
7647 int arLen = ar.Count;
7649 for (int i = 0; i < arLen; i++) {
7650 Indexer m = (Indexer) ar [i];
7651 if (IsDuplicateImplementation (m))
7659 bool IsDuplicateImplementation (Indexer indexer)
7661 if (this == indexer)
7664 if (!MemberName.Equals (indexer.MemberName))
7667 Type[] param_types = indexer.parameters.Types;
7669 // When it is not yet defined
7670 if (param_types == null)
7673 if (param_types.Length != parameters.Count)
7676 for (int i = 0; i < param_types.Length; i++)
7677 if (param_types [i] != parameters.Types [i])
7680 Report.SymbolRelatedToPreviousError (indexer);
7681 Report.Error (111, Location, TypeContainer.Error111, indexer.GetSignatureForError ());
7686 public override bool Define ()
7688 if (!DoDefineBase ())
7691 if (!base.Define ())
7694 if (!DefineParameters (parameters))
7697 if (MemberType == TypeManager.void_type) {
7698 Report.Error (620, Location, "Indexers cannot have void type");
7702 if (OptAttributes != null) {
7703 Attribute indexer_attr = OptAttributes.Search (TypeManager.indexer_name_type);
7704 if (indexer_attr != null) {
7705 // Remove the attribute from the list because it is not emitted
7706 OptAttributes.Attrs.Remove (indexer_attr);
7708 string name = indexer_attr.GetIndexerAttributeValue ();
7714 if (IsExplicitImpl) {
7715 Report.Error (415, indexer_attr.Location,
7716 "The `IndexerName' attribute is valid only on an " +
7717 "indexer that is not an explicit interface member declaration");
7721 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
7722 Report.Error (609, indexer_attr.Location,
7723 "Cannot set the `IndexerName' attribute on an indexer marked override");
7729 if (InterfaceType != null) {
7730 string base_IndexerName = TypeManager.IndexerPropertyName (InterfaceType);
7731 if (base_IndexerName != Name)
7732 ShortName = base_IndexerName;
7735 if (!Parent.PartialContainer.AddMember (this) ||
7736 !Parent.PartialContainer.AddMember (Get) || !Parent.PartialContainer.AddMember (Set))
7742 flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
7744 if (!DefineAccessors ())
7748 // Setup iterator if we are one
7749 if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
7750 Iterator iterator = Iterator.CreateIterator (Get, Parent, null, ModFlags);
7751 if (iterator == null)
7757 // Now name the parameters
7759 Parameter [] p = parameters.FixedParameters;
7761 // TODO: should be done in parser and it needs to do cycle
7762 if ((p [0].ModFlags & Parameter.Modifier.ISBYREF) != 0) {
7763 CSharpParser.Error_ParameterModifierNotValid (Location);
7768 PropertyBuilder = Parent.TypeBuilder.DefineProperty (
7769 Name, PropertyAttributes.None, MemberType, parameters.Types);
7772 PropertyBuilder.SetGetMethod (GetBuilder);
7775 PropertyBuilder.SetSetMethod (SetBuilder);
7777 TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder, parameters.Types);
7782 public override string GetDocCommentName (DeclSpace ds)
7784 return DocUtil.GetMethodDocCommentName (this, parameters, ds);
7787 public override string GetSignatureForError ()
7789 StringBuilder sb = new StringBuilder (Parent.GetSignatureForError ());
7790 if (MemberName.Left != null) {
7792 sb.Append (MemberName.Left);
7795 sb.Append (".this");
7796 sb.Append (parameters.GetSignatureForError ().Replace ('(', '[').Replace (')', ']'));
7797 return sb.ToString ();
7800 public override bool MarkForDuplicationCheck ()
7802 caching_flags |= Flags.TestMethodDuplication;
7806 protected override PropertyInfo ResolveBaseProperty ()
7808 return Parent.PartialContainer.BaseCache.FindMemberToOverride (
7809 Parent.TypeBuilder, Name, parameters.Types, null, true) as PropertyInfo;
7812 protected override bool VerifyClsCompliance ()
7814 if (!base.VerifyClsCompliance ())
7817 parameters.VerifyClsCompliance ();
7822 public class Operator : MethodOrOperator, IAnonymousHost {
7824 const int AllowedModifiers =
7830 public enum OpType : byte {
7840 // Unary and Binary operators
7863 // Implicit and Explicit
7867 // Just because of enum
7871 public readonly OpType OperatorType;
7873 public Operator (DeclSpace parent, OpType type, Expression ret_type,
7874 int mod_flags, Parameters parameters,
7875 ToplevelBlock block, Attributes attrs, Location loc)
7876 : base (parent, null, ret_type, mod_flags, AllowedModifiers, false,
7877 new MemberName ("op_" + type.ToString(), loc), attrs, parameters)
7879 OperatorType = type;
7883 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
7885 if (a.Type == TypeManager.conditional_attribute_type) {
7886 Error_ConditionalAttributeIsNotValid ();
7890 base.ApplyAttributeBuilder (a, cb);
7893 protected override bool CheckForDuplications ()
7895 ArrayList ar = Parent.PartialContainer.Operators;
7897 int arLen = ar.Count;
7899 for (int i = 0; i < arLen; i++) {
7900 Operator o = (Operator) ar [i];
7901 if (IsDuplicateImplementation (o))
7906 ar = Parent.PartialContainer.Methods;
7908 int arLen = ar.Count;
7910 for (int i = 0; i < arLen; i++) {
7911 Method m = (Method) ar [i];
7912 if (IsDuplicateImplementation (m))
7920 public override bool Define ()
7922 const int RequiredModifiers = Modifiers.PUBLIC | Modifiers.STATIC;
7923 if ((ModFlags & RequiredModifiers) != RequiredModifiers){
7924 Report.Error (558, Location, "User-defined operator `{0}' must be declared static and public", GetSignatureForError ());
7928 // imlicit and explicit operator of same types are not allowed
7929 if (OperatorType == OpType.Explicit || OperatorType == OpType.Implicit)
7930 MarkForDuplicationCheck ();
7932 if (!base.Define ())
7935 if (MemberType == TypeManager.void_type) {
7936 Report.Error (590, Location, "User-defined operators cannot return void");
7940 Type declaring_type = MethodData.DeclaringType;
7941 Type return_type = MemberType;
7942 Type first_arg_type = ParameterTypes [0];
7944 // Rules for conversion operators
7946 if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
7947 if (first_arg_type == return_type && first_arg_type == declaring_type){
7948 Report.Error (555, Location,
7949 "User-defined operator cannot take an object of the enclosing type and convert to an object of the enclosing type");
7953 if ((first_arg_type != declaring_type) && (return_type != declaring_type) &&
7954 !TypeManager.IsNullableTypeOf (first_arg_type, declaring_type) &&
7955 !TypeManager.IsNullableTypeOf (return_type, declaring_type)) {
7958 "User-defined conversion must convert to or from the " +
7963 if (first_arg_type.IsInterface || return_type.IsInterface){
7964 Report.Error (552, Location, "User-defined conversion `{0}' cannot convert to or from an interface type",
7965 GetSignatureForError ());
7969 if (first_arg_type.IsSubclassOf (return_type) || return_type.IsSubclassOf (first_arg_type)) {
7970 if (declaring_type.IsSubclassOf (return_type) || declaring_type.IsSubclassOf (first_arg_type)) {
7971 Report.Error (553, Location, "User-defined conversion `{0}' cannot convert to or from base class",
7972 GetSignatureForError ());
7975 Report.Error (554, Location, "User-defined conversion `{0}' cannot convert to or from derived class",
7976 GetSignatureForError ());
7979 } else if (OperatorType == OpType.LeftShift || OperatorType == OpType.RightShift) {
7980 if (first_arg_type != declaring_type || ParameterTypes [1] != TypeManager.int32_type) {
7981 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");
7984 } else if (Parameters.Count == 1) {
7985 // Checks for Unary operators
7987 if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
7988 if (return_type != declaring_type && !TypeManager.IsSubclassOf (return_type, declaring_type)) {
7989 Report.Error (448, Location,
7990 "The return type for ++ or -- operator must be the containing type or derived from the containing type");
7993 if (first_arg_type != declaring_type) {
7995 559, Location, "The parameter type for ++ or -- operator must be the containing type");
8000 if (first_arg_type != declaring_type){
8003 "The parameter of a unary operator must be the " +
8008 if (OperatorType == OpType.True || OperatorType == OpType.False) {
8009 if (return_type != TypeManager.bool_type){
8012 "The return type of operator True or False " +
8019 // Checks for Binary operators
8021 if (first_arg_type != declaring_type &&
8022 ParameterTypes [1] != declaring_type){
8025 "One of the parameters of a binary operator must " +
8026 "be the containing type");
8034 protected override bool DoDefine ()
8036 if (!base.DoDefine ())
8039 flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
8043 public override void Emit ()
8047 Parameters.ApplyAttributes (MethodBuilder);
8050 // abstract or extern methods have no bodies
8052 if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
8056 if ((flags & MethodAttributes.PinvokeImpl) == 0)
8057 ec = CreateEmitContext (Parent, MethodBuilder.GetILGenerator ());
8059 ec = CreateEmitContext (Parent, null);
8061 SourceMethod source = SourceMethod.Create (Parent, MethodBuilder, Block);
8062 ec.EmitTopBlock (this, Block);
8065 source.CloseMethod ();
8070 // Operator cannot be override
8071 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
8076 public static string GetName (OpType ot)
8079 case OpType.LogicalNot:
8081 case OpType.OnesComplement:
8083 case OpType.Increment:
8085 case OpType.Decrement:
8091 case OpType.Addition:
8093 case OpType.Subtraction:
8095 case OpType.UnaryPlus:
8097 case OpType.UnaryNegation:
8099 case OpType.Multiply:
8101 case OpType.Division:
8103 case OpType.Modulus:
8105 case OpType.BitwiseAnd:
8107 case OpType.BitwiseOr:
8109 case OpType.ExclusiveOr:
8111 case OpType.LeftShift:
8113 case OpType.RightShift:
8115 case OpType.Equality:
8117 case OpType.Inequality:
8119 case OpType.GreaterThan:
8121 case OpType.LessThan:
8123 case OpType.GreaterThanOrEqual:
8125 case OpType.LessThanOrEqual:
8127 case OpType.Implicit:
8129 case OpType.Explicit:
8135 public static OpType GetOperatorType (string name)
8137 if (name.StartsWith ("op_")){
8138 for (int i = 0; i < Unary.oper_names.Length; ++i) {
8139 if (Unary.oper_names [i] == name)
8143 for (int i = 0; i < Binary.oper_names.Length; ++i) {
8144 if (Binary.oper_names [i] == name)
8151 public override string GetSignatureForError ()
8153 StringBuilder sb = new StringBuilder ();
8154 if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
8155 sb.AppendFormat ("{0}.{1} operator {2}", Parent.GetSignatureForError (), GetName (OperatorType), Type.Type == null ? Type.ToString () : TypeManager.CSharpName (Type.Type));
8158 sb.AppendFormat ("{0}.operator {1}", Parent.GetSignatureForError (), GetName (OperatorType));
8161 sb.Append (Parameters.GetSignatureForError ());
8162 return sb.ToString ();
8167 // This is used to compare method signatures
8169 struct MethodSignature {
8171 public Type RetType;
8172 public Type [] Parameters;
8175 /// This delegate is used to extract methods which have the
8176 /// same signature as the argument
8178 public static MemberFilter method_signature_filter = new MemberFilter (MemberSignatureCompare);
8180 public MethodSignature (string name, Type ret_type, Type [] parameters)
8185 if (parameters == null)
8186 Parameters = Type.EmptyTypes;
8188 Parameters = parameters;
8191 public override string ToString ()
8194 if (Parameters.Length != 0){
8195 System.Text.StringBuilder sb = new System.Text.StringBuilder ();
8196 for (int i = 0; i < Parameters.Length; i++){
8197 sb.Append (Parameters [i]);
8198 if (i+1 < Parameters.Length)
8201 pars = sb.ToString ();
8204 return String.Format ("{0} {1} ({2})", RetType, Name, pars);
8207 public override int GetHashCode ()
8209 return Name.GetHashCode ();
8212 public override bool Equals (Object o)
8214 MethodSignature other = (MethodSignature) o;
8216 if (other.Name != Name)
8219 if (other.RetType != RetType)
8222 if (Parameters == null){
8223 if (other.Parameters == null)
8228 if (other.Parameters == null)
8231 int c = Parameters.Length;
8232 if (other.Parameters.Length != c)
8235 for (int i = 0; i < c; i++)
8236 if (other.Parameters [i] != Parameters [i])
8242 static bool MemberSignatureCompare (MemberInfo m, object filter_criteria)
8244 MethodSignature sig = (MethodSignature) filter_criteria;
8246 if (m.Name != sig.Name)
8250 MethodInfo mi = m as MethodInfo;
8251 PropertyInfo pi = m as PropertyInfo;
8254 ReturnType = mi.ReturnType;
8255 else if (pi != null)
8256 ReturnType = pi.PropertyType;
8261 // we use sig.RetType == null to mean `do not check the
8262 // method return value.
8264 if (sig.RetType != null)
8265 if (ReturnType != sig.RetType)
8270 args = TypeManager.GetParameterData (mi).Types;
8272 args = TypeManager.GetArgumentTypes (pi);
8273 Type [] sigp = sig.Parameters;
8275 if (args.Length != sigp.Length)
8278 for (int i = args.Length; i > 0; ){
8280 if (args [i] != sigp [i])