Add more incomplete statements to AST. Fixes #4361.
[mono.git] / mcs / mcs / attribute.cs
index caaad5513bbc523c2d85925cb0c82a09cd5471b4..ae9627e93be4b709c507235b19a347622c154bc1 100644 (file)
@@ -8,13 +8,11 @@
 //
 // Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
 // Copyright 2003-2008 Novell, Inc.
+// Copyright 2011 Xamarin Inc
 //
 
 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 +20,18 @@ using System.Security.Permissions;
 using System.Text;
 using System.IO;
 
+#if STATIC
+using SecurityType = System.Collections.Generic.List<IKVM.Reflection.Emit.CustomAttributeBuilder>;
+using BadImageFormat = IKVM.Reflection.BadImageFormatException;
+using IKVM.Reflection;
+using IKVM.Reflection.Emit;
+#else
+using SecurityType = System.Collections.Generic.Dictionary<System.Security.Permissions.SecurityAction, System.Security.PermissionSet>;
+using BadImageFormat = System.BadImageFormatException;
+using System.Reflection;
+using System.Reflection.Emit;
+#endif
+
 namespace Mono.CSharp {
 
        /// <summary>
@@ -41,9 +51,9 @@ namespace Mono.CSharp {
                        if (attributes == null)
                                attributes = attrs;
                        else
-                               throw new NotImplementedException ();
+                               attributes.AddAttributes (attrs.Attrs);
 
-                       attributes.AttachTo (this, context);
+                       attrs.AttachTo (this, context);
                }
 
                public Attributes OptAttributes {
@@ -58,7 +68,7 @@ namespace Mono.CSharp {
                /// <summary>
                /// Use member-specific procedure to apply attribute @a in @cb to the entity being built in @builder
                /// </summary>
-               public abstract void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa);
+               public abstract void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa);
 
                /// <summary>
                /// Returns one AttributeTarget for this element.
@@ -74,22 +84,24 @@ namespace Mono.CSharp {
                public abstract string[] ValidAttributeTargets { get; }
        };
 
-       public class Attribute : Expression
+       public class Attribute
        {
                public readonly string ExplicitTarget;
                public AttributeTargets Target;
                readonly ATypeNameExpression expression;
 
-               Arguments PosArguments;
-               Arguments NamedArguments;
+               Arguments pos_args, named_args;
 
                bool resolve_error;
+               bool arg_resolved;
                readonly bool nameEscaped;
+               readonly Location loc;
+               public TypeSpec Type;   
 
                //
                // An attribute can be attached to multiple targets (e.g. multiple fields)
                //
-               protected Attributable[] targets;
+               Attributable[] targets;
 
                //
                // A member context for the attribute, it's much easier to hold it here
@@ -97,50 +109,74 @@ namespace Mono.CSharp {
                //
                IMemberContext context;
 
-               static readonly AttributeUsageAttribute DefaultUsageAttribute = new AttributeUsageAttribute (AttributeTargets.All);
-               static Assembly orig_sec_assembly;
+               public static readonly AttributeUsageAttribute DefaultUsageAttribute = new AttributeUsageAttribute (AttributeTargets.All);
                public static readonly object[] EmptyObject = new object [0];
 
-               // non-null if named args present after Resolve () is called
-               PropertyInfo [] prop_info_arr;
-               FieldInfo [] field_info_arr;
-               object [] field_values_arr;
-               object [] prop_values_arr;
-               object [] pos_values;
-
-               static Dictionary<Type, AttributeUsageAttribute> usage_attr_cache;
-               // Cache for parameter-less attributes
-               static Dictionary<Type, CustomAttributeBuilder> att_cache;
+               List<KeyValuePair<MemberExpr, NamedArgument>> named_values;
 
                public Attribute (string target, ATypeNameExpression expr, Arguments[] args, Location loc, bool nameEscaped)
                {
                        this.expression = expr;
                        if (args != null) {
-                               PosArguments = args [0];
-                               NamedArguments = args [1];                              
+                               pos_args = args[0];
+                               named_args = args[1];
                        }
                        this.loc = loc;
                        ExplicitTarget = target;
                        this.nameEscaped = nameEscaped;
                }
 
-               public Attribute Clone ()
-               {
-                       Attribute a = new Attribute (ExplicitTarget, expression, null, loc, nameEscaped);
-                       a.PosArguments = PosArguments;
-                       a.NamedArguments = NamedArguments;
-                       return a;
+               public Location Location {
+                       get {
+                               return loc;
+                       }
+               }
+
+               public Arguments NamedArguments {
+                       get {
+                               return named_args;
+                       }
+               }
+
+               public Arguments PositionalArguments {
+                       get {
+                               return pos_args;
+                       }
+               }
+
+               public ATypeNameExpression TypeExpression {
+                       get {
+                               return expression;
+                       }
                }
 
-               static Attribute ()
+               void AddModuleCharSet (ResolveContext rc)
                {
-                       Reset ();
+                       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.Define ()) {
+                               return;
+                       }
+
+                       if (NamedArguments == null)
+                               named_args = new Arguments (1);
+
+                       var value = Constant.CreateConstant (rc.Module.PredefinedTypes.CharSet.TypeSpec, rc.Module.DefaultCharSet, Location);
+                       NamedArguments.Add (new NamedArgument (dll_import_char_set, loc, value));
                }
 
-               public static void Reset ()
+               public Attribute Clone ()
                {
-                       usage_attr_cache = new Dictionary<Type, AttributeUsageAttribute> (ReferenceEquality<Type>.Default);
-                       att_cache = new Dictionary<Type, CustomAttributeBuilder> (ReferenceEquality<Type>.Default);
+                       Attribute a = new Attribute (ExplicitTarget, expression, null, loc, nameEscaped);
+                       a.pos_args = pos_args;
+                       a.named_args = NamedArguments;
+                       return a;
                }
 
                //
@@ -148,7 +184,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 };
@@ -156,6 +192,13 @@ namespace Mono.CSharp {
                                return;
                        }
 
+                       // When re-attaching global attributes
+                       if (context is NamespaceContainer) {
+                               this.targets[0] = target;
+                               this.context = context;
+                               return;
+                       }
+
                        // Resize target array
                        Attributable[] new_array = new Attributable [this.targets.Length + 1];
                        targets.CopyTo (new_array, 0);
@@ -169,6 +212,11 @@ namespace Mono.CSharp {
                        target.OptAttributes = null;
                }
 
+               public ResolveContext CreateResolveContext ()
+               {
+                       return new ResolveContext (context, ResolveContext.Options.ConstantScope);
+               }
+
                static void Error_InvalidNamedArgument (ResolveContext rc, NamedArgument name)
                {
                        rc.Report.Error (617, name.Location, "`{0}' is not a valid named attribute argument. Named attribute arguments " +
@@ -184,11 +232,9 @@ namespace Mono.CSharp {
                                name.Name);
                }
 
-               public static void Error_AttributeArgumentNotValid (ResolveContext rc, Location loc)
+               public static void Error_AttributeArgumentIsDynamic (IMemberContext context, Location loc)
                {
-                       rc.Report.Error (182, loc,
-                                     "An attribute argument must be a constant expression, typeof " +
-                                     "expression or array creation expression");
+                       context.Module.Compiler.Report.Error (1982, loc, "An attribute argument cannot be dynamic expression");
                }
                
                public void Error_MissingGuidAttribute ()
@@ -227,42 +273,28 @@ namespace Mono.CSharp {
                        }
                }
 
-               protected virtual TypeExpr ResolveAsTypeTerminal (Expression expr, IMemberContext ec)
-               {
-                       return expr.ResolveAsTypeTerminal (ec, false);
-               }
-
-               Type ResolvePossibleAttributeType (ATypeNameExpression expr, ref bool is_attr)
-               {
-                       TypeExpr te = ResolveAsTypeTerminal (expr, context);
-                       if (te == null)
-                               return null;
-
-                       Type t = te.Type;
-                       if (TypeManager.IsSubclassOf (t, TypeManager.attribute_type)) {
-                               is_attr = true;
-                       } else {
-                               Report.SymbolRelatedToPreviousError (t);
-                               Report.Error (616, Location, "`{0}': is not an attribute class", TypeManager.CSharpName (t));
-                       }
-                       return t;
-               }
-
                /// <summary>
                ///   Tries to resolve the type of the attribute. Flags an error if it can't, and complain is true.
                /// </summary>
                void ResolveAttributeType ()
                {
                        SessionReportPrinter resolve_printer = new SessionReportPrinter ();
-                       ReportPrinter prev_recorder = context.Compiler.Report.SetPrinter (resolve_printer);
+                       ReportPrinter prev_recorder = Report.SetPrinter (resolve_printer);
 
                        bool t1_is_attr = false;
                        bool t2_is_attr = false;
-                       Type t1, t2;
+                       TypeSpec t1, t2;
                        ATypeNameExpression expanded = null;
 
+                       // TODO: Additional warnings such as CS0436 are swallowed because we don't
+                       // print on success
+
                        try {
-                               t1 = ResolvePossibleAttributeType (expression, ref t1_is_attr);
+                               t1 = expression.ResolveAsType (context);
+                               if (t1 != null)
+                                       t1_is_attr = t1.IsAttribute;
+
+                               resolve_printer.EndSession ();
 
                                if (nameEscaped) {
                                        t2 = null;
@@ -270,15 +302,15 @@ namespace Mono.CSharp {
                                        expanded = (ATypeNameExpression) expression.Clone (null);
                                        expanded.Name += "Attribute";
 
-                                       t2 = ResolvePossibleAttributeType (expanded, ref t2_is_attr);
+                                       t2 = expanded.ResolveAsType (context);
+                                       if (t2 != null)
+                                               t2_is_attr = t2.IsAttribute;
                                }
-
-                               resolve_printer.EndSession ();
                        } finally {
-                               context.Compiler.Report.SetPrinter (prev_recorder);
+                               context.Module.Compiler.Report.SetPrinter (prev_recorder);
                        }
 
-                       if (t1_is_attr && t2_is_attr) {
+                       if (t1_is_attr && t2_is_attr && t1 != t2) {
                                Report.Error (1614, Location, "`{0}' is ambiguous between `{1}' and `{2}'. Use either `@{0}' or `{0}Attribute'",
                                        GetSignatureForError (), expression.GetSignatureForError (), expanded.GetSignatureForError ());
                                resolve_error = true;
@@ -295,18 +327,33 @@ namespace Mono.CSharp {
                                return;
                        }
 
-                       resolve_printer.Merge (prev_recorder);
                        resolve_error = true;
+
+                       if (t1 != null) {
+                               resolve_printer.Merge (prev_recorder);
+
+                               Report.SymbolRelatedToPreviousError (t1);
+                               Report.Error (616, Location, "`{0}': is not an attribute class", t1.GetSignatureForError ());
+                               return;
+                       }
+
+                       if (t2 != null) {
+                               Report.SymbolRelatedToPreviousError (t2);
+                               Report.Error (616, Location, "`{0}': is not an attribute class", t2.GetSignatureForError ());
+                               return;
+                       }
+
+                       resolve_printer.Merge (prev_recorder);
                }
 
-               public virtual Type ResolveType ()
+               public TypeSpec ResolveType ()
                {
                        if (Type == null && !resolve_error)
                                ResolveAttributeType ();
                        return Type;
                }
 
-               public override string GetSignatureForError ()
+               public string GetSignatureForError ()
                {
                        if (Type != null)
                                return TypeManager.CSharpName (Type);
@@ -316,26 +363,48 @@ namespace Mono.CSharp {
 
                public bool HasSecurityAttribute {
                        get {
-                               PredefinedAttribute pa = PredefinedAttributes.Get.Security;
-                               return pa.IsDefined && TypeManager.IsSubclassOf (type, pa.Type);
+                               PredefinedAttribute pa = context.Module.PredefinedAttributes.Security;
+                               return pa.IsDefined && TypeSpec.IsBaseClass (Type, pa.TypeSpec, false);
                        }
                }
 
                public bool IsValidSecurityAttribute ()
                {
-                       return HasSecurityAttribute && IsSecurityActionValid (false);
+                       return HasSecurityAttribute && IsSecurityActionValid ();
                }
 
-               static bool IsValidArgumentType (Type t)
+               static bool IsValidArgumentType (TypeSpec t)
                {
-                       if (t.IsArray)
-                               t = TypeManager.GetElementType (t);
+                       if (t.IsArray) {
+                               var ac = (ArrayContainer) t;
+                               if (ac.Rank > 1)
+                                       return false;
+
+                               t = ac.Element;
+                       }
+
+                       switch (t.BuiltinType) {
+                       case BuiltinTypeSpec.Type.Int:
+                       case BuiltinTypeSpec.Type.UInt:
+                       case BuiltinTypeSpec.Type.Long:
+                       case BuiltinTypeSpec.Type.ULong:
+                       case BuiltinTypeSpec.Type.Float:
+                       case BuiltinTypeSpec.Type.Double:
+                       case BuiltinTypeSpec.Type.Char:
+                       case BuiltinTypeSpec.Type.Short:
+                       case BuiltinTypeSpec.Type.Bool:
+                       case BuiltinTypeSpec.Type.SByte:
+                       case BuiltinTypeSpec.Type.Byte:
+                       case BuiltinTypeSpec.Type.UShort:
+
+                       case BuiltinTypeSpec.Type.String:
+                       case BuiltinTypeSpec.Type.Object:
+                       case BuiltinTypeSpec.Type.Dynamic:
+                       case BuiltinTypeSpec.Type.Type:
+                               return true;
+                       }
 
-                       return t == TypeManager.string_type ||
-                               TypeManager.IsPrimitiveType (t) ||
-                               TypeManager.IsEnumType (t) ||
-                               t == TypeManager.object_type ||
-                               t == TypeManager.type_type;
+                       return t.IsEnum;
                }
 
                // TODO: Don't use this ambiguous value
@@ -343,38 +412,17 @@ 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;
-                               }
-                       }
-                       
-                       NamedArguments.Add (new NamedArgument (CharSetEnumMember, loc,
-                               Constant.CreateConstant (rc, typeof (CharSet), RootContext.ToplevelTypes.DefaultCharSet, Location)));
-               }
-
                public Report Report {
-                       get { return context.Compiler.Report; }
+                       get { return context.Module.Compiler.Report; }
                }
 
-               public CustomAttributeBuilder Resolve ()
+               public MethodSpec Resolve ()
                {
                        if (resolve_error)
                                return null;
 
                        resolve_error = true;
+                       arg_resolved = true;
 
                        if (Type == null) {
                                ResolveAttributeType ();
@@ -387,144 +435,69 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       ObsoleteAttribute obsolete_attr = AttributeTester.GetObsoleteAttribute (Type);
+                       ObsoleteAttribute obsolete_attr = Type.GetAttributeObsolete ();
                        if (obsolete_attr != null) {
                                AttributeTester.Report_ObsoleteMessage (obsolete_attr, TypeManager.CSharpName (Type), Location, Report);
                        }
 
-                       CustomAttributeBuilder cb;
-                       if (PosArguments == null && NamedArguments == null) {
-                               if (att_cache.TryGetValue (Type, out cb)) {
-                                       resolve_error = false;
-                                       return cb;
-                               }
-                       }
-
-                       ResolveContext rc = new ResolveContext (context, ResolveContext.Options.ConstantScope);
-                       var ctor = ResolveConstructor (rc);
-                       if (ctor == null) {
-                               if (Type is TypeBuilder && 
-                                   TypeManager.LookupDeclSpace (Type).MemberCache == null)
-                                       // The attribute type has been DefineType'd, but not Defined.  Let's not treat it as an error.
-                                       // It'll be resolved again when the attached-to entity is emitted.
-                                       resolve_error = false;
-                               return null;
-                       }
-
-                       ApplyModuleCharSet (rc);
-
-                       try {
-                               var ctor_meta = (ConstructorInfo) ctor.MetaInfo;
-                               // SRE does not allow private ctor but we want to report all source code errors
-                               if (ctor.MetaInfo.IsPrivate)
-                                       return null;
-
-                               if (NamedArguments == null) {
-                                       cb = new CustomAttributeBuilder (ctor_meta, pos_values);
-
-                                       if (pos_values.Length == 0)
-                                               att_cache.Add (Type, cb);
-
-                                       resolve_error = false;
-                                       return cb;
-                               }
+                       ResolveContext rc = null;
 
-                               if (!ResolveNamedArguments (rc)) {
+                       MethodSpec ctor;
+                       // Try if the attribute is simple and has been resolved before
+                       if (pos_args != null || !context.Module.AttributeConstructorCache.TryGetValue (Type, out ctor)) {
+                               rc = CreateResolveContext ();
+                               ctor = ResolveConstructor (rc);
+                               if (ctor == null) {
                                        return null;
                                }
 
-                               cb = new CustomAttributeBuilder (ctor_meta, pos_values,
-                                               prop_info_arr, prop_values_arr,
-                                               field_info_arr, field_values_arr);
-
-                               resolve_error = false;
-                               return cb;
-                       }
-                       catch (Exception) {
-                               Error_AttributeArgumentNotValid (rc, Location);
-                               return null;
-                       }
-               }
-
-               protected virtual MethodSpec ResolveConstructor (ResolveContext ec)
-               {
-                       if (PosArguments != null) {
-                               bool dynamic;
-                               PosArguments.Resolve (ec, out dynamic);
-                               if (dynamic) {
-                                       Error_AttributeArgumentNotValid (ec, loc);
-                                       return null;
-                               }
+                               if (pos_args == null && ctor.Parameters.IsEmpty)
+                                       context.Module.AttributeConstructorCache.Add (Type, ctor);
                        }
 
-                       MethodGroupExpr mg = MemberLookupFinal (ec, ec.CurrentType,
-                               Type, ConstructorInfo.ConstructorName, MemberTypes.Constructor,
-                               BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
-                               Location) as MethodGroupExpr;
-
-                       if (mg == null)
-                               throw new NotImplementedException ();
+                       //
+                       // Add [module: DefaultCharSet] to all DllImport import attributes
+                       //
+                       var module = context.Module;
+                       if ((Type == module.PredefinedAttributes.DllImport || Type == module.PredefinedAttributes.UnmanagedFunctionPointer) && module.HasDefaultCharSet) {
+                               if (rc == null)
+                                       rc = CreateResolveContext ();
 
-                       mg = mg.OverloadResolve (ec, ref PosArguments, false, Location);
-                       if (mg == null)
-                               return null;
-                       
-                       var constructor = (MethodSpec) mg;
-                       if (PosArguments == null) {
-                               pos_values = EmptyObject;
-                               return constructor;
+                               AddModuleCharSet (rc);
                        }
 
-                       if (!PosArguments.GetAttributableValue (ec, out pos_values))
-                               return null;
+                       if (NamedArguments != null) {
+                               if (rc == null)
+                                       rc = CreateResolveContext ();
 
-                       // Here we do the checks which should be done by corlib or by runtime.
-                       // However Zoltan doesn't like it and every Mono compiler has to do it again.
-                       PredefinedAttributes pa = PredefinedAttributes.Get;
-                       if (Type == pa.Guid) {
-                               try {
-                                       new Guid ((string)pos_values [0]);
-                               }
-                               catch (Exception e) {
-                                       Error_AttributeEmitError (e.Message);
+                               if (!ResolveNamedArguments (rc))
                                        return null;
-                               }
                        }
 
-                       if (Type == pa.AttributeUsage && (int)pos_values [0] == 0) {
-                               ec.Report.Error (591, Location, "Invalid value for argument to `System.AttributeUsage' attribute");
-                               return null;
-                       }
+                       resolve_error = false;
+                       return ctor;
+               }
 
-                       if (Type == pa.IndexerName || Type == pa.Conditional) {
-                               string v = pos_values [0] as string;
-                               if (!Tokenizer.IsValidIdentifier (v) || Tokenizer.IsKeyword (v)) {
-                                       ec.Report.Error (633, PosArguments [0].Expr.Location,
-                                               "The argument to the `{0}' attribute must be a valid identifier", GetSignatureForError ());
+               MethodSpec ResolveConstructor (ResolveContext ec)
+               {
+                       if (pos_args != null) {
+                               bool dynamic;
+                               pos_args.Resolve (ec, out dynamic);
+                               if (dynamic) {
+                                       Error_AttributeArgumentIsDynamic (ec.MemberContext, loc);
                                        return null;
                                }
                        }
 
-                       if (Type == pa.MethodImpl && pos_values.Length == 1 &&
-                               constructor.Parameters.Types [0] == TypeManager.short_type &&
-                               !System.Enum.IsDefined (typeof (MethodImplOptions), pos_values [0].ToString ())) {
-                               Error_AttributeEmitError ("Incorrect argument value.");
-                               return null;
-                       }
-
-                       return constructor;
+                       return Expression.ConstructorLookup (ec, Type, ref pos_args, loc);
                }
 
-               protected virtual bool ResolveNamedArguments (ResolveContext ec)
+               bool ResolveNamedArguments (ResolveContext ec)
                {
                        int named_arg_count = NamedArguments.Count;
-
-                       var field_infos = new List<FieldInfo> (named_arg_count);
-                       var prop_infos  = new List<PropertyInfo> (named_arg_count);
-                       var field_values = new List<object> (named_arg_count);
-                       var prop_values = new List<object> (named_arg_count);
-
                        var seen_names = new List<string> (named_arg_count);
+
+                       named_values = new List<KeyValuePair<MemberExpr, NamedArgument>> (named_arg_count);
                        
                        foreach (NamedArgument a in NamedArguments) {
                                string name = a.Name;
@@ -537,20 +510,14 @@ namespace Mono.CSharp {
 
                                a.Resolve (ec);
 
-                               Expression member = Expression.MemberLookup (ec.Compiler,
-                                       ec.CurrentType, Type, name,
-                                       MemberTypes.All,
-                                       BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static,
-                                       Location);
+                               Expression member = Expression.MemberLookup (ec, false, Type, name, 0, Expression.MemberLookupRestrictions.ExactArity, loc);
 
                                if (member == null) {
-                                       member = Expression.MemberLookup (ec.Compiler, ec.CurrentType, Type, name,
-                                               MemberTypes.All, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static,
-                                               Location);
+                                       member = Expression.MemberLookup (ec, true, Type, name, 0, Expression.MemberLookupRestrictions.ExactArity, loc);
 
                                        if (member != null) {
-                                               ec.Report.SymbolRelatedToPreviousError (member.Type);
-                                               Expression.ErrorIsInaccesible (Location, member.GetSignatureForError (), ec.Report);
+                                               // TODO: ec.Report.SymbolRelatedToPreviousError (member);
+                                               Expression.ErrorIsInaccesible (ec, member.GetSignatureForError (), loc);
                                                return false;
                                        }
                                }
@@ -568,9 +535,9 @@ namespace Mono.CSharp {
                                ObsoleteAttribute obsolete_attr;
 
                                if (member is PropertyExpr) {
-                                       PropertyInfo pi = ((PropertyExpr) member).PropertyInfo;
+                                       var pi = ((PropertyExpr) member).PropertyInfo;
 
-                                       if (!pi.CanWrite || !pi.CanRead || pi.GetGetMethod ().IsStatic) {
+                                       if (!pi.HasSet || !pi.HasGet || pi.IsStatic || !pi.Get.IsPublic || !pi.Set.IsPublic) {
                                                ec.Report.SymbolRelatedToPreviousError (pi);
                                                Error_InvalidNamedArgument (ec, a);
                                                return false;
@@ -582,61 +549,36 @@ namespace Mono.CSharp {
                                                return false;
                                        }
 
-                                       object value;
-                                       if (!a.Expr.GetAttributableValue (ec, member.Type, out value))
-                                               return false;
-
-                                       PropertyBase pb = TypeManager.GetProperty (pi);
-                                       if (pb != null)
-                                               obsolete_attr = pb.GetObsoleteAttribute ();
-                                       else
-                                               obsolete_attr = AttributeTester.GetMemberObsoleteAttribute (pi);
-
-                                       prop_values.Add (value);
-                                       prop_infos.Add (pi);
-                                       
+                                       obsolete_attr = pi.GetAttributeObsolete ();
+                                       pi.MemberDefinition.SetIsAssigned ();
                                } else {
                                        var fi = ((FieldExpr) member).Spec;
 
-                                       if (fi.IsReadOnly || fi.IsStatic) {
+                                       if (fi.IsReadOnly || fi.IsStatic || !fi.IsPublic) {
                                                Error_InvalidNamedArgument (ec, a);
                                                return false;
                                        }
 
                                        if (!IsValidArgumentType (member.Type)) {
-                                               ec.Report.SymbolRelatedToPreviousError (fi.MetaInfo);
+                                               ec.Report.SymbolRelatedToPreviousError (fi);
                                                Error_InvalidNamedArgumentType (ec, a);
                                                return false;
                                        }
 
-                                       object value;
-                                       if (!a.Expr.GetAttributableValue (ec, member.Type, out value))
-                                               return false;
-
-                                       FieldBase fb = TypeManager.GetField (fi.MetaInfo);
-                                       if (fb != null)
-                                               obsolete_attr = fb.GetObsoleteAttribute ();
-                                       else
-                                               obsolete_attr = AttributeTester.GetMemberObsoleteAttribute (fi.MetaInfo);
-
-                                       field_values.Add (value);
-                                       field_infos.Add (fi.MetaInfo);
+                                       obsolete_attr = fi.GetAttributeObsolete ();
+                                       fi.MemberDefinition.SetIsAssigned ();
                                }
 
                                if (obsolete_attr != null && !context.IsObsolete)
                                        AttributeTester.Report_ObsoleteMessage (obsolete_attr, member.GetSignatureForError (), member.Location, Report);
-                       }
-
-                       prop_info_arr = new PropertyInfo [prop_infos.Count];
-                       field_info_arr = new FieldInfo [field_infos.Count];
-                       field_values_arr = new object [field_values.Count];
-                       prop_values_arr = new object [prop_values.Count];
 
-                       field_infos.CopyTo  (field_info_arr, 0);
-                       field_values.CopyTo (field_values_arr, 0);
+                               if (a.Type != member.Type) {
+                                       a.Expr = Convert.ImplicitConversionRequired (ec, a.Expr, member.Type, a.Expr.Location);
+                               }
 
-                       prop_values.CopyTo  (prop_values_arr, 0);
-                       prop_infos.CopyTo   (prop_info_arr, 0);
+                               if (a.Expr != null)
+                                       named_values.Add (new KeyValuePair<MemberExpr, NamedArgument> ((MemberExpr) member, a));
+                       }
 
                        return true;
                }
@@ -647,7 +589,7 @@ namespace Mono.CSharp {
                public string GetValidTargets ()
                {
                        StringBuilder sb = new StringBuilder ();
-                       AttributeTargets targets = GetAttributeUsage (Type).ValidOn;
+                       AttributeTargets targets = Type.GetAttributeUsage (context.Module.PredefinedAttributes.AttributeUsage).ValidOn;
 
                        if ((targets & AttributeTargets.Assembly) != 0)
                                sb.Append ("assembly, ");
@@ -697,48 +639,9 @@ namespace Mono.CSharp {
                        return sb.Remove (sb.Length - 2, 2).ToString ();
                }
 
-               /// <summary>
-               /// Returns AttributeUsage attribute based on types hierarchy
-               /// </summary>
-               static AttributeUsageAttribute GetAttributeUsage (Type type)
-               {
-                       AttributeUsageAttribute ua;
-                       if (usage_attr_cache.TryGetValue (type, out ua))
-                               return ua;
-
-                       Class attr_class = TypeManager.LookupClass (type);
-                       PredefinedAttribute pa = PredefinedAttributes.Get.AttributeUsage;
-
-                       if (attr_class == null) {
-                               if (!pa.IsDefined)
-                                       return new AttributeUsageAttribute (0);
-
-                               object[] usage_attr = type.GetCustomAttributes (pa.Type, true);
-                               ua = (AttributeUsageAttribute)usage_attr [0];
-                               usage_attr_cache.Add (type, ua);
-                               return ua;
-                       }
-
-                       Attribute a = null;
-                       if (attr_class.OptAttributes != null)
-                               a = attr_class.OptAttributes.Search (pa);
-
-                       if (a == null) {
-                               if (attr_class.TypeBuilder.BaseType != TypeManager.attribute_type)
-                                       ua = GetAttributeUsage (attr_class.TypeBuilder.BaseType);
-                               else
-                                       ua = DefaultUsageAttribute;
-                       } else {
-                               ua = a.GetAttributeUsageAttribute ();
-                       }
-
-                       usage_attr_cache.Add (type, ua);
-                       return ua;
-               }
-
-               AttributeUsageAttribute GetAttributeUsageAttribute ()
+               public AttributeUsageAttribute GetAttributeUsageAttribute ()
                {
-                       if (pos_values == null)
+                       if (!arg_resolved)
                                // TODO: It is not neccessary to call whole Resolve (ApplyAttribute does it now) we need only ctor args.
                                // But because a lot of attribute class code must be rewritten will be better to wait...
                                Resolve ();
@@ -746,15 +649,15 @@ namespace Mono.CSharp {
                        if (resolve_error)
                                return DefaultUsageAttribute;
 
-                       AttributeUsageAttribute usage_attribute = new AttributeUsageAttribute ((AttributeTargets)pos_values [0]);
+                       AttributeUsageAttribute usage_attribute = new AttributeUsageAttribute ((AttributeTargets) ((Constant) pos_args[0].Expr).GetValue ());
 
-                       object field = GetPropertyValue ("AllowMultiple");
+                       var field = GetNamedValue ("AllowMultiple") as BoolConstant;
                        if (field != null)
-                               usage_attribute.AllowMultiple = (bool)field;
+                               usage_attribute.AllowMultiple = field.Value;
 
-                       field = GetPropertyValue ("Inherited");
+                       field = GetNamedValue ("Inherited") as BoolConstant;
                        if (field != null)
-                               usage_attribute.Inherited = (bool)field;
+                               usage_attribute.Inherited = field.Value;
 
                        return usage_attribute;
                }
@@ -764,15 +667,15 @@ namespace Mono.CSharp {
                /// </summary>
                public string GetIndexerAttributeValue ()
                {
-                       if (pos_values == null)
+                       if (!arg_resolved)
                                // TODO: It is not neccessary to call whole Resolve (ApplyAttribute does it now) we need only ctor args.
                                // But because a lot of attribute class code must be rewritten will be better to wait...
                                Resolve ();
 
-                       if (resolve_error)
+                       if (resolve_error || pos_args.Count != 1 || !(pos_args[0].Expr is Constant))
                                return null;
 
-                       return pos_values [0] as string;
+                       return ((Constant) pos_args[0].Expr).GetValue () as string;
                }
 
                /// <summary>
@@ -780,7 +683,7 @@ namespace Mono.CSharp {
                /// </summary>
                public string GetConditionalAttributeValue ()
                {
-                       if (pos_values == null)
+                       if (!arg_resolved)
                                // TODO: It is not neccessary to call whole Resolve (ApplyAttribute does it now) we need only ctor args.
                                // But because a lot of attribute class code must be rewritten will be better to wait...
                                Resolve ();
@@ -788,7 +691,7 @@ namespace Mono.CSharp {
                        if (resolve_error)
                                return null;
 
-                       return (string)pos_values [0];
+                       return ((Constant) pos_args[0].Expr).GetValue () as string;
                }
 
                /// <summary>
@@ -796,21 +699,28 @@ namespace Mono.CSharp {
                /// </summary>
                public ObsoleteAttribute GetObsoleteAttribute ()
                {
-                       if (pos_values == null)
+                       if (!arg_resolved) {
+                               // corlib only case when obsolete is used before is resolved
+                               var c = Type.MemberDefinition as Class;
+                               if (c != null && !c.HasMembersDefined)
+                                       c.Define ();
+                               
                                // TODO: It is not neccessary to call whole Resolve (ApplyAttribute does it now) we need only ctor args.
                                // But because a lot of attribute class code must be rewritten will be better to wait...
                                Resolve ();
+                       }
 
                        if (resolve_error)
                                return null;
 
-                       if (pos_values == null || pos_values.Length == 0)
+                       if (pos_args == null)
                                return new ObsoleteAttribute ();
 
-                       if (pos_values.Length == 1)
-                               return new ObsoleteAttribute ((string)pos_values [0]);
+                       string msg = ((Constant) pos_args[0].Expr).GetValue () as string;
+                       if (pos_args.Count == 1)
+                               return new ObsoleteAttribute (msg);
 
-                       return new ObsoleteAttribute ((string)pos_values [0], (bool)pos_values [1]);
+                       return new ObsoleteAttribute (msg, ((BoolConstant) pos_args[1].Expr).Value);
                }
 
                /// <summary>
@@ -820,7 +730,7 @@ namespace Mono.CSharp {
                /// </summary>
                public bool GetClsCompliantAttributeValue ()
                {
-                       if (pos_values == null)
+                       if (!arg_resolved)
                                // TODO: It is not neccessary to call whole Resolve (ApplyAttribute does it now) we need only ctor args.
                                // But because a lot of attribute class code must be rewritten will be better to wait...
                                Resolve ();
@@ -828,18 +738,18 @@ namespace Mono.CSharp {
                        if (resolve_error)
                                return false;
 
-                       return (bool)pos_values [0];
+                       return ((BoolConstant) pos_args[0].Expr).Value;
                }
 
-               public Type GetCoClassAttributeValue ()
+               public TypeSpec GetCoClassAttributeValue ()
                {
-                       if (pos_values == null)
+                       if (!arg_resolved)
                                Resolve ();
 
                        if (resolve_error)
                                return null;
 
-                       return (Type)pos_values [0];
+                       return GetArgumentType ();
                }
 
                public bool CheckTarget ()
@@ -858,6 +768,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);
                        }
@@ -868,19 +779,22 @@ namespace Mono.CSharp {
                                sb.Append (", ");
                        }
                        sb.Remove (sb.Length - 2, 2);
-                       Report.Error (657, Location, "`{0}' is not a valid attribute location for this declaration. " +
-                               "Valid attribute locations for this declaration are `{1}'", ExplicitTarget, sb.ToString ());
+                       Report.Warning (657, 1, Location,
+                               "`{0}' is not a valid attribute location for this declaration. Valid attribute locations for this declaration are `{1}'. All attributes in this section will be ignored",
+                               ExplicitTarget, sb.ToString ());
                        return false;
                }
 
                /// <summary>
                /// Tests permitted SecurityAction for assembly or other types
                /// </summary>
-               protected virtual bool IsSecurityActionValid (bool for_assembly)
+               bool IsSecurityActionValid ()
                {
                        SecurityAction action = GetSecurityActionValue ();
+                       bool for_assembly = Target == AttributeTargets.Assembly || Target == AttributeTargets.Module;
 
                        switch (action) {
+#pragma warning disable 618
                        case SecurityAction.Demand:
                        case SecurityAction.Assert:
                        case SecurityAction.Deny:
@@ -897,6 +811,7 @@ namespace Mono.CSharp {
                                if (for_assembly)
                                        return true;
                                break;
+#pragma warning restore 618
 
                        default:
                                Error_AttributeEmitError ("SecurityAction is out of range");
@@ -909,267 +824,114 @@ namespace Mono.CSharp {
 
                System.Security.Permissions.SecurityAction GetSecurityActionValue ()
                {
-                       return (SecurityAction)pos_values [0];
+                       return (SecurityAction) ((Constant) pos_args[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)
-               {
-                       Type orig_assembly_type = null;
-
-                       if (TypeManager.LookupDeclSpace (Type) != null) {
-                               if (!RootContext.StdLib) {
-                                       orig_assembly_type = Type.GetType (Type.FullName);
-                               } else {
-                                       string orig_version_path = Environment.GetEnvironmentVariable ("__SECURITY_BOOTSTRAP_DB");
-                                       if (orig_version_path == null) {
-                                               Error_AttributeEmitError ("security custom attributes can not be referenced from defining assembly");
-                                               return;
-                                       }
-
-                                       if (orig_sec_assembly == null) {
-                                               string file = Path.Combine (orig_version_path, Driver.OutputFile);
-                                               orig_sec_assembly = Assembly.LoadFile (file);
-                                       }
-
-                                       orig_assembly_type = orig_sec_assembly.GetType (Type.FullName, true);
-                                       if (orig_assembly_type == null) {
-                                               Report.Warning (-112, 1, Location, "Self-referenced security attribute `{0}' " +
-                                                               "was not found in previous version of assembly");
-                                               return;
-                                       }
-                               }
-                       }
-
-                       SecurityAttribute sa;
-                       // For all non-selfreferencing security attributes we can avoid all hacks
-                       if (orig_assembly_type == null) {
-                               sa = (SecurityAttribute) Activator.CreateInstance (Type, pos_values);
-
-                               if (prop_info_arr != null) {
-                                       for (int i = 0; i < prop_info_arr.Length; ++i) {
-                                               PropertyInfo pi = prop_info_arr [i];
-                                               pi.SetValue (sa, prop_values_arr [i], null);
-                                       }
-                               }
+               public void ExtractSecurityPermissionSet (MethodSpec ctor, ref SecurityType permissions)
+               {
+#if STATIC
+                       object[] values = new object[pos_args.Count];
+                       for (int i = 0; i < values.Length; ++i)
+                               values[i] = ((Constant) pos_args[i].Expr).GetValue ();
+
+                       PropertyInfo[] prop;
+                       object[] prop_values;
+                       if (named_values == null) {
+                               prop = null;
+                               prop_values = null;
                        } else {
-                               // HACK: All security attributes have same ctor syntax
-                               sa = (SecurityAttribute) Activator.CreateInstance (orig_assembly_type, new object[] { GetSecurityActionValue () } );
-
-                               // All types are from newly created assembly but for invocation with old one we need to convert them
-                               if (prop_info_arr != null) {
-                                       for (int i = 0; i < prop_info_arr.Length; ++i) {
-                                               PropertyInfo emited_pi = prop_info_arr [i];
-                                               // FIXME: We are missing return type filter
-                                               // TODO: pi can be null
-                                               PropertyInfo pi = orig_assembly_type.GetProperty (emited_pi.Name);
-
-                                               object old_instance = TypeManager.IsEnumType (pi.PropertyType) ?
-                                                       System.Enum.ToObject (pi.PropertyType, prop_values_arr [i]) :
-                                                       prop_values_arr [i];
-
-                                               pi.SetValue (sa, old_instance, null);
-                                       }
-                               }
-                       }
-
-                       IPermission perm;
-                       perm = sa.CreatePermission ();
-                       SecurityAction action = GetSecurityActionValue ();
-
-                       // IS is correct because for corlib we are using an instance from old corlib
-                       if (!(perm is System.Security.CodeAccessPermission)) {
-                               switch (action) {
-                               case SecurityAction.Demand:
-                                       action = (SecurityAction)13;
-                                       break;
-                               case SecurityAction.LinkDemand:
-                                       action = (SecurityAction)14;
-                                       break;
-                               case SecurityAction.InheritanceDemand:
-                                       action = (SecurityAction)15;
-                                       break;
+                               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 ();
                                }
                        }
 
-                       PermissionSet ps;
-                       if (!permissions.TryGetValue (action, out ps)) {
-                               if (sa is PermissionSetAttribute)
-                                       ps = new PermissionSet (sa.Unrestricted ? PermissionState.Unrestricted : PermissionState.None);
-                               else
-                                       ps = new PermissionSet (PermissionState.None);
-
-                               permissions.Add (action, ps);
-                       } else if (!ps.IsUnrestricted () && (sa is PermissionSetAttribute) && sa.Unrestricted) {
-                               ps = ps.Union (new PermissionSet (PermissionState.Unrestricted));
-                               permissions [action] = ps;
-                       }
-                       ps.AddPermission (perm);
-               }
-
-               public object GetPropertyValue (string name)
-               {
-                       if (prop_info_arr == null)
-                               return null;
-
-                       for (int i = 0; i < prop_info_arr.Length; ++i) {
-                               if (prop_info_arr [i].Name == name)
-                                       return prop_values_arr [i];
-                       }
+                       if (permissions == null)
+                               permissions = new SecurityType ();
 
-                       return null;
+                       var cab = new CustomAttributeBuilder ((ConstructorInfo) ctor.GetMetaInfo (), values, prop, prop_values);
+                       permissions.Add (cab);
+#else
+                       throw new NotSupportedException ();
+#endif
                }
 
-               //
-               // 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)
+               public Constant GetNamedValue (string name)
                {
-                       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");
+                       if (named_values == null)
                                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);
+                       for (int i = 0; i < named_values.Count; ++i) {
+                               if (named_values [i].Value.Name == name)
+                                       return named_values [i].Value.Expr as Constant;
                        }
-               }
 
-               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), pos_values [0].ToString ());
+                       return (CharSet) System.Enum.Parse (typeof (CharSet), ((Constant) pos_args[0].Expr).GetValue ().ToString ());
                }
 
                public bool HasField (string fieldName)
                {
-                       if (field_info_arr == null)
+                       if (named_values == null)
                                return false;
 
-                       foreach (FieldInfo fi in field_info_arr) {
-                               if (fi.Name == fieldName)
+                       foreach (var na in named_values) {
+                               if (na.Value.Name == fieldName)
                                        return true;
                        }
 
                        return false;
                }
 
-               public bool IsInternalMethodImplAttribute {
-                       get {
-                               if (Type != PredefinedAttributes.Get.MethodImpl)
-                                       return false;
-
-                               MethodImplOptions options;
-                               if (pos_values[0].GetType () != typeof (MethodImplOptions))
-                                       options = (MethodImplOptions)System.Enum.ToObject (typeof (MethodImplOptions), pos_values[0]);
-                               else
-                                       options = (MethodImplOptions)pos_values[0];
+               //
+               // Returns true for MethodImplAttribute with MethodImplOptions.InternalCall value
+               // 
+               public bool IsInternalCall ()
+               {
+                       return (GetMethodImplOptions () & MethodImplOptions.InternalCall) != 0;
+               }
 
-                               return (options & MethodImplOptions.InternalCall) != 0;
+               public MethodImplOptions GetMethodImplOptions ()
+               {
+                       MethodImplOptions options = 0;
+                       if (pos_args.Count == 1) {
+                               options = (MethodImplOptions) System.Enum.Parse (typeof (MethodImplOptions), ((Constant) pos_args[0].Expr).GetValue ().ToString ());
+                       } else if (HasField ("Value")) {
+                               var named = GetNamedValue ("Value");
+                               options = (MethodImplOptions) System.Enum.Parse (typeof (MethodImplOptions), named.GetValue ().ToString ());
                        }
+
+                       return options;
                }
 
-               public LayoutKind GetLayoutKindValue ()
+               //
+               // Returns true for StructLayoutAttribute with LayoutKind.Explicit value
+               // 
+               public bool IsExplicitLayoutKind ()
                {
-                       if (!RootContext.StdLib || pos_values [0].GetType () != typeof (LayoutKind))
-                               return (LayoutKind)System.Enum.ToObject (typeof (LayoutKind), pos_values [0]);
+                       if (pos_args == null || pos_args.Count != 1)
+                               return false;
 
-                       return (LayoutKind)pos_values [0];
+                       var value = (LayoutKind) System.Enum.Parse (typeof (LayoutKind), ((Constant) pos_args[0].Expr).GetValue ().ToString ());
+                       return value == LayoutKind.Explicit;
                }
 
-               public object GetParameterDefaultValue ()
+               public Expression GetParameterDefaultValue ()
                {
-                       return pos_values [0];
+                       if (pos_args == null)
+                               return null;
+
+                       return pos_args[0].Expr;
                }
 
                public override bool Equals (object obj)
@@ -1183,7 +945,7 @@ namespace Mono.CSharp {
 
                public override int GetHashCode ()
                {
-                       return type.GetHashCode () ^ Target.GetHashCode ();
+                       return Type.GetHashCode () ^ Target.GetHashCode ();
                }
 
                /// <summary>
@@ -1191,11 +953,13 @@ namespace Mono.CSharp {
                /// </summary>
                public void Emit (Dictionary<Attribute, List<Attribute>> allEmitted)
                {
-                       CustomAttributeBuilder cb = Resolve ();
-                       if (cb == null)
+                       var ctor = Resolve ();
+                       if (ctor == null)
                                return;
 
-                       AttributeUsageAttribute usage_attr = GetAttributeUsage (Type);
+                       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",
@@ -1203,12 +967,89 @@ namespace Mono.CSharp {
                                return;
                        }
 
-                       var predefined = PredefinedAttributes.Get;
+                       byte[] cdata;
+                       if (pos_args == null && named_values == null) {
+                               cdata = AttributeEncoder.Empty;
+                       } else {
+                               AttributeEncoder encoder = new AttributeEncoder ();
+
+                               if (pos_args != null) {
+                                       var param_types = ctor.Parameters.Types;
+                                       for (int j = 0; j < pos_args.Count; ++j) {
+                                               var pt = param_types[j];
+                                               var arg_expr = pos_args[j].Expr;
+                                               if (j == 0) {
+                                                       if ((Type == predefined.IndexerName || Type == predefined.Conditional) && arg_expr is Constant) {
+                                                               string v = ((Constant) arg_expr).GetValue () as string;
+                                                               if (!Tokenizer.IsValidIdentifier (v) || (Type == predefined.IndexerName && Tokenizer.IsKeyword (v))) {
+                                                                       context.Module.Compiler.Report.Error (633, arg_expr.Location,
+                                                                               "The argument to the `{0}' attribute must be a valid identifier", GetSignatureForError ());
+                                                                       return;
+                                                               }
+                                                       } 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.Module.Compiler.Report.Error (591, Location, "Invalid value for argument to `{0}' attribute",
+                                                                               "System.AttributeUsage");
+                                                               }
+                                                       } else if (Type == predefined.MarshalAs) {
+                                                               if (pos_args.Count == 1) {
+                                                                       var u_type = (UnmanagedType) System.Enum.Parse (typeof (UnmanagedType), ((Constant) pos_args[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 (pos_args.Count == 1 && pos_args[0].Expr is Constant) {
+                                                                       var value = ((Constant) pos_args[0].Expr).GetValue () as string;
+                                                                       if (string.IsNullOrEmpty (value))
+                                                                               Error_AttributeEmitError ("DllName cannot be empty");
+                                                               }
+                                                       } else if (Type == predefined.MethodImpl && pt.BuiltinType == BuiltinTypeSpec.Type.Short &&
+                                                               !System.Enum.IsDefined (typeof (MethodImplOptions), ((Constant) arg_expr).GetValue ().ToString ())) {
+                                                               Error_AttributeEmitError ("Incorrect argument value.");
+                                                               return;
+                                                       }
+                                               }
+
+                                               arg_expr.EncodeAttributeValue (context, encoder, pt);
+                                       }
+                               }
+
+                               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 ();
+                               }
+
+                               cdata = encoder.ToArray ();
+                       }
 
                        try {
                                foreach (Attributable target in targets)
-                                       target.ApplyAttributeBuilder (this, cb, predefined);
+                                       target.ApplyAttributeBuilder (this, ctor, cdata, predefined);
                        } catch (Exception e) {
+                               if (e is BadImageFormat && Report.Errors > 0)
+                                       return;
+
                                Error_AttributeEmitError (e.Message);
                                return;
                        }
@@ -1226,27 +1067,27 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       if (!RootContext.VerifyClsCompliance)
+                       if (!context.Module.Compiler.Settings.VerifyClsCompliance)
                                return;
 
                        // Here we are testing attribute arguments for array usage (error 3016)
                        if (Owner.IsClsComplianceRequired ()) {
-                               if (PosArguments != null)
-                                       PosArguments.CheckArrayAsAttribute (context.Compiler);
+                               if (pos_args != null)
+                                       pos_args.CheckArrayAsAttribute (context.Module.Compiler);
                        
                                if (NamedArguments == null)
                                        return;
 
-                               NamedArguments.CheckArrayAsAttribute (context.Compiler);
+                               NamedArguments.CheckArrayAsAttribute (context.Module.Compiler);
                        }
                }
 
                private Expression GetValue () 
                {
-                       if (PosArguments == null || PosArguments.Count < 1)
+                       if (pos_args == null || pos_args.Count < 1)
                                return null;
 
-                       return PosArguments [0].Expr;
+                       return pos_args[0].Expr;
                }
 
                public string GetString () 
@@ -1265,132 +1106,33 @@ namespace Mono.CSharp {
                        return false;
                }
 
-               public Type GetArgumentType ()
+               public TypeSpec GetArgumentType ()
                {
                        TypeOf e = GetValue () as TypeOf;
                        if (e == null)
                                return null;
                        return e.TypeArgument;
                }
+       }
+       
+       public class Attributes
+       {
+               public readonly List<Attribute> Attrs;
 
-               public override Expression CreateExpressionTree (ResolveContext ec)
+               public Attributes (Attribute a)
                {
-                       throw new NotSupportedException ("ET");
+                       Attrs = new List<Attribute> ();
+                       Attrs.Add (a);
                }
 
-               protected override Expression DoResolve (ResolveContext ec)
+               public Attributes (List<Attribute> attrs)
                {
-                       throw new NotImplementedException ();
+                       Attrs = attrs;
                }
 
-               public override void Emit (EmitContext ec)
+               public void AddAttribute (Attribute attr)
                {
-                       throw new NotImplementedException ();
-               }
-       }
-       
-
-       /// <summary>
-       /// For global attributes (assembly, module) we need special handling.
-       /// Attributes can be located in the several files
-       /// </summary>
-       public class GlobalAttribute : Attribute
-       {
-               public readonly NamespaceEntry ns;
-
-               public GlobalAttribute (NamespaceEntry ns, string target, ATypeNameExpression expression,
-                                       Arguments[] args, Location loc, bool nameEscaped):
-                       base (target, expression, args, loc, nameEscaped)
-               {
-                       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 ()
-               {
-                       // RootContext.ToplevelTypes has a single NamespaceEntry which gets overwritten
-                       // each time a new file is parsed.  However, we need to use the NamespaceEntry
-                       // in effect where the attribute was used.  Since code elsewhere cannot assume
-                       // that the NamespaceEntry is right, just overwrite it.
-                       //
-                       // Precondition: RootContext.ToplevelTypes == null
-
-                       if (RootContext.ToplevelTypes.NamespaceEntry != null)
-                               throw new InternalErrorException (Location + " non-null NamespaceEntry");
-
-                       RootContext.ToplevelTypes.NamespaceEntry = ns;
-               }
-
-               protected override bool IsSecurityActionValid (bool for_assembly)
-               {
-                       return base.IsSecurityActionValid (true);
-               }
-
-               void Leave ()
-               {
-                       RootContext.ToplevelTypes.NamespaceEntry = null;
-               }
-
-               protected override TypeExpr ResolveAsTypeTerminal (Expression expr, IMemberContext ec)
-               {
-                       try {
-                               Enter ();
-                               return base.ResolveAsTypeTerminal (expr, ec);
-                       }
-                       finally {
-                               Leave ();
-                       }
-               }
-
-               protected override MethodSpec ResolveConstructor (ResolveContext ec)
-               {
-                       try {
-                               Enter ();
-                               return base.ResolveConstructor (ec);
-                       }
-                       finally {
-                               Leave ();
-                       }
-               }
-
-               protected override bool ResolveNamedArguments (ResolveContext ec)
-               {
-                       try {
-                               Enter ();
-                               return base.ResolveNamedArguments (ec);
-                       }
-                       finally {
-                               Leave ();
-                       }
-               }
-       }
-
-       public class Attributes {
-               public readonly List<Attribute> Attrs;
-
-               public Attributes (Attribute a)
-               {
-                       Attrs = new List<Attribute> ();
-                       Attrs.Add (a);
-               }
-
-               public Attributes (List<Attribute> attrs)
-               {
-                       Attrs = attrs;
+                       Attrs.Add (attr);
                }
 
                public void AddAttributes (List<Attribute> attrs)
@@ -1418,16 +1160,50 @@ namespace Mono.CSharp {
                /// </summary>
                public bool CheckTargets ()
                {
-                       foreach (Attribute a in Attrs) {
-                               if (!a.CheckTarget ())
-                                       return false;
+                       for (int i = 0; i < Attrs.Count; ++i) {
+                               if (!Attrs [i].CheckTarget ())
+                                       Attrs.RemoveAt (i--);
                        }
+
                        return true;
                }
 
+               public void ConvertGlobalAttributes (TypeContainer member, NamespaceContainer currentNamespace, bool isGlobal)
+               {
+                       var member_explicit_targets = member.ValidAttributeTargets;
+                       for (int i = 0; i < Attrs.Count; ++i) {
+                               var attr = Attrs[0];
+                               if (attr.ExplicitTarget == null)
+                                       continue;
+
+                               int ii;
+                               for (ii = 0; ii < member_explicit_targets.Length; ++ii) {
+                                       if (attr.ExplicitTarget == member_explicit_targets[ii]) {
+                                               ii = -1;
+                                               break;
+                                       }
+                               }
+
+                               if (ii < 0 || !isGlobal)
+                                       continue;
+
+                               member.Module.AddAttribute (attr, currentNamespace);
+                               Attrs.RemoveAt (i);
+                               --i;
+                       }
+               }
+
                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;
                        }
@@ -1484,357 +1260,317 @@ namespace Mono.CSharp {
                }
        }
 
-       /// <summary>
-       /// Helper class for attribute verification routine.
-       /// </summary>
-       sealed class AttributeTester
+       public sealed class AttributeEncoder
        {
-               static Dictionary<Type, bool> analyzed_types;
-               static Dictionary<Type, ObsoleteAttribute> analyzed_types_obsolete;
-               static Dictionary<MemberInfo, ObsoleteAttribute> analyzed_member_obsolete;
-               static Dictionary<MethodBase, bool> analyzed_method_excluded;
-//             static Dictionary<FieldInfo, IFixedBuffer> fixed_buffer_cache;
-
-               static AttributeTester ()
+               [Flags]
+               public enum EncodedTypeProperties
                {
-                       Reset ();
+                       None = 0,
+                       DynamicType = 1,
+                       TypeParameter = 1 << 1
                }
 
-               private AttributeTester ()
+               public static readonly byte[] Empty;
+
+               byte[] buffer;
+               int pos;
+               const ushort Version = 1;
+
+               static AttributeEncoder ()
                {
+                       Empty = new byte[4];
+                       Empty[0] = (byte) Version;
                }
 
-               public static void Reset ()
+               public AttributeEncoder ()
                {
-                       analyzed_types = new Dictionary<Type, bool> (ReferenceEquality<Type>.Default);
-                       analyzed_types_obsolete = new Dictionary<Type, ObsoleteAttribute> (ReferenceEquality<Type>.Default);
-                       analyzed_member_obsolete = new Dictionary<MemberInfo, ObsoleteAttribute> (ReferenceEquality<MemberInfo>.Default);
-                       analyzed_method_excluded = new Dictionary<MethodBase, bool> (ReferenceEquality<MethodBase>.Default);
-//                     fixed_buffer_cache = new Dictionary<FieldInfo, IFixedBuffer> (ReferenceEquality<FieldInfo>.Default);
+                       buffer = new byte[32];
+                       Encode (Version);
                }
 
-               public enum Result {
-                       Ok,
-                       RefOutArrayError,
-                       ArrayArrayError
+               public void Encode (bool value)
+               {
+                       Encode (value ? (byte) 1 : (byte) 0);
                }
 
-               /// <summary>
-               /// Returns true if parameters of two compared methods are CLS-Compliant.
-               /// It tests differing only in ref or out, or in array rank.
-               /// </summary>
-               public static Result AreOverloadedMethodParamsClsCompliant (AParametersCollection pa, AParametersCollection pb) 
-               {
-                       Type [] types_a = pa.Types;
-                       Type [] types_b = pb.Types;
-                       if (types_a == null || types_b == null)
-                               return Result.Ok;
-
-                       if (types_a.Length != types_b.Length)
-                               return Result.Ok;
-
-                       Result result = Result.Ok;
-                       for (int i = 0; i < types_b.Length; ++i) {
-                               Type aType = types_a [i];
-                               Type bType = types_b [i];
-
-                               if (aType.IsArray && bType.IsArray) {
-                                       Type a_el_type = TypeManager.GetElementType (aType);
-                                       Type b_el_type = TypeManager.GetElementType (bType);
-                                       if (aType.GetArrayRank () != bType.GetArrayRank () && a_el_type == b_el_type) {
-                                               result = Result.RefOutArrayError;
-                                               continue;
-                                       }
-
-                                       if (a_el_type.IsArray || b_el_type.IsArray) {
-                                               result = Result.ArrayArrayError;
-                                               continue;
-                                       }
-                               }
-
-                               if (aType != bType)
-                                       return Result.Ok;
+               public void Encode (byte value)
+               {
+                       if (pos == buffer.Length)
+                               Grow (1);
 
-                               const Parameter.Modifier out_ref_mod = (Parameter.Modifier.OUTMASK | Parameter.Modifier.REFMASK);
-                               if ((pa.FixedParameters[i].ModFlags & out_ref_mod) != (pb.FixedParameters[i].ModFlags & out_ref_mod))
-                                       result = Result.RefOutArrayError;
-                       }
-                       return result;
+                       buffer [pos++] = value;
                }
 
-               /// <summary>
-               /// This method tests the CLS compliance of external types. It doesn't test type visibility.
-               /// </summary>
-               public static bool IsClsCompliant (Type type) 
+               public void Encode (sbyte value)
                {
-                       if (type == null)
-                               return true;
-
-                       bool result;
-                       if (analyzed_types.TryGetValue (type, out result))
-                               return result;
-
-                       if (type.IsPointer) {
-                               analyzed_types.Add (type, false);
-                               return false;
-                       }
-
-                       if (type.IsArray) {
-                               result = IsClsCompliant (TypeManager.GetElementType (type));
-                       } else if (TypeManager.IsNullableType (type)) {
-                               result = IsClsCompliant (TypeManager.TypeToCoreType (TypeManager.GetTypeArguments (type) [0]));
-                       } else {
-                               result = AnalyzeTypeCompliance (type);
-                       }
-                       analyzed_types.Add (type, result);
-                       return result;
-               }        
+                       Encode ((byte) value);
+               }
 
-               public static void VerifyModulesClsCompliance (CompilerContext ctx)
+               public void Encode (short value)
                {
-                       Module[] modules = GlobalRootNamespace.Instance.Modules;
-                       if (modules == null)
-                               return;
+                       if (pos + 2 > buffer.Length)
+                               Grow (2);
 
-                       // 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;
-                               }
-                       }
+                       buffer[pos++] = (byte) value;
+                       buffer[pos++] = (byte) (value >> 8);
                }
 
-               public static Type GetImportedIgnoreCaseClsType (string name)
+               public void Encode (ushort value)
                {
-                       foreach (Assembly a in GlobalRootNamespace.Instance.Assemblies) {
-                               Type t = a.GetType (name, false, true);
-                               if (t == null)
-                                       continue;
-
-                               if (IsClsCompliant (t))
-                                       return t;
-                       }
-                       return null;
+                       Encode ((short) value);
                }
 
-               static bool GetClsCompliantAttributeValue (ICustomAttributeProvider attribute_provider, Assembly a) 
+               public void Encode (int value)
                {
-                       PredefinedAttribute pa = PredefinedAttributes.Get.CLSCompliant;
-                       if (!pa.IsDefined)
-                               return false;
+                       if (pos + 4 > buffer.Length)
+                               Grow (4);
 
-                       object[] cls_attr = attribute_provider.GetCustomAttributes (pa.Type, false);
-                       if (cls_attr.Length == 0) {
-                               if (a == null)
-                                       return false;
-
-                               return GetClsCompliantAttributeValue (a, null);
-                       }
-                       
-                       return ((CLSCompliantAttribute)cls_attr [0]).IsCompliant;
+                       buffer[pos++] = (byte) value;
+                       buffer[pos++] = (byte) (value >> 8);
+                       buffer[pos++] = (byte) (value >> 16);
+                       buffer[pos++] = (byte) (value >> 24);
                }
 
-               static bool AnalyzeTypeCompliance (Type type)
+               public void Encode (uint value)
                {
-                       type = TypeManager.DropGenericTypeArguments (type);
-                       DeclSpace ds = TypeManager.LookupDeclSpace (type);
-                       if (ds != null) {
-                               return ds.IsClsComplianceRequired ();
-                       }
+                       Encode ((int) value);
+               }
 
-                       if (TypeManager.IsGenericParameter (type))
-                               return true;
+               public void Encode (long value)
+               {
+                       if (pos + 8 > buffer.Length)
+                               Grow (8);
 
-                       return GetClsCompliantAttributeValue (type, type.Assembly);
+                       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);
                }
 
-               /// <summary>
-               /// Returns instance of ObsoleteAttribute when type is obsolete
-               /// </summary>
-               public static ObsoleteAttribute GetObsoleteAttribute (Type type)
-               {
-                       ObsoleteAttribute result;
-                       if (analyzed_types_obsolete.TryGetValue (type, out result))
-                               return result;
-
-                       if (TypeManager.HasElementType (type)) {
-                               result = GetObsoleteAttribute (TypeManager.GetElementType (type));
-                       } else if (TypeManager.IsGenericParameter (type))
-                               result = null;  // TODO: throw new NotSupportedException ()
-                       else if (TypeManager.IsGenericType (type) && !TypeManager.IsGenericTypeDefinition (type)) {
-                               return GetObsoleteAttribute (TypeManager.DropGenericTypeArguments (type));
-                       } else {
-                               DeclSpace type_ds = TypeManager.LookupDeclSpace (type);
-
-                               // Type is external, we can get attribute directly
-                               if (type_ds == null) {
-                                       PredefinedAttribute pa = PredefinedAttributes.Get.Obsolete;
-                                       if (pa.IsDefined) {
-                                               object[] attribute = type.GetCustomAttributes (pa.Type, false);
-                                               if (attribute.Length == 1)
-                                                       result = (ObsoleteAttribute) attribute[0];
-                                       }
-                               } else {
-                                       result = type_ds.GetObsoleteAttribute ();
-                               }
-                       }
+               public void Encode (ulong value)
+               {
+                       Encode ((long) value);
+               }
 
-                       // Cannot use .Add because of corlib bootstrap
-                       analyzed_types_obsolete [type] = result;
-                       return result;
+               public void Encode (float value)
+               {
+                       Encode (SingleConverter.SingleToInt32Bits (value));
                }
 
-               /// <summary>
-               /// Returns instance of ObsoleteAttribute when method is obsolete
-               /// </summary>
-               public static ObsoleteAttribute GetMethodObsoleteAttribute (MethodBase mb)
+               public void Encode (double value)
                {
-                       IMethodData mc = TypeManager.GetMethod (mb);
-                       if (mc != null) 
-                               return mc.GetObsoleteAttribute ();
+                       Encode (BitConverter.DoubleToInt64Bits (value));
+               }
 
-                       // compiler generated methods are not registered by AddMethod
-                       if (mb.DeclaringType is TypeBuilder)
-                               return null;
+               public void Encode (string value)
+               {
+                       if (value == null) {
+                               Encode ((byte) 0xFF);
+                               return;
+                       }
 
-                       MemberInfo mi = TypeManager.GetPropertyFromAccessor (mb);
-                       if (mi != null)
-                               return GetMemberObsoleteAttribute (mi);
+                       var buf = Encoding.UTF8.GetBytes(value);
+                       WriteCompressedValue (buf.Length);
 
-                       mi = TypeManager.GetEventFromAccessor (mb);
-                       if (mi != null)
-                               return GetMemberObsoleteAttribute (mi);
+                       if (pos + buf.Length > buffer.Length)
+                               Grow (buf.Length);
 
-                       return GetMemberObsoleteAttribute (mb);
+                       Buffer.BlockCopy (buf, 0, buffer, pos, buf.Length);
+                       pos += buf.Length;
                }
 
-               /// <summary>
-               /// Returns instance of ObsoleteAttribute when member is obsolete
-               /// </summary>
-               public static ObsoleteAttribute GetMemberObsoleteAttribute (MemberInfo mi)
+               public EncodedTypeProperties Encode (TypeSpec type)
                {
-                       ObsoleteAttribute oa;
-                       if (analyzed_member_obsolete.TryGetValue (mi, out oa))
-                               return oa;
+                       switch (type.BuiltinType) {
+                       case BuiltinTypeSpec.Type.Bool:
+                               Encode ((byte) 0x02);
+                               break;
+                       case BuiltinTypeSpec.Type.Char:
+                               Encode ((byte) 0x03);
+                               break;
+                       case BuiltinTypeSpec.Type.SByte:
+                               Encode ((byte) 0x04);
+                               break;
+                       case BuiltinTypeSpec.Type.Byte:
+                               Encode ((byte) 0x05);
+                               break;
+                       case BuiltinTypeSpec.Type.Short:
+                               Encode ((byte) 0x06);
+                               break;
+                       case BuiltinTypeSpec.Type.UShort:
+                               Encode ((byte) 0x07);
+                               break;
+                       case BuiltinTypeSpec.Type.Int:
+                               Encode ((byte) 0x08);
+                               break;
+                       case BuiltinTypeSpec.Type.UInt:
+                               Encode ((byte) 0x09);
+                               break;
+                       case BuiltinTypeSpec.Type.Long:
+                               Encode ((byte) 0x0A);
+                               break;
+                       case BuiltinTypeSpec.Type.ULong:
+                               Encode ((byte) 0x0B);
+                               break;
+                       case BuiltinTypeSpec.Type.Float:
+                               Encode ((byte) 0x0C);
+                               break;
+                       case BuiltinTypeSpec.Type.Double:
+                               Encode ((byte) 0x0D);
+                               break;
+                       case BuiltinTypeSpec.Type.String:
+                               Encode ((byte) 0x0E);
+                               break;
+                       case BuiltinTypeSpec.Type.Type:
+                               Encode ((byte) 0x50);
+                               break;
+                       case BuiltinTypeSpec.Type.Object:
+                               Encode ((byte) 0x51);
+                               break;
+                       case BuiltinTypeSpec.Type.Dynamic:
+                               Encode ((byte) 0x51);
+                               return EncodedTypeProperties.DynamicType;
+                       default:
+                               if (type.IsArray) {
+                                       Encode ((byte) 0x1D);
+                                       return Encode (TypeManager.GetElementType (type));
+                               }
 
-                       if ((mi.DeclaringType is TypeBuilder) || TypeManager.IsGenericType (mi.DeclaringType))
-                               return null;
+                               if (type.Kind == MemberKind.Enum) {
+                                       Encode ((byte) 0x55);
+                                       EncodeTypeName (type);
+                               }
 
-                       PredefinedAttribute pa = PredefinedAttributes.Get.Obsolete;
-                       if (!pa.IsDefined)
-                               return null;
+                               break;
+                       }
 
-                       oa = System.Attribute.GetCustomAttribute (mi, pa.Type, false) as ObsoleteAttribute;
-                       analyzed_member_obsolete.Add (mi, oa);
-                       return oa;
+                       return EncodedTypeProperties.None;
                }
 
-               /// <summary>
-               /// Common method for Obsolete error/warning reporting.
-               /// </summary>
-               public static void Report_ObsoleteMessage (ObsoleteAttribute oa, string member, Location loc, Report Report)
+               public void EncodeTypeName (TypeSpec type)
                {
-                       if (oa.IsError) {
-                               Report.Error (619, loc, "`{0}' is obsolete: `{1}'", member, oa.Message);
-                               return;
-                       }
+                       var old_type = type.GetMetaInfo ();
+                       Encode (type.MemberDefinition.IsImported ? old_type.AssemblyQualifiedName : old_type.FullName);
+               }
 
-                       if (oa.Message == null || oa.Message.Length == 0) {
-                               Report.Warning (612, 1, loc, "`{0}' is obsolete", member);
-                               return;
-                       }
-                       Report.Warning (618, 2, loc, "`{0}' is obsolete: `{1}'", member, oa.Message);
+               //
+               // 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);
                }
 
-               public static bool IsConditionalMethodExcluded (MethodBase mb, Location loc)
+               //
+               // Encodes single field named argument per call
+               //
+               public void EncodeNamedFieldArgument (FieldSpec field, Constant value)
                {
-                       bool excluded;
-                       if (analyzed_method_excluded.TryGetValue (mb, out excluded))
-                               return excluded;
+                       Encode ((ushort) 1);    // length
+                       Encode ((byte) 0x53); // field
+                       Encode (field.MemberType);
+                       Encode (field.Name);
+                       value.EncodeAttributeValue (null, this, field.MemberType);
+               }
 
-                       PredefinedAttribute pa = PredefinedAttributes.Get.Conditional;
-                       if (!pa.IsDefined)
-                               return false;
+               public void EncodeNamedArguments<T> (T[] members, Constant[] values) where T : MemberSpec, IInterfaceMemberSpec
+               {
+                       Encode ((ushort) members.Length);
 
-                       ConditionalAttribute[] attrs = mb.GetCustomAttributes (pa.Type, true)
-                               as ConditionalAttribute[];
-                       if (attrs.Length == 0) {
-                               analyzed_method_excluded.Add (mb, false);
-                               return false;
-                       }
+                       for (int i = 0; i < members.Length; ++i)
+                       {
+                               var member = members[i];
 
-                       foreach (ConditionalAttribute a in attrs) {
-                               if (loc.CompilationUnit.IsConditionalDefined (a.ConditionString)) {
-                                       analyzed_method_excluded.Add (mb, false);
-                                       return false;
-                               }
+                               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);
                        }
+               }
 
-                       analyzed_method_excluded.Add (mb, true);
-                       return true;
+               public void EncodeEmptyNamedArguments ()
+               {
+                       Encode ((ushort) 0);
                }
 
-               /// <summary>
-               /// Analyzes class whether it has attribute which has ConditionalAttribute
-               /// and its condition is not defined.
-               /// </summary>
-               public static bool IsAttributeExcluded (Type type, Location loc)
+               void Grow (int inc)
                {
-                       if (!type.IsClass)
-                               return false;
+                       int size = System.Math.Max (pos * 4, pos + inc + 2);
+                       Array.Resize (ref buffer, size);
+               }
 
-                       Class class_decl = TypeManager.LookupDeclSpace (type) as Class;
+               void WriteCompressedValue (int value)
+               {
+                       if (value < 0x80) {
+                               Encode ((byte) value);
+                               return;
+                       }
 
-                       // TODO: add caching
-                       // TODO: merge all Type bases attribute caching to one cache to save memory
-                       PredefinedAttribute pa = PredefinedAttributes.Get.Conditional;
-                       if (class_decl == null && pa.IsDefined) {
-                               object[] attributes = type.GetCustomAttributes (pa.Type, false);
-                               foreach (ConditionalAttribute ca in attributes) {
-                                       if (loc.CompilationUnit.IsConditionalDefined (ca.ConditionString))
-                                               return false;
-                               }
-                               return attributes.Length > 0;
+                       if (value < 0x4000) {
+                               Encode ((byte) (0x80 | (value >> 8)));
+                               Encode ((byte) value);
+                               return;
                        }
 
-                       return class_decl.IsExcluded ();
+                       Encode (value);
                }
 
-               public static Type GetCoClassAttribute (Type type)
+               public byte[] ToArray ()
                {
-                       TypeContainer tc = TypeManager.LookupInterface (type);
-                       PredefinedAttribute pa = PredefinedAttributes.Get.CoClass;
-                       if (tc == null) {
-                               if (!pa.IsDefined)
-                                       return null;
-
-                               object[] o = type.GetCustomAttributes (pa.Type, false);
-                               if (o.Length < 1)
-                                       return null;
-                               return ((System.Runtime.InteropServices.CoClassAttribute)o[0]).CoClass;
-                       }
+                       byte[] buf = new byte[pos];
+                       Array.Copy (buffer, buf, pos);
+                       return buf;
+               }
+       }
 
-                       if (tc.OptAttributes == null)
-                               return null;
 
-                       Attribute a = tc.OptAttributes.Search (pa);
-                       if (a == null)
-                               return null;
+       /// <summary>
+       /// Helper class for attribute verification routine.
+       /// </summary>
+       static class AttributeTester
+       {
+               /// <summary>
+               /// Common method for Obsolete error/warning reporting.
+               /// </summary>
+               public static void Report_ObsoleteMessage (ObsoleteAttribute oa, string member, Location loc, Report Report)
+               {
+                       if (oa.IsError) {
+                               Report.Error (619, loc, "`{0}' is obsolete: `{1}'", member, oa.Message);
+                               return;
+                       }
 
-                       return a.GetCoClassAttributeValue ();
+                       if (oa.Message == null || oa.Message.Length == 0) {
+                               Report.Warning (612, 1, loc, "`{0}' is obsolete", member);
+                               return;
+                       }
+                       Report.Warning (618, 2, loc, "`{0}' is obsolete: `{1}'", member, oa.Message);
                }
        }
 
+       //
+       // 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;
@@ -1848,13 +1584,15 @@ namespace Mono.CSharp {
                public readonly PredefinedAttribute Guid;
                public readonly PredefinedAttribute AssemblyCulture;
                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;
-
-               // New in .NET 2.0
+               public readonly PredefinedAttribute UnverifiableCode;
                public readonly PredefinedAttribute DefaultCharset;
                public readonly PredefinedAttribute TypeForwarder;
                public readonly PredefinedAttribute FixedBuffer;
@@ -1863,109 +1601,117 @@ namespace Mono.CSharp {
                public readonly PredefinedAttribute RuntimeCompatibility;
                public readonly PredefinedAttribute DebuggerHidden;
                public readonly PredefinedAttribute UnsafeValueType;
+               public readonly PredefinedAttribute UnmanagedFunctionPointer;
+               public readonly PredefinedDebuggerBrowsableAttribute DebuggerBrowsable;
 
                // New in .NET 3.5
                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");
-                       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 readonly PredefinedAttribute CallerMemberNameAttribute;
+               public readonly PredefinedAttribute CallerLineNumberAttribute;
+               public readonly PredefinedAttribute CallerFilePathAttribute;
+
+               public PredefinedAttributes (ModuleContainer module)
+               {
+                       ParamArray = new PredefinedAttribute (module, "System", "ParamArrayAttribute");
+                       Out = new PredefinedAttribute (module, "System.Runtime.InteropServices", "OutAttribute");
+                       ParamArray.Resolve ();
+                       Out.Resolve ();
+
+                       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");
+                       UnmanagedFunctionPointer = new PredefinedAttribute (module, "System.Runtime.InteropServices", "UnmanagedFunctionPointerAttribute");
+                       DebuggerBrowsable = new PredefinedDebuggerBrowsableAttribute (module, "System.Diagnostics", "DebuggerBrowsableAttribute");
+
+                       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");
+
+                       CallerMemberNameAttribute = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "CallerMemberNameAttribute");
+                       CallerLineNumberAttribute = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "CallerLineNumberAttribute");
+                       CallerFilePathAttribute = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "CallerFilePathAttribute");
+
+                       // 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
        {
-               Type type;
-               CustomAttributeBuilder cab;
-               ConstructorInfo ctor;
-               readonly string ns, name;
-               CompilerContext compiler;
-
-               static readonly Type NotFound = typeof (PredefinedAttribute);
+               protected MethodSpec ctor;
 
-               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;
                }
 
-               public static bool operator == (Type type, PredefinedAttribute pa)
-               {
-                       return type == pa.type;
+               #region Properties
+
+               public MethodSpec Constructor {
+                       get {
+                               return ctor;
+                       }
                }
 
-               public static bool operator != (Type type, PredefinedAttribute pa)
+               #endregion
+
+               public static bool operator == (TypeSpec type, PredefinedAttribute pa)
                {
-                       return type != pa.type;
+                       return type == pa.type && pa.type != null;
                }
 
-               public ConstructorInfo Constructor {
-                       get { return ctor; }
+               public static bool operator != (TypeSpec type, PredefinedAttribute pa)
+               {
+                       return type != pa.type;
                }
 
                public override int GetHashCode ()
@@ -1973,11 +1719,6 @@ namespace Mono.CSharp {
                        return base.GetHashCode ();
                }
 
-               public string GetSignatureForError ()
-               {
-                       return ns + "." + name;
-               }
-
                public override bool Equals (object obj)
                {
                        throw new NotSupportedException ();
@@ -1986,106 +1727,244 @@ 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 (TypeBuilder builder)
                {
                        if (ResolveBuilder ())
-                               builder.SetCustomAttribute (cab);
+                               builder.SetCustomAttribute (GetCtorMetaInfo (), AttributeEncoder.Empty);
                }
 
                public void EmitAttribute (AssemblyBuilder builder)
                {
                        if (ResolveBuilder ())
-                               builder.SetCustomAttribute (cab);
+                               builder.SetCustomAttribute (GetCtorMetaInfo (), AttributeEncoder.Empty);
                }
 
-               public void EmitAttribute (ParameterBuilder builder)
+               public void EmitAttribute (ModuleBuilder builder)
                {
                        if (ResolveBuilder ())
-                               builder.SetCustomAttribute (cab);
-               }
-
-               public bool IsDefined {
-                       get { return type != null && type != NotFound; }
+                               builder.SetCustomAttribute (GetCtorMetaInfo (), AttributeEncoder.Empty);
                }
 
-               public void Initialize (CompilerContext ctx, bool canFail)
+               public void EmitAttribute (ParameterBuilder builder)
                {
-                       this.compiler = ctx;
-                       Resolve (canFail);
+                       if (ResolveBuilder ())
+                               builder.SetCustomAttribute (GetCtorMetaInfo (), AttributeEncoder.Empty);
                }
 
-               public bool Resolve (bool canFail)
+               ConstructorInfo GetCtorMetaInfo ()
                {
-                       if (type != null) {
-                               if (IsDefined)
-                                       return true;
-                               if (canFail)
-                                       return false;
-                       }
-
-                       type = TypeManager.CoreLookupType (compiler, ns, name, MemberKind.Class, !canFail);
-                       if (type == null) {
-                               type = NotFound;
-                               return false;
-                       }
-
-                       return true;
+                       return (ConstructorInfo) ctor.GetMetaInfo ();
                }
 
-               bool ResolveBuilder ()
+               public bool ResolveBuilder ()
                {
-                       if (cab != null)
+                       if (ctor != null)
                                return true;
 
                        //
                        // Handle all parameter-less attributes as optional
                        //
-                       if (!Resolve (true))
+                       if (!IsDefined)
                                return false;
 
-                       ConstructorInfo ci = TypeManager.GetPredefinedConstructor (type, Location.Null, Type.EmptyTypes);
-                       if (ci == null)
-                               return false;
+                       ctor = (MethodSpec) MemberCache.FindMember (type, MemberFilter.Constructor (ParametersCompiled.EmptyReadOnlyParameters), BindingRestriction.DeclaredOnly);
+                       return ctor != null;
+               }
+       }
 
-                       cab = new CustomAttributeBuilder (ci, new object[0]);
-                       return true;
+       public class PredefinedDebuggerBrowsableAttribute : PredefinedAttribute
+       {
+               public PredefinedDebuggerBrowsableAttribute (ModuleContainer module, string ns, string name)
+                       : base (module, ns, name)
+               {
                }
 
-               public bool ResolveConstructor (Location loc, params Type[] argType)
+               public void EmitAttribute (FieldBuilder builder, System.Diagnostics.DebuggerBrowsableState state)
                {
-                       if (ctor != null)
-                               throw new InternalErrorException ("Predefined ctor redefined");
+                       var ctor = module.PredefinedMembers.DebuggerBrowsableAttributeCtor.Get ();
+                       if (ctor == null)
+                               return;
 
-                       if (!Resolve (false))
-                               return false;
+                       AttributeEncoder encoder = new AttributeEncoder ();
+                       encoder.Encode ((int) state);
+                       encoder.EncodeEmptyNamedArguments ();
 
-                       ctor = TypeManager.GetPredefinedConstructor (type, loc, argType);
-                       return ctor != null;
+                       builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ());
+               }
+       }
+
+       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)
+               {
+                       var ctor = module.PredefinedMembers.DecimalConstantAttributeCtor.Resolve (loc);
+                       if (ctor == null)
+                               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 ();
+
+                       builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ());
+               }
+
+               public void EmitAttribute (FieldBuilder builder, decimal value, Location loc)
+               {
+                       var ctor = module.PredefinedMembers.DecimalConstantAttributeCtor.Resolve (loc);
+                       if (ctor == null)
+                               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 ();
+
+                       builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ());
+               }
+       }
+
+       public class PredefinedDynamicAttribute : PredefinedAttribute
+       {
+               MethodSpec tctor;
+
+               public PredefinedDynamicAttribute (ModuleContainer module, string ns, string name)
+                       : base (module, ns, name)
+               {
                }
 
-               public Type Type {
-                       get { return type; }
+               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.BuiltinType == BuiltinTypeSpec.Type.Dynamic)
+                               return new bool[] { true };
+
+                       return null;
+               }
+
+               bool ResolveTransformationCtor (Location loc)
+               {
+                       if (tctor != null)
+                               return true;
+
+                       tctor = module.PredefinedMembers.DynamicAttributeCtor.Resolve (loc);
+                       return tctor != null;
                }
        }
 }