// rootcontext.cs: keeps track of our tree representation, and assemblies loaded.
//
// Author: Miguel de Icaza (miguel@ximian.com)
-// Ravi Pratap (ravi@ximian.com)
+// Ravi Pratap (ravi@ximian.com)
+// Marek Safar (marek.safar@gmail.com)
+//
//
// Licensed under the terms of the GNU GPL
//
public enum LanguageVersion
{
- Default = 0,
- ISO_1 = 1
+ ISO_1 = 1,
+ Default_MCS = 2,
+ ISO_2 = 3,
+ LINQ = 4,
+
+#if GMCS_SOURCE
+ Default = LINQ
+#else
+ Default = Default_MCS
+#endif
}
public class RootContext {
//
// Contains the parsed tree
//
- static Tree tree;
+ static RootTypes root;
//
// This hashtable contains all of the #definitions across the source code
// This is only used to tell whether `System.Object' should
// have a base class or not.
//
- public static bool StdLib = true;
+ public static bool StdLib;
//
// This keeps track of the order in which classes were defined
// override).
//
static ArrayList type_container_resolve_order;
- static ArrayList attribute_types;
//
// Holds a reference to the Private Implementation Details
static TypeBuilder impl_details_class;
- public static int WarningLevel = 3;
-
- public static Target Target = Target.Exe;
- public static string TargetExt = ".exe";
+ public static Target Target;
+ public static string TargetExt;
public static bool VerifyClsCompliance = true;
- public static LanguageVersion Version = LanguageVersion.Default;
+ /// <summary>
+ /// Holds /optimize option
+ /// </summary>
+ public static bool Optimize = true;
+
+ public static LanguageVersion Version;
//
// We keep strongname related info here because
//
public static string StrongNameKeyFile;
public static string StrongNameKeyContainer;
- public static bool StrongNameDelaySign = false;
+ public static bool StrongNameDelaySign;
//
// If set, enable XML documentation generation
//
public static Documentation Documentation;
+ static public string MainClass;
+
//
// Constructor
//
static RootContext ()
{
- tree = new Tree ();
+ Reset ();
+ }
+
+ public static void Reset ()
+ {
+ root = new RootTypes ();
type_container_resolve_order = new ArrayList ();
+ EntryPoint = null;
+ Report.WarningLevel = 3;
+ Checked = false;
+ Unsafe = false;
+ StdLib = true;
+ StrongNameKeyFile = null;
+ StrongNameKeyContainer = null;
+ StrongNameDelaySign = false;
+ MainClass = null;
+ Target = Target.Exe;
+ TargetExt = ".exe";
+ Version = LanguageVersion.Default;
+ Documentation = null;
+ impl_details_class = null;
+ helper_classes = null;
}
-
+
public static bool NeedsEntryPoint {
- get {
- return RootContext.Target == Target.Exe || RootContext.Target == Target.WinExe;
- }
+ get { return RootContext.Target == Target.Exe || RootContext.Target == Target.WinExe; }
}
- static public Tree Tree {
- get {
- return tree;
- }
+ static public RootTypes ToplevelTypes {
+ get { return root; }
}
- static public string MainClass;
-
public static void RegisterOrder (TypeContainer tc)
{
type_container_resolve_order.Add (tc);
}
-
- public static void RegisterAttribute (TypeContainer tc)
- {
- if (attribute_types == null)
- attribute_types = new ArrayList ();
-
- attribute_types.Add (tc);
- }
//
// The default compiler checked state
//
- static public bool Checked = false;
+ static public bool Checked;
//
// Whether to allow Unsafe code
//
- static public bool Unsafe = false;
+ static public bool Unsafe;
- static string MakeFQN (string nsn, string name)
- {
- if (nsn == "")
- return name;
- return String.Concat (nsn, ".", name);
- }
-
// <remarks>
// This function is used to resolve the hierarchy tree.
// It processes interfaces, structs and classes in that order.
// </remarks>
static public void ResolveTree ()
{
- //
- // Process the attribute types separately and before anything else
- //
- if (attribute_types != null)
- foreach (TypeContainer tc in attribute_types)
- tc.DefineType ();
-
//
// Interfaces are processed next, as classes and
// structs might inherit from an object or implement
// a set of interfaces, we need to be able to tell
// them appart by just using the TypeManager.
//
- TypeContainer root = Tree.Types;
-
- ArrayList ifaces = root.Interfaces;
- if (ifaces != null){
- foreach (Interface i in ifaces)
- i.DefineType ();
- }
+ foreach (TypeContainer tc in root.Types)
+ tc.CreateType ();
foreach (TypeContainer tc in root.Types)
tc.DefineType ();
if (root.Delegates != null)
foreach (Delegate d in root.Delegates)
d.DefineType ();
-
- if (root.Enums != null)
- foreach (Enum e in root.Enums)
- e.DefineType ();
}
- static void Error_TypeConflict (string name, Location loc)
- {
- Report.Error (
- 520, loc, "`" + name + "' conflicts with a predefined type");
- }
+ delegate bool VerifyBootstrapType (Type t);
- static void Error_TypeConflict (string name)
+ static Type BootstrapCorlib_ResolveType (TypeContainer root, string name, VerifyBootstrapType typeVerifier)
{
- Report.Error (
- 520, "`" + name + "' conflicts with a predefined type");
- }
-
- //
- // Resolves a single class during the corlib bootstrap process
- //
- static TypeBuilder BootstrapCorlib_ResolveClass (TypeContainer root, string name)
- {
- object o = root.GetDefinition (name);
- if (o == null){
- Report.Error (518, "The predefined type `" + name + "' is not defined");
+ TypeLookupExpression tle = new TypeLookupExpression (name);
+ Report.DisableReporting ();
+ TypeExpr te = tle.ResolveAsTypeTerminal (root, false);
+ Report.EnableReporting ();
+ if (te == null) {
+ Report.Error (518, "The predefined type `{0}' is not defined or imported", name);
return null;
}
- if (!(o is Class)){
- if (o is DeclSpace){
- DeclSpace d = (DeclSpace) o;
-
- Error_TypeConflict (name, d.Location);
- } else
- Error_TypeConflict (name);
+ Type t = te.Type;
+ if (!typeVerifier (t)) {
+ MemberCore mc = root.GetDefinition (name);
+ Location loc = Location.Null;
+ if (mc != null) {
+ name = mc.GetSignatureForError ();
+ loc = mc.Location;
+ }
+ Report.Error (520, loc, "The predefined type `{0}' is not declared correctly", name);
return null;
}
- return ((DeclSpace) o).DefineType ();
+ AttributeTester.RegisterNonObsoleteType (t);
+ return t;
}
-
//
- // Resolves a struct during the corlib bootstrap process
+ // Resolves a single class during the corlib bootstrap process
//
- static void BootstrapCorlib_ResolveStruct (TypeContainer root, string name)
+ static Type BootstrapCorlib_ResolveClass (TypeContainer root, string name)
{
- object o = root.GetDefinition (name);
- if (o == null){
- Report.Error (518, "The predefined type `" + name + "' is not defined");
- return;
- }
-
- if (!(o is Struct)){
- if (o is DeclSpace){
- DeclSpace d = (DeclSpace) o;
-
- Error_TypeConflict (name, d.Location);
- } else
- Error_TypeConflict (name);
-
- return;
- }
+ return BootstrapCorlib_ResolveType (root, name, IsClass);
+ }
- ((DeclSpace) o).DefineType ();
+ static bool IsClass (Type t)
+ {
+ DeclSpace ds = TypeManager.LookupDeclSpace (t);
+ if (ds != null)
+ return ds is Class;
+ return t.IsClass;
}
//
// Resolves a struct during the corlib bootstrap process
//
- static void BootstrapCorlib_ResolveInterface (TypeContainer root, string name)
+ static Type BootstrapCorlib_ResolveStruct (TypeContainer root, string name)
{
- object o = root.GetDefinition (name);
- if (o == null){
- Report.Error (518, "The predefined type `" + name + "' is not defined");
- return;
- }
-
- if (!(o is Interface)){
- if (o is DeclSpace){
- DeclSpace d = (DeclSpace) o;
+ return BootstrapCorlib_ResolveType (root, name, IsStruct);
+ }
- Error_TypeConflict (name, d.Location);
- } else
- Error_TypeConflict (name);
+ static bool IsStruct (Type t)
+ {
+ DeclSpace ds = TypeManager.LookupDeclSpace (t);
+ if (ds != null)
+ return ds is Struct;
+
+ return TypeManager.IsSubclassOf (t, TypeManager.value_type);
+ }
- return;
- }
+ //
+ // Resolves an interface during the corlib bootstrap process
+ //
+ static void BootstrapCorlib_ResolveInterface (TypeContainer root, string name)
+ {
+ BootstrapCorlib_ResolveType (root, name, IsInterface);
+ }
- ((DeclSpace) o).DefineType ();
+ static bool IsInterface (Type t)
+ {
+ return t.IsInterface;
}
//
//
static void BootstrapCorlib_ResolveDelegate (TypeContainer root, string name)
{
- object o = root.GetDefinition (name);
- if (o == null){
- Report.Error (518, "The predefined type `" + name + "' is not defined");
- Environment.Exit (1);
- }
-
- if (!(o is Delegate)){
- Error_TypeConflict (name);
- return;
- }
+ BootstrapCorlib_ResolveType (root, name, IsDelegate);
+ }
- ((DeclSpace) o).DefineType ();
+ static bool IsDelegate (Type t)
+ {
+ return TypeManager.IsDelegateType (t);
}
-
/// <summary>
/// Resolves the core types in the compiler when compiling with --nostdlib
/// </summary>
static public void ResolveCore ()
{
- TypeContainer root = Tree.Types;
-
TypeManager.object_type = BootstrapCorlib_ResolveClass (root, "System.Object");
+ TypeManager.system_object_expr.Type = TypeManager.object_type;
TypeManager.value_type = BootstrapCorlib_ResolveClass (root, "System.ValueType");
+ TypeManager.system_valuetype_expr.Type = TypeManager.value_type;
+
+ //
+ // The core attributes
+ //
+ BootstrapCorlib_ResolveInterface (root, "System.Runtime.InteropServices._Attribute");
TypeManager.attribute_type = BootstrapCorlib_ResolveClass (root, "System.Attribute");
+ TypeManager.obsolete_attribute_type = BootstrapCorlib_ResolveClass (root, "System.ObsoleteAttribute");
+ if (TypeManager.obsolete_attribute_type != null) {
+ Class c = TypeManager.LookupClass (TypeManager.obsolete_attribute_type);
+ c.DefineMembers ();
+ }
+
+ TypeManager.indexer_name_type = BootstrapCorlib_ResolveClass (root, "System.Runtime.CompilerServices.IndexerNameAttribute");
string [] interfaces_first_stage = {
"System.IComparable", "System.ICloneable",
"System.Runtime.Serialization.ISerializable",
"System.Reflection.IReflect",
- "System.Reflection.ICustomAttributeProvider"
+ "System.Reflection.ICustomAttributeProvider",
+#if GMCS_SOURCE
+ "System.Runtime.InteropServices._Exception",
+
+ //
+ // Generic types
+ //
+ "System.Collections.Generic.IEnumerator`1",
+ "System.Collections.Generic.IEnumerable`1"
+#endif
};
foreach (string iname in interfaces_first_stage)
"System.Int32", "System.UInt32",
"System.Int64", "System.UInt64",
};
-
+
foreach (string cname in structs_first_stage)
BootstrapCorlib_ResolveStruct (root, cname);
string [] structs_second_stage = {
"System.Single", "System.Double",
- "System.Char", "System.Boolean",
+ "System.Char",
"System.Decimal", "System.Void",
"System.RuntimeFieldHandle",
"System.RuntimeArgumentHandle",
"System.ArgIterator"
};
+ TypeManager.bool_type = BootstrapCorlib_ResolveStruct (root, "System.Boolean");
+
foreach (string cname in structs_second_stage)
BootstrapCorlib_ResolveStruct (root, cname);
"System.Reflection.MemberInfo",
"System.Type",
"System.Exception",
+#if GMCS_SOURCE
+ "System.Activator",
+#endif
//
// These are not really important in the order, but they
"System.Runtime.CompilerServices.RuntimeHelpers",
"System.Reflection.DefaultMemberAttribute",
"System.Threading.Monitor",
+ "System.Threading.Interlocked",
"System.AttributeUsageAttribute",
"System.Runtime.InteropServices.DllImportAttribute",
"System.Runtime.CompilerServices.MethodImplAttribute",
"System.Runtime.InteropServices.MarshalAsAttribute",
+#if GMCS_SOURCE
+ "System.Runtime.CompilerServices.CompilerGeneratedAttribute",
+ "System.Runtime.CompilerServices.FixedBufferAttribute",
+#endif
"System.Diagnostics.ConditionalAttribute",
- "System.ObsoleteAttribute",
"System.ParamArrayAttribute",
"System.CLSCompliantAttribute",
"System.Security.UnverifiableCodeAttribute",
"System.Security.Permissions.SecurityAttribute",
- "System.Runtime.CompilerServices.IndexerNameAttribute",
"System.Runtime.CompilerServices.DecimalConstantAttribute",
"System.Runtime.InteropServices.InAttribute",
"System.Runtime.InteropServices.OutAttribute",
"System.Runtime.InteropServices.StructLayoutAttribute",
"System.Runtime.InteropServices.FieldOffsetAttribute",
+#if GMCS_SOURCE
+ "System.Runtime.InteropServices.DefaultCharSetAttribute",
+#endif
"System.InvalidOperationException",
"System.NotSupportedException",
"System.MarshalByRefObject",
- "System.Security.CodeAccessPermission"
+ "System.Security.CodeAccessPermission",
+ "System.Runtime.CompilerServices.RequiredAttributeAttribute",
+ "System.Runtime.InteropServices.GuidAttribute",
+ "System.Reflection.AssemblyCultureAttribute"
};
foreach (string cname in classes_second_stage)
BootstrapCorlib_ResolveClass (root, cname);
+#if GMCS_SOURCE
+ BootstrapCorlib_ResolveStruct (root, "System.Nullable`1");
+#endif
+ TypeManager.delegate_type = BootstrapCorlib_ResolveClass (root, "System.Delegate");
+ BootstrapCorlib_ResolveClass (root, "System.MulticastDelegate");
BootstrapCorlib_ResolveDelegate (root, "System.AsyncCallback");
-
- // These will be defined indirectly during the previous ResolveDelegate.
- // However make sure the rest of the checks happen.
- string [] delegate_types = { "System.Delegate", "System.MulticastDelegate" };
- foreach (string cname in delegate_types)
- BootstrapCorlib_ResolveClass (root, cname);
}
// <summary>
// </remarks>
static public void CloseTypes ()
{
- TypeContainer root = Tree.Types;
-
- if (root.Enums != null)
- foreach (Enum en in root.Enums)
- en.CloseType ();
-
- if (attribute_types != null)
- foreach (TypeContainer tc in attribute_types)
- tc.CloseType ();
-
//
// We do this in two passes, first we close the structs,
// then the classes, because it seems the code needs it this
// make sure that we define the structs in order as well.
//
foreach (TypeContainer tc in type_container_resolve_order){
- if (tc.Kind == Kind.Struct && tc.Parent == tree.Types){
+ if (tc.Kind == Kind.Struct && tc.Parent == root){
tc.CloseType ();
}
}
foreach (TypeContainer tc in type_container_resolve_order){
- if (!(tc.Kind == Kind.Struct && tc.Parent == tree.Types))
+ if (!(tc.Kind == Kind.Struct && tc.Parent == root))
tc.CloseType ();
}
// If we have a <PrivateImplementationDetails> class, close it
//
if (helper_classes != null){
- foreach (TypeBuilder type_builder in helper_classes)
+ foreach (TypeBuilder type_builder in helper_classes) {
+#if GMCS_SOURCE
+ type_builder.SetCustomAttribute (TypeManager.compiler_generated_attr);
+#endif
type_builder.CreateType ();
+ }
}
- attribute_types = null;
type_container_resolve_order = null;
helper_classes = null;
- //tree = null;
+ //root = null;
TypeManager.CleanUp ();
}
/// Used to register classes that need to be closed after all the
/// user defined classes
/// </summary>
- public static void RegisterHelperClass (TypeBuilder helper_class)
+ public static void RegisterCompilerGeneratedType (TypeBuilder helper_class)
{
if (helper_classes == null)
helper_classes = new ArrayList ();
+
helper_classes.Add (helper_class);
}
- static void Report1530 (Location loc)
- {
- Report.Error (1530, loc, "Keyword new not allowed for namespace elements");
- }
-
static public void PopulateCoreType (TypeContainer root, string name)
{
DeclSpace ds = (DeclSpace) root.GetDefinition (name);
+ // Core type was imported
+ if (ds == null)
+ return;
- ds.DefineMembers (root);
+ ds.DefineMembers ();
ds.Define ();
}
static public void BootCorlib_PopulateCoreTypes ()
{
- TypeContainer root = tree.Types;
-
PopulateCoreType (root, "System.Object");
PopulateCoreType (root, "System.ValueType");
PopulateCoreType (root, "System.Attribute");
+ PopulateCoreType (root, "System.Runtime.CompilerServices.IndexerNameAttribute");
}
// <summary>
// have been defined through `ResolveTree'
static public void PopulateTypes ()
{
- TypeContainer root = Tree.Types;
- if (attribute_types != null)
- foreach (TypeContainer tc in attribute_types)
- tc.DefineMembers (root);
-
if (type_container_resolve_order != null){
- if (RootContext.StdLib){
- foreach (TypeContainer tc in type_container_resolve_order)
- tc.DefineMembers (root);
- } else {
- foreach (TypeContainer tc in type_container_resolve_order) {
- // When compiling corlib, these types have already been
- // populated from BootCorlib_PopulateCoreTypes ().
- if (((tc.Name == "System.Object") ||
- (tc.Name == "System.Attribute") ||
- (tc.Name == "System.ValueType")))
- continue;
-
- tc.DefineMembers (root);
- }
- }
+ foreach (TypeContainer tc in type_container_resolve_order)
+ tc.ResolveType ();
+ foreach (TypeContainer tc in type_container_resolve_order)
+ tc.DefineMembers ();
}
ArrayList delegates = root.Delegates;
if (delegates != null){
foreach (Delegate d in delegates)
- if ((d.ModFlags & Modifiers.NEW) == 0)
- d.DefineMembers (root);
- else
- Report1530 (d.Location);
- }
-
- ArrayList enums = root.Enums;
- if (enums != null){
- foreach (Enum en in enums)
- if ((en.ModFlags & Modifiers.NEW) == 0)
- en.DefineMembers (root);
- else
- Report1530 (en.Location);
+ d.DefineMembers ();
}
//
//
static public void DefineTypes ()
{
- TypeContainer root = Tree.Types;
+ ArrayList delegates = root.Delegates;
+ if (delegates != null){
+ foreach (Delegate d in delegates)
+ d.Define ();
+ }
- if (attribute_types != null)
- foreach (TypeContainer tc in attribute_types)
- tc.Define ();
-
if (type_container_resolve_order != null){
foreach (TypeContainer tc in type_container_resolve_order) {
// When compiling corlib, these types have already been
if (!RootContext.StdLib &&
((tc.Name == "System.Object") ||
(tc.Name == "System.Attribute") ||
- (tc.Name == "System.ValueType")))
+ (tc.Name == "System.ValueType") ||
+ (tc.Name == "System.Runtime.CompilerServices.IndexerNameAttribute")))
continue;
- if ((tc.ModFlags & Modifiers.NEW) == 0)
- tc.Define ();
+ tc.Define ();
}
}
-
- ArrayList delegates = root.Delegates;
- if (delegates != null){
- foreach (Delegate d in delegates)
- if ((d.ModFlags & Modifiers.NEW) == 0)
- d.Define ();
- }
-
- ArrayList enums = root.Enums;
- if (enums != null){
- foreach (Enum en in enums)
- if ((en.ModFlags & Modifiers.NEW) == 0)
- en.Define ();
- }
}
static public void EmitCode ()
{
- if (attribute_types != null)
- foreach (TypeContainer tc in attribute_types)
+ if (type_container_resolve_order != null) {
+ foreach (TypeContainer tc in type_container_resolve_order)
tc.EmitType ();
- CodeGen.Assembly.Emit (Tree.Types);
- CodeGen.Module.Emit (Tree.Types);
-
- if (Tree.Types.Enums != null) {
- foreach (Enum e in Tree.Types.Enums)
- e.Emit ();
- }
+ if (Report.Errors > 0)
+ return;
- if (type_container_resolve_order != null) {
foreach (TypeContainer tc in type_container_resolve_order)
- tc.EmitType ();
+ tc.VerifyMembers ();
}
- if (Tree.Types.Delegates != null) {
- foreach (Delegate d in Tree.Types.Delegates)
+ if (root.Delegates != null) {
+ foreach (Delegate d in root.Delegates)
d.Emit ();
}
//
if (EmitCodeHook != null)
EmitCodeHook ();
+
+ CodeGen.Assembly.Emit (root);
+ CodeGen.Module.Emit (root);
}
//
TypeAttributes.NotPublic,
TypeManager.object_type);
- RegisterHelperClass (impl_details_class);
+ RegisterCompilerGeneratedType (impl_details_class);
}
fb = impl_details_class.DefineInitializedData (
return fb;
}
+
+ public static void CheckUnsafeOption (Location loc)
+ {
+ if (!Unsafe) {
+ Report.Error (227, loc,
+ "Unsafe code requires the `unsafe' command line option to be specified");
+ }
+ }
}
}