[csharp] repl using statement fix + support for --fatal
[mono.git] / mcs / mcs / attribute.cs
index 288ecd6b526d37046152b591f13fb78d569b81f4..fda379abcc8432948793c68f3060619dbd447d26 100644 (file)
 //
 
 using System;
-using System.Diagnostics;
 using System.Collections.Generic;
-using System.Reflection;
-using System.Reflection.Emit;
 using System.Runtime.InteropServices;
 using System.Runtime.CompilerServices;
 using System.Security; 
@@ -22,6 +19,16 @@ using System.Security.Permissions;
 using System.Text;
 using System.IO;
 
+#if STATIC
+using SecurityType = System.Collections.Generic.List<IKVM.Reflection.Emit.CustomAttributeBuilder>;
+using IKVM.Reflection;
+using IKVM.Reflection.Emit;
+#else
+using SecurityType = System.Collections.Generic.Dictionary<System.Security.Permissions.SecurityAction, System.Security.PermissionSet>;
+using System.Reflection;
+using System.Reflection.Emit;
+#endif
+
 namespace Mono.CSharp {
 
        /// <summary>
@@ -102,7 +109,7 @@ namespace Mono.CSharp {
                static Assembly orig_sec_assembly;
                public static readonly object[] EmptyObject = new object [0];
 
-               IList<KeyValuePair<MemberExpr, NamedArgument>> named_values;
+               List<KeyValuePair<MemberExpr, NamedArgument>> named_values;
 
                // Cache for parameter-less attributes
                static Dictionary<TypeSpec, MethodSpec> att_cache;
@@ -119,6 +126,27 @@ namespace Mono.CSharp {
                        this.nameEscaped = nameEscaped;
                }
 
+               void AddModuleCharSet (ResolveContext rc)
+               {
+                       const string dll_import_char_set = "CharSet";
+
+                       //
+                       // Only when not customized by user
+                       //
+                       if (HasField (dll_import_char_set))
+                               return;
+
+                       if (!rc.Module.PredefinedTypes.CharSet.IsDefined) {
+                               return;
+                       }
+
+                       if (NamedArguments == null)
+                               NamedArguments = new Arguments (1);
+
+                       var value = Constant.CreateConstant (rc, rc.Module.PredefinedTypes.CharSet.TypeSpec, rc.Module.DefaultCharSet, Location);
+                       NamedArguments.Add (new NamedArgument (dll_import_char_set, loc, value));
+               }
+
                public Attribute Clone ()
                {
                        Attribute a = new Attribute (ExplicitTarget, expression, null, loc, nameEscaped);
@@ -142,7 +170,7 @@ namespace Mono.CSharp {
                // we use @target field as a list of targets. The attribute
                // has to be resolved only once but emitted for each target.
                //
-               public virtual void AttachTo (Attributable target, IMemberContext context)
+               public void AttachTo (Attributable target, IMemberContext context)
                {
                        if (this.targets == null) {
                                this.targets = new Attributable[] { target };
@@ -308,8 +336,8 @@ namespace Mono.CSharp {
 
                public bool HasSecurityAttribute {
                        get {
-                               PredefinedAttribute pa = PredefinedAttributes.Get.Security;
-                               return pa.IsDefined && TypeSpec.IsBaseClass (type, pa.Type, false);
+                               PredefinedAttribute pa = context.Module.PredefinedAttributes.Security;
+                               return pa.IsDefined && TypeSpec.IsBaseClass (type, pa.TypeSpec, false);
                        }
                }
 
@@ -335,29 +363,6 @@ namespace Mono.CSharp {
                        get { return expression.Name; }
                }
 
-               void ApplyModuleCharSet (ResolveContext rc)
-               {
-                       if (Type != PredefinedAttributes.Get.DllImport)
-                               return;
-
-                       if (!RootContext.ToplevelTypes.HasDefaultCharSet)
-                               return;
-
-                       const string CharSetEnumMember = "CharSet";
-                       if (NamedArguments == null) {
-                               NamedArguments = new Arguments (1);
-                       } else {
-                               foreach (NamedArgument a in NamedArguments) {
-                                       if (a.Name == CharSetEnumMember)
-                                               return;
-                               }
-                       }
-
-                       var char_set = Import.ImportType (typeof (CharSet));
-                       NamedArguments.Add (new NamedArgument (CharSetEnumMember, loc,
-                               Constant.CreateConstant (rc, char_set, RootContext.ToplevelTypes.DefaultCharSet, Location)));
-               }
-
                public Report Report {
                        get { return context.Compiler.Report; }
                }
@@ -401,7 +406,13 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       ApplyModuleCharSet (rc);
+                       //
+                       // Add [module: DefaultCharSet] to all DllImport import attributes
+                       //
+                       var module = context.Module;
+                       if (Type == module.PredefinedAttributes.DllImport && module.HasDefaultCharSet) {
+                               AddModuleCharSet (rc);
+                       }
 
                        if (NamedArguments != null && !ResolveNamedArguments (rc)) {
                                return null;
@@ -443,10 +454,10 @@ namespace Mono.CSharp {
 
                                a.Resolve (ec);
 
-                               Expression member = Expression.MemberLookup (ec, ec.CurrentType, Type, name, 0, false, loc);
+                               Expression member = Expression.MemberLookup (ec, ec.CurrentType, Type, name, 0, MemberLookupRestrictions.ExactArity, loc);
 
                                if (member == null) {
-                                       member = Expression.MemberLookup (null, ec.CurrentType, Type, name, 0, false, loc);
+                                       member = Expression.MemberLookup (null, ec.CurrentType, Type, name, 0, MemberLookupRestrictions.ExactArity, loc);
 
                                        if (member != null) {
                                                // TODO: ec.Report.SymbolRelatedToPreviousError (member);
@@ -483,6 +494,7 @@ namespace Mono.CSharp {
                                        }
 
                                        obsolete_attr = pi.GetAttributeObsolete ();
+                                       pi.MemberDefinition.SetIsAssigned ();
                                } else {
                                        var fi = ((FieldExpr) member).Spec;
 
@@ -498,6 +510,7 @@ namespace Mono.CSharp {
                                        }
 
                                        obsolete_attr = fi.GetAttributeObsolete ();
+                                       fi.MemberDefinition.SetIsAssigned ();
                                }
 
                                if (obsolete_attr != null && !context.IsObsolete)
@@ -520,7 +533,7 @@ namespace Mono.CSharp {
                public string GetValidTargets ()
                {
                        StringBuilder sb = new StringBuilder ();
-                       AttributeTargets targets = Type.GetAttributeUsage (PredefinedAttributes.Get.AttributeUsage).ValidOn;
+                       AttributeTargets targets = Type.GetAttributeUsage (context.Module.PredefinedAttributes.AttributeUsage).ValidOn;
 
                        if ((targets & AttributeTargets.Assembly) != 0)
                                sb.Append ("assembly, ");
@@ -582,11 +595,11 @@ namespace Mono.CSharp {
 
                        AttributeUsageAttribute usage_attribute = new AttributeUsageAttribute ((AttributeTargets)((Constant) PosArguments [0].Expr).GetValue ());
 
-                       var field = GetPropertyValue ("AllowMultiple") as BoolConstant;
+                       var field = GetNamedValue ("AllowMultiple") as BoolConstant;
                        if (field != null)
                                usage_attribute.AllowMultiple = field.Value;
 
-                       field = GetPropertyValue ("Inherited") as BoolConstant;
+                       field = GetNamedValue ("Inherited") as BoolConstant;
                        if (field != null)
                                usage_attribute.Inherited = field.Value;
 
@@ -699,6 +712,7 @@ namespace Mono.CSharp {
                                case "field": Target = AttributeTargets.Field; return true;
                                case "method": Target = AttributeTargets.Method; return true;
                                case "property": Target = AttributeTargets.Property; return true;
+                               case "module": Target = AttributeTargets.Module; return true;
                                }
                                throw new InternalErrorException ("Unknown explicit target: " + ExplicitTarget);
                        }
@@ -722,6 +736,7 @@ namespace Mono.CSharp {
                        SecurityAction action = GetSecurityActionValue ();
 
                        switch (action) {
+#pragma warning disable 618
                        case SecurityAction.Demand:
                        case SecurityAction.Assert:
                        case SecurityAction.Deny:
@@ -738,6 +753,7 @@ namespace Mono.CSharp {
                                if (for_assembly)
                                        return true;
                                break;
+#pragma warning restore 618
 
                        default:
                                Error_AttributeEmitError ("SecurityAction is out of range");
@@ -750,15 +766,40 @@ namespace Mono.CSharp {
 
                System.Security.Permissions.SecurityAction GetSecurityActionValue ()
                {
-                       return (SecurityAction) ((Constant) PosArguments[0].Expr).GetTypedValue ();
+                       return (SecurityAction) ((Constant) PosArguments[0].Expr).GetValue ();
                }
 
                /// <summary>
                /// Creates instance of SecurityAttribute class and add result of CreatePermission method to permission table.
                /// </summary>
                /// <returns></returns>
-               public void ExtractSecurityPermissionSet (Dictionary<SecurityAction, PermissionSet> permissions)
-               {
+               public void ExtractSecurityPermissionSet (MethodSpec ctor, ref SecurityType permissions)
+               {
+#if STATIC
+                       object[] values = new object [PosArguments.Count];
+                       for (int i = 0; i < values.Length; ++i)
+                               values [i] = ((Constant) PosArguments [i].Expr).GetValue ();
+
+                       PropertyInfo[] prop;
+                       object[] prop_values;
+                       if (named_values == null) {
+                               prop = null;
+                               prop_values = null;
+                       } else {
+                               prop = new PropertyInfo[named_values.Count];
+                               prop_values = new object [named_values.Count];
+                               for (int i = 0; i < prop.Length; ++i) {
+                                       prop [i] = ((PropertyExpr) named_values [i].Key).PropertyInfo.MetaInfo;
+                                       prop_values [i] = ((Constant) named_values [i].Value.Expr).GetValue ();
+                               }
+                       }
+
+                       if (permissions == null)
+                               permissions = new SecurityType ();
+
+                       var cab = new CustomAttributeBuilder ((ConstructorInfo) ctor.GetMetaInfo (), values, prop, prop_values);
+                       permissions.Add (cab);
+#else
                        Type orig_assembly_type = null;
 
                        if (Type.MemberDefinition is TypeContainer) {
@@ -772,7 +813,7 @@ namespace Mono.CSharp {
                                        }
 
                                        if (orig_sec_assembly == null) {
-                                               string file = Path.Combine (orig_version_path, Driver.OutputFile);
+                                               string file = Path.Combine (orig_version_path, Path.GetFileName (RootContext.OutputFile));
                                                orig_sec_assembly = Assembly.LoadFile (file);
                                        }
 
@@ -792,7 +833,7 @@ namespace Mono.CSharp {
                        if (orig_assembly_type == null) {
                                args = new object[PosArguments.Count];
                                for (int j = 0; j < args.Length; ++j) {
-                                       args[j] = ((Constant) PosArguments[j].Expr).GetTypedValue ();
+                                       args[j] = ((Constant) PosArguments[j].Expr).GetValue ();
                                }
 
                                sa = (SecurityAttribute) Activator.CreateInstance (Type.GetMetaInfo (), args);
@@ -800,7 +841,7 @@ namespace Mono.CSharp {
                                if (named_values != null) {
                                        for (int i = 0; i < named_values.Count; ++i) {
                                                PropertyInfo pi = ((PropertyExpr) named_values[i].Key).PropertyInfo.MetaInfo;
-                                               pi.SetValue (sa, ((Constant) named_values [i].Value.Expr).GetTypedValue (), null);
+                                               pi.SetValue (sa, ((Constant) named_values [i].Value.Expr).GetValue (), null);
                                        }
                                }
                        } else {
@@ -816,7 +857,7 @@ namespace Mono.CSharp {
                                                // TODO: pi can be null
                                                PropertyInfo pi = orig_assembly_type.GetProperty (emited_pi.Name);
 
-                                               pi.SetValue (sa, ((Constant) named_values[i].Value.Expr).GetTypedValue (), null);
+                                               pi.SetValue (sa, ((Constant) named_values[i].Value.Expr).GetValue (), null);
                                        }
                                }
                        }
@@ -840,6 +881,9 @@ namespace Mono.CSharp {
                                }
                        }
 
+                       if (permissions == null)
+                               permissions = new SecurityType ();
+
                        PermissionSet ps;
                        if (!permissions.TryGetValue (action, out ps)) {
                                if (sa is PermissionSetAttribute)
@@ -853,9 +897,10 @@ namespace Mono.CSharp {
                                permissions [action] = ps;
                        }
                        ps.AddPermission (perm);
+#endif
                }
 
-               public Constant GetPropertyValue (string name)
+               public Constant GetNamedValue (string name)
                {
                        if (named_values == null)
                                return null;
@@ -868,109 +913,6 @@ namespace Mono.CSharp {
                        return null;
                }
 
-               //
-               // Theoretically, we can get rid of this, since FieldBuilder.SetCustomAttribute()
-               // and ParameterBuilder.SetCustomAttribute() are supposed to handle this attribute.
-               // However, we can't, since it appears that the .NET 1.1 SRE hangs when given a MarshalAsAttribute.
-               //
-#if false
-               public UnmanagedMarshal GetMarshal (Attributable attr)
-               {
-                       UnmanagedType UnmanagedType;
-                       if (!RootContext.StdLib || pos_values [0].GetType () != typeof (UnmanagedType))
-                               UnmanagedType = (UnmanagedType) System.Enum.ToObject (typeof (UnmanagedType), pos_values [0]);
-                       else
-                               UnmanagedType = (UnmanagedType) pos_values [0];
-
-                       object value = GetFieldValue ("SizeParamIndex");
-                       if (value != null && UnmanagedType != UnmanagedType.LPArray) {
-                               Error_AttributeEmitError ("SizeParamIndex field is not valid for the specified unmanaged type");
-                               return null;
-                       }
-
-                       object o = GetFieldValue ("ArraySubType");
-                       UnmanagedType array_sub_type = o == null ? (UnmanagedType) 0x50 /* NATIVE_MAX */ : (UnmanagedType) o;
-
-                       switch (UnmanagedType) {
-                       case UnmanagedType.CustomMarshaler: {
-                               MethodInfo define_custom = typeof (UnmanagedMarshal).GetMethod ("DefineCustom",
-                                       BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
-                               if (define_custom == null) {
-                                       Report.RuntimeMissingSupport (Location, "set marshal info");
-                                       return null;
-                               }
-                               
-                               object [] args = new object [4];
-                               args [0] = GetFieldValue ("MarshalTypeRef");
-                               args [1] = GetFieldValue ("MarshalCookie");
-                               args [2] = GetFieldValue ("MarshalType");
-                               args [3] = Guid.Empty;
-                               return (UnmanagedMarshal) define_custom.Invoke (null, args);
-                       }
-                       case UnmanagedType.LPArray: {
-                               object size_const = GetFieldValue ("SizeConst");
-                               object size_param_index = GetFieldValue ("SizeParamIndex");
-
-                               if ((size_const != null) || (size_param_index != null)) {
-                                       MethodInfo define_array = typeof (UnmanagedMarshal).GetMethod ("DefineLPArrayInternal",
-                                               BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
-                                       if (define_array == null) {
-                                               Report.RuntimeMissingSupport (Location, "set marshal info");
-                                               return null;
-                                       }
-                               
-                                       object [] args = new object [3];
-                                       args [0] = array_sub_type;
-                                       args [1] = size_const == null ? -1 : size_const;
-                                       args [2] = size_param_index == null ? -1 : size_param_index;
-                                       return (UnmanagedMarshal) define_array.Invoke (null, args);
-                               }
-                               else
-                                       return UnmanagedMarshal.DefineLPArray (array_sub_type);
-                       }
-                       case UnmanagedType.SafeArray:
-                               return UnmanagedMarshal.DefineSafeArray (array_sub_type);
-
-                       case UnmanagedType.ByValArray:
-                               FieldBase fm = attr as FieldBase;
-                               if (fm == null) {
-                                       Error_AttributeEmitError ("Specified unmanaged type is only valid on fields");
-                                       return null;
-                               }
-                               return UnmanagedMarshal.DefineByValArray ((int) GetFieldValue ("SizeConst"));
-
-                       case UnmanagedType.ByValTStr:
-                               return UnmanagedMarshal.DefineByValTStr ((int) GetFieldValue ("SizeConst"));
-
-                       default:
-                               return UnmanagedMarshal.DefineUnmanagedMarshal (UnmanagedType);
-                       }
-               }
-
-               object GetFieldValue (string name)
-               {
-                       int i;
-                       if (field_info_arr == null)
-                               return null;
-                       i = 0;
-                       foreach (FieldInfo fi in field_info_arr) {
-                               if (fi.Name == name)
-                                       return GetValue (field_values_arr [i]);
-                               i++;
-                       }
-                       return null;
-               }
-
-               static object GetValue (object value)
-               {
-                       if (value is EnumConstant)
-                               return ((EnumConstant) value).GetValue ();
-                       else
-                               return value;                           
-               }
-               
-#endif
-
                public CharSet GetCharSetValue ()
                {
                        return (CharSet)System.Enum.Parse (typeof (CharSet), ((Constant) PosArguments [0].Expr).GetValue ().ToString ());
@@ -989,27 +931,32 @@ namespace Mono.CSharp {
                        return false;
                }
 
-               public bool IsInternalMethodImplAttribute {
-                       get {
-                               if (Type != PredefinedAttributes.Get.MethodImpl)
-                                       return false;
-
-                               MethodImplOptions options;
-                               if (PosArguments[0].Type.GetMetaInfo () != typeof (MethodImplOptions))
-                                       options = (MethodImplOptions) System.Enum.ToObject (typeof (MethodImplOptions), ((Constant) PosArguments[0].Expr).GetValue ());
-                               else
-                                       options = (MethodImplOptions) ((Constant) PosArguments [0].Expr).GetValue ();
-
-                               return (options & MethodImplOptions.InternalCall) != 0;
+               //
+               // Returns true for MethodImplAttribute with MethodImplOptions.InternalCall value
+               // 
+               public bool IsInternalCall ()
+               {
+                       MethodImplOptions options = 0;
+                       if (PosArguments.Count == 1) {
+                               options = (MethodImplOptions) System.Enum.Parse (typeof (MethodImplOptions), ((Constant) PosArguments[0].Expr).GetValue ().ToString ());
+                       } else if (HasField ("Value")) {
+                               var named = GetNamedValue ("Value");
+                               options = (MethodImplOptions) System.Enum.Parse (typeof (MethodImplOptions), named.GetValue ().ToString ());
                        }
+
+                       return (options & MethodImplOptions.InternalCall) != 0;
                }
 
-               public LayoutKind GetLayoutKindValue ()
+               //
+               // Returns true for StructLayoutAttribute with LayoutKind.Explicit value
+               // 
+               public bool IsExplicitLayoutKind ()
                {
-                       if (!RootContext.StdLib || PosArguments[0].Type.GetMetaInfo () != typeof (LayoutKind))
-                               return (LayoutKind) System.Enum.ToObject (typeof (LayoutKind), ((Constant) PosArguments[0].Expr).GetValue ());
+                       if (PosArguments.Count != 1)
+                               return false;
 
-                       return (LayoutKind) ((Constant) PosArguments[0].Expr).GetValue ();
+                       var value = (LayoutKind) System.Enum.Parse (typeof (LayoutKind), ((Constant) PosArguments[0].Expr).GetValue ().ToString ());
+                       return value == LayoutKind.Explicit;
                }
 
                public Constant GetParameterDefaultValue (out TypeSpec type)
@@ -1046,7 +993,9 @@ namespace Mono.CSharp {
                        if (ctor == null)
                                return;
 
-                       AttributeUsageAttribute usage_attr = Type.GetAttributeUsage (PredefinedAttributes.Get.AttributeUsage);
+                       var predefined = context.Module.PredefinedAttributes;
+
+                       AttributeUsageAttribute usage_attr = Type.GetAttributeUsage (predefined.AttributeUsage);
                        if ((usage_attr.ValidOn & Target) == 0) {
                                Report.Error (592, Location, "The attribute `{0}' is not valid on this declaration type. " +
                                              "It is valid on `{1}' declarations only",
@@ -1054,64 +1003,80 @@ namespace Mono.CSharp {
                                return;
                        }
 
-                       var predefined = PredefinedAttributes.Get;
-
-                       AttributeEncoder encoder = new AttributeEncoder (false);
-
-                       if (PosArguments != null) {
-                               var param_types = ctor.Parameters.Types;
-                               for (int j = 0; j < PosArguments.Count; ++j) {
-                                       var pt = param_types[j];
-                                       var arg_expr = PosArguments[j].Expr;
-                                       if (j == 0) {
-                                               if (Type == predefined.IndexerName || Type == predefined.Conditional) {
-                                                       string v = ((StringConstant) arg_expr).Value;
-                                                       if (!Tokenizer.IsValidIdentifier (v) || Tokenizer.IsKeyword (v)) {
-                                                               context.Compiler.Report.Error (633, arg_expr.Location,
-                                                                       "The argument to the `{0}' attribute must be a valid identifier", GetSignatureForError ());
-                                                       }
-                                               } else if (Type == predefined.Guid) {
-                                                       try {
+                       byte[] cdata;
+                       if (PosArguments == null && named_values == null) {
+                               cdata = AttributeEncoder.Empty;
+                       } else {
+                               AttributeEncoder encoder = new AttributeEncoder ();
+
+                               if (PosArguments != null) {
+                                       var param_types = ctor.Parameters.Types;
+                                       for (int j = 0; j < PosArguments.Count; ++j) {
+                                               var pt = param_types[j];
+                                               var arg_expr = PosArguments[j].Expr;
+                                               if (j == 0) {
+                                                       if (Type == predefined.IndexerName || Type == predefined.Conditional) {
                                                                string v = ((StringConstant) arg_expr).Value;
-                                                               new Guid (v);
-                                                       } catch (Exception e) {
-                                                               Error_AttributeEmitError (e.Message);
+                                                               if (!Tokenizer.IsValidIdentifier (v) || Tokenizer.IsKeyword (v)) {
+                                                                       context.Compiler.Report.Error (633, arg_expr.Location,
+                                                                               "The argument to the `{0}' attribute must be a valid identifier", GetSignatureForError ());
+                                                               }
+                                                       } else if (Type == predefined.Guid) {
+                                                               try {
+                                                                       string v = ((StringConstant) arg_expr).Value;
+                                                                       new Guid (v);
+                                                               } catch (Exception e) {
+                                                                       Error_AttributeEmitError (e.Message);
+                                                                       return;
+                                                               }
+                                                       } else if (Type == predefined.AttributeUsage) {
+                                                               int v = ((IntConstant) ((EnumConstant) arg_expr).Child).Value;
+                                                               if (v == 0) {
+                                                                       context.Compiler.Report.Error (591, Location, "Invalid value for argument to `{0}' attribute",
+                                                                               "System.AttributeUsage");
+                                                               }
+                                                       } else if (Type == predefined.MarshalAs) {
+                                                               if (PosArguments.Count == 1) {
+                                                                       var u_type = (UnmanagedType) System.Enum.Parse (typeof (UnmanagedType), ((Constant) PosArguments[0].Expr).GetValue ().ToString ());
+                                                                       if (u_type == UnmanagedType.ByValArray && !(Owner is FieldBase)) {
+                                                                               Error_AttributeEmitError ("Specified unmanaged type is only valid on fields");
+                                                                       }
+                                                               }
+                                                       } else if (Type == predefined.DllImport) {
+                                                               if (PosArguments.Count == 1) {
+                                                                       var value = ((Constant) PosArguments[0].Expr).GetValue () as string;
+                                                                       if (string.IsNullOrEmpty (value))
+                                                                               Error_AttributeEmitError ("DllName cannot be empty");
+                                                               }
+                                                       } else if (Type == predefined.MethodImpl && pt == TypeManager.short_type &&
+                                                               !System.Enum.IsDefined (typeof (MethodImplOptions), ((Constant) arg_expr).GetValue ().ToString ())) {
+                                                               Error_AttributeEmitError ("Incorrect argument value.");
                                                                return;
                                                        }
-                                               } else if (Type == predefined.AttributeUsage) {
-                                                       int v = ((IntConstant)((EnumConstant) arg_expr).Child).Value;
-                                                       if (v == 0) {
-                                                               context.Compiler.Report.Error (591, Location, "Invalid value for argument to `{0}' attribute",
-                                                                       "System.AttributeUsage");
-                                                       }
-                                               } else if (Type == predefined.MethodImpl && pt == TypeManager.short_type &&
-                                                       !System.Enum.IsDefined (typeof (MethodImplOptions), ((Constant) arg_expr).GetValue ().ToString ())) {
-                                                       Error_AttributeEmitError ("Incorrect argument value.");
-                                                       return;
                                                }
-                                       }
 
-                                       arg_expr.EncodeAttributeValue (context, encoder, pt);
+                                               arg_expr.EncodeAttributeValue (context, encoder, pt);
+                                       }
                                }
-                       }
-
-                       if (named_values != null) {
-                               encoder.Stream.Write ((ushort) named_values.Count);
-                               foreach (var na in named_values) {
-                                       if (na.Key is FieldExpr)
-                                               encoder.Stream.Write ((byte) 0x53);
-                                       else
-                                               encoder.Stream.Write ((byte) 0x54);
 
-                                       encoder.Encode (na.Key.Type);
-                                       encoder.Encode (na.Value.Name);
-                                       na.Value.Expr.EncodeAttributeValue (context, encoder, na.Key.Type);
+                               if (named_values != null) {
+                                       encoder.Encode ((ushort) named_values.Count);
+                                       foreach (var na in named_values) {
+                                               if (na.Key is FieldExpr)
+                                                       encoder.Encode ((byte) 0x53);
+                                               else
+                                                       encoder.Encode ((byte) 0x54);
+
+                                               encoder.Encode (na.Key.Type);
+                                               encoder.Encode (na.Value.Name);
+                                               na.Value.Expr.EncodeAttributeValue (context, encoder, na.Key.Type);
+                                       }
+                               } else {
+                                       encoder.EncodeEmptyNamedArguments ();
                                }
-                       } else {
-                               encoder.Stream.Write ((ushort) 0);
-                       }
 
-                       byte[] cdata = encoder.ToArray ();
+                               cdata = encoder.ToArray ();
+                       }
 
                        try {
                                foreach (Attributable target in targets)
@@ -1212,21 +1177,6 @@ namespace Mono.CSharp {
                {
                        this.ns = ns;
                }
-               
-               public override void AttachTo (Attributable target, IMemberContext context)
-               {
-                       if (ExplicitTarget == "assembly") {
-                               base.AttachTo (CodeGen.Assembly, context);
-                               return;
-                       }
-
-                       if (ExplicitTarget == "module") {
-                               base.AttachTo (RootContext.ToplevelTypes, context);
-                               return;
-                       }
-
-                       throw new NotImplementedException ("Unknown global explicit target " + ExplicitTarget);
-               }
 
                void Enter ()
                {
@@ -1334,8 +1284,16 @@ namespace Mono.CSharp {
                }
 
                public Attribute Search (PredefinedAttribute t)
+               {
+                       return Search (null, t);
+               }
+
+               public Attribute Search (string explicitTarget, PredefinedAttribute t)
                {
                        foreach (Attribute a in Attrs) {
+                               if (explicitTarget != null && a.ExplicitTarget != explicitTarget)
+                                       continue;
+
                                if (a.ResolveType () == t)
                                        return a;
                        }
@@ -1392,7 +1350,7 @@ namespace Mono.CSharp {
                }
        }
 
-       public struct AttributeEncoder
+       public sealed class AttributeEncoder
        {
                [Flags]
                public enum EncodedTypeProperties
@@ -1402,70 +1360,159 @@ namespace Mono.CSharp {
                        TypeParameter = 1 << 1
                }
 
-               public readonly BinaryWriter Stream;
+               public static readonly byte[] Empty;
 
-               public AttributeEncoder (bool empty)
+               byte[] buffer;
+               int pos;
+               const ushort Version = 1;
+
+               static AttributeEncoder ()
                {
-                       if (empty) {
-                               Stream = null;
-                               return;
-                       }
+                       Empty = new byte[4];
+                       Empty[0] = (byte) Version;
+               }
 
-                       Stream = new BinaryWriter (new MemoryStream ());
-                       const ushort version = 1;
-                       Stream.Write (version);
+               public AttributeEncoder ()
+               {
+                       buffer = new byte[32];
+                       Encode (Version);
+               }
+
+               public void Encode (bool value)
+               {
+                       Encode (value ? (byte) 1 : (byte) 0);
+               }
+
+               public void Encode (byte value)
+               {
+                       if (pos == buffer.Length)
+                               Grow (1);
+
+                       buffer [pos++] = value;
+               }
+
+               public void Encode (sbyte value)
+               {
+                       Encode ((byte) value);
+               }
+
+               public void Encode (short value)
+               {
+                       if (pos + 2 > buffer.Length)
+                               Grow (2);
+
+                       buffer[pos++] = (byte) value;
+                       buffer[pos++] = (byte) (value >> 8);
+               }
+
+               public void Encode (ushort value)
+               {
+                       Encode ((short) value);
+               }
+
+               public void Encode (int value)
+               {
+                       if (pos + 4 > buffer.Length)
+                               Grow (4);
+
+                       buffer[pos++] = (byte) value;
+                       buffer[pos++] = (byte) (value >> 8);
+                       buffer[pos++] = (byte) (value >> 16);
+                       buffer[pos++] = (byte) (value >> 24);
+               }
+
+               public void Encode (uint value)
+               {
+                       Encode ((int) value);
+               }
+
+               public void Encode (long value)
+               {
+                       if (pos + 8 > buffer.Length)
+                               Grow (8);
+
+                       buffer[pos++] = (byte) value;
+                       buffer[pos++] = (byte) (value >> 8);
+                       buffer[pos++] = (byte) (value >> 16);
+                       buffer[pos++] = (byte) (value >> 24);
+                       buffer[pos++] = (byte) (value >> 32);
+                       buffer[pos++] = (byte) (value >> 40);
+                       buffer[pos++] = (byte) (value >> 48);
+                       buffer[pos++] = (byte) (value >> 56);
+               }
+
+               public void Encode (ulong value)
+               {
+                       Encode ((long) value);
+               }
+
+               public void Encode (float value)
+               {
+                       Encode (SingleConverter.SingleToInt32Bits (value));
+               }
+
+               public void Encode (double value)
+               {
+                       Encode (BitConverter.DoubleToInt64Bits (value));
                }
 
                public void Encode (string value)
                {
-                       if (value == null)
-                               throw new ArgumentNullException ();
+                       if (value == null) {
+                               Encode ((byte) 0xFF);
+                               return;
+                       }
 
                        var buf = Encoding.UTF8.GetBytes(value);
                        WriteCompressedValue (buf.Length);
-                       Stream.Write (buf);
+
+                       if (pos + buf.Length > buffer.Length)
+                               Grow (buf.Length);
+
+                       Buffer.BlockCopy (buf, 0, buffer, pos, buf.Length);
+                       pos += buf.Length;
                }
 
                public EncodedTypeProperties Encode (TypeSpec type)
                {
                        if (type == TypeManager.bool_type) {
-                               Stream.Write ((byte) 0x02);
+                               Encode ((byte) 0x02);
                        } else if (type == TypeManager.char_type) {
-                               Stream.Write ((byte) 0x03);
+                               Encode ((byte) 0x03);
                        } else if (type == TypeManager.sbyte_type) {
-                               Stream.Write ((byte) 0x04);
+                               Encode ((byte) 0x04);
                        } else if (type == TypeManager.byte_type) {
-                               Stream.Write ((byte) 0x05);
+                               Encode ((byte) 0x05);
                        } else if (type == TypeManager.short_type) {
-                               Stream.Write ((byte) 0x06);
+                               Encode ((byte) 0x06);
                        } else if (type == TypeManager.ushort_type) {
-                               Stream.Write ((byte) 0x07);
+                               Encode ((byte) 0x07);
                        } else if (type == TypeManager.int32_type) {
-                               Stream.Write ((byte) 0x08);
+                               Encode ((byte) 0x08);
                        } else if (type == TypeManager.uint32_type) {
-                               Stream.Write ((byte) 0x09);
+                               Encode ((byte) 0x09);
                        } else if (type == TypeManager.int64_type) {
-                               Stream.Write ((byte) 0x0A);
+                               Encode ((byte) 0x0A);
                        } else if (type == TypeManager.uint64_type) {
-                               Stream.Write ((byte) 0x0B);
+                               Encode ((byte) 0x0B);
                        } else if (type == TypeManager.float_type) {
-                               Stream.Write ((byte) 0x0C);
+                               Encode ((byte) 0x0C);
                        } else if (type == TypeManager.double_type) {
-                               Stream.Write ((byte) 0x0D);
+                               Encode ((byte) 0x0D);
                        } else if (type == TypeManager.string_type) {
-                               Stream.Write ((byte) 0x0E);
+                               Encode ((byte) 0x0E);
                        } else if (type == TypeManager.type_type) {
-                               Stream.Write ((byte) 0x50);
+                               Encode ((byte) 0x50);
                        } else if (type == TypeManager.object_type) {
-                               Stream.Write ((byte) 0x51);
+                               Encode ((byte) 0x51);
                        } else if (TypeManager.IsEnumType (type)) {
-                               Stream.Write ((byte) 0x55);
+                               Encode ((byte) 0x55);
                                EncodeTypeName (type);
                        } else if (type.IsArray) {
-                               Stream.Write ((byte) 0x1D);
+                               Encode ((byte) 0x1D);
                                return Encode (TypeManager.GetElementType (type));
                        } else if (type == InternalType.Dynamic) {
-                               Stream.Write ((byte) 0x51);
+                               Encode ((byte) 0x51);
                                return EncodedTypeProperties.DynamicType;
                        }
 
@@ -1478,25 +1525,83 @@ namespace Mono.CSharp {
                        Encode (type.MemberDefinition.IsImported ? old_type.AssemblyQualifiedName : old_type.FullName);
                }
 
+               //
+               // Encodes single property named argument per call
+               //
+               public void EncodeNamedPropertyArgument (PropertySpec property, Constant value)
+               {
+                       Encode ((ushort) 1);    // length
+                       Encode ((byte) 0x54); // property
+                       Encode (property.MemberType);
+                       Encode (property.Name);
+                       value.EncodeAttributeValue (null, this, property.MemberType);
+               }
+
+               //
+               // Encodes single field named argument per call
+               //
+               public void EncodeNamedFieldArgument (FieldSpec field, Constant value)
+               {
+                       Encode ((ushort) 1);    // length
+                       Encode ((byte) 0x53); // field
+                       Encode (field.MemberType);
+                       Encode (field.Name);
+                       value.EncodeAttributeValue (null, this, field.MemberType);
+               }
+
+               public void EncodeNamedArguments<T> (T[] members, Constant[] values) where T : MemberSpec, IInterfaceMemberSpec
+               {
+                       Encode ((ushort) members.Length);
+
+                       for (int i = 0; i < members.Length; ++i)
+                       {
+                               var member = members[i];
+
+                               if (member.Kind == MemberKind.Field)
+                                       Encode ((byte) 0x53);
+                               else if (member.Kind == MemberKind.Property)
+                                       Encode ((byte) 0x54);
+                               else
+                                       throw new NotImplementedException (member.Kind.ToString ());
+
+                               Encode (member.MemberType);
+                               Encode (member.Name);
+                               values [i].EncodeAttributeValue (null, this, member.MemberType);
+                       }
+               }
+
+               public void EncodeEmptyNamedArguments ()
+               {
+                       Encode ((ushort) 0);
+               }
+
+               void Grow (int inc)
+               {
+                       int size = System.Math.Max (pos * 4, pos + inc + 2);
+                       Array.Resize (ref buffer, size);
+               }
+
                void WriteCompressedValue (int value)
                {
                        if (value < 0x80) {
-                               Stream.Write ((byte) value);
+                               Encode ((byte) value);
                                return;
                        }
 
                        if (value < 0x4000) {
-                               Stream.Write ((byte) (0x80 | (value >> 8)));
-                               Stream.Write ((byte) value);
+                               Encode ((byte) (0x80 | (value >> 8)));
+                               Encode ((byte) value);
                                return;
                        }
 
-                       Stream.Write (value);
+                       Encode (value);
                }
 
                public byte[] ToArray ()
                {
-                       return ((MemoryStream) Stream.BaseStream).ToArray ();
+                       byte[] buf = new byte[pos];
+                       Array.Copy (buffer, buf, pos);
+                       return buf;
                }
        }
 
@@ -1556,36 +1661,6 @@ namespace Mono.CSharp {
                        return result;
                }
 
-               public static void VerifyModulesClsCompliance (CompilerContext ctx)
-               {
-                       Module[] modules = GlobalRootNamespace.Instance.Modules;
-                       if (modules == null)
-                               return;
-
-                       // The first module is generated assembly
-                       for (int i = 1; i < modules.Length; ++i) {
-                               Module module = modules [i];
-                               if (!GetClsCompliantAttributeValue (module, null)) {
-                                       ctx.Report.Error (3013, "Added modules must be marked with the CLSCompliant attribute " +
-                                                     "to match the assembly", module.Name);
-                                       return;
-                               }
-                       }
-               }
-
-               static bool GetClsCompliantAttributeValue (ICustomAttributeProvider attribute_provider, Assembly a) 
-               {
-                       object[] cls_attr = attribute_provider.GetCustomAttributes (typeof (CLSCompliantAttribute), false);
-                       if (cls_attr.Length == 0) {
-                               if (a == null)
-                                       return false;
-
-                               return GetClsCompliantAttributeValue (a, null);
-                       }
-                       
-                       return ((CLSCompliantAttribute)cls_attr [0]).IsCompliant;
-               }
-
                /// <summary>
                /// Common method for Obsolete error/warning reporting.
                /// </summary>
@@ -1604,13 +1679,16 @@ namespace Mono.CSharp {
                }
        }
 
+       //
+       // Predefined attribute types
+       //
        public class PredefinedAttributes
        {
-               // Core types
+               // Build-in attributes
                public readonly PredefinedAttribute ParamArray;
                public readonly PredefinedAttribute Out;
 
-               // Optional types
+               // Optional attributes
                public readonly PredefinedAttribute Obsolete;
                public readonly PredefinedAttribute DllImport;
                public readonly PredefinedAttribute MethodImpl;
@@ -1626,11 +1704,13 @@ namespace Mono.CSharp {
                public readonly PredefinedAttribute AssemblyVersion;
                public readonly PredefinedAttribute AssemblyAlgorithmId;
                public readonly PredefinedAttribute AssemblyFlags;
+               public readonly PredefinedAttribute AssemblyFileVersion;
                public readonly PredefinedAttribute ComImport;
                public readonly PredefinedAttribute CoClass;
                public readonly PredefinedAttribute AttributeUsage;
                public readonly PredefinedAttribute DefaultParameterValue;
                public readonly PredefinedAttribute OptionalParameter;
+               public readonly PredefinedAttribute UnverifiableCode;
 
                // New in .NET 2.0
                public readonly PredefinedAttribute DefaultCharset;
@@ -1646,97 +1726,97 @@ namespace Mono.CSharp {
                public readonly PredefinedAttribute Extension;
 
                // New in .NET 4.0
-               public readonly PredefinedAttribute Dynamic;
-               public readonly PredefinedAttribute DynamicTransform;   // DynamicAttribute with transform arguments
+               public readonly PredefinedDynamicAttribute Dynamic;
 
                //
                // Optional types which are used as types and for member lookup
                //
                public readonly PredefinedAttribute DefaultMember;
-               public readonly PredefinedAttribute DecimalConstant;
+               public readonly PredefinedDecimalAttribute DecimalConstant;
                public readonly PredefinedAttribute StructLayout;
                public readonly PredefinedAttribute FieldOffset;
 
-               public static PredefinedAttributes Get = new PredefinedAttributes ();
-
-               private PredefinedAttributes ()
-               {
-                       ParamArray = new PredefinedAttribute ("System", "ParamArrayAttribute");
-                       Out = new PredefinedAttribute ("System.Runtime.InteropServices", "OutAttribute");
-
-                       Obsolete = new PredefinedAttribute ("System", "ObsoleteAttribute");
-                       DllImport = new PredefinedAttribute ("System.Runtime.InteropServices", "DllImportAttribute");
-                       MethodImpl = new PredefinedAttribute ("System.Runtime.CompilerServices", "MethodImplAttribute");
-                       MarshalAs = new PredefinedAttribute ("System.Runtime.InteropServices", "MarshalAsAttribute");
-                       In = new PredefinedAttribute ("System.Runtime.InteropServices", "InAttribute");
-                       IndexerName = new PredefinedAttribute ("System.Runtime.CompilerServices", "IndexerNameAttribute");
-                       Conditional = new PredefinedAttribute ("System.Diagnostics", "ConditionalAttribute");
-                       CLSCompliant = new PredefinedAttribute ("System", "CLSCompliantAttribute");
-                       Security = new PredefinedAttribute ("System.Security.Permissions", "SecurityAttribute");
-                       Required = new PredefinedAttribute ("System.Runtime.CompilerServices", "RequiredAttributeAttribute");
-                       Guid = new PredefinedAttribute ("System.Runtime.InteropServices", "GuidAttribute");
-                       AssemblyCulture = new PredefinedAttribute ("System.Reflection", "AssemblyCultureAttribute");
-                       AssemblyVersion = new PredefinedAttribute ("System.Reflection", "AssemblyVersionAttribute");
-                       AssemblyAlgorithmId = new PredefinedAttribute ("System.Reflection", "AssemblyAlgorithmIdAttribute");
-                       AssemblyFlags = new PredefinedAttribute ("System.Reflection", "AssemblyFlagsAttribute");
-                       ComImport = new PredefinedAttribute ("System.Runtime.InteropServices", "ComImportAttribute");
-                       CoClass = new PredefinedAttribute ("System.Runtime.InteropServices", "CoClassAttribute");
-                       AttributeUsage = new PredefinedAttribute ("System", "AttributeUsageAttribute");
-                       DefaultParameterValue = new PredefinedAttribute ("System.Runtime.InteropServices", "DefaultParameterValueAttribute");
-                       OptionalParameter = new PredefinedAttribute ("System.Runtime.InteropServices", "OptionalAttribute");
-
-                       DefaultCharset = new PredefinedAttribute ("System.Runtime.InteropServices", "DefaultCharSetAttribute");
-                       TypeForwarder = new PredefinedAttribute ("System.Runtime.CompilerServices", "TypeForwardedToAttribute");
-                       FixedBuffer = new PredefinedAttribute ("System.Runtime.CompilerServices", "FixedBufferAttribute");
-                       CompilerGenerated = new PredefinedAttribute ("System.Runtime.CompilerServices", "CompilerGeneratedAttribute");
-                       InternalsVisibleTo = new PredefinedAttribute ("System.Runtime.CompilerServices", "InternalsVisibleToAttribute");
-                       RuntimeCompatibility = new PredefinedAttribute ("System.Runtime.CompilerServices", "RuntimeCompatibilityAttribute");
-                       DebuggerHidden = new PredefinedAttribute ("System.Diagnostics", "DebuggerHiddenAttribute");
-                       UnsafeValueType = new PredefinedAttribute ("System.Runtime.CompilerServices", "UnsafeValueTypeAttribute");
-
-                       Extension = new PredefinedAttribute ("System.Runtime.CompilerServices", "ExtensionAttribute");
-
-                       Dynamic = new PredefinedAttribute ("System.Runtime.CompilerServices", "DynamicAttribute");
-                       DynamicTransform = new PredefinedAttribute ("System.Runtime.CompilerServices", "DynamicAttribute");
-
-                       DefaultMember = new PredefinedAttribute ("System.Reflection", "DefaultMemberAttribute");
-                       DecimalConstant = new PredefinedAttribute ("System.Runtime.CompilerServices", "DecimalConstantAttribute");
-                       StructLayout = new PredefinedAttribute ("System.Runtime.InteropServices", "StructLayoutAttribute");
-                       FieldOffset = new PredefinedAttribute ("System.Runtime.InteropServices", "FieldOffsetAttribute");
-               }
-
-               public void Initialize (CompilerContext ctx)
-               {
-                       foreach (FieldInfo fi in GetType ().GetFields (BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)) {
-                               ((PredefinedAttribute) fi.GetValue (this)).Initialize (ctx, true);
+               public PredefinedAttributes (ModuleContainer module)
+               {
+                       ParamArray = new PredefinedAttribute (module, "System", "ParamArrayAttribute");
+                       Out = new PredefinedAttribute (module, "System.Runtime.InteropServices", "OutAttribute");
+                       ParamArray.Resolve (Location.Null);
+                       Out.Resolve (Location.Null);
+
+                       Obsolete = new PredefinedAttribute (module, "System", "ObsoleteAttribute");
+                       DllImport = new PredefinedAttribute (module, "System.Runtime.InteropServices", "DllImportAttribute");
+                       MethodImpl = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "MethodImplAttribute");
+                       MarshalAs = new PredefinedAttribute (module, "System.Runtime.InteropServices", "MarshalAsAttribute");
+                       In = new PredefinedAttribute (module, "System.Runtime.InteropServices", "InAttribute");
+                       IndexerName = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "IndexerNameAttribute");
+                       Conditional = new PredefinedAttribute (module, "System.Diagnostics", "ConditionalAttribute");
+                       CLSCompliant = new PredefinedAttribute (module, "System", "CLSCompliantAttribute");
+                       Security = new PredefinedAttribute (module, "System.Security.Permissions", "SecurityAttribute");
+                       Required = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "RequiredAttributeAttribute");
+                       Guid = new PredefinedAttribute (module, "System.Runtime.InteropServices", "GuidAttribute");
+                       AssemblyCulture = new PredefinedAttribute (module, "System.Reflection", "AssemblyCultureAttribute");
+                       AssemblyVersion = new PredefinedAttribute (module, "System.Reflection", "AssemblyVersionAttribute");
+                       AssemblyAlgorithmId = new PredefinedAttribute (module, "System.Reflection", "AssemblyAlgorithmIdAttribute");
+                       AssemblyFlags = new PredefinedAttribute (module, "System.Reflection", "AssemblyFlagsAttribute");
+                       AssemblyFileVersion = new PredefinedAttribute (module, "System.Reflection", "AssemblyFileVersionAttribute");
+                       ComImport = new PredefinedAttribute (module, "System.Runtime.InteropServices", "ComImportAttribute");
+                       CoClass = new PredefinedAttribute (module, "System.Runtime.InteropServices", "CoClassAttribute");
+                       AttributeUsage = new PredefinedAttribute (module, "System", "AttributeUsageAttribute");
+                       DefaultParameterValue = new PredefinedAttribute (module, "System.Runtime.InteropServices", "DefaultParameterValueAttribute");
+                       OptionalParameter = new PredefinedAttribute (module, "System.Runtime.InteropServices", "OptionalAttribute");
+                       UnverifiableCode = new PredefinedAttribute (module, "System.Security", "UnverifiableCodeAttribute");
+
+                       DefaultCharset = new PredefinedAttribute (module, "System.Runtime.InteropServices", "DefaultCharSetAttribute");
+                       TypeForwarder = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "TypeForwardedToAttribute");
+                       FixedBuffer = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "FixedBufferAttribute");
+                       CompilerGenerated = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "CompilerGeneratedAttribute");
+                       InternalsVisibleTo = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "InternalsVisibleToAttribute");
+                       RuntimeCompatibility = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "RuntimeCompatibilityAttribute");
+                       DebuggerHidden = new PredefinedAttribute (module, "System.Diagnostics", "DebuggerHiddenAttribute");
+                       UnsafeValueType = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "UnsafeValueTypeAttribute");
+
+                       Extension = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "ExtensionAttribute");
+
+                       Dynamic = new PredefinedDynamicAttribute (module, "System.Runtime.CompilerServices", "DynamicAttribute");
+
+                       DefaultMember = new PredefinedAttribute (module, "System.Reflection", "DefaultMemberAttribute");
+                       DecimalConstant = new PredefinedDecimalAttribute (module, "System.Runtime.CompilerServices", "DecimalConstantAttribute");
+                       StructLayout = new PredefinedAttribute (module, "System.Runtime.InteropServices", "StructLayoutAttribute");
+                       FieldOffset = new PredefinedAttribute (module, "System.Runtime.InteropServices", "FieldOffsetAttribute");
+
+                       // TODO: Should define only attributes which are used for comparison
+                       const System.Reflection.BindingFlags all_fields = System.Reflection.BindingFlags.Public |
+                               System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.DeclaredOnly;
+
+                       foreach (var fi in GetType ().GetFields (all_fields)) {
+                               ((PredefinedAttribute) fi.GetValue (this)).Define ();
                        }
                }
-
-               public static void Reset ()
-               {
-                       Get = new PredefinedAttributes ();
-               }
        }
 
-       public class PredefinedAttribute
+       public class PredefinedAttribute : PredefinedType
        {
-               TypeSpec type;
-               CustomAttributeBuilder cab;
-               MethodSpec ctor;
-               readonly string ns, name;
-               CompilerContext compiler;
-
-               static readonly TypeSpec NotFound = InternalType.Null;
+               protected MethodSpec ctor;
+               List<PropertySpec> properties;
 
-               public PredefinedAttribute (string ns, string name)
+               public PredefinedAttribute (ModuleContainer module, string ns, string name)
+                       : base (module, MemberKind.Class, ns, name)
                {
-                       this.ns = ns;
-                       this.name = name;
                }
 
+               #region Properties
+
+               public MethodSpec Constructor {
+                       get {
+                               return ctor;
+                       }
+               }
+
+               #endregion
+
                public static bool operator == (TypeSpec type, PredefinedAttribute pa)
                {
-                       return type == pa.type;
+                       return type == pa.type && pa.type != null;
                }
 
                public static bool operator != (TypeSpec type, PredefinedAttribute pa)
@@ -1744,20 +1824,11 @@ namespace Mono.CSharp {
                        return type != pa.type;
                }
 
-               public ConstructorInfo Constructor {
-                       get { return ctor == null ? null : (ConstructorInfo) ctor.GetMetaInfo (); }
-               }
-
                public override int GetHashCode ()
                {
                        return base.GetHashCode ();
                }
 
-               public string GetSignatureForError ()
-               {
-                       return ns + "." + name;
-               }
-
                public override bool Equals (object obj)
                {
                        throw new NotSupportedException ();
@@ -1766,90 +1837,109 @@ namespace Mono.CSharp {
                public void EmitAttribute (ConstructorBuilder builder)
                {
                        if (ResolveBuilder ())
-                               builder.SetCustomAttribute (cab);
+                               builder.SetCustomAttribute (GetCtorMetaInfo (), AttributeEncoder.Empty);
                }
 
                public void EmitAttribute (MethodBuilder builder)
                {
                        if (ResolveBuilder ())
-                               builder.SetCustomAttribute (cab);
+                               builder.SetCustomAttribute (GetCtorMetaInfo (), AttributeEncoder.Empty);
                }
 
                public void EmitAttribute (PropertyBuilder builder)
                {
                        if (ResolveBuilder ())
-                               builder.SetCustomAttribute (cab);
+                               builder.SetCustomAttribute (GetCtorMetaInfo (), AttributeEncoder.Empty);
                }
 
                public void EmitAttribute (FieldBuilder builder)
                {
                        if (ResolveBuilder ())
-                               builder.SetCustomAttribute (cab);
+                               builder.SetCustomAttribute (GetCtorMetaInfo (), AttributeEncoder.Empty);
+               }
+
+               public void EmitAttribute (FieldBuilder builder, AttributeEncoder argsEncoded)
+               {
+                       builder.SetCustomAttribute (GetCtorMetaInfo (), argsEncoded.ToArray ());
                }
 
                public void EmitAttribute (TypeBuilder builder)
                {
                        if (ResolveBuilder ())
-                               builder.SetCustomAttribute (cab);
+                               builder.SetCustomAttribute (GetCtorMetaInfo (), AttributeEncoder.Empty);
+               }
+
+               public void EmitAttribute (TypeBuilder builder, AttributeEncoder argsEncoded)
+               {
+                       builder.SetCustomAttribute (GetCtorMetaInfo (), argsEncoded.ToArray ());
                }
 
                public void EmitAttribute (AssemblyBuilder builder)
                {
                        if (ResolveBuilder ())
-                               builder.SetCustomAttribute (cab);
+                               builder.SetCustomAttribute (GetCtorMetaInfo (), AttributeEncoder.Empty);
+               }
+
+               public void EmitAttribute (ModuleBuilder builder)
+               {
+                       if (ResolveBuilder ())
+                               builder.SetCustomAttribute (GetCtorMetaInfo (), AttributeEncoder.Empty);
                }
 
                public void EmitAttribute (ParameterBuilder builder)
                {
                        if (ResolveBuilder ())
-                               builder.SetCustomAttribute (cab);
+                               builder.SetCustomAttribute (GetCtorMetaInfo (), AttributeEncoder.Empty);
                }
 
-               public bool IsDefined {
-                       get { return type != null && type != NotFound; }
+               public void EmitAttribute (ParameterBuilder builder, AttributeEncoder argsEncoded)
+               {
+                       builder.SetCustomAttribute (GetCtorMetaInfo (), argsEncoded.ToArray ());
                }
 
-               public void Initialize (CompilerContext ctx, bool canFail)
+               ConstructorInfo GetCtorMetaInfo ()
                {
-                       this.compiler = ctx;
-                       Resolve (canFail);
+                       return (ConstructorInfo) ctor.GetMetaInfo ();
                }
 
-               public bool Resolve (bool canFail)
+               public PropertySpec GetProperty (string name, TypeSpec memberType, Location loc)
                {
-                       if (type != null) {
-                               if (IsDefined)
-                                       return true;
-                               if (canFail)
-                                       return false;
+                       PropertySpec spec;
+
+                       if (properties != null) {
+                               spec = properties.Find (l => l.Name == name);
+                       } else {
+                               spec = null;
                        }
 
-                       type = TypeManager.CoreLookupType (compiler, ns, name, MemberKind.Class, !canFail);
-                       if (type == null) {
-                               type = NotFound;
-                               return false;
+                       if (spec == null) {
+                               spec = TypeManager.GetPredefinedProperty (type, name, loc, memberType);
+
+                               if (spec != null) {
+                                       if (properties == null) {
+                                               properties = new List<PropertySpec> ();
+                                       }
+
+                                       properties.Add (spec);
+                               }
                        }
 
-                       return true;
+                       return spec;
                }
 
-               bool ResolveBuilder ()
+               public bool ResolveBuilder ()
                {
-                       if (cab != null)
+                       if (ctor != null)
                                return true;
 
                        //
                        // Handle all parameter-less attributes as optional
                        //
-                       if (!Resolve (true))
-                               return false;
-
-                       var ci = TypeManager.GetPredefinedConstructor (type, Location.Null, TypeSpec.EmptyTypes);
-                       if (ci == null)
+                       if (!IsDefined)
                                return false;
 
-                       cab = new CustomAttributeBuilder ((ConstructorInfo) ci.GetMetaInfo (), new object[0]);
-                       return true;
+                       ctor = TypeManager.GetPredefinedConstructor (type, Location.Null, TypeSpec.EmptyTypes);
+                       return ctor != null;
                }
 
                public bool ResolveConstructor (Location loc, params TypeSpec[] argType)
@@ -1857,15 +1947,172 @@ namespace Mono.CSharp {
                        if (ctor != null)
                                throw new InternalErrorException ("Predefined ctor redefined");
 
-                       if (!Resolve (false))
+                       if (Resolve (loc) == null)
                                return false;
 
                        ctor = TypeManager.GetPredefinedConstructor (type, loc, argType);
                        return ctor != null;
                }
+       }
+
+       public class PredefinedDecimalAttribute : PredefinedAttribute
+       {
+               public PredefinedDecimalAttribute (ModuleContainer module, string ns, string name)
+                       : base (module, ns, name)
+               {
+               }
+
+               public void EmitAttribute (ParameterBuilder builder, decimal value, Location loc)
+               {
+                       if (Resolve (loc) == null)
+                               return;
+
+                       if (ctor == null && !ResolveConstructor (loc, TypeManager.byte_type, TypeManager.byte_type, TypeManager.uint32_type, TypeManager.uint32_type, TypeManager.uint32_type))
+                               return;
+
+                       int[] bits = decimal.GetBits (value);
+                       AttributeEncoder encoder = new AttributeEncoder ();
+                       encoder.Encode ((byte) (bits[3] >> 16));
+                       encoder.Encode ((byte) (bits[3] >> 31));
+                       encoder.Encode ((uint) bits[2]);
+                       encoder.Encode ((uint) bits[1]);
+                       encoder.Encode ((uint) bits[0]);
+                       encoder.EncodeEmptyNamedArguments ();
+
+                       EmitAttribute (builder, encoder);
+               }
+
+               public void EmitAttribute (FieldBuilder builder, decimal value, Location loc)
+               {
+                       if (Resolve (loc) == null)
+                               return;
+
+                       if (ctor == null && !ResolveConstructor (loc, TypeManager.byte_type, TypeManager.byte_type, TypeManager.uint32_type, TypeManager.uint32_type, TypeManager.uint32_type))
+                               return;
+
+                       int[] bits = decimal.GetBits (value);
+                       AttributeEncoder encoder = new AttributeEncoder ();
+                       encoder.Encode ((byte) (bits[3] >> 16));
+                       encoder.Encode ((byte) (bits[3] >> 31));
+                       encoder.Encode ((uint) bits[2]);
+                       encoder.Encode ((uint) bits[1]);
+                       encoder.Encode ((uint) bits[0]);
+                       encoder.EncodeEmptyNamedArguments ();
+
+                       EmitAttribute (builder, encoder);
+               }
+       }
+
+       public class PredefinedDynamicAttribute : PredefinedAttribute
+       {
+               MethodSpec tctor;
+
+               public PredefinedDynamicAttribute (ModuleContainer module, string ns, string name)
+                       : base (module, ns, name)
+               {
+               }
+
+               public void EmitAttribute (FieldBuilder builder, TypeSpec type, Location loc)
+               {
+                       if (ResolveTransformationCtor (loc)) {
+                               var cab = new CustomAttributeBuilder ((ConstructorInfo) tctor.GetMetaInfo (), new object[] { GetTransformationFlags (type) });
+                               builder.SetCustomAttribute (cab);
+                       }
+               }
+
+               public void EmitAttribute (ParameterBuilder builder, TypeSpec type, Location loc)
+               {
+                       if (ResolveTransformationCtor (loc)) {
+                               var cab = new CustomAttributeBuilder ((ConstructorInfo) tctor.GetMetaInfo (), new object[] { GetTransformationFlags (type) });
+                               builder.SetCustomAttribute (cab);
+                       }
+               }
+
+               public void EmitAttribute (PropertyBuilder builder, TypeSpec type, Location loc)
+               {
+                       if (ResolveTransformationCtor (loc)) {
+                               var cab = new CustomAttributeBuilder ((ConstructorInfo) tctor.GetMetaInfo (), new object[] { GetTransformationFlags (type) });
+                               builder.SetCustomAttribute (cab);
+                       }
+               }
+
+               public void EmitAttribute (TypeBuilder builder, TypeSpec type, Location loc)
+               {
+                       if (ResolveTransformationCtor (loc)) {
+                               var cab = new CustomAttributeBuilder ((ConstructorInfo) tctor.GetMetaInfo (), new object[] { GetTransformationFlags (type) });
+                               builder.SetCustomAttribute (cab);
+                       }
+               }
+
+               //
+               // When any element of the type is a dynamic type
+               //
+               // This method builds a transformation array for dynamic types
+               // used in places where DynamicAttribute cannot be applied to.
+               // It uses bool flag when type is of dynamic type and each
+               // section always starts with "false" for some reason.
+               //
+               // LAMESPEC: This should be part of C# specification
+               // 
+               // Example: Func<dynamic, int, dynamic[]>
+               // Transformation: { false, true, false, false, true }
+               //
+               static bool[] GetTransformationFlags (TypeSpec t)
+               {
+                       bool[] element;
+                       var ac = t as ArrayContainer;
+                       if (ac != null) {
+                               element = GetTransformationFlags (ac.Element);
+                               if (element == null)
+                                       return null;
+
+                               bool[] res = new bool[element.Length + 1];
+                               res[0] = false;
+                               Array.Copy (element, 0, res, 1, element.Length);
+                               return res;
+                       }
+
+                       if (t == null)
+                               return null;
+
+                       if (t.IsGeneric) {
+                               List<bool> transform = null;
+                               var targs = t.TypeArguments;
+                               for (int i = 0; i < targs.Length; ++i) {
+                                       element = GetTransformationFlags (targs[i]);
+                                       if (element != null) {
+                                               if (transform == null) {
+                                                       transform = new List<bool> ();
+                                                       for (int ii = 0; ii <= i; ++ii)
+                                                               transform.Add (false);
+                                               }
+
+                                               transform.AddRange (element);
+                                       } else if (transform != null) {
+                                               transform.Add (false);
+                                       }
+                               }
+
+                               if (transform != null)
+                                       return transform.ToArray ();
+                       }
+
+                       if (t == InternalType.Dynamic)
+                               return new bool[] { true };
+
+                       return null;
+               }
+
+               bool ResolveTransformationCtor (Location loc)
+               {
+                       if (tctor != null)
+                               return true;
+
+                       if (Resolve (loc) == null)
+                               return false;
 
-               public TypeSpec Type {
-                       get { return type; }
+                       tctor = TypeManager.GetPredefinedConstructor (type, Location.Null, ArrayContainer.MakeType (TypeManager.bool_type));
+                       return tctor != null;
                }
        }
 }