Merge pull request #136 from spencerhakim/master
[mono.git] / mcs / mcs / attribute.cs
1 //
2 // attribute.cs: Attribute Handler
3 //
4 // Author: Ravi Pratap (ravi@ximian.com)
5 //         Marek Safar (marek.safar@seznam.cz)
6 //
7 // Dual licensed under the terms of the MIT X11 or GNU GPL
8 //
9 // Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
10 // Copyright 2003-2008 Novell, Inc.
11 //
12
13 using System;
14 using System.Collections.Generic;
15 using System.Runtime.InteropServices;
16 using System.Runtime.CompilerServices;
17 using System.Security; 
18 using System.Security.Permissions;
19 using System.Text;
20 using System.IO;
21
22 #if STATIC
23 using SecurityType = System.Collections.Generic.List<IKVM.Reflection.Emit.CustomAttributeBuilder>;
24 using BadImageFormat = IKVM.Reflection.BadImageFormatException;
25 using IKVM.Reflection;
26 using IKVM.Reflection.Emit;
27 #else
28 using SecurityType = System.Collections.Generic.Dictionary<System.Security.Permissions.SecurityAction, System.Security.PermissionSet>;
29 using BadImageFormat = System.BadImageFormatException;
30 using System.Reflection;
31 using System.Reflection.Emit;
32 #endif
33
34 namespace Mono.CSharp {
35
36         /// <summary>
37         ///   Base class for objects that can have Attributes applied to them.
38         /// </summary>
39         public abstract class Attributable {
40                 //
41                 // Holds all attributes attached to this element
42                 //
43                 protected Attributes attributes;
44
45                 public void AddAttributes (Attributes attrs, IMemberContext context)
46                 {
47                         if (attrs == null)
48                                 return;
49
50                         if (attributes == null)
51                                 attributes = attrs;
52                         else
53                                 attributes.AddAttributes (attrs.Attrs);
54
55                         attrs.AttachTo (this, context);
56                 }
57
58                 public Attributes OptAttributes {
59                         get {
60                                 return attributes;
61                         }
62                         set {
63                                 attributes = value;
64                         }
65                 }
66
67                 /// <summary>
68                 /// Use member-specific procedure to apply attribute @a in @cb to the entity being built in @builder
69                 /// </summary>
70                 public abstract void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa);
71
72                 /// <summary>
73                 /// Returns one AttributeTarget for this element.
74                 /// </summary>
75                 public abstract AttributeTargets AttributeTargets { get; }
76
77                 public abstract bool IsClsComplianceRequired ();
78
79                 /// <summary>
80                 /// Gets list of valid attribute targets for explicit target declaration.
81                 /// The first array item is default target. Don't break this rule.
82                 /// </summary>
83                 public abstract string[] ValidAttributeTargets { get; }
84         };
85
86         public class Attribute
87         {
88                 public readonly string ExplicitTarget;
89                 public AttributeTargets Target;
90                 readonly ATypeNameExpression expression;
91
92                 Arguments PosArguments;
93                 Arguments NamedArguments;
94
95                 bool resolve_error;
96                 bool arg_resolved;
97                 readonly bool nameEscaped;
98                 readonly Location loc;
99                 public TypeSpec Type;   
100
101                 //
102                 // An attribute can be attached to multiple targets (e.g. multiple fields)
103                 //
104                 Attributable[] targets;
105
106                 //
107                 // A member context for the attribute, it's much easier to hold it here
108                 // than trying to pull it during resolve
109                 //
110                 IMemberContext context;
111
112                 public static readonly AttributeUsageAttribute DefaultUsageAttribute = new AttributeUsageAttribute (AttributeTargets.All);
113                 public static readonly object[] EmptyObject = new object [0];
114
115                 List<KeyValuePair<MemberExpr, NamedArgument>> named_values;
116
117                 public Attribute (string target, ATypeNameExpression expr, Arguments[] args, Location loc, bool nameEscaped)
118                 {
119                         this.expression = expr;
120                         if (args != null) {
121                                 PosArguments = args[0];
122                                 NamedArguments = args[1];
123                         }
124                         this.loc = loc;
125                         ExplicitTarget = target;
126                         this.nameEscaped = nameEscaped;
127                 }
128
129                 public Location Location {
130                         get {
131                                 return loc;
132                         }
133                 }
134
135                 void AddModuleCharSet (ResolveContext rc)
136                 {
137                         const string dll_import_char_set = "CharSet";
138
139                         //
140                         // Only when not customized by user
141                         //
142                         if (HasField (dll_import_char_set))
143                                 return;
144
145                         if (!rc.Module.PredefinedTypes.CharSet.Define ()) {
146                                 return;
147                         }
148
149                         if (NamedArguments == null)
150                                 NamedArguments = new Arguments (1);
151
152                         var value = Constant.CreateConstant (rc.Module.PredefinedTypes.CharSet.TypeSpec, rc.Module.DefaultCharSet, Location);
153                         NamedArguments.Add (new NamedArgument (dll_import_char_set, loc, value));
154                 }
155
156                 public Attribute Clone ()
157                 {
158                         Attribute a = new Attribute (ExplicitTarget, expression, null, loc, nameEscaped);
159                         a.PosArguments = PosArguments;
160                         a.NamedArguments = NamedArguments;
161                         return a;
162                 }
163
164                 //
165                 // When the same attribute is attached to multiple fiels
166                 // we use @target field as a list of targets. The attribute
167                 // has to be resolved only once but emitted for each target.
168                 //
169                 public void AttachTo (Attributable target, IMemberContext context)
170                 {
171                         if (this.targets == null) {
172                                 this.targets = new Attributable[] { target };
173                                 this.context = context;
174                                 return;
175                         }
176
177                         // When re-attaching global attributes
178                         if (context is NamespaceContainer) {
179                                 this.targets[0] = target;
180                                 this.context = context;
181                                 return;
182                         }
183
184                         // Resize target array
185                         Attributable[] new_array = new Attributable [this.targets.Length + 1];
186                         targets.CopyTo (new_array, 0);
187                         new_array [targets.Length] = target;
188                         this.targets = new_array;
189
190                         // No need to update context, different targets cannot have
191                         // different contexts, it's enough to remove same attributes
192                         // from secondary members.
193
194                         target.OptAttributes = null;
195                 }
196
197                 public ResolveContext CreateResolveContext ()
198                 {
199                         return new ResolveContext (context, ResolveContext.Options.ConstantScope);
200                 }
201
202                 static void Error_InvalidNamedArgument (ResolveContext rc, NamedArgument name)
203                 {
204                         rc.Report.Error (617, name.Location, "`{0}' is not a valid named attribute argument. Named attribute arguments " +
205                                       "must be fields which are not readonly, static, const or read-write properties which are " +
206                                       "public and not static",
207                               name.Name);
208                 }
209
210                 static void Error_InvalidNamedArgumentType (ResolveContext rc, NamedArgument name)
211                 {
212                         rc.Report.Error (655, name.Location,
213                                 "`{0}' is not a valid named attribute argument because it is not a valid attribute parameter type",
214                                 name.Name);
215                 }
216
217                 public static void Error_AttributeArgumentIsDynamic (IMemberContext context, Location loc)
218                 {
219                         context.Module.Compiler.Report.Error (1982, loc, "An attribute argument cannot be dynamic expression");
220                 }
221                 
222                 public void Error_MissingGuidAttribute ()
223                 {
224                         Report.Error (596, Location, "The Guid attribute must be specified with the ComImport attribute");
225                 }
226
227                 public void Error_MisusedExtensionAttribute ()
228                 {
229                         Report.Error (1112, Location, "Do not use `{0}' directly. Use parameter modifier `this' instead", GetSignatureForError ());
230                 }
231
232                 public void Error_MisusedDynamicAttribute ()
233                 {
234                         Report.Error (1970, loc, "Do not use `{0}' directly. Use `dynamic' keyword instead", GetSignatureForError ());
235                 }
236
237                 /// <summary>
238                 /// This is rather hack. We report many emit attribute error with same error to be compatible with
239                 /// csc. But because csc has to report them this way because error came from ilasm we needn't.
240                 /// </summary>
241                 public void Error_AttributeEmitError (string inner)
242                 {
243                         Report.Error (647, Location, "Error during emitting `{0}' attribute. The reason is `{1}'",
244                                       TypeManager.CSharpName (Type), inner);
245                 }
246
247                 public void Error_InvalidSecurityParent ()
248                 {
249                         Error_AttributeEmitError ("it is attached to invalid parent");
250                 }
251
252                 Attributable Owner {
253                         get {
254                                 return targets [0];
255                         }
256                 }
257
258                 /// <summary>
259                 ///   Tries to resolve the type of the attribute. Flags an error if it can't, and complain is true.
260                 /// </summary>
261                 void ResolveAttributeType ()
262                 {
263                         SessionReportPrinter resolve_printer = new SessionReportPrinter ();
264                         ReportPrinter prev_recorder = context.Module.Compiler.Report.SetPrinter (resolve_printer);
265
266                         bool t1_is_attr = false;
267                         bool t2_is_attr = false;
268                         TypeSpec t1, t2;
269                         ATypeNameExpression expanded = null;
270
271                         // TODO: Additional warnings such as CS0436 are swallowed because we don't
272                         // print on success
273
274                         try {
275                                 t1 = expression.ResolveAsType (context);
276                                 if (t1 != null)
277                                         t1_is_attr = t1.IsAttribute;
278
279                                 resolve_printer.EndSession ();
280
281                                 if (nameEscaped) {
282                                         t2 = null;
283                                 } else {
284                                         expanded = (ATypeNameExpression) expression.Clone (null);
285                                         expanded.Name += "Attribute";
286
287                                         t2 = expanded.ResolveAsType (context);
288                                         if (t2 != null)
289                                                 t2_is_attr = t2.IsAttribute;
290                                 }
291                         } finally {
292                                 context.Module.Compiler.Report.SetPrinter (prev_recorder);
293                         }
294
295                         if (t1_is_attr && t2_is_attr && t1 != t2) {
296                                 Report.Error (1614, Location, "`{0}' is ambiguous between `{1}' and `{2}'. Use either `@{0}' or `{0}Attribute'",
297                                         GetSignatureForError (), expression.GetSignatureForError (), expanded.GetSignatureForError ());
298                                 resolve_error = true;
299                                 return;
300                         }
301
302                         if (t1_is_attr) {
303                                 Type = t1;
304                                 return;
305                         }
306
307                         if (t2_is_attr) {
308                                 Type = t2;
309                                 return;
310                         }
311
312                         resolve_error = true;
313
314                         if (t1 != null) {
315                                 resolve_printer.Merge (prev_recorder);
316
317                                 Report.SymbolRelatedToPreviousError (t1);
318                                 Report.Error (616, Location, "`{0}': is not an attribute class", t1.GetSignatureForError ());
319                                 return;
320                         }
321
322                         if (t2 != null) {
323                                 Report.SymbolRelatedToPreviousError (t2);
324                                 Report.Error (616, Location, "`{0}': is not an attribute class", t2.GetSignatureForError ());
325                                 return;
326                         }
327
328                         resolve_printer.Merge (prev_recorder);
329                 }
330
331                 public TypeSpec ResolveType ()
332                 {
333                         if (Type == null && !resolve_error)
334                                 ResolveAttributeType ();
335                         return Type;
336                 }
337
338                 public string GetSignatureForError ()
339                 {
340                         if (Type != null)
341                                 return TypeManager.CSharpName (Type);
342
343                         return expression.GetSignatureForError ();
344                 }
345
346                 public bool HasSecurityAttribute {
347                         get {
348                                 PredefinedAttribute pa = context.Module.PredefinedAttributes.Security;
349                                 return pa.IsDefined && TypeSpec.IsBaseClass (Type, pa.TypeSpec, false);
350                         }
351                 }
352
353                 public bool IsValidSecurityAttribute ()
354                 {
355                         return HasSecurityAttribute && IsSecurityActionValid ();
356                 }
357
358                 static bool IsValidArgumentType (TypeSpec t)
359                 {
360                         if (t.IsArray) {
361                                 var ac = (ArrayContainer) t;
362                                 if (ac.Rank > 1)
363                                         return false;
364
365                                 t = ac.Element;
366                         }
367
368                         switch (t.BuiltinType) {
369                         case BuiltinTypeSpec.Type.Int:
370                         case BuiltinTypeSpec.Type.UInt:
371                         case BuiltinTypeSpec.Type.Long:
372                         case BuiltinTypeSpec.Type.ULong:
373                         case BuiltinTypeSpec.Type.Float:
374                         case BuiltinTypeSpec.Type.Double:
375                         case BuiltinTypeSpec.Type.Char:
376                         case BuiltinTypeSpec.Type.Short:
377                         case BuiltinTypeSpec.Type.Bool:
378                         case BuiltinTypeSpec.Type.SByte:
379                         case BuiltinTypeSpec.Type.Byte:
380                         case BuiltinTypeSpec.Type.UShort:
381
382                         case BuiltinTypeSpec.Type.String:
383                         case BuiltinTypeSpec.Type.Object:
384                         case BuiltinTypeSpec.Type.Dynamic:
385                         case BuiltinTypeSpec.Type.Type:
386                                 return true;
387                         }
388
389                         return t.IsEnum;
390                 }
391
392                 // TODO: Don't use this ambiguous value
393                 public string Name {
394                         get { return expression.Name; }
395                 }
396
397                 public Report Report {
398                         get { return context.Module.Compiler.Report; }
399                 }
400
401                 public MethodSpec Resolve ()
402                 {
403                         if (resolve_error)
404                                 return null;
405
406                         resolve_error = true;
407                         arg_resolved = true;
408
409                         if (Type == null) {
410                                 ResolveAttributeType ();
411                                 if (Type == null)
412                                         return null;
413                         }
414
415                         if (Type.IsAbstract) {
416                                 Report.Error (653, Location, "Cannot apply attribute class `{0}' because it is abstract", GetSignatureForError ());
417                                 return null;
418                         }
419
420                         ObsoleteAttribute obsolete_attr = Type.GetAttributeObsolete ();
421                         if (obsolete_attr != null) {
422                                 AttributeTester.Report_ObsoleteMessage (obsolete_attr, TypeManager.CSharpName (Type), Location, Report);
423                         }
424
425                         ResolveContext rc = null;
426
427                         MethodSpec ctor;
428                         // Try if the attribute is simple and has been resolved before
429                         if (PosArguments != null || !context.Module.AttributeConstructorCache.TryGetValue (Type, out ctor)) {
430                                 rc = CreateResolveContext ();
431                                 ctor = ResolveConstructor (rc);
432                                 if (ctor == null) {
433                                         return null;
434                                 }
435
436                                 if (PosArguments == null && ctor.Parameters.IsEmpty)
437                                         context.Module.AttributeConstructorCache.Add (Type, ctor);
438                         }
439
440                         //
441                         // Add [module: DefaultCharSet] to all DllImport import attributes
442                         //
443                         var module = context.Module;
444                         if ((Type == module.PredefinedAttributes.DllImport || Type == module.PredefinedAttributes.UnmanagedFunctionPointer) && module.HasDefaultCharSet) {
445                                 if (rc == null)
446                                         rc = CreateResolveContext ();
447
448                                 AddModuleCharSet (rc);
449                         }
450
451                         if (NamedArguments != null) {
452                                 if (rc == null)
453                                         rc = CreateResolveContext ();
454
455                                 if (!ResolveNamedArguments (rc))
456                                         return null;
457                         }
458
459                         resolve_error = false;
460                         return ctor;
461                 }
462
463                 MethodSpec ResolveConstructor (ResolveContext ec)
464                 {
465                         if (PosArguments != null) {
466                                 bool dynamic;
467                                 PosArguments.Resolve (ec, out dynamic);
468                                 if (dynamic) {
469                                         Error_AttributeArgumentIsDynamic (ec.MemberContext, loc);
470                                         return null;
471                                 }
472                         }
473
474                         return Expression.ConstructorLookup (ec, Type, ref PosArguments, loc);
475                 }
476
477                 bool ResolveNamedArguments (ResolveContext ec)
478                 {
479                         int named_arg_count = NamedArguments.Count;
480                         var seen_names = new List<string> (named_arg_count);
481
482                         named_values = new List<KeyValuePair<MemberExpr, NamedArgument>> (named_arg_count);
483                         
484                         foreach (NamedArgument a in NamedArguments) {
485                                 string name = a.Name;
486                                 if (seen_names.Contains (name)) {
487                                         ec.Report.Error (643, a.Location, "Duplicate named attribute `{0}' argument", name);
488                                         continue;
489                                 }                       
490         
491                                 seen_names.Add (name);
492
493                                 a.Resolve (ec);
494
495                                 Expression member = Expression.MemberLookup (ec, false, Type, name, 0, Expression.MemberLookupRestrictions.ExactArity, loc);
496
497                                 if (member == null) {
498                                         member = Expression.MemberLookup (ec, true, Type, name, 0, Expression.MemberLookupRestrictions.ExactArity, loc);
499
500                                         if (member != null) {
501                                                 // TODO: ec.Report.SymbolRelatedToPreviousError (member);
502                                                 Expression.ErrorIsInaccesible (ec, member.GetSignatureForError (), loc);
503                                                 return false;
504                                         }
505                                 }
506
507                                 if (member == null){
508                                         Expression.Error_TypeDoesNotContainDefinition (ec, Location, Type, name);
509                                         return false;
510                                 }
511                                 
512                                 if (!(member is PropertyExpr || member is FieldExpr)) {
513                                         Error_InvalidNamedArgument (ec, a);
514                                         return false;
515                                 }
516
517                                 ObsoleteAttribute obsolete_attr;
518
519                                 if (member is PropertyExpr) {
520                                         var pi = ((PropertyExpr) member).PropertyInfo;
521
522                                         if (!pi.HasSet || !pi.HasGet || pi.IsStatic || !pi.Get.IsPublic || !pi.Set.IsPublic) {
523                                                 ec.Report.SymbolRelatedToPreviousError (pi);
524                                                 Error_InvalidNamedArgument (ec, a);
525                                                 return false;
526                                         }
527
528                                         if (!IsValidArgumentType (member.Type)) {
529                                                 ec.Report.SymbolRelatedToPreviousError (pi);
530                                                 Error_InvalidNamedArgumentType (ec, a);
531                                                 return false;
532                                         }
533
534                                         obsolete_attr = pi.GetAttributeObsolete ();
535                                         pi.MemberDefinition.SetIsAssigned ();
536                                 } else {
537                                         var fi = ((FieldExpr) member).Spec;
538
539                                         if (fi.IsReadOnly || fi.IsStatic || !fi.IsPublic) {
540                                                 Error_InvalidNamedArgument (ec, a);
541                                                 return false;
542                                         }
543
544                                         if (!IsValidArgumentType (member.Type)) {
545                                                 ec.Report.SymbolRelatedToPreviousError (fi);
546                                                 Error_InvalidNamedArgumentType (ec, a);
547                                                 return false;
548                                         }
549
550                                         obsolete_attr = fi.GetAttributeObsolete ();
551                                         fi.MemberDefinition.SetIsAssigned ();
552                                 }
553
554                                 if (obsolete_attr != null && !context.IsObsolete)
555                                         AttributeTester.Report_ObsoleteMessage (obsolete_attr, member.GetSignatureForError (), member.Location, Report);
556
557                                 if (a.Type != member.Type) {
558                                         a.Expr = Convert.ImplicitConversionRequired (ec, a.Expr, member.Type, a.Expr.Location);
559                                 }
560
561                                 if (a.Expr != null)
562                                         named_values.Add (new KeyValuePair<MemberExpr, NamedArgument> ((MemberExpr) member, a));
563                         }
564
565                         return true;
566                 }
567
568                 /// <summary>
569                 ///   Get a string containing a list of valid targets for the attribute 'attr'
570                 /// </summary>
571                 public string GetValidTargets ()
572                 {
573                         StringBuilder sb = new StringBuilder ();
574                         AttributeTargets targets = Type.GetAttributeUsage (context.Module.PredefinedAttributes.AttributeUsage).ValidOn;
575
576                         if ((targets & AttributeTargets.Assembly) != 0)
577                                 sb.Append ("assembly, ");
578
579                         if ((targets & AttributeTargets.Module) != 0)
580                                 sb.Append ("module, ");
581
582                         if ((targets & AttributeTargets.Class) != 0)
583                                 sb.Append ("class, ");
584
585                         if ((targets & AttributeTargets.Struct) != 0)
586                                 sb.Append ("struct, ");
587
588                         if ((targets & AttributeTargets.Enum) != 0)
589                                 sb.Append ("enum, ");
590
591                         if ((targets & AttributeTargets.Constructor) != 0)
592                                 sb.Append ("constructor, ");
593
594                         if ((targets & AttributeTargets.Method) != 0)
595                                 sb.Append ("method, ");
596
597                         if ((targets & AttributeTargets.Property) != 0)
598                                 sb.Append ("property, indexer, ");
599
600                         if ((targets & AttributeTargets.Field) != 0)
601                                 sb.Append ("field, ");
602
603                         if ((targets & AttributeTargets.Event) != 0)
604                                 sb.Append ("event, ");
605
606                         if ((targets & AttributeTargets.Interface) != 0)
607                                 sb.Append ("interface, ");
608
609                         if ((targets & AttributeTargets.Parameter) != 0)
610                                 sb.Append ("parameter, ");
611
612                         if ((targets & AttributeTargets.Delegate) != 0)
613                                 sb.Append ("delegate, ");
614
615                         if ((targets & AttributeTargets.ReturnValue) != 0)
616                                 sb.Append ("return, ");
617
618                         if ((targets & AttributeTargets.GenericParameter) != 0)
619                                 sb.Append ("type parameter, ");
620
621                         return sb.Remove (sb.Length - 2, 2).ToString ();
622                 }
623
624                 public AttributeUsageAttribute GetAttributeUsageAttribute ()
625                 {
626                         if (!arg_resolved)
627                                 // TODO: It is not neccessary to call whole Resolve (ApplyAttribute does it now) we need only ctor args.
628                                 // But because a lot of attribute class code must be rewritten will be better to wait...
629                                 Resolve ();
630
631                         if (resolve_error)
632                                 return DefaultUsageAttribute;
633
634                         AttributeUsageAttribute usage_attribute = new AttributeUsageAttribute ((AttributeTargets)((Constant) PosArguments [0].Expr).GetValue ());
635
636                         var field = GetNamedValue ("AllowMultiple") as BoolConstant;
637                         if (field != null)
638                                 usage_attribute.AllowMultiple = field.Value;
639
640                         field = GetNamedValue ("Inherited") as BoolConstant;
641                         if (field != null)
642                                 usage_attribute.Inherited = field.Value;
643
644                         return usage_attribute;
645                 }
646
647                 /// <summary>
648                 /// Returns custom name of indexer
649                 /// </summary>
650                 public string GetIndexerAttributeValue ()
651                 {
652                         if (!arg_resolved)
653                                 // TODO: It is not neccessary to call whole Resolve (ApplyAttribute does it now) we need only ctor args.
654                                 // But because a lot of attribute class code must be rewritten will be better to wait...
655                                 Resolve ();
656
657                         if (resolve_error || PosArguments.Count != 1 || !(PosArguments [0].Expr is Constant))
658                                 return null;
659
660                         return ((Constant) PosArguments [0].Expr).GetValue () as string;
661                 }
662
663                 /// <summary>
664                 /// Returns condition of ConditionalAttribute
665                 /// </summary>
666                 public string GetConditionalAttributeValue ()
667                 {
668                         if (!arg_resolved)
669                                 // TODO: It is not neccessary to call whole Resolve (ApplyAttribute does it now) we need only ctor args.
670                                 // But because a lot of attribute class code must be rewritten will be better to wait...
671                                 Resolve ();
672
673                         if (resolve_error)
674                                 return null;
675
676                         return ((Constant) PosArguments[0].Expr).GetValue () as string;
677                 }
678
679                 /// <summary>
680                 /// Creates the instance of ObsoleteAttribute from this attribute instance
681                 /// </summary>
682                 public ObsoleteAttribute GetObsoleteAttribute ()
683                 {
684                         if (!arg_resolved) {
685                                 // corlib only case when obsolete is used before is resolved
686                                 var c = Type.MemberDefinition as Class;
687                                 if (c != null && !c.HasMembersDefined)
688                                         c.Define ();
689                                 
690                                 // TODO: It is not neccessary to call whole Resolve (ApplyAttribute does it now) we need only ctor args.
691                                 // But because a lot of attribute class code must be rewritten will be better to wait...
692                                 Resolve ();
693                         }
694
695                         if (resolve_error)
696                                 return null;
697
698                         if (PosArguments == null)
699                                 return new ObsoleteAttribute ();
700
701                         string msg = ((Constant) PosArguments[0].Expr).GetValue () as string;
702                         if (PosArguments.Count == 1)
703                                 return new ObsoleteAttribute (msg);
704
705                         return new ObsoleteAttribute (msg, ((BoolConstant) PosArguments[1].Expr).Value);
706                 }
707
708                 /// <summary>
709                 /// Returns value of CLSCompliantAttribute contructor parameter but because the method can be called
710                 /// before ApplyAttribute. We need to resolve the arguments.
711                 /// This situation occurs when class deps is differs from Emit order.  
712                 /// </summary>
713                 public bool GetClsCompliantAttributeValue ()
714                 {
715                         if (!arg_resolved)
716                                 // TODO: It is not neccessary to call whole Resolve (ApplyAttribute does it now) we need only ctor args.
717                                 // But because a lot of attribute class code must be rewritten will be better to wait...
718                                 Resolve ();
719
720                         if (resolve_error)
721                                 return false;
722
723                         return ((BoolConstant) PosArguments[0].Expr).Value;
724                 }
725
726                 public TypeSpec GetCoClassAttributeValue ()
727                 {
728                         if (!arg_resolved)
729                                 Resolve ();
730
731                         if (resolve_error)
732                                 return null;
733
734                         return GetArgumentType ();
735                 }
736
737                 public bool CheckTarget ()
738                 {
739                         string[] valid_targets = Owner.ValidAttributeTargets;
740                         if (ExplicitTarget == null || ExplicitTarget == valid_targets [0]) {
741                                 Target = Owner.AttributeTargets;
742                                 return true;
743                         }
744
745                         // TODO: we can skip the first item
746                         if (Array.Exists (valid_targets, i => i == ExplicitTarget)) {
747                                 switch (ExplicitTarget) {
748                                 case "return": Target = AttributeTargets.ReturnValue; return true;
749                                 case "param": Target = AttributeTargets.Parameter; return true;
750                                 case "field": Target = AttributeTargets.Field; return true;
751                                 case "method": Target = AttributeTargets.Method; return true;
752                                 case "property": Target = AttributeTargets.Property; return true;
753                                 case "module": Target = AttributeTargets.Module; return true;
754                                 }
755                                 throw new InternalErrorException ("Unknown explicit target: " + ExplicitTarget);
756                         }
757                                 
758                         StringBuilder sb = new StringBuilder ();
759                         foreach (string s in valid_targets) {
760                                 sb.Append (s);
761                                 sb.Append (", ");
762                         }
763                         sb.Remove (sb.Length - 2, 2);
764                         Report.Warning (657, 1, Location,
765                                 "`{0}' is not a valid attribute location for this declaration. Valid attribute locations for this declaration are `{1}'. All attributes in this section will be ignored",
766                                 ExplicitTarget, sb.ToString ());
767                         return false;
768                 }
769
770                 /// <summary>
771                 /// Tests permitted SecurityAction for assembly or other types
772                 /// </summary>
773                 bool IsSecurityActionValid ()
774                 {
775                         SecurityAction action = GetSecurityActionValue ();
776                         bool for_assembly = Target == AttributeTargets.Assembly || Target == AttributeTargets.Module;
777
778                         switch (action) {
779 #pragma warning disable 618
780                         case SecurityAction.Demand:
781                         case SecurityAction.Assert:
782                         case SecurityAction.Deny:
783                         case SecurityAction.PermitOnly:
784                         case SecurityAction.LinkDemand:
785                         case SecurityAction.InheritanceDemand:
786                                 if (!for_assembly)
787                                         return true;
788                                 break;
789
790                         case SecurityAction.RequestMinimum:
791                         case SecurityAction.RequestOptional:
792                         case SecurityAction.RequestRefuse:
793                                 if (for_assembly)
794                                         return true;
795                                 break;
796 #pragma warning restore 618
797
798                         default:
799                                 Error_AttributeEmitError ("SecurityAction is out of range");
800                                 return false;
801                         }
802
803                         Error_AttributeEmitError (String.Concat ("SecurityAction `", action, "' is not valid for this declaration"));
804                         return false;
805                 }
806
807                 System.Security.Permissions.SecurityAction GetSecurityActionValue ()
808                 {
809                         return (SecurityAction) ((Constant) PosArguments[0].Expr).GetValue ();
810                 }
811
812                 /// <summary>
813                 /// Creates instance of SecurityAttribute class and add result of CreatePermission method to permission table.
814                 /// </summary>
815                 /// <returns></returns>
816                 public void ExtractSecurityPermissionSet (MethodSpec ctor, ref SecurityType permissions)
817                 {
818 #if STATIC
819                         object[] values = new object [PosArguments.Count];
820                         for (int i = 0; i < values.Length; ++i)
821                                 values [i] = ((Constant) PosArguments [i].Expr).GetValue ();
822
823                         PropertyInfo[] prop;
824                         object[] prop_values;
825                         if (named_values == null) {
826                                 prop = null;
827                                 prop_values = null;
828                         } else {
829                                 prop = new PropertyInfo[named_values.Count];
830                                 prop_values = new object [named_values.Count];
831                                 for (int i = 0; i < prop.Length; ++i) {
832                                         prop [i] = ((PropertyExpr) named_values [i].Key).PropertyInfo.MetaInfo;
833                                         prop_values [i] = ((Constant) named_values [i].Value.Expr).GetValue ();
834                                 }
835                         }
836
837                         if (permissions == null)
838                                 permissions = new SecurityType ();
839
840                         var cab = new CustomAttributeBuilder ((ConstructorInfo) ctor.GetMetaInfo (), values, prop, prop_values);
841                         permissions.Add (cab);
842 #else
843                         throw new NotSupportedException ();
844 #endif
845                 }
846
847                 public Constant GetNamedValue (string name)
848                 {
849                         if (named_values == null)
850                                 return null;
851
852                         for (int i = 0; i < named_values.Count; ++i) {
853                                 if (named_values [i].Value.Name == name)
854                                         return named_values [i].Value.Expr as Constant;
855                         }
856
857                         return null;
858                 }
859
860                 public CharSet GetCharSetValue ()
861                 {
862                         return (CharSet)System.Enum.Parse (typeof (CharSet), ((Constant) PosArguments [0].Expr).GetValue ().ToString ());
863                 }
864
865                 public bool HasField (string fieldName)
866                 {
867                         if (named_values == null)
868                                 return false;
869
870                         foreach (var na in named_values) {
871                                 if (na.Value.Name == fieldName)
872                                         return true;
873                         }
874
875                         return false;
876                 }
877
878                 //
879                 // Returns true for MethodImplAttribute with MethodImplOptions.InternalCall value
880                 // 
881                 public bool IsInternalCall ()
882                 {
883                         MethodImplOptions options = 0;
884                         if (PosArguments.Count == 1) {
885                                 options = (MethodImplOptions) System.Enum.Parse (typeof (MethodImplOptions), ((Constant) PosArguments[0].Expr).GetValue ().ToString ());
886                         } else if (HasField ("Value")) {
887                                 var named = GetNamedValue ("Value");
888                                 options = (MethodImplOptions) System.Enum.Parse (typeof (MethodImplOptions), named.GetValue ().ToString ());
889                         }
890
891                         return (options & MethodImplOptions.InternalCall) != 0;
892                 }
893
894                 //
895                 // Returns true for StructLayoutAttribute with LayoutKind.Explicit value
896                 // 
897                 public bool IsExplicitLayoutKind ()
898                 {
899                         if (PosArguments == null || PosArguments.Count != 1)
900                                 return false;
901
902                         var value = (LayoutKind) System.Enum.Parse (typeof (LayoutKind), ((Constant) PosArguments[0].Expr).GetValue ().ToString ());
903                         return value == LayoutKind.Explicit;
904                 }
905
906                 public Expression GetParameterDefaultValue ()
907                 {
908                         if (PosArguments == null)
909                                 return null;
910
911                         return PosArguments[0].Expr;
912                 }
913
914                 public override bool Equals (object obj)
915                 {
916                         Attribute a = obj as Attribute;
917                         if (a == null)
918                                 return false;
919
920                         return Type == a.Type && Target == a.Target;
921                 }
922
923                 public override int GetHashCode ()
924                 {
925                         return Type.GetHashCode () ^ Target.GetHashCode ();
926                 }
927
928                 /// <summary>
929                 /// Emit attribute for Attributable symbol
930                 /// </summary>
931                 public void Emit (Dictionary<Attribute, List<Attribute>> allEmitted)
932                 {
933                         var ctor = Resolve ();
934                         if (ctor == null)
935                                 return;
936
937                         var predefined = context.Module.PredefinedAttributes;
938
939                         AttributeUsageAttribute usage_attr = Type.GetAttributeUsage (predefined.AttributeUsage);
940                         if ((usage_attr.ValidOn & Target) == 0) {
941                                 Report.Error (592, Location, "The attribute `{0}' is not valid on this declaration type. " +
942                                               "It is valid on `{1}' declarations only",
943                                         GetSignatureForError (), GetValidTargets ());
944                                 return;
945                         }
946
947                         byte[] cdata;
948                         if (PosArguments == null && named_values == null) {
949                                 cdata = AttributeEncoder.Empty;
950                         } else {
951                                 AttributeEncoder encoder = new AttributeEncoder ();
952
953                                 if (PosArguments != null) {
954                                         var param_types = ctor.Parameters.Types;
955                                         for (int j = 0; j < PosArguments.Count; ++j) {
956                                                 var pt = param_types[j];
957                                                 var arg_expr = PosArguments[j].Expr;
958                                                 if (j == 0) {
959                                                         if ((Type == predefined.IndexerName || Type == predefined.Conditional) && arg_expr is Constant) {
960                                                                 string v = ((Constant) arg_expr).GetValue () as string;
961                                                                 if (!Tokenizer.IsValidIdentifier (v) || Tokenizer.IsKeyword (v)) {
962                                                                         context.Module.Compiler.Report.Error (633, arg_expr.Location,
963                                                                                 "The argument to the `{0}' attribute must be a valid identifier", GetSignatureForError ());
964                                                                         return;
965                                                                 }
966                                                         } else if (Type == predefined.Guid) {
967                                                                 try {
968                                                                         string v = ((StringConstant) arg_expr).Value;
969                                                                         new Guid (v);
970                                                                 } catch (Exception e) {
971                                                                         Error_AttributeEmitError (e.Message);
972                                                                         return;
973                                                                 }
974                                                         } else if (Type == predefined.AttributeUsage) {
975                                                                 int v = ((IntConstant) ((EnumConstant) arg_expr).Child).Value;
976                                                                 if (v == 0) {
977                                                                         context.Module.Compiler.Report.Error (591, Location, "Invalid value for argument to `{0}' attribute",
978                                                                                 "System.AttributeUsage");
979                                                                 }
980                                                         } else if (Type == predefined.MarshalAs) {
981                                                                 if (PosArguments.Count == 1) {
982                                                                         var u_type = (UnmanagedType) System.Enum.Parse (typeof (UnmanagedType), ((Constant) PosArguments[0].Expr).GetValue ().ToString ());
983                                                                         if (u_type == UnmanagedType.ByValArray && !(Owner is FieldBase)) {
984                                                                                 Error_AttributeEmitError ("Specified unmanaged type is only valid on fields");
985                                                                         }
986                                                                 }
987                                                         } else if (Type == predefined.DllImport) {
988                                                                 if (PosArguments.Count == 1 && PosArguments[0].Expr is Constant) {
989                                                                         var value = ((Constant) PosArguments[0].Expr).GetValue () as string;
990                                                                         if (string.IsNullOrEmpty (value))
991                                                                                 Error_AttributeEmitError ("DllName cannot be empty");
992                                                                 }
993                                                         } else if (Type == predefined.MethodImpl && pt.BuiltinType == BuiltinTypeSpec.Type.Short &&
994                                                                 !System.Enum.IsDefined (typeof (MethodImplOptions), ((Constant) arg_expr).GetValue ().ToString ())) {
995                                                                 Error_AttributeEmitError ("Incorrect argument value.");
996                                                                 return;
997                                                         }
998                                                 }
999
1000                                                 arg_expr.EncodeAttributeValue (context, encoder, pt);
1001                                         }
1002                                 }
1003
1004                                 if (named_values != null) {
1005                                         encoder.Encode ((ushort) named_values.Count);
1006                                         foreach (var na in named_values) {
1007                                                 if (na.Key is FieldExpr)
1008                                                         encoder.Encode ((byte) 0x53);
1009                                                 else
1010                                                         encoder.Encode ((byte) 0x54);
1011
1012                                                 encoder.Encode (na.Key.Type);
1013                                                 encoder.Encode (na.Value.Name);
1014                                                 na.Value.Expr.EncodeAttributeValue (context, encoder, na.Key.Type);
1015                                         }
1016                                 } else {
1017                                         encoder.EncodeEmptyNamedArguments ();
1018                                 }
1019
1020                                 cdata = encoder.ToArray ();
1021                         }
1022
1023                         try {
1024                                 foreach (Attributable target in targets)
1025                                         target.ApplyAttributeBuilder (this, ctor, cdata, predefined);
1026                         } catch (Exception e) {
1027                                 if (e is BadImageFormat && Report.Errors > 0)
1028                                         return;
1029
1030                                 Error_AttributeEmitError (e.Message);
1031                                 return;
1032                         }
1033
1034                         if (!usage_attr.AllowMultiple && allEmitted != null) {
1035                                 if (allEmitted.ContainsKey (this)) {
1036                                         var a = allEmitted [this];
1037                                         if (a == null) {
1038                                                 a = new List<Attribute> (2);
1039                                                 allEmitted [this] = a;
1040                                         }
1041                                         a.Add (this);
1042                                 } else {
1043                                         allEmitted.Add (this, null);
1044                                 }
1045                         }
1046
1047                         if (!context.Module.Compiler.Settings.VerifyClsCompliance)
1048                                 return;
1049
1050                         // Here we are testing attribute arguments for array usage (error 3016)
1051                         if (Owner.IsClsComplianceRequired ()) {
1052                                 if (PosArguments != null)
1053                                         PosArguments.CheckArrayAsAttribute (context.Module.Compiler);
1054                         
1055                                 if (NamedArguments == null)
1056                                         return;
1057
1058                                 NamedArguments.CheckArrayAsAttribute (context.Module.Compiler);
1059                         }
1060                 }
1061
1062                 private Expression GetValue () 
1063                 {
1064                         if (PosArguments == null || PosArguments.Count < 1)
1065                                 return null;
1066
1067                         return PosArguments [0].Expr;
1068                 }
1069
1070                 public string GetString () 
1071                 {
1072                         Expression e = GetValue ();
1073                         if (e is StringConstant)
1074                                 return ((StringConstant)e).Value;
1075                         return null;
1076                 }
1077
1078                 public bool GetBoolean () 
1079                 {
1080                         Expression e = GetValue ();
1081                         if (e is BoolConstant)
1082                                 return ((BoolConstant)e).Value;
1083                         return false;
1084                 }
1085
1086                 public TypeSpec GetArgumentType ()
1087                 {
1088                         TypeOf e = GetValue () as TypeOf;
1089                         if (e == null)
1090                                 return null;
1091                         return e.TypeArgument;
1092                 }
1093         }
1094         
1095         public class Attributes
1096         {
1097                 public readonly List<Attribute> Attrs;
1098
1099                 public Attributes (Attribute a)
1100                 {
1101                         Attrs = new List<Attribute> ();
1102                         Attrs.Add (a);
1103                 }
1104
1105                 public Attributes (List<Attribute> attrs)
1106                 {
1107                         Attrs = attrs;
1108                 }
1109
1110                 public void AddAttribute (Attribute attr)
1111                 {
1112                         Attrs.Add (attr);
1113                 }
1114
1115                 public void AddAttributes (List<Attribute> attrs)
1116                 {
1117                         Attrs.AddRange (attrs);
1118                 }
1119
1120                 public void AttachTo (Attributable attributable, IMemberContext context)
1121                 {
1122                         foreach (Attribute a in Attrs)
1123                                 a.AttachTo (attributable, context);
1124                 }
1125
1126                 public Attributes Clone ()
1127                 {
1128                         var al = new List<Attribute> (Attrs.Count);
1129                         foreach (Attribute a in Attrs)
1130                                 al.Add (a.Clone ());
1131
1132                         return new Attributes (al);
1133                 }
1134
1135                 /// <summary>
1136                 /// Checks whether attribute target is valid for the current element
1137                 /// </summary>
1138                 public bool CheckTargets ()
1139                 {
1140                         for (int i = 0; i < Attrs.Count; ++i) {
1141                                 if (!Attrs [i].CheckTarget ())
1142                                         Attrs.RemoveAt (i--);
1143                         }
1144
1145                         return true;
1146                 }
1147
1148                 public void ConvertGlobalAttributes (TypeContainer member, NamespaceContainer currentNamespace, bool isGlobal)
1149                 {
1150                         var member_explicit_targets = member.ValidAttributeTargets;
1151                         for (int i = 0; i < Attrs.Count; ++i) {
1152                                 var attr = Attrs[0];
1153                                 if (attr.ExplicitTarget == null)
1154                                         continue;
1155
1156                                 int ii;
1157                                 for (ii = 0; ii < member_explicit_targets.Length; ++ii) {
1158                                         if (attr.ExplicitTarget == member_explicit_targets[ii]) {
1159                                                 ii = -1;
1160                                                 break;
1161                                         }
1162                                 }
1163
1164                                 if (ii < 0 || !isGlobal)
1165                                         continue;
1166
1167                                 member.Module.AddAttribute (attr, currentNamespace);
1168                                 Attrs.RemoveAt (i);
1169                                 --i;
1170                         }
1171                 }
1172
1173                 public Attribute Search (PredefinedAttribute t)
1174                 {
1175                         return Search (null, t);
1176                 }
1177
1178                 public Attribute Search (string explicitTarget, PredefinedAttribute t)
1179                 {
1180                         foreach (Attribute a in Attrs) {
1181                                 if (explicitTarget != null && a.ExplicitTarget != explicitTarget)
1182                                         continue;
1183
1184                                 if (a.ResolveType () == t)
1185                                         return a;
1186                         }
1187                         return null;
1188                 }
1189
1190                 /// <summary>
1191                 /// Returns all attributes of type 't'. Use it when attribute is AllowMultiple = true
1192                 /// </summary>
1193                 public Attribute[] SearchMulti (PredefinedAttribute t)
1194                 {
1195                         List<Attribute> ar = null;
1196
1197                         foreach (Attribute a in Attrs) {
1198                                 if (a.ResolveType () == t) {
1199                                         if (ar == null)
1200                                                 ar = new List<Attribute> (Attrs.Count);
1201                                         ar.Add (a);
1202                                 }
1203                         }
1204
1205                         return ar == null ? null : ar.ToArray ();
1206                 }
1207
1208                 public void Emit ()
1209                 {
1210                         CheckTargets ();
1211
1212                         Dictionary<Attribute, List<Attribute>> ld = Attrs.Count > 1 ? new Dictionary<Attribute, List<Attribute>> () : null;
1213
1214                         foreach (Attribute a in Attrs)
1215                                 a.Emit (ld);
1216
1217                         if (ld == null || ld.Count == 0)
1218                                 return;
1219
1220                         foreach (var d in ld) {
1221                                 if (d.Value == null)
1222                                         continue;
1223
1224                                 Attribute a = d.Key;
1225
1226                                 foreach (Attribute collision in d.Value)
1227                                         a.Report.SymbolRelatedToPreviousError (collision.Location, "");
1228
1229                                 a.Report.Error (579, a.Location, "The attribute `{0}' cannot be applied multiple times",
1230                                         a.GetSignatureForError ());
1231                         }
1232                 }
1233
1234                 public bool Contains (PredefinedAttribute t)
1235                 {
1236                         return Search (t) != null;
1237                 }
1238         }
1239
1240         public sealed class AttributeEncoder
1241         {
1242                 [Flags]
1243                 public enum EncodedTypeProperties
1244                 {
1245                         None = 0,
1246                         DynamicType = 1,
1247                         TypeParameter = 1 << 1
1248                 }
1249
1250                 public static readonly byte[] Empty;
1251
1252                 byte[] buffer;
1253                 int pos;
1254                 const ushort Version = 1;
1255
1256                 static AttributeEncoder ()
1257                 {
1258                         Empty = new byte[4];
1259                         Empty[0] = (byte) Version;
1260                 }
1261
1262                 public AttributeEncoder ()
1263                 {
1264                         buffer = new byte[32];
1265                         Encode (Version);
1266                 }
1267
1268                 public void Encode (bool value)
1269                 {
1270                         Encode (value ? (byte) 1 : (byte) 0);
1271                 }
1272
1273                 public void Encode (byte value)
1274                 {
1275                         if (pos == buffer.Length)
1276                                 Grow (1);
1277
1278                         buffer [pos++] = value;
1279                 }
1280
1281                 public void Encode (sbyte value)
1282                 {
1283                         Encode ((byte) value);
1284                 }
1285
1286                 public void Encode (short value)
1287                 {
1288                         if (pos + 2 > buffer.Length)
1289                                 Grow (2);
1290
1291                         buffer[pos++] = (byte) value;
1292                         buffer[pos++] = (byte) (value >> 8);
1293                 }
1294
1295                 public void Encode (ushort value)
1296                 {
1297                         Encode ((short) value);
1298                 }
1299
1300                 public void Encode (int value)
1301                 {
1302                         if (pos + 4 > buffer.Length)
1303                                 Grow (4);
1304
1305                         buffer[pos++] = (byte) value;
1306                         buffer[pos++] = (byte) (value >> 8);
1307                         buffer[pos++] = (byte) (value >> 16);
1308                         buffer[pos++] = (byte) (value >> 24);
1309                 }
1310
1311                 public void Encode (uint value)
1312                 {
1313                         Encode ((int) value);
1314                 }
1315
1316                 public void Encode (long value)
1317                 {
1318                         if (pos + 8 > buffer.Length)
1319                                 Grow (8);
1320
1321                         buffer[pos++] = (byte) value;
1322                         buffer[pos++] = (byte) (value >> 8);
1323                         buffer[pos++] = (byte) (value >> 16);
1324                         buffer[pos++] = (byte) (value >> 24);
1325                         buffer[pos++] = (byte) (value >> 32);
1326                         buffer[pos++] = (byte) (value >> 40);
1327                         buffer[pos++] = (byte) (value >> 48);
1328                         buffer[pos++] = (byte) (value >> 56);
1329                 }
1330
1331                 public void Encode (ulong value)
1332                 {
1333                         Encode ((long) value);
1334                 }
1335
1336                 public void Encode (float value)
1337                 {
1338                         Encode (SingleConverter.SingleToInt32Bits (value));
1339                 }
1340
1341                 public void Encode (double value)
1342                 {
1343                         Encode (BitConverter.DoubleToInt64Bits (value));
1344                 }
1345
1346                 public void Encode (string value)
1347                 {
1348                         if (value == null) {
1349                                 Encode ((byte) 0xFF);
1350                                 return;
1351                         }
1352
1353                         var buf = Encoding.UTF8.GetBytes(value);
1354                         WriteCompressedValue (buf.Length);
1355
1356                         if (pos + buf.Length > buffer.Length)
1357                                 Grow (buf.Length);
1358
1359                         Buffer.BlockCopy (buf, 0, buffer, pos, buf.Length);
1360                         pos += buf.Length;
1361                 }
1362
1363                 public EncodedTypeProperties Encode (TypeSpec type)
1364                 {
1365                         switch (type.BuiltinType) {
1366                         case BuiltinTypeSpec.Type.Bool:
1367                                 Encode ((byte) 0x02);
1368                                 break;
1369                         case BuiltinTypeSpec.Type.Char:
1370                                 Encode ((byte) 0x03);
1371                                 break;
1372                         case BuiltinTypeSpec.Type.SByte:
1373                                 Encode ((byte) 0x04);
1374                                 break;
1375                         case BuiltinTypeSpec.Type.Byte:
1376                                 Encode ((byte) 0x05);
1377                                 break;
1378                         case BuiltinTypeSpec.Type.Short:
1379                                 Encode ((byte) 0x06);
1380                                 break;
1381                         case BuiltinTypeSpec.Type.UShort:
1382                                 Encode ((byte) 0x07);
1383                                 break;
1384                         case BuiltinTypeSpec.Type.Int:
1385                                 Encode ((byte) 0x08);
1386                                 break;
1387                         case BuiltinTypeSpec.Type.UInt:
1388                                 Encode ((byte) 0x09);
1389                                 break;
1390                         case BuiltinTypeSpec.Type.Long:
1391                                 Encode ((byte) 0x0A);
1392                                 break;
1393                         case BuiltinTypeSpec.Type.ULong:
1394                                 Encode ((byte) 0x0B);
1395                                 break;
1396                         case BuiltinTypeSpec.Type.Float:
1397                                 Encode ((byte) 0x0C);
1398                                 break;
1399                         case BuiltinTypeSpec.Type.Double:
1400                                 Encode ((byte) 0x0D);
1401                                 break;
1402                         case BuiltinTypeSpec.Type.String:
1403                                 Encode ((byte) 0x0E);
1404                                 break;
1405                         case BuiltinTypeSpec.Type.Type:
1406                                 Encode ((byte) 0x50);
1407                                 break;
1408                         case BuiltinTypeSpec.Type.Object:
1409                                 Encode ((byte) 0x51);
1410                                 break;
1411                         case BuiltinTypeSpec.Type.Dynamic:
1412                                 Encode ((byte) 0x51);
1413                                 return EncodedTypeProperties.DynamicType;
1414                         default:
1415                                 if (type.IsArray) {
1416                                         Encode ((byte) 0x1D);
1417                                         return Encode (TypeManager.GetElementType (type));
1418                                 }
1419
1420                                 if (type.Kind == MemberKind.Enum) {
1421                                         Encode ((byte) 0x55);
1422                                         EncodeTypeName (type);
1423                                 }
1424
1425                                 break;
1426                         }
1427
1428                         return EncodedTypeProperties.None;
1429                 }
1430
1431                 public void EncodeTypeName (TypeSpec type)
1432                 {
1433                         var old_type = type.GetMetaInfo ();
1434                         Encode (type.MemberDefinition.IsImported ? old_type.AssemblyQualifiedName : old_type.FullName);
1435                 }
1436
1437                 //
1438                 // Encodes single property named argument per call
1439                 //
1440                 public void EncodeNamedPropertyArgument (PropertySpec property, Constant value)
1441                 {
1442                         Encode ((ushort) 1);    // length
1443                         Encode ((byte) 0x54); // property
1444                         Encode (property.MemberType);
1445                         Encode (property.Name);
1446                         value.EncodeAttributeValue (null, this, property.MemberType);
1447                 }
1448
1449                 //
1450                 // Encodes single field named argument per call
1451                 //
1452                 public void EncodeNamedFieldArgument (FieldSpec field, Constant value)
1453                 {
1454                         Encode ((ushort) 1);    // length
1455                         Encode ((byte) 0x53); // field
1456                         Encode (field.MemberType);
1457                         Encode (field.Name);
1458                         value.EncodeAttributeValue (null, this, field.MemberType);
1459                 }
1460
1461                 public void EncodeNamedArguments<T> (T[] members, Constant[] values) where T : MemberSpec, IInterfaceMemberSpec
1462                 {
1463                         Encode ((ushort) members.Length);
1464
1465                         for (int i = 0; i < members.Length; ++i)
1466                         {
1467                                 var member = members[i];
1468
1469                                 if (member.Kind == MemberKind.Field)
1470                                         Encode ((byte) 0x53);
1471                                 else if (member.Kind == MemberKind.Property)
1472                                         Encode ((byte) 0x54);
1473                                 else
1474                                         throw new NotImplementedException (member.Kind.ToString ());
1475
1476                                 Encode (member.MemberType);
1477                                 Encode (member.Name);
1478                                 values [i].EncodeAttributeValue (null, this, member.MemberType);
1479                         }
1480                 }
1481
1482                 public void EncodeEmptyNamedArguments ()
1483                 {
1484                         Encode ((ushort) 0);
1485                 }
1486
1487                 void Grow (int inc)
1488                 {
1489                         int size = System.Math.Max (pos * 4, pos + inc + 2);
1490                         Array.Resize (ref buffer, size);
1491                 }
1492
1493                 void WriteCompressedValue (int value)
1494                 {
1495                         if (value < 0x80) {
1496                                 Encode ((byte) value);
1497                                 return;
1498                         }
1499
1500                         if (value < 0x4000) {
1501                                 Encode ((byte) (0x80 | (value >> 8)));
1502                                 Encode ((byte) value);
1503                                 return;
1504                         }
1505
1506                         Encode (value);
1507                 }
1508
1509                 public byte[] ToArray ()
1510                 {
1511                         byte[] buf = new byte[pos];
1512                         Array.Copy (buffer, buf, pos);
1513                         return buf;
1514                 }
1515         }
1516
1517
1518         /// <summary>
1519         /// Helper class for attribute verification routine.
1520         /// </summary>
1521         static class AttributeTester
1522         {
1523                 public enum Result {
1524                         Ok,
1525                         RefOutArrayError,
1526                         ArrayArrayError
1527                 }
1528
1529                 /// <summary>
1530                 /// Returns true if parameters of two compared methods are CLS-Compliant.
1531                 /// It tests differing only in ref or out, or in array rank.
1532                 /// </summary>
1533                 public static Result AreOverloadedMethodParamsClsCompliant (AParametersCollection pa, AParametersCollection pb) 
1534                 {
1535                         TypeSpec [] types_a = pa.Types;
1536                         TypeSpec [] types_b = pb.Types;
1537                         if (types_a == null || types_b == null)
1538                                 return Result.Ok;
1539
1540                         if (types_a.Length != types_b.Length)
1541                                 return Result.Ok;
1542
1543                         Result result = Result.Ok;
1544                         for (int i = 0; i < types_b.Length; ++i) {
1545                                 TypeSpec aType = types_a [i];
1546                                 TypeSpec bType = types_b [i];
1547
1548                                 var ac_a = aType as ArrayContainer;
1549                                 var ac_b = aType as ArrayContainer;
1550
1551                                 if (ac_a != null && ac_b != null) {
1552                                         if (ac_a.Rank != ac_b.Rank && ac_a.Element == ac_b.Element) {
1553                                                 result = Result.RefOutArrayError;
1554                                                 continue;
1555                                         }
1556
1557                                         if (ac_a.Element.IsArray || ac_b.Element.IsArray) {
1558                                                 result = Result.ArrayArrayError;
1559                                                 continue;
1560                                         }
1561                                 }
1562
1563                                 if (aType != bType)
1564                                         return Result.Ok;
1565
1566                                 const Parameter.Modifier out_ref_mod = (Parameter.Modifier.OUTMASK | Parameter.Modifier.REFMASK);
1567                                 if ((pa.FixedParameters[i].ModFlags & out_ref_mod) != (pb.FixedParameters[i].ModFlags & out_ref_mod))
1568                                         result = Result.RefOutArrayError;
1569                         }
1570                         return result;
1571                 }
1572
1573                 /// <summary>
1574                 /// Common method for Obsolete error/warning reporting.
1575                 /// </summary>
1576                 public static void Report_ObsoleteMessage (ObsoleteAttribute oa, string member, Location loc, Report Report)
1577                 {
1578                         if (oa.IsError) {
1579                                 Report.Error (619, loc, "`{0}' is obsolete: `{1}'", member, oa.Message);
1580                                 return;
1581                         }
1582
1583                         if (oa.Message == null || oa.Message.Length == 0) {
1584                                 Report.Warning (612, 1, loc, "`{0}' is obsolete", member);
1585                                 return;
1586                         }
1587                         Report.Warning (618, 2, loc, "`{0}' is obsolete: `{1}'", member, oa.Message);
1588                 }
1589         }
1590
1591         //
1592         // Predefined attribute types
1593         //
1594         public class PredefinedAttributes
1595         {
1596                 // Build-in attributes
1597                 public readonly PredefinedAttribute ParamArray;
1598                 public readonly PredefinedAttribute Out;
1599
1600                 // Optional attributes
1601                 public readonly PredefinedAttribute Obsolete;
1602                 public readonly PredefinedAttribute DllImport;
1603                 public readonly PredefinedAttribute MethodImpl;
1604                 public readonly PredefinedAttribute MarshalAs;
1605                 public readonly PredefinedAttribute In;
1606                 public readonly PredefinedAttribute IndexerName;
1607                 public readonly PredefinedAttribute Conditional;
1608                 public readonly PredefinedAttribute CLSCompliant;
1609                 public readonly PredefinedAttribute Security;
1610                 public readonly PredefinedAttribute Required;
1611                 public readonly PredefinedAttribute Guid;
1612                 public readonly PredefinedAttribute AssemblyCulture;
1613                 public readonly PredefinedAttribute AssemblyVersion;
1614                 public readonly PredefinedAttribute AssemblyAlgorithmId;
1615                 public readonly PredefinedAttribute AssemblyFlags;
1616                 public readonly PredefinedAttribute AssemblyFileVersion;
1617                 public readonly PredefinedAttribute ComImport;
1618                 public readonly PredefinedAttribute CoClass;
1619                 public readonly PredefinedAttribute AttributeUsage;
1620                 public readonly PredefinedAttribute DefaultParameterValue;
1621                 public readonly PredefinedAttribute OptionalParameter;
1622                 public readonly PredefinedAttribute UnverifiableCode;
1623                 public readonly PredefinedAttribute DefaultCharset;
1624                 public readonly PredefinedAttribute TypeForwarder;
1625                 public readonly PredefinedAttribute FixedBuffer;
1626                 public readonly PredefinedAttribute CompilerGenerated;
1627                 public readonly PredefinedAttribute InternalsVisibleTo;
1628                 public readonly PredefinedAttribute RuntimeCompatibility;
1629                 public readonly PredefinedAttribute DebuggerHidden;
1630                 public readonly PredefinedAttribute UnsafeValueType;
1631                 public readonly PredefinedAttribute UnmanagedFunctionPointer;
1632
1633                 // New in .NET 3.5
1634                 public readonly PredefinedAttribute Extension;
1635
1636                 // New in .NET 4.0
1637                 public readonly PredefinedDynamicAttribute Dynamic;
1638
1639                 //
1640                 // Optional types which are used as types and for member lookup
1641                 //
1642                 public readonly PredefinedAttribute DefaultMember;
1643                 public readonly PredefinedDecimalAttribute DecimalConstant;
1644                 public readonly PredefinedAttribute StructLayout;
1645                 public readonly PredefinedAttribute FieldOffset;
1646
1647                 public PredefinedAttributes (ModuleContainer module)
1648                 {
1649                         ParamArray = new PredefinedAttribute (module, "System", "ParamArrayAttribute");
1650                         Out = new PredefinedAttribute (module, "System.Runtime.InteropServices", "OutAttribute");
1651                         ParamArray.Resolve ();
1652                         Out.Resolve ();
1653
1654                         Obsolete = new PredefinedAttribute (module, "System", "ObsoleteAttribute");
1655                         DllImport = new PredefinedAttribute (module, "System.Runtime.InteropServices", "DllImportAttribute");
1656                         MethodImpl = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "MethodImplAttribute");
1657                         MarshalAs = new PredefinedAttribute (module, "System.Runtime.InteropServices", "MarshalAsAttribute");
1658                         In = new PredefinedAttribute (module, "System.Runtime.InteropServices", "InAttribute");
1659                         IndexerName = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "IndexerNameAttribute");
1660                         Conditional = new PredefinedAttribute (module, "System.Diagnostics", "ConditionalAttribute");
1661                         CLSCompliant = new PredefinedAttribute (module, "System", "CLSCompliantAttribute");
1662                         Security = new PredefinedAttribute (module, "System.Security.Permissions", "SecurityAttribute");
1663                         Required = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "RequiredAttributeAttribute");
1664                         Guid = new PredefinedAttribute (module, "System.Runtime.InteropServices", "GuidAttribute");
1665                         AssemblyCulture = new PredefinedAttribute (module, "System.Reflection", "AssemblyCultureAttribute");
1666                         AssemblyVersion = new PredefinedAttribute (module, "System.Reflection", "AssemblyVersionAttribute");
1667                         AssemblyAlgorithmId = new PredefinedAttribute (module, "System.Reflection", "AssemblyAlgorithmIdAttribute");
1668                         AssemblyFlags = new PredefinedAttribute (module, "System.Reflection", "AssemblyFlagsAttribute");
1669                         AssemblyFileVersion = new PredefinedAttribute (module, "System.Reflection", "AssemblyFileVersionAttribute");
1670                         ComImport = new PredefinedAttribute (module, "System.Runtime.InteropServices", "ComImportAttribute");
1671                         CoClass = new PredefinedAttribute (module, "System.Runtime.InteropServices", "CoClassAttribute");
1672                         AttributeUsage = new PredefinedAttribute (module, "System", "AttributeUsageAttribute");
1673                         DefaultParameterValue = new PredefinedAttribute (module, "System.Runtime.InteropServices", "DefaultParameterValueAttribute");
1674                         OptionalParameter = new PredefinedAttribute (module, "System.Runtime.InteropServices", "OptionalAttribute");
1675                         UnverifiableCode = new PredefinedAttribute (module, "System.Security", "UnverifiableCodeAttribute");
1676
1677                         DefaultCharset = new PredefinedAttribute (module, "System.Runtime.InteropServices", "DefaultCharSetAttribute");
1678                         TypeForwarder = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "TypeForwardedToAttribute");
1679                         FixedBuffer = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "FixedBufferAttribute");
1680                         CompilerGenerated = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "CompilerGeneratedAttribute");
1681                         InternalsVisibleTo = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "InternalsVisibleToAttribute");
1682                         RuntimeCompatibility = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "RuntimeCompatibilityAttribute");
1683                         DebuggerHidden = new PredefinedAttribute (module, "System.Diagnostics", "DebuggerHiddenAttribute");
1684                         UnsafeValueType = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "UnsafeValueTypeAttribute");
1685                         UnmanagedFunctionPointer = new PredefinedAttribute (module, "System.Runtime.InteropServices", "UnmanagedFunctionPointerAttribute");
1686
1687                         Extension = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "ExtensionAttribute");
1688
1689                         Dynamic = new PredefinedDynamicAttribute (module, "System.Runtime.CompilerServices", "DynamicAttribute");
1690
1691                         DefaultMember = new PredefinedAttribute (module, "System.Reflection", "DefaultMemberAttribute");
1692                         DecimalConstant = new PredefinedDecimalAttribute (module, "System.Runtime.CompilerServices", "DecimalConstantAttribute");
1693                         StructLayout = new PredefinedAttribute (module, "System.Runtime.InteropServices", "StructLayoutAttribute");
1694                         FieldOffset = new PredefinedAttribute (module, "System.Runtime.InteropServices", "FieldOffsetAttribute");
1695
1696                         // TODO: Should define only attributes which are used for comparison
1697                         const System.Reflection.BindingFlags all_fields = System.Reflection.BindingFlags.Public |
1698                                 System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.DeclaredOnly;
1699
1700                         foreach (var fi in GetType ().GetFields (all_fields)) {
1701                                 ((PredefinedAttribute) fi.GetValue (this)).Define ();
1702                         }
1703                 }
1704         }
1705
1706         public class PredefinedAttribute : PredefinedType
1707         {
1708                 protected MethodSpec ctor;
1709
1710                 public PredefinedAttribute (ModuleContainer module, string ns, string name)
1711                         : base (module, MemberKind.Class, ns, name)
1712                 {
1713                 }
1714
1715                 #region Properties
1716
1717                 public MethodSpec Constructor {
1718                         get {
1719                                 return ctor;
1720                         }
1721                 }
1722
1723                 #endregion
1724
1725                 public static bool operator == (TypeSpec type, PredefinedAttribute pa)
1726                 {
1727                         return type == pa.type && pa.type != null;
1728                 }
1729
1730                 public static bool operator != (TypeSpec type, PredefinedAttribute pa)
1731                 {
1732                         return type != pa.type;
1733                 }
1734
1735                 public override int GetHashCode ()
1736                 {
1737                         return base.GetHashCode ();
1738                 }
1739
1740                 public override bool Equals (object obj)
1741                 {
1742                         throw new NotSupportedException ();
1743                 }
1744
1745                 public void EmitAttribute (ConstructorBuilder builder)
1746                 {
1747                         if (ResolveBuilder ())
1748                                 builder.SetCustomAttribute (GetCtorMetaInfo (), AttributeEncoder.Empty);
1749                 }
1750
1751                 public void EmitAttribute (MethodBuilder builder)
1752                 {
1753                         if (ResolveBuilder ())
1754                                 builder.SetCustomAttribute (GetCtorMetaInfo (), AttributeEncoder.Empty);
1755                 }
1756
1757                 public void EmitAttribute (PropertyBuilder builder)
1758                 {
1759                         if (ResolveBuilder ())
1760                                 builder.SetCustomAttribute (GetCtorMetaInfo (), AttributeEncoder.Empty);
1761                 }
1762
1763                 public void EmitAttribute (FieldBuilder builder)
1764                 {
1765                         if (ResolveBuilder ())
1766                                 builder.SetCustomAttribute (GetCtorMetaInfo (), AttributeEncoder.Empty);
1767                 }
1768
1769                 public void EmitAttribute (FieldBuilder builder, AttributeEncoder argsEncoded)
1770                 {
1771                         builder.SetCustomAttribute (GetCtorMetaInfo (), argsEncoded.ToArray ());
1772                 }
1773
1774                 public void EmitAttribute (TypeBuilder builder)
1775                 {
1776                         if (ResolveBuilder ())
1777                                 builder.SetCustomAttribute (GetCtorMetaInfo (), AttributeEncoder.Empty);
1778                 }
1779
1780                 public void EmitAttribute (TypeBuilder builder, AttributeEncoder argsEncoded)
1781                 {
1782                         builder.SetCustomAttribute (GetCtorMetaInfo (), argsEncoded.ToArray ());
1783                 }
1784
1785                 public void EmitAttribute (AssemblyBuilder builder)
1786                 {
1787                         if (ResolveBuilder ())
1788                                 builder.SetCustomAttribute (GetCtorMetaInfo (), AttributeEncoder.Empty);
1789                 }
1790
1791                 public void EmitAttribute (ModuleBuilder builder)
1792                 {
1793                         if (ResolveBuilder ())
1794                                 builder.SetCustomAttribute (GetCtorMetaInfo (), AttributeEncoder.Empty);
1795                 }
1796
1797                 public void EmitAttribute (ParameterBuilder builder)
1798                 {
1799                         if (ResolveBuilder ())
1800                                 builder.SetCustomAttribute (GetCtorMetaInfo (), AttributeEncoder.Empty);
1801                 }
1802
1803                 public void EmitAttribute (ParameterBuilder builder, AttributeEncoder argsEncoded)
1804                 {
1805                         builder.SetCustomAttribute (GetCtorMetaInfo (), argsEncoded.ToArray ());
1806                 }
1807
1808                 ConstructorInfo GetCtorMetaInfo ()
1809                 {
1810                         return (ConstructorInfo) ctor.GetMetaInfo ();
1811                 }
1812
1813                 public bool ResolveBuilder ()
1814                 {
1815                         if (ctor != null)
1816                                 return true;
1817
1818                         //
1819                         // Handle all parameter-less attributes as optional
1820                         //
1821                         if (!IsDefined)
1822                                 return false;
1823
1824                         ctor = (MethodSpec) MemberCache.FindMember (type, MemberFilter.Constructor (ParametersCompiled.EmptyReadOnlyParameters), BindingRestriction.DeclaredOnly);
1825                         return ctor != null;
1826                 }
1827         }
1828
1829         public class PredefinedDecimalAttribute : PredefinedAttribute
1830         {
1831                 public PredefinedDecimalAttribute (ModuleContainer module, string ns, string name)
1832                         : base (module, ns, name)
1833                 {
1834                 }
1835
1836                 public void EmitAttribute (ParameterBuilder builder, decimal value, Location loc)
1837                 {
1838                         var ctor = module.PredefinedMembers.DecimalConstantAttributeCtor.Resolve (loc);
1839                         if (ctor == null)
1840                                 return;
1841
1842                         int[] bits = decimal.GetBits (value);
1843                         AttributeEncoder encoder = new AttributeEncoder ();
1844                         encoder.Encode ((byte) (bits[3] >> 16));
1845                         encoder.Encode ((byte) (bits[3] >> 31));
1846                         encoder.Encode ((uint) bits[2]);
1847                         encoder.Encode ((uint) bits[1]);
1848                         encoder.Encode ((uint) bits[0]);
1849                         encoder.EncodeEmptyNamedArguments ();
1850
1851                         builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ());
1852                 }
1853
1854                 public void EmitAttribute (FieldBuilder builder, decimal value, Location loc)
1855                 {
1856                         var ctor = module.PredefinedMembers.DecimalConstantAttributeCtor.Resolve (loc);
1857                         if (ctor == null)
1858                                 return;
1859
1860                         int[] bits = decimal.GetBits (value);
1861                         AttributeEncoder encoder = new AttributeEncoder ();
1862                         encoder.Encode ((byte) (bits[3] >> 16));
1863                         encoder.Encode ((byte) (bits[3] >> 31));
1864                         encoder.Encode ((uint) bits[2]);
1865                         encoder.Encode ((uint) bits[1]);
1866                         encoder.Encode ((uint) bits[0]);
1867                         encoder.EncodeEmptyNamedArguments ();
1868
1869                         builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ());
1870                 }
1871         }
1872
1873         public class PredefinedDynamicAttribute : PredefinedAttribute
1874         {
1875                 MethodSpec tctor;
1876
1877                 public PredefinedDynamicAttribute (ModuleContainer module, string ns, string name)
1878                         : base (module, ns, name)
1879                 {
1880                 }
1881
1882                 public void EmitAttribute (FieldBuilder builder, TypeSpec type, Location loc)
1883                 {
1884                         if (ResolveTransformationCtor (loc)) {
1885                                 var cab = new CustomAttributeBuilder ((ConstructorInfo) tctor.GetMetaInfo (), new object[] { GetTransformationFlags (type) });
1886                                 builder.SetCustomAttribute (cab);
1887                         }
1888                 }
1889
1890                 public void EmitAttribute (ParameterBuilder builder, TypeSpec type, Location loc)
1891                 {
1892                         if (ResolveTransformationCtor (loc)) {
1893                                 var cab = new CustomAttributeBuilder ((ConstructorInfo) tctor.GetMetaInfo (), new object[] { GetTransformationFlags (type) });
1894                                 builder.SetCustomAttribute (cab);
1895                         }
1896                 }
1897
1898                 public void EmitAttribute (PropertyBuilder builder, TypeSpec type, Location loc)
1899                 {
1900                         if (ResolveTransformationCtor (loc)) {
1901                                 var cab = new CustomAttributeBuilder ((ConstructorInfo) tctor.GetMetaInfo (), new object[] { GetTransformationFlags (type) });
1902                                 builder.SetCustomAttribute (cab);
1903                         }
1904                 }
1905
1906                 public void EmitAttribute (TypeBuilder builder, TypeSpec type, Location loc)
1907                 {
1908                         if (ResolveTransformationCtor (loc)) {
1909                                 var cab = new CustomAttributeBuilder ((ConstructorInfo) tctor.GetMetaInfo (), new object[] { GetTransformationFlags (type) });
1910                                 builder.SetCustomAttribute (cab);
1911                         }
1912                 }
1913
1914                 //
1915                 // When any element of the type is a dynamic type
1916                 //
1917                 // This method builds a transformation array for dynamic types
1918                 // used in places where DynamicAttribute cannot be applied to.
1919                 // It uses bool flag when type is of dynamic type and each
1920                 // section always starts with "false" for some reason.
1921                 //
1922                 // LAMESPEC: This should be part of C# specification
1923                 // 
1924                 // Example: Func<dynamic, int, dynamic[]>
1925                 // Transformation: { false, true, false, false, true }
1926                 //
1927                 static bool[] GetTransformationFlags (TypeSpec t)
1928                 {
1929                         bool[] element;
1930                         var ac = t as ArrayContainer;
1931                         if (ac != null) {
1932                                 element = GetTransformationFlags (ac.Element);
1933                                 if (element == null)
1934                                         return null;
1935
1936                                 bool[] res = new bool[element.Length + 1];
1937                                 res[0] = false;
1938                                 Array.Copy (element, 0, res, 1, element.Length);
1939                                 return res;
1940                         }
1941
1942                         if (t == null)
1943                                 return null;
1944
1945                         if (t.IsGeneric) {
1946                                 List<bool> transform = null;
1947                                 var targs = t.TypeArguments;
1948                                 for (int i = 0; i < targs.Length; ++i) {
1949                                         element = GetTransformationFlags (targs[i]);
1950                                         if (element != null) {
1951                                                 if (transform == null) {
1952                                                         transform = new List<bool> ();
1953                                                         for (int ii = 0; ii <= i; ++ii)
1954                                                                 transform.Add (false);
1955                                                 }
1956
1957                                                 transform.AddRange (element);
1958                                         } else if (transform != null) {
1959                                                 transform.Add (false);
1960                                         }
1961                                 }
1962
1963                                 if (transform != null)
1964                                         return transform.ToArray ();
1965                         }
1966
1967                         if (t.BuiltinType == BuiltinTypeSpec.Type.Dynamic)
1968                                 return new bool[] { true };
1969
1970                         return null;
1971                 }
1972
1973                 bool ResolveTransformationCtor (Location loc)
1974                 {
1975                         if (tctor != null)
1976                                 return true;
1977
1978                         tctor = module.PredefinedMembers.DynamicAttributeCtor.Resolve (loc);
1979                         return tctor != null;
1980                 }
1981         }
1982 }