Thread: [csdoc-patches] csdoc/src/mcs/mcs ChangeLog,1.1,1.2 TODO,1.1,1.2 anonymous.cs,1.1,1.2 assign.cs,1.1,
Status: Planning
Brought to you by:
mastergaurav
Update of /cvsroot/csdoc/csdoc/src/mcs/mcs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18346 Modified Files: ChangeLog TODO anonymous.cs assign.cs attribute.cs class.cs codegen.cs const.cs convert.cs cs-parser.jay decl.cs delegate.cs ecore.cs enum.cs expression.cs iterators.cs mcs.exe.config parameter.cs parser.cs report.cs rootcontext.cs statement.cs support.cs typemanager.cs Log Message: 2004-10-28 Gaurav Vaish * **/* :: Latest from mono/mcs Index: ChangeLog =================================================================== RCS file: /cvsroot/csdoc/csdoc/src/mcs/mcs/ChangeLog,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** ChangeLog 6 Oct 2004 19:28:29 -0000 1.1 --- ChangeLog 29 Oct 2004 13:54:36 -0000 1.2 *************** *** 1,2 **** --- 1,467 ---- + 2004-10-27 Miguel de Icaza <mi...@xi...> + + * expression.cs (LocalVariableReference.DoResolveLValue): Check + for obsolete use of a variable here. Fixes regression on errors + cs0619-25 and cs0619-26. + + 2004-10-27 Marek Safar <mar...@se...> + + Fix #62358, implemented security attribute encoding. + + * attribute.cs (Attribute.CheckSecurityActionValididy): New method. + Tests permitted SecurityAction for assembly or other types. + (Assembly.ExtractSecurityPermissionSet): New method. Transforms + data from SecurityPermissionAttribute to PermisionSet class. + + * class.cs (ApplyAttributeBuilder): Added special handling + for System.Security.Permissions.SecurityAttribute based types. + + * codegen.cs (AssemblyClass.ApplyAttributeBuilder): Added + special handling for System.Security.Permissions.SecurityAttribute + based types. + + * enum.cs (ApplyAttributeBuilder): Added special handling + for System.Security.Permissions.SecurityAttribute based types. + + * parameter.cs (ApplyAttributeBuilder): Added special handling + for System.Security.Permissions.SecurityAttribute based types. + + * rootcontext.cs: Next 2 core types. + + * typemanager.cs (TypeManager.security_permission_attr_type): + Built in type for the SecurityPermission Attribute. + (code_access_permission_type): Build in type. + + 2004-10-17 Miguel de Icaza <mi...@xi...> + + * expression.cs (LocalVariableReference.DoResolveBase, Emit): + Remove the tests for `ec.RemapToProxy' from here, and encapsulate + all of this information into + EmitContext.EmitCapturedVariableInstance. + + * codegen.cs (EmitCapturedVariableInstance): move here the + funcionality of emitting an ldarg.0 in the presence of a + remapping. This centralizes the instance emit code. + + (EmitContext.EmitThis): If the ScopeInfo contains a THIS field, + then emit a load of this: it means that we have reached the + topmost ScopeInfo: the one that contains the pointer to the + instance of the class hosting the anonymous method. + + * anonymous.cs (AddField, HaveCapturedFields): Propagate field + captures to the topmost CaptureContext. + + 2004-10-12 Miguel de Icaza <mi...@xi...> + + * expression.cs (LocalVariableReference): Move the knowledge about + the iterators into codegen's EmitCapturedVariableInstance. + + 2004-10-11 Miguel de Icaza <mi...@xi...> + + * codegen.cs (EmitContext.ResolveTopBlock): Emit a 1643 when not + all code paths return a value from an anonymous method (it is the + same as the 161 error, but for anonymous methods). + + 2004-10-08 Miguel de Icaza <mi...@xi...> + + The introduction of anonymous methods in the compiler changed + various ways of doing things in the compiler. The most + significant one is the hard split between the resolution phase + and the emission phases of the compiler. + + For instance, routines that referenced local variables no + longer can safely create temporary variables during the + resolution phase: they must do so from the emission phase, + since the variable might have been "captured", hence access to + it can not be done with the local-variable operations from the runtime. + + * statement.cs + + (Block.Flags): New flag `IsTopLevel' to indicate that this block + is a toplevel block. + + (ToplevelBlock): A new kind of Block, these are the blocks that + are created by the parser for all toplevel method bodies. These + include methods, accessors and anonymous methods. + + These contain some extra information not found in regular blocks: + A pointer to an optional CaptureContext (for tracking captured + local variables and parameters). A pointer to the parent + ToplevelBlock. + + (Return.Resolve): Catch missmatches when returning a value from an + anonymous method (error 1662). + Invoke NeedReturnLabel from the Resolve phase instead of the emit + phase. + + (Break.Resolve): ditto. + + (SwitchLabel): instead of defining the labels during the + resolution phase, we now turned the public ILLabel and ILLabelCode + labels into methods called GetILLabelCode() and GetILLabel() that + only define the label during the Emit phase. + + (GotoCase): Track the SwitchLabel instead of the computed label + (its contained therein). Emit the code by using + SwitchLabel.GetILLabelCode (). + + (LocalInfo.Flags.Captured): A new flag has been introduce to track + whether the Local has been captured or not. + + (LocalInfo.IsCaptured): New property, used to tell whether the + local has been captured. + + * anonymous.cs: Vastly updated to contain the anonymous method + support. + + The main classes here are: CaptureContext which tracks any + captured information for a toplevel block and ScopeInfo used to + track the activation frames for various local variables. + + Each toplevel block has an optional capture context associated + with it. When a method contains an anonymous method both the + toplevel method and the anonymous method will create a capture + context. When variables or parameters are captured, they are + recorded on the CaptureContext that owns them, for example: + + void Demo () { + int a; + MyDelegate d = delegate { + a = 1; + } + } + + Here `a' will be recorded as captured on the toplevel + CapturedContext, the inner captured context will not have anything + (it will only have data if local variables or parameters from it + are captured in a nested anonymous method. + + The ScopeInfo is used to track the activation frames for local + variables, for example: + + for (int i = 0; i < 10; i++) + for (int j = 0; j < 10; j++){ + MyDelegate d = delegate { + call (i, j); + } + } + + At runtime this captures a single captured variable `i', but it + captures 10 different versions of the variable `j'. The variable + `i' will be recorded on the toplevel ScopeInfo, while `j' will be + recorded on a child. + + The toplevel ScopeInfo will also track information like the `this' + pointer if instance variables were referenced (this is necessary + as the anonymous method lives inside a nested class in the host + type of the method). + + (AnonymousMethod): Expanded to track the Toplevel, implement + `AnonymousMethod.Compatible' to tell whether an anonymous method + can be converted to a target delegate type. + + The routine now also produces the anonymous method content + + (AnonymousDelegate): A helper class that derives from + DelegateCreation, this is used to generate the code necessary to + produce the delegate for the anonymous method that was created. + + * assign.cs: API adjustments for new changes in + Convert.ImplicitStandardConversionExists. + + * class.cs: Adjustments to cope with the fact that now toplevel + blocks are of type `ToplevelBlock'. + + * cs-parser.jay: Now we produce ToplevelBlocks for toplevel blocks + insteda of standard blocks. + + Flag errors if params arguments are passed to anonymous methods. + + * codegen.cs (EmitContext): Replace `InAnonymousMethod' with + `CurrentAnonymousMethod' which points to the current Anonymous + Method. The variable points to the AnonymousMethod class that + holds the code being compiled. It is set in the new EmitContext + created for the anonymous method. + + (EmitContext.Phase): Introduce a variable and an enumeration to + assist in enforcing some rules about when and where we are allowed + to invoke certain methods (EmitContext.NeedsReturnLabel is the + only one that enfonces this right now). + + (EmitContext.HaveCaptureInfo): new helper method that returns + whether we have a CapturedContext initialized. + + (EmitContext.CaptureVariable): New method used to register that a + LocalInfo must be flagged for capturing. + + (EmitContext.CapturedParameter): New method used to register that a + parameters must be flagged for capturing. + + (EmitContext.CapturedField): New method used to register that a + field must be flagged for capturing. + + (EmitContext.HaveCapturedVariables, + EmitContext.HaveCapturedFields): Return whether there are captured + variables or fields. + + (EmitContext.EmitMethodHostInstance): This is used to emit the + instance for the anonymous method. The instance might be null + (static methods), this (for anonymous methods that capture nothing + and happen to live side-by-side with the current method body) or a + more complicated expression if the method has a CaptureContext. + + (EmitContext.EmitTopBlock): Routine that drives the emission of + code: it will first resolve the top block, then emit any metadata + and then emit the code. The split is done so that we can extract + any anonymous methods and flag any captured variables/parameters. + + (EmitContext.ResolveTopBlock): Triggers the resolution phase, + during this phase, the ILGenerator should not be used as labels + and local variables declared here might not be accessible to any + code that is part of an anonymous method. + + Exceptions to this include the temporary variables that are + created by some statements internally for holding temporary + variables. + + (EmitContext.EmitMeta): New routine, in charge of emitting all the + metadata for a cb + + (EmitContext.TemporaryReturn): This method is typically called + from the Emit phase, and its the only place where we allow the + ReturnLabel to be defined other than the EmitMeta. The reason is + that otherwise we would have to duplicate a lot of logic in the + Resolve phases of various methods that today is on the Emit + phase. + + (EmitContext.NeedReturnLabel): This no longer creates the label, + as the ILGenerator is not valid during the resolve phase. + + (EmitContext.EmitThis): Extended the knowledge in this class to + work in anonymous methods in addition to iterators. + + (EmitContext.EmitCapturedVariableInstance): This emits whatever + code is necessary on the stack to access the instance to a local + variable (the variable will be accessed as a field). + + (EmitContext.EmitParameter, EmitContext.EmitAssignParameter, + EmitContext.EmitAddressOfParameter): Routines to support + parameters (not completed at this point). + + Removals: Removed RemapLocal and RemapLocalLValue. We probably + will also remove the parameters. + + * convert.cs (Convert): Define a `ConstantEC' which points to a + null. This is just to prefity some code that uses + ImplicitStandardConversion code and do not have an EmitContext + handy. + + The idea is to flag explicitly that at that point in time, it is + known that the conversion will not trigger the delegate checking + code in implicit conversions (which requires a valid + EmitContext). + + Everywhere: pass new EmitContext parameter since + ImplicitStandardConversionExists now requires it to check for + anonymous method conversions. + + (Convert.ImplicitStandardConversionExists): If the type of an + expression is the anonymous_method_type, and the type is a + delegate, we invoke the AnonymousMethod.Compatible method to check + whether an implicit conversion is possible. + + (Convert.ImplicitConversionStandard): Only do implicit method + group conversions if the language level is not ISO_1. + + * delegate.cs (Delegate.GetInvokeMethod): Common method to get the + MethodInfo for the Invoke method. used by Delegate and + AnonymousDelegate. + + * expression.cs (Binary.DoNumericPromotions): only allow anonymous + method conversions if the target type is a delegate. + + Removed extra debugging nops. + + (LocalVariableReference): Turn the `local_info' into a public + field. + + Add `prepared' field, the same hack used for FieldExprs to cope + with composed assignments, as Local variables do not necessarily + operate purely on the stack as they used to: they can be captured + fields. + + Add `temp' for a temporary result, like fields. + + Refactor DoResolve and DoResolveLValue into DoResolveBase. + + It now copes with Local variables that are captured and emits the + proper instance variable to load it from a field in the captured + case. + + (ParameterReference.DoResolveBase): During the resolve phase, + capture parameters if we are in an anonymous method. + + (ParameterReference.Emit, ParameterReference.AddressOf): If in an + anonymous method, use the EmitContext helper routines to emit the + parameter reference. + + * iterators.cs: Set RemapToProxy to true/false during the + EmitDispose class. + + * parameters.cs (GetParameterByName): New helper method. + + * typemanager.cs (anonymous_method_type) a new type that + represents an anonyous method. This is always an internal type, + used as a fencepost to test against the anonymous-methodness of an + expression. + + 2004-10-24 Marek Safar <mar...@se...> + + Fixed bugs #63705, #67130 + * decl.cs (MemberCache.MemberCache): Add parameter to distinguish + imported and defined interfaces. + (CacheEntry, EntryType): Changed to protected internal. + + * class.cs (TypeContainer.DoDefineMembers): Setup cache for + interfaces too. + + * typemanager.cs (LookupInterfaceContainer): New method. + Fills member container from base interfaces. + + 2004-10-20 Marek Safar <mar...@se...> + + * class.cs (MethodCore.CheckBase): Add errors 505, 533, 544, + 561 report. + (PropertyBase.FindOutParentMethod): Add errors 545, 546 report. + + 2004-10-18 Martin Baulig <ma...@xi...> + + Merged latest changes into gmcs. Please keep this comment in + here, it makes it easier for me to see what changed in MCS since + the last time I merged. + + 2004-10-18 Martin Baulig <ma...@xi...> + + * statement.cs (Fixed.Resolve): Don't access the TypeExpr's + `Type' directly, but call ResolveType() on it. + (Catch.Resolve): Likewise. + (Foreach.Resolve): Likewise. + + 2004-10-18 Martin Baulig <ma...@xi...> + + * expression.cs (Cast.DoResolve): Don't access the TypeExpr's + `Type' directly, but call ResolveType() on it. + (Probe.DoResolve): Likewise. + (ArrayCreation.LookupType): Likewise. + (TypeOf.DoResolve): Likewise. + (SizeOf.DoResolve): Likewise. + + 2004-10-18 Martin Baulig <ma...@xi...> + + * expression.cs (Invocation.BetterFunction): Put back + TypeManager.TypeToCoreType(). + + 2004-10-18 Raja R Harinath <rha...@no...> + + * class.cs (FieldMember.DoDefine): Reset ec.InUnsafe after doing + the ResolveType. + + 2004-10-18 Martin Baulig <ma...@xi...> + + * parameter.cs (Parameter.Resolve): Don't access the TypeExpr's + `Type' directly, but call ResolveType() on it. + + 2004-10-18 Martin Baulig <ma...@xi...> + + * class.cs (FieldMember.Define): Don't access the TypeExpr's + `Type' directly, but call ResolveType() on it. + (MemberBase.DoDefine): Likewise. + + * expression.cs (New.DoResolve): Don't access the TypeExpr's + `Type' directly, but call ResolveType() on it. + (ComposedCast.DoResolveAsTypeStep): Likewise. + + * statement.cs (LocalInfo.Resolve): Don't access the TypeExpr's + `Type' directly, but call ResolveType() on it. + + 2004-10-17 John Luke <joh...@gm...> + + * class.cs (Operator.GetSignatureForError): use CSharpName + + * parameter.cs (Parameter.GetSignatureForError): Returns + correct name even if was not defined. + + 2004-10-13 Raja R Harinath <rha...@no...> + + Fix #65816. + * class.cs (TypeContainer.EmitContext): New property. + (DefineNestedTypes): Create an emitcontext for each part. + (MethodCore.DoDefineParameters): Use container's emitcontext. + Pass type array to InternalParameters. + (MemberBase.DoDefine): Use container's emitcontext. + (FieldMember.Define): Likewise. + (Event.Define): Likewise. + (SetMethod.GetParameterInfo): Change argument to EmitContext. + Pass type array to InternalParameters. + (SetIndexerMethod.GetParameterInfo): Likewise. + (SetMethod.Define): Pass emitcontext to GetParameterInfo. + * delegate.cs (Define): Pass emitcontext to + ComputeAndDefineParameterTypes and GetParameterInfo. Pass type + array to InternalParameters. + * expression.cs (ParameterReference.DoResolveBase): Pass + emitcontext to GetParameterInfo. + (ComposedCast.DoResolveAsTypeStep): Remove check on + ec.ResolvingTypeTree. + * parameter.cs (Parameter.Resolve): Change argument to + EmitContext. Use ResolveAsTypeTerminal. + (Parameter.GetSignature): Change argument to EmitContext. + (Parameters.ComputeSignature): Likewise. + (Parameters.ComputeParameterTypes): Likewise. + (Parameters.GetParameterInfo): Likewise. + (Parameters.ComputeAndDefineParameterTypes): Likewise. + Re-use ComputeParameterTypes. Set ec.ResolvingTypeTree. + * support.cs (InternalParameters..ctor): Remove variant that takes + a DeclSpace. + * typemanager.cs (system_intptr_expr): New. + (InitExpressionTypes): Initialize it. + + 2004-10-12 Chris Toshok <to...@xi...> + + * cs-parser.jay: fix location for try_statement and catch_clause. + + 2004-10-11 Martin Baulig <ma...@xi...> + + * report.cs: Don't make --fatal abort on warnings, we have + -warnaserror for that. + + 2004-10-07 Raja R Harinath <rha...@no...> + + More DeclSpace.ResolveType avoidance. + * decl.cs (MemberCore.InUnsafe): New property. + * class.cs (MemberBase.DoDefine): Use ResolveAsTypeTerminal + with newly created EmitContext. + (FieldMember.Define): Likewise. + * delegate.cs (Delegate.Define): Likewise. + * ecore.cs (SimpleName.ResolveAsTypeStep): Lookup with alias + only if normal name-lookup fails. + (TypeExpr.DoResolve): Enable error-checking. + * expression.cs (ArrayCreation.DoResolve): Use ResolveAsTypeTerminal. + (SizeOf.DoResolve): Likewise. + (ComposedCast.DoResolveAsTypeStep): Likewise. + (StackAlloc.DoResolve): Likewise. + * statement.cs (Block.Flags): Add new flag 'Unsafe'. + (Block.Unsafe): New property. + (Block.EmitMeta): Set ec.InUnsafe as appropriate. + (Unsafe): Set 'unsafe' flag of contained block. + (LocalInfo.Resolve): Use ResolveAsTypeTerminal. + (Fixed.Resolve): Likewise. + (Catch.Resolve): Likewise. + (Using.ResolveLocalVariableDecls): Likewise. + (Foreach.Resolve): Likewise. + + 2004-10-05 John Luke <joh...@gm...> + + * cs-parser.jay: add location to error CS0175 + 2004-10-04 Miguel de Icaza <mi...@xi...> *************** *** 86,95 **** (Convert.ImplicitReferenceConversionExists): Likewise. - 2004-09-23 Martin Baulig <ma...@xi...> - - Merged latest changes into gmcs. Please keep this comment in - here, it makes it easier for me to see what changed in MCS since - the last time I merged. - 2004-09-23 Marek Safar <mar...@se...> --- 551,554 ---- Index: TODO =================================================================== RCS file: /cvsroot/csdoc/csdoc/src/mcs/mcs/TODO,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** TODO 6 Oct 2004 19:28:29 -0000 1.1 --- TODO 29 Oct 2004 13:54:36 -0000 1.2 *************** *** 1,2 **** --- 1,3 ---- + NEW NOTES: ---------- *************** *** 46,50 **** Iterators --------- - * Reset should throw not implemented now. --- 47,50 ---- Index: anonymous.cs =================================================================== RCS file: /cvsroot/csdoc/csdoc/src/mcs/mcs/anonymous.cs,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** anonymous.cs 6 Oct 2004 19:28:29 -0000 1.1 --- anonymous.cs 29 Oct 2004 13:54:36 -0000 1.2 *************** *** 5,12 **** // Miguel de Icaza (mi...@xi...) // ! // (C) 2003 Ximian, Inc. // using System; using System.Collections; using System.Reflection; --- 5,18 ---- // Miguel de Icaza (mi...@xi...) [...1140 lines suppressed...] + if (scopes [b.ID] != null){ + LinkScope (scope, b.ID); + break; + } + } + + if (scope.ParentScope == null && ParentCaptureContext != null){ + CaptureContext pcc = ParentCaptureContext; + + for (Block b = Host.ContainingBlock; b != null; b = b.Parent){ + if (pcc.scopes [b.ID] != null){ + pcc.LinkScope (scope, b.ID); + break; + } + } + } + } + } } } Index: assign.cs =================================================================== RCS file: /cvsroot/csdoc/csdoc/src/mcs/mcs/assign.cs,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** assign.cs 6 Oct 2004 19:28:29 -0000 1.1 --- assign.cs 29 Oct 2004 13:54:36 -0000 1.2 *************** *** 361,364 **** --- 361,365 ---- eclass = ExprClass.Value; + if (target is EventExpr) { EventInfo ei = ((EventExpr) target).EventInfo; *************** *** 443,447 **** // the type of target // ! if (Convert.ImplicitStandardConversionExists (a.original_source, target_type)) return this; --- 444,448 ---- // the type of target // ! if (Convert.ImplicitStandardConversionExists (ec, a.original_source, target_type)) return this; Index: attribute.cs =================================================================== RCS file: /cvsroot/csdoc/csdoc/src/mcs/mcs/attribute.cs,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** attribute.cs 6 Oct 2004 19:28:29 -0000 1.1 --- attribute.cs 29 Oct 2004 13:54:36 -0000 1.2 *************** *** 19,22 **** --- 19,24 ---- using System.Runtime.InteropServices; using System.Runtime.CompilerServices; + using System.Security; + using System.Security.Permissions; using System.Text; *************** *** 80,84 **** public Type Type; ! // Is non-null if type is AttributeUsageAttribute AttributeUsageAttribute usage_attribute; --- 82,86 ---- public Type Type; ! // Is non-null if type is AttributeUsageAttribute AttributeUsageAttribute usage_attribute; *************** *** 125,128 **** --- 127,144 ---- } + /// <summary> + /// This is rather hack. We report many emit attribute error with same error to be compatible with + /// csc. But because csc has to report them this way because error came from ilasm we needn't. + /// </summary> + public void Error_AttributeEmitError (string inner) + { + Report.Error (647, Location, "Error emitting '{0}' attribute because '{1}'", Name, inner); + } + + public void Error_InvalidSecurityParent () + { + Error_AttributeEmitError ("it is attached to invalid parent"); + } + void Error_AttributeConstructorMismatch () { *************** *** 710,713 **** --- 726,830 ---- } + /// <summary> + /// Tests permitted SecurityAction for assembly or other types + /// </summary> + public bool CheckSecurityActionValidity (bool for_assembly) + { + SecurityAction action = GetSecurityActionValue (); + + if ((action == SecurityAction.RequestMinimum || action == SecurityAction.RequestOptional || action == SecurityAction.RequestRefuse) && for_assembly) + return true; + + if (!for_assembly) { + if (action < SecurityAction.Demand || action > SecurityAction.InheritanceDemand) { + Error_AttributeEmitError ("SecurityAction is out of range"); + return false; + } + + if ((action != SecurityAction.RequestMinimum && action != SecurityAction.RequestOptional && action != SecurityAction.RequestRefuse) && !for_assembly) + return true; + } + + Error_AttributeEmitError (String.Concat ("SecurityAction '", action, "' is not valid for this declaration")); + return false; + } + + System.Security.Permissions.SecurityAction GetSecurityActionValue () + { + return (SecurityAction)pos_values [0]; + } + + /// <summary> + /// Creates instance of SecurityAttribute class and add result of CreatePermission method to permission table. + /// </summary> + /// <returns></returns> + public void ExtractSecurityPermissionSet (ListDictionary permissions) + { + if (TypeManager.LookupDeclSpace (Type) != null && RootContext.StdLib) { + Error_AttributeEmitError ("security custom attributes can not be referenced from defining assembly"); + return; + } + + SecurityAttribute sa; + // For all assemblies except corlib we can avoid all hacks + if (RootContext.StdLib) { + sa = (SecurityAttribute) Activator.CreateInstance (Type, pos_values); + + if (prop_info_arr != null) { + for (int i = 0; i < prop_info_arr.Length; ++i) { + PropertyInfo pi = prop_info_arr [i]; + pi.SetValue (sa, prop_values_arr [i], null); + } + } + } else { + Type temp_type = Type.GetType (Type.FullName); + // HACK: All mscorlib attributes have same ctor syntax + sa = (SecurityAttribute) Activator.CreateInstance (temp_type, new object[] { GetSecurityActionValue () } ); + + // All types are from newly created corlib but for invocation with old we need to convert them + if (prop_info_arr != null) { + for (int i = 0; i < prop_info_arr.Length; ++i) { + PropertyInfo emited_pi = prop_info_arr [i]; + PropertyInfo pi = temp_type.GetProperty (emited_pi.Name, emited_pi.PropertyType); + + object old_instance = pi.PropertyType.IsEnum ? + System.Enum.ToObject (pi.PropertyType, prop_values_arr [i]) : + prop_values_arr [i]; + + pi.SetValue (sa, old_instance, null); + } + } + } + + IPermission perm = sa.CreatePermission (); + SecurityAction action; + + if (perm.GetType().IsSubclassOf (TypeManager.code_access_permission_type)) { + action = GetSecurityActionValue (); + } else { + switch (GetSecurityActionValue ()) { + case SecurityAction.Demand: + action = (SecurityAction)13; + break; + case SecurityAction.LinkDemand: + action = (SecurityAction)14; + break; + case SecurityAction.InheritanceDemand: + action = (SecurityAction)15; + break; + default: + Error_AttributeEmitError ("Invalid SecurityAction for non-Code Access Security permission"); + return; + } + } + + PermissionSet ps = (PermissionSet)permissions [action]; + if (ps == null) { + ps = new PermissionSet (PermissionState.None); + permissions.Add (action, ps); + } + ps.AddPermission (sa.CreatePermission ()); + } + object GetValue (object value) { Index: class.cs =================================================================== RCS file: /cvsroot/csdoc/csdoc/src/mcs/mcs/class.cs,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** class.cs 6 Oct 2004 19:28:29 -0000 1.1 --- class.cs 29 Oct 2004 13:54:36 -0000 1.2 *************** *** 33,40 **** --- 33,43 ---- using System; using System.Collections; + using System.Collections.Specialized; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; + using System.Security; + using System.Security.Permissions; using System.Text; *************** *** 421,425 **** // The emit context for toplevel objects. EmitContext ec; ! // // Pointers to the default constructor and the default static constructor --- 424,432 ---- // The emit context for toplevel objects. EmitContext ec; ! ! public EmitContext EmitContext { ! get { return ec; } ! } ! // // Pointers to the default constructor and the default static constructor *************** *** 1278,1281 **** --- 1285,1289 ---- part.TypeBuilder = TypeBuilder; part.base_class_type = base_class_type; + part.ec = new EmitContext (part, Mono.CSharp.Location.Null, null, null, ModFlags); } } *************** *** 1311,1318 **** parent_container = TypeManager.LookupMemberContainer (TypeBuilder.BaseType); ! // TODO: ! //if (TypeBuilder.IsInterface) { ! // parent_container = TypeManager.LookupInterfaceContainer (base_inteface_types); ! //} if (IsTopLevel) { --- 1319,1324 ---- parent_container = TypeManager.LookupMemberContainer (TypeBuilder.BaseType); ! if (TypeBuilder.IsInterface) ! parent_container = TypeManager.LookupInterfaceContainer (base_inteface_types); if (IsTopLevel) { *************** *** 1395,1399 **** #if CACHE if (!(this is ClassPart)) ! member_cache = new MemberCache (this); #endif --- 1401,1405 ---- #if CACHE if (!(this is ClassPart)) ! member_cache = new MemberCache (this, false); #endif *************** *** 2587,2590 **** --- 2593,2597 ---- public abstract class ClassOrStruct : TypeContainer { bool hasExplicitLayout = false; + ListDictionary declarative_security; public ClassOrStruct (NamespaceEntry ns, TypeContainer parent, *************** *** 2620,2623 **** --- 2627,2638 ---- public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb) { + if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) { + if (declarative_security == null) + declarative_security = new ListDictionary (); + + a.ExtractSecurityPermissionSet (declarative_security); + return; + } + if (a.Type == TypeManager.struct_layout_attribute_type && (LayoutKind) a.GetPositionalValue (0) == LayoutKind.Explicit) *************** *** 2627,2630 **** --- 2642,2656 ---- } + public override void Emit() + { + base.Emit (); + + if (declarative_security != null) { + foreach (DictionaryEntry de in declarative_security) { + TypeBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value); + } + } + } + public override void Register () { *************** *** 2888,2892 **** public abstract class MethodCore : MemberBase { public readonly Parameters Parameters; ! protected Block block; // --- 2914,2918 ---- public abstract class MethodCore : MemberBase { public readonly Parameters Parameters; ! protected ToplevelBlock block; // *************** *** 2932,2936 **** } ! public Block Block { get { return block; --- 2958,2962 ---- } ! public ToplevelBlock Block { get { return block; *************** *** 2981,2984 **** --- 3007,3021 ---- return false; } + } else { + if (parent_method.IsAbstract && !IsInterface) { + Report.SymbolRelatedToPreviousError (parent_method); + Report.Error (533, Location, "'{0}' hides inherited abstract member", GetSignatureForError (Parent)); + return false; + } + } + + if (parent_method.IsSpecialName && !(this is PropertyBase)) { + Report.Error (561, Location, "'{0}': cannot override '{1}' because it is a special compiler-generated method", GetSignatureForError (Parent), TypeManager.GetFullNameSignature (parent_method)); + return false; } *************** *** 3001,3010 **** } if ((ModFlags & Modifiers.OVERRIDE) != 0) { ! Report.Error (115, Location, "'{0}': no suitable methods found to override", GetSignatureForError (Parent)); return false; } - MemberInfo conflict_symbol = Parent.FindMemberWithSameName (Name, !(this is Property)); if (conflict_symbol == null) { if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) { --- 3038,3054 ---- } + MemberInfo conflict_symbol = Parent.FindMemberWithSameName (Name, !(this is Property)); if ((ModFlags & Modifiers.OVERRIDE) != 0) { ! if (conflict_symbol != null) { ! Report.SymbolRelatedToPreviousError (conflict_symbol); ! if (this is PropertyBase) ! Report.Error (544, Location, "'{0}': cannot override because '{1}' is not a property", GetSignatureForError (Parent), TypeManager.GetFullNameSignature (conflict_symbol)); ! else ! Report.Error (505, Location, "'{0}': cannot override because '{1}' is not a method", GetSignatureForError (Parent), TypeManager.GetFullNameSignature (conflict_symbol)); ! } else ! Report.Error (115, Location, "'{0}': no suitable methods found to override", GetSignatureForError (Parent)); return false; } if (conflict_symbol == null) { if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) { *************** *** 3132,3136 **** if (!IsInterface && (parent_method.IsVirtual || parent_method.IsAbstract)) { if (RootContext.WarningLevel >= 2) ! Report.Warning (114, Location, "'{0}' hides inherited member '{1}'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword", GetSignatureForError (Parent), parent_method); } else Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent)); --- 3176,3180 ---- if (!IsInterface && (parent_method.IsVirtual || parent_method.IsAbstract)) { if (RootContext.WarningLevel >= 2) ! Report.Warning (114, Location, "'{0}' hides inherited member '{1}'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword", GetSignatureForError (Parent), TypeManager.CSharpSignature (parent_method)); } else Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent)); *************** *** 3169,3179 **** protected virtual bool DoDefineParameters () { // Check if arguments were correct ! parameter_types = Parameters.GetParameterInfo (Parent); if ((parameter_types == null) || !CheckParameters (Parent, parameter_types)) return false; ! parameter_info = new InternalParameters (Parent, Parameters); Parameter array_param = Parameters.ArrayParameter; --- 3213,3231 ---- protected virtual bool DoDefineParameters () { + EmitContext ec = Parent.EmitContext; + if (ec == null) + throw new InternalErrorException ("DoDefineParameters invoked too early"); + + bool old_unsafe = ec.InUnsafe; + ec.InUnsafe = InUnsafe; // Check if arguments were correct ! parameter_types = Parameters.GetParameterInfo (ec); ! ec.InUnsafe = old_unsafe; ! if ((parameter_types == null) || !CheckParameters (Parent, parameter_types)) return false; ! parameter_info = new InternalParameters (parameter_types, Parameters); Parameter array_param = Parameters.ArrayParameter; *************** *** 3337,3340 **** --- 3389,3393 ---- public MethodData MethodData; ReturnParameter return_attributes; + ListDictionary declarative_security; /// <summary> *************** *** 3463,3466 **** --- 3516,3526 ---- } + if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) { + if (declarative_security == null) + declarative_security = new ListDictionary (); + a.ExtractSecurityPermissionSet (declarative_security); + return; + } + if (a.Type == TypeManager.conditional_attribute_type) { if (IsOperator || IsExplicitImpl) { *************** *** 3614,3617 **** --- 3674,3684 ---- MethodData.Emit (Parent, this); base.Emit (); + + if (declarative_security != null) { + foreach (DictionaryEntry de in declarative_security) { + MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value); + } + } + Block = null; MethodData = null; *************** *** 3941,3944 **** --- 4008,4012 ---- public ConstructorBuilder ConstructorBuilder; public ConstructorInitializer Initializer; + ListDictionary declarative_security; // <summary> *************** *** 4006,4009 **** --- 4074,4085 ---- public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb) { + if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) { + if (declarative_security == null) { + declarative_security = new ListDictionary (); + } + a.ExtractSecurityPermissionSet (declarative_security); + return; + } + ConstructorBuilder.SetCustomAttribute (cb); } *************** *** 4195,4198 **** --- 4271,4280 ---- base.Emit (); + if (declarative_security != null) { + foreach (DictionaryEntry de in declarative_security) { + ConstructorBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value); + } + } + block = null; } *************** *** 4292,4296 **** Attributes OptAttributes { get; } ! Block Block { get; } EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig); --- 4374,4378 ---- Attributes OptAttributes { get; } ! ToplevelBlock Block { get; } EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig); *************** *** 4527,4531 **** ((MethodCore) member).Parameters.LabelParameters (ec, MethodBuilder, loc); ! Block block = method.Block; // --- 4609,4614 ---- ((MethodCore) member).Parameters.LabelParameters (ec, MethodBuilder, loc); ! SymbolWriter sw = CodeGen.SymbolWriter; ! ToplevelBlock block = method.Block; // *************** *** 4583,4587 **** } ! void EmitDestructor (EmitContext ec, Block block) { ILGenerator ig = ec.ig; --- 4666,4670 ---- } ! void EmitDestructor (EmitContext ec, ToplevelBlock block) { ILGenerator ig = ec.ig; *************** *** 4758,4761 **** --- 4841,4848 ---- protected virtual bool DoDefine () { + EmitContext ec = Parent.EmitContext; + if (ec == null) + throw new InternalErrorException ("MemberBase.DoDefine called too early"); + if (Name == null) throw new InternalErrorException (); *************** *** 4779,4786 **** // Lookup Type, verify validity ! MemberType = Parent.ResolveType (Type, false, Location); ! if (MemberType == null) return false; if ((Parent.ModFlags & Modifiers.SEALED) != 0){ if ((ModFlags & (Modifiers.VIRTUAL|Modifiers.ABSTRACT)) != 0){ --- 4866,4879 ---- // Lookup Type, verify validity ! bool old_unsafe = ec.InUnsafe; ! ec.InUnsafe = InUnsafe; ! Type = Type.ResolveAsTypeTerminal (ec, false); ! ec.InUnsafe = old_unsafe; ! ! if (Type == null) return false; + MemberType = Type.Type; + if ((Parent.ModFlags & Modifiers.SEALED) != 0){ if ((ModFlags & (Modifiers.VIRTUAL|Modifiers.ABSTRACT)) != 0){ *************** *** 4825,4834 **** if (IsExplicitImpl) { ! InterfaceType = Parent.ResolveType ( ! ExplicitInterfaceName.GetTypeExpression (Location), ! false, Location); ! if (InterfaceType == null) return false; if (InterfaceType.IsClass) { Report.Error (538, Location, "'{0}' in explicit interface declaration is not an interface", ExplicitInterfaceName); --- 4918,4928 ---- if (IsExplicitImpl) { ! Expression expr = ExplicitInterfaceName.GetTypeExpression (Location); ! TypeExpr texpr = expr.ResolveAsTypeTerminal (ec, false); ! if (texpr == null) return false; + InterfaceType = texpr.ResolveType (ec); + if (InterfaceType.IsClass) { Report.Error (538, Location, "'{0}' in explicit interface declaration is not an interface", ExplicitInterfaceName); *************** *** 4902,4906 **** [Flags] ! public enum Status : byte { ASSIGNED = 1, USED = 2 } static string[] attribute_targets = new string [] { "field" }; --- 4996,5003 ---- [Flags] ! public enum Status : byte { ! ASSIGNED = 1, ! USED = 2 ! } static string[] attribute_targets = new string [] { "field" }; *************** *** 4941,4945 **** } ! FieldBuilder.SetCustomAttribute (cb); } --- 5038,5046 ---- } ! if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) { ! a.Error_InvalidSecurityParent (); ! return; ! } ! FieldBuilder.SetCustomAttribute (cb); } *************** *** 4955,4958 **** --- 5056,5060 ---- protected readonly Object init; + // Private. Expression init_expr; *************** *** 5089,5097 **** public override bool Define() { ! MemberType = Parent.ResolveType (Type, false, Location); ! ! if (MemberType == null) return false; if (!CheckBase ()) return false; --- 5191,5207 ---- public override bool Define() { ! EmitContext ec = Parent.EmitContext; ! if (ec == null) ! throw new InternalErrorException ("FieldMember.Define called too early"); ! ! bool old_unsafe = ec.InUnsafe; ! ec.InUnsafe = InUnsafe; ! TypeExpr texpr = Type.ResolveAsTypeTerminal (ec, false); ! if (texpr == null) return false; + MemberType = texpr.ResolveType (ec); + ec.InUnsafe = old_unsafe; + if (!CheckBase ()) return false; *************** *** 5245,5253 **** // Null if the accessor is empty, or a Block if not // ! public Block Block; public Attributes Attributes; public Location Location; ! public Accessor (Block b, Attributes attrs, Location loc) { Block = b; --- 5355,5363 ---- // Null if the accessor is empty, or a Block if not // ! public ToplevelBlock Block; public Attributes Attributes; public Location Location; ! public Accessor (ToplevelBlock b, Attributes attrs, Location loc) { Block = b; *************** *** 5262,5266 **** public abstract class AbstractPropertyEventMethod: MemberCore, IMethodData { protected MethodData method_data; ! protected Block block; // The accessor are created event if they are not wanted. --- 5372,5377 ---- public abstract class AbstractPropertyEventMethod: MemberCore, IMethodData { protected MethodData method_data; ! protected ToplevelBlock block; ! protected ListDictionary declarative_security; // The accessor are created event if they are not wanted. *************** *** 5303,5307 **** #region IMethodData Members ! public Block Block { get { return block; --- 5414,5418 ---- #region IMethodData Members ! public ToplevelBlock Block { get { return block; *************** *** 5345,5348 **** --- 5456,5466 ---- } + if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) { + if (declarative_security == null) + declarative_security = new ListDictionary (); + a.ExtractSecurityPermissionSet (declarative_security); + return; + } + if (a.Target == AttributeTargets.Method) { method_data.MethodBuilder.SetCustomAttribute (cb); *************** *** 5374,5377 **** --- 5492,5502 ---- { method_data.Emit (container, this); + + if (declarative_security != null) { + foreach (DictionaryEntry de in declarative_security) { + method_data.MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value); + } + } + block = null; } *************** *** 5489,5503 **** } ! protected virtual InternalParameters GetParameterInfo (TypeContainer container) { Parameter [] parms = new Parameter [1]; parms [0] = new Parameter (method.Type, "value", Parameter.Modifier.NONE, null); ! return new InternalParameters ( ! container, new Parameters (parms, null, method.Location)); } public override MethodBuilder Define(TypeContainer container) { ! method_data = new MethodData (method, GetParameterInfo (container), method.ModFlags, method.flags, this); if (!method_data.Define (container)) --- 5614,5631 ---- } ! protected virtual InternalParameters GetParameterInfo (EmitContext ec) { Parameter [] parms = new Parameter [1]; parms [0] = new Parameter (method.Type, "value", Parameter.Modifier.NONE, null); ! Parameters parameters = new Parameters (parms, null, method.Location); ! Type [] types = parameters.GetParameterInfo (ec); ! return new InternalParameters (types, parameters); } public override MethodBuilder Define(TypeContainer container) { ! if (container.EmitContext == null) ! throw new InternalErrorException ("SetMethod.Define called too early"); ! method_data = new MethodData (method, GetParameterInfo (container.EmitContext), method.ModFlags, method.flags, this); if (!method_data.Define (container)) *************** *** 5613,5616 **** --- 5741,5749 ---- public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb) { + if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) { + a.Error_InvalidSecurityParent (); + return; + } + PropertyBuilder.SetCustomAttribute (cb); } *************** *** 5683,5686 **** --- 5816,5820 ---- } + // TODO: rename to Resolve...... protected override MethodInfo FindOutParentMethod (TypeContainer container, ref Type parent_ret_type) { *************** *** 5692,5703 **** parent_ret_type = parent_property.PropertyType; ! ! MethodInfo temp_m; ! temp_m = parent_property.GetGetMethod (true); ! if (temp_m != null) ! return temp_m; ! ! System.Diagnostics.Debug.Assert (parent_property.GetSetMethod (true) != null, "Internal error property without get/set"); ! return parent_property.GetSetMethod (true); } --- 5826,5845 ---- parent_ret_type = parent_property.PropertyType; ! MethodInfo get_accessor = parent_property.GetGetMethod (true); ! MethodInfo set_accessor = parent_property.GetSetMethod (true); ! ! if ((ModFlags & Modifiers.OVERRIDE) != 0) { ! if (Get != null && !Get.IsDummy && get_accessor == null) { ! Report.SymbolRelatedToPreviousError (parent_property); ! Report.Error (545, Location, "'{0}': cannot override because '{1}' does not have an overridable get accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (parent_property)); ! } ! ! if (Set != null && !Set.IsDummy && set_accessor == null) { ! Report.SymbolRelatedToPreviousError (parent_property); ! Report.Error (546, Location, "'{0}': cannot override because '{1}' does not have an overridable set accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (parent_property)); ! } ! } ! ! return get_accessor != null ? get_accessor : set_accessor; } *************** *** 6259,6262 **** --- 6401,6409 ---- public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb) { + if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) { + a.Error_InvalidSecurityParent (); + return; + } + EventBuilder.SetCustomAttribute (cb); } *************** *** 6293,6300 **** } Parameter [] parms = new Parameter [1]; parms [0] = new Parameter (Type, "value", Parameter.Modifier.NONE, null); ! InternalParameters ip = new InternalParameters ( ! Parent, new Parameters (parms, null, Location)); if (!CheckBase ()) --- 6440,6456 ---- } + EmitContext ec = Parent.EmitContext; + if (ec == null) + throw new InternalErrorException ("Event.Define called too early?"); + bool old_unsafe = ec.InUnsafe; + ec.InUnsafe = InUnsafe; + Parameter [] parms = new Parameter [1]; parms [0] = new Parameter (Type, "value", Parameter.Modifier.NONE, null); ! Parameters parameters = new Parameters (parms, null, Location); ! Type [] types = parameters.GetParameterInfo (ec); ! InternalParameters ip = new InternalParameters (types, parameters); ! ! ec.InUnsafe = old_unsafe; if (!CheckBase ()) *************** *** 6424,6428 **** } ! protected override InternalParameters GetParameterInfo (TypeContainer container) { Parameter [] fixed_parms = parameters.FixedParameters; --- 6580,6584 ---- } ! protected override InternalParameters GetParameterInfo (EmitContext ec) { Parameter [] fixed_parms = parameters.FixedParameters; *************** *** 6451,6456 **** Parameters set_formal_params = new Parameters (tmp, null, method.Location); ! return new InternalParameters (container, set_formal_params); } } --- 6607,6613 ---- Parameters set_formal_params = new Parameters (tmp, null, method.Location); + Type [] types = set_formal_params.GetParameterInfo (ec); ! return new InternalParameters (types, set_formal_params); } } *************** *** 6678,6682 **** public Operator (TypeContainer parent, OpType type, Expression ret_type, int mod_flags, Parameters parameters, ! Block block, Attributes attrs, Location loc) : base (parent, ret_type, mod_flags, AllowedModifiers, false, new MemberName ("op_" + type), attrs, parameters, loc) --- 6835,6839 ---- public Operator (TypeContainer parent, OpType type, Expression ret_type, int mod_flags, Parameters parameters, ! ToplevelBlock block, Attributes attrs, Location loc) : base (parent, ret_type, mod_flags, AllowedModifiers, false, new MemberName ("op_" + type), attrs, parameters, loc) *************** *** 6939,6943 **** { StringBuilder sb = new StringBuilder (); ! sb.AppendFormat ("{0}.operator {1} {2}({3}", tc.Name, GetName (OperatorType), Type.ToString (), Parameters.FixedParameters [0].GetSignatureForError ()); if (Parameters.FixedParameters.Length > 1) { --- 7096,7101 ---- { StringBuilder sb = new StringBuilder (); ! sb.AppendFormat ("{0}.operator {1} {2}({3}", tc.Name, GetName (OperatorType), Type.Type == null ? Type.ToString () : TypeManager.CSharpName (Type.Type), ! Parameters.FixedParameters [0].GetSignatureForError ()); if (Parameters.FixedParameters.Length > 1) { Index: codegen.cs =================================================================== RCS file: /cvsroot/csdoc/csdoc/src/mcs/mcs/codegen.cs,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** codegen.cs 6 Oct 2004 19:28:29 -0000 1.1 --- codegen.cs 29 Oct 2004 13:54:36 -0000 1.2 *************** *** 5,18 **** // Miguel de Icaza (mi...@xi...) // ! // (C) 2001 Ximian, Inc. // ! using System; using System.IO; using System.Collections; using System.Reflection; using System.Reflection.Emit; using System.Runtime.InteropServices; using System.Security.Cryptography; using Mono.Security.Cryptography; --- 5,22 ---- // Miguel de Icaza (mi...@xi...) // ! // (C) 2001, 2002, 2003 Ximian, Inc. ! // (C) 2004 Novell, Inc. // ! //#define PRODUCTION using System; using System.IO; using System.Collections; + using System.Collections.Specialized; using System.Reflection; using System.Reflection.Emit; using System.Runtime.InteropServices; + using System.Security; using System.Security.Cryptography; + using System.Security.Permissions; using Mono.Security.Cryptography; *************** *** 253,257 **** } } ! /// <summary> /// An Emit Context is created for each body of code (from methods, --- 257,261 ---- } } ! /// <summary> /// An Emit Context is created for each body of code (from methods, *************** *** 368,372 **** /// Whether we are inside an anonymous method. /// </summary> ! public bool InAnonymousMethod; /// <summary> --- 372,376 ---- /// Whether we are inside an anonymous method. /// </summary> ! public AnonymousMethod CurrentAnonymousMethod; /// <summary> *************** *** 393,396 **** --- 397,407 ---- /// <summary> + /// Anonymous methods can capture local variables and fields, + /// this object tracks it. It is copied from the TopLevelBlock + /// field. + /// </summary> + public CaptureContext capture_context; + + /// <summary> /// Trace when method is called and is obsolete then this member suppress message /// when call is inside next [Obsolete] method or type. *************** *** 398,405 **** public bool TestObsoleteMethodUsage = true; public Iterator CurrentIterator; ! FlowBranching current_flow_branching; public EmitContext (DeclSpace parent, DeclSpace ds, Location l, ILGenerator ig, Type return_type, int code_flags, bool is_constructor) --- 409,430 ---- public bool TestObsoleteMethodUsage = true; + /// <summary> + /// The current iterator + /// </summary> public Iterator CurrentIterator; ! /// <summary> ! /// Whether we are in the resolving stage or not ! /// </summary> ! enum Phase { ! Created, ! Resolving, ! Emitting ! } + Phase current_phase; + + FlowBranching current_flow_branching; + public EmitContext (DeclSpace parent, DeclSpace ds, Location l, ILGenerator ig, Type return_type, int code_flags, bool is_constructor) *************** *** 411,415 **** CheckState = RootContext.Checked; ConstantCheckState = true; ! IsStatic = (code_flags & Modifiers.STATIC) != 0; InIterator = (code_flags & Modifiers.METHOD_YIELDS) != 0; --- 436,440 ---- CheckState = RootContext.Checked; ConstantCheckState = true; ! IsStatic = (code_flags & Modifiers.STATIC) != 0; InIterator = (code_flags & Modifiers.METHOD_YIELDS) != 0; *************** *** 419,422 **** --- 444,448 ---- CurrentBlock = null; CurrentFile = 0; + current_phase = Phase.Created; if (parent != null){ *************** *** 429,433 **** } loc = l; ! if (ReturnType == TypeManager.void_type) ReturnType = null; --- 455,459 ---- } loc = l; ! if (ReturnType == TypeManager.void_type) ReturnType = null; *************** *** 452,455 **** --- 478,487 ---- } + public bool HaveCaptureInfo { + get { + return capture_context != null; + } + } + // <summary> // Starts a new code branching. This inherits the state of all local *************** *** 518,545 **** } ! public void EmitTopBlock (Block block, InternalParameters ip, Location loc) { ! bool unreachable = false; if (!Location.IsNull (loc)) CurrentFile = loc.File; ! if (block != null){ ! try { int errors = Report.Errors; ! block.EmitMeta (this, ip); if (Report.Errors == errors){ bool old_do_flow_analysis = DoFlowAnalysis; DoFlowAnalysis = true; ! current_flow_branching = FlowBranching.CreateBranching ( ! null, FlowBranching.BranchingType.Block, block, loc); if (!block.Resolve (this)) { current_flow_branching = null; DoFlowAnalysis = old_do_flow_analysis; ! return; } --- 550,688 ---- } ! public void CaptureVariable (LocalInfo li) { ! capture_context.AddLocal (CurrentAnonymousMethod, li); ! li.IsCaptured = true; ! } ! ! public void CaptureParameter (string name, Type t, int idx) ! { ! ! capture_context.AddParameter (this, CurrentAnonymousMethod, name, t, idx); ! } ! ! // ! // Use to register a field as captured ! // ! public void CaptureField (FieldExpr fe) ! { ! capture_context.AddField (fe); ! } ! ! // ! // Whether anonymous methods have captured variables ! // ! public bool HaveCapturedVariables () ! { ! if (capture_context != null) ! return capture_context.HaveCapturedVariables; ! return false; ! } ! ! // ! // Whether anonymous methods have captured fields or this. ! // ! public bool HaveCapturedFields () ! { ! if (capture_context != null) ! return capture_context.HaveCapturedFields; ! return false; ! } + // + // Emits the instance pointer for the host method + // + public void EmitMethodHostInstance (EmitContext target, AnonymousMethod am) + { + if (capture_context != null) + capture_context.EmitMethodHostInstance (target, am); + else if (IsStatic) + target.ig.Emit (OpCodes.Ldnull); + else + target.ig.Emit (OpCodes.Ldarg_0); + } + + // + // Returns whether the `local' variable has been captured by an anonymous + // method + // + public bool IsCaptured (LocalInfo local) + { + return capture_context.IsCaptured (local); + } + + public bool IsParameterCaptured (string name) + { + if (capture_context != null) + return capture_context.IsParameterCaptured (name); + return false; + } + + public void EmitMeta (ToplevelBlock b, InternalParameters ip) + { + if (capture_context != null) + capture_context.EmitHelperClasses (this); + b.EmitMeta (this); + + if (HasReturnLabel) + ReturnLabel = ig.DefineLabel (); + } + + // + // Here until we can fix the problem with Mono.CSharp.Switch, which + // currently can not cope with ig == null during resolve (which must + // be fixed for switch statements to work on anonymous methods). + // + public void EmitTopBlock (ToplevelBlock block, InternalParameters ip, Location loc) + { + if (block == null) + return; + + bool unreachable; + + if (ResolveTopBlock (null, block, ip, loc, out unreachable)){ + EmitMeta (block, ip); + + current_phase = Phase.Emitting; + EmitResolvedTopBlock (block, unreachable); + } + } + + public bool ResolveTopBlock (EmitContext anonymous_method_host, ToplevelBlock block, + InternalParameters ip, Location loc, out bool unreachable) + { + current_phase = Phase.Resolving; + + unreachable = false; + + capture_context = block.CaptureContext; + if (!Location.IsNull (loc)) CurrentFile = loc.File; ! #if PRODUCTION ! try { ! #endif int errors = Report.Errors; ! block.ResolveMeta (block, this, ip); + if (Report.Errors == errors){ bool old_do_flow_analysis = DoFlowAnalysis; DoFlowAnalysis = true; ! if (anonymous_method_host != null) ! current_flow_branching = FlowBranching.CreateBranching ( ! anonymous_method_host.CurrentBranching, FlowBranching.BranchingType.Block, ! block, loc); ! else ! current_flow_branching = FlowBranching.CreateBranching ( ! null, FlowBranching.BranchingType.Block, block, loc); if (!block.Resolve (this)) { current_flow_branching = null; DoFlowAnalysis = old_do_flow_analysis; ! return false; } *************** *** 549,554 **** DoFlowAnalysis = old_do_flow_analysis; - block.Emit (this); - if (reachability.AlwaysReturns || reachability.AlwaysThrows || --- 692,695 ---- *************** *** 556,560 **** unreachable = true; } ! } catch (Exception e) { Console.WriteLine ("Exception caught by the compiler while compiling:"); Console.WriteLine (" Block that caused the problem begin at: " + loc); --- 697,702 ---- unreachable = true; } ! #if PRODUCTION ! } catch (Exception e) { Console.WriteLine ("Exception caught by the compiler while compiling:"); Console.WriteLine (" Block that caused the problem begin at: " + loc); *************** *** 565,583 **** } Console.WriteLine (e.GetType ().FullName + ": " + e.Message); ! Console.WriteLine (Report.FriendlyStackTrace (e)); ! ! Environment.Exit (1); ! } } if (ReturnType != null && !unreachable){ if (!InIterator){ ! Report.Error (161, loc, "Not all code paths return a value"); ! return; } } if (HasReturnLabel) ig.MarkLabel (ReturnLabel); if (return_value != null){ ig.Emit (OpCodes.Ldloc, return_value); --- 707,739 --... [truncated message content] |