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