using System.Reflection;
using System.Runtime.CompilerServices;
-[assembly: AssemblyVersion("1.1.2")]
+[assembly: AssemblyVersion("1.1.1")]
[assembly: AssemblyTitle ("Mono C# Compiler")]
[assembly: AssemblyDescription ("Mono C# Compiler with Generics")]
[assembly: AssemblyCopyright ("2001, 2002, 2003 Ximian, Inc.")]
-2004-11-07 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (Invocation.OverloadResolve): Flag error if we are
- calling an unsafe method from a safe location.
-
-2004-11-06 Marek Safar <marek.safar@seznam.cz>
-
- Fix #69167
- * codegen.cs (ApplyAttributeBuilder): Do not return; it is only warning.
-
-2004-11-06 Miguel de Icaza <miguel@ximian.com>
-
- * namespace.cs (VerifyUsing): use GetPartialName instead of
- ToString.
-
-2004-11-05 Miguel de Icaza <miguel@ximian.com>
-
- * statement.cs (Return.Resolve): Fix regression in typo: if
- `in_exc', we have to request a NeedReturnLabel, this was a typo
- introduced in the anonymous method check-in. Fixes #69131.
-
- * Indexers were using the ShortName when defining themselves,
- causing a regression in the compiler bootstrap when applying the
- patch from 2004-11-02 (first part), now they use their full name
- and the bug is gone.
-
-2004-11-04 Zoltan Varga <vargaz@freemail.hu>
-
- * driver.cs: Strip the path from the names of embedded resources. Fixes
- #68519.
-
-2004-11-04 Raja R Harinath <rharinath@novell.com>
-
- Fix error message regression: cs0104-2.cs.
- * namespace.cs (NamespaceEntry.Lookup): Remove 'silent' flag.
- (AliasEntry.Resolve): Update.
- * rootcontext.cs (RootContext.NamespaceLookup): Update. Remove
- 'silent' flag.
- (RootContext.LookupType): Update.
-
-2004-11-03 Carlos Alberto Cortez <carlos@unixmexico.org>
-
- * cs-parser.jay: Add support for handling accessor modifiers
- * class: Add support port accessor modifiers and error checking,
- define PropertyMethod.Define as virtual (not abstract anymore)
- * ecore.cs: Add checking for proeprties access with access modifiers
- * iterators.cs: Modify Accessor constructor call based in the modified
- constructor
-2004-11-02 Ben Maurer <bmaurer@ximian.com>
-
- * expression.cs (StringConcat): Handle being called twice,
- as when we have a concat in a field init with more than two
- ctors in the class
-
-2004-11-02 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (Event.Define, Indexer.Define, Property.Define): Do not
- special case explicit implementations, we should always produce
- the .property or .event declaration.
-
- * decl.cs (MemberName): Renamed GetFullName to GetPartialName
- since it will not return correct data if people use this
- unresolved in the presence of using statements (see test-313).
-
- * class.cs (MethodData.Define): If we are an explicit interface
- implementation, set the method name to the full name of the
- interface plus the name of the method.
-
- Notice that using the method.MethodName.GetFullName() does not
- work, as it will only contain the name as declared on the source
- file (it can be a shorthand in the presence of using statements)
- and not the fully qualifed type name, for example:
-
- using System;
-
- class D : ICloneable {
- object ICloneable.Clone () {
- }
- }
-
- Would produce a method called `ICloneable.Clone' instead of
- `System.ICloneable.Clone'.
-
- * namespace.cs (Alias.Resolve): Use GetPartialName.
-
-2004-11-01 Marek Safar <marek.safar@seznam.cz>
-
- * cs-parser.jay: Add error 1055 report.
-
-2004-11-01 Miguel de Icaza <miguel@ximian.com>
-
- * assign.cs (Assign.DoResolve): Only do the transform of
- assignment into a New if the types are compatible, if not, fall
- through and let the implicit code deal with the errors and with
- the necessary conversions.
-
-2004-11-01 Marek Safar <marek.safar@seznam.cz>
-
- * cs-parser.jay: Add error 1031 report.
-
- * cs-tokenizer.cs: Add location for error 1038.
-
-2004-10-31 Marek Safar <marek.safar@seznam.cz>
-
- * cs-parser.jay: Add error 1016 report.
-
-2004-10-31 Marek Safar <marek.safar@seznam.cz>
-
- * cs-parser.jay: Add errors 1575,1611 report.
-
-2004-10-31 Marek Safar <marek.safar@seznam.cz>
-
- * cs-parser.jay: Add error 1001 report.
-
-2004-10-31 Marek Safar <marek.safar@seznam.cz>
-
- Fix #68850
- * attribute.cs (GetMarshal): Add method argument for
- caller identification.
-
- * class.cs, codegen.cs, enum.cs, parameter.cs: Added
- agument for GetMarshal and RuntimeMissingSupport.
-
-2004-10-31 Marek Safar <marek.safar@seznam.cz>
-
- * attribute.cs (ExtractSecurityPermissionSet): Removed
- TypeManager.code_access_permission_type.
-
- * typemanager.cs: Removed TypeManager.code_access_permission_type.
-
-2004-10-27 Miguel de Icaza <miguel@ximian.com>
-
- * 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 <marek.safar@seznam.cz>
-
- 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 <miguel@ximian.com>
-
- * 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 <miguel@ximian.com>
-
- * expression.cs (LocalVariableReference): Move the knowledge about
- the iterators into codegen's EmitCapturedVariableInstance.
-
-2004-10-11 Miguel de Icaza <miguel@ximian.com>
-
- * 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 <miguel@ximian.com>
-
- 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 <marek.safar@seznam.cz>
-
- 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 <marek.safar@seznam.cz>
-
- * class.cs (MethodCore.CheckBase): Add errors 505, 533, 544,
- 561 report.
- (PropertyBase.FindOutParentMethod): Add errors 545, 546 report.
-
-2004-11-10 Martin Baulig <martin@ximian.com>
-
- * expression.cs (Invocation.BetterFunction): If two methods have
- equal parameter types, but only one of them is generic, the
- non-generic one wins.
- (New.DoResolve): Don't set `is_struct' to false if we're a generic
- instance; just use `Type.IsValueType' to determine whether
- something is a struct or not.
- (MemberAccess.DoResolveAsTypeStep): Don't modify the `args' field,
- so we can be called multiple times.
-
-2004-11-10 Martin Baulig <martin@ximian.com>
-
- * generic.cs (TypeParameter.DefineConstraints): New public method.
- (TypeParameter.CheckAccessLevel): Override this and return true.
- (ConstructedType.ResolveType): Renamed to DoResolveType(), don't
- override ResolveType() anymore.
- (ConstructedType.DoResolveAsTypeStep): Call DoResolveType() here.
-
-2004-11-10 Martin Baulig <martin@ximian.com>
-
- * rootcontext.cs (RootContext.LookupType): If we're a nested type,
- call DeclSpace.ResolveNestedType() on it.
-
-2004-11-10 Martin Baulig <martin@ximian.com>
-
- * support.cs (ReflectionParameters.ParameterModifier): If `gpd' is
- non-null, call ParameterModifier() on it.
-
-2004-11-10 Martin Baulig <martin@ximian.com>
-
- * iterators.cs
- (Iterators): Added `current_type' and `this_type' fields.
- (Iterators.DefineIterator): Create a new EmitContext and store it
- in `ec'; compute `this_type'.
-
-2004-11-10 Martin Baulig <martin@ximian.com>
-
- * typemanager.cs
- (TypeManager.IsPrivateAccessible): New public method.
- (Closure.Filter): Use IsPrivateAccessible() instead of IsEqual().
-
-2004-11-10 Martin Baulig <martin@ximian.com>
-
- * class.cs (TypeContainer.DefineType): Call
- TypeBuilder.DefineGenericParameters() before resolving the type
- parameters.
- (MethodData.parent_method): New protected field.
- (MethodData..ctor): Added `MethodInfo parent_method' argument.
- (MethodData.Define): Compute `parent_method'.
-
- * decl.cs
- (MemberCore.GetObsoleteAttribute): Don't create a new EmitContext.
- (MemberCore.GetClsCompliantAttributeValue): Likewise.
- (DeclSpace.ec): New protected field; store the EmitContext here.
- (DeclSpace.EmitContext): New public property.
- (DeclSpace.ResolveType): Un-comment from the [Obsolte] attribute.
- (DeclSpace.ResolveNestedType): New public method.
- (DeclSpace.ResolveTypeExpr): Just call ResolveAsTypeTerminal() here.
- (DeclSpace.NestedAccessible): Added `Type tb' argument.
- (DeclSpace.FamilyAccessible): Likewise.
- (DeclSpace.FindType): Call ResolveNestedType() for nested types.
- (DeclSpace.GetClsCompliantAttributeValue): Don't create a new
- EmitContext.
-
- * delegate.cs (Delegate.Define): Store the EmitContext in the `ec'
- field.
-
- * enum.cs (Enum.Define): Store the EmitContext in the `ec' field.
- (Enum.Emit): Don't create a new EmitContext.
-
-2004-10-18 Martin Baulig <martin@ximian.com>
-
- * 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 <martin@ximian.com>
-
- * 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 Raja R Harinath <rharinath@novell.com>
-
- * class.cs (FieldMember.DoDefine): Reset ec.InUnsafe after doing
- the ResolveType.
-
-2004-10-17 John Luke <john.luke@gmail.com>
-
- * class.cs (Operator.GetSignatureForError): use CSharpName
-
- * parameter.cs (Parameter.GetSignatureForError): Returns
- correct name even if was not defined.
-
-2004-10-13 Raja R Harinath <rharinath@novell.com>
-
- 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 <toshok@ximian.com>
-
- * cs-parser.jay: fix location for try_statement and catch_clause.
-
-2004-10-18 Martin Baulig <martin@ximian.com>
-
- * 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 <john.luke@gmail.com>
-
- * class.cs (Operator.GetSignatureForError): use CSharpName
-
- * parameter.cs (Parameter.GetSignatureForError): Returns
- correct name even if was not defined.
-
-2004-10-13 Raja R Harinath <rharinath@novell.com>
-
- 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 <toshok@ximian.com>
-
- * cs-parser.jay: fix location for try_statement and catch_clause.
-
-2004-10-07 Raja R Harinath <rharinath@novell.com>
-
- 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 <john.luke@gmail.com>
-
- * cs-parser.jay: add location to error CS0175
-
-2004-10-04 Miguel de Icaza <miguel@ximian.com>
-
- * ecore.cs (Expression.Constantity): Add support for turning null
- into a constant.
-
- * const.cs (Const.Define): Allow constants to be reference types
- as long as the value is Null.
-
-2004-10-04 Juraj Skripsky <js@hotfeet.ch>
-
- * namespace.cs (NamespaceEntry.Using): No matter which warning
- level is set, check if this namespace name has already been added.
-
-2004-10-03 Ben Maurer <bmaurer@ximian.com>
-
- * expression.cs: reftype [!=]= null should always use br[true,false].
- # 67410
-
-2004-10-03 Marek Safar <marek.safar@seznam.cz>
-
- Fix #67108
- * attribute.cs: Enum conversion moved to
- GetAttributeArgumentExpression to be applied to the all
- expressions.
-
-2004-10-01 Raja R Harinath <rharinath@novell.com>
-
- Fix #65833, test-300.cs, cs0122-5.cs, cs0122-6.cs.
- * class.c (TypeContainer.DefineType): Flag error if
- base types aren't accessible due to access permissions.
- * decl.cs (DeclSpace.ResolveType): Move logic to
- Expression.ResolveAsTypeTerminal.
- (DeclSpace.ResolveTypeExpr): Thin layer over
- Expression.ResolveAsTypeTerminal.
- (DeclSpace.CheckAccessLevel, DeclSpace.FamilyAccess):
- Refactor code into NestedAccess. Use it.
- (DeclSpace.NestedAccess): New.
- * ecore.cs (Expression.ResolveAsTypeTerminal): Add new
- argument to silence errors. Check access permissions.
- (TypeExpr.DoResolve, TypeExpr.ResolveType): Update.
- * expression.cs (ProbeExpr.DoResolve): Use ResolveAsTypeTerminal.
- (Cast.DoResolve): Likewise.
- (New.DoResolve): Likewise.
- (InvocationOrCast.DoResolve,ResolveStatement): Likewise.
- (TypeOf.DoResolve): Likewise.
-
- * expression.cs (Invocation.BetterConversion): Return the Type of
- the better conversion. Implement section 14.4.2.3 more faithfully.
- (Invocation.BetterFunction): Make boolean. Make correspondence to
- section 14.4.2.2 explicit.
- (Invocation.OverloadResolve): Update.
- (Invocation): Remove is_base field.
- (Invocation.DoResolve): Don't use is_base. Use mg.IsBase.
- (Invocation.Emit): Likewise.
-
-2004-09-24 Marek Safar <marek.safar@seznam.cz>
-
- * cs-parser.jay: Reverted 642 warning fix.
-
-2004-09-23 Marek Safar <marek.safar@seznam.cz>
-
- Fix bug #66615
- * decl.cs (FindMemberWithSameName): Indexer can have more than
- 1 argument.
-
-2004-09-23 Marek Safar <marek.safar@seznam.cz>
-
- * expression.cs (LocalVariableReference.DoResolveLValue):
- Do not report warning 219 for out values.
- (EmptyExpression.Null): New member to avoid extra allocations.
-
-2004-09-23 Marek Safar <marek.safar@seznam.cz>
-
- * cs-parser.jay: Fix wrong warning 642 report.
-
- * cs-tokenizer.cs (CheckNextToken): New helper;
- Inspect next character if is same as expected.
-
-2004-09-23 Martin Baulig <martin@ximian.com>
-
- * convert.cs (Convert.ImplicitReferenceConversion): Some code cleanup.
- (Convert.ImplicitReferenceConversionExists): Likewise.
-
2004-11-09 Raja R Harinath <rharinath@novell.com>
* Makefile (DISTFILES): Comment out a few missing files.
// Author:
// Miguel de Icaza (miguel@ximain.com)
//
-// (C) 2003, 2004 Novell, Inc.
-//
-// TODO: Ideally, we should have the helper classes emited as a hierarchy to map
-// their nesting, and have the visibility set to private, instead of NestedAssembly
-//
-//
+// (C) 2003 Ximian, Inc.
//
using System;
-using System.Text;
using System.Collections;
using System.Reflection;
using System.Reflection.Emit;
namespace Mono.CSharp {
public class AnonymousMethod : Expression {
- // Used to generate unique method names.
- static int anonymous_method_count;
-
// An array list of AnonymousMethodParameter or null
- public Parameters Parameters;
-
- //
- // The block that makes up the body for the anonymous mehtod
- //
- public ToplevelBlock Block;
-
- //
- // The container block for this anonymous method.
- //
- public Block ContainingBlock;
-
- //
- // The implicit method we create
- //
- public Method method;
-
- MethodInfo invoke_mb;
-
- // The emit context for the anonymous method
- public EmitContext aec;
- public InternalParameters amp;
- bool unreachable;
-
- //
- // The modifiers applied to the method, we aggregate them
- //
- int method_modifiers = Modifiers.INTERNAL;
+ Parameters parameters;
+ Block block;
- //
- // During the resolve stage of the anonymous method body,
- // we discover the actual scope where we are hosted, or
- // null to host the method in the same class
- //
- public ScopeInfo Scope;
-
- //
- // Points to our container anonymous method if its present
- //
- public AnonymousMethod ContainerAnonymousMethod;
-
- public AnonymousMethod (Parameters parameters, ToplevelBlock container, ToplevelBlock block, Location l)
+ public AnonymousMethod (Parameters parameters, Block block, Location l)
{
- Parameters = parameters;
- Block = block;
+ this.parameters = parameters;
+ this.block = block;
loc = l;
-
- //
- // The order is important: this setups the CaptureContext tree hierarchy.
- //
- container.SetHaveAnonymousMethods (l, this);
- block.SetHaveAnonymousMethods (l, this);
}
public override Expression DoResolve (EmitContext ec)
// anywhere', we depend on special conversion
// rules.
//
- type = TypeManager.anonymous_method_type;
-
+ type = typeof (AnonymousMethod);
return this;
}
{
// nothing, as we only exist to not do anything.
}
-
- //
- // Creates the host for the anonymous method
- //
- bool CreateMethodHost (EmitContext ec, Type return_type)
- {
- //
- // Crude hack follows: we replace the TypeBuilder during the
- // definition to get the method hosted in the right class
- //
-
- TypeBuilder current_type = ec.TypeContainer.TypeBuilder;
- TypeBuilder type_host = Scope == null ? current_type : Scope.ScopeTypeBuilder;
-
- if (current_type == null)
- throw new Exception ("The current_type is null");
-
- if (type_host == null)
- throw new Exception ("Type host is null");
-
- if (current_type == type_host && ec.IsStatic){
- if (ec.IsStatic)
- method_modifiers |= Modifiers.STATIC;
- current_type = null;
- }
-
- method = new Method (
- (TypeContainer) ec.TypeContainer, null,
- new TypeExpression (return_type, loc),
- method_modifiers, false, new MemberName ("<#AnonymousMethod>" + anonymous_method_count++),
- Parameters, null, loc);
- method.Block = Block;
-
-
- //
- // Swap the TypeBuilder while we define the method, then restore
- //
- if (current_type != null)
- ec.TypeContainer.TypeBuilder = type_host;
- bool res = method.Define ();
- if (current_type != null)
- ec.TypeContainer.TypeBuilder = current_type;
- return res;
- }
-
- void Error_ParameterMismatch (Type t)
- {
- Report.Error (1661, loc, "Anonymous method could not be converted to delegate `" +
- "{0}' since there is a parameter mismatch", t);
- }
-
- //
- // Returns true if this anonymous method can be implicitly
- // converted to the delegate type `delegate_type'
- //
- public Expression Compatible (EmitContext ec, Type delegate_type, bool probe)
- {
- //
- // At this point its the first time we know the return type that is
- // needed for the anonymous method. We create the method here.
- //
-
- MethodGroupExpr invoke_mg = Delegate.GetInvokeMethod (ec, delegate_type, loc);
- invoke_mb = (MethodInfo) invoke_mg.Methods [0];
- ParameterData invoke_pd = Invocation.GetParameterData (invoke_mb);
-
- //
- // If implicit parameters are set, then we must check for out in the parameters
- // and flag it accordingly.
- //
- bool out_invalid_check = false;
-
- if (Parameters == null){
- int i, j;
- out_invalid_check = true;
-
- //
- // We provide a set of inaccessible parameters
- //
- int params_idx = -1;
- for (i = 0; i < invoke_pd.Count; i++){
- if (invoke_pd.ParameterModifier (i) == Parameter.Modifier.PARAMS)
- params_idx = i;
- }
- int n = invoke_pd.Count - (params_idx != -1 ? 1 : 0);
- Parameter [] fixedpars = new Parameter [n];
-
- for (i = j = 0; i < invoke_pd.Count; i++){
- if (invoke_pd.ParameterModifier (i) == Parameter.Modifier.PARAMS)
- continue;
- fixedpars [j] = new Parameter (
- new TypeExpression (invoke_pd.ParameterType (i), loc),
- "+" + j, invoke_pd.ParameterModifier (i), null);
- j++;
- }
-
- Parameter variable = null;
- if (params_idx != -1){
- variable = new Parameter (
- new TypeExpression (invoke_pd.ParameterType (params_idx), loc),
- "+" + params_idx, invoke_pd.ParameterModifier (params_idx), null);
- }
-
- Parameters = new Parameters (fixedpars, variable, loc);
- }
-
- //
- // First, parameter types of `delegate_type' must be compatible
- // with the anonymous method.
- //
- amp = new InternalParameters (Parameters.GetParameterInfo (ec), Parameters);
-
- if (amp.Count != invoke_pd.Count){
- if (!probe){
- Report.Error (1593, loc,
- "Anonymous method has {0} parameters, while delegate requires {1}",
- amp.Count, invoke_pd.Count);
- Error_ParameterMismatch (delegate_type);
- }
- return null;
- }
-
- for (int i = 0; i < amp.Count; i++){
- Parameter.Modifier amp_mod = amp.ParameterModifier (i);
- if (amp_mod != invoke_pd.ParameterModifier (i)){
- if (!probe){
- Report.Error (1676, loc,
- "Signature mismatch in parameter modifier for parameter #0", i + 1);
- Error_ParameterMismatch (delegate_type);
- }
- return null;
- }
-
- if (amp.ParameterType (i) != invoke_pd.ParameterType (i)){
- if (!probe){
- Report.Error (1678, loc,
- "Signature mismatch in parameter {0}: need `{1}' got `{2}'", i + 1,
- TypeManager.CSharpName (invoke_pd.ParameterType (i)),
- TypeManager.CSharpName (amp.ParameterType (i)));
- Error_ParameterMismatch (delegate_type);
- }
- return null;
- }
-
- if (out_invalid_check && (invoke_pd.ParameterModifier (i) & Parameter.Modifier.OUT) != 0){
- if (!probe){
- Report.Error (1676, loc,"Parameter {0} must include the `out' modifier ", i+1);
- Error_ParameterMismatch (delegate_type);
- }
- return null;
- }
- }
-
- //
- // If we are only probing, return ourselves
- //
- if (probe)
- return this;
-
- //
- // Second: the return type of the delegate must be compatible with
- // the anonymous type. Instead of doing a pass to examine the block
- // we satisfy the rule by setting the return type on the EmitContext
- // to be the delegate type return type.
- //
-
- //MethodBuilder builder = method_data.MethodBuilder;
- //ILGenerator ig = builder.GetILGenerator ();
-
-
- aec = new EmitContext (
- ec.TypeContainer, ec.DeclSpace, loc, null,
- invoke_mb.ReturnType,
- /* REVIEW */ (ec.InIterator ? Modifiers.METHOD_YIELDS : 0) |
- (ec.InUnsafe ? Modifiers.UNSAFE : 0),
- /* No constructor */ false);
-
- aec.CurrentAnonymousMethod = this;
- ContainerAnonymousMethod = ec.CurrentAnonymousMethod;
- ContainingBlock = ec.CurrentBlock;
-
- if (aec.ResolveTopBlock (ec, Block, amp, loc, out unreachable))
- return new AnonymousDelegate (this, delegate_type, loc).Resolve (ec);
-
- return null;
- }
-
- public MethodBuilder GetMethodBuilder ()
- {
- return method.MethodData.MethodBuilder;
- }
-
- public void EmitMethod (EmitContext ec)
- {
- if (!CreateMethodHost (ec, invoke_mb.ReturnType))
- return;
-
- MethodBuilder builder = GetMethodBuilder ();
- ILGenerator ig = builder.GetILGenerator ();
- aec.ig = ig;
-
- Parameters.LabelParameters (aec, builder, loc);
-
- //
- // Adjust based on the computed state of the
- // method from CreateMethodHost
-
- if ((method_modifiers & Modifiers.STATIC) != 0)
- aec.IsStatic = true;
-
- aec.EmitMeta (Block, amp);
- aec.EmitResolvedTopBlock (Block, unreachable);
- }
- }
-
- //
- // This will emit the code for the delegate, as well delegate creation on the host
- //
- public class AnonymousDelegate : DelegateCreation {
- AnonymousMethod am;
-
- public AnonymousDelegate (AnonymousMethod am, Type target_type, Location l)
- {
- type = target_type;
- loc = l;
- this.am = am;
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- eclass = ExprClass.Value;
- return this;
- }
-
- public override void Emit (EmitContext ec)
- {
- am.EmitMethod (ec);
-
- //
- // Now emit the delegate creation.
- //
- if ((am.method.ModFlags & Modifiers.STATIC) == 0)
- delegate_instance_expression = new AnonymousInstance (am);
-
- Expression ml = Expression.MemberLookup (ec, type, ".ctor", loc);
- constructor_method = ((MethodGroupExpr) ml).Methods [0];
- delegate_method = am.GetMethodBuilder ();
- base.Emit (ec);
- }
-
- class AnonymousInstance : Expression {
- AnonymousMethod am;
-
- public AnonymousInstance (AnonymousMethod am)
- {
- this.am = am;
- eclass = ExprClass.Value;
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- return this;
- }
-
- public override void Emit (EmitContext ec)
- {
- am.aec.EmitMethodHostInstance (ec, am);
- }
- }
- }
-
- class CapturedParameter {
- public Type Type;
- public FieldBuilder FieldBuilder;
- public int Idx;
-
- public CapturedParameter (Type type, int idx)
- {
- Type = type;
- Idx = idx;
- }
}
-
- //
- // Here we cluster all the variables captured on a given scope, we also
- // keep some extra information that might be required on each scope.
- //
- public class ScopeInfo {
- public CaptureContext CaptureContext;
- public ScopeInfo ParentScope;
- public Block ScopeBlock;
- public bool NeedThis = false;
- public bool HostsParameters = false;
-
- // For tracking the number of scopes created.
- public int id;
- static int count;
- bool inited = false;
-
- ArrayList locals = new ArrayList ();
- ArrayList children = new ArrayList ();
-
- //
- // The types and fields generated
- //
- public TypeBuilder ScopeTypeBuilder;
- public ConstructorBuilder ScopeConstructor;
- public FieldBuilder THIS;
- public FieldBuilder ParentLink;
-
- //
- // Points to the object of type `ScopeTypeBuilder' that
- // holds the data for the scope
- //
- public LocalBuilder ScopeInstance;
-
-
- public ScopeInfo (CaptureContext cc, Block b)
- {
- CaptureContext = cc;
- ScopeBlock = b;
- id = count++;
-
- cc.AddScope (this);
- }
-
- public void AddLocal (LocalInfo li)
- {
- if (locals.Contains (li))
- return;
-
- locals.Add (li);
}
- public bool IsCaptured (LocalInfo li)
- {
- return locals.Contains (li);
- }
-
- public void AddChild (ScopeInfo si)
- {
- if (children.Contains (si))
- return;
- children.Add (si);
- }
-
- static int indent = 0;
-
- void Pad ()
- {
- for (int i = 0; i < indent; i++)
- Console.Write (" ");
- }
-
- void EmitDebug ()
- {
- //Console.WriteLine (Environment.StackTrace);
- Pad ();
- Console.WriteLine ("START");
- indent++;
- Pad ();
- Console.WriteLine ("NeedThis=" + NeedThis);
- foreach (LocalInfo li in locals){
- Pad ();
- Console.WriteLine ("var {0}", li.Name);
- }
-
- foreach (ScopeInfo si in children)
- si.EmitDebug ();
- indent--;
- Pad ();
- Console.WriteLine ("END");
- }
-
- public string MakeHelperName ()
- {
- return String.Format ("<>AnonHelp<{0}>", id);
- }
-
- public void EmitScopeConstructor ()
- {
- Type [] constructor_types = TypeManager.NoTypes;
- Parameters constructor_parameters = Parameters.EmptyReadOnlyParameters;
- ScopeConstructor = ScopeTypeBuilder.DefineConstructor (
- MethodAttributes.Public | MethodAttributes.HideBySig |
- MethodAttributes.SpecialName | MethodAttributes.RTSpecialName,
- CallingConventions.HasThis, constructor_types);
- InternalParameters parameter_info = new InternalParameters (constructor_types, constructor_parameters);
- TypeManager.RegisterMethod (ScopeConstructor, parameter_info, constructor_types);
-
- ILGenerator cig = ScopeConstructor.GetILGenerator ();
- cig.Emit (OpCodes.Ldarg_0);
- cig.Emit (OpCodes.Call, TypeManager.object_ctor);
- cig.Emit (OpCodes.Ret);
- }
-
- public void EmitScopeType (EmitContext ec)
- {
- //EmitDebug ();
-
- if (ScopeTypeBuilder != null)
- return;
-
- ILGenerator ig = ec.ig;
- TypeBuilder container = ec.TypeContainer.TypeBuilder;
-
- ScopeTypeBuilder = container.DefineNestedType (
- MakeHelperName (), TypeAttributes.AutoLayout | TypeAttributes.Class | TypeAttributes.NestedAssembly,
- TypeManager.object_type, null);
-
- if (NeedThis)
- THIS = ScopeTypeBuilder.DefineField ("<>THIS", container, FieldAttributes.Assembly);
-
- if (ParentScope != null){
- if (ParentScope.ScopeTypeBuilder == null){
- throw new Exception (String.Format ("My parent has not been initialized {0} and {1}", ParentScope, this));
- }
-
- ParentLink = ScopeTypeBuilder.DefineField ("<>parent", ParentScope.ScopeTypeBuilder,
- FieldAttributes.Assembly);
- }
-
- if (NeedThis && ParentScope != null)
- throw new Exception ("I was not expecting THIS && having a parent");
-
- foreach (LocalInfo info in locals){
- info.FieldBuilder = ScopeTypeBuilder.DefineField (
- info.Name, info.VariableType, FieldAttributes.Assembly);
- }
-
- if (HostsParameters){
- Hashtable captured_parameters = CaptureContext.captured_parameters;
-
- foreach (DictionaryEntry de in captured_parameters){
- string name = (string) de.Key;
- CapturedParameter cp = (CapturedParameter) de.Value;
- FieldBuilder fb;
-
- fb = ScopeTypeBuilder.DefineField ("<p:" + name + ">", cp.Type, FieldAttributes.Assembly);
- cp.FieldBuilder = fb;
- }
- }
-
- EmitScopeConstructor ();
- foreach (ScopeInfo si in children){
- si.EmitScopeType (ec);
- }
- }
-
- public void CloseTypes ()
- {
- RootContext.RegisterHelperClass (ScopeTypeBuilder);
- foreach (ScopeInfo si in children)
- si.CloseTypes ();
- }
-
- //
- // Emits the initialization code for the scope
- //
- public void EmitInitScope (EmitContext ec)
- {
- ILGenerator ig = ec.ig;
-
- if (inited)
- return;
-
- ig.Emit (OpCodes.Newobj, (ConstructorInfo) ScopeConstructor);
- ScopeInstance = ig.DeclareLocal (ScopeTypeBuilder);
- ig.Emit (OpCodes.Stloc, ScopeInstance);
-
- if (THIS != null){
- ig.Emit (OpCodes.Ldloc, ScopeInstance);
- ig.Emit (OpCodes.Ldarg_0);
- ig.Emit (OpCodes.Stfld, THIS);
- }
-
- //
- // Copy the parameter values, if any
- //
- int extra = ec.IsStatic ? 0 : 1;
- if (HostsParameters){
- Hashtable captured_parameters = CaptureContext.captured_parameters;
-
- foreach (DictionaryEntry de in captured_parameters){
- string name = (string) de.Key;
- CapturedParameter cp = (CapturedParameter) de.Value;
-
- ig.Emit (OpCodes.Ldloc, ScopeInstance);
- ParameterReference.EmitLdArg (ig, cp.Idx + extra);
- ig.Emit (OpCodes.Stfld, cp.FieldBuilder);
- }
- }
-
- if (ParentScope != null){
- //
- // Only emit initialization in our capturecontext world
- //
- if (ParentScope.CaptureContext == CaptureContext){
- ig.Emit (OpCodes.Ldloc, ScopeInstance);
- ig.Emit (OpCodes.Ldloc, ParentScope.ScopeInstance);
- ig.Emit (OpCodes.Stfld, ParentLink);
- } else {
- ig.Emit (OpCodes.Ldloc, ScopeInstance);
- ig.Emit (OpCodes.Ldarg_0);
- ig.Emit (OpCodes.Stfld, ParentLink);
- }
- }
- inited = true;
- }
-
- static void DoPath (StringBuilder sb, ScopeInfo start)
- {
- if (start.ParentScope != null){
- DoPath (sb, start.ParentScope);
- sb.Append (", ");
- }
- sb.Append ((start.id).ToString ());
- }
-
- public override string ToString ()
- {
- StringBuilder sb = new StringBuilder ();
-
- sb.Append ("{");
- if (CaptureContext != null){
- sb.Append (CaptureContext.ToString ());
- sb.Append (":");
- }
-
- DoPath (sb, this);
- sb.Append ("}");
-
- return sb.ToString ();
- }
- }
-
- //
- // CaptureContext objects are created on demand if a method has
- // anonymous methods and kept on the ToplevelBlock.
- //
- // If they exist, all ToplevelBlocks in the containing block are
- // linked together (children pointing to their parents).
- //
- public class CaptureContext {
- public static int count;
- public int cc_id;
- Location loc;
-
- //
- // Points to the toplevel block that owns this CaptureContext
- //
- ToplevelBlock toplevel_owner;
- Hashtable scopes = new Hashtable ();
- bool have_captured_vars = false;
- ScopeInfo topmost = null;
-
- //
- // Captured fields
- //
- Hashtable captured_fields = new Hashtable ();
- Hashtable captured_variables = new Hashtable ();
- public Hashtable captured_parameters = new Hashtable ();
- public AnonymousMethod Host;
-
- public CaptureContext (ToplevelBlock toplevel_owner, Location loc, AnonymousMethod host)
- {
- cc_id = count++;
- this.toplevel_owner = toplevel_owner;
- this.loc = loc;
-
- if (host != null)
- Host = host;
- }
-
- void DoPath (StringBuilder sb, CaptureContext cc)
- {
- if (cc.ParentCaptureContext != null){
- DoPath (sb, cc.ParentCaptureContext);
- sb.Append (".");
- }
- sb.Append (cc_id.ToString ());
- }
-
- public override string ToString ()
- {
- ToplevelBlock parent = ParentToplevel;
- StringBuilder sb = new StringBuilder ();
-
- sb.Append ("[");
- DoPath (sb, this);
- sb.Append ("]");
- return sb.ToString ();
- }
-
- public ToplevelBlock ParentToplevel {
- get {
- return toplevel_owner.Container;
- }
- }
-
- public CaptureContext ParentCaptureContext {
- get {
- ToplevelBlock parent = ParentToplevel;
-
- return (parent == null) ? null : parent.CaptureContext;
- }
- }
-
- // Returns the deepest of two scopes
- public ScopeInfo Deepest (ScopeInfo a, ScopeInfo b)
- {
- ScopeInfo p;
-
- if (a == null)
- return b;
- if (b == null)
- return a;
- if (a == b)
- return a;
-
- //
- // If they Scopes are on the same CaptureContext, we do the double
- // checks just so if there is an invariant change in the future,
- // we get the exception at the end
- //
- for (p = a; p != null; p = p.ParentScope)
- if (p == b)
- return a;
-
- for (p = b; p != null; p = p.ParentScope)
- if (p == a)
- return b;
-
- CaptureContext ca = a.CaptureContext;
- CaptureContext cb = b.CaptureContext;
-
- for (CaptureContext c = ca; c != null; c = c.ParentCaptureContext)
- if (c == cb)
- return a;
-
- for (CaptureContext c = cb; c != null; c = c.ParentCaptureContext)
- if (c == ca)
- return b;
- throw new Exception ("Should never be reached");
- }
-
- void AdjustMethodScope (AnonymousMethod am, ScopeInfo scope)
- {
- am.Scope = Deepest (am.Scope, scope);
- }
-
- void LinkScope (ScopeInfo scope, int id)
- {
- ScopeInfo parent = (ScopeInfo) scopes [id];
- scope.ParentScope = parent;
- parent.AddChild (scope);
-
- if (scope == topmost)
- topmost = parent;
- }
-
- public void AddLocal (AnonymousMethod am, LocalInfo li)
- {
- if (li.Block.Toplevel != toplevel_owner){
- ParentCaptureContext.AddLocal (am, li);
- return;
- }
- int block_id = li.Block.ID;
- ScopeInfo scope;
- if (scopes [block_id] == null){
- scope = new ScopeInfo (this, li.Block);
- scopes [block_id] = scope;
- } else
- scope = (ScopeInfo) scopes [block_id];
-
- if (topmost == null){
- topmost = scope;
- } else {
- // Link to parent
- for (Block b = scope.ScopeBlock.Parent; b != null; b = b.Parent){
- if (scopes [b.ID] != null){
- LinkScope (scope, b.ID);
- break;
- }
- }
-
- if (scope.ParentScope == null && ParentCaptureContext != null){
- CaptureContext pcc = ParentCaptureContext;
-
- for (Block b = am.ContainingBlock; b != null; b = b.Parent){
- if (pcc.scopes [b.ID] != null){
- pcc.LinkScope (scope, b.ID);
- break;
- }
- }
- }
- }
-
- //
- // Adjust the owner
- //
- if (Host != null)
- AdjustMethodScope (Host, topmost);
-
- //
- // Adjust the user
- //
- AdjustMethodScope (am, scope);
-
- if (captured_variables [li] != null)
- return;
-
- have_captured_vars = true;
- captured_variables [li] = li;
- scope.AddLocal (li);
- }
-
- //
- // Retursn the CaptureContext for the block that defines the parameter `name'
- //
- static CaptureContext _ContextForParameter (ToplevelBlock current, string name)
- {
- ToplevelBlock container = current.Container;
- if (container != null){
- CaptureContext cc = _ContextForParameter (container, name);
- if (cc != null)
- return cc;
- }
- if (current.IsParameterReference (name))
- return current.ToplevelBlockCaptureContext;
- return null;
- }
-
- static CaptureContext ContextForParameter (ToplevelBlock current, string name)
- {
- CaptureContext cc = _ContextForParameter (current, name);
- if (cc == null)
- throw new Exception (String.Format ("request for parameteter {0} failed: not found", name));
- return cc;
- }
-
- //
- // Records the captured parameter at the appropriate CaptureContext
- //
- public void AddParameter (EmitContext ec, AnonymousMethod am, string name, Type t, int idx)
- {
- CaptureContext cc = ContextForParameter (ec.CurrentBlock.Toplevel, name);
-
- cc.AddParameterToContext (am, name, t, idx);
- }
-
- //
- // Records the parameters in the context
- //
- void AddParameterToContext (AnonymousMethod am, string name, Type t, int idx)
- {
- if (captured_parameters == null)
- captured_parameters = new Hashtable ();
- if (captured_parameters [name] != null)
- return;
- captured_parameters [name] = new CapturedParameter (t, idx);
-
- if (topmost == null){
- //
- // Create one ScopeInfo, if there are none.
- //
- topmost = new ScopeInfo (this, toplevel_owner);
- scopes [toplevel_owner.ID] = topmost;
- } else {
- //
- // If the topmost ScopeInfo is not at the topblock level, insert
- // a new ScopeInfo there.
- //
- if (topmost.ScopeBlock != toplevel_owner){
- ScopeInfo par_si = new ScopeInfo (this, toplevel_owner);
- scopes [toplevel_owner.ID] = topmost;
- topmost.ParentScope = par_si;
- topmost = par_si;
- }
- }
-
- topmost.HostsParameters = true;
- AdjustMethodScope (am, topmost);
- }
-
- //
- // Captured fields are only recorded on the topmost CaptureContext, because that
- // one is the one linked to the owner of instance fields
- //
- public void AddField (FieldExpr fe)
- {
- if (fe.FieldInfo.IsStatic)
- throw new Exception ("Attempt to register a static field as a captured field");
-
- CaptureContext parent = ParentCaptureContext;
- if (parent != null)
- parent.AddField (fe);
- else
- captured_fields [fe] = fe;
- }
-
-
- public bool HaveCapturedVariables {
- get {
- return have_captured_vars;
- }
- }
-
- public bool HaveCapturedFields {
- get {
- CaptureContext parent = ParentCaptureContext;
- if (parent != null)
- return parent.HaveCapturedFields;
- return captured_fields.Count > 0;
- }
- }
-
- public bool IsCaptured (LocalInfo local)
- {
- foreach (ScopeInfo si in scopes.Values){
- if (si.IsCaptured (local))
- return true;
- }
- return false;
- }
-
- //
- // Returns whether the parameter is captured
- //
- public bool IsParameterCaptured (string name)
- {
- if (ParentCaptureContext != null && ParentCaptureContext.IsParameterCaptured (name))
- return true;
-
- if (captured_parameters != null)
- return captured_parameters [name] != null;
- return false;
- }
-
- public void EmitHelperClasses (EmitContext ec)
- {
- if (topmost != null){
- topmost.NeedThis = HaveCapturedFields;
- topmost.EmitScopeType (ec);
- }
- }
-
- public void CloseHelperClasses ()
- {
- if (topmost != null)
- topmost.CloseTypes ();
- }
-
- ScopeInfo GetScopeFromBlock (EmitContext ec, Block b)
- {
- ScopeInfo si;
-
- si = (ScopeInfo) scopes [b.ID];
- if (si == null)
- throw new Exception ("Si is null for block " + b.ID);
- si.EmitInitScope (ec);
-
- return si;
- }
-
- //
- // Emits the opcodes necessary to load the instance of the captured
- // variable in `li'
- //
- public void EmitCapturedVariableInstance (EmitContext ec, LocalInfo li, AnonymousMethod am)
- {
- ILGenerator ig = ec.ig;
- ScopeInfo si;
-
- if (li.Block.Toplevel == toplevel_owner){
- si = GetScopeFromBlock (ec, li.Block);
- ig.Emit (OpCodes.Ldloc, si.ScopeInstance);
- return;
- }
-
- si = am.Scope;
- ig.Emit (OpCodes.Ldarg_0);
- if (si != null){
- while (si.ScopeBlock.ID != li.Block.ID){
- if (si.ParentLink != null)
- ig.Emit (OpCodes.Ldfld, si.ParentLink);
- si = si.ParentScope;
- if (si == null)
- throw new Exception (
- String.Format ("Never found block {0} starting at {1} while looking up {2}",
- li.Block.ID, am.Scope.ScopeBlock.ID, li.Name));
- }
- }
- }
-
- //
- // Internal routine that loads the instance to reach parameter `name'
- //
- void EmitParameterInstance (EmitContext ec, string name)
- {
- CaptureContext cc = ContextForParameter (ec.CurrentBlock.Toplevel, name);
- if (cc != this){
- cc.EmitParameterInstance (ec, name);
- return;
- }
- Block invocation_block = ec.CurrentBlock;
- CapturedParameter par_info = (CapturedParameter) captured_parameters [name];
- ILGenerator ig = ec.ig;
-
- ScopeInfo si;
- if (ec.CurrentBlock == toplevel_owner){
- si = GetScopeFromBlock (ec, toplevel_owner);
- ig.Emit (OpCodes.Ldloc, si.ScopeInstance);
- return;
- }
-
- si = ec.CurrentAnonymousMethod.Scope;
- ig.Emit (OpCodes.Ldarg_0);
- if (si != null){
- while (si.ParentLink != null) {
- ig.Emit (OpCodes.Ldfld, si.ParentLink);
- si = si.ParentScope;
- }
- }
- }
-
- //
- // Emits the code necessary to load the parameter named `name' within
- // an anonymous method.
- //
- public void EmitParameter (EmitContext ec, string name)
- {
- CaptureContext cc = ContextForParameter (ec.CurrentBlock.Toplevel, name);
- if (cc != this){
- cc.EmitParameter (ec, name);
- return;
- }
- EmitParameterInstance (ec, name);
- CapturedParameter par_info = (CapturedParameter) captured_parameters [name];
- ec.ig.Emit (OpCodes.Ldfld, par_info.FieldBuilder);
- }
-
- //
- // Implements the assignment of `source' to the paramenter named `name' within
- // an anonymous method.
- //
- public void EmitAssignParameter (EmitContext ec, string name, Expression source, bool leave_copy, bool prepare_for_load)
- {
- CaptureContext cc = ContextForParameter (ec.CurrentBlock.Toplevel, name);
- if (cc != this){
- cc.EmitAssignParameter (ec, name, source, leave_copy, prepare_for_load);
- return;
- }
- ILGenerator ig = ec.ig;
- CapturedParameter par_info = (CapturedParameter) captured_parameters [name];
-
- EmitParameterInstance (ec, name);
- source.Emit (ec);
- if (leave_copy)
- ig.Emit (OpCodes.Dup);
- ig.Emit (OpCodes.Stfld, par_info.FieldBuilder);
- }
-
- //
- // Emits the address for the parameter named `name' within
- // an anonymous method.
- //
- public void EmitAddressOfParameter (EmitContext ec, string name)
- {
- CaptureContext cc = ContextForParameter (ec.CurrentBlock.Toplevel, name);
- if (cc != this){
- cc.EmitAddressOfParameter (ec, name);
- return;
- }
- EmitParameterInstance (ec, name);
- CapturedParameter par_info = (CapturedParameter) captured_parameters [name];
- ec.ig.Emit (OpCodes.Ldflda, par_info.FieldBuilder);
- }
-
- //
- // The following methods are only invoked on the host for the
- // anonymous method.
- //
- public void EmitMethodHostInstance (EmitContext target, AnonymousMethod am)
- {
- ILGenerator ig = target.ig;
- ScopeInfo si = am.Scope;
-
- if (si == null){
- ig.Emit (OpCodes.Ldarg_0);
- return;
- }
-
- si.EmitInitScope (target);
- ig.Emit (OpCodes.Ldloc, si.ScopeInstance);
- }
-
- ArrayList all_scopes = new ArrayList ();
-
- public void AddScope (ScopeInfo si)
- {
- all_scopes.Add (si);
- toplevel_owner.RegisterCaptureContext (this);
- }
-
- //
- // Links any scopes that were not linked previously
- //
- public void AdjustScopes ()
- {
- foreach (ScopeInfo scope in all_scopes){
- if (scope.ParentScope != null)
- continue;
-
- for (Block b = scope.ScopeBlock.Parent; b != null; b = b.Parent){
- 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;
- }
- }
- }
- }
- }
- }
-}
return null;
}
+ if (source is New && target_type.IsValueType &&
+ (target.eclass != ExprClass.IndexerAccess) && (target.eclass != ExprClass.PropertyAccess)){
+ New n = (New) source;
+
+ if (n.SetValueTypeVariable (target))
+ return n;
+ else
+ return null;
+ }
+
if ((source.eclass == ExprClass.Type) && (source is TypeExpr)) {
source.Error_UnexpectedKind ("variable or value", loc);
return null;
}
- if (target_type == source_type){
- if (source is New && target_type.IsValueType &&
- (target.eclass != ExprClass.IndexerAccess) && (target.eclass != ExprClass.PropertyAccess)){
- New n = (New) source;
-
- if (n.SetValueTypeVariable (target))
- return n;
- else
- return null;
- }
-
+ if (target_type == source_type)
return this;
- }
-
+
//
// If this assignemnt/operator was part of a compound binary
// operator, then we allow an explicit conversion, as detailed
// 2. and the original right side is implicitly convertible to
// the type of target
//
- if (Convert.ImplicitStandardConversionExists (ec, a.original_source, target_type))
+ if (Convert.ImplicitStandardConversionExists (a.original_source, target_type))
return this;
//
using System.Reflection.Emit;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
-using System.Security;
-using System.Security.Permissions;
using System.Text;
namespace Mono.CSharp {
-202, loc, "Can not use a type parameter in an attribute");
}
- /// <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 ()
{
Report.Error (-6, Location,
public static bool GetAttributeArgumentExpression (Expression e, Location loc, Type arg_type, out object result)
{
if (e is EnumConstant) {
- if (RootContext.StdLib)
- result = ((EnumConstant)e).GetValueAsEnumType ();
- else
- result = ((EnumConstant)e).GetValue ();
-
+ result = e;
return true;
}
}
pos_values = new object [pos_arg_count];
+ object[] real_pos_values = new object [pos_arg_count];
//
// First process positional arguments
if (!GetAttributeArgumentExpression (e, Location, a.Type, out val))
return null;
- pos_values [i] = val;
+ if (val is EnumConstant) {
+ EnumConstant econst = (EnumConstant) e;
+
+ pos_values [i] = val = econst.GetValue ();
+ real_pos_values [i] = econst.GetValueAsEnumType ();
+ } else {
+ real_pos_values [i] = pos_values [i] = val;
+ }
if (DoCompares){
- if (usage_attr) {
- usage_attribute = new AttributeUsageAttribute ((AttributeTargets)val);
- } else if (MethodImplAttr) {
+ if (usage_attr)
+ usage_attribute = new AttributeUsageAttribute ((AttributeTargets) val);
+ else if (MethodImplAttr)
this.ImplOptions = (MethodImplOptions) val;
- } else if (GuidAttr){
+ else if (GuidAttr){
//
// we will later check the validity of the type
//
continue;
if (j == group_in_params_array){
- object v = pos_values [j];
+ object v = real_pos_values [j];
int count = pos_arg_count - j;
object [] array = new object [count];
- pos_values [j] = array;
+ real_pos_values [j] = array;
array [0] = v;
} else {
- object [] array = (object []) pos_values [group_in_params_array];
+ object [] array = (object []) real_pos_values [group_in_params_array];
- array [j - group_in_params_array] = pos_values [j];
+ array [j - group_in_params_array] = real_pos_values [j];
}
}
object [] new_pos_values = new object [argc];
for (int p = 0; p < argc; p++)
- new_pos_values [p] = pos_values [p];
- pos_values = new_pos_values;
+ new_pos_values [p] = real_pos_values [p];
+ real_pos_values = new_pos_values;
}
try {
prop_infos.CopyTo (prop_info_arr, 0);
cb = new CustomAttributeBuilder (
- (ConstructorInfo) constructor, pos_values,
+ (ConstructorInfo) constructor, real_pos_values,
prop_info_arr, prop_values_arr,
field_info_arr, field_values_arr);
}
else
cb = new CustomAttributeBuilder (
- (ConstructorInfo) constructor, pos_values);
+ (ConstructorInfo) constructor, real_pos_values);
} catch (NullReferenceException) {
//
// Don't know what to do here
return (bool)pos_values [0];
}
- /// <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;
-
- // IS is correct because for corlib we are using an instance from old corlib
- if (perm is System.Security.CodeAccessPermission) {
- 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)
{
if (value is EnumConstant)
return null;
}
- public UnmanagedMarshal GetMarshal (Attributable attr)
+ public UnmanagedMarshal GetMarshal ()
{
- object value = GetFieldValue ("SizeParamIndex");
- if (value != null && UnmanagedType != UnmanagedType.LPArray) {
- Error_AttributeEmitError ("SizeParamIndex field is not valid for the specified unmanaged type");
- return null;
- }
-
object o = GetFieldValue ("ArraySubType");
UnmanagedType array_sub_type = o == null ? UnmanagedType.I4 : (UnmanagedType) o;
case UnmanagedType.CustomMarshaler:
MethodInfo define_custom = typeof (UnmanagedMarshal).GetMethod ("DefineCustom",
BindingFlags.Static | BindingFlags.Public);
- if (define_custom == null) {
- Report.RuntimeMissingSupport (Location, "set marshal info");
+ if (define_custom == null)
return null;
- }
object [] args = new object [4];
args [0] = GetFieldValue ("MarshalTypeRef");
return UnmanagedMarshal.DefineSafeArray (array_sub_type);
case UnmanagedType.ByValArray:
- FieldMember fm = attr as FieldMember;
- if (fm == null) {
- Error_AttributeEmitError ("Specified unmanaged type is only valid on fields");
- return null;
- }
return UnmanagedMarshal.DefineByValArray ((int) GetFieldValue ("SizeConst"));
case UnmanagedType.ByValTStr:
using System;
using System.Text;
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 Mono.CompilerServices.SymbolWriter;
// Holds the parts of a partial class;
ArrayList parts;
+ // The emit context for toplevel objects.
+ EmitContext ec;
+
//
// Pointers to the default constructor and the default static constructor
//
}
}
catch (ArgumentException) {
- Report.RuntimeMissingSupport (Location, "static classes");
+ Report.RuntimeMissingSupport ("static classes");
return null;
}
TypeManager.AddUserType (Name, TypeBuilder, this);
if (IsGeneric) {
- string[] param_names = new string [TypeParameters.Length];
- for (int i = 0; i < TypeParameters.Length; i++)
- param_names [i] = TypeParameters [i].Name;
-
- GenericTypeParameterBuilder[] gen_params;
- gen_params = TypeBuilder.DefineGenericParameters (param_names);
-
int offset = CountTypeParameters - CurrentTypeParameters.Length;
- for (int i = offset; i < gen_params.Length; i++)
- CurrentTypeParameters [i - offset].Define (gen_params [i]);
-
foreach (TypeParameter type_param in CurrentTypeParameters) {
if (!type_param.Resolve (this)) {
error = true;
}
}
- for (int i = offset; i < gen_params.Length; i++)
- CurrentTypeParameters [i - offset].DefineConstraints ();
+ CurrentType = new ConstructedType (
+ Name, TypeParameters, Location);
+
+ string[] param_names = new string [TypeParameters.Length];
+ for (int i = 0; i < TypeParameters.Length; i++)
+ param_names [i] = TypeParameters [i].Name;
+
+ GenericTypeParameterBuilder[] gen_params;
+
+ gen_params = TypeBuilder.DefineGenericParameters (param_names);
- CurrentType = new ConstructedType (Name, TypeParameters, Location);
+ for (int i = offset; i < gen_params.Length; i++)
+ CurrentTypeParameters [i - offset].Define (gen_params [i]);
}
if (IsGeneric) {
foreach (ClassPart part in Parts) {
part.TypeBuilder = TypeBuilder;
part.parent_type = parent_type;
- part.ec = new EmitContext (part, Mono.CSharp.Location.Null, null, null, ModFlags);
}
}
if (TypeBuilder.BaseType != null)
parent_container = TypeManager.LookupMemberContainer (TypeBuilder.BaseType);
- if (TypeBuilder.IsInterface)
- parent_container = TypeManager.LookupInterfaceContainer (ifaces);
+ // TODO:
+ //if (TypeBuilder.IsInterface) {
+ // parent_container = TypeManager.LookupInterfaceContainer (base_inteface_types);
+ //}
if (IsTopLevel) {
if ((ModFlags & Modifiers.NEW) != 0)
#if CACHE
if (!(this is ClassPart))
- member_cache = new MemberCache (this, false);
+ member_cache = new MemberCache (this);
#endif
if (parts != null) {
public abstract class ClassOrStruct : TypeContainer {
bool hasExplicitLayout = false;
- ListDictionary declarative_security;
public ClassOrStruct (NamespaceEntry ns, TypeContainer parent,
MemberName name, Attributes attrs, Kind kind,
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)
hasExplicitLayout = true;
base.ApplyAttributeBuilder (a, cb);
}
- 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 ()
{
Parent.AddClassOrStruct (this);
public readonly Parameters Parameters;
public readonly GenericMethod GenericMethod;
public readonly DeclSpace ds;
- protected ToplevelBlock block;
+ protected Block block;
//
// Parameters, cached for semantic analysis.
}
}
- public ToplevelBlock Block {
+ public Block Block {
get {
return block;
}
"change return type when overriding inherited member");
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;
}
if (RootContext.WarningLevel > 2) {
return true;
}
- 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));
+ 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)) {
Report.Warning (109, Location, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError (Parent));
Report.SymbolRelatedToPreviousError (parent_method);
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));
+ 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));
}
protected virtual bool DoDefineParameters ()
{
- EmitContext ec = ds.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;
-
+ parameter_types = Parameters.GetParameterInfo (ds);
if ((parameter_types == null) ||
!CheckParameters (ds, parameter_types))
return false;
TypeParameter[] tparam = ds.IsGeneric ? ds.TypeParameters : null;
- parameter_info = new InternalParameters (parameter_types, Parameters, tparam);
+ parameter_info = new InternalParameters (ds, Parameters, tparam);
Parameter array_param = Parameters.ArrayParameter;
if ((array_param != null) &&
public MethodBuilder MethodBuilder;
public MethodData MethodData;
ReturnParameter return_attributes;
- ListDictionary declarative_security;
/// <summary>
/// Modifiers allowed in a class declaration
return;
}
- 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) {
Report.Error (577, Location, "Conditional not valid on '{0}' because it is a destructor, operator, or explicit interface implementation", GetSignatureForError ());
if (GenericMethod != null) {
string mname = MemberName.GetMethodName ();
mb = Parent.TypeBuilder.DefineGenericMethod (mname, flags);
- if (!GenericMethod.Define (mb, ReturnType))
+ if (!GenericMethod.Define (mb))
return false;
}
flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
MethodData = new MethodData (this, ParameterInfo, ModFlags, flags,
- this, mb, GenericMethod, parent_method);
+ this, mb, GenericMethod);
if (!MethodData.Define (Parent))
return false;
{
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;
}
public class Constructor : MethodCore, IMethodData {
public ConstructorBuilder ConstructorBuilder;
public ConstructorInitializer Initializer;
- ListDictionary declarative_security;
// <summary>
// Modifiers allowed for a constructor.
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);
}
base.Emit ();
- if (declarative_security != null) {
- foreach (DictionaryEntry de in declarative_security) {
- ConstructorBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
- }
- }
-
block = null;
}
GenericMethod GenericMethod { get; }
Attributes OptAttributes { get; }
- ToplevelBlock Block { get; }
+ Block Block { get; }
EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig);
ObsoleteAttribute GetObsoleteAttribute ();
protected int modifiers;
protected MethodAttributes flags;
protected Type declaring_type;
- protected MethodInfo parent_method;
EmitContext ec;
public MethodData (MemberBase member, InternalParameters parameters,
int modifiers, MethodAttributes flags,
IMethodData method, MethodBuilder builder,
- GenericMethod generic, MethodInfo parent_method)
+ GenericMethod generic)
: this (member, parameters, modifiers, flags, method)
{
this.builder = builder;
this.GenericMethod = generic;
- this.parent_method = parent_method;
}
static string RemoveArity (string name)
implementing = container.Pending.IsInterfaceMethod (
member.InterfaceType, name, method.ReturnType, ParameterTypes);
- if (member.InterfaceType != null){
- if (implementing == null){
- Report.Error (539, method.Location,
- "'{0}' in explicit interface declaration is not an interface", method_name);
+ if (member.InterfaceType != null && implementing == null){
+ Report.Error (539, method.Location, "'{0}' in explicit interface declaration is not an interface", method_name);
return false;
}
- method_name = member.InterfaceType.FullName + "." + name;
- }
}
//
bool is_override = member.IsExplicitImpl |
((modifiers & Modifiers.OVERRIDE) != 0);
- if (implementing != null)
- parent_method = implementing;
+ is_override &= IsImplementing;
- if (!GenericMethod.DefineType (ec, builder, parent_method, is_override))
+ if (!GenericMethod.DefineType (
+ ec, builder, implementing, is_override))
return false;
}
if (member is MethodCore)
((MethodCore) member).Parameters.LabelParameters (ec, MethodBuilder, loc);
- SymbolWriter sw = CodeGen.SymbolWriter;
- ToplevelBlock block = method.Block;
+ Block block = method.Block;
//
// abstract or extern methods have no bodies
source.CloseMethod ();
}
- void EmitDestructor (EmitContext ec, ToplevelBlock block)
+ void EmitDestructor (EmitContext ec, Block block)
{
ILGenerator ig = ec.ig;
protected virtual bool DoDefineBase ()
{
- EmitContext ec = Parent.EmitContext;
- if (ec == null)
- throw new InternalErrorException ("MemberBase.DoDefine called too early");
-
if (Name == null)
throw new InternalErrorException ();
protected virtual bool DoDefine (DeclSpace decl)
{
- EmitContext ec = decl.EmitContext;
- if (ec == null)
- throw new InternalErrorException ("MemberBase.DoDefine called too early");
-
- ec.InUnsafe = InUnsafe;
-
// Lookup Type, verify validity
- bool old_unsafe = ec.InUnsafe;
- ec.InUnsafe = InUnsafe;
- TypeExpr texpr = Type.ResolveAsTypeTerminal (ec, false);
- ec.InUnsafe = old_unsafe;
-
- if (texpr == null)
- return false;
-
- MemberType = texpr.ResolveType (ec);
+ MemberType = decl.ResolveType (Type, false, Location);
if (MemberType == null)
return false;
return false;
if (IsExplicitImpl) {
- Expression expr = ExplicitInterfaceName.GetTypeExpression (Location);
- TypeExpr iface_texpr = expr.ResolveAsTypeTerminal (ec, false);
- if (iface_texpr == null)
- return false;
+ Expression iface_expr = ExplicitInterfaceName.GetTypeExpression (Location);
- InterfaceType = iface_texpr.ResolveType (ec);
+ InterfaceType = Parent.ResolveType (iface_expr, false, Location);
if (InterfaceType == null)
return false;
public Status status;
[Flags]
- public enum Status : byte {
- ASSIGNED = 1,
- USED = 2
- }
+ public enum Status : byte { ASSIGNED = 1, USED = 2 }
static string[] attribute_targets = new string [] { "field" };
public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
{
if (a.Type == TypeManager.marshal_as_attr_type) {
- UnmanagedMarshal marshal = a.GetMarshal (this);
+ UnmanagedMarshal marshal = a.GetMarshal ();
if (marshal != null) {
FieldBuilder.SetMarshal (marshal);
+ return;
}
+ Report.Warning (-24, a.Location, "The Microsoft Runtime cannot set this marshal info. Please use the Mono runtime instead.");
return;
}
- if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
- a.Error_InvalidSecurityParent ();
- return;
- }
FieldBuilder.SetCustomAttribute (cb);
}
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;
+ MemberType = Parent.ResolveType (Type, false, Location);
+
if (MemberType == null)
return false;
if (!CheckBase ())
return false;
-
+
if (!Parent.AsAccessible (MemberType, ModFlags)) {
Report.Error (52, Location,
- "Inconsistent accessibility: field type `" +
- TypeManager.CSharpName (MemberType) + "' is less " +
- "accessible than field `" + Name + "'");
+ "Inconsistent accessibility: field type `" +
+ TypeManager.CSharpName (MemberType) + "' is less " +
+ "accessible than field `" + Name + "'");
return false;
}
//
// Null if the accessor is empty, or a Block if not
//
- public const int AllowedModifiers =
- Modifiers.PUBLIC |
- Modifiers.PROTECTED |
- Modifiers.INTERNAL |
- Modifiers.PRIVATE;
-
- public ToplevelBlock Block;
+ public Block Block;
public Attributes Attributes;
public Location Location;
- public int ModFlags;
- public Accessor (ToplevelBlock b, int mod, Attributes attrs, Location loc)
+ public Accessor (Block b, Attributes attrs, Location loc)
{
Block = b;
Attributes = attrs;
Location = loc;
- ModFlags = Modifiers.Check (AllowedModifiers, mod, 0, loc);
}
}
// When it will be possible move here a lot of child code and template method type.
public abstract class AbstractPropertyEventMethod: MemberCore, IMethodData {
protected MethodData method_data;
- protected ToplevelBlock block;
- protected ListDictionary declarative_security;
+ protected Block block;
// The accessor are created event if they are not wanted.
// But we need them because their names are reserved.
#region IMethodData Members
- public ToplevelBlock Block {
+ public Block Block {
get {
return block;
}
return;
}
- 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);
return;
public virtual void Emit (TypeContainer container)
{
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;
}
public override MethodBuilder Define(TypeContainer container)
{
- base.Define (container);
-
- method_data = new MethodData (method, method.ParameterInfo, ModFlags, flags, this);
+ method_data = new MethodData (method, method.ParameterInfo, method.ModFlags, method.flags, this);
if (!method_data.Define (container))
return null;
base.ApplyAttributeBuilder (a, cb);
}
- protected virtual InternalParameters GetParameterInfo (EmitContext ec)
+ protected virtual InternalParameters GetParameterInfo (TypeContainer container)
{
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);
+ return new InternalParameters (
+ container, new Parameters (parms, null, method.Location));
}
public override MethodBuilder Define(TypeContainer container)
{
- if (container.EmitContext == null)
- throw new InternalErrorException ("SetMethod.Define called too early");
-
- base.Define (container);
-
- method_data = new MethodData (method, GetParameterInfo (container.EmitContext), ModFlags, flags, this);
+ method_data = new MethodData (method, GetParameterInfo (container), method.ModFlags, method.flags, this);
if (!method_data.Define (container))
return null;
public abstract class PropertyMethod: AbstractPropertyEventMethod {
protected readonly MethodCore method;
- protected MethodAttributes flags;
public PropertyMethod (MethodCore method, string prefix)
: base (method, prefix)
: base (method, accessor, prefix)
{
this.method = method;
- this.ModFlags = accessor.ModFlags;
-
- if (accessor.ModFlags != 0 && RootContext.Version == LanguageVersion.ISO_1) {
- Report.FeatureIsNotStandardized (Location, "accessor modifiers");
- Environment.Exit (1);
- }
}
public override AttributeTargets AttributeTargets {
}
}
- public virtual MethodBuilder Define (TypeContainer container)
- {
- //
- // Check for custom access modifier
- //
- if (ModFlags == 0) {
- ModFlags = method.ModFlags;
- flags = method.flags;
- } else {
- CheckModifiers (container, ModFlags);
- ModFlags |= (method.ModFlags & (~Modifiers.Accessibility));
- flags = Modifiers.MethodAttr (ModFlags);
- flags |= (method.flags & (~MethodAttributes.MemberAccessMask));
- }
-
- return null;
-
- }
+ public abstract MethodBuilder Define (TypeContainer container);
public override Type[] ParameterTypes {
get {
{
return String.Concat (tc.Name, '.', method.Name);
}
-
- void CheckModifiers (TypeContainer container, int modflags)
- {
- int flags = 0;
- int mflags = method.ModFlags & Modifiers.Accessibility;
-
- if ((mflags & Modifiers.PUBLIC) != 0) {
- flags |= Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE;
- }
- else if ((mflags & Modifiers.PROTECTED) != 0) {
- if ((mflags & Modifiers.INTERNAL) != 0)
- flags |= Modifiers.PROTECTED | Modifiers.INTERNAL;
-
- flags |= Modifiers.PRIVATE;
- }
- else if ((mflags & Modifiers.INTERNAL) != 0)
- flags |= Modifiers.PRIVATE;
-
- if ((mflags == modflags) || (modflags & (~flags)) != 0)
- Report.Error (273, Location, "{0}: accessibility modifier must be more restrictive than the property or indexer",
- GetSignatureForError (container));
- }
- }
+ }
public PropertyMethod Get, Set;
public PropertyBuilder PropertyBuilder;
public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
{
- if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
- a.Error_InvalidSecurityParent ();
- return;
- }
-
PropertyBuilder.SetCustomAttribute (cb);
}
if (!base.DoDefine (ds))
return false;
- //
- // Accessors modifiers check
- //
- if (Get.ModFlags != 0 && Set.ModFlags != 0) {
- Report.Error (274, Location, "'{0}': cannot specify accessibility modifiers for both accessors of the property or indexer.",
- GetSignatureForError ());
- return false;
- }
-
- if ((Get.IsDummy || Set.IsDummy)
- && (Get.ModFlags != 0 || Set.ModFlags != 0) && (ModFlags & Modifiers.OVERRIDE) == 0) {
- Report.Error (276, Location,
- "'{0}': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor.",
- GetSignatureForError ());
- return false;
- }
-
if (MemberType.IsAbstract && MemberType.IsSealed) {
Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
return false;
return true;
}
- // TODO: rename to Resolve......
protected override MethodInfo FindOutParentMethod (TypeContainer container, ref Type parent_ret_type)
{
PropertyInfo parent_property = container.ParentContainer.MemberCache.FindMemberToOverride (
return null;
parent_ret_type = parent_property.PropertyType;
- MethodInfo get_accessor = parent_property.GetGetMethod (true);
- MethodInfo set_accessor = parent_property.GetSetMethod (true);
- MethodAttributes get_accessor_access, set_accessor_access;
-
- 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));
- }
- }
-
- //
- // Check parent accessors access
- //
- get_accessor_access = set_accessor_access = 0;
- if ((ModFlags & Modifiers.NEW) == 0) {
- if (get_accessor != null) {
- MethodAttributes get_flags = Modifiers.MethodAttr (Get.ModFlags != 0 ? Get.ModFlags : ModFlags);
- get_accessor_access = (get_accessor.Attributes & MethodAttributes.MemberAccessMask);
-
- if (!Get.IsDummy && (get_accessor_access) !=
- (get_flags & MethodAttributes.MemberAccessMask))
- Report.Error (507, Location, "'{0}' can't change the access modifiers when overriding inherited member '{1}'",
- GetSignatureForError (), TypeManager.GetFullNameSignature (parent_property));
- }
- if (set_accessor != null) {
- MethodAttributes set_flags = Modifiers.MethodAttr (Set.ModFlags != 0 ? Set.ModFlags : ModFlags);
- set_accessor_access = (set_accessor.Attributes & MethodAttributes.MemberAccessMask);
-
- if (!Set.IsDummy & (set_accessor_access) !=
- (set_flags & MethodAttributes.MemberAccessMask))
- Report.Error (507, Location, "'{0}' can't change the access modifiers when overriding inherited member '{1}'",
- GetSignatureForError (container), TypeManager.GetFullNameSignature (parent_property));
- }
- }
+ MethodInfo temp_m;
+ temp_m = parent_property.GetGetMethod (true);
+ if (temp_m != null)
+ return temp_m;
- //
- // Get the less restrictive access
- //
- return get_accessor_access > set_accessor_access ? get_accessor : set_accessor;
+ System.Diagnostics.Debug.Assert (parent_property.GetSetMethod (true) != null, "Internal error property without get/set");
+ return parent_property.GetSetMethod (true);
}
public override void Emit ()
prop_attr |= PropertyAttributes.RTSpecialName |
PropertyAttributes.SpecialName;
- PropertyBuilder = Parent.TypeBuilder.DefineProperty (
- Name, prop_attr, MemberType, null);
+ if (!IsExplicitImpl){
+ PropertyBuilder = Parent.TypeBuilder.DefineProperty (
+ Name, prop_attr, MemberType, null);
- if (!Get.IsDummy)
- PropertyBuilder.SetGetMethod (GetBuilder);
+ if (!Get.IsDummy)
+ PropertyBuilder.SetGetMethod (GetBuilder);
- if (!Set.IsDummy)
- PropertyBuilder.SetSetMethod (SetBuilder);
+ if (!Set.IsDummy)
+ PropertyBuilder.SetSetMethod (SetBuilder);
- TypeManager.RegisterProperty (PropertyBuilder, GetBuilder, SetBuilder);
+ TypeManager.RegisterProperty (PropertyBuilder, GetBuilder, SetBuilder);
+ }
return true;
}
public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
{
- if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
- a.Error_InvalidSecurityParent ();
- return;
- }
-
EventBuilder.SetCustomAttribute (cb);
}
{
EventAttributes e_attr;
e_attr = EventAttributes.None;
-
+;
if (!DoDefineBase ())
return false;
return false;
}
- 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;
+ InternalParameters ip = new InternalParameters (
+ Parent, new Parameters (parms, null, Location));
if (!CheckBase ())
return false;
if (RemoveBuilder == null)
return false;
- EventBuilder = new MyEventBuilder (this, Parent.TypeBuilder, Name, e_attr, MemberType);
+ if (!IsExplicitImpl){
+ EventBuilder = new MyEventBuilder (this,
+ Parent.TypeBuilder, Name, e_attr, MemberType);
- if (Add.Block == null && Remove.Block == null && !IsInterface) {
+ if (Add.Block == null && Remove.Block == null &&
+ !IsInterface) {
FieldBuilder = Parent.TypeBuilder.DefineField (
Name, MemberType,
FieldAttributes.Private | ((ModFlags & Modifiers.STATIC) != 0 ? FieldAttributes.Static : 0));
EventBuilder.SetRemoveOnMethod (RemoveBuilder);
TypeManager.RegisterEvent (EventBuilder, AddBuilder, RemoveBuilder);
+ }
+
return true;
}
}
}
- protected override InternalParameters GetParameterInfo (EmitContext ec)
+ protected override InternalParameters GetParameterInfo (TypeContainer container)
{
Parameter [] fixed_parms = parameters.FixedParameters;
method.Type, "value", Parameter.Modifier.NONE, null);
Parameters set_formal_params = new Parameters (tmp, null, method.Location);
- Type [] types = set_formal_params.GetParameterInfo (ec);
- return new InternalParameters (types, set_formal_params);
+ return new InternalParameters (container, set_formal_params);
}
+
}
+
const int AllowedModifiers =
Modifiers.NEW |
Modifiers.PUBLIC |
ShortName = indexer_attr.GetIndexerAttributeValue (ec);
if (IsExplicitImpl) {
- Report.Error (415, indexer_attr.Location,
- "The 'IndexerName' attribute is valid only on an" +
- "indexer that is not an explicit interface member declaration");
+ Report.Error (415, indexer_attr.Location, "The 'IndexerName' attribute is valid only on an indexer that is not an explicit interface member declaration");
return false;
}
if ((ModFlags & Modifiers.OVERRIDE) != 0) {
- Report.Error (609, indexer_attr.Location,
- "Cannot set the 'IndexerName' attribute on an indexer marked override");
+ Report.Error (609, indexer_attr.Location, "Cannot set the 'IndexerName' attribute on an indexer marked override");
return false;
}
if (!Tokenizer.IsValidIdentifier (ShortName)) {
- Report.Error (633, indexer_attr.Location,
- "The argument to the 'IndexerName' attribute must be a valid identifier");
+ Report.Error (633, indexer_attr.Location, "The argument to the 'IndexerName' attribute must be a valid identifier");
return false;
}
}
}
+ //
+ // Define the PropertyBuilder if one of the following conditions are met:
+ // a) we're not implementing an interface indexer.
+ // b) the indexer has a different IndexerName and this is no
+ // explicit interface implementation.
+ //
+ if (!IsExplicitImpl) {
PropertyBuilder = Parent.TypeBuilder.DefineProperty (
- Name, prop_attr, MemberType, ParameterTypes);
+ ShortName, prop_attr, MemberType, ParameterTypes);
if (!Get.IsDummy)
PropertyBuilder.SetGetMethod (GetBuilder);
if (!Set.IsDummy)
PropertyBuilder.SetSetMethod (SetBuilder);
- TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder, ParameterTypes);
+ TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder,
+ ParameterTypes);
+ }
return true;
}
public Operator (TypeContainer parent, OpType type, Expression ret_type,
int mod_flags, Parameters parameters,
- ToplevelBlock block, Attributes attrs, Location loc)
+ Block block, Attributes attrs, Location loc)
: base (parent, null, ret_type, mod_flags, AllowedModifiers, false,
new MemberName ("op_" + type), attrs, parameters, loc)
{
public override string GetSignatureForError (TypeContainer tc)
{
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 ());
+ sb.AppendFormat ("{0}.operator {1} {2}({3}", tc.Name, GetName (OperatorType), Type.ToString (), Parameters.FixedParameters [0].GetSignatureForError ());
if (Parameters.FixedParameters.Length > 1) {
sb.Append (",");
// Author:
// Miguel de Icaza (miguel@ximian.com)
//
-// (C) 2001, 2002, 2003 Ximian, Inc.
-// (C) 2004 Novell, Inc.
+// (C) 2001 Ximian, 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;
/// <summary>
/// Whether we are inside an anonymous method.
/// </summary>
- public AnonymousMethod CurrentAnonymousMethod;
+ public bool InAnonymousMethod;
/// <summary>
/// Location for this EmitContext
/// </summary>
public bool InEnumContext;
- /// <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.
/// </summary>
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,
IsConstructor = is_constructor;
CurrentBlock = null;
CurrentFile = 0;
- current_phase = Phase.Created;
if (parent != null){
// Can only be null for the ResolveType contexts.
}
}
- public bool HaveCaptureInfo {
- get {
- return capture_context != null;
- }
- }
-
// <summary>
// Starts a new code branching. This inherits the state of all local
// variables and parameters from the current branching.
current_flow_branching = current_flow_branching.Parent;
}
- public void CaptureVariable (LocalInfo li)
+ public void EmitTopBlock (Block block, InternalParameters ip, Location loc)
{
- 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;
+ bool unreachable = false;
if (!Location.IsNull (loc))
CurrentFile = loc.File;
-#if PRODUCTION
- try {
-#endif
+ if (block != null){
+ try {
int errors = Report.Errors;
- block.ResolveMeta (block, this, ip);
-
+ block.EmitMeta (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;
+ return;
}
FlowBranching.Reachability reachability = current_flow_branching.MergeTopBlock ();
DoFlowAnalysis = old_do_flow_analysis;
+ block.Emit (this);
+
if (reachability.AlwaysReturns ||
reachability.AlwaysThrows ||
reachability.IsUnreachable)
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);
-
- if (CurrentBlock != null){
- Console.WriteLine (" Block being compiled: [{0},{1}]",
- CurrentBlock.StartLocation, CurrentBlock.EndLocation);
- }
- Console.WriteLine (e.GetType ().FullName + ": " + e.Message);
- throw;
- }
+#if FIXME
+ } catch (Exception e) {
+ Console.WriteLine ("Exception caught by the compiler while compiling:");
+ Console.WriteLine (" Block that caused the problem begin at: " + loc);
+
+ if (CurrentBlock != null){
+ Console.WriteLine (" Block being compiled: [{0},{1}]",
+ CurrentBlock.StartLocation, CurrentBlock.EndLocation);
+ }
+ Console.WriteLine (e.GetType ().FullName + ": " + e.Message);
+ Console.WriteLine (Report.FriendlyStackTrace (e));
+
+ Environment.Exit (1);
+#else
+ } finally {
#endif
+ }
+ }
if (ReturnType != null && !unreachable){
if (!InIterator){
- if (CurrentAnonymousMethod != null){
- Report.Error (1643, loc, "Not all code paths return a value in anonymous method of type `{0}'",
- CurrentAnonymousMethod.Type);
- } else {
- Report.Error (161, loc, "Not all code paths return a value");
- }
-
- return false;
+ Report.Error (161, loc, "Not all code paths return a value");
+ return;
}
}
- block.CompleteContexts ();
-
- return true;
- }
-
- public void EmitResolvedTopBlock (ToplevelBlock block, bool unreachable)
- {
- if (block != null)
- block.Emit (this);
if (HasReturnLabel)
ig.MarkLabel (ReturnLabel);
-
if (return_value != null){
ig.Emit (OpCodes.Ldloc, return_value);
ig.Emit (OpCodes.Ret);
ig.Emit (OpCodes.Ret);
}
}
-
- //
- // Close pending helper classes if we are the toplevel
- //
- if (capture_context != null && capture_context.ParentToplevel == null)
- capture_context.CloseHelperClasses ();
}
/// <summary>
/// return value from the function. By default this is not
/// used. This is only required when returns are found inside
/// Try or Catch statements.
- ///
- /// This method is typically invoked from the Emit phase, so
- /// we allow the creation of a return label if it was not
- /// requested during the resolution phase. Could be cleaned
- /// up, but it would replicate a lot of logic in the Emit phase
- /// of the code that uses it.
/// </summary>
public LocalBuilder TemporaryReturn ()
{
if (return_value == null){
return_value = ig.DeclareLocal (ReturnType);
- if (!HasReturnLabel){
ReturnLabel = ig.DefineLabel ();
HasReturnLabel = true;
}
- }
return return_value;
}
- /// <summary>
- /// This method is used during the Resolution phase to flag the
- /// need to define the ReturnLabel
- /// </summary>
public void NeedReturnLabel ()
{
- if (current_phase != Phase.Resolving){
- //
- // The reason is that the `ReturnLabel' is declared between
- // resolution and emission
- //
- throw new Exception ("NeedReturnLabel called from Emit phase, should only be called during Resolve");
- }
-
- if (!InIterator && !HasReturnLabel)
+ if (!InIterator && !HasReturnLabel) {
+ ReturnLabel = ig.DefineLabel ();
HasReturnLabel = true;
+ }
}
//
throw new Exception ("MapVariable for an unknown state");
}
+ //
+ // Invoke this routine to remap a VariableInfo into the
+ // proper MemberAccess expression
+ //
+ public Expression RemapLocal (LocalInfo local_info)
+ {
+ FieldExpr fe = new FieldExpr (local_info.FieldBuilder, loc);
+ fe.InstanceExpression = new ProxyInstance ();
+ return fe.DoResolve (this);
+ }
+
+ public Expression RemapLocalLValue (LocalInfo local_info, Expression right_side)
+ {
+ FieldExpr fe = new FieldExpr (local_info.FieldBuilder, loc);
+ fe.InstanceExpression = new ProxyInstance ();
+ return fe.DoResolveLValue (this, right_side);
+ }
+
public Expression RemapParameter (int idx)
{
FieldExpr fe = new FieldExprNoAddress (CurrentIterator.parameter_fields [idx].FieldBuilder, loc);
public void EmitThis ()
{
ig.Emit (OpCodes.Ldarg_0);
- if (InIterator){
- if (!IsStatic){
+ if (InIterator && !IsStatic){
FieldBuilder this_field = CurrentIterator.this_field.FieldBuilder;
if (TypeManager.IsValueType (this_field.FieldType))
ig.Emit (OpCodes.Ldflda, this_field);
else
ig.Emit (OpCodes.Ldfld, this_field);
}
- } else if (capture_context != null && CurrentAnonymousMethod != null){
- ScopeInfo si = CurrentAnonymousMethod.Scope;
- while (si != null){
- if (si.ParentLink != null)
- ig.Emit (OpCodes.Ldfld, si.ParentLink);
- if (si.THIS != null){
- ig.Emit (OpCodes.Ldfld, si.THIS);
- break;
- }
- si = si.ParentScope;
- }
- }
- }
-
- //
- // Emits the code necessary to load the instance required
- // to access the captured LocalInfo
- //
- public void EmitCapturedVariableInstance (LocalInfo li)
- {
- if (RemapToProxy){
- ig.Emit (OpCodes.Ldarg_0);
- return;
- }
-
- if (capture_context == null)
- throw new Exception ("Calling EmitCapturedContext when there is no capture_context");
-
- capture_context.EmitCapturedVariableInstance (this, li, CurrentAnonymousMethod);
- }
-
- public void EmitParameter (string name)
- {
- capture_context.EmitParameter (this, name);
- }
-
- public void EmitAssignParameter (string name, Expression source, bool leave_copy, bool prepare_for_load)
- {
- capture_context.EmitAssignParameter (this, name, source, leave_copy, prepare_for_load);
- }
-
- public void EmitAddressOfParameter (string name)
- {
- capture_context.EmitAddressOfParameter (this, name);
}
public Expression GetThis (Location loc)
bool is_cls_compliant;
- ListDictionary declarative_security;
-
static string[] attribute_targets = new string [] { "assembly" };
public AssemblyClass (): base ()
public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder customBuilder)
{
- if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (true)) {
- if (declarative_security == null)
- declarative_security = new ListDictionary ();
-
- a.ExtractSecurityPermissionSet (declarative_security);
- return;
- }
-
Builder.SetCustomAttribute (customBuilder);
}
- public override void Emit (TypeContainer tc)
- {
- base.Emit (tc);
-
- if (declarative_security != null) {
-
- MethodInfo add_permission = typeof (AssemblyBuilder).GetMethod ("AddPermissionRequests", BindingFlags.Instance | BindingFlags.NonPublic);
- object builder_instance = Builder;
-
- try {
- // Microsoft runtime hacking
- if (add_permission == null) {
- Type assembly_builder = typeof (AssemblyBuilder).Assembly.GetType ("System.Reflection.Emit.AssemblyBuilderData");
- add_permission = assembly_builder.GetMethod ("AddPermissionRequests", BindingFlags.Instance | BindingFlags.NonPublic);
-
- FieldInfo fi = typeof (AssemblyBuilder).GetField ("m_assemblyData", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetField);
- builder_instance = fi.GetValue (Builder);
- }
-
- object[] args = new object [] { declarative_security [SecurityAction.RequestMinimum],
- declarative_security [SecurityAction.RequestOptional],
- declarative_security [SecurityAction.RequestRefuse] };
- add_permission.Invoke (builder_instance, args);
- }
- catch {
- Report.RuntimeMissingSupport (Location.Null, "assembly permission setting");
- }
- }
- }
-
public override string[] ValidAttributeTargets {
get {
return attribute_targets;
{
if (a != null && a.Type == TypeManager.cls_compliant_attribute_type) {
Report.Warning (3012, a.Location, "You must specify the CLSCompliant attribute on the assembly, not the module, to enable CLS compliance checking");
+ return;
}
Builder.SetCustomAttribute (customBuilder);
while (ttype.IsArray)
ttype = TypeManager.GetElementType (ttype);
- if (!TypeManager.IsBuiltinType (ttype) && (!ttype.IsSubclassOf (TypeManager.enum_type)) && !(Expr is NullLiteral)) {
+ if (!TypeManager.IsBuiltinType (ttype) &&
+ (!ttype.IsSubclassOf (TypeManager.enum_type))) {
Report.Error (
-3, Location,
"Constant type is not valid (only system types are allowed)");
if (expr is NullLiteral && !type.IsValueType && !TypeManager.IsEnumType (type))
return NullLiteral.Null;
- if (!Convert.ImplicitStandardConversionExists (Convert.ConstantEC, expr, type)){
+ if (!Convert.ImplicitStandardConversionExists (expr, type)){
Convert.Error_CannotImplicitConversion (loc, expr.Type, type);
return null;
}
// A container class for all the conversion operations
//
public class Convert {
- //
- // This is used to prettify the code: a null argument is allowed
- // for ImplicitStandardConversion as long as it is known that
- // no anonymous method will play a role.
- //
- // FIXME: renamed from `const' to `static' to allow bootstraping from older
- // versions of the compiler that could not cope with this construct.
- //
- public static EmitContext ConstantEC = null;
-
static void Error_CannotConvertType (Location loc, Type source, Type target)
{
Report.Error (30, loc, "Cannot convert type '" +
return true;
}
- static Type TypeParam_EffectiveBaseType (EmitContext ec, Type t)
+ static Type TypeParam_EffectiveBaseType (Type t)
{
GenericConstraints gc = TypeManager.GetTypeParameterConstraints (t);
if (gc == null)
return TypeManager.object_type;
- return TypeParam_EffectiveBaseType (ec, gc);
+ return TypeParam_EffectiveBaseType (gc);
}
- static Type TypeParam_EffectiveBaseType (EmitContext ec, GenericConstraints gc)
+ static Type TypeParam_EffectiveBaseType (GenericConstraints gc)
{
ArrayList list = new ArrayList ();
list.Add (gc.EffectiveBaseClass);
GenericConstraints new_gc = TypeManager.GetTypeParameterConstraints (t);
if (new_gc != null)
- list.Add (TypeParam_EffectiveBaseType (ec, new_gc));
+ list.Add (TypeParam_EffectiveBaseType (new_gc));
}
- return FindMostEncompassedType (ec, list);
+ return FindMostEncompassedType (list);
}
static Expression TypeParameterConversion (Expression expr, bool is_reference, Type target_type)
return new BoxedCast (expr, target_type);
}
- static Expression ImplicitTypeParameterConversion (EmitContext ec, Expression expr,
- Type target_type)
+ static Expression ImplicitTypeParameterConversion (Expression expr, Type target_type)
{
Type expr_type = expr.Type;
// We're converting from a type parameter which is known to be a reference type.
bool is_reference = gc.IsReferenceType;
- Type base_type = TypeParam_EffectiveBaseType (ec, gc);
+ Type base_type = TypeParam_EffectiveBaseType (gc);
if (TypeManager.IsSubclassOf (base_type, target_type))
return TypeParameterConversion (expr, is_reference, target_type);
}
static EmptyExpression MyEmptyExpr;
- static public Expression ImplicitReferenceConversion (EmitContext ec, Expression expr, Type target_type)
+ static public Expression ImplicitReferenceConversion (Expression expr, Type target_type)
{
Type expr_type = expr.Type;
return null;
if (expr_type.IsGenericParameter)
- return ImplicitTypeParameterConversion (ec, expr, target_type);
+ return ImplicitTypeParameterConversion (expr, target_type);
//
// notice that it is possible to write "ValueType v = 1", the ValueType here
if (TypeManager.IsValueType (expr_type))
return new BoxedCast (expr);
- if (expr_type.IsClass || expr_type.IsInterface || expr_type == TypeManager.enum_type){
- if (target_type == TypeManager.anonymous_method_type)
- return null;
+ if (expr_type.IsClass || expr_type.IsInterface || expr_type == TypeManager.enum_type)
return new EmptyCast (expr, target_type);
- }
return null;
} else if (target_type == TypeManager.value_type) {
Type target_element_type = TypeManager.GetElementType (target_type);
if (!expr_element_type.IsValueType && !target_element_type.IsValueType)
- if (ImplicitStandardConversionExists (ConstantEC, MyEmptyExpr,
+ if (ImplicitStandardConversionExists (MyEmptyExpr,
target_element_type))
return new EmptyCast (expr, target_type);
}
// Tests whether an implicit reference conversion exists between expr_type
// and target_type
//
- public static bool ImplicitReferenceConversionExists (EmitContext ec, Expression expr, Type target_type)
+ public static bool ImplicitReferenceConversionExists (Expression expr, Type target_type)
{
Type expr_type = expr.Type;
if (expr_type.IsGenericParameter)
- return ImplicitTypeParameterConversion (ec, expr, target_type) != null;
+ return ImplicitTypeParameterConversion (expr, target_type) != null;
//
// This is the boxed case.
if (target_type == TypeManager.object_type) {
if (expr_type.IsClass || TypeManager.IsValueType (expr_type) ||
expr_type.IsInterface || expr_type == TypeManager.enum_type)
- if (target_type != TypeManager.anonymous_method_type)
return true;
return false;
Type target_element_type = TypeManager.GetElementType (target_type);
if (!expr_element_type.IsValueType && !target_element_type.IsValueType)
- if (ImplicitStandardConversionExists (ConstantEC, MyEmptyExpr,
+ if (ImplicitStandardConversionExists (MyEmptyExpr,
target_element_type))
return true;
}
if ((expr is NullLiteral) && target_type.IsGenericParameter)
return TypeParameter_to_Null (target_type);
- if (ImplicitStandardConversionExists (ec, expr, target_type))
+ if (ImplicitStandardConversionExists (expr, target_type))
return true;
Expression dummy = ImplicitUserConversion (ec, expr, target_type, Location.Null);
/// <summary>
/// Determines if a standard implicit conversion exists from
/// expr_type to target_type
- ///
- /// ec should point to a real EmitContext if expr.Type is TypeManager.anonymous_method_type.
/// </summary>
- public static bool ImplicitStandardConversionExists (EmitContext ec, Expression expr, Type target_type)
+ public static bool ImplicitStandardConversionExists (Expression expr, Type target_type)
{
Type expr_type = expr.Type;
return true;
}
- if (ImplicitReferenceConversionExists (ec, expr, target_type))
+ if (ImplicitReferenceConversionExists (expr, target_type))
return true;
//
if (target_type == TypeManager.void_ptr_type && expr_type.IsPointer)
return true;
- if (expr_type == TypeManager.anonymous_method_type){
- if (!TypeManager.IsDelegateType (target_type))
- return false;
-
- AnonymousMethod am = (AnonymousMethod) expr;
- int errors = Report.Errors;
-
- Expression conv = am.Compatible (ec, target_type, true);
- if (conv != null)
- return true;
- }
-
return false;
}
/// Finds "most encompassed type" according to the spec (13.4.2)
/// amongst the methods in the MethodGroupExpr
/// </summary>
- static Type FindMostEncompassedType (EmitContext ec, ArrayList types)
+ static Type FindMostEncompassedType (ArrayList types)
{
Type best = null;
continue;
}
- if (ImplicitStandardConversionExists (ec, priv_fmet_param, best))
+ if (ImplicitStandardConversionExists (priv_fmet_param, best))
best = t;
}
/// Finds "most encompassing type" according to the spec (13.4.2)
/// amongst the types in the given set
/// </summary>
- static Type FindMostEncompassingType (EmitContext ec, ArrayList types)
+ static Type FindMostEncompassingType (ArrayList types)
{
Type best = null;
continue;
}
- if (ImplicitStandardConversionExists (ec, priv_fmee_ret, t))
+ if (ImplicitStandardConversionExists (priv_fmee_ret, t))
best = t;
}
/// by making use of FindMostEncomp* methods. Applies the correct rules separately
/// for explicit and implicit conversion operators.
/// </summary>
- static public Type FindMostSpecificSource (EmitContext ec, MethodGroupExpr me,
- Expression source, bool apply_explicit_conv_rules,
+ static public Type FindMostSpecificSource (MethodGroupExpr me, Expression source,
+ bool apply_explicit_conv_rules,
Location loc)
{
ArrayList src_types_set = new ArrayList ();
// or encompassed by S to a type encompassing or encompassed by T
//
priv_fms_expr.SetType (param_type);
- if (ImplicitStandardConversionExists (ec, priv_fms_expr, source_type))
+ if (ImplicitStandardConversionExists (priv_fms_expr, source_type))
src_types_set.Add (param_type);
else {
- if (ImplicitStandardConversionExists (ec, source, param_type))
+ if (ImplicitStandardConversionExists (source, param_type))
src_types_set.Add (param_type);
}
} else {
//
// Only if S is encompassed by param_type
//
- if (ImplicitStandardConversionExists (ec, source, param_type))
+ if (ImplicitStandardConversionExists (source, param_type))
src_types_set.Add (param_type);
}
}
ArrayList candidate_set = new ArrayList ();
foreach (Type param_type in src_types_set){
- if (ImplicitStandardConversionExists (ec, source, param_type))
+ if (ImplicitStandardConversionExists (source, param_type))
candidate_set.Add (param_type);
}
if (candidate_set.Count != 0)
- return FindMostEncompassedType (ec, candidate_set);
+ return FindMostEncompassedType (candidate_set);
}
//
// Final case
//
if (apply_explicit_conv_rules)
- return FindMostEncompassingType (ec, src_types_set);
+ return FindMostEncompassingType (src_types_set);
else
- return FindMostEncompassedType (ec, src_types_set);
+ return FindMostEncompassedType (src_types_set);
}
//
/// <summary>
/// Finds the most specific target Tx according to section 13.4.4
/// </summary>
- static public Type FindMostSpecificTarget (EmitContext ec, MethodGroupExpr me,
- Type target, bool apply_explicit_conv_rules,
+ static public Type FindMostSpecificTarget (MethodGroupExpr me, Type target,
+ bool apply_explicit_conv_rules,
Location loc)
{
ArrayList tgt_types_set = new ArrayList ();
// or encompassed by S to a type encompassing or encompassed by T
//
priv_fms_expr.SetType (ret_type);
- if (ImplicitStandardConversionExists (ec, priv_fms_expr, target))
+ if (ImplicitStandardConversionExists (priv_fms_expr, target))
tgt_types_set.Add (ret_type);
else {
priv_fms_expr.SetType (target);
- if (ImplicitStandardConversionExists (ec, priv_fms_expr, ret_type))
+ if (ImplicitStandardConversionExists (priv_fms_expr, ret_type))
tgt_types_set.Add (ret_type);
}
} else {
// Only if T is encompassed by param_type
//
priv_fms_expr.SetType (ret_type);
- if (ImplicitStandardConversionExists (ec, priv_fms_expr, target))
+ if (ImplicitStandardConversionExists (priv_fms_expr, target))
tgt_types_set.Add (ret_type);
}
}
foreach (Type ret_type in tgt_types_set){
priv_fmt_expr.SetType (ret_type);
- if (ImplicitStandardConversionExists (ec, priv_fmt_expr, target))
+ if (ImplicitStandardConversionExists (priv_fmt_expr, target))
candidate_set.Add (ret_type);
}
if (candidate_set.Count != 0)
- return FindMostEncompassingType (ec, candidate_set);
+ return FindMostEncompassingType (candidate_set);
}
//
// Okay, final case !
//
if (apply_explicit_conv_rules)
- return FindMostEncompassedType (ec, tgt_types_set);
+ return FindMostEncompassedType (tgt_types_set);
else
- return FindMostEncompassingType (ec, tgt_types_set);
+ return FindMostEncompassingType (tgt_types_set);
}
/// <summary>
Type most_specific_source, most_specific_target;
- most_specific_source = FindMostSpecificSource (ec, union, source, look_for_explicit, loc);
+ most_specific_source = FindMostSpecificSource (union, source, look_for_explicit, loc);
if (most_specific_source == null)
return null;
- most_specific_target = FindMostSpecificTarget (ec, union, target, look_for_explicit, loc);
+ most_specific_target = FindMostSpecificTarget (union, target, look_for_explicit, loc);
if (most_specific_target == null)
return null;
if (expr.eclass == ExprClass.MethodGroup){
if (!TypeManager.IsDelegateType (target_type)){
+ Report.Error (428, loc,
+ String.Format (
+ "Cannot convert method group to `{0}', since it is not a delegate",
+ TypeManager.CSharpName (target_type)));
return null;
}
- //
- // Only allow anonymous method conversions on post ISO_1
- //
- if (RootContext.Version != LanguageVersion.ISO_1){
- MethodGroupExpr mg = expr as MethodGroupExpr;
- if (mg != null)
- return ImplicitDelegateCreation.Create (ec, mg, target_type, loc);
- }
+ return ImplicitDelegateCreation.Create (ec, (MethodGroupExpr) expr, target_type, loc);
}
if (expr_type.Equals (target_type) && !(expr is NullLiteral))
if (e != null)
return e;
- e = ImplicitReferenceConversion (ec, expr, target_type);
+ e = ImplicitReferenceConversion (expr, target_type);
if (e != null)
return e;
}
}
- if (expr_type == TypeManager.anonymous_method_type){
- if (!TypeManager.IsDelegateType (target_type)){
- Report.Error (1660, loc,
- "Cannot convert anonymous method to `{0}', since it is not a delegate",
- TypeManager.CSharpName (target_type));
- return null;
- }
-
- AnonymousMethod am = (AnonymousMethod) expr;
- int errors = Report.Errors;
-
- Expression conv = am.Compatible (ec, target_type, false);
- if (conv != null)
- return conv;
-
- //
- // We return something instead of null, to avoid
- // the duplicate error, since am.Compatible would have
- // reported that already
- //
- if (errors != Report.Errors)
- return new EmptyCast (expr, target_type);
- }
-
return null;
}
static public void Error_CannotImplicitConversion (Location loc, Type source, Type target)
{
- Report.Error (29, loc, "Cannot convert implicitly from {0} to `{1}'",
- source == TypeManager.anonymous_method_type ?
- "anonymous method" : "`" + TypeManager.CSharpName (source) + "'",
- TypeManager.CSharpName (target));
+ string msg = "Cannot convert implicitly from `"+
+ TypeManager.CSharpName (source) + "' to `" +
+ TypeManager.CSharpName (target) + "'";
+
+ Report.Error (29, loc, msg);
}
/// <summary>
if (TypeManager.IsEnumType (real_target_type))
real_target_type = TypeManager.EnumToUnderlying (real_target_type);
- if (ImplicitStandardConversionExists (ec, expr, real_target_type)){
+ if (ImplicitStandardConversionExists (expr, real_target_type)){
Expression ce = ImplicitConversionStandard (ec, expr, real_target_type, loc);
if (real_target_type != target_type)
/// Current block is used to add statements as we find
/// them.
/// </summary>
- Block current_block, top_current_block;
+ Block current_block;
+
+ /// <summary>
+ /// If true, creates a toplevel block in the block production
+ /// This is flagged by the delegate creation
+ /// </summary>
+ bool create_toplevel_block;
Delegate current_delegate;
$$ = args;
}
- | named_argument_list COMMA expression
- {
- Report.Error (1016, lexer.Location, "Named attribute argument expected");
- $$ = null;
- }
;
named_argument
{
$$ = new StackAlloc ((Expression) $2, (Expression) $4, lexer.Location);
}
- | STACKALLOC type
- {
- Report.Error (1575, lexer.Location, "A stackalloc expression requires [] after type");
- $$ = null;
- }
;
method_declaration
}
}
- method.Block = (ToplevelBlock) $3;
+ method.Block = (Block) $3;
current_container.AddMethod (method);
current_local_parameters = null;
{
$$ = new Parameter ((Expression) $3, (string) $4, (Parameter.Modifier) $2, (Attributes) $1);
}
- | opt_attributes
- opt_parameter_modifier
- type
- {
- Report.Error (1001, lexer.Location, "Identifier expected");
- $$ = null;
- }
| opt_attributes
opt_parameter_modifier
type
$$ = new Parameter ((Expression) $3, (string) $4, Parameter.Modifier.PARAMS, (Attributes) $1);
note ("type must be a single-dimension array type");
}
- | opt_attributes PARAMS parameter_modifier type IDENTIFIER
- {
- Report.Error (1611, lexer.Location, "The params parameter cannot be declared as ref or out");
- $$ = null;
- }
| opt_attributes PARAMS type error {
CheckIdentifierToken (yyToken);
$$ = null;
;
get_accessor_declaration
- : opt_attributes opt_modifiers GET
+ : opt_attributes GET
{
// If this is not the case, then current_local_parameters has already
// been set in indexer_declaration
}
accessor_body
{
- $$ = new Accessor ((ToplevelBlock) $5, (int) $2, (Attributes) $1, lexer.Location);
+ $$ = new Accessor ((Block) $4, (Attributes) $1, lexer.Location);
current_local_parameters = null;
lexer.PropertyParsing = true;
}
;
set_accessor_declaration
- : opt_attributes opt_modifiers SET
+ : opt_attributes SET
{
Parameter [] args;
Parameter implicit_value_parameter = new Parameter (
}
accessor_body
{
- $$ = new Accessor ((ToplevelBlock) $5, (int) $2, (Attributes) $1, lexer.Location);
+ $$ = new Accessor ((Block) $4, (Attributes) $1, lexer.Location);
current_local_parameters = null;
lexer.PropertyParsing = true;
}
Operator op = new Operator (
current_class, decl.optype, decl.ret_type, (int) $2,
new Parameters (param_list, null, decl.location),
- (ToplevelBlock) $5, (Attributes) $1, decl.location);
+ (Block) $5, (Attributes) $1, decl.location);
if (SimpleIteratorContainer.Simple.Yields)
op.SetYields ();
constructor_body
{
Constructor c = (Constructor) $3;
- c.Block = (ToplevelBlock) $4;
+ c.Block = (Block) $4;
c.OptAttributes = (Attributes) $1;
c.ModFlags = (int) $2;
current_class, TypeManager.system_void_expr, m, "Finalize",
new Parameters (null, null, l), (Attributes) $1, l);
- d.Block = (ToplevelBlock) $7;
+ d.Block = (Block) $7;
current_container.AddMethod (d);
}
}
}
| add_accessor_declaration { $$ = null; }
| remove_accessor_declaration { $$ = null; }
- | error
- {
- Report.Error (1055, lexer.Location, "An add or remove accessor expected");
- $$ = null;
- }
- | { $$ = null; }
;
add_accessor_declaration
}
block
{
- $$ = new Accessor ((ToplevelBlock) $4, 0, (Attributes) $1, lexer.Location);
+ $$ = new Accessor ((Block) $4, (Attributes) $1, lexer.Location);
lexer.EventParsing = true;
}
| opt_attributes ADD error {
}
block
{
- $$ = new Accessor ((ToplevelBlock) $4, 0, (Attributes) $1, lexer.Location);
+ $$ = new Accessor ((Block) $4, (Attributes) $1, lexer.Location);
lexer.EventParsing = true;
}
| opt_attributes REMOVE error {
$$ = new BaseIndexerAccess ((ArrayList) $3, lexer.Location);
}
| BASE error {
- Report.Error (175, lexer.Location, "Use of keyword `base' is not valid in this context");
+ Report.Error (175, "Use of keyword `base' is not valid in this context");
$$ = null;
}
;
{
$$ = new ArrayCreation ((Expression) $2, (string) $3, (ArrayList) $4, lexer.Location);
}
- | NEW error
- {
- Report.Error (1031, lexer.Location, "Type expected");
- $$ = null;
- }
| NEW type error
{
Report.Error (1526, lexer.Location, "new expression requires () or [] after type");
: DELEGATE opt_anonymous_method_signature {
oob_stack.Push (current_local_parameters);
current_local_parameters = (Parameters)$2;
-
- // Force the next block to be created as a ToplevelBlock
- oob_stack.Push (current_block);
- oob_stack.Push (top_current_block);
- oob_stack.Push (lexer.Location);
- current_block = null;
+ create_toplevel_block = true;
} block {
- Location loc = (Location) oob_stack.Pop ();
- top_current_block = (Block) oob_stack.Pop ();
- current_block = (Block) oob_stack.Pop ();
+ if (true){
+ Report.Error (-213, lexer.Location, "Anonymous methods are not supported in this branch");
+ $$ = null;
+ } else {
+ create_toplevel_block = false;
if (RootContext.Version == LanguageVersion.ISO_1){
Report.FeatureIsNotStandardized (lexer.Location, "anonymous methods");
$$ = null;
- } else {
- ToplevelBlock anon_block = (ToplevelBlock) $4;
-
- anon_block.Parent = current_block;
- $$ = new AnonymousMethod ((Parameters) $2, (ToplevelBlock) top_current_block,
- anon_block, loc);
+ } else
+ $$ = new AnonymousMethod ((Parameters) $2, (Block) $4, lexer.Location);
+ current_local_parameters = (Parameters) oob_stack.Pop ();
}
- current_local_parameters = (Parameters) oob_stack.Pop ();
}
;
opt_anonymous_method_signature
- : /* empty */ { $$ = null; }
+ : /* empty */ { $$ = Parameters.EmptyReadOnlyParameters; }
| anonymous_method_signature
;
anonymous_method_parameter
: opt_parameter_modifier type IDENTIFIER {
- $$ = new Parameter ((Expression) $2, (string) $3, (Parameter.Modifier) $1, null);
- }
- | PARAMS type IDENTIFIER {
- Report.Error (-221, lexer.Location, "params modifier not allowed in anonymous method declaration");
- $$ = null;
+ $$ = new Parameter ((Expression) $2, (string) $2, (Parameter.Modifier) $1, null);
}
;
block
: OPEN_BRACE
{
- if (current_block == null){
- current_block = new ToplevelBlock ((ToplevelBlock) top_current_block, current_local_parameters, lexer.Location);
- top_current_block = current_block;
+ if (current_block == null || create_toplevel_block){
+ current_block = new ToplevelBlock (current_local_parameters, lexer.Location);
} else {
current_block = new Block (current_block, current_local_parameters,
lexer.Location, Location.Null);
$$ = current_block;
current_block.SetEndLocation (lexer.Location);
current_block = current_block.Parent;
- if (current_block == null)
- top_current_block = null;
}
;
// Now s contains the list of specific catch clauses
// and g contains the general one.
- $$ = new Try ((Block) $2, c, g, null, ((Block) $2).loc);
+ $$ = new Try ((Block) $2, c, g, null, lexer.Location);
}
| TRY block opt_catch_clauses FINALLY block
{
}
}
- $$ = new Try ((Block) $2, s, g, (Block) $5, ((Block) $2).loc);
+ $$ = new Try ((Block) $2, s, g, (Block) $5, lexer.Location);
}
| TRY block error
{
}
- $$ = new Catch (type, id , (Block) $4, ((Block) $4).loc);
+ $$ = new Catch (type, id , (Block) $4, lexer.Location);
}
;
Attributes get_attrs, Attributes set_attrs, Location get_loc, Location set_loc)
{
if (has_get)
- Get = new Accessor (null, 0, get_attrs, get_loc);
+ Get = new Accessor (null, get_attrs, get_loc);
if (has_set)
- Set = new Accessor (null, 0, set_attrs, set_loc);
+ Set = new Accessor (null, set_attrs, set_loc);
}
}
if (ifstack != null && ifstack.Count >= 1) {\r
int state = (int) ifstack.Pop ();\r
if ((state & REGION) != 0)\r
- Report.Error (1038, Location, "#endregion directive expected");\r
+ Report.Error (1038, "#endregion directive expected");\r
else \r
- Report.Error (1027, Location, "#endif directive expected");\r
+ Report.Error (1027, "#endif directive expected");\r
}\r
\r
}\r
public string GetMethodName ()
{
if (Left != null)
- return Left.GetPartialName () + "." + Name;
+ return Left.GetFullName () + "." + Name;
else
return Name;
}
- ///
- /// This returns exclusively the name as seen on the source code
- /// it is not the fully qualifed type after resolution
- ///
- public string GetPartialName ()
+ public string GetFullName ()
{
string full_name;
if (TypeArguments != null)
else
full_name = Name;
if (Left != null)
- return Left.GetPartialName () + "." + full_name;
+ return Left.GetFullName () + "." + full_name;
else
return full_name;
}
public override string ToString ()
{
- throw new Exception ("This exception is thrown because someone is miss-using\n" +
- "MemberName.ToString in the compiler. Please report this bug");
-
string full_name;
if (TypeArguments != null)
full_name = Name + "<" + TypeArguments + ">";
VerifyClsCompliance (Parent);
}
- public bool InUnsafe {
- get {
- return ((ModFlags & Modifiers.UNSAFE) != 0) || Parent.UnsafeContext;
- }
- }
-
//
// Whehter is it ok to use an unsafe pointer in this type container
//
if (OptAttributes == null)
return null;
- Attribute obsolete_attr = OptAttributes.Search (
- TypeManager.obsolete_attribute_type, ds.EmitContext);
+ // TODO: remove this allocation
+ EmitContext ec = new EmitContext (ds.Parent, ds, ds.Location,
+ null, null, ds.ModFlags, false);
+
+ Attribute obsolete_attr = OptAttributes.Search (TypeManager.obsolete_attribute_type, ec);
if (obsolete_attr == null)
return null;
bool GetClsCompliantAttributeValue (DeclSpace ds)
{
if (OptAttributes != null) {
- Attribute cls_attribute = OptAttributes.GetClsCompliantAttribute (ds.EmitContext);
+ EmitContext ec = new EmitContext (ds.Parent, ds, ds.Location,
+ null, null, ds.ModFlags, false);
+ Attribute cls_attribute = OptAttributes.GetClsCompliantAttribute (ec);
if (cls_attribute != null) {
caching_flags |= Flags.HasClsCompliantAttribute;
return cls_attribute.GetClsCompliantAttributeValue (ds);
readonly bool is_generic;
readonly int count_type_params;
- // The emit context for toplevel objects.
- protected EmitContext ec;
-
- public EmitContext EmitContext {
- get { return ec; }
- }
-
//
// Whether we are Generic
//
/// </summary>
protected bool AddToContainer (MemberCore symbol, bool is_method, string fullname, string basename)
{
- if (basename == Basename && !(this is Interface)) {
+ if (basename == Basename) {
Report.SymbolRelatedToPreviousError (this);
Report.Error (542, "'{0}': member names cannot be the same as their enclosing type", symbol.Location, symbol.GetSignatureForError ());
return false;
}
// <summary>
- // Looks up the type, as parsed into the expression `e'.
+ // Looks up the type, as parsed into the expression `e'
// </summary>
- [Obsolete ("This method is going away soon")]
public Type ResolveType (Expression e, bool silent, Location loc)
{
TypeExpr d = ResolveTypeExpr (e, silent, loc);
- return d == null ? null : d.Type;
+ if (d == null)
+ return null;
+
+ return ResolveType (d, loc);
}
- public Type ResolveNestedType (Type t, Location loc)
+ public Type ResolveType (TypeExpr d, Location loc)
{
+ if (!d.CheckAccessLevel (this)) {
+ Report.Error (122, loc, "'{0}' is inaccessible due to its protection level", d.Name);
+ return null;
+ }
+
+ Type t = d.ResolveType (type_resolve_ec);
+ if (t == null)
+ return null;
+
+ if (d is UnboundTypeExpression)
+ return t;
+
TypeContainer tc = TypeManager.LookupTypeContainer (t);
if ((tc != null) && tc.IsGeneric) {
if (!IsGeneric) {
return null;
}
- TypeParameter[] args;
- if (this is GenericMethod)
- args = Parent.TypeParameters;
- else
- args = TypeParameters;
+ ConstructedType ctype = new ConstructedType (
+ t, TypeParameters, loc);
- ConstructedType ctype = new ConstructedType (t, args, loc);
- t = ctype.ResolveType (ec);
+ t = ctype.ResolveType (type_resolve_ec);
}
return t;
// <summary>
// Resolves the expression `e' for a type, and will recursively define
- // types. This should only be used for resolving base types.
+ // types.
// </summary>
public TypeExpr ResolveTypeExpr (Expression e, bool silent, Location loc)
{
else
type_resolve_ec.ContainerType = TypeBuilder;
- return e.ResolveAsTypeTerminal (type_resolve_ec, silent);
+ int errors = Report.Errors;
+
+ TypeExpr d = e.ResolveAsTypeTerminal (type_resolve_ec);
+
+ if ((d != null) && (d.eclass == ExprClass.Type))
+ return d;
+
+ if (silent || (Report.Errors != errors))
+ return null;
+
+ if (e is SimpleName){
+ SimpleName s = new SimpleName (((SimpleName) e).Name, loc);
+ d = s.ResolveAsTypeTerminal (type_resolve_ec);
+
+ if ((d == null) || (d.Type == null)) {
+ Report.Error (246, loc, "Cannot find type `{0}'", e);
+ return null;
+ }
+
+ int num_args = TypeManager.GetNumberOfTypeArguments (d.Type);
+
+ if (num_args == 0) {
+ Report.Error (308, loc,
+ "The non-generic type `{0}' cannot " +
+ "be used with type arguments.",
+ TypeManager.CSharpName (d.Type));
+ return null;
+ }
+
+ Report.Error (305, loc,
+ "Using the generic type `{0}' " +
+ "requires {1} type arguments",
+ TypeManager.GetFullName (d.Type), num_args);
+ return null;
+ }
+
+ Report.Error (246, loc, "Cannot find type `{0}'", e);
+ return null;
}
public bool CheckAccessLevel (Type check_type)
{
TypeBuilder tb;
- if ((this is GenericMethod) || (this is Iterator))
+ if (this is GenericMethod)
tb = Parent.TypeBuilder;
else
tb = TypeBuilder;
return true; // FIXME
TypeAttributes check_attr = check_type.Attributes & TypeAttributes.VisibilityMask;
-
+
//
// Broken Microsoft runtime, return public for arrays, no matter what
// the accessibility is for their underlying class, and they return
case TypeAttributes.NotPublic:
- if (TypeBuilder == null)
- // FIXME: TypeBuilder will be null when invoked by Class.GetNormalBases().
- // However, this is invoked again later -- so safe to return true.
- // May also be null when resolving top-level attributes.
- return true;
- //
- // This test should probably use the declaringtype.
- //
+ // In same cases is null.
+ if (TypeBuilder == null)
+ return true;
+
+ //
+ // This test should probably use the declaringtype.
+ //
return check_type.Assembly == TypeBuilder.Assembly;
case TypeAttributes.NestedPublic:
return true;
case TypeAttributes.NestedPrivate:
- return NestedAccessible (tb, check_type);
+ string check_type_name = check_type.FullName;
+ string type_name = tb.FullName;
+
+ int cio = check_type_name.LastIndexOf ('+');
+ string container = check_type_name.Substring (0, cio);
+
+ //
+ // Check if the check_type is a nested class of the current type
+ //
+ if (check_type_name.StartsWith (type_name + "+")){
+ return true;
+ }
+
+ if (type_name.StartsWith (container)){
+ return true;
+ }
+
+ return false;
case TypeAttributes.NestedFamily:
//
}
- protected bool NestedAccessible (Type tb, Type check_type)
+ protected bool FamilyAccessible (TypeBuilder tb, Type check_type)
{
+ Type declaring = check_type.DeclaringType;
+ if (tb.IsSubclassOf (declaring))
+ return true;
+
string check_type_name = check_type.FullName;
- // At this point, we already know check_type is a nested class.
int cio = check_type_name.LastIndexOf ('+');
+ string container = check_type_name.Substring (0, cio);
- // Ensure that the string 'container' has a '+' in it to avoid false matches
- string container = check_type_name.Substring (0, cio + 1);
-
- // Ensure that type_name ends with a '+' so that it can match 'container', if necessary
- string type_name = tb.FullName + "+";
-
- // If the current class is nested inside the container of check_type,
- // we can access check_type even if it is private or protected.
- return type_name.StartsWith (container);
- }
-
- protected bool FamilyAccessible (Type tb, Type check_type)
- {
- Type declaring = check_type.DeclaringType;
- if (tb == declaring || TypeManager.IsFamilyAccessible (tb, declaring))
+ //
+ // Check if the check_type is a nested class of the current type
+ //
+ if (check_type_name.StartsWith (container + "+"))
return true;
- return NestedAccessible (tb, check_type);
+ return false;
}
// Access level of a type.
return null;
if ((t != null) && containing_ds.CheckAccessLevel (t))
- return ResolveNestedType (t, loc);
+ return t;
current_type = current_type.BaseType;
}
caching_flags &= ~Flags.HasCompliantAttribute_Undetected;
if (OptAttributes != null) {
+ EmitContext ec = new EmitContext (Parent, this, Location,
+ null, null, ModFlags, false);
Attribute cls_attribute = OptAttributes.GetClsCompliantAttribute (ec);
if (cls_attribute != null) {
caching_flags |= Flags.HasClsCompliantAttribute;
/// <summary>
/// Create a new MemberCache for the given IMemberContainer `container'.
/// </summary>
- public MemberCache (IMemberContainer container, bool setup_inherited_interfaces)
+ public MemberCache (IMemberContainer container)
{
this.Container = container;
if (Container.ParentContainer != null)
parent = Container.ParentContainer.MemberCache;
else
- parent = null;
- member_hash = SetupCacheForInterface (parent, setup_inherited_interfaces);
+ parent = TypeHandle.ObjectType.MemberCache;
+ member_hash = SetupCacheForInterface (parent);
} else if (Container.ParentContainer != null)
member_hash = SetupCache (Container.ParentContainer.MemberCache);
else
Hashtable SetupCache (MemberCache parent)
{
Hashtable hash = new Hashtable ();
- if (parent == null)
- return hash;
IDictionaryEnumerator it = parent.member_hash.GetEnumerator ();
while (it.MoveNext ()) {
hash [it.Key] = ((ArrayList) it.Value).Clone ();
- }
+ }
return hash;
}
/// Type.GetMembers() won't return any inherited members for interface types,
/// so we need to do this manually. Interfaces also inherit from System.Object.
/// </summary>
- Hashtable SetupCacheForInterface (MemberCache parent, bool deep_setup)
+ Hashtable SetupCacheForInterface (MemberCache parent)
{
Hashtable hash = SetupCache (parent);
-
- if (!deep_setup)
- return hash;
-
Type [] ifaces = TypeManager.GetInterfaces (Container.Type);
foreach (Type itype in ifaces) {
{
// We need to call AddMembers() with a single member type at a time
// to get the member type part of CacheEntry.EntryType right.
- if (!container.IsInterface) {
- AddMembers (MemberTypes.Constructor, container);
- AddMembers (MemberTypes.Field, container);
- }
+ AddMembers (MemberTypes.Constructor, container);
+ AddMembers (MemberTypes.Field, container);
AddMembers (MemberTypes.Method, container);
AddMembers (MemberTypes.Property, container);
AddMembers (MemberTypes.Event, container);
/// number to speed up the searching process.
/// </summary>
[Flags]
- protected internal enum EntryType {
+ protected enum EntryType {
None = 0x000,
Instance = 0x001,
MaskType = Constructor|Event|Field|Method|Property|NestedType
}
- protected internal struct CacheEntry {
+ protected struct CacheEntry {
public readonly IMemberContainer Container;
public readonly EntryType EntryType;
public readonly MemberInfo Member;
// Does exist easier way how to detect indexer ?
if ((entry.EntryType & EntryType.Property) != 0) {
Type[] arg_types = TypeManager.GetArgumentTypes ((PropertyInfo)entry.Member);
- if (arg_types.Length > 0)
+ if (arg_types.Length == 1)
continue;
}
}
{
MethodAttributes mattr;
int i;
- ec = new EmitContext (this, this, Location, null, null, ModFlags, false);
+ EmitContext ec = new EmitContext (this, this, Location, null,
+ null, ModFlags, false);
if (IsGeneric) {
foreach (TypeParameter type_param in TypeParameters)
//
// FIXME: POSSIBLY make these static, as they are always the same
Parameter [] fixed_pars = new Parameter [2];
- fixed_pars [0] = new Parameter (TypeManager.system_object_expr, "object",
- Parameter.Modifier.NONE, null);
- fixed_pars [1] = new Parameter (TypeManager.system_intptr_expr, "method",
- Parameter.Modifier.NONE, null);
+ fixed_pars [0] = new Parameter (null, null, Parameter.Modifier.NONE, null);
+ fixed_pars [1] = new Parameter (null, null, Parameter.Modifier.NONE, null);
Parameters const_parameters = new Parameters (fixed_pars, null, Location);
TypeManager.RegisterMethod (
// First, call the `out of band' special method for
// defining recursively any types we need:
- if (!Parameters.ComputeAndDefineParameterTypes (ec))
+ if (!Parameters.ComputeAndDefineParameterTypes (this))
return false;
- param_types = Parameters.GetParameterInfo (ec);
+ param_types = Parameters.GetParameterInfo (this);
if (param_types == null)
return false;
return false;
}
- ReturnType = ReturnType.ResolveAsTypeTerminal (ec, false);
+ ReturnType = ResolveTypeExpr (ReturnType, false, Location);
if (ReturnType == null)
return false;
InvokeBuilder.SetImplementationFlags (MethodImplAttributes.Runtime);
TypeManager.RegisterMethod (InvokeBuilder,
- new InternalParameters (param_types, Parameters),
+ new InternalParameters (Parent, Parameters),
param_types);
//
Parameter.Modifier.NONE, null);
Parameters async_parameters = new Parameters (async_params, null, Location);
- async_parameters.ComputeAndDefineParameterTypes (ec);
+ async_parameters.ComputeAndDefineParameterTypes (this);
+ async_parameters.ComputeAndDefineParameterTypes (this);
TypeManager.RegisterMethod (BeginInvokeBuilder,
- new InternalParameters (async_param_types, async_parameters),
+ new InternalParameters (Parent, async_parameters),
async_param_types);
//
}
Parameters end_parameters = new Parameters (end_params, null, Location);
- end_parameters.ComputeAndDefineParameterTypes (ec);
+ end_parameters.ComputeAndDefineParameterTypes (this);
TypeManager.RegisterMethod (
EndInvokeBuilder,
- new InternalParameters (end_param_types, end_parameters),
+ new InternalParameters (Parent, end_parameters),
end_param_types);
return true;
public override void Emit ()
{
if (OptAttributes != null) {
+ EmitContext ec = new EmitContext (
+ Parent, this, Location, null, null, ModFlags, false);
Parameters.LabelParameters (ec, InvokeBuilder, Location);
OptAttributes.Emit (ec, this);
}
return true;
}
- //
- // Returns the MethodBase for "Invoke" from a delegate type, this is used
- // to extract the signature of a delegate.
- //
- public static MethodGroupExpr GetInvokeMethod (EmitContext ec, Type delegate_type,
- Location loc)
- {
- Expression ml = Expression.MemberLookup (
- ec, delegate_type, "Invoke", loc);
-
- MethodGroupExpr mg = ml as MethodGroupExpr;
- if (mg == null) {
- Report.Error (-100, loc, "Internal error: could not find Invoke method!");
- return null;
- }
-
- return mg;
- }
-
/// <summary>
/// Verifies whether the method in question is compatible with the delegate
/// Returns the method itself if okay and null if not.
public static MethodBase VerifyMethod (EmitContext ec, Type delegate_type, MethodBase mb,
Location loc)
{
- MethodGroupExpr mg = GetInvokeMethod (ec, delegate_type, loc);
- if (mg == null)
+ Expression ml = Expression.MemberLookup (
+ ec, delegate_type, "Invoke", loc);
+
+ if (!(ml is MethodGroupExpr)) {
+ Report.Error (-100, loc, "Internal error: could not find Invoke method!");
return null;
+ }
+
+ MethodBase invoke_mb = ((MethodGroupExpr) ml).Methods [0];
- MethodBase invoke_mb = mg.Methods [0];
ParameterData invoke_pd = Invocation.GetParameterData (invoke_mb);
- if (!mg.HasTypeArguments &&
+ if (!((MethodGroupExpr) ml).HasTypeArguments &&
!Invocation.InferTypeArguments (ec, invoke_pd, ref mb))
return null;
if (!params_method && pd_count != arg_count) {
Report.Error (1593, loc,
- "Delegate '{0}' does not take {1} arguments",
- delegate_type.ToString (), arg_count);
+ "Delegate '" + delegate_type.ToString ()
+ + "' does not take '" + arg_count + "' arguments");
return false;
}
margs [1] = spec.Substring (0, cp);
} else {
margs [1] = spec;
- margs [0] = Path.GetFileName (spec);
+ margs [0] = spec.Replace ('/','.').Replace ('\\', '.');
}
if (File.Exists ((string) margs [1]))
// value will be returned if the expression is not a type
// reference
//
- public TypeExpr ResolveAsTypeTerminal (EmitContext ec, bool silent)
+ public TypeExpr ResolveAsTypeTerminal (EmitContext ec)
{
- int errors = Report.Errors;
-
- TypeExpr te = ResolveAsTypeStep (ec) as TypeExpr;
-
- if (te == null || te.eclass != ExprClass.Type) {
- if (!silent && errors == Report.Errors)
- Report.Error (246, Location, "Cannot find type '{0}'", ToString ());
- return null;
- }
-
- if (!te.CheckAccessLevel (ec.DeclSpace)) {
- Report.Error (122, Location, "'{0}' is inaccessible due to its protection level", te.Name);
- return null;
- }
-
- return te;
+ return ResolveAsTypeStep (ec) as TypeExpr;
}
/// <summary>
Constant e = Constantify (v, real_type);
return new EnumConstant (e, t);
- } else if (v == null && !TypeManager.IsValueType (t))
- return NullLiteral.Null;
- else
+ } else
throw new Exception ("Unknown type for constant (" + t +
"), details: " + v);
}
/// </summary>
public static object ConvertIntLiteral (Constant c, Type target_type, Location loc)
{
- if (!Convert.ImplicitStandardConversionExists (Convert.ConstantEC, c, target_type)){
+ if (!Convert.ImplicitStandardConversionExists (c, target_type)){
Convert.Error_CannotImplicitConversion (loc, c.Type, target_type);
return null;
}
TypeParameterExpr generic_type = ds.LookupGeneric (Name, loc);
if (generic_type != null)
- return generic_type.ResolveAsTypeTerminal (ec, false);
+ return generic_type.ResolveAsTypeTerminal (ec);
if (ec.ResolvingTypeTree){
int errors = Report.Errors;
}
}
- if ((t = RootContext.LookupType (ds, Name, true, loc)) != null)
- return t;
-
- if (alias_value != null) {
+ //
+ // First, the using aliases
+ //
+ if (alias_value != null){
if (alias_value.IsType)
return alias_value.Type;
if ((t = RootContext.LookupType (ds, alias_value.Name, true, loc)) != null)
return new SimpleName (alias_value.Name, loc);
}
+ //
+ // Stage 2: Lookup up if we are an alias to a type
+ // or a namespace.
+ //
+
+ if ((t = RootContext.LookupType (ds, Name, true, loc)) != null)
+ return t;
+
// No match, maybe our parent can compose us
// into something meaningful.
return this;
return var.Resolve (ec);
}
- ParameterReference pref = current_block.GetParameterReference (Name, loc);
- if (pref != null) {
+ int idx = -1;
+ Parameter par = null;
+ Parameters pars = current_block.Parameters;
+ if (pars != null)
+ par = pars.GetParameterByName (Name, out idx);
+
+ if (par != null) {
+ ParameterReference param;
+
+ param = new ParameterReference (pars, current_block, idx, Name, loc);
+
if (right_side != null)
- return pref.ResolveLValue (ec, right_side);
+ return param.ResolveLValue (ec, right_side);
else
- return pref.Resolve (ec);
+ return param.Resolve (ec);
}
}
override public Expression DoResolve (EmitContext ec)
{
- return ResolveAsTypeTerminal (ec, false);
+ return ResolveAsTypeTerminal (ec);
}
override public void Emit (EmitContext ec)
public virtual Type ResolveType (EmitContext ec)
{
- TypeExpr t = ResolveAsTypeTerminal (ec, false);
+ TypeExpr t = ResolveAsTypeTerminal (ec);
if (t == null)
return null;
}
ConstructedType ctype = new ConstructedType (type, args, loc);
- return ctype.ResolveAsTypeTerminal (ec, false);
+ return ctype.ResolveAsTypeTerminal (ec);
} else if (num_args > 0) {
Report.Error (305, loc,
"Using the generic type `{0}' " +
public override Type ResolveType (EmitContext ec)
{
- TypeExpr t = ResolveAsTypeTerminal (ec, false);
+ TypeExpr t = ResolveAsTypeTerminal (ec);
if (t == null)
return null;
AttributeTester.Report_ObsoleteMessage (oa, TypeManager.GetFullNameSignature (FieldInfo), loc);
}
- if (ec.CurrentAnonymousMethod != null){
- if (!FieldInfo.IsStatic){
- if (ec.TypeContainer is Struct){
- Report.Error (1673, loc, "Can not reference instance variables in anonymous methods hosted in structs");
- return null;
- }
- ec.CaptureField (this);
- }
- }
-
// If the instance expression is a local variable or parameter.
IVariable var = instance_expr as IVariable;
if ((var == null) || (var.VariableInfo == null))
{
FindAccessors (ec.ContainerType);
+ if (setter != null && !IsAccessorAccessible (ec.ContainerType, setter) ||
+ getter != null && !IsAccessorAccessible (ec.ContainerType, getter)) {
+ Report.Error (122, loc, "'{0}' is inaccessible due to its protection level", PropertyInfo.Name);
+ }
+
is_static = getter != null ? getter.IsStatic : setter.IsStatic;
}
return null;
}
- if (!IsAccessorAccessible (ec.ContainerType, getter)) {
- Report.Error (122, loc, "'{0}.get' is inaccessible due to its protection level", PropertyInfo.Name);
- return null;
- }
-
if (!InstanceResolve (ec))
return null;
return null;
}
- if (!IsAccessorAccessible (ec.ContainerType, setter)) {
- Report.Error (122, loc, "'{0}.set' is inaccessible due to its protection level", PropertyInfo.Name);
- return null;
- }
-
if (!InstanceResolve (ec))
return null;
public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
{
if (a.Type == TypeManager.marshal_as_attr_type) {
- UnmanagedMarshal marshal = a.GetMarshal (this);
+ UnmanagedMarshal marshal = a.GetMarshal ();
if (marshal != null) {
builder.SetMarshal (marshal);
- }
return;
}
-
- if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
- a.Error_InvalidSecurityParent ();
+ Report.Warning (-24, a.Location, "The Microsoft Runtime cannot set this marshal info. Please use the Mono runtime instead.");
return;
}
if (TypeBuilder == null)
return false;
- ec = new EmitContext (this, this, Location, null, UnderlyingType, ModFlags, false);
+ EmitContext ec = new EmitContext (this, this, Location, null,
+ UnderlyingType, ModFlags, false);
+
object default_value = 0;
public override void Emit ()
{
+ EmitContext ec = new EmitContext (
+ Parent, this, Location, null, null, ModFlags, false);
+
if (OptAttributes != null) {
OptAttributes.Emit (ec, this);
}
/// size.
/// </remarks>
public abstract class Probe : Expression {
- public Expression ProbeType;
+ public readonly Expression ProbeType;
protected Expression expr;
protected Type probe_type;
public override Expression DoResolve (EmitContext ec)
{
- TypeExpr texpr = ProbeType.ResolveAsTypeTerminal (ec, false);
- if (texpr == null)
+ probe_type = ec.DeclSpace.ResolveType (ProbeType, false, loc);
+
+ if (probe_type == null)
return null;
- probe_type = texpr.ResolveType (ec);
CheckObsoleteAttribute (probe_type);
if (expr == null)
return null;
- TypeExpr target = target_type.ResolveAsTypeTerminal (ec, false);
- if (target == null)
+ type = ec.DeclSpace.ResolveType (target_type, false, Location);
+
+ if (type == null)
return null;
- type = target.ResolveType (ec);
-
CheckObsoleteAttribute (type);
if (type.IsAbstract && type.IsSealed) {
// Special cases: string or type parameter comapred to null
//
if (oper == Operator.Equality || oper == Operator.Inequality){
- if ((!TypeManager.IsValueType (l) && (right is NullLiteral)) ||
- (!TypeManager.IsValueType (r) && (left is NullLiteral))) {
+ if ((l == TypeManager.string_type && (right is NullLiteral)) ||
+ (r == TypeManager.string_type && (left is NullLiteral))){
Type = TypeManager.bool_type;
return this;
//
// Also, a standard conversion must exist from either one
//
- if (!(Convert.ImplicitStandardConversionExists (ec, left, r) ||
- Convert.ImplicitStandardConversionExists (ec, right, l))){
+ if (!(Convert.ImplicitStandardConversionExists (left, r) ||
+ Convert.ImplicitStandardConversionExists (right, l))){
Error_OperatorCannotBeApplied ();
return null;
}
//
if (oper == Operator.Addition || oper == Operator.Subtraction) {
if (TypeManager.IsDelegateType (l)){
- if (((right.eclass == ExprClass.MethodGroup) ||
- (r == TypeManager.anonymous_method_type))){
- if ((RootContext.Version != LanguageVersion.ISO_1)){
- Expression tmp = Convert.ImplicitConversionRequired (ec, right, l, loc);
- if (tmp == null)
- return null;
- right = tmp;
- r = right.Type;
- }
+ if ((right.eclass == ExprClass.MethodGroup) &&
+ (RootContext.Version != LanguageVersion.ISO_1)){
+ Expression tmp = Convert.ImplicitConversionRequired (ec, right, l, loc);
+ if (tmp == null)
+ return null;
+ right = tmp;
+ r = right.Type;
}
if (TypeManager.IsDelegateType (r)){
- MethodInfo method;
- ArrayList args = new ArrayList (2);
+ MethodInfo method;
+ ArrayList args = new ArrayList (2);
- args = new ArrayList (2);
- args.Add (new Argument (left, Argument.AType.Expression));
- args.Add (new Argument (right, Argument.AType.Expression));
+ args = new ArrayList (2);
+ args.Add (new Argument (left, Argument.AType.Expression));
+ args.Add (new Argument (right, Argument.AType.Expression));
- if (oper == Operator.Addition)
- method = TypeManager.delegate_combine_delegate_delegate;
- else
- method = TypeManager.delegate_remove_delegate_delegate;
-
- if (l != r) {
- Error_OperatorCannotBeApplied ();
- return null;
- }
+ if (oper == Operator.Addition)
+ method = TypeManager.delegate_combine_delegate_delegate;
+ else
+ method = TypeManager.delegate_remove_delegate_delegate;
- return new BinaryDelegate (l, method, args);
+ if (l != r) {
+ Error_OperatorCannotBeApplied ();
+ return null;
}
+
+ return new BinaryDelegate (l, method, args);
+ }
}
//
public class StringConcat : Expression {
ArrayList operands;
bool invalid = false;
- bool emit_conv_done = false;
- //
- // Are we also concating objects?
- //
- bool is_strings_only = true;
+
public StringConcat (EmitContext ec, Location loc, Expression left, Expression right)
{
MethodInfo concat_method = null;
//
- // Do conversion to arguments; check for strings only
+ // Are we also concating objects?
//
+ bool is_strings_only = true;
- // This can get called multiple times, so we have to deal with that.
- if (!emit_conv_done) {
- emit_conv_done = true;
+ //
+ // Do conversion to arguments; check for strings only
+ //
for (int i = 0; i < operands.Count; i ++) {
Expression e = (Expression) operands [i];
is_strings_only &= e.Type == TypeManager.string_type;
// method might look at the type of this expression, see it is a
// string and emit a string [] when we want an object [];
- e = new EmptyCast (e, TypeManager.object_type);
+ e = Convert.ImplicitConversion (ec, e, TypeManager.object_type, loc);
}
operands [i] = new Argument (e, Argument.AType.Expression);
}
- }
//
// Find the right method
Label false_target = ig.DefineLabel ();
Label end_target = ig.DefineLabel ();
+ ig.Emit (OpCodes.Nop);
+
left.Emit (ec);
left_temp.Store (ec);
ig.MarkLabel (false_target);
op.Emit (ec);
ig.MarkLabel (end_target);
+
+ ig.Emit (OpCodes.Nop);
}
}
public class LocalVariableReference : Expression, IAssignMethod, IMemoryLocation, IVariable {
public readonly string Name;
public readonly Block Block;
- public LocalInfo local_info;
+ LocalInfo local_info;
bool is_readonly;
- bool prepared;
- LocalTemporary temp;
public LocalVariableReference (Block block, string name, Location l)
{
eclass = ExprClass.Variable;
}
- //
// Setting `is_readonly' to false will allow you to create a writable
// reference to a read-only variable. This is used by foreach and using.
- //
public LocalVariableReference (Block block, string name, Location l,
LocalInfo local_info, bool is_readonly)
: this (block, name, l)
}
public VariableInfo VariableInfo {
- get {
- return local_info.VariableInfo;
- }
+ get { return local_info.VariableInfo; }
}
public bool IsReadOnly {
}
}
- protected Expression DoResolveBase (EmitContext ec, Expression lvalue_right_side)
+ protected void DoResolveBase (EmitContext ec)
{
if (local_info == null) {
local_info = Block.GetLocalInfo (Name);
}
type = local_info.VariableType;
-
- VariableInfo variable_info = local_info.VariableInfo;
- if (lvalue_right_side != null){
- if (is_readonly){
- Error (1604, "cannot assign to `" + Name + "' because it is readonly");
- return null;
- }
-
- if (variable_info != null)
- variable_info.SetAssigned (ec);
- }
-
+#if false
+ if (ec.InAnonymousMethod)
+ Block.LiftVariable (local_info);
+#endif
+ }
+
+ protected Expression DoResolve (EmitContext ec, bool is_lvalue)
+ {
Expression e = Block.GetConstantExpression (Name);
if (e != null) {
local_info.Used = true;
return e.Resolve (ec);
}
+ VariableInfo variable_info = local_info.VariableInfo;
if ((variable_info != null) && !variable_info.IsAssigned (ec, loc))
return null;
- if (lvalue_right_side == null)
+ if (!is_lvalue)
local_info.Used = true;
- if (ec.CurrentAnonymousMethod != null){
- //
- // If we are referencing a variable from the external block
- // flag it for capturing
- //
- if (local_info.Block.Toplevel != ec.CurrentBlock.Toplevel){
- ec.CaptureVariable (local_info);
- //Console.WriteLine ("Capturing at " + loc);
- }
- }
-
+ if (local_info.LocalBuilder == null)
+ return ec.RemapLocal (local_info);
+
return this;
}
public override Expression DoResolve (EmitContext ec)
{
- return DoResolveBase (ec, null);
+ DoResolveBase (ec);
+
+ return DoResolve (ec, false);
}
override public Expression DoResolveLValue (EmitContext ec, Expression right_side)
{
- Expression ret = DoResolveBase (ec, right_side);
- if (ret != null)
- CheckObsoleteAttribute (ret.Type);
+ DoResolveBase (ec);
+
+ VariableInfo variable_info = local_info.VariableInfo;
+ if (variable_info != null)
+ variable_info.SetAssigned (ec);
+
+ Expression e = DoResolve (ec, true);
+
+ if (e == null)
+ return null;
+
+ if (is_readonly){
+ Error (1604, "cannot assign to `" + Name + "' because it is readonly");
+ return null;
+ }
+
+ CheckObsoleteAttribute (e.Type);
+
+ if (local_info.LocalBuilder == null)
+ return ec.RemapLocalLValue (local_info, right_side);
- return ret;
+ return this;
}
public bool VerifyFixed (bool is_expression)
{
ILGenerator ig = ec.ig;
- if (local_info.FieldBuilder == null){
- //
- // A local variable on the local CLR stack
- //
ig.Emit (OpCodes.Ldloc, local_info.LocalBuilder);
- } else {
- //
- // A local variable captured by anonymous methods.
- //
- if (!prepared)
- ec.EmitCapturedVariableInstance (local_info);
-
- ig.Emit (OpCodes.Ldfld, local_info.FieldBuilder);
- }
}
public void Emit (EmitContext ec, bool leave_copy)
{
Emit (ec);
- if (leave_copy){
+ if (leave_copy)
ec.ig.Emit (OpCodes.Dup);
- if (local_info.FieldBuilder != null){
- temp = new LocalTemporary (ec, Type);
- temp.Store (ec);
- }
- }
}
public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool prepare_for_load)
{
- ILGenerator ig = ec.ig;
- prepared = prepare_for_load;
-
- if (local_info.FieldBuilder == null){
- //
- // A local variable on the local CLR stack
- //
- if (local_info.LocalBuilder == null)
- throw new Exception ("This should not happen: both Field and Local are null");
-
source.Emit (ec);
if (leave_copy)
ec.ig.Emit (OpCodes.Dup);
- ig.Emit (OpCodes.Stloc, local_info.LocalBuilder);
- } else {
- //
- // A local variable captured by anonymous methods or itereators.
- //
- ec.EmitCapturedVariableInstance (local_info);
-
- if (prepare_for_load)
- ig.Emit (OpCodes.Dup);
- source.Emit (ec);
- if (leave_copy){
- ig.Emit (OpCodes.Dup);
- temp = new LocalTemporary (ec, Type);
- temp.Store (ec);
- }
- ig.Emit (OpCodes.Stfld, local_info.FieldBuilder);
- if (temp != null)
- temp.Emit (ec);
- }
+ ec.ig.Emit (OpCodes.Stloc, local_info.LocalBuilder);
}
public void AddressOf (EmitContext ec, AddressOp mode)
{
ILGenerator ig = ec.ig;
- if (local_info.FieldBuilder == null){
- //
- // A local variable on the local CLR stack
- //
ig.Emit (OpCodes.Ldloca, local_info.LocalBuilder);
- } else {
- //
- // A local variable captured by anonymous methods or iterators
- //
- ec.EmitCapturedVariableInstance (local_info);
- ig.Emit (OpCodes.Ldflda, local_info.FieldBuilder);
- }
}
public override string ToString ()
VariableInfo vi;
public Parameter.Modifier mod;
public bool is_ref, is_out, prepared;
-
- public bool IsOut {
- get {
- return is_out;
- }
- }
-
- public bool IsRef {
- get {
- return is_ref;
- }
- }
-
LocalTemporary temp;
public ParameterReference (Parameters pars, Block block, int idx, string name, Location loc)
public bool IsAssigned (EmitContext ec, Location loc)
{
- if (!ec.DoFlowAnalysis || !is_out || ec.CurrentBranching.IsAssigned (vi))
+ if (!ec.DoFlowAnalysis || !is_out ||
+ ec.CurrentBranching.IsAssigned (vi))
return true;
Report.Error (165, loc,
public bool IsFieldAssigned (EmitContext ec, string field_name, Location loc)
{
- if (!ec.DoFlowAnalysis || !is_out || ec.CurrentBranching.IsFieldAssigned (vi, field_name))
+ if (!ec.DoFlowAnalysis || !is_out ||
+ ec.CurrentBranching.IsFieldAssigned (vi, field_name))
return true;
Report.Error (170, loc,
protected void DoResolveBase (EmitContext ec)
{
- type = pars.GetParameterInfo (ec, idx, out mod);
+ type = pars.GetParameterInfo (ec.DeclSpace, idx, out mod);
is_ref = (mod & Parameter.Modifier.ISBYREF) != 0;
is_out = (mod & Parameter.Modifier.OUT) != 0;
eclass = ExprClass.Variable;
if (is_out)
vi = block.ParameterMap [idx];
-
- if (ec.CurrentAnonymousMethod != null){
- if (is_ref){
- Report.Error (1628, Location,
- "Can not reference a ref or out parameter in an anonymous method");
- return;
- }
-
- //
- // If we are referencing the parameter from the external block
- // flag it for capturing
- //
- //Console.WriteLine ("Is parameter `{0}' local? {1}", name, block.IsLocalParameter (name));
- if (!block.IsLocalParameter (name)){
- ec.CaptureParameter (name, type, idx);
- }
- }
}
//
arg_idx++;
EmitLdArg (ig, arg_idx);
-
- //
- // FIXME: Review for anonymous methods
- //
}
public override void Emit (EmitContext ec)
{
- if (ec.HaveCaptureInfo && ec.IsParameterCaptured (name)){
- ec.EmitParameter (name);
- return;
- }
-
Emit (ec, false);
}
public void Emit (EmitContext ec, bool leave_copy)
{
ILGenerator ig = ec.ig;
+
int arg_idx = idx;
if (!ec.IsStatic)
public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool prepare_for_load)
{
- if (ec.HaveCaptureInfo && ec.IsParameterCaptured (name)){
- ec.EmitAssignParameter (name, source, leave_copy, prepare_for_load);
- return;
- }
-
ILGenerator ig = ec.ig;
int arg_idx = idx;
public void AddressOf (EmitContext ec, AddressOp mode)
{
- if (ec.HaveCaptureInfo && ec.IsParameterCaptured (name)){
- ec.EmitAddressOfParameter (name);
- return;
- }
-
int arg_idx = idx;
if (!ec.IsStatic)
}
Expr = Expr.ResolveLValue (ec, Expr);
} else if (ArgType == AType.Out)
- Expr = Expr.ResolveLValue (ec, EmptyExpression.Null);
+ Expr = Expr.ResolveLValue (ec, new EmptyExpression ());
else
Expr = Expr.Resolve (ec);
if (Expr is ParameterReference){
ParameterReference pr = (ParameterReference) Expr;
- if (pr.IsRef)
+ if (pr.is_ref)
pr.EmitLoad (ec);
else {
Expression expr;
MethodBase method = null;
+ bool is_base;
static Hashtable method_parameter_cache;
/// <summary>
/// Determines "better conversion" as specified in 7.4.2.3
///
- /// Returns : p if a->p is better,
- /// q if a->q is better,
- /// null if neither is better
+ /// Returns : 1 if a->p is better
+ /// 0 if a->q or neither is better
/// </summary>
- static Type BetterConversion (EmitContext ec, Argument a, Type p, Type q, Location loc)
+ static int BetterConversion (EmitContext ec, Argument a, Type p, Type q, Location loc)
{
Type argument_type = TypeManager.TypeToCoreType (a.Type);
Expression argument_expr = a.Expr;
if (p == null || q == null)
throw new InternalErrorException ("BetterConversion Got a null conversion");
+ //
+ // This is a special case since csc behaves this way.
+ //
+ if (argument_expr is NullLiteral &&
+ p == TypeManager.string_type &&
+ q == TypeManager.object_type)
+ return 1;
+ else if (argument_expr is NullLiteral &&
+ p == TypeManager.object_type &&
+ q == TypeManager.string_type)
+ return 0;
+
+ //
+ // csc behaves this way so we emulate it. Basically, if the argument
+ // is null and one of the types to compare is 'object' and the other
+ // is a reference type, we prefer the other.
+ //
+ // I can't find this anywhere in the spec but we can interpret this
+ // to mean that null can be of any type you wish in such a context
+ //
+ if (argument_expr is NullLiteral &&
+ !p.IsValueType &&
+ q == TypeManager.object_type)
+ return 1;
+ else if (argument_expr is NullLiteral &&
+ !q.IsValueType &&
+ p == TypeManager.object_type)
+ return 0;
+
+
if (p == q)
- return null;
-
- if (argument_expr is NullLiteral) {
- //
- // If the argument is null and one of the types to compare is 'object' and
- // the other is a reference type, we prefer the other.
- //
- // This follows from the usual rules:
- // * There is an implicit conversion from 'null' to type 'object'
- // * There is an implicit conversion from 'null' to any reference type
- // * There is an implicit conversion from any reference type to type 'object'
- // * There is no implicit conversion from type 'object' to other reference types
- // => Conversion of 'null' to a reference type is better than conversion to 'object'
- //
- // FIXME: This probably isn't necessary, since the type of a NullLiteral is 'System.Null'.
- // I think it used to be 'object' and thus needed a special case to avoid the
- // immediately following two checks.
- //
- if (!p.IsValueType && q == TypeManager.object_type)
- return p;
- if (!q.IsValueType && p == TypeManager.object_type)
- return q;
- }
-
+ return 0;
+
if (argument_type == p)
- return p;
+ return 1;
if (argument_type == q)
- return q;
+ return 0;
Expression p_tmp = new EmptyExpression (p);
Expression q_tmp = new EmptyExpression (q);
-
- bool p_to_q = Convert.ImplicitConversionExists (ec, p_tmp, q);
- bool q_to_p = Convert.ImplicitConversionExists (ec, q_tmp, p);
-
- if (p_to_q && !q_to_p)
- return p;
-
- if (q_to_p && !p_to_q)
- return q;
+
+ if (Convert.ImplicitConversionExists (ec, p_tmp, q) == true &&
+ Convert.ImplicitConversionExists (ec, q_tmp, p) == false)
+ return 1;
if (p == TypeManager.sbyte_type)
if (q == TypeManager.byte_type || q == TypeManager.ushort_type ||
q == TypeManager.uint32_type || q == TypeManager.uint64_type)
- return p;
- if (q == TypeManager.sbyte_type)
- if (p == TypeManager.byte_type || p == TypeManager.ushort_type ||
- p == TypeManager.uint32_type || p == TypeManager.uint64_type)
- return q;
+ return 1;
if (p == TypeManager.short_type)
if (q == TypeManager.ushort_type || q == TypeManager.uint32_type ||
q == TypeManager.uint64_type)
- return p;
-
- if (q == TypeManager.short_type)
- if (p == TypeManager.ushort_type || p == TypeManager.uint32_type ||
- p == TypeManager.uint64_type)
- return q;
+ return 1;
if (p == TypeManager.int32_type)
if (q == TypeManager.uint32_type || q == TypeManager.uint64_type)
- return p;
-
- if (q == TypeManager.int32_type)
- if (p == TypeManager.uint32_type || p == TypeManager.uint64_type)
- return q;
+ return 1;
if (p == TypeManager.int64_type)
if (q == TypeManager.uint64_type)
- return p;
- if (q == TypeManager.int64_type)
- if (p == TypeManager.uint64_type)
- return q;
+ return 1;
- return null;
+ return 0;
}
/// <summary>
/// and the current best match
/// </summary>
/// <remarks>
- /// Returns a boolean indicating :
- /// false if candidate ain't better
- /// true if candidate is better than the current best match
+ /// Returns an integer indicating :
+ /// 0 if candidate ain't better
+ /// 1 if candidate is better than the current best match
/// </remarks>
- static bool BetterFunction (EmitContext ec, ArrayList args, int argument_count,
- MethodBase candidate, bool candidate_params,
- MethodBase best, bool best_params, Location loc)
+ static int BetterFunction (EmitContext ec, ArrayList args, int argument_count,
+ MethodBase candidate, bool candidate_params,
+ MethodBase best, bool best_params, Location loc)
{
ParameterData candidate_pd = GetParameterData (candidate);
ParameterData best_pd = GetParameterData (best);
// }
//
// interface IFooBar : IFoo, IBar {}
- //
+ //
// We cant tell if IFoo.DoIt is better than IBar.DoIt
//
// However, we have to consider that
// Trim (); is better than Trim (params char[] chars);
//
if (cand_count == 0 && argument_count == 0)
- return !candidate_params && best_params;
+ return best_params ? 1 : 0;
if ((candidate_pd.ParameterModifier (cand_count - 1) != Parameter.Modifier.PARAMS) &&
(candidate_pd.ParameterModifier (cand_count - 1) != Parameter.Modifier.ARGLIST))
if (cand_count != argument_count)
- return false;
+ return 0;
- bool better_at_least_one = false;
- bool is_equal = true;
+ int rating1 = 0, rating2 = 0;
for (int j = 0; j < argument_count; ++j) {
+ int x, y;
+
Argument a = (Argument) args [j];
- Type ct = TypeManager.TypeToCoreType (candidate_pd.ParameterType (j));
- Type bt = TypeManager.TypeToCoreType (best_pd.ParameterType (j));
+ Type ct = TypeManager.TypeToCoreType (
+ candidate_pd.ParameterType (j));
+ Type bt = TypeManager.TypeToCoreType (
+ best_pd.ParameterType (j));
if (candidate_pd.ParameterModifier (j) == Parameter.Modifier.PARAMS)
if (candidate_params)
if (best_params)
bt = TypeManager.GetElementType (bt);
- if (!ct.Equals (bt))
- is_equal = false;
+ x = BetterConversion (ec, a, ct, bt, loc);
+ y = BetterConversion (ec, a, bt, ct, loc);
- Type better = BetterConversion (ec, a, ct, bt, loc);
- // for each argument, the conversion to 'ct' should be no worse than
- // the conversion to 'bt'.
- if (better == bt)
- return false;
+ if (x < y)
+ return 0;
- // for at least one argument, the conversion to 'ct' should be better than
- // the conversion to 'bt'.
- if (better == ct)
- better_at_least_one = true;
+ rating1 += x;
+ rating2 += y;
}
//
// force it to select the candidate
//
if (!candidate_params && best_params && cand_count == argument_count)
- return true;
-
- //
- // If two methods have equal parameter types, but
- // only one of them is generic, the non-generic one wins.
- //
- if (is_equal) {
- if (TypeManager.IsGenericMethod (best) && !TypeManager.IsGenericMethod (candidate))
- return true;
- else if (!TypeManager.IsGenericMethod (best) && TypeManager.IsGenericMethod (candidate))
- return false;
- }
+ return 1;
- return better_at_least_one;
+ if (rating1 > rating2)
+ return 1;
+ else
+ return 0;
}
public static string FullMethodDesc (MethodBase mb)
Argument a = (Argument) arguments [i];
Parameter.Modifier a_mod = a.GetParameterModifier () &
- (unchecked (~(Parameter.Modifier.OUT | Parameter.Modifier.REF)));
+ ~(Parameter.Modifier.OUT | Parameter.Modifier.REF);
Parameter.Modifier p_mod = pd.ParameterModifier (i) &
- (unchecked (~(Parameter.Modifier.OUT | Parameter.Modifier.REF)));
+ ~(Parameter.Modifier.OUT | Parameter.Modifier.REF);
if (a_mod == p_mod) {
Argument a = (Argument) arguments [i];
Parameter.Modifier a_mod = a.GetParameterModifier () &
- unchecked (~(Parameter.Modifier.OUT | Parameter.Modifier.REF));
+ ~(Parameter.Modifier.OUT | Parameter.Modifier.REF);
Parameter.Modifier p_mod = pd.ParameterModifier (i) &
- unchecked (~(Parameter.Modifier.OUT | Parameter.Modifier.REF));
+ ~(Parameter.Modifier.OUT | Parameter.Modifier.REF);
if (a_mod == p_mod ||
if (BetterFunction (ec, Arguments, arg_count,
candidate, cand_params,
- method, method_params, loc)) {
+ method, method_params, loc) != 0) {
method = candidate;
method_params = cand_params;
}
continue;
bool cand_params = candidate_to_form != null && candidate_to_form.Contains (candidate);
- if (!BetterFunction (ec, Arguments, arg_count,
+ if (BetterFunction (ec, Arguments, arg_count,
method, method_params,
candidate, cand_params,
- loc)) {
+ loc) != 1) {
Report.SymbolRelatedToPreviousError (candidate);
ambiguous = true;
}
a.Expr = conv;
}
- if (parameter_type.IsPointer){
- if (!ec.InUnsafe){
- UnsafeError (loc);
- return false;
- }
- }
-
Parameter.Modifier a_mod = a.GetParameterModifier () &
- unchecked (~(Parameter.Modifier.OUT | Parameter.Modifier.REF));
+ ~(Parameter.Modifier.OUT | Parameter.Modifier.REF);
Parameter.Modifier p_mod = pd.ParameterModifier (j) &
- unchecked (~(Parameter.Modifier.OUT | Parameter.Modifier.REF));
+ ~(Parameter.Modifier.OUT | Parameter.Modifier.REF);
if (a_mod != p_mod &&
pd.ParameterModifier (pd_count - 1) != Parameter.Modifier.PARAMS) {
// First, resolve the expression that is used to
// trigger the invocation
//
+ if (expr is BaseAccess)
+ is_base = true;
+
if (expr is ConstructedType)
expr = ((ConstructedType) expr).GetSimpleName (ec);
//
// Only base will allow this invocation to happen.
//
- if (mg.IsBase && method.IsAbstract){
+ if (is_base && method.IsAbstract){
Report.Error (205, loc, "Cannot call an abstract base member: " +
FullMethodDesc (method));
return null;
}
if (method.Name == "Finalize" && Arguments == null) {
- if (mg.IsBase)
+ if (is_base)
Report.Error (250, loc, "Do not directly call your base class Finalize method. It is called automatically from your destructor");
else
Report.Error (245, loc, "Destructors and object.Finalize cannot be called directly. Consider calling IDisposable.Dispose if available");
{
MethodGroupExpr mg = (MethodGroupExpr) this.expr;
- EmitCall (ec, mg.IsBase, method.IsStatic, mg.InstanceExpression, method, Arguments, loc);
+ EmitCall (ec, is_base, method.IsStatic, mg.InstanceExpression, method, Arguments, loc);
}
public override void EmitStatement (EmitContext ec)
//
// First try to resolve it as a cast.
//
- TypeExpr te = expr.ResolveAsTypeTerminal (ec, true);
- if (te != null) {
- Cast cast = new Cast (te, argument, loc);
+ type = ec.DeclSpace.ResolveType (expr, true, loc);
+ if (type != null) {
+ Cast cast = new Cast (new TypeExpression (type, loc), argument, loc);
return cast.Resolve (ec);
}
//
// First try to resolve it as a cast.
//
- TypeExpr te = expr.ResolveAsTypeTerminal (ec, true);
- if (te != null) {
+ type = ec.DeclSpace.ResolveType (expr, true, loc);
+ if (type != null) {
error201 ();
return null;
}
return this;
}
- TypeExpr texpr = RequestedType.ResolveAsTypeTerminal (ec, false);
- if (texpr == null)
- return null;
-
- type = texpr.ResolveType (ec);
+ type = ec.DeclSpace.ResolveType (RequestedType, false, loc);
+
if (type == null)
return null;
return null;
}
- bool is_struct = type.IsValueType;
+ bool is_struct = type.IsValueType && !type.IsGenericInstance;
eclass = ExprClass.Value;
//
//
// Lookup the type
//
- TypeExpr array_type_expr;
+ Expression array_type_expr;
array_type_expr = new ComposedCast (requested_base_type, array_qualifier.ToString (), loc);
- array_type_expr = array_type_expr.ResolveAsTypeTerminal (ec, false);
- if (array_type_expr == null)
+ type = ec.DeclSpace.ResolveType (array_type_expr, false, loc);
+
+ if (type == null)
return false;
- type = array_type_expr.ResolveType (ec);
-
if (!type.IsArray) {
Error (622, "Can only use array initializer expressions to assign to array types. Try using a new expression instead.");
return false;
/// Implements the typeof operator
/// </summary>
public class TypeOf : Expression {
- public Expression QueriedType;
+ public readonly Expression QueriedType;
protected Type typearg;
public TypeOf (Expression queried_type, Location l)
public override Expression DoResolve (EmitContext ec)
{
- TypeExpr texpr = QueriedType.ResolveAsTypeTerminal (ec, false);
- if (texpr == null)
- return null;
+ typearg = ec.DeclSpace.ResolveType (QueriedType, false, loc);
- typearg = texpr.ResolveType (ec);
+ if (typearg == null)
+ return null;
if (typearg == TypeManager.void_type) {
Error (673, "System.Void cannot be used from C# - " +
return null;
}
- TypeExpr texpr = QueriedType.ResolveAsTypeTerminal (ec, false);
- if (texpr == null)
+ QueriedType = ec.DeclSpace.ResolveTypeExpr (QueriedType, false, loc);
+ if (QueriedType == null || QueriedType.Type == null)
return null;
- if (texpr is TypeParameterExpr){
- ((TypeParameterExpr)texpr).Error_CannotUseAsUnmanagedType (loc);
+ if (QueriedType is TypeParameterExpr){
+ ((TypeParameterExpr)QueriedType).Error_CannotUseAsUnmanagedType (loc);
return null;
}
- type_queried = texpr.ResolveType (ec);
+ type_queried = QueriedType.Type;
+ if (type_queried == null)
+ return null;
CheckObsoleteAttribute (type_queried);
if (t == null)
return null;
- TypeArguments the_args = args;
if (TypeManager.HasGenericArguments (expr_type)) {
Type[] decl_args = TypeManager.GetTypeArguments (expr_type);
if (args != null)
new_args.Add (args);
- the_args = new_args;
+ args = new_args;
}
- if (the_args != null) {
- ConstructedType ctype = new ConstructedType (t, the_args, loc);
+ if (args != null) {
+ ConstructedType ctype = new ConstructedType (t, args, loc);
return ctype.ResolveAsTypeStep (ec);
}
/// is needed (the `New' class).
/// </summary>
public class EmptyExpression : Expression {
- public static readonly EmptyExpression Null = new EmptyExpression ();
-
- // TODO: should be protected
public EmptyExpression ()
{
type = TypeManager.object_type;
public override TypeExpr DoResolveAsTypeStep (EmitContext ec)
{
- TypeExpr lexpr = left.ResolveAsTypeTerminal (ec, false);
- if (lexpr == null)
+ Type ltype = ec.DeclSpace.ResolveType (left, false, loc);
+ if (ltype == null)
return null;
- Type ltype = lexpr.ResolveType (ec);
-
if ((ltype == TypeManager.void_type) && (dim != "*")) {
Report.Error (1547, Location,
"Keyword 'void' cannot be used in this context");
return null;
}
+ if (!ec.ResolvingTypeTree){
+ //
+ // If the above flag is set, this is being invoked from the ResolveType function.
+ // Upper layers take care of the type validity in this context.
+ //
if (!ec.InUnsafe && type.IsPointer){
UnsafeError (loc);
return null;
}
+ }
eclass = ExprClass.Type;
return this;
return null;
}
- TypeExpr texpr = t.ResolveAsTypeTerminal (ec, false);
- if (texpr == null)
- return null;
+ otype = ec.DeclSpace.ResolveType (t, false, loc);
- otype = texpr.ResolveType (ec);
if (otype == null)
return null;
Type t2 = constraints.ClassConstraint;
TypeExpr e2 = constraints.class_constraint;
- if (!Convert.ImplicitReferenceConversionExists (ec, e1, t2) &&
- !Convert.ImplicitReferenceConversionExists (ec, e2, t1)) {
+ if (!Convert.ImplicitReferenceConversionExists (e1, t2) &&
+ !Convert.ImplicitReferenceConversionExists (e2, t1)) {
Report.Error (455, loc,
"Type parameter `{0}' inherits " +
"conflicting constraints `{1}' and `{2}'",
throw new InvalidOperationException ();
this.type = type;
- TypeManager.AddTypeParameter (type, this);
- }
-
- public void DefineConstraints ()
- {
+ Type[] ifaces = null;
if (constraints != null)
constraints.Define (type);
+ TypeManager.AddTypeParameter (type, this);
}
public bool DefineType (EmitContext ec)
get { return false; }
}
- public override bool CheckAccessLevel (DeclSpace ds)
- {
- return true;
- }
-
public void Error_CannotUseAsUnmanagedType (Location loc)
{
Report.Error (-203, loc, "Can not use type parameter as unamanged type");
atypes = new Type [count];
for (int i = 0; i < count; i++){
- TypeExpr te = ((Expression) args [i]).ResolveAsTypeTerminal (ec, false);
+ TypeExpr te = ds.ResolveTypeExpr (
+ (Expression) args [i], false, Location);
if (te == null) {
ok = false;
continue;
return false;
}
- return Convert.ImplicitStandardConversionExists (ec, expr, ctype);
+ return Convert.ImplicitStandardConversionExists (expr, ctype);
}
protected bool CheckConstraints (EmitContext ec, int index)
public override TypeExpr DoResolveAsTypeStep (EmitContext ec)
{
- if (type != null)
- return this;
if (gt != null)
- return DoResolveType (ec);
+ return this;
//
// First, resolve the generic type.
new_args.Add (args);
args = new_args;
- return DoResolveType (ec);
+ return this;
}
Type t;
int num_args;
SimpleName sn = new SimpleName (name, loc);
- TypeExpr resolved = sn.ResolveAsTypeTerminal (ec, true);
+ TypeExpr resolved = sn.ResolveAsTypeTerminal (ec);
if ((resolved == null) || (resolved.Type == null)) {
Report.Error (246, loc,
"The type or namespace name `{0}<...>' "+
}
gt = t.GetGenericTypeDefinition ();
- return DoResolveType (ec);
+ return this;
}
- TypeExpr DoResolveType (EmitContext ec)
+ public override Type ResolveType (EmitContext ec)
{
+ if (type != null)
+ return type;
+ if (DoResolveAsTypeStep (ec) == null)
+ return null;
+
//
// Resolve the arguments.
//
// Now bind the parameters.
//
type = gt.BindGenericParameters (atypes);
- return this;
+ return type;
}
public Expression GetSimpleName (EmitContext ec)
return true;
}
- public bool Define (MethodBuilder mb, Type return_type)
+ public bool Define (MethodBuilder mb)
{
if (!Define ())
return false;
for (int i = 0; i < TypeParameters.Length; i++)
TypeParameters [i].Define (gen_params [i]);
- ec = new EmitContext (
- this, this, Location, null, return_type, ModFlags, false);
-
return true;
}
"catch clause");
return false;
}
- if (ec.CurrentAnonymousMethod != null){
- Report.Error (1621, loc, "yield statement can not appear inside an anonymoud method");
+ if (ec.InAnonymousMethod){
+ Report.Error (1621, loc, "yield statement can not appear " +
+ "inside an anonymoud method");
return false;
}
}
public class Iterator : Class {
- ToplevelBlock original_block;
- ToplevelBlock block;
string original_name;
+ Block original_block;
+ Block block;
Type iterator_type;
TypeExpr iterator_type_expr;
// Context from the original method
//
TypeContainer container;
- TypeExpr current_type;
- Type this_type;
Type return_type;
Type [] param_types;
InternalParameters parameters;
Label dispatcher = ig.DefineLabel ();
ig.Emit (OpCodes.Br, dispatcher);
- ec.RemapToProxy = true;
Label [] labels = new Label [resume_points.Count];
for (int i = 0; i < labels.Length; i++) {
ResumePoint point = (ResumePoint) resume_points [i];
ig.EndExceptionBlock ();
ig.Emit (OpCodes.Br, end);
}
- ec.RemapToProxy = false;
ig.MarkLabel (dispatcher);
ig.Emit (OpCodes.Ldarg_0);
//
public Iterator (TypeContainer container, string name, Type return_type,
Type [] param_types, InternalParameters parameters,
- int modifiers, ToplevelBlock block, Location loc)
+ int modifiers, Block block, Location loc)
: base (container.NamespaceEntry, container, MakeProxyName (name),
Modifiers.PRIVATE, null, loc)
{
this.parameters = parameters;
this.original_name = name;
this.original_block = block;
- this.block = new ToplevelBlock (loc);
+ this.block = new Block (null);
fields = new Hashtable ();
public bool DefineIterator ()
{
- ec = new EmitContext (this, Mono.CSharp.Location.Null, null, null, ModFlags);
-
if (!CheckType (return_type)) {
Report.Error (
1624, Location,
}
}
- if (container.CurrentType != null)
- this_type = container.CurrentType.ResolveType (ec);
- else
- this_type = container.TypeBuilder;
-
generic_args = new TypeArguments (Location);
generic_args.Add (new TypeExpression (iterator_type, Location));
//
protected override bool DefineNestedTypes ()
{
- if (CurrentType != null)
- current_type = CurrentType;
- else
- current_type = new TypeExpression (TypeBuilder, Location);
-
Define_Fields ();
Define_Constructor ();
Define_Current (false);
ArrayList args = new ArrayList ();
if (!is_static) {
- Type t = this_type;
+ Type t = container.TypeBuilder;
args.Add (new Argument (
new ThisParameterReference (t, 0, Location)));
}
new SimpleParameterReference (t, first + i, Location)));
}
- Expression new_expr = new New (current_type, args, Location);
+ Expression new_expr = new New (
+ new TypeExpression (TypeBuilder, Location), args, Location);
block.AddStatement (new NoCheckReturn (new_expr, Location));
}
if (!is_static) {
this_field = new Field (
- this, new TypeExpression (this_type, loc),
+ this,
+ new TypeExpression (container.TypeBuilder, Location),
Modifiers.PRIVATE, "this", null, null, loc);
AddField (this_field);
}
if (!is_static)
list.Add (new Parameter (
- new TypeExpression (this_type, Location),
+ new TypeExpression (container.TypeBuilder, Location),
"this", Parameter.Modifier.NONE, null));
list.Add (new Parameter (
TypeManager.system_boolean_expr, "initialized",
Location);
AddConstructor (ctor);
- ToplevelBlock block = ctor.Block = new ToplevelBlock (Location);
+ Block block = ctor.Block = new Block (null);
if (!is_static) {
- Type t = this_type;
+ Type t = container.TypeBuilder;
Assign assign = new Assign (
new FieldExpression (this_field),
MemberName name = new MemberName (left, "Current", null);
- ToplevelBlock get_block = new ToplevelBlock (Location);
+ Block get_block = new Block (null);
get_block.AddStatement (new If (
new Binary (
new FieldExpression (current_field), Location),
Location));
- Accessor getter = new Accessor (get_block, 0, null, Location);
+ Accessor getter = new Accessor (get_block, null, Location);
Property current = new Property (
this, type, 0, false, name, null, getter, null, Location);
Location.Null);
AddMethod (move_next);
- ToplevelBlock block = move_next.Block = new ToplevelBlock (Location);
+ Block block = move_next.Block = new Block (null);
MoveNextMethod inline = new MoveNextMethod (this, Location);
block.AddStatement (inline);
Location.Null);
AddMethod (get_enumerator);
- get_enumerator.Block = new ToplevelBlock (Location);
+ get_enumerator.Block = new Block (null);
Expression ce = new MemberAccess (
new SimpleName ("System.Threading.Interlocked", Location),
args.Add (new Argument (
new FieldExpression (parameter_fields [i])));
- Expression new_expr = new New (current_type, args, Location);
+ Expression new_expr = new New (
+ new TypeExpression (TypeBuilder, Location), args, Location);
get_enumerator.Block.AddStatement (new Return (new_expr, Location));
}
Parameters.EmptyReadOnlyParameters, null, Location);
AddMethod (reset);
- reset.Block = new ToplevelBlock (Location);
+ reset.Block = new Block (null);
reset.Block.AddStatement (Create_ThrowNotSupported ());
}
Parameters.EmptyReadOnlyParameters, null, Location);
AddMethod (dispose);
- dispose.Block = new ToplevelBlock (Location);
+ dispose.Block = new Block (null);
dispose.Block.AddStatement (new DisposeMethod (this, Location));
}
- public ToplevelBlock Block {
+ public Block Block {
get { return block; }
}
// According to section 16.3.1, the namespace-or-type-name is resolved
// as if the immediately containing namespace body has no using-directives.
resolved = NamespaceEntry.Lookup (
- null, alias, Alias.CountTypeArguments, true, Location);
+ null, alias, Alias.CountTypeArguments, true, false, Location);
NamespaceEntry curr_ns = NamespaceEntry.Parent;
while ((curr_ns != null) && (resolved == null)) {
resolved = curr_ns.Lookup (
null, alias, Alias.CountTypeArguments,
- false, Location);
+ false, false, Location);
if (resolved == null)
curr_ns = curr_ns.Parent;
if (using_clauses == null)
using_clauses = new ArrayList ();
- foreach (UsingEntry old_entry in using_clauses) {
- if (old_entry.Name == ns) {
- if (RootContext.WarningLevel >= 3)
+ if (RootContext.WarningLevel >= 3) {
+ foreach (UsingEntry old_entry in using_clauses){
+ if (old_entry.Name == ns){
Report.Warning (105, loc, "The using directive for '{0}' appeared previously in this namespace", ns);
return;
+ }
}
}
}
public IAlias Lookup (DeclSpace ds, string name, int num_type_params,
- bool ignore_using, Location loc)
+ bool ignore_using, bool silent, Location loc)
{
IAlias o;
Namespace ns;
string first = name.Substring (0, pos);
string last = name.Substring (pos + 1);
- o = Lookup (ds, first, 0, ignore_using, loc);
+ o = Lookup (ds, first, 0, ignore_using, silent, loc);
if (o == null)
return null;
match = using_ns.Lookup (ds, name, loc);
if ((match != null) && match.IsType){
if (t != null) {
- DeclSpace.Error_AmbiguousTypeReference (loc, name, t.Name, match.Name);
+ if (!silent)
+ DeclSpace.Error_AmbiguousTypeReference (loc, name, t.Name, match.Name);
return null;
} else {
t = match;
continue;
}
- error246 (entry.Location, entry.Alias.GetPartialName ());
+ error246 (entry.Location, entry.Alias.ToString ());
}
}
}
public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
{
if (a.Type == TypeManager.marshal_as_attr_type) {
- UnmanagedMarshal marshal = a.GetMarshal (this);
+ UnmanagedMarshal marshal = a.GetMarshal ();
if (marshal != null) {
builder.SetMarshal (marshal);
- }
- return;
+ return;
}
-
- if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
- a.Error_InvalidSecurityParent ();
+ Report.Warning (-24, a.Location, "The Microsoft Runtime cannot set this marshal info. Please use the Mono runtime instead.");
return;
}
static string[] attribute_targets = new string [] { "param" };
- public Expression TypeName;
+ public readonly Expression TypeName;
public readonly Modifier ModFlags;
public readonly string Name;
GenericConstraints constraints;
// <summary>
// Resolve is used in method definitions
// </summary>
- public bool Resolve (EmitContext ec, Location l)
+ public bool Resolve (DeclSpace ds, Location l)
{
- TypeExpr texpr = TypeName.ResolveAsTypeTerminal (ec, false);
+ TypeExpr texpr = ds.ResolveTypeExpr (TypeName, false, l);
if (texpr == null)
return false;
if (tparam != null)
constraints = tparam.TypeParameter.Constraints;
- parameter_type = texpr.ResolveType (ec);
-
+ parameter_type = ds.ResolveType (texpr, l);
+
if (parameter_type.IsAbstract && parameter_type.IsSealed) {
Report.Error (721, l, "'{0}': static types cannot be used as parameters", GetSignatureForError ());
return false;
/// Returns the signature for this parameter evaluating it on the
/// @tc context
/// </summary>
- public string GetSignature (EmitContext ec, Location loc)
+ public string GetSignature (DeclSpace ds, Location loc)
{
if (parameter_type == null){
- if (!Resolve (ec, loc))
+ if (!Resolve (ds, loc))
return null;
}
public string GetSignatureForError ()
{
- string typeName;
- if (parameter_type != null)
- typeName = TypeManager.CSharpName (parameter_type);
- else if (TypeName.Type != null)
- typeName = TypeManager.CSharpName (TypeName.Type);
- else
- typeName = TypeName.ToString ();
-
- switch (ModFlags & unchecked (~Modifier.ISBYREF)) {
+ string typeName = TypeManager.CSharpName (parameter_type);
+ switch (ModFlags & ~Modifier.ISBYREF) {
case Modifier.OUT:
return "out " + typeName;
case Modifier.PARAMS:
}
}
- public void ComputeSignature (EmitContext ec)
+ public void ComputeSignature (DeclSpace ds)
{
signature = "";
if (FixedParameters != null){
for (int i = 0; i < FixedParameters.Length; i++){
Parameter par = FixedParameters [i];
- signature += par.GetSignature (ec, loc);
+ signature += par.GetSignature (ds, loc);
}
}
//
count = FixedParameters.Length;
string array_par_name = ArrayParameter != null ? ArrayParameter.Name : null;
-
for (i = 0; i < count; i++){
string base_name = FixedParameters [i].Name;
+
for (j = i + 1; j < count; j++){
if (base_name != FixedParameters [j].Name)
continue;
/// <summary>
/// Returns the signature of the Parameters evaluated in
- /// the @ec EmitContext
+ /// the @tc environment
/// </summary>
- public string GetSignature (EmitContext ec)
+ public string GetSignature (DeclSpace ds)
{
if (signature == null){
VerifyArgs ();
- ComputeSignature (ec);
+ ComputeSignature (ds);
}
return signature;
return null;
}
- public Parameter GetParameterByName (string name)
- {
- int idx;
-
- return GetParameterByName (name, out idx);
- }
-
- bool ComputeParameterTypes (EmitContext ec)
+ bool ComputeParameterTypes (DeclSpace ds)
{
int extra = (ArrayParameter != null) ? 1 : 0;
int i = 0;
foreach (Parameter p in FixedParameters){
Type t = null;
- if (p.Resolve (ec, loc))
+ if (p.Resolve (ds, loc))
t = p.ExternalType ();
else
failed = true;
}
if (extra > 0){
- if (ArrayParameter.Resolve (ec, loc))
+ if (ArrayParameter.Resolve (ds, loc))
types [i] = ArrayParameter.ExternalType ();
else
failed = true;
// This variant is used by Delegates, because they need to
// resolve/define names, instead of the plain LookupType
//
- public bool ComputeAndDefineParameterTypes (EmitContext ec)
+ public bool ComputeAndDefineParameterTypes (DeclSpace ds)
{
- bool old_type_resolving = ec.ResolvingTypeTree;
- ec.ResolvingTypeTree = true;
- bool retval = ComputeParameterTypes (ec);
- ec.ResolvingTypeTree = old_type_resolving;
- return retval;
+ int extra = (ArrayParameter != null) ? 1 : 0;
+ int i = 0;
+ int pc;
+
+ if (FixedParameters == null)
+ pc = extra;
+ else
+ pc = extra + FixedParameters.Length;
+
+ types = new Type [pc];
+
+ if (!VerifyArgs ()){
+ FixedParameters = null;
+ return false;
+ }
+
+ bool ok_flag = true;
+
+ if (FixedParameters != null){
+ foreach (Parameter p in FixedParameters){
+ Type t = null;
+
+ if (p.Resolve (ds, loc))
+ t = p.ExternalType ();
+ else
+ ok_flag = false;
+
+ types [i] = t;
+ i++;
+ }
+ }
+
+ if (extra > 0){
+ if (ArrayParameter.Resolve (ds, loc))
+ types [i] = ArrayParameter.ExternalType ();
+ else
+ ok_flag = false;
+ }
+
+ //
+ // invalidate the cached types
+ //
+ if (!ok_flag){
+ types = null;
+ }
+
+ return ok_flag;
}
/// <summary>
/// </summary>
static Type [] no_types = new Type [0];
- public Type [] GetParameterInfo (EmitContext ec)
+ public Type [] GetParameterInfo (DeclSpace ds)
{
if (types != null)
return types;
if (FixedParameters == null && ArrayParameter == null)
return no_types;
- if (ComputeParameterTypes (ec) == false){
+ if (ComputeParameterTypes (ds) == false){
types = null;
return null;
}
/// Note that the returned type will not contain any dereference in this
/// case (ie, you get "int" for a ref int instead of "int&"
/// </summary>
- public Type GetParameterInfo (EmitContext ec, int idx, out Parameter.Modifier mod)
+ public Type GetParameterInfo (DeclSpace ds, int idx, out Parameter.Modifier mod)
{
mod = Parameter.Modifier.NONE;
return null;
if (types == null)
- if (ComputeParameterTypes (ec) == false)
+ if (ComputeParameterTypes (ds) == false)
return null;
//
Console.WriteLine (String.Format ("{0}({1}) (Location of symbol related to previous error)", loc.Name, loc.Row));
}
- static public void RuntimeMissingSupport (Location loc, string feature)
+ static public void RuntimeMissingSupport (string feature)
{
- Report.Error (-88, loc, "Your .NET Runtime does not support '{0}'. Please use the latest Mono runtime instead.", feature);
+ Report.Error (-88, "Your .NET Runtime does not support '{0}'. Please use the latest Mono runtime instead.", feature);
}
/// <summary>
"System.ParamArrayAttribute",
"System.CLSCompliantAttribute",
"System.Security.UnverifiableCodeAttribute",
- "System.Security.Permissions.SecurityAttribute",
"System.Runtime.CompilerServices.IndexerNameAttribute",
"System.Runtime.InteropServices.InAttribute",
"System.Runtime.InteropServices.StructLayoutAttribute",
"System.Runtime.InteropServices.FieldOffsetAttribute",
"System.InvalidOperationException",
"System.NotSupportedException",
- "System.MarshalByRefObject",
- "System.Security.CodeAccessPermission"
+ "System.MarshalByRefObject"
};
// We must store them here before calling BootstrapCorlib_ResolveDelegate.
}
static TypeExpr NamespaceLookup (DeclSpace ds, string name,
- int num_type_args, Location loc)
+ int num_type_args, bool silent, Location loc)
{
//
// Try in the current namespace and all its implicit parents
//
for (NamespaceEntry ns = ds.NamespaceEntry; ns != null; ns = ns.ImplicitParent) {
- IAlias result = ns.Lookup (ds, name, num_type_args, false, loc);
+ IAlias result = ns.Lookup (ds, name, num_type_args, false, silent, loc);
if (result == null)
continue;
//
Type type = TypeManager.LookupType (current_type.FullName + "." + name);
if (type != null){
- type = ds.ResolveNestedType (type, loc);
t = new TypeExpression (type, loc);
ds.Cache [name] = t;
return t;
containing_ds = containing_ds.Parent;
}
- t = NamespaceLookup (ds, name, num_type_params, loc);
+ t = NamespaceLookup (ds, name, num_type_params, silent, loc);
if (t != null){
ds.Cache [name] = t;
return t;
// Martin Baulig (martin@gnome.org)
//
// (C) 2001, 2002, 2003 Ximian, Inc.
-// (C) 2003, 2004 Novell, Inc.
//
using System;
public override bool Resolve (EmitContext ec)
{
if (ec.ReturnType == null){
- if (Expr != null){
- if (ec.CurrentAnonymousMethod != null){
- Report.Error (1662, loc, String.Format (
- "Anonymous method could not be converted to delegate " +
- "since the return value does not match the delegate value"));
- }
+ if (Expr != null){
Error (127, "Return with a value not allowed here");
return false;
}
} else
vector.CheckOutParameters (ec.CurrentBranching);
- if (in_exc)
- ec.NeedReturnLabel ();
-
ec.CurrentBranching.CurrentUsageVector.Return ();
return true;
}
ec.ig.Emit (OpCodes.Stloc, ec.TemporaryReturn ());
}
- if (in_exc)
+ if (in_exc) {
+ ec.NeedReturnLabel ();
ec.ig.Emit (OpCodes.Leave, ec.ReturnLabel);
- else
+ } else {
ec.ig.Emit (OpCodes.Ret);
}
}
+ }
public class Goto : Statement {
string target;
/// </summary>
public class GotoCase : Statement {
Expression expr;
- SwitchLabel sl;
+ Label label;
public GotoCase (Expression e, Location l)
{
if (val == null)
return false;
- sl = (SwitchLabel) ec.Switch.Elements [val];
+ SwitchLabel sl = (SwitchLabel) ec.Switch.Elements [val];
if (sl == null){
Report.Error (
return false;
}
+ label = sl.ILLabelCode;
+
ec.CurrentBranching.CurrentUsageVector.Goto ();
return true;
}
protected override void DoEmit (EmitContext ec)
{
- ec.ig.Emit (OpCodes.Br, sl.GetILLabelCode (ec));
+ ec.ig.Emit (OpCodes.Br, label);
}
}
crossing_exc = ec.CurrentBranching.BreakCrossesTryCatchBoundary ();
- if (!crossing_exc)
- ec.NeedReturnLabel ();
-
ec.CurrentBranching.CurrentUsageVector.Break ();
return true;
}
if (crossing_exc)
ig.Emit (OpCodes.Leave, ec.LoopEnd);
else {
+ ec.NeedReturnLabel ();
ig.Emit (OpCodes.Br, ec.LoopEnd);
}
}
}
}
- //
- // The information about a user-perceived local variable
- //
public class LocalInfo {
public Expression Type;
//
// Most of the time a variable will be stored in a LocalBuilder
//
- // But sometimes, it will be stored in a field (variables that have been
- // hoisted by iterators or by anonymous methods). The context of the field will
+ // But sometimes, it will be stored in a field. The context of the field will
// be stored in the EmitContext
//
//
Used = 1,
ReadOnly = 2,
Pinned = 4,
- IsThis = 8,
- Captured = 16
+ IsThis = 8
}
Flags flags;
public bool Resolve (EmitContext ec)
{
- if (VariableType == null) {
- TypeExpr texpr = Type.ResolveAsTypeTerminal (ec, false);
- if (texpr == null)
- return false;
-
- VariableType = texpr.ResolveType (ec);
- if (VariableType == null)
- return false;
- }
+ if (VariableType == null)
+ VariableType = ec.DeclSpace.ResolveType (Type, false, Location);
if (VariableType == TypeManager.void_type) {
Report.Error (1547, Location,
return false;
}
+ if (VariableType == null)
+ return false;
+
if (VariableType.IsAbstract && VariableType.IsSealed) {
Report.Error (723, Location, "Cannot declare variable of static type '{0}'", TypeManager.CSharpName (VariableType));
return false;
}
}
- public bool IsCaptured {
- get {
- return (flags & Flags.Captured) != 0;
- }
-
- set {
- flags |= Flags.Captured;
- }
- }
-
public override string ToString ()
{
return String.Format ("LocalInfo ({0},{1},{2},{3})",
return (flags & Flags.Used) != 0;
}
set {
- flags = value ? (flags | Flags.Used) : (unchecked (flags & ~Flags.Used));
+ flags = value ? (flags | Flags.Used) : (flags & ~Flags.Used);
}
}
return (flags & Flags.ReadOnly) != 0;
}
set {
- flags = value ? (flags | Flags.ReadOnly) : (unchecked (flags & ~Flags.ReadOnly));
+ flags = value ? (flags | Flags.ReadOnly) : (flags & ~Flags.ReadOnly);
}
}
/// they contain extra information that is not necessary on normal blocks.
/// </remarks>
public class Block : Statement {
- public Block Parent;
+ public readonly Block Parent;
public readonly Location StartLocation;
public Location EndLocation = Location.Null;
[Flags]
- public enum Flags {
+ public enum Flags : byte {
Implicit = 1,
Unchecked = 2,
BlockUsed = 4,
VariablesInitialized = 8,
HasRet = 16,
IsDestructor = 32,
- HasVarargs = 64,
- IsToplevel = 128,
- Unsafe = 256
+ HasVarargs = 64
}
Flags flags;
}
}
- public bool Unsafe {
- get {
- return (flags & Flags.Unsafe) != 0;
- }
- set {
- flags |= Flags.Unsafe;
- }
- }
-
public bool HasVarargs {
get {
if (Parent != null)
// Keeps track of constants
Hashtable constants;
- //
- // The parameters for the block, this is only needed on the toplevel block really
- // TODO: move `parameters' into ToplevelBlock
- Parameters parameters;
-
//
// If this is a switch section, the enclosing switch block.
//
Block switch_block;
- protected static int id;
+ static int id;
int this_id;
return e != null;
}
- //
- // Returns a `ParameterReference' for the given name, or null if there
- // is no such parameter
- //
- public ParameterReference GetParameterReference (string name, Location loc)
- {
+ Parameters parameters = null;
+ public Parameters Parameters {
+ get {
Block b = this;
-
- do {
- Parameters pars = b.parameters;
-
- if (pars != null){
- Parameter par;
- int idx;
-
- par = pars.GetParameterByName (name, out idx);
- if (par != null){
- ParameterReference pr;
-
- pr = new ParameterReference (pars, this, idx, name, loc);
- return pr;
- }
- }
+ while (b.Parent != null)
b = b.Parent;
- } while (b != null);
- return null;
+ return b.parameters;
}
-
- //
- // Whether the parameter named `name' is local to this block,
- // or false, if the parameter belongs to an encompassing block.
- //
- public bool IsLocalParameter (string name)
- {
- Block b = this;
- int toplevel_count = 0;
-
- do {
- if (this is ToplevelBlock)
- toplevel_count++;
-
- Parameters pars = b.parameters;
- if (pars != null){
- if (pars.GetParameterByName (name) != null)
- return true;
- return false;
- }
- if (toplevel_count > 0)
- return false;
- b = b.Parent;
- } while (b != null);
- return false;
- }
-
- //
- // Whether the `name' is a parameter reference
- //
- public bool IsParameterReference (string name)
- {
- Block b = this;
-
- do {
- Parameters pars = b.parameters;
-
- if (pars != null)
- if (pars.GetParameterByName (name) != null)
- return true;
- b = b.Parent;
- } while (b != null);
- return false;
}
/// <returns>
public VariableMap ParameterMap {
get {
if ((flags & Flags.VariablesInitialized) == 0)
- throw new Exception ("Variables have not been initialized yet");
+ throw new Exception ();
return param_map;
}
public VariableMap LocalMap {
get {
if ((flags & Flags.VariablesInitialized) == 0)
- throw new Exception ("Variables have not been initialized yet");
+ throw new Exception ();
return local_map;
}
}
+ public bool LiftVariable (LocalInfo local_info)
+ {
+ return false;
+ }
+
/// <summary>
/// Emits the variable declarations and labels.
/// </summary>
/// tc: is our typecontainer (to resolve type references)
/// ig: is the code generator:
/// </remarks>
- public void ResolveMeta (ToplevelBlock toplevel, EmitContext ec, InternalParameters ip)
+ public void EmitMeta (EmitContext ec, InternalParameters ip)
{
ILGenerator ig = ec.ig;
- bool old_unsafe = ec.InUnsafe;
-
- // If some parent block was unsafe, we remain unsafe even if this block
- // isn't explicitly marked as such.
- ec.InUnsafe |= Unsafe;
-
//
// Compute the VariableMap's.
//
bool old_check_state = ec.ConstantCheckState;
ec.ConstantCheckState = (flags & Flags.Unchecked) == 0;
+ bool remap_locals = ec.RemapToProxy;
//
// Process this block variables
continue;
}
-#if false
if (remap_locals)
vi.FieldBuilder = ec.MapVariable (name, vi.VariableType);
else if (vi.Pinned)
vi.LocalBuilder = TypeManager.DeclareLocalPinned (ig, vi.VariableType);
else if (!vi.IsThis)
vi.LocalBuilder = ig.DeclareLocal (vi.VariableType);
-#endif
if (constants == null)
continue;
//
if (children != null){
foreach (Block b in children)
- b.ResolveMeta (toplevel, ec, ip);
- }
- ec.InUnsafe = old_unsafe;
- }
-
- //
- // Emits the local variable declarations for a block
- //
- public void EmitMeta (EmitContext ec)
- {
- ILGenerator ig = ec.ig;
-
- if (variables != null){
- bool have_captured_vars = ec.HaveCapturedVariables ();
- bool remap_locals = ec.RemapToProxy;
-
- foreach (DictionaryEntry de in variables){
- LocalInfo vi = (LocalInfo) de.Value;
-
- if (have_captured_vars && ec.IsCaptured (vi))
- continue;
-
- if (remap_locals){
- vi.FieldBuilder = ec.MapVariable (vi.Name, vi.VariableType);
- } else {
- if (vi.Pinned)
- //
- // This is needed to compile on both .NET 1.x and .NET 2.x
- // the later introduced `DeclareLocal (Type t, bool pinned)'
- //
- vi.LocalBuilder = TypeManager.DeclareLocalPinned (ig, vi.VariableType);
- else if (!vi.IsThis)
- vi.LocalBuilder = ig.DeclareLocal (vi.VariableType);
- }
- }
- }
-
- if (children != null){
- foreach (Block b in children)
- b.EmitMeta (ec);
+ b.EmitMeta (ec, ip);
}
}
ec.CurrentBlock = prev_block;
}
-
- public ToplevelBlock Toplevel {
- get {
- Block b = this;
- while (b.Parent != null){
- if ((b.flags & Flags.IsToplevel) != 0)
- break;
- b = b.Parent;
- }
-
- return (ToplevelBlock) b;
- }
- }
-
- //
- // Returns true if we ar ea child of `b'.
- //
- public bool IsChildOf (Block b)
- {
- Block current = this;
-
- do {
- if (current.Parent == b)
- return true;
- current = current.Parent;
- } while (current != null);
- return false;
- }
}
//
- // A toplevel block contains extra information, the split is done
- // only to separate information that would otherwise bloat the more
- // lightweight Block.
- //
- // In particular, this was introduced when the support for Anonymous
- // Methods was implemented.
//
public class ToplevelBlock : Block {
- //
- // Pointer to the host of this anonymous method, or null
- // if we are the topmost block
- //
- public ToplevelBlock Container;
- CaptureContext capture_context;
-
- Hashtable capture_contexts;
-
- static int did = 0;
-
- int my_id = did++;
-
-
- public void RegisterCaptureContext (CaptureContext cc)
- {
- if (capture_contexts == null)
- capture_contexts = new Hashtable ();
- capture_contexts [cc] = cc;
- }
-
- public void CompleteContexts ()
- {
- if (capture_contexts == null)
- return;
-
- foreach (CaptureContext cc in capture_contexts.Keys){
- cc.AdjustScopes ();
- }
- }
-
- public CaptureContext ToplevelBlockCaptureContext {
- get {
- return capture_context;
- }
- }
-
- //
- // Parent is only used by anonymous blocks to link back to their
- // parents
- //
- public ToplevelBlock (ToplevelBlock container, Parameters parameters, Location start) :
- base (null, Flags.IsToplevel, parameters, start, Location.Null)
- {
- Container = container;
- }
-
public ToplevelBlock (Parameters parameters, Location start) :
- base (null, Flags.IsToplevel, parameters, start, Location.Null)
+ base (null, parameters, start, Location.Null)
{
}
public ToplevelBlock (Flags flags, Parameters parameters, Location start) :
- base (null, flags | Flags.IsToplevel, parameters, start, Location.Null)
+ base (null, flags, parameters, start, Location.Null)
{
}
-
- public ToplevelBlock (Location loc) : base (null, Flags.IsToplevel, loc, loc)
- {
- }
-
- public void SetHaveAnonymousMethods (Location loc, AnonymousMethod host)
- {
- if (capture_context == null)
- capture_context = new CaptureContext (this, loc, host);
- }
-
- public CaptureContext CaptureContext {
- get {
- return capture_context;
- }
- }
}
public class SwitchLabel {
Expression label;
object converted;
public Location loc;
-
- Label il_label;
- bool il_label_set;
- Label il_label_code;
- bool il_label_code_set;
+ public Label ILLabel;
+ public Label ILLabelCode;
//
// if expr == null, then it is the default case.
}
}
- public Label GetILLabel (EmitContext ec)
- {
- if (!il_label_set){
- il_label = ec.ig.DefineLabel ();
- il_label_set = true;
- }
- return il_label;
- }
-
- public Label GetILLabelCode (EmitContext ec)
- {
- if (!il_label_code_set){
- il_label_code = ec.ig.DefineLabel ();
- il_label_code_set = true;
- }
- return il_label_code;
- }
-
//
// Resolves the expression, reduces it to a literal if possible
// and then converts it to the requested type.
//
public bool ResolveAndReduce (EmitContext ec, Type required_type)
{
+ ILLabel = ec.ig.DefineLabel ();
+ ILLabelCode = ec.ig.DefineLabel ();
+
if (label == null)
return true;
if (e is StringConstant || e is NullLiteral){
if (required_type == TypeManager.string_type){
converted = e;
+ ILLabel = ec.ig.DefineLabel ();
return true;
}
}
ig.Emit (OpCodes.Ldloc, val);
EmitObjectInteger (ig, key);
SwitchLabel sl = (SwitchLabel) Elements [key];
- ig.Emit (OpCodes.Beq, sl.GetILLabel (ec));
+ ig.Emit (OpCodes.Beq, sl.ILLabel);
}
}
else
if (System.Convert.ToInt64 (key) == kb.nFirst + iJump)
{
SwitchLabel sl = (SwitchLabel) Elements [key];
- rgLabels [iJump] = sl.GetILLabel (ec);
+ rgLabels [iJump] = sl.ILLabel;
iKey++;
}
else
{
foreach (SwitchLabel sl in ss.Labels)
{
- ig.MarkLabel (sl.GetILLabel (ec));
- ig.MarkLabel (sl.GetILLabelCode (ec));
+ ig.MarkLabel (sl.ILLabel);
+ ig.MarkLabel (sl.ILLabelCode);
if (sl.Label == null)
{
ig.MarkLabel (lblDefault);
null_found = false;
for (int label = 0; label < label_count; label++){
SwitchLabel sl = (SwitchLabel) ss.Labels [label];
- ig.MarkLabel (sl.GetILLabel (ec));
+ ig.MarkLabel (sl.ILLabel);
if (!first_test){
ig.MarkLabel (next_test);
ig.MarkLabel (null_target);
ig.MarkLabel (sec_begin);
foreach (SwitchLabel sl in ss.Labels)
- ig.MarkLabel (sl.GetILLabelCode (ec));
+ ig.MarkLabel (sl.ILLabelCode);
if (mark_default)
ig.MarkLabel (default_target);
public Unsafe (Block b)
{
Block = b;
- Block.Unsafe = true;
}
public override bool Resolve (EmitContext ec)
return false;
}
- TypeExpr texpr = type.ResolveAsTypeTerminal (ec, false);
- if (texpr == null)
+ expr_type = ec.DeclSpace.ResolveType (type, false, loc);
+ if (expr_type == null)
return false;
- expr_type = texpr.ResolveType (ec);
-
CheckObsolete (expr_type);
if (ec.RemapToProxy){
public override bool Resolve (EmitContext ec)
{
if (type_expr != null) {
- TypeExpr te = type_expr.ResolveAsTypeTerminal (ec, false);
- if (te == null)
+ type = ec.DeclSpace.ResolveType (type_expr, false, loc);
+ if (type == null)
return false;
- type = te.ResolveType (ec);
-
CheckObsolete (type);
if (type != TypeManager.exception_type && !type.IsSubclassOf (TypeManager.exception_type)){
//
bool ResolveLocalVariableDecls (EmitContext ec)
{
+ expr_type = ec.DeclSpace.ResolveType (expr, false, loc);
int i = 0;
- TypeExpr texpr = expr.ResolveAsTypeTerminal (ec, false);
- if (texpr == null)
+ if (expr_type == null)
return false;
- expr_type = texpr.ResolveType (ec);
-
//
// The type must be an IDisposable or an implicit conversion
// must exist.
if (expr == null)
return false;
- TypeExpr texpr = type.ResolveAsTypeTerminal (ec, false);
- if (texpr == null)
+ var_type = ec.DeclSpace.ResolveType (type, false, loc);
+ if (var_type == null)
return false;
-
- var_type = texpr.ResolveType (ec);
-
+
//
// We need an instance variable. Not sure this is the best
// way of doing this.
// Although it is not as important in this case, as the type
// will not likely be object (what the enumerator will return).
//
- Report.Debug (64, "RESOLVE FOREACH #1", element_type, empty.Type, element_type == empty.Type,
- var_type, empty.Type.DeclaringType, var_type.DeclaringType, loc);
conv = Convert.ExplicitConversion (ec, empty, var_type, loc);
if (conv == null)
ok = false;
static bool GetEnumeratorFilter (MemberInfo m, object criteria)
{
- Report.Debug (64, "GET ENUMERATOR FILTER", m, criteria);
-
if (m == null)
return false;
{
ForeachHelperMethods hm = new ForeachHelperMethods (ec);
- Report.Debug (64, "PROBE COLLECTION TYPE", t);
-
for (Type tt = t; tt != null && tt != TypeManager.object_type;){
- Report.Debug (64, "PROBE COLLECTION TYPE #1", t, tt);
-
- if (TryType (tt, hm)) {
- Report.Debug (64, "PROBE COLLECTION TYPE #2", t, tt);
+ if (TryType (tt, hm))
return hm;
- }
tt = tt.BaseType;
}
while (t != null){
Type [] ifaces = t.GetInterfaces ();
- Report.Debug (64, "PROBE COLLECTION TYPE #3", t, ifaces);
-
foreach (Type i in ifaces){
- Report.Debug (64, "PROBE COLLECTION TYPE #4", t, ifaces, i);
- if (TryType (i, hm)) {
- Report.Debug (64, "PROBE COLLECTION TYPE #5", t, ifaces, i);
+ if (TryType (i, hm))
return hm;
- }
}
//
if (ec.InIterator){
conv.Emit (ec);
- ig.Emit (OpCodes.Stfld, ((LocalVariableReference) variable).local_info.FieldBuilder);
+ ig.Emit (OpCodes.Stfld, ((FieldExpr) variable).FieldInfo);
} else
((IAssignMethod)variable).EmitAssign (ec, conv, false, false);
ArrayAccess.EmitLoadOpcode (ig, element_type);
if (ec.InIterator){
conv.Emit (ec);
- ig.Emit (OpCodes.Stfld, ((LocalVariableReference) variable).local_info.FieldBuilder);
+ ig.Emit (OpCodes.Stfld, ((FieldExpr) variable).FieldInfo);
} else
((IAssignMethod)variable).EmitAssign (ec, conv, false, false);
ig.Emit (OpCodes.Call, get);
if (ec.InIterator){
conv.Emit (ec);
- ig.Emit (OpCodes.Stfld, ((LocalVariableReference) variable).local_info.FieldBuilder);
+ ig.Emit (OpCodes.Stfld, ((FieldExpr) variable).FieldInfo);
} else
((IAssignMethod)variable).EmitAssign (ec, conv, false, false);
statement.Emit (ec);
int len = pi.Length;
if (last_arg_is_params && pos >= pi.Length - 1)
- return Parameter.Modifier.PARAMS;
+ return Parameter.Modifier.PARAMS;
else if (is_varargs && pos >= pi.Length)
return Parameter.Modifier.ARGLIST;
- if (gpd != null)
- return gpd.ParameterModifier (pos);
-
Type t = pi [pos].ParameterType;
if (t.IsByRef){
if ((pi [pos].Attributes & ParameterAttributes.Out) != 0)
{
this.param_types = param_types;
this.Parameters = parameters;
+ }
+ public InternalParameters (DeclSpace ds, Parameters parameters)
+ : this (parameters.GetParameterInfo (ds), parameters)
+ {
has_varargs = parameters.HasArglist;
if (param_types == null)
count = param_types.Length;
}
- public InternalParameters (Type [] param_types, Parameters parameters,
+ public InternalParameters (DeclSpace ds, Parameters parameters,
TypeParameter [] type_params)
- : this (param_types, parameters)
+ : this (ds, parameters)
{
this.TypeParameters = type_params;
}
static public Type obsolete_attribute_type;
static public Type conditional_attribute_type;
static public Type in_attribute_type;
- static public Type anonymous_method_type;
static public Type cls_compliant_attribute_type;
static public Type typed_reference_type;
static public Type arg_iterator_type;
static public Type mbr_type;
static public Type struct_layout_attribute_type;
static public Type field_offset_attribute_type;
- static public Type security_attr_type;
static public Type generic_ienumerator_type;
static public Type generic_ienumerable_type;
static public TypeExpr system_asynccallback_expr;
static public TypeExpr system_iasyncresult_expr;
static public TypeExpr system_valuetype_expr;
- static public TypeExpr system_intptr_expr;
//
// This is only used when compiling corlib
system_asynccallback_expr = new TypeLookupExpression ("System.AsyncCallback");
system_iasyncresult_expr = new TypeLookupExpression ("System.IAsyncResult");
system_valuetype_expr = new TypeLookupExpression ("System.ValueType");
- system_intptr_expr = new TypeLookupExpression ("System.IntPtr");
}
static TypeManager ()
return LookupTypeContainer (t);
}
- /// <summary>
- /// Fills member container from base interfaces
- /// </summary>
- public static IMemberContainer LookupInterfaceContainer (Type[] types)
- {
- if (types == null)
- return null;
-
- IMemberContainer complete = null;
- foreach (Type t in types) {
- IMemberContainer one_type_cont = null;
- if (t is TypeBuilder) {
- one_type_cont = builder_to_declspace [t] as IMemberContainer;
- } else
- one_type_cont = TypeHandle.GetTypeHandle (t);
-
- if (complete == null) {
- complete = one_type_cont;
- continue;
- }
-
- // We need to avoid including same member more than once
- foreach (DictionaryEntry de in one_type_cont.MemberCache.Members) {
- object o = complete.MemberCache.Members [de.Key];
- if (o == null) {
- complete.MemberCache.Members.Add (de.Key, de.Value);
- continue;
- }
-
- ArrayList al_old = (ArrayList)o;
- ArrayList al_new = (ArrayList)de.Value;
-
- foreach (MemberCache.CacheEntry ce in al_new) {
- bool exist = false;
- foreach (MemberCache.CacheEntry ce_old in al_old) {
- if (ce.Member == ce_old.Member) {
- exist = true;
- break;
- }
- }
- if (!exist)
- al_old.Add (ce);
- }
- }
- }
- return complete;
- }
-
public static IMemberContainer LookupMemberContainer (Type t)
{
if (t is TypeBuilder) {
cls_compliant_attribute_type = CoreLookupType ("System.CLSCompliantAttribute");
struct_layout_attribute_type = CoreLookupType ("System.Runtime.InteropServices.StructLayoutAttribute");
field_offset_attribute_type = CoreLookupType ("System.Runtime.InteropServices.FieldOffsetAttribute");
- security_attr_type = CoreLookupType ("System.Security.Permissions.SecurityAttribute");
//
// Generic types
system_asynccallback_expr.Type = asynccallback_type;
system_iasyncresult_expr.Type = iasyncresult_type;
system_valuetype_expr.Type = value_type;
-
- //
- // These are only used for compare purposes
- //
- anonymous_method_type = typeof (AnonymousMethod);
}
//
return false;
}
- public static bool IsPrivateAccessible (Type type, Type parent)
- {
- if (type.Equals (parent))
- return true;
-
- if ((type is TypeBuilder) && type.IsGenericTypeDefinition && parent.IsGenericInstance) {
- //
- // `a' is a generic type definition's TypeBuilder and `b' is a
- // generic instance of the same type.
- //
- // Example:
- //
- // class Stack<T>
- // {
- // void Test (Stack<T> stack) { }
- // }
- //
- // The first argument of `Test' will be the generic instance
- // "Stack<!0>" - which is the same type than the "Stack" TypeBuilder.
- //
- //
- // We hit this via Closure.Filter() for gen-82.cs.
- //
- if (type != parent.GetGenericTypeDefinition ())
- return false;
-
- return true;
- }
-
- if (type.IsGenericInstance && parent.IsGenericInstance) {
- Type tdef = type.GetGenericTypeDefinition ();
- Type pdef = parent.GetGenericTypeDefinition ();
-
- if (type.GetGenericTypeDefinition () != parent.GetGenericTypeDefinition ())
- return false;
-
- return true;
- }
-
- return false;
- }
-
public static bool IsFamilyAccessible (Type type, Type parent)
{
TypeParameter tparam = LookupTypeParameter (type);
if (ma == MethodAttributes.Private)
return private_ok ||
- IsPrivateAccessible (invocation_type, mb.DeclaringType) ||
+ IsEqual (invocation_type, mb.DeclaringType) ||
IsNestedChildOf (invocation_type, mb.DeclaringType);
//
if (fa == FieldAttributes.Private)
return private_ok ||
- IsPrivateAccessible (invocation_type, fi.DeclaringType) ||
+ IsEqual (invocation_type, fi.DeclaringType) ||
IsNestedChildOf (invocation_type, fi.DeclaringType);
//
if (((qualifier_type == null) || (qualifier_type == invocation_type)) &&
(invocation_type != null) &&
- IsPrivateAccessible (m.DeclaringType, invocation_type))
+ IsEqual (m.DeclaringType, invocation_type))
return true;
//
// This happens with interfaces, they have a null
// basetype. Look members up in the Object class.
//
- if (current_type == null) {
+ if (current_type == null)
current_type = TypeManager.object_type;
- searching = true;
- }
}
if (list.Length == 0)
if (type.BaseType != null)
BaseType = GetTypeHandle (type.BaseType);
this.is_interface = type.IsInterface || type.IsGenericParameter;
- this.member_cache = new MemberCache (this, true);
+ this.member_cache = new MemberCache (this);
}
// IMemberContainer methods