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