+ //\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
+ if (opt_attrs.AttributeSections == null)\r
+ return;\r
+\r
+ foreach (AttributeSection asec in opt_attrs.AttributeSections) {\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
+ Error_AttributeNotValidForElement (a, loc);\r
+ return;\r
+ }\r
+\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
+ } else if (kind is Constructor) {\r
+ ((ConstructorBuilder) builder).SetCustomAttribute (cb);\r
+ } else if (kind is Field) {\r
+ ((FieldBuilder) builder).SetCustomAttribute (cb);\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
+ 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
+ TypeContainer tc = (TypeContainer) kind;\r
+ \r
+ if (a.UsageAttr) {\r
+ tc.Targets = a.Targets;\r
+ tc.AllowMultiple = a.AllowMultiple;\r
+ tc.Inherited = a.Inherited;\r
+ \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
+ 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
+ } 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
+\r