Handle ENETDOWN error if defined.
[mono.git] / mcs / mcs / field.cs
1 //
2 // field.cs: All field handlers
3 //
4 // Authors: Miguel de Icaza (miguel@gnu.org)
5 //          Martin Baulig (martin@ximian.com)
6 //          Marek Safar (marek.safar@seznam.cz)
7 //
8 // Dual licensed under the terms of the MIT X11 or GNU GPL
9 //
10 // Copyright 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
11 // Copyright 2004-2008 Novell, Inc
12 // Copyright 2011 Xamarin Inc
13 //
14
15 using System;
16 using System.Collections.Generic;
17 using System.Runtime.InteropServices;
18
19 #if STATIC
20 using MetaType = IKVM.Reflection.Type;
21 using IKVM.Reflection;
22 using IKVM.Reflection.Emit;
23 #else
24 using MetaType = System.Type;
25 using System.Reflection;
26 using System.Reflection.Emit;
27 #endif
28
29 namespace Mono.CSharp
30 {
31         public class FieldDeclarator
32         {
33                 public FieldDeclarator (SimpleMemberName name, Expression initializer)
34                 {
35                         this.Name = name;
36                         this.Initializer = initializer;
37                 }
38
39                 #region Properties
40
41                 public SimpleMemberName Name { get; private set; }
42                 public Expression Initializer { get; private set; }
43
44                 #endregion
45         }
46
47         //
48         // Abstract class for all fields
49         //
50         abstract public class FieldBase : MemberBase
51         {
52                 protected FieldBuilder FieldBuilder;
53                 protected FieldSpec spec;
54                 public Status status;
55                 protected Expression initializer;
56                 protected List<FieldDeclarator> declarators;
57
58                 [Flags]
59                 public enum Status : byte {
60                         HAS_OFFSET = 4          // Used by FieldMember.
61                 }
62
63                 static readonly string[] attribute_targets = new string [] { "field" };
64
65                 protected FieldBase (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, MemberName name, Attributes attrs)
66                         : base (parent, type, mod, allowed_mod | Modifiers.ABSTRACT, Modifiers.PRIVATE, name, attrs)
67                 {
68                         if ((mod & Modifiers.ABSTRACT) != 0)
69                                 Report.Error (681, Location, "The modifier 'abstract' is not valid on fields. Try using a property instead");
70                 }
71
72                 #region Properties
73
74                 public override AttributeTargets AttributeTargets {
75                         get {
76                                 return AttributeTargets.Field;
77                         }
78                 }
79
80                 public List<FieldDeclarator> Declarators {
81                         get {
82                                 return this.declarators;
83                         }
84                 }
85
86                 public Expression Initializer {
87                         get {
88                                 return initializer;
89                         }
90                         set {
91                                 this.initializer = value;
92                         }
93                 }
94
95                 public string Name {
96                         get {
97                                 return MemberName.Name;
98                         }
99                 }
100
101                 public FieldSpec Spec {
102                         get {
103                                 return spec;
104                         }
105                 }
106
107                 public override string[] ValidAttributeTargets  {
108                         get {
109                                 return attribute_targets;
110                         }
111                 }
112
113                 #endregion
114
115                 public void AddDeclarator (FieldDeclarator declarator)
116                 {
117                         if (declarators == null)
118                                 declarators = new List<FieldDeclarator> (2);
119
120                         declarators.Add (declarator);
121
122                         Parent.AddNameToContainer (this, declarator.Name.Value);
123                 }
124
125                 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
126                 {
127                         if (a.Type == pa.FieldOffset) {
128                                 status |= Status.HAS_OFFSET;
129
130                                 if (!Parent.PartialContainer.HasExplicitLayout) {
131                                         Report.Error (636, Location, "The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit)");
132                                         return;
133                                 }
134
135                                 if ((ModFlags & Modifiers.STATIC) != 0 || this is Const) {
136                                         Report.Error (637, Location, "The FieldOffset attribute is not allowed on static or const fields");
137                                         return;
138                                 }
139                         }
140
141                         if (a.Type == pa.FixedBuffer) {
142                                 Report.Error (1716, Location, "Do not use 'System.Runtime.CompilerServices.FixedBuffer' attribute. Use the 'fixed' field modifier instead");
143                                 return;
144                         }
145
146 #if false
147                         if (a.Type == pa.MarshalAs) {
148                                 UnmanagedMarshal marshal = a.GetMarshal (this);
149                                 if (marshal != null) {
150                                         FieldBuilder.SetMarshal (marshal);
151                                 }
152                                 return;
153                         }
154 #endif
155                         if ((a.HasSecurityAttribute)) {
156                                 a.Error_InvalidSecurityParent ();
157                                 return;
158                         }
159
160                         if (a.Type == pa.Dynamic) {
161                                 a.Error_MisusedDynamicAttribute ();
162                                 return;
163                         }
164
165                         FieldBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
166                 }
167
168                 public void SetCustomAttribute (MethodSpec ctor, byte[] data)
169                 {
170                         FieldBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), data);
171                 }
172
173                 protected override bool CheckBase ()
174                 {
175                         if (!base.CheckBase ())
176                                 return false;
177
178                         MemberSpec candidate;
179                         bool overrides = false;
180                         var conflict_symbol = MemberCache.FindBaseMember (this, out candidate, ref overrides);
181                         if (conflict_symbol == null)
182                                 conflict_symbol = candidate;
183
184                         if (conflict_symbol == null) {
185                                 if ((ModFlags & Modifiers.NEW) != 0) {
186                                         Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required",
187                                                 GetSignatureForError ());
188                                 }
189                         } else {
190                                 if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE | Modifiers.BACKING_FIELD)) == 0) {
191                                         Report.SymbolRelatedToPreviousError (conflict_symbol);
192                                         Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
193                                                 GetSignatureForError (), conflict_symbol.GetSignatureForError ());
194                                 }
195
196                                 if (conflict_symbol.IsAbstract) {
197                                         Report.SymbolRelatedToPreviousError (conflict_symbol);
198                                         Report.Error (533, Location, "`{0}' hides inherited abstract member `{1}'",
199                                                 GetSignatureForError (), conflict_symbol.GetSignatureForError ());
200                                 }
201                         }
202  
203                         return true;
204                 }
205
206                 public virtual Constant ConvertInitializer (ResolveContext rc, Constant expr)
207                 {
208                         return expr.ConvertImplicitly (MemberType);
209                 }
210
211                 protected override void DoMemberTypeDependentChecks ()
212                 {
213                         base.DoMemberTypeDependentChecks ();
214
215                         if (MemberType.IsGenericParameter)
216                                 return;
217
218                         if (MemberType.IsStatic)
219                                 Error_VariableOfStaticClass (Location, GetSignatureForError (), MemberType, Report);
220
221                         CheckBase ();
222                         IsTypePermitted ();
223                 }
224
225                 //
226                 //   Represents header string for documentation comment.
227                 //
228                 public override string DocCommentHeader {
229                         get { return "F:"; }
230                 }
231
232                 public override void Emit ()
233                 {
234                         if (member_type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
235                                 Module.PredefinedAttributes.Dynamic.EmitAttribute (FieldBuilder);
236                         } else if (!Parent.IsCompilerGenerated && member_type.HasDynamicElement) {
237                                 Module.PredefinedAttributes.Dynamic.EmitAttribute (FieldBuilder, member_type, Location);
238                         }
239
240                         if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated)
241                                 Module.PredefinedAttributes.CompilerGenerated.EmitAttribute (FieldBuilder);
242                         if ((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0)
243                                 Module.PredefinedAttributes.DebuggerBrowsable.EmitAttribute (FieldBuilder, System.Diagnostics.DebuggerBrowsableState.Never);
244
245                         if (OptAttributes != null) {
246                                 OptAttributes.Emit ();
247                         }
248
249                         if (((status & Status.HAS_OFFSET) == 0) && (ModFlags & (Modifiers.STATIC | Modifiers.BACKING_FIELD)) == 0 && Parent.PartialContainer.HasExplicitLayout) {
250                                 Report.Error (625, Location, "`{0}': Instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute", GetSignatureForError ());
251                         }
252
253                         ConstraintChecker.Check (this, member_type, type_expr.Location);
254
255                         base.Emit ();
256                 }
257
258                 public static void Error_VariableOfStaticClass (Location loc, string variable_name, TypeSpec static_class, Report Report)
259                 {
260                         Report.SymbolRelatedToPreviousError (static_class);
261                         Report.Error (723, loc, "`{0}': cannot declare variables of static types",
262                                 variable_name);
263                 }
264
265                 protected override bool VerifyClsCompliance ()
266                 {
267                         if (!base.VerifyClsCompliance ())
268                                 return false;
269
270                         if (!MemberType.IsCLSCompliant () || this is FixedField) {
271                                 Report.Warning (3003, 1, Location, "Type of `{0}' is not CLS-compliant",
272                                         GetSignatureForError ());
273                         }
274                         return true;
275                 }
276         }
277
278         //
279         // Field specification
280         //
281         public class FieldSpec : MemberSpec, IInterfaceMemberSpec
282         {
283                 FieldInfo metaInfo;
284                 TypeSpec memberType;
285
286                 public FieldSpec (TypeSpec declaringType, IMemberDefinition definition, TypeSpec memberType, FieldInfo info, Modifiers modifiers)
287                         : base (MemberKind.Field, declaringType, definition, modifiers)
288                 {
289                         this.metaInfo = info;
290                         this.memberType = memberType;
291                 }
292
293                 #region Properties
294
295                 public bool IsReadOnly {
296                         get {
297                                 return (Modifiers & Modifiers.READONLY) != 0;
298                         }
299                 }
300
301                 public TypeSpec MemberType {
302                         get {
303                                 return memberType;
304                         }
305                 }
306
307 #endregion
308
309                 public FieldInfo GetMetaInfo ()
310                 {
311                         if ((state & StateFlags.PendingMetaInflate) != 0) {
312                                 var decl_meta = DeclaringType.GetMetaInfo ();
313                                 if (DeclaringType.IsTypeBuilder) {
314                                         metaInfo = TypeBuilder.GetField (decl_meta, metaInfo);
315                                 } else {
316                                         var orig_token = metaInfo.MetadataToken;
317                                         metaInfo = decl_meta.GetField (Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
318                                         if (metaInfo.MetadataToken != orig_token)
319                                                 throw new NotImplementedException ("Resolved to wrong meta token");
320
321                                         // What a stupid API, does not work because field handle is imported
322                                         // metaInfo = FieldInfo.GetFieldFromHandle (metaInfo.FieldHandle, DeclaringType.MetaInfo.TypeHandle);
323                                 }
324
325                                 state &= ~StateFlags.PendingMetaInflate;
326                         }
327
328                         return metaInfo;
329                 }
330
331                 public override MemberSpec InflateMember (TypeParameterInflator inflator)
332                 {
333                         var fs = (FieldSpec) base.InflateMember (inflator);
334                         fs.memberType = inflator.Inflate (memberType);
335                         return fs;
336                 }
337
338                 public FieldSpec Mutate (TypeParameterMutator mutator)
339                 {
340                         var decl = DeclaringType;
341                         if (DeclaringType.IsGenericOrParentIsGeneric)
342                                 decl = mutator.Mutate (decl);
343
344                         if (decl == DeclaringType)
345                                 return this;
346
347                         var fs = (FieldSpec) MemberwiseClone ();
348                         fs.declaringType = decl;
349                         fs.state |= StateFlags.PendingMetaInflate;
350
351                         // Gets back FieldInfo in case of metaInfo was inflated
352                         fs.metaInfo = MemberCache.GetMember (TypeParameterMutator.GetMemberDeclaringType (DeclaringType), this).metaInfo;
353                         return fs;
354                 }
355
356                 public override List<TypeSpec> ResolveMissingDependencies ()
357                 {
358                         return memberType.ResolveMissingDependencies ();
359                 }
360         }
361
362         /// <summary>
363         /// Fixed buffer implementation
364         /// </summary>
365         public class FixedField : FieldBase
366         {
367                 public const string FixedElementName = "FixedElementField";
368                 static int GlobalCounter = 0;
369
370                 TypeBuilder fixed_buffer_type;
371
372                 const Modifiers AllowedModifiers =
373                         Modifiers.NEW |
374                         Modifiers.PUBLIC |
375                         Modifiers.PROTECTED |
376                         Modifiers.INTERNAL |
377                         Modifiers.PRIVATE |
378                         Modifiers.UNSAFE;
379
380                 public FixedField (TypeDefinition parent, FullNamedExpression type, Modifiers mod, MemberName name, Attributes attrs)
381                         : base (parent, type, mod, AllowedModifiers, name, attrs)
382                 {
383                 }
384
385                 #region Properties
386
387                 //
388                 // Explicit struct layout set by parent
389                 //
390                 public CharSet? CharSet {
391                         get; set;
392                 }               
393
394                 #endregion
395
396                 public override Constant ConvertInitializer (ResolveContext rc, Constant expr)
397                 {
398                         return expr.ImplicitConversionRequired (rc, rc.BuiltinTypes.Int, Location);
399                 }
400
401                 public override bool Define ()
402                 {
403                         if (!base.Define ())
404                                 return false;
405
406                         if (!BuiltinTypeSpec.IsPrimitiveType (MemberType)) {
407                                 Report.Error (1663, Location,
408                                         "`{0}': Fixed size buffers type must be one of the following: bool, byte, short, int, long, char, sbyte, ushort, uint, ulong, float or double",
409                                         GetSignatureForError ());
410                         } else if (declarators != null) {
411                                 var t = new TypeExpression (MemberType, TypeExpression.Location);
412                                 foreach (var d in declarators) {
413                                         var f = new FixedField (Parent, t, ModFlags, new MemberName (d.Name.Value, d.Name.Location), OptAttributes);
414                                         f.initializer = d.Initializer;
415                                         ((ConstInitializer) f.initializer).Name = d.Name.Value;
416                                         f.Define ();
417                                         Parent.PartialContainer.Members.Add (f);
418                                 }
419                         }
420                         
421                         // Create nested fixed buffer container
422                         string name = String.Format ("<{0}>__FixedBuffer{1}", Name, GlobalCounter++);
423                         fixed_buffer_type = Parent.TypeBuilder.DefineNestedType (name,
424                                 TypeAttributes.NestedPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit,
425                                 Compiler.BuiltinTypes.ValueType.GetMetaInfo ());
426
427                         var ffield = fixed_buffer_type.DefineField (FixedElementName, MemberType.GetMetaInfo (), FieldAttributes.Public);
428                         
429                         FieldBuilder = Parent.TypeBuilder.DefineField (Name, fixed_buffer_type, ModifiersExtensions.FieldAttr (ModFlags));
430
431                         var element_spec = new FieldSpec (null, this, MemberType, ffield, ModFlags);
432                         spec = new FixedFieldSpec (Module, Parent.Definition, this, FieldBuilder, element_spec, ModFlags);
433
434                         Parent.MemberCache.AddMember (spec);
435                         return true;
436                 }
437
438                 protected override void DoMemberTypeIndependentChecks ()
439                 {
440                         base.DoMemberTypeIndependentChecks ();
441
442                         if (!IsUnsafe)
443                                 Expression.UnsafeError (Report, Location);
444
445                         if (Parent.PartialContainer.Kind != MemberKind.Struct) {
446                                 Report.Error (1642, Location, "`{0}': Fixed size buffer fields may only be members of structs",
447                                         GetSignatureForError ());
448                         }
449                 }
450
451                 public override void Emit()
452                 {
453                         ResolveContext rc = new ResolveContext (this);
454                         IntConstant buffer_size_const = initializer.Resolve (rc) as IntConstant;
455                         if (buffer_size_const == null)
456                                 return;
457
458                         int buffer_size = buffer_size_const.Value;
459
460                         if (buffer_size <= 0) {
461                                 Report.Error (1665, Location, "`{0}': Fixed size buffers must have a length greater than zero", GetSignatureForError ());
462                                 return;
463                         }
464
465                         EmitFieldSize (buffer_size);
466
467 #if STATIC
468                         if (Module.HasDefaultCharSet)
469                                 fixed_buffer_type.__SetAttributes (fixed_buffer_type.Attributes | Module.DefaultCharSetType);
470 #endif
471
472                         Module.PredefinedAttributes.UnsafeValueType.EmitAttribute (fixed_buffer_type);
473                         Module.PredefinedAttributes.CompilerGenerated.EmitAttribute (fixed_buffer_type);
474                         fixed_buffer_type.CreateType ();
475
476                         base.Emit ();
477                 }
478
479                 void EmitFieldSize (int buffer_size)
480                 {
481                         int type_size = BuiltinTypeSpec.GetSize (MemberType);
482
483                         if (buffer_size > int.MaxValue / type_size) {
484                                 Report.Error (1664, Location, "Fixed size buffer `{0}' of length `{1}' and type `{2}' exceeded 2^31 limit",
485                                         GetSignatureForError (), buffer_size.ToString (), MemberType.GetSignatureForError ());
486                                 return;
487                         }
488
489                         AttributeEncoder encoder;
490
491                         var ctor = Module.PredefinedMembers.StructLayoutAttributeCtor.Resolve (Location);
492                         if (ctor == null)
493                                 return;
494
495                         var field_size = Module.PredefinedMembers.StructLayoutSize.Resolve (Location);
496                         var field_charset = Module.PredefinedMembers.StructLayoutCharSet.Resolve (Location);
497                         if (field_size == null || field_charset == null)
498                                 return;
499
500                         var char_set = CharSet ?? Module.DefaultCharSet ?? 0;
501
502                         encoder = new AttributeEncoder ();
503                         encoder.Encode ((short)LayoutKind.Sequential);
504                         encoder.EncodeNamedArguments (
505                                 new [] { field_size, field_charset },
506                                 new Constant [] { 
507                                         new IntConstant (Compiler.BuiltinTypes, buffer_size * type_size, Location),
508                                         new IntConstant (Compiler.BuiltinTypes, (int) char_set, Location)
509                                 }
510                         );
511
512                         fixed_buffer_type.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ());
513
514                         //
515                         // Don't emit FixedBufferAttribute attribute for private types
516                         //
517                         if ((ModFlags & Modifiers.PRIVATE) != 0)
518                                 return;
519
520                         ctor = Module.PredefinedMembers.FixedBufferAttributeCtor.Resolve (Location);
521                         if (ctor == null)
522                                 return;
523
524                         encoder = new AttributeEncoder ();
525                         encoder.EncodeTypeName (MemberType);
526                         encoder.Encode (buffer_size);
527                         encoder.EncodeEmptyNamedArguments ();
528
529                         FieldBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ());
530                 }
531         }
532
533         class FixedFieldSpec : FieldSpec
534         {
535                 readonly FieldSpec element;
536
537                 public FixedFieldSpec (ModuleContainer module, TypeSpec declaringType, IMemberDefinition definition, FieldInfo info, FieldSpec element, Modifiers modifiers)
538                         : base (declaringType, definition, PointerContainer.MakeType (module, element.MemberType), info, modifiers)
539                 {
540                         this.element = element;
541
542                         // It's never CLS-Compliant
543                         state &= ~StateFlags.CLSCompliant_Undetected;
544                 }
545
546                 public FieldSpec Element {
547                         get {
548                                 return element;
549                         }
550                 }
551                 
552                 public TypeSpec ElementType {
553                         get {
554                                 return element.MemberType;
555                         }
556                 }
557         }
558
559         //
560         // The Field class is used to represents class/struct fields during parsing.
561         //
562         public class Field : FieldBase {
563                 // <summary>
564                 //   Modifiers allowed in a class declaration
565                 // </summary>
566                 const Modifiers AllowedModifiers =
567                         Modifiers.NEW |
568                         Modifiers.PUBLIC |
569                         Modifiers.PROTECTED |
570                         Modifiers.INTERNAL |
571                         Modifiers.PRIVATE |
572                         Modifiers.STATIC |
573                         Modifiers.VOLATILE |
574                         Modifiers.UNSAFE |
575                         Modifiers.READONLY;
576
577                 public Field (TypeDefinition parent, FullNamedExpression type, Modifiers mod, MemberName name, Attributes attrs)
578                         : base (parent, type, mod, AllowedModifiers, name, attrs)
579                 {
580                 }
581
582                 bool CanBeVolatile ()
583                 {
584                         switch (MemberType.BuiltinType) {
585                         case BuiltinTypeSpec.Type.Bool:
586                         case BuiltinTypeSpec.Type.Char:
587                         case BuiltinTypeSpec.Type.SByte:
588                         case BuiltinTypeSpec.Type.Byte:
589                         case BuiltinTypeSpec.Type.Short:
590                         case BuiltinTypeSpec.Type.UShort:
591                         case BuiltinTypeSpec.Type.Int:
592                         case BuiltinTypeSpec.Type.UInt:
593                         case BuiltinTypeSpec.Type.Float:
594                         case BuiltinTypeSpec.Type.UIntPtr:
595                         case BuiltinTypeSpec.Type.IntPtr:
596                                 return true;
597                         }
598
599                         if (TypeSpec.IsReferenceType (MemberType))
600                                 return true;
601
602                         if (MemberType.IsEnum)
603                                 return true;
604
605                         return false;
606                 }
607
608                 public override void Accept (StructuralVisitor visitor)
609                 {
610                         visitor.Visit (this);
611                 }
612                 
613                 public override bool Define ()
614                 {
615                         if (!base.Define ())
616                                 return false;
617
618                         MetaType[] required_modifier = null;
619                         if ((ModFlags & Modifiers.VOLATILE) != 0) {
620                                 var mod = Module.PredefinedTypes.IsVolatile.Resolve ();
621                                 if (mod != null)
622                                         required_modifier = new MetaType[] { mod.GetMetaInfo () };
623                         }
624
625                         FieldBuilder = Parent.TypeBuilder.DefineField (
626                                 Name, member_type.GetMetaInfo (), required_modifier, null, ModifiersExtensions.FieldAttr (ModFlags));
627
628                         spec = new FieldSpec (Parent.Definition, this, MemberType, FieldBuilder, ModFlags);
629
630                         //
631                         // Don't cache inaccessible fields except for struct where we
632                         // need them for definitive assignment checks
633                         //
634                         if ((ModFlags & Modifiers.BACKING_FIELD) == 0 || Parent.Kind == MemberKind.Struct) {
635                                 Parent.MemberCache.AddMember (spec);
636                         }
637
638                         if (initializer != null) {
639                                 Parent.RegisterFieldForInitialization (this, new FieldInitializer (this, initializer, TypeExpression.Location));
640                         }
641
642                         if (declarators != null) {
643                                 foreach (var d in declarators) {
644                                         var t = new TypeExpression (MemberType, d.Name.Location);
645                                         var f = new Field (Parent, t, ModFlags, new MemberName (d.Name.Value, d.Name.Location), OptAttributes);
646                                         if (d.Initializer != null)
647                                                 f.initializer = d.Initializer;
648
649                                         f.Define ();
650                                         Parent.PartialContainer.Members.Add (f);
651                                 }
652                         }
653
654                         return true;
655                 }
656
657                 protected override void DoMemberTypeDependentChecks ()
658                 {
659                         if ((ModFlags & Modifiers.BACKING_FIELD) != 0)
660                                 return;
661
662                         base.DoMemberTypeDependentChecks ();
663
664                         if ((ModFlags & Modifiers.VOLATILE) != 0) {
665                                 if (!CanBeVolatile ()) {
666                                         Report.Error (677, Location, "`{0}': A volatile field cannot be of the type `{1}'",
667                                                 GetSignatureForError (), MemberType.GetSignatureForError ());
668                                 }
669
670                                 if ((ModFlags & Modifiers.READONLY) != 0) {
671                                         Report.Error (678, Location, "`{0}': A field cannot be both volatile and readonly",
672                                                 GetSignatureForError ());
673                                 }
674                         }
675                 }
676
677                 protected override bool VerifyClsCompliance ()
678                 {
679                         if (!base.VerifyClsCompliance ())
680                                 return false;
681
682                         if ((ModFlags & Modifiers.VOLATILE) != 0) {
683                                 Report.Warning (3026, 1, Location, "CLS-compliant field `{0}' cannot be volatile", GetSignatureForError ());
684                         }
685
686                         return true;
687                 }
688         }
689 }