Example #1
0
 public override Field VisitField(Field field) {
   if (field == null) return null;
   bool savedInsideUnsafeCode = this.typeSystem.insideUnsafeCode;
   this.typeSystem.insideUnsafeCode = field.IsUnsafe;
   if (field.DeclaringType is Interface && !this.InterfaceAllowsThisKindOfField(field))
     this.HandleError(field, Error.InterfaceHasField);
   this.currentField = field;
   field.ImplementedInterfaces = this.VisitInterfaceReferenceList(field.ImplementedInterfaces);
   if (this.currentType != null && (this.currentType.Flags & TypeFlags.ExplicitLayout) != 0 && !field.IsStatic) {
     if ((field.Attributes == null || field.GetAttribute(SystemTypes.FieldOffsetAttribute) == null) && (field.DeclaringType == null || !field.DeclaringType.IsNormalized)) {
       this.HandleError(field.Name, Error.MissingStructOffset, this.GetMemberSignature(field));
     }
   }
   field.Attributes = this.VisitAttributeList(field.Attributes, field);
   field.Type = this.VisitTypeReference(field.Type);
   EnumNode enumType = field.DeclaringType as EnumNode;
   if (enumType == null && this.IsLessAccessible(field.Type, field) && (field.DeclaringType == null || !field.DeclaringType.IsNormalized)) {
     this.HandleError(field.Name, Error.FieldTypeLessAccessibleThanField, this.GetTypeName(field.Type), this.GetTypeName(field.DeclaringType)+"."+field.Name);
     this.HandleRelatedError(field.Type);
   }
   if (field.IsVolatile) {
     if (field.IsInitOnly || field.IsLiteral) {
       this.HandleError(field.Name, Error.VolatileAndReadonly, this.GetMemberSignature(field));
       field.Flags &= ~FieldFlags.InitOnly;
     } else if (field.Type != null && field.Type.IsValueType) {
       switch (this.typeSystem.GetUnderlyingType(field.Type).TypeCode) {
         case TypeCode.Boolean:
         case TypeCode.Byte:
         case TypeCode.SByte:
         case TypeCode.Int16:
         case TypeCode.UInt16:
         case TypeCode.Int32:
         case TypeCode.UInt32:
         case TypeCode.Char:
         case TypeCode.Single:
           break;
         default:
           if (field.Type != SystemTypes.IntPtr && field.Type != SystemTypes.UIntPtr)
             this.HandleError(field.Name, Error.VolatileNonWordSize, this.GetMemberSignature(field), this.GetTypeName(field.Type));
           break;
       }
     }
   }
   if (field.Initializer != null) {
     if (!field.IsStatic && field.DeclaringType is Struct)
       this.HandleError(field.Initializer, Error.InstanceFieldInitializerInStruct, this.GetMemberSignature(field));
     bool savedCheckOverflow = this.typeSystem.checkOverflow;
     this.typeSystem.checkOverflow = true;
     if (field.IsLiteral && enumType != null) {
       field.Initializer = this.VisitExpression(field.Initializer);
       if (field.Initializer != null && field.DefaultValue != null) {
         Literal lit = field.DefaultValue;
         if (lit.Type != null && !this.typeSystem.ImplicitLiteralCoercionFromTo(lit, lit.Type, enumType.UnderlyingType)) {
           if (!enumType.IsErroneous) {
             if ((lit.Type.IsPrimitiveInteger || lit.Type == enumType) && lit.Value is IConvertible && ((IConvertible)lit.Value).ToInt64(null) >= 0)
               this.HandleError(field.Initializer, Error.EnumerationValueOutOfRange, this.GetMemberSignature(field));
             else
               this.HandleError(field.Initializer, Error.NoImplicitCoercionFromConstant, lit.SourceContext.SourceText, this.GetTypeName(enumType.UnderlyingType));
           }
           field.DefaultValue = new Literal(0, enumType.UnderlyingType, lit.SourceContext);
           enumType.IsErroneous = true;
         }
       } else {
         field.DefaultValue = new Literal(0, enumType.UnderlyingType);
         enumType.IsErroneous = true;
       }
     } else {
       field.Initializer = this.typeSystem.ImplicitCoercion(this.VisitExpression(field.Initializer), field.Type, this.TypeViewer);
       if (field.IsLiteral) field.DefaultValue = field.Initializer as Literal;
     }
     this.typeSystem.checkOverflow = savedCheckOverflow;
   }
   if (field.IsLiteral && field.DefaultValue == null) {
     if (field.Initializer != null)
       this.HandleError(field.Initializer, Error.NotConstantExpression, this.GetMemberSignature(field));
     field.Flags &= ~(FieldFlags.Literal|FieldFlags.HasDefault);
     field.Flags |= FieldFlags.InitOnly;
   }
   if (field.IsStrictReadonly) {
     if (!field.IsInitOnly)
       this.HandleError(field, Error.StrictReadonlyNotReadonly);
     if (field.IsStatic)
       this.HandleError(field, Error.StrictReadonlyStatic);
   }
   this.currentField = null;
   this.typeSystem.insideUnsafeCode = savedInsideUnsafeCode;
   return field;
 }