2002-11-16 Martin Baulig <martin@ximian.com>
[mono.git] / mcs / mcs / attribute.cs
index d3b1ad64b2df886ee5e92c85a63ab73d9dd1fbc0..b939cf436ba46b09f46ef580e6a2f015cf3f41a5 100644 (file)
 //\r
 \r
 using System;\r
+using System.Diagnostics;\r
 using System.Collections;\r
 using System.Reflection;\r
 using System.Reflection.Emit;\r
 using System.Runtime.InteropServices;\r
+using System.Runtime.CompilerServices;\r
 using System.Text;\r
 \r
 namespace Mono.CSharp {\r
@@ -30,11 +32,15 @@ namespace Mono.CSharp {
                // The following are only meaningful when the attribute\r
                // being emitted is one of the builtin ones\r
                //\r
-               public AttributeTargets Targets;\r
-               public bool AllowMultiple;\r
-               public bool Inherited;\r
+               AttributeTargets Targets;\r
+               bool AllowMultiple;\r
+               bool Inherited;\r
 \r
-               public bool UsageAttr = false;\r
+               bool UsageAttr = false;\r
+               \r
+               MethodImplOptions ImplOptions;\r
+               UnmanagedType     UnmanagedType;\r
+               CustomAttributeBuilder cb;\r
                \r
                public Attribute (string name, ArrayList args, Location loc)\r
                {\r
@@ -43,7 +49,7 @@ namespace Mono.CSharp {
                        Location = loc;\r
                }\r
 \r
-               void error617 (string name)\r
+               void Error_InvalidNamedArgument (string name)\r
                {\r
                        Report.Error (617, Location, "'" + name + "' is not a valid named attribute " +\r
                                      "argument. Named attribute arguments must be fields which are not " +\r
@@ -51,55 +57,97 @@ namespace Mono.CSharp {
                                      "are not static.");\r
                }\r
 \r
-               void error182 ()\r
+               void Error_AttributeArgumentNotValid ()\r
                {\r
                        Report.Error (182, Location,\r
                                      "An attribute argument must be a constant expression, typeof " +\r
                                      "expression or array creation expression");\r
                }\r
 \r
-               public CustomAttributeBuilder Resolve (EmitContext ec)\r
+               static void Error_AttributeConstructorMismatch (Location loc)\r
                {\r
-                       string name = Name;\r
+                       Report.Error (\r
+                                       -6, loc,\r
+                                       "Could not find a constructor for this argument list.");\r
+               }\r
+               \r
+               private Type CheckAttributeType (EmitContext ec) {\r
+                       Type t;\r
+                       bool isattributeclass = true;\r
+                       \r
+                       t = RootContext.LookupType (ec.DeclSpace, Name, true, Location);\r
+                       if (t != null) {\r
+                               isattributeclass = t.IsSubclassOf (TypeManager.attribute_type);\r
+                               if (isattributeclass)\r
+                                       return t;\r
+                       }\r
+                       t = RootContext.LookupType (ec.DeclSpace, Name + "Attribute", true, Location);\r
+                       if (t != null) {\r
+                               if (t.IsSubclassOf (TypeManager.attribute_type))\r
+                                       return t;\r
+                       }\r
+                       if (!isattributeclass) {\r
+                               Report.Error (616, Location, "'" + Name + "': is not an attribute class");\r
+                               return null;\r
+                       }\r
+                       if (t != null) {\r
+                               Report.Error (616, Location, "'" + Name + "Attribute': is not an attribute class");\r
+                               return null;\r
+                       }\r
+                       Report.Error (\r
+                               246, Location, "Could not find attribute '" + Name + "' (are you" +\r
+                               " missing a using directive or an assembly reference ?)");\r
+                       return null;\r
+               }\r
 \r
-                       UsageAttr = false;\r
+               public Type ResolveType (EmitContext ec)\r
+               {\r
+                       Type = CheckAttributeType (ec);\r
+                       return Type;\r
+               }\r
 \r
-                       if (Name.IndexOf ("Attribute") == -1)\r
-                               name = Name + "Attribute";\r
-                       else if (Name.LastIndexOf ("Attribute") == 0)\r
-                               name = Name + "Attribute";\r
+               \r
+               public CustomAttributeBuilder Resolve (EmitContext ec)\r
+               {\r
+                       if (Type == null)\r
+                               Type = CheckAttributeType (ec);\r
+                       if (Type == null)\r
+                               return null;\r
 \r
-                       Type = RootContext.LookupType (ec.TypeContainer, name, false, Location);\r
+                       bool MethodImplAttr = false;\r
+                       bool MarshalAsAttr = false;\r
 \r
-                       if (Type == null) {\r
-                               Report.Error (\r
-                                       246, Location, "Could not find attribute '" + Name + "' (are you" +\r
-                                       " missing a using directive or an assembly reference ?)");\r
-                               return null;\r
-                       }\r
+                       UsageAttr = false;\r
 \r
                        if (Type == TypeManager.attribute_usage_type)\r
                                UsageAttr = true;\r
-                       \r
+                       if (Type == TypeManager.methodimpl_attr_type)\r
+                               MethodImplAttr = true;\r
+                       if (Type == TypeManager.marshal_as_attr_type)\r
+                               MarshalAsAttr = true;\r
+\r
                        // Now we extract the positional and named arguments\r
                        \r
                        ArrayList pos_args = new ArrayList ();\r
                        ArrayList named_args = new ArrayList ();\r
+                       int pos_arg_count = 0;\r
                        \r
                        if (Arguments != null) {\r
                                pos_args = (ArrayList) Arguments [0];\r
+                               if (pos_args != null)\r
+                                       pos_arg_count = pos_args.Count;\r
                                if (Arguments.Count > 1)\r
                                        named_args = (ArrayList) Arguments [1];\r
                        }\r
-                               \r
-                       object [] pos_values = new object [pos_args.Count];\r
+\r
+                       object [] pos_values = new object [pos_arg_count];\r
 \r
                        //\r
                        // First process positional arguments \r
                        //\r
-                       \r
+\r
                        int i;\r
-                       for (i = 0; i < pos_args.Count; i++) {\r
+                       for (i = 0; i < pos_arg_count; i++) {\r
                                Argument a = (Argument) pos_args [i];\r
                                Expression e;\r
 \r
@@ -107,15 +155,25 @@ namespace Mono.CSharp {
                                        return null;\r
 \r
                                e = a.Expr;\r
+\r
                                if (e is Constant) {\r
                                        pos_values [i] = ((Constant) e).GetValue ();\r
-\r
-                                       if (UsageAttr)\r
-                                               this.Targets = (AttributeTargets) pos_values [0];\r
-                               } else { \r
-                                       error182 ();\r
+                               } else if (e is TypeOf) {\r
+                                       pos_values [i] = ((TypeOf) e).TypeArg;\r
+                               } else {\r
+                                       Error_AttributeArgumentNotValid ();\r
                                        return null;\r
                                }\r
+                               \r
+                               if (UsageAttr)\r
+                                       this.Targets = (AttributeTargets) pos_values [0];\r
+                               \r
+                               if (MethodImplAttr)\r
+                                       this.ImplOptions = (MethodImplOptions) pos_values [0];\r
+                               \r
+                               if (MarshalAsAttr)\r
+                                       this.UnmanagedType =\r
+                                       (System.Runtime.InteropServices.UnmanagedType) pos_values [0];\r
                        }\r
 \r
                        //\r
@@ -126,7 +184,7 @@ namespace Mono.CSharp {
                        ArrayList prop_infos  = new ArrayList ();\r
                        ArrayList field_values = new ArrayList ();\r
                        ArrayList prop_values = new ArrayList ();\r
-\r
+                       \r
                        for (i = 0; i < named_args.Count; i++) {\r
                                DictionaryEntry de = (DictionaryEntry) named_args [i];\r
                                string member_name = (string) de.Key;\r
@@ -137,13 +195,13 @@ namespace Mono.CSharp {
                                        return null;\r
 \r
                                Expression member = Expression.MemberLookup (\r
-                                       ec, Type, member_name, false,\r
+                                       ec, Type, member_name,\r
                                        MemberTypes.Field | MemberTypes.Property,\r
                                        BindingFlags.Public | BindingFlags.Instance,\r
                                        Location);\r
 \r
                                if (member == null || !(member is PropertyExpr || member is FieldExpr)) {\r
-                                       error617 (member_name);\r
+                                       Error_InvalidNamedArgument (member_name);\r
                                        return null;\r
                                }\r
 \r
@@ -153,7 +211,7 @@ namespace Mono.CSharp {
                                        PropertyInfo pi = pe.PropertyInfo;\r
 \r
                                        if (!pi.CanWrite) {\r
-                                               error617 (member_name);\r
+                                               Error_InvalidNamedArgument (member_name);\r
                                                return null;\r
                                        }\r
 \r
@@ -168,8 +226,10 @@ namespace Mono.CSharp {
                                                                this.Inherited = (bool) o;\r
                                                }\r
                                                \r
-                                       } else { \r
-                                               error182 ();\r
+                                       } else if (e is TypeOf) {\r
+                                               prop_values.Add (((TypeOf) e).TypeArg);\r
+                                       } else {\r
+                                               Error_AttributeArgumentNotValid ();\r
                                                return null;\r
                                        }\r
                                        \r
@@ -180,29 +240,34 @@ namespace Mono.CSharp {
                                        FieldInfo fi = fe.FieldInfo;\r
 \r
                                        if (fi.IsInitOnly) {\r
-                                               error617 (member_name);\r
+                                               Error_InvalidNamedArgument (member_name);\r
                                                return null;\r
                                        }\r
 \r
-                                       if (e is Constant)\r
-                                               field_values.Add (((Constant) e).GetValue ());\r
-                                       else { \r
-                                               error182 ();\r
+                                       //\r
+                                       // Handle charset here, and set the TypeAttributes\r
+                                       \r
+                                       if (e is Constant){\r
+                                               object value = ((Constant) e).GetValue ();\r
+                                               \r
+                                               field_values.Add (value);\r
+                                       } else if (e is TypeOf) {\r
+                                               field_values.Add (((TypeOf) e).TypeArg);\r
+                                       } else {\r
+                                               Error_AttributeArgumentNotValid ();\r
                                                return null;\r
                                        }\r
                                        \r
                                        field_infos.Add (fi);\r
                                }\r
                        }\r
-                       \r
+\r
                        Expression mg = Expression.MemberLookup (\r
-                               ec, Type, ".ctor", false, MemberTypes.Constructor,\r
+                               ec, Type, ".ctor", MemberTypes.Constructor,\r
                                BindingFlags.Public | BindingFlags.Instance, Location);\r
 \r
                        if (mg == null) {\r
-                               Report.Error (\r
-                                       -6, Location,\r
-                                       "Could not find a constructor for this argument list.");\r
+                               Error_AttributeConstructorMismatch (Location);\r
                                return null;\r
                        }\r
 \r
@@ -210,11 +275,26 @@ namespace Mono.CSharp {
                                ec, (MethodGroupExpr) mg, pos_args, Location);\r
 \r
                        if (constructor == null) {\r
-                               Report.Error (\r
-                                       -6, Location,\r
-                                       "Could not find a constructor for this argument list.");\r
+                               Error_AttributeConstructorMismatch (Location);\r
                                return null;\r
                        }\r
+\r
+                       //\r
+                       // Now we perform some checks on the positional args as they\r
+                       // cannot be null for a constructor which expects a parameter\r
+                       // of type object\r
+                       //\r
+\r
+                       ParameterData pd = Invocation.GetParameterData (constructor);\r
+\r
+                       for (int j = 0; j < pos_arg_count; ++j) {\r
+                               Argument a = (Argument) pos_args [j];\r
+                               \r
+                               if (a.Expr is NullLiteral && pd.ParameterType (j) == TypeManager.object_type) {\r
+                                       Error_AttributeArgumentNotValid ();\r
+                                       return null;\r
+                               }\r
+                       }\r
                        \r
                        PropertyInfo [] prop_info_arr = new PropertyInfo [prop_infos.Count];\r
                        FieldInfo [] field_info_arr = new FieldInfo [field_infos.Count];\r
@@ -226,11 +306,31 @@ namespace Mono.CSharp {
 \r
                        prop_values.CopyTo  (prop_values_arr, 0);\r
                        prop_infos.CopyTo   (prop_info_arr, 0);\r
-                       \r
-                       CustomAttributeBuilder cb = new CustomAttributeBuilder (\r
-                               (ConstructorInfo) constructor, pos_values,\r
-                               prop_info_arr, prop_values_arr,\r
-                               field_info_arr, field_values_arr); \r
+\r
+                       try {\r
+                               cb = new CustomAttributeBuilder (\r
+                                       (ConstructorInfo) constructor, pos_values,\r
+                                       prop_info_arr, prop_values_arr,\r
+                                       field_info_arr, field_values_arr); \r
+\r
+                       } catch (NullReferenceException) {\r
+                               // \r
+                               // Don't know what to do here\r
+                               //\r
+                               Report.Warning (\r
+                                       -100, Location, "NullReferenceException while trying to create attribute. Something's wrong!");\r
+                       } catch {\r
+                               //\r
+                               // Sample:\r
+                               // using System.ComponentModel;\r
+                               // [DefaultValue (CollectionChangeAction.Add)]\r
+                               // class X { static void Main () {} }\r
+                               //\r
+                               Report.Warning (\r
+                                       -23, Location,\r
+                                       "The compiler can not encode this attribute in .NET due to\n" +\r
+                                       "\ta bug in the .NET runtime.  Try the Mono runtime");\r
+                       }\r
                        \r
                        return cb;\r
                }\r
@@ -243,11 +343,24 @@ namespace Mono.CSharp {
                        TypeContainer a = TypeManager.LookupAttr (attr.Type);\r
 \r
                        if (a == null) {\r
-                               System.Attribute [] attrs = System.Attribute.GetCustomAttributes (attr.Type);\r
                                \r
+                               System.Attribute [] attrs = null;\r
+                               \r
+                               try {\r
+                                       attrs = System.Attribute.GetCustomAttributes (attr.Type);\r
+                                       \r
+                               } catch {\r
+                                       Report.Error (-20, attr.Location, "Cannot find attribute type " + attr.Name +\r
+                                                     " (maybe you forgot to set the usage using the" +\r
+                                                     " AttributeUsage attribute ?).");\r
+                                       return null;\r
+                               }\r
+                                       \r
                                foreach (System.Attribute tmp in attrs)\r
-                                       if (tmp is AttributeUsageAttribute) \r
+                                       if (tmp is AttributeUsageAttribute) {\r
                                                targets = ((AttributeUsageAttribute) tmp).ValidOn;\r
+                                               break;\r
+                                       }\r
                        } else\r
                                targets = a.Targets;\r
 \r
@@ -298,20 +411,34 @@ namespace Mono.CSharp {
 \r
                }\r
 \r
-               public static void error592 (Attribute a, Location loc)\r
+               public static void Error_AttributeNotValidForElement (Attribute a, Location loc)\r
                {\r
-                       Report.Error (592, loc, "Attribute '" + a.Name + "' is not valid on this declaration type. " +\r
-                                     "It is valid on " + GetValidPlaces (a) + "declarations only.");\r
+                       Report.Error (\r
+                               592, loc, "Attribute '" + a.Name +\r
+                               "' is not valid on this declaration type. " +\r
+                               "It is valid on " + GetValidPlaces (a) + "declarations only.");\r
                }\r
 \r
                public static bool CheckAttribute (Attribute a, object element)\r
                {\r
                        TypeContainer attr = TypeManager.LookupAttr (a.Type);\r
                        AttributeTargets targets = 0;\r
+\r
                        \r
                        if (attr == null) {\r
-                               System.Attribute [] attrs = System.Attribute.GetCustomAttributes (a.Type);\r
 \r
+                               System.Attribute [] attrs = null;\r
+                               \r
+                               try {\r
+                                       attrs = System.Attribute.GetCustomAttributes (a.Type);\r
+\r
+                               } catch {\r
+                                       Report.Error (-20, a.Location, "Cannot find attribute type " + a.Name +\r
+                                                     " (maybe you forgot to set the usage using the" +\r
+                                                     " AttributeUsage attribute ?).");\r
+                                       return false;\r
+                               }\r
+                                       \r
                                foreach (System.Attribute tmp in attrs)\r
                                        if (tmp is AttributeUsageAttribute) \r
                                                targets = ((AttributeUsageAttribute) tmp).ValidOn;\r
@@ -344,12 +471,12 @@ namespace Mono.CSharp {
                                        return true;\r
                                else\r
                                        return false;\r
-                       } else if (element is Event) {\r
+                       } else if (element is Event || element is InterfaceEvent) {\r
                                if ((targets & AttributeTargets.Event) != 0)\r
                                        return true;\r
                                else\r
                                        return false;\r
-                       } else if (element is Field) {\r
+                       } else if (element is Field || element is FieldBuilder) {\r
                                if ((targets & AttributeTargets.Field) != 0)\r
                                        return true;\r
                                else\r
@@ -359,76 +486,218 @@ namespace Mono.CSharp {
                                        return true;\r
                                else\r
                                        return false;\r
-                       } else if (element is Method) {\r
+                       } else if (element is Method || element is Operator || element is InterfaceMethod || element is Accessor) {\r
                                if ((targets & AttributeTargets.Method) != 0)\r
                                        return true;\r
                                else\r
                                        return false;\r
-                       } else if (element is Parameter) {\r
+                       } else if (element is ParameterBuilder) {\r
                                if ((targets & AttributeTargets.Parameter) != 0)\r
                                        return true;\r
                                else\r
                                        return false;\r
-                       } else if (element is Property) {\r
+                       } else if (element is Property || element is Indexer ||\r
+                                  element is InterfaceProperty || element is InterfaceIndexer) {\r
                                if ((targets & AttributeTargets.Property) != 0)\r
                                        return true;\r
                                else\r
                                        return false;\r
+                       } else if (element is AssemblyBuilder){\r
+                               if ((targets & AttributeTargets.Assembly) != 0)\r
+                                       return true;\r
+                               else\r
+                                       return false;\r
                        }\r
 \r
                        return false;\r
                }\r
 \r
+               //\r
+               // This method should be invoked to pull the IndexerName attribute from an\r
+               // Indexer if it exists.\r
+               //\r
+               public static string ScanForIndexerName (EmitContext ec, Attributes opt_attrs)\r
+               {\r
+                       if (opt_attrs == null)\r
+                               return null;\r
+                       if (opt_attrs.AttributeSections == null)\r
+                               return null;\r
+\r
+                       foreach (AttributeSection asec in opt_attrs.AttributeSections) {\r
+                               if (asec.Attributes == null)\r
+                                       continue;\r
+\r
+                               foreach (Attribute a in asec.Attributes){\r
+                                       if (a.ResolveType (ec) == null)\r
+                                               return null;\r
+                                       \r
+                                       if (a.Type != TypeManager.indexer_name_type)\r
+                                               continue;\r
+\r
+                                       //\r
+                                       // So we have found an IndexerName, pull the data out.\r
+                                       //\r
+                                       if (a.Arguments == null || a.Arguments [0] == null){\r
+                                               Error_AttributeConstructorMismatch (a.Location);\r
+                                               return null;\r
+                                       }\r
+                                       ArrayList pos_args = (ArrayList) a.Arguments [0];\r
+                                       if (pos_args.Count == 0){\r
+                                               Error_AttributeConstructorMismatch (a.Location);\r
+                                               return null;\r
+                                       }\r
+                                       \r
+                                       Argument arg = (Argument) pos_args [0];\r
+                                       if (!arg.Resolve (ec, a.Location))\r
+                                               return null;\r
+                                       \r
+                                       Expression e = arg.Expr;\r
+                                       if (!(e is StringConstant)){\r
+                                               Error_AttributeConstructorMismatch (a.Location);\r
+                                               return null;\r
+                                       }\r
+\r
+                                       //\r
+                                       // Remove the attribute from the list\r
+                                       //\r
+                                       asec.Attributes.Remove (a);\r
+\r
+                                       return (((StringConstant) e).Value);\r
+                               }\r
+                       }\r
+                       return null;\r
+               }\r
+\r
+               //\r
+               // This pulls the condition name out of a Conditional attribute\r
+               //\r
+               public string Conditional_GetConditionName ()\r
+               {\r
+                       //\r
+                       // So we have a Conditional, pull the data out.\r
+                       //\r
+                       if (Arguments == null || Arguments [0] == null){\r
+                               Error_AttributeConstructorMismatch (Location);\r
+                               return null;\r
+                       }\r
+\r
+                       ArrayList pos_args = (ArrayList) Arguments [0];\r
+                       if (pos_args.Count != 1){\r
+                               Error_AttributeConstructorMismatch (Location);\r
+                               return null;\r
+                       }\r
+\r
+                       Argument arg = (Argument) pos_args [0]; \r
+                       if (!(arg.Expr is StringConstant)){\r
+                               Error_AttributeConstructorMismatch (Location);\r
+                               return null;\r
+                       }\r
+\r
+                       return ((StringConstant) arg.Expr).Value;\r
+               }\r
+\r
+               //\r
+               // This pulls the obsolete message and error flag out of an Obsolete attribute\r
+               //\r
+               public string Obsolete_GetObsoleteMessage (out bool is_error)\r
+               {\r
+                       is_error = false;\r
+                       //\r
+                       // So we have an Obsolete, pull the data out.\r
+                       //\r
+                       if (Arguments == null || Arguments [0] == null)\r
+                               return "";\r
+\r
+                       ArrayList pos_args = (ArrayList) Arguments [0];\r
+                       if (pos_args.Count == 0)\r
+                               return "";\r
+                       else if (pos_args.Count > 2){\r
+                               Error_AttributeConstructorMismatch (Location);\r
+                               return null;\r
+                       }\r
+\r
+                       Argument arg = (Argument) pos_args [0]; \r
+                       if (!(arg.Expr is StringConstant)){\r
+                               Error_AttributeConstructorMismatch (Location);\r
+                               return null;\r
+                       }\r
+\r
+                       if (pos_args.Count == 2){\r
+                               Argument arg2 = (Argument) pos_args [1];\r
+                               if (!(arg2.Expr is BoolConstant)){\r
+                                       Error_AttributeConstructorMismatch (Location);\r
+                                       return null;\r
+                               }\r
+                               is_error = ((BoolConstant) arg2.Expr).Value;\r
+                       }\r
+\r
+                       return ((StringConstant) arg.Expr).Value;\r
+               }\r
+\r
+               //\r
+               // Applies the attributes to the `builder'.\r
+               //\r
                public static void ApplyAttributes (EmitContext ec, object builder, object kind,\r
                                                    Attributes opt_attrs, Location loc)\r
                {\r
                        if (opt_attrs == null)\r
                                return;\r
-\r
                        if (opt_attrs.AttributeSections == null)\r
                                return;\r
 \r
                        foreach (AttributeSection asec in opt_attrs.AttributeSections) {\r
-\r
                                if (asec.Attributes == null)\r
                                        continue;\r
 \r
+                               if (asec.Target == "assembly" && !(builder is AssemblyBuilder))\r
+                                       continue;\r
+                               \r
                                foreach (Attribute a in asec.Attributes) {\r
                                        CustomAttributeBuilder cb = a.Resolve (ec);\r
+\r
                                        if (cb == null)\r
                                                continue;\r
 \r
                                        if (!(kind is TypeContainer))\r
                                                if (!CheckAttribute (a, kind)) {\r
-                                                       error592 (a, loc);\r
+                                                       Error_AttributeNotValidForElement (a, loc);\r
                                                        return;\r
                                                }\r
 \r
-                                       \r
-                                       if (kind is Method) {\r
-                                               if (a.Type != TypeManager.dllimport_type)\r
+                                       if (kind is Method || kind is Operator || kind is InterfaceMethod ||\r
+                                           kind is Accessor) {\r
+                                               if (a.Type == TypeManager.methodimpl_attr_type) {\r
+                                                       if (a.ImplOptions == MethodImplOptions.InternalCall)\r
+                                                               ((MethodBuilder) builder).\r
+                                                               SetImplementationFlags (\r
+                                                                       MethodImplAttributes.InternalCall |\r
+                                                                       MethodImplAttributes.Runtime);\r
+                                               } else if (a.Type != TypeManager.dllimport_type){\r
                                                        ((MethodBuilder) builder).SetCustomAttribute (cb);\r
-\r
+                                               }\r
                                        } else if (kind is Constructor) {\r
                                                ((ConstructorBuilder) builder).SetCustomAttribute (cb);\r
-\r
                                        } else if (kind is Field) {\r
                                                ((FieldBuilder) builder).SetCustomAttribute (cb);\r
-\r
-                                       } else if (kind is Property || kind is Indexer) {\r
+                                       } else if (kind is Property || kind is Indexer ||\r
+                                                  kind is InterfaceProperty || kind is InterfaceIndexer) {\r
                                                ((PropertyBuilder) builder).SetCustomAttribute (cb);\r
+                                       } else if (kind is Event || kind is InterfaceEvent) {\r
+                                               ((MyEventBuilder) builder).SetCustomAttribute (cb);\r
+                                       } else if (kind is ParameterBuilder) {\r
 \r
-                                       } else if (kind is Event) {\r
-                                               ((EventBuilder) builder).SetCustomAttribute (cb);\r
-\r
-                                       } else if (kind is Operator) {\r
-                                               ((MethodBuilder) builder).SetCustomAttribute (cb);\r
-\r
+                                               if (a.Type == TypeManager.marshal_as_attr_type) {\r
+                                                       UnmanagedMarshal marshal =\r
+                                                               UnmanagedMarshal.DefineUnmanagedMarshal (a.UnmanagedType);\r
+                                                       \r
+                                                       ((ParameterBuilder) builder).SetMarshal (marshal);\r
+                                               } else \r
+                                                       ((ParameterBuilder) builder).SetCustomAttribute (cb);\r
+                                               \r
                                        } else if (kind is Enum) {\r
                                                ((TypeBuilder) builder).SetCustomAttribute (cb); \r
 \r
                                        } else if (kind is TypeContainer) {\r
-\r
                                                TypeContainer tc = (TypeContainer) kind;\r
                                                \r
                                                if (a.UsageAttr) {\r
@@ -436,19 +705,59 @@ namespace Mono.CSharp {
                                                        tc.AllowMultiple = a.AllowMultiple;\r
                                                        tc.Inherited = a.Inherited;\r
                                                        \r
-                                                       RootContext.TypeManager.RegisterAttrType (\r
-                                                                                (TypeBuilder) builder, tc);\r
+                                               } else if (a.Type == TypeManager.default_member_type) {\r
+                                                       if (tc.Indexers != null) {\r
+                                                               Report.Error (646, loc,\r
+                                                                     "Cannot specify the DefaultMember attribute on" +\r
+                                                                     " a type containing an indexer");\r
+                                                               return;\r
+                                                       }\r
 \r
                                                } else {\r
                                                        if (!CheckAttribute (a, kind)) {\r
-                                                               error592 (a, loc);\r
+                                                               Error_AttributeNotValidForElement (a, loc);\r
                                                                return;\r
                                                        }\r
                                                }\r
+\r
+                                               try {\r
+                                                       ((TypeBuilder) builder).SetCustomAttribute (cb);\r
+                                               } catch (System.ArgumentException) {\r
+                                                       Report.Warning (\r
+                                                               -21, loc,\r
+                                               "The CharSet named property on StructLayout\n"+\r
+                                               "\tdoes not work correctly on Microsoft.NET\n"+\r
+                                               "\tYou might want to remove the CharSet declaration\n"+\r
+                                               "\tor compile using the Mono runtime instead of the\n"+\r
+                                               "\tMicrosoft .NET runtime");\r
+                                               }\r
                                                \r
+                                       } else if (kind is Interface) {\r
+                                               Interface iface = (Interface) kind;\r
+\r
+                                               if ((a.Type == TypeManager.default_member_type) &&\r
+                                                   (iface.InterfaceIndexers != null)) {\r
+                                                       Report.Error (\r
+                                                               646, loc,\r
+                                                               "Cannot specify the DefaultMember attribute on" +\r
+                                                               " a type containing an indexer");\r
+                                                       return;\r
+                                               }\r
+\r
+                                               if (!CheckAttribute (a, kind)) {\r
+                                                       Error_AttributeNotValidForElement (a, loc);\r
+                                                       return;\r
+                                               }\r
+\r
                                                ((TypeBuilder) builder).SetCustomAttribute (cb);\r
-                                               \r
-                                       }\r
+                                       } else if (kind is AssemblyBuilder){\r
+                                               ((AssemblyBuilder) builder).SetCustomAttribute (cb);\r
+                                       } else if (kind is ModuleBuilder) {\r
+                                               ((ModuleBuilder) builder).SetCustomAttribute (cb);\r
+                                       } else if (kind is FieldBuilder) {\r
+                                               ((FieldBuilder) builder).SetCustomAttribute (cb);\r
+                                       } else\r
+                                               throw new Exception ("Unknown kind: " + kind);\r
                                }\r
                        }\r
                }\r
@@ -465,20 +774,9 @@ namespace Mono.CSharp {
                                return null;\r
                        }\r
 \r
-                       string attr_name = Name;\r
-\r
-                       if (Name.IndexOf ("Attribute") == -1)\r
-                               attr_name = Name + "Attribute";\r
-                       else if (Name.LastIndexOf ("Attribute") == 0)\r
-                               attr_name = Name + "Attribute";\r
-                       \r
-                       Type = RootContext.LookupType (ec.TypeContainer, attr_name, false, Location);\r
-\r
-                       if (Type == null) {\r
-                               Report.Error (246, Location, "Could not find attribute '" + Name + "' (are you" +\r
-                                             " missing a using directive or an assembly reference ?)");\r
+                       Type = CheckAttributeType (ec);\r
+                       if (Type == null)\r
                                return null;\r
-                       }\r
                        \r
                        ArrayList named_args = new ArrayList ();\r
                        \r
@@ -497,18 +795,18 @@ namespace Mono.CSharp {
                        if (tmp.Expr is Constant)\r
                                dll_name = (string) ((Constant) tmp.Expr).GetValue ();\r
                        else { \r
-                               error182 ();\r
+                               Error_AttributeArgumentNotValid ();\r
                                return null;\r
                        }\r
 \r
                        // Now we process the named arguments\r
-                       CallingConvention cc = 0;\r
-                       CharSet charset = 0;\r
-                       bool preserve_sig = false;\r
+                       CallingConvention cc = CallingConvention.Winapi;\r
+                       CharSet charset = CharSet.Ansi;\r
+                       bool preserve_sig = true;\r
                        bool exact_spelling = false;\r
                        bool set_last_err = false;\r
                        string entry_point = null;\r
-                       \r
+\r
                        for (int i = 0; i < named_args.Count; i++) {\r
 \r
                                DictionaryEntry de = (DictionaryEntry) named_args [i];\r
@@ -519,13 +817,14 @@ namespace Mono.CSharp {
                                if (!a.Resolve (ec, Location))\r
                                        return null;\r
 \r
-                               Expression member = Expression.MemberLookup (ec, Type, member_name, false,\r
-                                                                            MemberTypes.Field | MemberTypes.Property,\r
-                                                                            BindingFlags.Public | BindingFlags.Instance,\r
-                                                                            Location);\r
+                               Expression member = Expression.MemberLookup (\r
+                                       ec, Type, member_name, \r
+                                       MemberTypes.Field | MemberTypes.Property,\r
+                                       BindingFlags.Public | BindingFlags.Instance,\r
+                                       Location);\r
 \r
                                if (member == null || !(member is FieldExpr)) {\r
-                                       error617 (member_name);\r
+                                       Error_InvalidNamedArgument (member_name);\r
                                        return null;\r
                                }\r
 \r
@@ -534,7 +833,7 @@ namespace Mono.CSharp {
                                        FieldInfo fi = fe.FieldInfo;\r
 \r
                                        if (fi.IsInitOnly) {\r
-                                               error617 (member_name);\r
+                                               Error_InvalidNamedArgument (member_name);\r
                                                return null;\r
                                        }\r
 \r
@@ -554,20 +853,26 @@ namespace Mono.CSharp {
                                                else if (member_name == "PreserveSig")\r
                                                        preserve_sig = (bool) c.GetValue ();\r
                                        } else { \r
-                                               error182 ();\r
+                                               Error_AttributeArgumentNotValid ();\r
                                                return null;\r
                                        }\r
                                        \r
                                }\r
                        }\r
 \r
+                       if (entry_point == null)\r
+                               entry_point = name;\r
+                       \r
                        MethodBuilder mb = builder.DefinePInvokeMethod (\r
-                               name, dll_name, flags,\r
+                               name, dll_name, entry_point, flags | MethodAttributes.HideBySig,\r
                                CallingConventions.Standard,\r
                                ret_type,\r
                                param_types,\r
                                cc,\r
-                               charset); \r
+                               charset);\r
+\r
+                       if (preserve_sig)\r
+                               mb.SetImplementationFlags (MethodImplAttributes.PreserveSig);\r
                        \r
                        return mb;\r
                }\r
@@ -588,10 +893,10 @@ namespace Mono.CSharp {
        }\r
 \r
        public class Attributes {\r
-\r
                public ArrayList AttributeSections;\r
+               public Location Location;\r
 \r
-               public Attributes (AttributeSection a)\r
+               public Attributes (AttributeSection a, Location loc)\r
                {\r
                        AttributeSections = new ArrayList ();\r
                        AttributeSections.Add (a);\r