// 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;
}
}
+ //
+ // 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)
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)
{
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;
}
}
return ((TypeParameterSpec) t).IsReferenceType;
case MemberKind.Struct:
case MemberKind.Enum:
+ case MemberKind.Void:
return false;
case MemberKind.InternalCompilerType:
//
}
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;
}
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 ErrorType = new InternalType ("<error>");
readonly string name;