//
using System;
-using System.IO;
using System.Globalization;
using System.Collections.Generic;
-using System.Reflection;
-using System.Reflection.Emit;
using System.Text;
-using System.Runtime.CompilerServices;
-using System.Diagnostics;
-using System.Linq;
namespace Mono.CSharp {
static public PredefinedTypeSpec exception_type;
- static public TypeSpec null_type;
static public TypeSpec typed_reference_type;
static public TypeSpec arg_iterator_type;
static public TypeSpec mbr_type;
static public TypeSpec asynccallback_type;
static public TypeSpec runtime_argument_handle_type;
static public TypeSpec void_ptr_type;
+ static public TypeSpec interop_charset;
//
// C# 2.0
public static TypeExpr binder_type;
public static TypeSpec binder_flags;
- //
- // Expressions representing the internal types. Used during declaration
- // definition.
- //
- static public TypeExpr system_object_expr, system_string_expr;
- static public TypeExpr system_boolean_expr, system_decimal_expr;
- static public TypeExpr system_single_expr, system_double_expr;
- static public TypeExpr system_sbyte_expr, system_byte_expr;
- static public TypeExpr system_int16_expr, system_uint16_expr;
- static public TypeExpr system_int32_expr, system_uint32_expr;
- static public TypeExpr system_int64_expr, system_uint64_expr;
- static public TypeExpr system_char_expr, system_void_expr;
- static public TypeExpr system_valuetype_expr;
public static TypeExpr expression_type_expr;
static public MethodSpec delegate_remove_delegate_delegate;
static public PropertySpec int_get_offset_to_string_data;
static public MethodSpec int_interlocked_compare_exchange;
+ public static MethodSpec gen_interlocked_compare_exchange;
static public PropertySpec ienumerator_getcurrent;
public static MethodSpec methodbase_get_type_from_handle;
public static MethodSpec methodbase_get_type_from_handle_generic;
public static MethodSpec fieldinfo_get_field_from_handle;
public static MethodSpec fieldinfo_get_field_from_handle_generic;
- static public MethodSpec activator_create_instance;
+ public static MethodSpec activator_create_instance;
//
// The constructors.
static public MethodSpec void_decimal_ctor_int_arg;
public static MethodSpec void_decimal_ctor_long_arg;
- static Dictionary<Assembly, bool> assembly_internals_vis_attrs;
-
- //
- // These are expressions that represent some of the internal data types, used
- // elsewhere
- //
- public static void InitExpressionTypes ()
- {
- system_object_expr = new TypeLookupExpression (object_type);
- system_string_expr = new TypeLookupExpression (string_type);
- system_boolean_expr = new TypeLookupExpression (bool_type);
- system_decimal_expr = new TypeLookupExpression (decimal_type);
- system_single_expr = new TypeLookupExpression (float_type);
- system_double_expr = new TypeLookupExpression (double_type);
- system_sbyte_expr = new TypeLookupExpression (sbyte_type);
- system_byte_expr = new TypeLookupExpression (byte_type);
- system_int16_expr = new TypeLookupExpression (short_type);
- system_uint16_expr = new TypeLookupExpression (ushort_type);
- system_int32_expr = new TypeLookupExpression (int32_type);
- system_uint32_expr = new TypeLookupExpression (uint32_type);
- system_int64_expr = new TypeLookupExpression (int64_type);
- system_uint64_expr = new TypeLookupExpression (uint64_type);
- system_char_expr = new TypeLookupExpression (char_type);
- system_void_expr = new TypeLookupExpression (void_type);
- system_valuetype_expr = new TypeLookupExpression (value_type);
- }
-
static TypeManager ()
{
Reset ();
{
// object_type = null;
- type_hash = new DoubleHash ();
- assembly_internals_vis_attrs = new Dictionary<Assembly, bool> ();
-
// TODO: I am really bored by all this static stuff
system_type_get_type_from_handle =
bool_movenext_void =
void_monitor_exit_object =
void_initializearray_array_fieldhandle =
int_interlocked_compare_exchange =
+ gen_interlocked_compare_exchange =
methodbase_get_type_from_handle =
methodbase_get_type_from_handle_generic =
fieldinfo_get_field_from_handle =
runtime_helpers_type = iasyncresult_type = asynccallback_type =
runtime_argument_handle_type = void_ptr_type = isvolatile_type =
generic_ilist_type = generic_icollection_type = generic_ienumerator_type =
- generic_ienumerable_type = generic_nullable_type = expression_type =
+ generic_ienumerable_type = generic_nullable_type = expression_type = interop_charset =
parameter_expression_type = fieldinfo_type = methodinfo_type = ctorinfo_type = null;
expression_type_expr = null;
}
- //
- // We use this hash for multiple kinds of constructed types:
- //
- // (T, "&") Given T, get T &
- // (T, "*") Given T, get T *
- // (T, "[]") Given T and a array dimension, get T []
- // (T, X) Given a type T and a simple name X, get the type T+X
- //
- // Accessibility tests, if necessary, should be done by the user
- //
- static DoubleHash type_hash = new DoubleHash ();
-
- //
- // Gets the reference to T version of the Type (T&)
- //
- public static Type GetReferenceType (TypeSpec t)
- {
- return t.GetMetaInfo ().MakeByRefType ();
- }
-
- public static TypeSpec GetConstructedType (TypeSpec t, string dim)
- {
- object ret = null;
- if (type_hash.Lookup (t, dim, out ret))
- return (TypeSpec) ret;
-
- TypeSpec ds;
- if (dim.Length == 1) {
- if (dim[0] == '*') {
- ds = PointerContainer.MakeType (t);
- } else if (dim[0] == '&') {
- ds = ReferenceContainer.MakeType (t);
- } else {
- throw new NotImplementedException ("net");
- }
- } else if (dim.Length == 2) { // optimizes common "[]"
- ds = ArrayContainer.MakeType (t);
- } else {
- int rank = dim.IndexOf (']');
- if (rank + 1 != dim.Length)
- t = GetConstructedType (t, dim.Substring (rank + 1));
-
- ds = ArrayContainer.MakeType (t, rank);
- }
-
- type_hash.Insert (t, dim, ds);
- return ds;
- }
-
/// <summary>
/// Returns the C# name of a type if possible, or the full type name otherwise
/// </summary>
public static TypeSpec CoreLookupType (CompilerContext ctx, string ns_name, string name, int arity, MemberKind kind, bool required)
{
- Namespace ns = GlobalRootNamespace.Instance.GetNamespace (ns_name, true);
- var te = ns.Lookup (ctx, name, arity, Location.Null);
+ Namespace ns = ctx.GlobalRootNamespace.GetNamespace (ns_name, true);
+ var te = ns.LookupType (ctx, name, arity, !required, Location.Null);
var ts = te == null ? null : te.Type;
if (!required)
return ts;
}
- static MemberSpec GetPredefinedMember (TypeSpec t, MemberFilter filter, Location loc)
+ static MemberSpec GetPredefinedMember (TypeSpec t, MemberFilter filter, bool optional, Location loc)
{
- const BindingRestriction restrictions = BindingRestriction.AccessibleOnly | BindingRestriction.DeclaredOnly;
- var member = MemberCache.FindMember (t, filter, restrictions);
+ var member = MemberCache.FindMember (t, filter, BindingRestriction.DeclaredOnly);
+
+ if (member != null && member.IsAccessible (InternalType.FakeInternalType))
+ return member;
- if (member != null)
+ if (optional)
return member;
string method_args = null;
public static MethodSpec GetPredefinedConstructor (TypeSpec t, Location loc, params TypeSpec [] args)
{
var pc = ParametersCompiled.CreateFullyResolved (args);
- return GetPredefinedMember (t, MemberFilter.Constructor (pc), loc) as MethodSpec;
+ return GetPredefinedMember (t, MemberFilter.Constructor (pc), false, loc) as MethodSpec;
}
//
public static MethodSpec GetPredefinedMethod (TypeSpec t, string name, Location loc, params TypeSpec [] args)
{
var pc = ParametersCompiled.CreateFullyResolved (args);
- return GetPredefinedMethod (t, MemberFilter.Method (name, 0, pc, null), loc);
+ return GetPredefinedMethod (t, MemberFilter.Method (name, 0, pc, null), false, loc);
}
public static MethodSpec GetPredefinedMethod (TypeSpec t, MemberFilter filter, Location loc)
{
- return GetPredefinedMember (t, filter, loc) as MethodSpec;
+ return GetPredefinedMethod (t, filter, false, loc);
+ }
+
+ public static MethodSpec GetPredefinedMethod (TypeSpec t, MemberFilter filter, bool optional, Location loc)
+ {
+ return GetPredefinedMember (t, filter, optional, loc) as MethodSpec;
}
public static FieldSpec GetPredefinedField (TypeSpec t, string name, Location loc, TypeSpec type)
{
- return GetPredefinedMember (t, MemberFilter.Field (name, type), loc) as FieldSpec;
+ return GetPredefinedMember (t, MemberFilter.Field (name, type), false, loc) as FieldSpec;
}
public static PropertySpec GetPredefinedProperty (TypeSpec t, string name, Location loc, TypeSpec type)
{
- return GetPredefinedMember (t, MemberFilter.Property (name, type), loc) as PropertySpec;
+ return GetPredefinedMember (t, MemberFilter.Property (name, type), false, loc) as PropertySpec;
}
public static IList<PredefinedTypeSpec> InitCoreTypes ()
/// population of the type has happened (for example, to
/// bootstrap the corlib.dll
/// </remarks>
- public static bool InitCoreTypes (CompilerContext ctx, IList<PredefinedTypeSpec> predefined)
+ public static bool InitCoreTypes (ModuleContainer module, IList<PredefinedTypeSpec> predefined)
{
+ var ctx = module.Compiler;
foreach (var p in predefined) {
var found = CoreLookupType (ctx, p.Namespace, p.Name, p.Kind, true);
if (found == null || found == p)
continue;
if (!RootContext.StdLib) {
- var ns = GlobalRootNamespace.Instance.GetNamespace (p.Namespace, false);
+ var ns = module.GlobalRootNamespace.GetNamespace (p.Namespace, false);
ns.ReplaceTypeWithPredefined (found, p);
var tc = found.MemberDefinition as TypeContainer;
}
}
- PredefinedAttributes.Get.ParamArray.Initialize (ctx, false);
- PredefinedAttributes.Get.Out.Initialize (ctx, false);
+ ctx.PredefinedAttributes.ParamArray.Initialize (ctx, false);
+ ctx.PredefinedAttributes.Out.Initialize (ctx, false);
+
+ if (InternalType.Dynamic.GetMetaInfo () == null) {
+ InternalType.Dynamic.SetMetaInfo (object_type.GetMetaInfo ());
+
+ if (object_type.MemberDefinition.IsImported)
+ InternalType.Dynamic.MemberCache = object_type.MemberCache;
+
+ InternalType.Null.SetMetaInfo (object_type.GetMetaInfo ());
+ }
return ctx.Report.Errors == 0;
}
//
public static void InitOptionalCoreTypes (CompilerContext ctx)
{
- //
- // These are only used for compare purposes
- //
- null_type = InternalType.Null;
-
void_ptr_type = PointerContainer.MakeType (void_type);
//
// Initialize InternalsVisibleTo as the very first optional type. Otherwise we would populate
// types cache with incorrect accessiblity when any of optional types is internal.
//
- PredefinedAttributes.Get.Initialize (ctx);
+ ctx.PredefinedAttributes.Initialize (ctx);
runtime_argument_handle_type = CoreLookupType (ctx, "System", "RuntimeArgumentHandle", MemberKind.Struct, false);
asynccallback_type = CoreLookupType (ctx, "System", "AsyncCallback", MemberKind.Delegate, false);
generic_ienumerable_type = CoreLookupType (ctx, "System.Collections.Generic", "IEnumerable", 1, MemberKind.Interface, false);
generic_nullable_type = CoreLookupType (ctx, "System", "Nullable", 1, MemberKind.Struct, false);
+ isvolatile_type = CoreLookupType (ctx, "System.Runtime.CompilerServices", "IsVolatile", MemberKind.Class, false);
+
//
// Optional types which are used as types and for member lookup
//
{
return t.IsDelegate;
}
-
- //
- // When any element of the type is a dynamic type
- //
- // This method builds a transformation array for dynamic types
- // used in places where DynamicAttribute cannot be applied to.
- // It uses bool flag when type is of dynamic type and each
- // section always starts with "false" for some reason.
- //
- // LAMESPEC: This should be part of C# specification !
- //
- // Example: Func<dynamic, int, dynamic[]>
- // Transformation: { false, true, false, false, true }
- //
- public static bool[] HasDynamicTypeUsed (TypeSpec t)
- {
- var ac = t as ArrayContainer;
- if (ac != null) {
- if (HasDynamicTypeUsed (ac.Element) != null)
- return new bool[] { false, true };
-
- return null;
- }
-
- if (t == null)
- return null;
-
- if (IsGenericType (t)) {
- List<bool> transform = null;
- var targs = GetTypeArguments (t);
- for (int i = 0; i < targs.Length; ++i) {
- var element = HasDynamicTypeUsed (targs [i]);
- if (element != null) {
- if (transform == null) {
- transform = new List<bool> ();
- for (int ii = 0; ii <= i; ++ii)
- transform.Add (false);
- }
-
- transform.AddRange (element);
- } else if (transform != null) {
- transform.Add (false);
- }
- }
-
- if (transform != null)
- return transform.ToArray ();
- }
-
- if (object.ReferenceEquals (InternalType.Dynamic, t))
- return new bool [] { true };
-
- return null;
- }
// Obsolete
public static bool IsEnumType (TypeSpec t)
return t.IsStruct;
}
- public static bool IsSubclassOf (TypeSpec type, TypeSpec base_type)
- {
- do {
- if (type == base_type)
- return true;
-
- type = type.BaseType;
- } while (type != null);
-
- return false;
- }
-
public static bool IsFamilyAccessible (TypeSpec type, TypeSpec parent)
{
// TypeParameter tparam = LookupTypeParameter (type);
type = type.GetDefinition (); // DropGenericTypeArguments (type);
parent = parent.GetDefinition (); // DropGenericTypeArguments (parent);
- if (IsEqual (type, parent))
+ if (type == parent)
return false;
type = type.DeclaringType;
while (type != null) {
- if (IsEqual (type.GetDefinition (), parent))
+ if (type.GetDefinition () == parent)
return true;
type = type.DeclaringType;
return t == arg_iterator_type || t == typed_reference_type;
}
- //
- // Checks whether `invocationAssembly' is same or a friend of the assembly
- //
- public static bool IsThisOrFriendAssembly (Assembly invocationAssembly, Assembly assembly)
- {
- if (assembly == null)
- throw new ArgumentNullException ("assembly");
-
- // TODO: This can happen for constants used at assembly level and
- // predefined members
- // But there is no way to test for it for now, so it could be abused
- // elsewhere too.
- if (invocationAssembly == null)
- invocationAssembly = CodeGen.Assembly.Builder;
-
- if (invocationAssembly == assembly)
- return true;
-
- bool value;
- if (assembly_internals_vis_attrs.TryGetValue (assembly, out value))
- return value;
-
- object[] attrs = assembly.GetCustomAttributes (typeof (InternalsVisibleToAttribute), false);
- if (attrs.Length == 0) {
- assembly_internals_vis_attrs.Add (assembly, false);
- return false;
- }
-
- bool is_friend = false;
-
- AssemblyName this_name = CodeGen.Assembly.Name;
- if (this_name == null)
- return false;
-
- byte [] this_token = this_name.GetPublicKeyToken ();
- foreach (InternalsVisibleToAttribute attr in attrs) {
- if (attr.AssemblyName == null || attr.AssemblyName.Length == 0)
- continue;
-
- AssemblyName aname = null;
- try {
- aname = new AssemblyName (attr.AssemblyName);
- } catch (FileLoadException) {
- } catch (ArgumentException) {
- }
-
- if (aname == null || aname.Name != this_name.Name)
- continue;
-
- byte [] key_token = aname.GetPublicKeyToken ();
- if (key_token != null) {
- if (this_token.Length == 0) {
- // Same name, but assembly is not strongnamed
- Error_FriendAccessNameNotMatching (aname.FullName, RootContext.ToplevelTypes.Compiler.Report);
- break;
- }
-
- if (!CompareKeyTokens (this_token, key_token))
- continue;
- }
-
- is_friend = true;
- break;
- }
-
- assembly_internals_vis_attrs.Add (assembly, is_friend);
- return is_friend;
- }
-
- static bool CompareKeyTokens (byte [] token1, byte [] token2)
- {
- for (int i = 0; i < token1.Length; i++)
- if (token1 [i] != token2 [i])
- return false;
-
- return true;
- }
-
- static void Error_FriendAccessNameNotMatching (string other_name, Report Report)
- {
- Report.Error (281,
- "Friend access was granted to `{0}', but the output assembly is named `{1}'. Try adding a reference to `{0}' or change the output assembly name to match it",
- other_name, CodeGen.Assembly.Name.FullName);
- }
-
public static TypeSpec GetElementType (TypeSpec t)
{
return ((ElementTypeSpec)t).Element;
return false;
}
-
- //
- // Returns whether the array of memberinfos contains the given method
- //
- public static bool ArrayContainsMethod (List<MemberSpec> array, MethodSpec new_method, bool ignoreDeclType)
- {
- AParametersCollection new_args = new_method.Parameters;
-
- foreach (MethodSpec method in array) {
- if (!ignoreDeclType && method.DeclaringType != new_method.DeclaringType)
- continue;
-
- if (method.Name != new_method.Name)
- continue;
-
- if (!TypeSpecComparer.Override.IsEqual (method.ReturnType, new_method.ReturnType))
- continue;
-
- AParametersCollection old_args = method.Parameters;
- int old_count = old_args.Count;
- int i;
-
- if (new_args.Count != old_count)
- continue;
-
- for (i = 0; i < old_count; i++) {
- if (!TypeSpecComparer.Override.IsEqual (old_args.Types[i], new_args.Types[i]))
- break;
- }
- if (i != old_count)
- continue;
-
- return true;
- }
-
- return false;
- }
#region Generics
// This method always return false for non-generic compiler,
// while Type.IsGenericParameter is returned if it is supported.
return type.GetMetaInfo ().ContainsGenericParameters;
}
- public static bool IsEqual (TypeSpec a, TypeSpec b)
- {
- return a == b && !(a is InternalType);
- }
-
public static TypeSpec[] GetTypeArguments (TypeSpec t)
{
// TODO: return empty array !!
return generic_nullable_type == t.GetDefinition ();
}
#endregion
-
- //
- // Looks up a member called `name' in the `queried_type'. This lookup
- // is done by code that is contained in the definition for `invocation_type'
- // through a qualifier of type `qualifier_type' (or null if there is no qualifier).
- //
- // `invocation_type' is used to check whether we're allowed to access the requested
- // member wrt its protection level.
- //
- // When called from MemberAccess, `qualifier_type' is the type which is used to access
- // the requested member (`class B { A a = new A (); a.foo = 5; }'; here invocation_type
- // is B and qualifier_type is A). This is used to do the CS1540 check.
- //
- // When resolving a SimpleName, `qualifier_type' is null.
- //
- // The `qualifier_type' is used for the CS1540 check; it's normally either null or
- // the same than `queried_type' - except when we're being called from BaseAccess;
- // in this case, `invocation_type' is the current type and `queried_type' the base
- // type, so this'd normally trigger a CS1540.
- //
- // The binding flags are `bf' and the kind of members being looked up are `mt'
- //
- // The return value always includes private members which code in `invocation_type'
- // is allowed to access (using the specified `qualifier_type' if given); only use
- // BindingFlags.NonPublic to bypass the permission check.
- //
- // The 'almost_match' argument is used for reporting error CS1540.
- //
- // Returns an array of a single element for everything but Methods/Constructors
- // that might return multiple matches.
- //
- public static IList<MemberSpec> MemberLookup (TypeSpec invocation_type, TypeSpec qualifier_type,
- TypeSpec queried_type, MemberKind mt,
- BindingRestriction opt, string name, int arity, IList<MemberSpec> almost_match)
- {
- Timer.StartTimer (TimerType.MemberLookup);
-
- var retval = RealMemberLookup (invocation_type, qualifier_type,
- queried_type, mt, opt, name, arity, almost_match);
-
- Timer.StopTimer (TimerType.MemberLookup);
-
- return retval;
- }
-
- static IList<MemberSpec> RealMemberLookup (TypeSpec invocation_type, TypeSpec qualifier_type,
- TypeSpec queried_type, MemberKind mt,
- BindingRestriction bf, string name, int arity, IList<MemberSpec> almost_match)
- {
- MemberFilter filter = new MemberFilter (name, arity, mt, null, null);
- if ((bf & BindingRestriction.AccessibleOnly) != 0) {
- filter.InvocationType = invocation_type ?? InternalType.FakeInternalType;
- }
-
- return MemberCache.FindMembers (queried_type, filter, bf);
- }
}
}