+ //
+ // If implementing is still valid, set flags
+ //
+ if (implementing != null){
+ //
+ // When implementing interface methods, set NewSlot.
+ //
+ if (implementing.DeclaringType.IsInterface)
+ flags |= MethodAttributes.NewSlot;
+
+ flags |=
+ MethodAttributes.Virtual |
+ MethodAttributes.HideBySig;
+
+ // Get the method name from the explicit interface.
+ if (member.InterfaceType != null) {
+ name = implementing.Name;
+ method_name = prefix + name;
+ }
+
+ IsImplementing = true;
+ }
+
+ //
+ // Create the MethodBuilder for the method
+ //
+ if ((flags & MethodAttributes.PinvokeImpl) != 0) {
+ if ((modifiers & Modifiers.STATIC) == 0) {
+ Report.Error (601, Location,
+ "The DllImport attribute must be specified on " +
+ "a method marked 'static' and 'extern'.");
+ return false;
+ }
+
+ EmitContext ec = new EmitContext (
+ parent, Location, null, ReturnType, modifiers);
+
+ builder = dllimport_attribute.DefinePInvokeMethod (
+ ec, parent.TypeBuilder, method_name, flags,
+ ReturnType, ParameterTypes);
+ } else
+ builder = parent.TypeBuilder.DefineMethod (
+ method_name, flags, CallingConventions,
+ ReturnType, ParameterTypes);
+
+ if (builder == null)
+ return false;
+
+ if (IsImplementing) {
+ //
+ // clear the pending implemntation flag
+ //
+ if (member is Indexer) {
+ parent.Pending.ImplementIndexer (
+ member.InterfaceType, builder, ReturnType,
+ ParameterTypes, true);
+ } else
+ parent.Pending.ImplementMethod (
+ member.InterfaceType, name, ReturnType,
+ ParameterTypes, member.IsExplicitImpl);
+
+ if (member.IsExplicitImpl)
+ parent.TypeBuilder.DefineMethodOverride (
+ builder, implementing);
+ }
+
+ if (!TypeManager.RegisterMethod (builder, ParameterInfo, ParameterTypes)) {
+ Report.Error (111, Location,
+ "Class `" + parent.Name +
+ "' already contains a definition with the " +
+ "same return value and parameter types as the " +
+ "'get' method of property `" + member.Name + "'");
+ return false;
+ }
+
+ TypeManager.AddMethod (builder, this);
+
+ return true;
+ }
+
+ //
+ // Emits the code
+ //
+ public virtual void Emit (TypeContainer parent, Block block, object kind)
+ {
+ ILGenerator ig;
+ EmitContext ec;
+
+ if ((flags & MethodAttributes.PinvokeImpl) == 0)
+ ig = builder.GetILGenerator ();
+ else
+ ig = null;
+
+ ec = new EmitContext (parent, Location, ig, ReturnType, modifiers);
+
+ if (OptAttributes != null)
+ Attribute.ApplyAttributes (ec, builder, kind, OptAttributes, Location);
+
+ if (member is MethodCore)
+ ((MethodCore) member).LabelParameters (ec, ParameterTypes, MethodBuilder);
+
+ //
+ // abstract or extern methods have no bodies
+ //
+ if ((modifiers & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0){
+ if (block == null)
+ return;
+
+ //
+ // abstract or extern methods have no bodies.
+ //
+ if ((modifiers & Modifiers.ABSTRACT) != 0)
+ Report.Error (
+ 500, Location, "Abstract method `" +
+ TypeManager.MonoBASIC_Signature (builder) +
+ "' can not have a body");
+
+ if ((modifiers & Modifiers.EXTERN) != 0)
+ Report.Error (
+ 179, Location, "External method `" +
+ TypeManager.MonoBASIC_Signature (builder) +
+ "' can not have a body");
+
+ return;
+ }
+
+ //
+ // Methods must have a body unless they're extern or abstract
+ //
+ if (block == null) {
+ Report.Error (
+ 501, Location, "Method `" +
+ TypeManager.MonoBASIC_Signature (builder) +
+ "' must declare a body since it is not marked " +
+ "abstract or extern");
+ return;
+ }
+
+ //
+ // Handle destructors specially
+ //
+ // FIXME: This code generates buggy code
+ //
+ if (member.Name == "Finalize" && ReturnType == TypeManager.void_type)
+ EmitDestructor (ec, block);
+ else {
+ ISymbolWriter sw = CodeGen.SymbolWriter;
+
+ if ((sw != null) && !Location.IsNull (Location) &&
+ !Location.IsNull (block.EndLocation)) {
+ Location end = block.EndLocation;
+ MethodToken token = MethodBuilder.GetToken ();
+ sw.OpenMethod (new SymbolToken (token.Token));
+ // Avoid error if we don't support debugging for the platform
+ try {
+ sw.SetMethodSourceRange (Location.SymbolDocument,
+ Location.Row, 0,
+ end.SymbolDocument,
+ end.Row, 0);
+ } catch (Exception) {
+ }
+
+ ec.EmitTopBlock (block, member.Name, ParameterInfo, Location);
+
+ sw.CloseMethod ();
+ } else
+ ec.EmitTopBlock (block, member.Name, ParameterInfo, Location);
+ }
+ }
+
+ void EmitDestructor (EmitContext ec, Block block)
+ {
+ ILGenerator ig = ec.ig;
+
+ Label finish = ig.DefineLabel ();
+ bool old_in_try = ec.InTry;
+
+ ig.BeginExceptionBlock ();
+ ec.InTry = true;
+ ec.ReturnLabel = finish;
+ ec.HasReturnLabel = true;
+ ec.EmitTopBlock (block, null, Location);
+ ec.InTry = old_in_try;
+
+ // ig.MarkLabel (finish);
+ bool old_in_finally = ec.InFinally;
+ ec.InFinally = true;
+ ig.BeginFinallyBlock ();
+
+ if (ec.ContainerType.BaseType != null) {
+ Expression member_lookup = Expression.MemberLookup (
+ ec, ec.ContainerType.BaseType, ec.ContainerType.BaseType, "Finalize",
+ MemberTypes.Method, Expression.AllBindingFlags, Location);
+
+ if (member_lookup != null){
+ MethodGroupExpr parent_destructor = ((MethodGroupExpr) member_lookup);
+
+ ig.Emit (OpCodes.Ldarg_0);
+ ig.Emit (OpCodes.Call, (MethodInfo) parent_destructor.Methods [0]);
+ }
+ }
+ ec.InFinally = old_in_finally;
+
+ ig.EndExceptionBlock ();
+ //ig.MarkLabel (ec.ReturnLabel);
+ ig.Emit (OpCodes.Ret);
+ }
+ }
+
+ abstract public class MemberBase : MemberCore {
+ public Expression Type;
+ public readonly Attributes OptAttributes;
+ public Expression Implements;
+
+ protected MethodAttributes flags;
+
+ //
+ // The "short" name of this property / indexer / event. This is the
+ // name without the explicit interface.
+ //
+ public string ShortName;
+
+ //
+ // The type of this property / indexer / event
+ //
+ public Type MemberType;