mcs/error recovery: handle errors caused by closing braces after a statement expressi...
[mono.git] / mcs / mcs / typespec.cs
index 5988ddca5f7f04053a3c105e64d61ffab3180399..7ed97604a0f209ab5db2269ec37d8641e858fc8a 100644 (file)
@@ -6,6 +6,7 @@
 // Dual licensed under the terms of the MIT X11 or GNU GPL
 //
 // Copyright 2010 Novell, Inc
+// Copyright 2011 Xamarin, Inc (http://www.xamarin.com)
 //
 
 using System;
@@ -283,6 +284,28 @@ namespace Mono.CSharp
                        }
                }
 
+               //
+               // Whether a type is unmanaged. This is used by the unsafe code
+               //
+               public bool IsUnmanaged {
+                       get {
+                               if (IsPointer)
+                                       return ((ElementTypeSpec) this).Element.IsUnmanaged;
+
+                               var ds = MemberDefinition as TypeDefinition;
+                               if (ds != null)
+                                       return ds.IsUnmanagedType ();
+
+                               if (Kind == MemberKind.Void)
+                                       return true;
+
+                               if (IsNested && DeclaringType.IsGenericOrParentIsGeneric)
+                                       return false;
+
+                               return IsValueType (this);
+                       }
+               }
+
                public MemberCache MemberCache {
                        get {
                                if (cache == null || (state & StateFlags.PendingMemberCacheMembers) != 0)
@@ -339,6 +362,58 @@ namespace Mono.CSharp
                        return false;
                }
 
+               //
+               // Special version used during type definition
+               //
+               public bool AddInterfaceDefined (TypeSpec iface)
+               {
+                       if (!AddInterface (iface))
+                               return false;
+
+                       //
+                       // We can get into a situation where a type is inflated before
+                       // its interfaces are resoved. Consider this situation
+                       //
+                       // class A<T> : X<A<int>>, IFoo {}
+                       //
+                       // When resolving base class of X`1 we inflate context type A`1
+                       // All this happens before we even hit IFoo resolve. Without
+                       // additional expansion any inside usage of A<T> would miss IFoo
+                       // interface because it comes from early inflated TypeSpec
+                       //
+                       if (inflated_instances != null) {
+                               foreach (var inflated in inflated_instances) {
+                                       inflated.Value.AddInterface (iface);
+                               }
+                       }
+
+                       return true;
+               }
+
+               //
+               // Returns all type arguments, usefull for nested types
+               //
+               public static TypeSpec[] GetAllTypeArguments (TypeSpec type)
+               {
+                       IList<TypeSpec> targs = TypeSpec.EmptyTypes;
+
+                       do {
+                               if (type.Arity > 0) {
+                                       if (targs.Count == 0) {
+                                               targs = type.TypeArguments;
+                                       } else {
+                                               var list = targs as List<TypeSpec> ?? new List<TypeSpec> (targs);
+                                               list.AddRange (type.TypeArguments);
+                                               targs = list;
+                                       }
+                               }
+
+                               type = type.declaringType;
+                       } while (type != null);
+
+                       return targs as TypeSpec[] ?? ((List<TypeSpec>) targs).ToArray ();
+               }
+
                public AttributeUsageAttribute GetAttributeUsage (PredefinedAttribute pa)
                {
                        if (Kind != MemberKind.Class)
@@ -464,12 +539,13 @@ namespace Mono.CSharp
                {
                        var t = this;
                        do {
-                               if (t.Interfaces != null) {
-                                       foreach (TypeSpec i in t.Interfaces) {
-                                               if (i == iface || TypeSpecComparer.IsEqual (i, iface))
+                               var ifaces = t.Interfaces;
+                               if (ifaces != null) {
+                                       for (int i = 0; i < ifaces.Count; ++i) {
+                                               if (TypeSpecComparer.IsEqual (ifaces[i], iface))
                                                        return true;
 
-                                               if (variantly && TypeSpecComparer.Variant.IsEqual (i, iface))
+                                               if (variantly && TypeSpecComparer.Variant.IsEqual (ifaces[i], iface))
                                                        return true;
                                        }
                                }
@@ -535,6 +611,7 @@ namespace Mono.CSharp
                                return ((TypeParameterSpec) t).IsReferenceType;
                        case MemberKind.Struct:
                        case MemberKind.Enum:
+                       case MemberKind.Void:
                                return false;
                        case MemberKind.InternalCompilerType:
                                //
@@ -1016,10 +1093,11 @@ namespace Mono.CSharp
                                }
 
                                for (int i = 0; i < targs_definition.Length; ++i) {
+                                       if (TypeSpecComparer.IsEqual (t1_targs[i], t2_targs[i]))
+                                               continue;
+
                                        Variance v = targs_definition[i].Variance;
                                        if (v == Variance.None) {
-                                               if (t1_targs[i] == t2_targs[i])
-                                                       continue;
                                                return false;
                                        }
 
@@ -1243,7 +1321,7 @@ namespace Mono.CSharp
                public static readonly InternalType NullLiteral = new InternalType ("null");
                public static readonly InternalType FakeInternalType = new InternalType ("<fake$type>");
                public static readonly InternalType Namespace = new InternalType ("<namespace>");
-               public static readonly InternalType CurrentTypeOnStack = new InternalType ("<this>");
+               public static readonly InternalType ErrorType = new InternalType ("<error>");
 
                readonly string name;