Fix typos.
[mono.git] / mcs / mcs / attribute.cs
1 //\r
2 // attribute.cs: Attribute Handler\r
3 //\r
4 // Author: Ravi Pratap (ravi@ximian.com)\r
5 //\r
6 // Licensed under the terms of the GNU GPL\r
7 //\r
8 // (C) 2001 Ximian, Inc (http://www.ximian.com)\r
9 //\r
10 //\r
11 \r
12 using System;\r
13 using System.Collections;\r
14 using System.Reflection;\r
15 using System.Reflection.Emit;\r
16 using System.Runtime.InteropServices;\r
17 using System.Runtime.CompilerServices;\r
18 using System.Text;\r
19 \r
20 namespace Mono.CSharp {\r
21 \r
22         public class Attribute {\r
23                 public readonly string    Name;\r
24                 public readonly ArrayList Arguments;\r
25 \r
26                 Location Location;\r
27 \r
28                 public Type Type;\r
29                 \r
30                 //\r
31                 // The following are only meaningful when the attribute\r
32                 // being emitted is one of the builtin ones\r
33                 //\r
34                 public AttributeTargets Targets;\r
35                 public bool AllowMultiple;\r
36                 public bool Inherited;\r
37 \r
38                 public bool UsageAttr = false;\r
39                 \r
40                 public MethodImplOptions ImplOptions;\r
41                 public UnmanagedType     UnmanagedType;\r
42                 \r
43                 public Attribute (string name, ArrayList args, Location loc)\r
44                 {\r
45                         Name = name;\r
46                         Arguments = args;\r
47                         Location = loc;\r
48                 }\r
49 \r
50                 void error617 (string name)\r
51                 {\r
52                         Report.Error (617, Location, "'" + name + "' is not a valid named attribute " +\r
53                                       "argument. Named attribute arguments must be fields which are not " +\r
54                                       "readonly, static or const, or properties with a set accessor which "+\r
55                                       "are not static.");\r
56                 }\r
57 \r
58                 void error182 ()\r
59                 {\r
60                         Report.Error (182, Location,\r
61                                       "An attribute argument must be a constant expression, typeof " +\r
62                                       "expression or array creation expression");\r
63                 }\r
64 \r
65                 public CustomAttributeBuilder Resolve (EmitContext ec)\r
66                 {\r
67                         string name = Name;\r
68                         bool MethodImplAttr = false;\r
69                         bool MarshalAsAttr = false;\r
70 \r
71                         UsageAttr = false;\r
72 \r
73                         if (Name.IndexOf ("Attribute") == -1)\r
74                                 name = Name + "Attribute";\r
75                         else if (Name.LastIndexOf ("Attribute") == 0)\r
76                                 name = Name + "Attribute";\r
77 \r
78                         Type = RootContext.LookupType (ec.DeclSpace, name, false, Location);\r
79 \r
80                         if (Type == null) {\r
81                                 Report.Error (\r
82                                         246, Location, "Could not find attribute '" + Name + "' (are you" +\r
83                                         " missing a using directive or an assembly reference ?)");\r
84                                 return null;\r
85                         }\r
86 \r
87                         if (Type == TypeManager.attribute_usage_type)\r
88                                 UsageAttr = true;\r
89                         if (Type == TypeManager.methodimpl_attr_type)\r
90                                 MethodImplAttr = true;\r
91                         if (Type == TypeManager.marshal_as_attr_type)\r
92                                 MarshalAsAttr = true;\r
93                         \r
94 \r
95                         // Now we extract the positional and named arguments\r
96                         \r
97                         ArrayList pos_args = new ArrayList ();\r
98                         ArrayList named_args = new ArrayList ();\r
99                         \r
100                         if (Arguments != null) {\r
101                                 pos_args = (ArrayList) Arguments [0];\r
102                                 if (Arguments.Count > 1)\r
103                                         named_args = (ArrayList) Arguments [1];\r
104                         }\r
105                                 \r
106                         object [] pos_values = new object [pos_args.Count];\r
107 \r
108                         //\r
109                         // First process positional arguments \r
110                         //\r
111                         \r
112                         int i;\r
113                         for (i = 0; i < pos_args.Count; i++) {\r
114                                 Argument a = (Argument) pos_args [i];\r
115                                 Expression e;\r
116 \r
117                                 if (!a.Resolve (ec, Location))\r
118                                         return null;\r
119 \r
120                                 e = a.Expr;\r
121                                 if (e is Constant) {\r
122                                         pos_values [i] = ((Constant) e).GetValue ();\r
123                                 } else if (e is TypeOf) {\r
124                                         pos_values [i] = ((TypeOf) e).TypeArg;\r
125                                 } else {\r
126                                         error182 ();\r
127                                         return null;\r
128                                 }\r
129                                 \r
130                                 if (UsageAttr)\r
131                                         this.Targets = (AttributeTargets) pos_values [0];\r
132                                 \r
133                                 if (MethodImplAttr)\r
134                                         this.ImplOptions = (MethodImplOptions) pos_values [0];\r
135                                 \r
136                                 if (MarshalAsAttr)\r
137                                         this.UnmanagedType =\r
138                                         (System.Runtime.InteropServices.UnmanagedType) pos_values [0];\r
139                         }\r
140 \r
141                         //\r
142                         // Now process named arguments\r
143                         //\r
144 \r
145                         ArrayList field_infos = new ArrayList ();\r
146                         ArrayList prop_infos  = new ArrayList ();\r
147                         ArrayList field_values = new ArrayList ();\r
148                         ArrayList prop_values = new ArrayList ();\r
149                         \r
150                         for (i = 0; i < named_args.Count; i++) {\r
151                                 DictionaryEntry de = (DictionaryEntry) named_args [i];\r
152                                 string member_name = (string) de.Key;\r
153                                 Argument a  = (Argument) de.Value;\r
154                                 Expression e;\r
155                                 \r
156                                 if (!a.Resolve (ec, Location))\r
157                                         return null;\r
158 \r
159                                 Expression member = Expression.MemberLookup (\r
160                                         ec, Type, member_name,\r
161                                         MemberTypes.Field | MemberTypes.Property,\r
162                                         BindingFlags.Public | BindingFlags.Instance,\r
163                                         Location);\r
164 \r
165                                 if (member == null || !(member is PropertyExpr || member is FieldExpr)) {\r
166                                         error617 (member_name);\r
167                                         return null;\r
168                                 }\r
169 \r
170                                 e = a.Expr;\r
171                                 if (member is PropertyExpr) {\r
172                                         PropertyExpr pe = (PropertyExpr) member;\r
173                                         PropertyInfo pi = pe.PropertyInfo;\r
174 \r
175                                         if (!pi.CanWrite) {\r
176                                                 error617 (member_name);\r
177                                                 return null;\r
178                                         }\r
179 \r
180                                         if (e is Constant) {\r
181                                                 object o = ((Constant) e).GetValue ();\r
182                                                 prop_values.Add (o);\r
183                                                 \r
184                                                 if (UsageAttr) {\r
185                                                         if (member_name == "AllowMultiple")\r
186                                                                 this.AllowMultiple = (bool) o;\r
187                                                         if (member_name == "Inherited")\r
188                                                                 this.Inherited = (bool) o;\r
189                                                 }\r
190                                                 \r
191                                         } else { \r
192                                                 error182 ();\r
193                                                 return null;\r
194                                         }\r
195                                         \r
196                                         prop_infos.Add (pi);\r
197                                         \r
198                                 } else if (member is FieldExpr) {\r
199                                         FieldExpr fe = (FieldExpr) member;\r
200                                         FieldInfo fi = fe.FieldInfo;\r
201 \r
202                                         if (fi.IsInitOnly) {\r
203                                                 error617 (member_name);\r
204                                                 return null;\r
205                                         }\r
206 \r
207                                         if (e is Constant)\r
208                                                 field_values.Add (((Constant) e).GetValue ());\r
209                                         else { \r
210                                                 error182 ();\r
211                                                 return null;\r
212                                         }\r
213                                         \r
214                                         field_infos.Add (fi);\r
215                                 }\r
216                         }\r
217                         \r
218                         Expression mg = Expression.MemberLookup (\r
219                                 ec, Type, ".ctor", MemberTypes.Constructor,\r
220                                 BindingFlags.Public | BindingFlags.Instance, Location);\r
221 \r
222                         if (mg == null) {\r
223                                 Report.Error (\r
224                                         -6, Location,\r
225                                         "Could not find a constructor for this argument list.");\r
226                                 return null;\r
227                         }\r
228 \r
229                         MethodBase constructor = Invocation.OverloadResolve (\r
230                                 ec, (MethodGroupExpr) mg, pos_args, Location);\r
231 \r
232                         if (constructor == null) {\r
233                                 Report.Error (\r
234                                         -6, Location,\r
235                                         "Could not find a constructor for this argument list.");\r
236                                 return null;\r
237                         }\r
238                         \r
239                         PropertyInfo [] prop_info_arr = new PropertyInfo [prop_infos.Count];\r
240                         FieldInfo [] field_info_arr = new FieldInfo [field_infos.Count];\r
241                         object [] field_values_arr = new object [field_values.Count];\r
242                         object [] prop_values_arr = new object [prop_values.Count];\r
243 \r
244                         field_infos.CopyTo  (field_info_arr, 0);\r
245                         field_values.CopyTo (field_values_arr, 0);\r
246 \r
247                         prop_values.CopyTo  (prop_values_arr, 0);\r
248                         prop_infos.CopyTo   (prop_info_arr, 0);\r
249                         \r
250                         CustomAttributeBuilder cb = new CustomAttributeBuilder (\r
251                                 (ConstructorInfo) constructor, pos_values,\r
252                                 prop_info_arr, prop_values_arr,\r
253                                 field_info_arr, field_values_arr); \r
254                         \r
255                         return cb;\r
256                 }\r
257 \r
258                 static string GetValidPlaces (Attribute attr)\r
259                 {\r
260                         StringBuilder sb = new StringBuilder ();\r
261                         AttributeTargets targets = 0;\r
262                         \r
263                         TypeContainer a = TypeManager.LookupAttr (attr.Type);\r
264 \r
265                         if (a == null) {\r
266                                 \r
267                                 System.Attribute [] attrs = null;\r
268                                 \r
269                                 try {\r
270                                         attrs = System.Attribute.GetCustomAttributes (attr.Type);\r
271                                         \r
272                                 } catch {\r
273                                         Report.Error (-20, attr.Location, "Cannot find attribute type " + attr.Name +\r
274                                                       " (maybe you forgot to set the usage using the" +\r
275                                                       " AttributeUsage attribute ?).");\r
276                                         return null;\r
277                                 }\r
278                                         \r
279                                 foreach (System.Attribute tmp in attrs)\r
280                                         if (tmp is AttributeUsageAttribute) \r
281                                                 targets = ((AttributeUsageAttribute) tmp).ValidOn;\r
282                         } else\r
283                                 targets = a.Targets;\r
284 \r
285                         \r
286                         if ((targets & AttributeTargets.Assembly) != 0)\r
287                                 sb.Append ("'assembly' ");\r
288 \r
289                         if ((targets & AttributeTargets.Class) != 0)\r
290                                 sb.Append ("'class' ");\r
291 \r
292                         if ((targets & AttributeTargets.Constructor) != 0)\r
293                                 sb.Append ("'constructor' ");\r
294 \r
295                         if ((targets & AttributeTargets.Delegate) != 0)\r
296                                 sb.Append ("'delegate' ");\r
297 \r
298                         if ((targets & AttributeTargets.Enum) != 0)\r
299                                 sb.Append ("'enum' ");\r
300 \r
301                         if ((targets & AttributeTargets.Event) != 0)\r
302                                 sb.Append ("'event' ");\r
303 \r
304                         if ((targets & AttributeTargets.Field) != 0)\r
305                                 sb.Append ("'field' ");\r
306 \r
307                         if ((targets & AttributeTargets.Interface) != 0)\r
308                                 sb.Append ("'interface' ");\r
309 \r
310                         if ((targets & AttributeTargets.Method) != 0)\r
311                                 sb.Append ("'method' ");\r
312 \r
313                         if ((targets & AttributeTargets.Module) != 0)\r
314                                 sb.Append ("'module' ");\r
315 \r
316                         if ((targets & AttributeTargets.Parameter) != 0)\r
317                                 sb.Append ("'parameter' ");\r
318 \r
319                         if ((targets & AttributeTargets.Property) != 0)\r
320                                 sb.Append ("'property' ");\r
321 \r
322                         if ((targets & AttributeTargets.ReturnValue) != 0)\r
323                                 sb.Append ("'return value' ");\r
324 \r
325                         if ((targets & AttributeTargets.Struct) != 0)\r
326                                 sb.Append ("'struct' ");\r
327 \r
328                         return sb.ToString ();\r
329 \r
330                 }\r
331 \r
332                 public static void error592 (Attribute a, Location loc)\r
333                 {\r
334                         Report.Error (\r
335                                 592, loc, "Attribute '" + a.Name +\r
336                                 "' is not valid on this declaration type. " +\r
337                                 "It is valid on " + GetValidPlaces (a) + "declarations only.");\r
338                 }\r
339 \r
340                 public static bool CheckAttribute (Attribute a, object element)\r
341                 {\r
342                         TypeContainer attr = TypeManager.LookupAttr (a.Type);\r
343                         AttributeTargets targets = 0;\r
344 \r
345                         \r
346                         if (attr == null) {\r
347 \r
348                                 System.Attribute [] attrs = null;\r
349                                 \r
350                                 try {\r
351                                         attrs = System.Attribute.GetCustomAttributes (a.Type);\r
352 \r
353                                 } catch {\r
354                                         Report.Error (-20, a.Location, "Cannot find attribute type " + a.Name +\r
355                                                       " (maybe you forgot to set the usage using the" +\r
356                                                       " AttributeUsage attribute ?).");\r
357                                         return false;\r
358                                 }\r
359                                         \r
360                                 foreach (System.Attribute tmp in attrs)\r
361                                         if (tmp is AttributeUsageAttribute) \r
362                                                 targets = ((AttributeUsageAttribute) tmp).ValidOn;\r
363                         } else\r
364                                 targets = attr.Targets;\r
365 \r
366                         if (element is Class) {\r
367                                 if ((targets & AttributeTargets.Class) != 0)\r
368                                         return true;\r
369                                 else\r
370                                         return false;\r
371                                 \r
372                         } else if (element is Struct) {\r
373                                 if ((targets & AttributeTargets.Struct) != 0)\r
374                                         return true;\r
375                                 else\r
376                                         return false;\r
377                         } else if (element is Constructor) {\r
378                                 if ((targets & AttributeTargets.Constructor) != 0)\r
379                                         return true;\r
380                                 else\r
381                                         return false;\r
382                         } else if (element is Delegate) {\r
383                                 if ((targets & AttributeTargets.Delegate) != 0)\r
384                                         return true;\r
385                                 else\r
386                                         return false;\r
387                         } else if (element is Enum) {\r
388                                 if ((targets & AttributeTargets.Enum) != 0)\r
389                                         return true;\r
390                                 else\r
391                                         return false;\r
392                         } else if (element is Event) {\r
393                                 if ((targets & AttributeTargets.Event) != 0)\r
394                                         return true;\r
395                                 else\r
396                                         return false;\r
397                         } else if (element is Field) {\r
398                                 if ((targets & AttributeTargets.Field) != 0)\r
399                                         return true;\r
400                                 else\r
401                                         return false;\r
402                         } else if (element is Interface) {\r
403                                 if ((targets & AttributeTargets.Interface) != 0)\r
404                                         return true;\r
405                                 else\r
406                                         return false;\r
407                         } else if (element is Method || element is Operator) {\r
408                                 if ((targets & AttributeTargets.Method) != 0)\r
409                                         return true;\r
410                                 else\r
411                                         return false;\r
412                         } else if (element is ParameterBuilder) {\r
413                                 if ((targets & AttributeTargets.Parameter) != 0)\r
414                                         return true;\r
415                                 else\r
416                                         return false;\r
417                         } else if (element is Property) {\r
418                                 if ((targets & AttributeTargets.Property) != 0)\r
419                                         return true;\r
420                                 else\r
421                                         return false;\r
422                         } else if (element is AssemblyBuilder){\r
423                                 if ((targets & AttributeTargets.Assembly) != 0)\r
424                                         return true;\r
425                                 else\r
426                                         return false;\r
427                         }\r
428 \r
429                         return false;\r
430                 }\r
431                 \r
432                 public static void ApplyAttributes (EmitContext ec, object builder, object kind,\r
433                                                     Attributes opt_attrs, Location loc)\r
434                 {\r
435                         if (opt_attrs == null)\r
436                                 return;\r
437 \r
438                         if (opt_attrs.AttributeSections == null)\r
439                                 return;\r
440 \r
441                         foreach (AttributeSection asec in opt_attrs.AttributeSections) {\r
442 \r
443                                 if (asec.Attributes == null)\r
444                                         continue;\r
445 \r
446                                 if (asec.Target == "assembly" && !(builder is AssemblyBuilder))\r
447                                         continue;\r
448                                 \r
449                                 foreach (Attribute a in asec.Attributes) {\r
450                                         CustomAttributeBuilder cb = a.Resolve (ec);\r
451 \r
452                                         if (cb == null)\r
453                                                 continue;\r
454 \r
455                                         if (!(kind is TypeContainer))\r
456                                                 if (!CheckAttribute (a, kind)) {\r
457                                                         error592 (a, loc);\r
458                                                         return;\r
459                                                 }\r
460 \r
461                                         if (kind is Method || kind is Operator) {\r
462 \r
463                                                 if (a.Type == TypeManager.methodimpl_attr_type) {\r
464                                                         if (a.ImplOptions == MethodImplOptions.InternalCall)\r
465                                                                 ((MethodBuilder) builder).SetImplementationFlags (\r
466                                                                            MethodImplAttributes.InternalCall |\r
467                                                                            MethodImplAttributes.Runtime);\r
468                                                 } else if (a.Type != TypeManager.dllimport_type)\r
469                                                         ((MethodBuilder) builder).SetCustomAttribute (cb);\r
470 \r
471                                         } else if (kind is Constructor) {\r
472                                                 ((ConstructorBuilder) builder).SetCustomAttribute (cb);\r
473                                         } else if (kind is Field) {\r
474                                                 ((FieldBuilder) builder).SetCustomAttribute (cb);\r
475                                         } else if (kind is Property || kind is Indexer) {\r
476                                                 ((PropertyBuilder) builder).SetCustomAttribute (cb);\r
477                                         } else if (kind is Event) {\r
478                                                 ((EventBuilder) builder).SetCustomAttribute (cb);\r
479                                         } else if (kind is ParameterBuilder) {\r
480 \r
481                                                 if (a.Type == TypeManager.marshal_as_attr_type) {\r
482                                                         UnmanagedMarshal marshal =\r
483                                                                 UnmanagedMarshal.DefineUnmanagedMarshal (a.UnmanagedType);\r
484                                                         \r
485                                                         ((ParameterBuilder) builder).SetMarshal (marshal);\r
486                                                 } else \r
487                                                         ((ParameterBuilder) builder).SetCustomAttribute (cb);\r
488                                                 \r
489                                         } else if (kind is Enum) {\r
490                                                 ((TypeBuilder) builder).SetCustomAttribute (cb); \r
491 \r
492                                         } else if (kind is TypeContainer) {\r
493                                                 TypeContainer tc = (TypeContainer) kind;\r
494                                                 \r
495                                                 if (a.UsageAttr) {\r
496                                                         tc.Targets = a.Targets;\r
497                                                         tc.AllowMultiple = a.AllowMultiple;\r
498                                                         tc.Inherited = a.Inherited;\r
499                                                         \r
500                                                 } else if (a.Type == TypeManager.default_member_type) {\r
501                                                         if (tc.Indexers != null) {\r
502                                                                 Report.Error (646, loc,\r
503                                                                       "Cannot specify the DefaultMember attribute on" +\r
504                                                                       " a type containing an indexer");\r
505                                                                 return;\r
506                                                         }\r
507 \r
508                                                 } else {\r
509                                                         if (!CheckAttribute (a, kind)) {\r
510                                                                 error592 (a, loc);\r
511                                                                 return;\r
512                                                         }\r
513                                                 }\r
514                                                 \r
515                                                 ((TypeBuilder) builder).SetCustomAttribute (cb);\r
516                                                 \r
517                                         } else if (kind is AssemblyBuilder){\r
518                                                 ((AssemblyBuilder) builder).SetCustomAttribute (cb);\r
519                                         } else if (kind is ModuleBuilder) {\r
520                                                 ((ModuleBuilder) builder).SetCustomAttribute (cb);\r
521                                         } else\r
522                                                 throw new Exception ("Unknown kind: " + kind);\r
523                                 }\r
524                         }\r
525                 }\r
526 \r
527                 public MethodBuilder DefinePInvokeMethod (EmitContext ec, TypeBuilder builder, string name,\r
528                                                           MethodAttributes flags, Type ret_type, Type [] param_types)\r
529                 {\r
530                         //\r
531                         // We extract from the attribute the information we need \r
532                         //\r
533 \r
534                         if (Arguments == null) {\r
535                                 Console.WriteLine ("Internal error : this is not supposed to happen !");\r
536                                 return null;\r
537                         }\r
538 \r
539                         string attr_name = Name;\r
540 \r
541                         if (Name.IndexOf ("Attribute") == -1)\r
542                                 attr_name = Name + "Attribute";\r
543                         else if (Name.LastIndexOf ("Attribute") == 0)\r
544                                 attr_name = Name + "Attribute";\r
545                         \r
546                         Type = RootContext.LookupType (ec.DeclSpace, attr_name, false, Location);\r
547 \r
548                         if (Type == null) {\r
549                                 Report.Error (246, Location, "Could not find attribute '" + Name + "' (are you" +\r
550                                               " missing a using directive or an assembly reference ?)");\r
551                                 return null;\r
552                         }\r
553                         \r
554                         ArrayList named_args = new ArrayList ();\r
555                         \r
556                         ArrayList pos_args = (ArrayList) Arguments [0];\r
557                         if (Arguments.Count > 1)\r
558                                 named_args = (ArrayList) Arguments [1];\r
559                         \r
560 \r
561                         string dll_name = null;\r
562                         \r
563                         Argument tmp = (Argument) pos_args [0];\r
564 \r
565                         if (!tmp.Resolve (ec, Location))\r
566                                 return null;\r
567                         \r
568                         if (tmp.Expr is Constant)\r
569                                 dll_name = (string) ((Constant) tmp.Expr).GetValue ();\r
570                         else { \r
571                                 error182 ();\r
572                                 return null;\r
573                         }\r
574 \r
575                         // Now we process the named arguments\r
576                         CallingConvention cc = CallingConvention.Winapi;\r
577                         CharSet charset = CharSet.Ansi;\r
578                         bool preserve_sig = true;\r
579                         bool exact_spelling = false;\r
580                         bool set_last_err = false;\r
581                         string entry_point = null;\r
582 \r
583                         for (int i = 0; i < named_args.Count; i++) {\r
584 \r
585                                 DictionaryEntry de = (DictionaryEntry) named_args [i];\r
586 \r
587                                 string member_name = (string) de.Key;\r
588                                 Argument a  = (Argument) de.Value;\r
589 \r
590                                 if (!a.Resolve (ec, Location))\r
591                                         return null;\r
592 \r
593                                 Expression member = Expression.MemberLookup (\r
594                                         ec, Type, member_name, \r
595                                         MemberTypes.Field | MemberTypes.Property,\r
596                                         BindingFlags.Public | BindingFlags.Instance,\r
597                                         Location);\r
598 \r
599                                 if (member == null || !(member is FieldExpr)) {\r
600                                         error617 (member_name);\r
601                                         return null;\r
602                                 }\r
603 \r
604                                 if (member is FieldExpr) {\r
605                                         FieldExpr fe = (FieldExpr) member;\r
606                                         FieldInfo fi = fe.FieldInfo;\r
607 \r
608                                         if (fi.IsInitOnly) {\r
609                                                 error617 (member_name);\r
610                                                 return null;\r
611                                         }\r
612 \r
613                                         if (a.Expr is Constant) {\r
614                                                 Constant c = (Constant) a.Expr;\r
615                                                 \r
616                                                 if (member_name == "CallingConvention")\r
617                                                         cc = (CallingConvention) c.GetValue ();\r
618                                                 else if (member_name == "CharSet")\r
619                                                         charset = (CharSet) c.GetValue ();\r
620                                                 else if (member_name == "EntryPoint")\r
621                                                         entry_point = (string) c.GetValue ();\r
622                                                 else if (member_name == "SetLastError")\r
623                                                         set_last_err = (bool) c.GetValue ();\r
624                                                 else if (member_name == "ExactSpelling")\r
625                                                         exact_spelling = (bool) c.GetValue ();\r
626                                                 else if (member_name == "PreserveSig")\r
627                                                         preserve_sig = (bool) c.GetValue ();\r
628                                         } else { \r
629                                                 error182 ();\r
630                                                 return null;\r
631                                         }\r
632                                         \r
633                                 }\r
634                         }\r
635 \r
636                         MethodBuilder mb = builder.DefinePInvokeMethod (\r
637                                 name, dll_name, flags | MethodAttributes.HideBySig,\r
638                                 CallingConventions.Standard,\r
639                                 ret_type,\r
640                                 param_types,\r
641                                 cc,\r
642                                 charset);\r
643 \r
644                         if (preserve_sig)\r
645                                 mb.SetImplementationFlags (MethodImplAttributes.PreserveSig);\r
646                         \r
647                         return mb;\r
648                 }\r
649                 \r
650         }\r
651         \r
652         public class AttributeSection {\r
653                 \r
654                 public readonly string    Target;\r
655                 public readonly ArrayList Attributes;\r
656                 \r
657                 public AttributeSection (string target, ArrayList attrs)\r
658                 {\r
659                         Target = target;\r
660                         Attributes = attrs;\r
661                 }\r
662                 \r
663         }\r
664 \r
665         public class Attributes {\r
666                 public ArrayList AttributeSections;\r
667                 public Location Location;\r
668 \r
669                 public Attributes (AttributeSection a, Location loc)\r
670                 {\r
671                         AttributeSections = new ArrayList ();\r
672                         AttributeSections.Add (a);\r
673 \r
674                 }\r
675 \r
676                 public void AddAttribute (AttributeSection a)\r
677                 {\r
678                         if (a != null)\r
679                                 AttributeSections.Add (a);\r
680                 }\r
681         }\r
682 }\r