~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to contrib/ICSharpCode.NRefactory.CSharp/Parser/mcs/field.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

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