X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Frootcontext.cs;h=e6c2c4b2f1dc5ea543ad89cab34d2add27f13dc4;hb=cd5d5a8abe403c911b2a348122d9bc2f75b350c4;hp=6c84b9f1e12f4f6c3b04732b6ec73dc41fc72a53;hpb=38ade841602a2e5bd0326e92361914bc116837ae;p=mono.git diff --git a/mcs/mcs/rootcontext.cs b/mcs/mcs/rootcontext.cs old mode 100755 new mode 100644 index 6c84b9f1e12..e6c2c4b2f1d --- a/mcs/mcs/rootcontext.cs +++ b/mcs/mcs/rootcontext.cs @@ -2,11 +2,14 @@ // 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 // -// (C) 2001 Ximian, Inc (http://www.ximian.com) +// Dual licensed under the terms of the MIT X11 or GNU GPL +// +// Copyright 2001 Ximian, Inc (http://www.ximian.com) +// Copyright 2004-2008 Novell, Inc using System; using System.Collections; @@ -16,105 +19,180 @@ using System.Diagnostics; namespace Mono.CSharp { + public enum LanguageVersion + { + ISO_1 = 1, + Default_MCS = 2, + ISO_2 = 3, + LINQ = 4, + Future = 5, + +#if GMCS_SOURCE + Default = LINQ +#else + Default = Default_MCS +#endif + } + public class RootContext { // - // Contains the parsed tree + // COMPILER OPTIONS CLASS // - static Tree tree; + public static Target Target; + public static string TargetExt; + public static bool VerifyClsCompliance = true; + public static bool Optimize = true; + public static LanguageVersion Version; // - // This hashtable contains all of the #definitions across the source code - // it is used by the ConditionalAttribute handler. + // We keep strongname related info here because + // it's also used as complier options from CSC 8.x // - public static Hashtable AllDefines = new Hashtable (); - + public static string StrongNameKeyFile; + public static string StrongNameKeyContainer; + public static bool StrongNameDelaySign; + + // + // If set, enable XML documentation generation + // + public static Documentation Documentation; + + static public string MainClass; + + // + // The default compiler checked state + // + static public bool Checked; + // - // The list of global attributes (those that target the assembly) + // If true, it means that the compiler is executing as + // in eval mode so unresolved variables are resolved in + // static classes maintained by the eval engine. // - static Hashtable global_attributes = new Hashtable (); + static public bool EvalMode; + + // + // If true, the compiler is operating in statement mode, + // this currently turns local variable declaration into + // static variables of a class + // + static public bool StatementMode; + // + // Whether to allow Unsafe code + // + static public bool Unsafe; + // // Whether we are being linked against the standard libraries. // This is only used to tell whether `System.Object' should - // have a parent or not. + // have a base class or not. + // + public static bool StdLib; + + public static bool NeedsEntryPoint { + get { return Target == Target.Exe || Target == Target.WinExe; } + } + + // + // COMPILER OPTIONS CLASS END + // + + // + // Contains the parsed tree // - public static bool StdLib = true; + static ModuleContainer root; + // + // This hashtable contains all of the #definitions across the source code + // it is used by the ConditionalAttribute handler. + // + static ArrayList AllDefines; + // // This keeps track of the order in which classes were defined // so that we can poulate them in that order. // - // Order is important, because we need to be able to tell by - // examining the parent's list of methods which ones are virtual + // Order is important, because we need to be able to tell, by + // examining the list of methods of the base class, which ones are virtual // or abstract as well as the parent names (to implement new, // override). // static ArrayList type_container_resolve_order; - static ArrayList interface_resolve_order; - static ArrayList attribute_types; // // Holds a reference to the Private Implementation Details // class. // + static ArrayList helper_classes; + static TypeBuilder impl_details_class; - public static int WarningLevel = 2; - // // Constructor // static RootContext () { - tree = new Tree (); - interface_resolve_order = new ArrayList (); - type_container_resolve_order = new ArrayList (); + Reset (true); } - static public Tree Tree { - get { - return tree; - } - } - - static public string MainClass; - - public static void RegisterOrder (Interface iface) + public static void PartialReset () { - interface_resolve_order.Add (iface); + Reset (false); } - public static void RegisterOrder (TypeContainer tc) + public static void Reset (bool full) { - type_container_resolve_order.Add (tc); + if (full) + root = null; + + type_container_resolve_order = new ArrayList (); + EntryPoint = null; + Report.WarningLevel = 4; + 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; + + // + // Setup default defines + // + AllDefines = new ArrayList (); + AddConditional ("__MonoCS__"); } - public static void RegisterAttribute (TypeContainer tc) + public static void AddConditional (string p) { - if (attribute_types == null) - attribute_types = new ArrayList (); - - attribute_types.Add (tc); + if (AllDefines.Contains (p)) + return; + AllDefines.Add (p); } - - // - // The default compiler checked state - // - static public bool Checked = false; - // - // Whether to allow Unsafe code - // - static public bool Unsafe = false; - - static string MakeFQN (string nsn, string name) + public static bool IsConditionalDefined (string value) { - string prefix = (nsn == "" ? "" : nsn + "."); + return AllDefines.Contains (value); + } + + static public ModuleContainer ToplevelTypes { + get { return root; } + set { root = value; } + } - return prefix + name; + public static void RegisterOrder (TypeContainer tc) + { + type_container_resolve_order.Add (tc); } - + // // This function is used to resolve the hierarchy tree. // It processes interfaces, structs and classes in that order. @@ -124,250 +202,25 @@ namespace Mono.CSharp { // 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 (); - + root.Resolve (); + // // 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; + foreach (TypeContainer tc in root.Types) + tc.CreateType (); - ArrayList ifaces = root.Interfaces; - if (ifaces != null){ - foreach (Interface i in ifaces) - i.DefineType (); - } - - - foreach (TypeContainer tc in root.Types) + 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"); - } - - static void Error_TypeConflict (string name) - { - 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"); - return null; - } - - if (!(o is Class)){ - if (o is DeclSpace){ - DeclSpace d = (DeclSpace) o; - - Error_TypeConflict (name, d.Location); - } else - Error_TypeConflict (name); - - return null; - } - - return ((DeclSpace) o).DefineType (); - } - - // - // Resolves a struct during the corlib bootstrap process - // - static void 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 Struct)){ - if (o is DeclSpace){ - DeclSpace d = (DeclSpace) o; - - Error_TypeConflict (name, d.Location); - } else - Error_TypeConflict (name); - - return; - } - - ((DeclSpace) o).DefineType (); } - // - // Resolves a struct during the corlib bootstrap process - // - static void BootstrapCorlib_ResolveInterface (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; - - Error_TypeConflict (name, d.Location); - } else - Error_TypeConflict (name); - - return; - } - - ((DeclSpace) o).DefineType (); - } - - // - // Resolves a delegate during the corlib bootstrap process - // - 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 (0); - } - - if (!(o is Delegate)){ - Error_TypeConflict (name); - return; - } - - ((DeclSpace) o).DefineType (); - } - - - /// - /// Resolves the core types in the compiler when compiling with --nostdlib - /// - static public void ResolveCore () - { - TypeContainer root = Tree.Types; - - TypeManager.object_type = BootstrapCorlib_ResolveClass (root, "System.Object"); - TypeManager.value_type = BootstrapCorlib_ResolveClass (root, "System.ValueType"); - TypeManager.attribute_type = BootstrapCorlib_ResolveClass (root, "System.Attribute"); - - string [] interfaces_first_stage = { - "System.IComparable", "System.ICloneable", - "System.IConvertible", - - "System.Collections.IEnumerable", - "System.Collections.ICollection", - "System.Collections.IEnumerator", - "System.Collections.IList", - "System.IAsyncResult", - "System.IDisposable", - - "System.Runtime.Serialization.ISerializable", - - "System.Reflection.IReflect", - "System.Reflection.ICustomAttributeProvider" - }; - - foreach (string iname in interfaces_first_stage) - BootstrapCorlib_ResolveInterface (root, iname); - - // - // These are the base value types - // - string [] structs_first_stage = { - "System.Byte", "System.SByte", - "System.Int16", "System.UInt16", - "System.Int32", "System.UInt32", - "System.Int64", "System.UInt64", - }; - - foreach (string cname in structs_first_stage) - BootstrapCorlib_ResolveStruct (root, cname); - - // - // Now, we can load the enumerations, after this point, - // we can use enums. - // - TypeManager.InitEnumUnderlyingTypes (); - - string [] structs_second_stage = { - "System.Single", "System.Double", - "System.Char", "System.Boolean", - "System.Decimal", "System.Void", - "System.RuntimeFieldHandle", - "System.RuntimeTypeHandle", - "System.IntPtr" - }; - - foreach (string cname in structs_second_stage) - BootstrapCorlib_ResolveStruct (root, cname); - - // - // These are classes that depends on the core interfaces - // - string [] classes_second_stage = { - "System.Reflection.MemberInfo", - "System.Type", - "System.Exception", - - // - // These are not really important in the order, but they - // are used by the compiler later on (typemanager/CoreLookupType-d) - // - "System.Runtime.CompilerServices.RuntimeHelpers", - "System.Reflection.DefaultMemberAttribute", - "System.Threading.Monitor", - - "System.AttributeUsageAttribute", - "System.Runtime.InteropServices.DllImportAttribute", - "System.Runtime.CompilerServices.MethodImplAttribute", - "System.Runtime.InteropServices.MarshalAsAttribute", - "System.Diagnostics.ConditionalAttribute", - "System.ObsoleteAttribute", - "System.ParamArrayAttribute", - "System.Security.UnverifiableCodeAttribute", - "System.Runtime.CompilerServices.IndexerNameAttribute", - }; - - // We must store them here before calling BootstrapCorlib_ResolveDelegate. - TypeManager.string_type = BootstrapCorlib_ResolveClass (root, "System.String"); - TypeManager.enum_type = BootstrapCorlib_ResolveClass (root, "System.Enum"); - TypeManager.array_type = BootstrapCorlib_ResolveClass (root, "System.Array"); - TypeManager.multicast_delegate_type = BootstrapCorlib_ResolveClass (root, "System.MulticastDelegate"); - TypeManager.delegate_type = BootstrapCorlib_ResolveClass (root, "System.Delegate"); - - foreach (string cname in classes_second_stage) - BootstrapCorlib_ResolveClass (root, cname); - - BootstrapCorlib_ResolveDelegate (root, "System.AsyncCallback"); - } - // // Closes all open types // @@ -380,21 +233,6 @@ namespace Mono.CSharp { // static public void CloseTypes () { - TypeContainer root = Tree.Types; - - ArrayList ifaces = root.Interfaces; - - if (root.Enums != null) - foreach (Enum en in root.Enums) - en.CloseType (); - - if (attribute_types != null) - foreach (TypeContainer tc in attribute_types) - tc.CloseType (); - - foreach (Interface iface in interface_resolve_order) - iface.CloseType (); - // // We do this in two passes, first we close the structs, // then the classes, because it seems the code needs it this @@ -402,13 +240,13 @@ namespace Mono.CSharp { // make sure that we define the structs in order as well. // foreach (TypeContainer tc in type_container_resolve_order){ - if (tc is 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 is Struct && tc.Parent == tree.Types)) + if (!(tc.Kind == Kind.Struct && tc.Parent == root)) tc.CloseType (); } @@ -420,209 +258,47 @@ namespace Mono.CSharp { // // If we have a class, close it // - if (impl_details_class != null){ - impl_details_class.CreateType (); - } - } - - // - // This idea is from Felix Arrese-Igor - // - // Returns : the implicit parent of a composite namespace string - // eg. Implicit parent of A.B is A - // - static public string ImplicitParent (string ns) - { - int i = ns.LastIndexOf ("."); - if (i < 0) - return null; - - return ns.Substring (0, i); - } - - static Type NamespaceLookup (Namespace curr_ns, string name, Location loc) - { - Type t; - - // - // Try in the current namespace and all its implicit parents - // - for (string ns = curr_ns.Name; ns != null; ns = ImplicitParent (ns)) { - t = TypeManager.LookupType (MakeFQN (ns, name)); - if (t != null) - return t; - } - - // - // It's possible that name already is fully qualified. So we do - // a simple direct lookup without adding any namespace names - // - t = TypeManager.LookupType (name); - if (t != null) - return t; - - // - // Try the aliases in the current namespace - // - string alias = curr_ns.LookupAlias (name); - - if (alias != null) { - t = TypeManager.LookupType (alias); - if (t != null) - return t; - - t = TypeManager.LookupType (MakeFQN (alias, name)); - if (t != null) - return t; - } - - for (Namespace ns = curr_ns; ns != null; ns = ns.Parent) { - // - // Look in the namespace ns - // - t = TypeManager.LookupType (MakeFQN (ns.Name, name)); - if (t != null) - return t; - - // - // Then try with the using clauses - // - ArrayList using_list = ns.UsingTable; - - if (using_list == null) - continue; - - Type match = null; - foreach (Namespace.UsingEntry ue in using_list) { - match = TypeManager.LookupType (MakeFQN (ue.Name, name)); - if (match != null){ - if (t != null){ - DeclSpace.Error_AmbiguousTypeReference (loc, name, t, match); - return null; - } - - t = match; - ue.Used = true; - } - } - if (t != null) - return t; - - // - // Try with aliases - // - string a = ns.LookupAlias (name); - if (a != null) { - t = TypeManager.LookupType (a); - if (t != null) - return t; - - t = TypeManager.LookupType (MakeFQN (a, name)); - if (t != null) - return t; - } - } - - return null; - } - - // - // Public function used to locate types, this can only - // be used after the ResolveTree function has been invoked. - // - // Returns: Type or null if they type can not be found. - // - // Come to think of it, this should be a DeclSpace - // - static public Type LookupType (DeclSpace ds, string name, bool silent, Location loc) - { - Type t; - - if (ds.Cache.Contains (name)){ - t = (Type) ds.Cache [name]; - if (t != null) - return t; - } else { - // - // For the case the type we are looking for is nested within this one - // or is in any base class - // - DeclSpace containing_ds = ds; - while (containing_ds != null){ - Type current_type = containing_ds.TypeBuilder; - - while (current_type != null) { - // - // nested class - // - t = TypeManager.LookupType (current_type.FullName + "." + name); - if (t != null){ - ds.Cache [name] = t; - return t; - } - - current_type = current_type.BaseType; - } - - containing_ds = containing_ds.Parent; - } - - t = NamespaceLookup (ds.Namespace, name, loc); - if (t != null){ - ds.Cache [name] = t; - return t; + if (helper_classes != null){ + foreach (TypeBuilder type_builder in helper_classes) { + PredefinedAttributes.Get.CompilerGenerated.EmitAttribute (type_builder); + type_builder.CreateType (); } } - - if (!silent) - Report.Error (246, loc, "Cannot find type `"+name+"'"); - return null; + type_container_resolve_order = null; + helper_classes = null; + //root = null; + TypeManager.CleanUp (); } - // - // This is the silent version of LookupType, you can use this - // to `probe' for a type - // - static public Type LookupType (TypeContainer tc, string name, Location loc) - { - return LookupType (tc, name, true, loc); - } - - static public bool IsNamespace (string name) + /// + /// Used to register classes that need to be closed after all the + /// user defined classes + /// + public static void RegisterCompilerGeneratedType (TypeBuilder helper_class) { - Namespace ns; - - if (tree.Namespaces != null){ - ns = (Namespace) tree.Namespaces [name]; + if (helper_classes == null) + helper_classes = new ArrayList (); - if (ns != null) - return true; - } - - return false; - } - - static void Report1530 (Location loc) - { - Report.Error (1530, loc, "Keyword new not allowed for namespace elements"); + helper_classes.Add (helper_class); } 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.Define (root); + 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"); } // @@ -633,42 +309,15 @@ namespace Mono.CSharp { // 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 (interface_resolve_order != null){ - foreach (Interface iface in interface_resolve_order) - if ((iface.ModFlags & Modifiers.NEW) == 0) - iface.DefineMembers (root); - else - Report1530 (iface.Location); - } - if (type_container_resolve_order != null){ - if (RootContext.StdLib){ - 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; - - if ((tc.ModFlags & Modifiers.NEW) == 0) - tc.DefineMembers (root); - else - Report1530 (tc.Location); - } - } else { - foreach (TypeContainer tc in type_container_resolve_order) { - if ((tc.ModFlags & Modifiers.NEW) == 0) - tc.DefineMembers (root); - else - Report1530 (tc.Location); + foreach (TypeContainer tc in type_container_resolve_order) + tc.ResolveType (); + foreach (TypeContainer tc in type_container_resolve_order) { + try { + tc.Define (); + } catch (Exception e) { + throw new InternalErrorException (tc, e); } } } @@ -676,122 +325,46 @@ namespace Mono.CSharp { 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); - } - } - - static public void DefineTypes () - { - TypeContainer root = Tree.Types; - - if (attribute_types != null) - foreach (TypeContainer tc in attribute_types) - tc.Define (root); - - if (interface_resolve_order != null){ - foreach (Interface iface in interface_resolve_order) - if ((iface.ModFlags & Modifiers.NEW) == 0) - iface.Define (root); + d.Define (); } - + // + // Check for cycles in the struct layout + // if (type_container_resolve_order != null){ - foreach (TypeContainer tc in type_container_resolve_order) { - // When compiling corlib, these types have already been - // populated from BootCorlib_PopulateCoreTypes (). - if (!RootContext.StdLib && - ((tc.Name == "System.Object") || - (tc.Name == "System.Attribute") || - (tc.Name == "System.ValueType"))) - continue; - - if ((tc.ModFlags & Modifiers.NEW) == 0) - tc.Define (root); - } - } - - ArrayList delegates = root.Delegates; - if (delegates != null){ - foreach (Delegate d in delegates) - if ((d.ModFlags & Modifiers.NEW) == 0) - d.Define (root); - } - - ArrayList enums = root.Enums; - if (enums != null){ - foreach (Enum en in enums) - if ((en.ModFlags & Modifiers.NEW) == 0) - en.Define (root); + Hashtable seen = new Hashtable (); + foreach (TypeContainer tc in type_container_resolve_order) + TypeManager.CheckStructCycles (tc, seen); } } static public void EmitCode () { - // - // Because of the strange way in which we do things, global - // attributes must be processed first. - // - if (global_attributes.Count > 0){ - AssemblyBuilder ab = CodeGen.AssemblyBuilder; - TypeContainer dummy = new TypeContainer (null, "", new Location (-1)); - EmitContext temp_ec = new EmitContext ( - dummy, Mono.CSharp.Location.Null, null, null, 0, false); - - foreach (DictionaryEntry de in global_attributes){ - Namespace ns = (Namespace) de.Key; - Attributes attrs = (Attributes) de.Value; - - dummy.Namespace = ns; - Attribute.ApplyAttributes (temp_ec, ab, ab, attrs, attrs.Location); - } - } - - if (attribute_types != null) - foreach (TypeContainer tc in attribute_types) - tc.Emit (); - if (type_container_resolve_order != null) { foreach (TypeContainer tc in type_container_resolve_order) - tc.EmitConstants (); - + tc.EmitType (); + + if (Report.Errors > 0) + return; + foreach (TypeContainer tc in type_container_resolve_order) - tc.Emit (); + tc.VerifyMembers (); } - if (Unsafe) { - if (TypeManager.unverifiable_code_ctor == null) { - Console.WriteLine ("Internal error ! Cannot set unverifiable code attribute."); - return; - } - - CustomAttributeBuilder cb = new CustomAttributeBuilder (TypeManager.unverifiable_code_ctor, - new object [0]); - CodeGen.ModuleBuilder.SetCustomAttribute (cb); - } + if (root.Delegates != null) { + foreach (Delegate d in root.Delegates) + d.Emit (); + } + + CodeGen.Assembly.Emit (root); + root.Emit (); } // // Public Field, used to track which method is the public entry // point. // - static public MethodInfo EntryPoint; - - // - // Track the location of the entry point. - // - static public Location EntryPointLocation; + static public Method EntryPoint; // // These are used to generate unique names on the structs and fields. @@ -815,11 +388,15 @@ namespace Mono.CSharp { static public FieldBuilder MakeStaticData (byte [] data) { FieldBuilder fb; - int size = data.Length; - if (impl_details_class == null) - impl_details_class = CodeGen.ModuleBuilder.DefineType ( - "", TypeAttributes.NotPublic, TypeManager.object_type); + if (impl_details_class == null){ + impl_details_class = ToplevelTypes.Builder.DefineType ( + "", + TypeAttributes.NotPublic, + TypeManager.object_type); + + RegisterCompilerGeneratedType (impl_details_class); + } fb = impl_details_class.DefineInitializedData ( "$$field-" + (field_count++), data, @@ -828,20 +405,12 @@ namespace Mono.CSharp { return fb; } - // - // Adds a global attribute that was declared in `container', - // the attribute is in `attr', and it was defined at `loc' - // - static public void AddGlobalAttribute (TypeContainer container, - AttributeSection attr, Location loc) + public static void CheckUnsafeOption (Location loc) { - Namespace ns = container.Namespace; - Attributes a = (Attributes) global_attributes [ns]; - - if (a == null) - global_attributes [ns] = new Attributes (attr, loc); - else - a.AddAttribute (attr); + if (!Unsafe) { + Report.Error (227, loc, + "Unsafe code requires the `unsafe' command line option to be specified"); + } } } }