//\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
// 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
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
"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
- int i;\r
- for (i = 0; i < pos_args.Count; i++) {\r
\r
+ int i;\r
+ for (i = 0; i < pos_arg_count; i++) {\r
Argument a = (Argument) pos_args [i];\r
+ Expression e;\r
\r
if (!a.Resolve (ec, Location))\r
return null;\r
\r
- Expression e = Expression.Reduce (ec, a.Expr);\r
-\r
- if (e is Literal) {\r
- pos_values [i] = ((Literal) e).GetValue ();\r
+ e = a.Expr;\r
\r
- if (UsageAttr)\r
- this.Targets = (AttributeTargets) pos_values [0];\r
- } else { \r
- error182 ();\r
+ if (e is Constant) {\r
+ pos_values [i] = ((Constant) e).GetValue ();\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
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
-\r
DictionaryEntry de = (DictionaryEntry) named_args [i];\r
-\r
string member_name = (string) de.Key;\r
Argument a = (Argument) de.Value;\r
-\r
+ Expression e;\r
+ \r
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 PropertyExpr || member is FieldExpr)) {\r
- error617 (member_name);\r
+ Error_InvalidNamedArgument (member_name);\r
return null;\r
}\r
\r
+ e = a.Expr;\r
if (member is PropertyExpr) {\r
PropertyExpr pe = (PropertyExpr) member;\r
PropertyInfo pi = pe.PropertyInfo;\r
\r
if (!pi.CanWrite) {\r
- error617 (member_name);\r
+ Error_InvalidNamedArgument (member_name);\r
return null;\r
}\r
\r
- Expression e = Expression.Reduce (ec, a.Expr);\r
- \r
- if (e is Literal) {\r
- object o = ((Literal) e).GetValue ();\r
+ if (e is Constant) {\r
+ object o = ((Constant) e).GetValue ();\r
prop_values.Add (o);\r
\r
if (UsageAttr) {\r
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
FieldInfo fi = fe.FieldInfo;\r
\r
if (fi.IsInitOnly) {\r
- error617 (member_name);\r
+ Error_InvalidNamedArgument (member_name);\r
return null;\r
}\r
\r
- Expression e = Expression.Reduce (ec, a.Expr);\r
+ //\r
+ // Handle charset here, and set the TypeAttributes\r
\r
- if (e is Literal)\r
- field_values.Add (((Literal) e).GetValue ());\r
- else { \r
- error182 ();\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
- Expression mg = Expression.MemberLookup (ec, Type, ".ctor", false,\r
- MemberTypes.Constructor,\r
- BindingFlags.Public | BindingFlags.Instance,\r
- Location);\r
+\r
+ Expression mg = Expression.MemberLookup (\r
+ ec, Type, ".ctor", MemberTypes.Constructor,\r
+ BindingFlags.Public | BindingFlags.Instance, Location);\r
\r
if (mg == null) {\r
- Report.Error (-6, Location, "Could not find a constructor for this argument list.");\r
+ Error_AttributeConstructorMismatch (Location);\r
return null;\r
}\r
\r
- MethodBase constructor = Invocation.OverloadResolve (ec, (MethodGroupExpr) mg, pos_args, Location);\r
+ MethodBase constructor = Invocation.OverloadResolve (\r
+ ec, (MethodGroupExpr) mg, pos_args, Location);\r
\r
if (constructor == null) {\r
- Report.Error (-6, Location, "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
\r
prop_values.CopyTo (prop_values_arr, 0);\r
prop_infos.CopyTo (prop_info_arr, 0);\r
- \r
- CustomAttributeBuilder cb = new CustomAttributeBuilder ((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
+ } 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
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
\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
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
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
+ 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
public MethodBuilder DefinePInvokeMethod (EmitContext ec, TypeBuilder builder, string name,\r
MethodAttributes flags, Type ret_type, Type [] param_types)\r
{\r
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
if (!tmp.Resolve (ec, Location))\r
return null;\r
\r
- Expression exp = Expression.Reduce (ec, tmp.Expr);\r
- \r
- if (exp is Literal)\r
- dll_name = (string) ((Literal) exp).GetValue ();\r
+ 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
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
FieldInfo fi = fe.FieldInfo;\r
\r
if (fi.IsInitOnly) {\r
- error617 (member_name);\r
+ Error_InvalidNamedArgument (member_name);\r
return null;\r
}\r
\r
- Expression e = Expression.Reduce (ec, a.Expr);\r
- \r
- if (e is Literal) {\r
- Literal l = (Literal) e;\r
+ if (a.Expr is Constant) {\r
+ Constant c = (Constant) a.Expr;\r
\r
if (member_name == "CallingConvention")\r
- cc = (CallingConvention) l.GetValue ();\r
+ cc = (CallingConvention) c.GetValue ();\r
else if (member_name == "CharSet")\r
- charset = (CharSet) l.GetValue ();\r
+ charset = (CharSet) c.GetValue ();\r
else if (member_name == "EntryPoint")\r
- entry_point = (string) l.GetValue ();\r
+ entry_point = (string) c.GetValue ();\r
else if (member_name == "SetLastError")\r
- set_last_err = (bool) l.GetValue ();\r
+ set_last_err = (bool) c.GetValue ();\r
else if (member_name == "ExactSpelling")\r
- exact_spelling = (bool) l.GetValue ();\r
+ exact_spelling = (bool) c.GetValue ();\r
else if (member_name == "PreserveSig")\r
- preserve_sig = (bool) l.GetValue ();\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
- CallingConventions.Standard,\r
- ret_type,\r
- param_types,\r
- cc,\r
- charset); \r
+ name, dll_name, entry_point, flags | MethodAttributes.HideBySig,\r
+ CallingConventions.Standard,\r
+ ret_type,\r
+ param_types,\r
+ cc,\r
+ charset);\r
+\r
+ if (preserve_sig)\r
+ mb.SetImplementationFlags (MethodImplAttributes.PreserveSig);\r
\r
return mb;\r
}\r
}\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