Rework gc descriptor to include size information in more cases.
[mono.git] / mcs / mcs / roottypes.cs
index b179287e1d823059126ab984452c6238fca0e86a..48f2b266b3b7637a15fdbf0c15a8dfebc27f70c6 100644 (file)
@@ -8,6 +8,7 @@
 //
 // Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
 // Copyright 2003-2008 Novell, Inc.
+// Copyright 2011 Xamarin Inc
 //
 
 using System;
@@ -63,27 +64,14 @@ namespace Mono.CSharp
                                        // DefineInitializedData because it creates public type,
                                        // and its name is not unique among modules
                                        //
-                                       size_type = new Struct (null, this, new MemberName ("$ArrayType=" + data.Length, Location), Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED, null);
+                                       size_type = new Struct (null, this, new MemberName ("$ArrayType=" + data.Length, loc), Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED, null);
                                        size_type.CreateType ();
                                        size_type.DefineType ();
 
                                        size_types.Add (data.Length, size_type);
-                                       var ctor = Module.PredefinedMembers.StructLayoutAttributeCtor.Resolve (Location);
-                                       if (ctor != null) {
-                                               var argsEncoded = new AttributeEncoder ();
-                                               argsEncoded.Encode ((short) LayoutKind.Explicit);
-
-                                               var field_size = Module.PredefinedMembers.StructLayoutSize.Resolve (Location);
-                                               var pack = Module.PredefinedMembers.StructLayoutPack.Resolve (Location);
-                                               if (field_size != null && pack != null) {
-                                                       argsEncoded.EncodeNamedArguments (
-                                                               new[] { field_size, pack },
-                                                               new[] { new IntConstant (Compiler.BuiltinTypes, (int) data.Length, Location), new IntConstant (Compiler.BuiltinTypes, 1, Location) }
-                                                       );
-
-                                                       size_type.TypeBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), argsEncoded.ToArray ());
-                                               }
-                                       }
+
+                                       // It has to work even if StructLayoutAttribute does not exist
+                                       size_type.TypeBuilder.__SetLayout (1, data.Length);
                                }
 
                                var name = "$field-" + fields.ToString ("X");
@@ -124,6 +112,9 @@ namespace Mono.CSharp
                readonly Dictionary<TypeSpec, ReferenceContainer> reference_types;
                readonly Dictionary<TypeSpec, MethodSpec> attrs_cache;
 
+               // Used for unique namespaces/types during parsing
+               Dictionary<MemberName, ITypesContainer> defined_type_containers;
+
                AssemblyDefinition assembly;
                readonly CompilerContext context;
                readonly RootNamespace global_ns;
@@ -154,6 +145,8 @@ namespace Mono.CSharp
                        pointer_types = new Dictionary<TypeSpec, PointerContainer> ();
                        reference_types = new Dictionary<TypeSpec, ReferenceContainer> ();
                        attrs_cache = new Dictionary<TypeSpec, MethodSpec> ();
+
+                       defined_type_containers = new Dictionary<MemberName, ITypesContainer> ();
                }
 
                #region Properties
@@ -220,6 +213,10 @@ namespace Mono.CSharp
                        }
                }
 
+               public bool HasTypesFullyDefined {
+                       get; set;
+               }
+
                //
                // Returns module global:: namespace
                //
@@ -370,7 +367,7 @@ namespace Mono.CSharp
                public RootNamespace CreateRootNamespace (string alias)
                {
                        if (alias == global_ns.Alias) {
-                               NamespaceEntry.Error_GlobalNamespaceRedefined (Location.Null, Report);
+                               RootNamespace.Error_GlobalNamespaceRedefined (Report, Location.Null);
                                return global_ns;
                        }
 
@@ -391,14 +388,25 @@ namespace Mono.CSharp
 
                public new void CreateType ()
                {
+                       // Release cache used by parser only
+                       if (Evaluator == null)
+                               defined_type_containers = null;
+                       else
+                               defined_type_containers.Clear ();
+
                        foreach (TypeContainer tc in types)
                                tc.CreateType ();
                }
 
                public new void Define ()
                {
-                       foreach (TypeContainer tc in types)
-                               tc.DefineType ();
+                       foreach (TypeContainer tc in types) {
+                               try {
+                                       tc.DefineType ();
+                               } catch (Exception e) {
+                                       throw new InternalErrorException (tc, e);
+                               }
+                       }
 
                        foreach (TypeContainer tc in types)
                                tc.ResolveTypeParameters ();
@@ -410,6 +418,8 @@ namespace Mono.CSharp
                                        throw new InternalErrorException (tc, e);
                                }
                        }
+
+                       HasTypesFullyDefined = true;
                }
 
                public override void Emit ()
@@ -490,16 +500,58 @@ namespace Mono.CSharp
                        return DeclaringAssembly.IsCLSCompliant;
                }
 
-               protected override bool AddMemberType (TypeContainer ds)
+               protected override bool AddMemberType (TypeContainer tc)
                {
-                       if (!AddToContainer (ds, ds.Name))
-                               return false;
-                       ds.NamespaceEntry.NS.AddType (this, ds.Definition);
-                       return true;
+                       if (AddTypesContainer (tc)) {
+                               if ((tc.ModFlags & Modifiers.PARTIAL) != 0)
+                                       defined_names.Add (tc.Name, tc);
+
+                               tc.NamespaceEntry.NS.AddType (this, tc.Definition);
+                               return true;
+                       }
+
+                       return false;
+               }
+
+               public bool AddTypesContainer (ITypesContainer container)
+               {
+                       var mn = container.MemberName;
+                       ITypesContainer found;
+                       if (!defined_type_containers.TryGetValue (mn, out found)) {
+                               defined_type_containers.Add (mn, container);
+                               return true;
+                       }
+
+                       if (container is NamespaceContainer && found is NamespaceContainer)
+                               return true;
+
+                       var container_tc = container as TypeContainer;
+                       var found_tc = found as TypeContainer;
+                       if (container_tc != null && found_tc != null && container_tc.Kind == found_tc.Kind) {
+                               if ((found_tc.ModFlags & container_tc.ModFlags & Modifiers.PARTIAL) != 0) {
+                                       return false;
+                               }
+
+                               if (((found_tc.ModFlags | container_tc.ModFlags) & Modifiers.PARTIAL) != 0) {
+                                       Report.SymbolRelatedToPreviousError (found_tc);
+                                       Error_MissingPartialModifier (container_tc);
+                                       return false;
+                               }
+                       }
+
+                       string ns = mn.Left != null ? mn.Left.GetSignatureForError () : Module.GlobalRootNamespace.GetSignatureForError ();
+                       mn = new MemberName (mn.Name, mn.TypeArguments, mn.Location);
+
+                       Report.SymbolRelatedToPreviousError (found.Location, "");
+                       Report.Error (101, container.Location,
+                               "The namespace `{0}' already contains a definition for `{1}'",
+                               ns, mn.GetSignatureForError ());
+                       return false;
                }
 
                protected override void RemoveMemberType (TypeContainer ds)
                {
+                       defined_type_containers.Remove (ds.MemberName);
                        ds.NamespaceEntry.NS.RemoveDeclSpace (ds.Basename);
                        base.RemoveMemberType (ds);
                }
@@ -521,7 +573,7 @@ namespace Mono.CSharp
        }
 
        sealed class RootDeclSpace : TypeContainer {
-               public RootDeclSpace (ModuleContainer module, NamespaceEntry ns)
+               public RootDeclSpace (ModuleContainer module, NamespaceContainer ns)
                        : base (ns, null, MemberName.Null, null, 0)
                {
                        PartialContainer = module;
@@ -562,7 +614,7 @@ namespace Mono.CSharp
                        return PartialContainer.IsClsComplianceRequired ();
                }
 
-               public override IList<MethodSpec> LookupExtensionMethod (TypeSpec extensionType, string name, int arity, ref NamespaceEntry scope)
+               public override ExtensionMethodCandidates LookupExtensionMethod (TypeSpec extensionType, string name, int arity)
                {
                        return null;
                }