Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xmcs/class/corlib/System.Reflection.Emit/common.src23
-rw-r--r--mcs/class/corlib/System.Reflection/common.src25
-rwxr-xr-xmcs/mcs/ChangeLog10303
-rwxr-xr-xmcs/mcs/class.cs4737
-rwxr-xr-xmcs/mcs/expression.cs7390
5 files changed, 0 insertions, 22478 deletions
diff --git a/mcs/class/corlib/System.Reflection.Emit/common.src b/mcs/class/corlib/System.Reflection.Emit/common.src
deleted file mode 100755
index 569a9d60748..00000000000
--- a/mcs/class/corlib/System.Reflection.Emit/common.src
+++ /dev/null
@@ -1,23 +0,0 @@
-AssemblyBuilder.cs
-AssemblyBuilderAccess.cs
-ConstructorBuilder.cs
-EventToken.cs
-FieldToken.cs
-FlowControl.cs
-ILGenerator.cs
-Label.cs
-MethodToken.cs
-ModuleBuilder.cs
-OpCode.cs
-OpCodes.cs
-OpCodeType.cs
-OperandType.cs
-PackingSize.cs
-ParameterToken.cs
-PEFileKinds.cs
-PropertyToken.cs
-SignatureToken.cs
-StackBehaviour.cs
-StringToken.cs
-TypeBuilder.cs
-TypeToken.cs
diff --git a/mcs/class/corlib/System.Reflection/common.src b/mcs/class/corlib/System.Reflection/common.src
deleted file mode 100644
index 022b6768fcc..00000000000
--- a/mcs/class/corlib/System.Reflection/common.src
+++ /dev/null
@@ -1,25 +0,0 @@
-Assembly.cs
-AssemblyNameFlags.cs
-BindingFlags.cs
-CallingConventions.cs
-ConstructorInfo.cs
-DefaultMemberAttribute.cs
-EventAttributes.cs
-EventInfo.cs
-FieldAttributes.cs
-FieldInfo.cs
-ICustomAttributeProvider.cs
-MemberFilter.cs
-MemberInfo.cs
-MemberTypes.cs
-MethodAttributes.cs
-MethodBase.cs
-MethodImplAttributes.cs
-MethodInfo.cs
-Module.cs
-ParameterAttributes.cs
-PropertyAttributes.cs
-PropertyInfo.cs
-ResourceAttributes.cs
-ResourceLocation.cs
-TypeAttributes.cs
diff --git a/mcs/mcs/ChangeLog b/mcs/mcs/ChangeLog
deleted file mode 100755
index 50bc4086c41..00000000000
--- a/mcs/mcs/ChangeLog
+++ /dev/null
@@ -1,10303 +0,0 @@
-2002-12-10 Ravi Pratap <ravi@ximian.com>
-
- * attribute.cs (ApplyAttributes): Keep track of the emitted
- attributes on a per-target basis. This fixes bug #35413.
-
-2002-12-10 Miguel de Icaza <miguel@ximian.com>
-
- * driver.cs (MainDriver): On rotor encoding 28591 does not exist,
- default to the Windows 1252 encoding.
-
- (UnixParseOption): Support version, thanks to Alp for the missing
- pointer.
-
- * AssemblyInfo.cs: Add nice assembly information.
-
- * cs-tokenizer.cs: Add fix from Felix to the #if/#else handler
- (bug 35169).
-
- * cs-parser.jay: Allow a trailing comma before the close bracked
- in the attribute_section production.
-
- * ecore.cs (FieldExpr.AddressOf): Until I figure out why the
- address of the instance was being taken, I will take this out,
- because we take the address of the object immediately here.
-
-2002-12-09 Ravi Pratap <ravi@ximian.com>
-
- * typemanager.cs (AreMultipleAllowed): Take care of the most
- obvious case where attribute type is not in the current assembly -
- stupid me ;-)
-
-2002-12-08 Miguel de Icaza <miguel@ximian.com>
-
- * ecore.cs (SimpleName.DoResolve): First perform lookups on using
- definitions, instead of doing that afterwards.
-
- Also we use a nice little hack, depending on the constructor, we
- know if we are a "composed" name or a simple name. Hence, we
- avoid the IndexOf test, and we avoid
-
- * codegen.cs: Add code to assist in a bug reporter to track down
- the source of a compiler crash.
-
-2002-12-07 Ravi Pratap <ravi@ximian.com>
-
- * attribute.cs (Attribute.ApplyAttributes) : Keep track of which attribute
- types have been emitted for a given element and flag an error
- if something which does not have AllowMultiple set is used more
- than once.
-
- * typemanager.cs (RegisterAttributeAllowMultiple): Keep track of
- attribute types and their corresponding AllowMultiple properties
-
- (AreMultipleAllowed): Check the property for a given type.
-
- * attribute.cs (Attribute.ApplyAttributes): Register the AllowMultiple
- property in the case we have a TypeContainer.
-
- (Attributes.AddAttribute): Detect duplicates and just skip on
- adding them. This trivial fix catches a pretty gross error in our
- attribute emission - global attributes were being emitted twice!
-
- Bugzilla bug #33187 is now fixed.
-
-2002-12-06 Miguel de Icaza <miguel@ximian.com>
-
- * cs-tokenizer.cs (pp_expr): Properly recurse here (use pp_expr
- instead of pp_and).
-
- * expression.cs (Binary.ResolveOperator): I can only use the
- Concat (string, string, string) and Concat (string, string,
- string, string) if the child is actually a concatenation of
- strings.
-
-2002-12-04 Miguel de Icaza <miguel@ximian.com>
-
- * cs-tokenizer.cs: Small fix, because decimal_digits is used in a
- context where we need a 2-character lookahead.
-
- * pending.cs (PendingImplementation): Rework so we can keep track
- of interface types all the time, and flag those which were
- implemented by parents as optional.
-
-2002-12-03 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (Binary.ResolveOperator): Use
- String.Concat(string,string,string) or
- String.Concat(string,string,string,string) when possible.
-
- * typemanager: More helper methods.
-
-
-Tue Dec 3 19:32:04 CET 2002 Paolo Molaro <lupus@ximian.com>
-
- * pending.cs: remove the bogus return from GetMissingInterfaces()
- (see the 2002-11-06 entry: the mono runtime is now fixed in cvs).
-
-2002-12-02 Gonzalo Paniagua Javier <gonzalo@ximian.com>
-
- * namespace.cs: avoid duplicated 'using xxx' being added to
- using_clauses. This prevents mcs from issuing and 'ambiguous type' error
- when we get more than one 'using' statement for the same namespace.
- Report a CS0105 warning for it.
-
-2002-11-30 Miguel de Icaza <miguel@ximian.com>
-
- * cs-tokenizer.cs (consume_identifier): use read directly, instead
- of calling getChar/putback, uses internal knowledge of it.
-
- (xtoken): Reorder tokenizer so most common patterns are checked
- first. This reduces the compilation time in another 5% (from 8.11s
- average to 7.73s for bootstrapping mcs on my Mobile p4/1.8ghz).
-
- The parsing time is 22% of the compilation in mcs, and from that
- 64% is spent on the tokenization process.
-
- I tried using a binary search for keywords, but this is slower
- than the hashtable. Another option would be to do a couple of
- things:
-
- * Not use a StringBuilder, instead use an array of chars,
- with a set value. Notice that this way we could catch
- the 645 error without having to do it *afterwards*.
-
- * We could write a hand-parser to avoid the hashtable
- compares altogether.
-
- The identifier consumption process takes 37% of the tokenization
- time. Another 15% is spent on is_number. 56% of the time spent
- on is_number is spent on Int64.Parse:
-
- * We could probably choose based on the string length to
- use Int32.Parse or Int64.Parse and avoid all the 64-bit
- computations.
-
- Another 3% is spend on wrapping `xtoken' in the `token' function.
-
- Handle 0xa0 as whitespace (#34752)
-
-2002-11-26 Miguel de Icaza <miguel@ximian.com>
-
- * typemanager.cs (IsCLRType): New routine to tell whether a type
- is one of the builtin types.
-
- Maybe it needs to use TypeCodes to be faster. Maybe we could use
- typecode in more places instead of doing pointer comparissions.
- We could leverage some knowledge about the way the typecodes are
- laid out.
-
- New code to cache namespaces in assemblies, it is currently not
- invoked, to be used soon.
-
- * decl.cs (DeclSpace.MakeFQN): Simple optimization.
-
- * expression.cs (Binary.ResolveOperator): specially handle
- strings, and do not perform user-defined operator overloading for
- built-in types.
-
-2002-11-24 Miguel de Icaza <miguel@ximian.com>
-
- * cs-tokenizer.cs: Avoid calling Char.IsDigit which is an
- internalcall as it is a pretty simple operation; Avoid whenever
- possible to call Char.IsLetter.
-
- (consume_identifier): Cut by half the number of
- hashtable calls by merging the is_keyword and GetKeyword behavior.
-
- Do not short-circuit, because if we do, we
- report errors (ie, #if false && true would produce an invalid
- directive error);
-
-
-2002-11-24 Martin Baulig <martin@ximian.com>
-
- * expression.cs (Cast.TryReduce): If we're in checked syntax,
- check constant ranges and report a CS0221. Fixes #33186.
-
-2002-11-24 Martin Baulig <martin@ximian.com>
-
- * cs-parser.jay: Make this work for uninitialized variable
- declarations in the `for' initializer. Fixes #32416.
-
-2002-11-24 Martin Baulig <martin@ximian.com>
-
- * ecore.cs (Expression.ConvertExplicit): Make casting from/to
- System.Enum actually work. Fixes bug #32269, added verify-6.cs.
-
-2002-11-24 Martin Baulig <martin@ximian.com>
-
- * expression.cs (Binary.DoNumericPromotions): Added `check_user_conv'
- argument; if true, we also check for user-defined conversions.
- This is only needed if both arguments are of a user-defined type.
- Fixes #30443, added test-175.cs.
- (Binary.ForceConversion): Pass the location argument to ConvertImplicit.
-
- * ecore.cs (Expression.ImplicitUserConversionExists): New method.
-
-2002-11-24 Martin Baulig <martin@ximian.com>
-
- * expression.cs (ArrayAccess.GetStoreOpcode): New public static
- function to get the store opcode.
- (Invocation.EmitParams): Call ArrayAccess.GetStoreOpcode() and
- only emit the Ldelema if the store opcode is Stobj. You must run
- both test-34 and test-167 to test this. Fixes #34529.
-
-2002-11-23 Martin Baulig <martin@ximian.com>
-
- * ecore.cs (Expression.MemberLookup): Added additional
- `qualifier_type' argument which is used when we're being called
- from MemberAccess.DoResolve() and null if we're called from a
- SimpleName lookup.
- (Expression.MemberLookupFailed): New method to report errors; this
- does the CS1540 check and reports the correct error message.
-
- * typemanager.cs (MemberLookup): Added additional `qualifier_type'
- argument for the CS1540 check and redone the way how we're dealing
- with private members. See the comment in the source code for details.
- (FilterWithClosure): Reverted this back to revision 1.197; renamed
- `closure_start_type' to `closure_qualifier_type' and check whether
- it's not null. It was not this filter being broken, it was just
- being called with the wrong arguments.
-
- * expression.cs (MemberAccess.DoResolve): use MemberLookupFinal()
- and pass it the correct `qualifier_type'; this also does the error
- handling for us.
-
-2002-11-22 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (Invocation.EmitParams): If the we are dealing
- with a non-built-in value type, load its address as well.
-
- (ArrayCreation): Use a a pretty constant instead
- of the hardcoded value 2. Use 6 instead of 2 for the number of
- static initializers.
-
- (ArrayCreation.EmitDynamicInitializers): Peel enumerations,
- because they are not really value types, just glorified integers.
-
- * driver.cs: Do not append .exe, the CSC compiler does not do it.
-
- * ecore.cs: Remove redundant code for enumerations, make them use
- the same code path as everything else, fixes the casting issue
- with enumerations in Windows.Forms.
-
- * attribute.cs: Do only cast to string if it is a string, the
- validation happens later.
-
- * typemanager.cs: Temproary hack to avoid a bootstrap issue until
- people upgrade their corlibs.
-
- * ecore.cs: Oops, enumerations were not following the entire code path
-
-2002-11-21 Miguel de Icaza <miguel@ximian.com>
-
- * typemanager.cs (FilterWithClosure): Commented out the test for
- 1540 in typemanager.cs, as it has problems when accessing
- protected methods from a parent class (see test-174.cs).
-
- * attribute.cs (Attribute.ValidateGuid): new method.
- (Attribute.Resolve): Use above.
-
-2002-11-19 Miguel de Icaza <miguel@ximian.com>
-
- * enum.cs: In FindMembers, perform a recursive lookup for values. (34308)
-
- * ecore.cs (SimpleName.SimpleNameResolve): Remove the special
- handling for enumerations, as we only needed the TypeContainer
- functionality to begin with (this is required for the fix below to
- work for enums that reference constants in a container class for
- example).
-
- * codegen.cs (EmitContext): Make TypeContainer a DeclSpace.
-
- * enum.cs (Enum.Define): Use `this' instead of parent, so we have
- a valid TypeBuilder to perform lookups on.o
-
- * class.cs (InheritableMemberSignatureCompare): Use true in the
- call to GetGetMethod and GetSetMethod, because we are comparing
- the signature, and we need to get the methods *even* if they are
- private.
-
- (PropertyBase.CheckBase): ditto.
-
- * statement.cs (Switch.ResolveAndReduce, Block.EmitMeta,
- GotoCase.Resolve): Use Peel on EmpytCasts.
-
- * ecore.cs (EmptyCast): drop child, add Peel method.
-
-2002-11-17 Martin Baulig <martin@ximian.com>
-
- * ecore.cs (EmptyCast.Child): New public property.
-
- * statement.cs (SwitchLabel.ResolveAndReduce): Check whether the
- label resolved to an EmptyCast. Fixes #34162.
- (GotoCase.Resolve): Likewise.
- (Block.EmitMeta): Likewise.
-
-2002-11-17 Martin Baulig <martin@ximian.com>
-
- * expression.cs (Invocation.BetterConversion): Prefer int over
- uint; short over ushort; long over ulong for integer literals.
- Use ImplicitConversionExists instead of StandardConversionExists
- since we also need to check for user-defined implicit conversions.
- Fixes #34165. Added test-173.cs.
-
-2002-11-16 Martin Baulig <martin@ximian.com>
-
- * expression.cs (Binary.EmitBranchable): Eliminate comparisions
- with the `true' and `false' literals. Fixes #33151.
-
-2002-11-16 Martin Baulig <martin@ximian.com>
-
- * typemanager.cs (RealMemberLookup): Reverted Miguel's patch from
- October 22nd; don't do the cs1540 check for static members.
-
- * ecore.cs (PropertyExpr.ResolveAccessors): Rewrote this; we're
- now using our own filter here and doing the cs1540 check again.
-
-2002-11-16 Martin Baulig <martin@ximian.com>
-
- * support.cs (InternalParameters): Don't crash if we don't have
- any fixed parameters. Fixes #33532.
-
-2002-11-16 Martin Baulig <martin@ximian.com>
-
- * decl.cs (MemberCache.AddMethods): Use BindingFlags.FlattenHierarchy
- when looking up static methods to make this work on Windows.
- Fixes #33773.
-
-2002-11-16 Martin Baulig <martin@ximian.com>
-
- * ecore.cs (PropertyExpr.VerifyAssignable): Check whether we have
- a setter rather than using PropertyInfo.CanWrite.
-
-2002-11-15 Nick Drochak <ndrochak@gol.com>
-
- * class.cs: Allow acces to block member by subclasses. Fixes build
- breaker.
-
-2002-11-14 Martin Baulig <martin@ximian.com>
-
- * class.cs (Constructor.Emit): Added the extern/block check.
- Fixes bug #33678.
-
-2002-11-14 Martin Baulig <martin@ximian.com>
-
- * expression.cs (IndexerAccess.DoResolve): Do a DeclaredOnly
- iteration while looking for indexers, this is needed because the
- indexer may have a different name in our base classes. Fixed the
- error reporting (no indexers at all, not get accessor, no
- overloaded match). Fixes bug #33089.
- (IndexerAccess.DoResolveLValue): Likewise.
-
-2002-11-14 Martin Baulig <martin@ximian.com>
-
- * class.cs (PropertyBase.CheckBase): Make this work for multiple
- indexers. Fixes the first part of bug #33089.
- (MethodSignature.InheritableMemberSignatureCompare): Added support
- for properties.
-
-2002-11-13 Ravi Pratap <ravi@ximian.com>
-
- * attribute.cs (Attribute.Resolve): Catch the
- NullReferenceException and report it since it isn't supposed to
- happen.
-
-2002-11-12 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (Binary.EmitBranchable): Also handle the cases for
- LogicalOr and LogicalAnd that can benefit from recursively
- handling EmitBranchable. The code now should be nice for Paolo.
-
-2002-11-08 Miguel de Icaza <miguel@ximian.com>
-
- * typemanager.cs (LookupType): Added a negative-hit hashtable for
- the Type lookups, as we perform quite a number of lookups on
- non-Types. This can be removed once we can deterministically tell
- whether we have a type or a namespace in advance.
-
- But this might require special hacks from our corlib.
-
- * TODO: updated.
-
- * ecore.cs (TryImplicitIntConversion): Handle conversions to float
- and double which avoids a conversion from an integer to a double.
-
- * expression.cs: tiny optimization, avoid calling IsConstant,
- because it effectively performs the lookup twice.
-
-2002-11-06 Miguel de Icaza <miguel@ximian.com>
-
- But a bogus return here to keep the semantics of the old code
- until the Mono runtime is fixed.
-
- * pending.cs (GetMissingInterfaces): New method used to remove all
- the interfaces that are already implemented by our parent
- classes from the list of pending methods.
-
- * interface.cs: Add checks for calls after ResolveTypeExpr.
-
-2002-11-05 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (Class.Emit): Report warning 67: event not used if the
- warning level is beyond 3.
-
- * ecore.cs (Expression.ConvertExplicit): Missed a check for expr
- being a NullLiteral.
-
- * cs-parser.jay: Fix, Gonzalo reverted the order of the rank
- specifiers.
-
- * class.cs (TypeContainer.GetClassBases): Cover a missing code
- path that might fail if a type can not be resolved.
-
- * expression.cs (Binary.Emit): Emit unsigned versions of the
- operators.
-
- * driver.cs: use error 5.
-
-2002-11-02 Gonzalo Paniagua Javier <gonzalo@gnome-db.org>
-
- * cs-parser.jay: simplified a rule and 5 SR conflicts dissapeared.
-
-2002-11-01 Miguel de Icaza <miguel@ximian.com>
-
- * cs-parser.jay (switch_section): A beautiful patch from Martin
- Baulig that fixed 33094.
-
-2002-10-31 Miguel de Icaza <miguel@ximian.com>
-
- * ecore.cs (PropertyExpr.DoResolveLValue, PropertyExpr.DoResolve):
- Check whether the base is abstract and report an error if so.
-
- * expression.cs (IndexerAccess.DoResolveLValue,
- IndexerAccess.DoResolve): ditto.
-
- (Invocation.DoResolve): ditto.
-
- (Invocation.FullMethodDesc): Improve the report string.
-
- * statement.cs (Block): Eliminate IsVariableDefined as it is
- basically just a wrapper for GetVariableInfo.
-
- * ecore.cs (SimpleName): Use new
-
- * support.cs (ReflectionParamter.ParameterType): We unwrap the
- type, as we return the actual parameter ref/unref state on a
- different call.
-
-2002-10-30 Miguel de Icaza <miguel@ximian.com>
-
- * support.cs: Return proper flags REF/OUT fixing the previous
- commit.
-
- * expression.cs: Reverted last patch, that was wrong. Is_ref is
- not used to mean `ref' but `ref or out' in ParameterReference
-
- * delegate.cs (FullDelegateDesc): use ParameterDesc to get the
- full type signature instead of calling TypeManger.CSharpName
- ourselves.
-
- * support.cs (InternalParameters.ParameterDesc): Do not compare
- directly to the modflags, because REF/OUT will actually be bitsets
- if set.
-
- * delegate.cs (VerifyMethod): Check also the modifiers.
-
- * cs-tokenizer.cs: Fix bug where floating point values with an
- exponent where a sign was missing was ignored.
-
- * driver.cs: Allow multiple assemblies to be specified in a single
- /r: argument
-
-2002-10-28 Miguel de Icaza <miguel@ximian.com>
-
- * cs-parser.jay: Ugly. We had to add a multiplicative_expression,
- because identifiers after a parenthesis would end up in this kind
- of production, and we needed to desamiguate it for having casts
- like:
-
- (UserDefinedType *) xxx
-
-2002-10-24 Miguel de Icaza <miguel@ximian.com>
-
- * typemanager.cs (RealMemberLookup): when we deal with a subclass,
- we should set on the Bindingflags.NonPublic, but not turn on
- private_ok. private_ok controls whether a Private member is
- returned (this is chekced on the filter routine), while the
- BindingFlags.NonPublic just controls whether private/protected
- will be allowed. This fixes the problem part of the problem of
- private properties being allowed to be used in derived classes.
-
- * expression.cs (BaseAccess): Provide an DoResolveLValue method,
- so we can call the children DoResolveLValue method (this will
- properly signal errors on lvalue assignments to base properties)
-
- * ecore.cs (PropertyExpr.ResolveAccessors): If both setter and
- getter are null, and we have a property info, we know that this
- happened because the lookup failed, so we report an error 122 for
- protection level violation.
-
- We also silently return if setter and getter are null in the
- resolve functions, this condition only happens if we have flagged
- the error before. This is the other half of the problem.
-
- (PropertyExpr.ResolveAccessors): Turns out that PropertyInfo does
- not have accessibility information, that is why we were returning
- true in the filter function in typemanager.cs.
-
- To properly report 122 (property is inaccessible because of its
- protection level) correctly, we report this error in ResolveAccess
- by failing if both the setter and the getter are lacking (ie, the
- lookup failed).
-
- DoResolve and DoLResolve have been modified to check for both
- setter/getter being null and returning silently, the reason being
- that I did not want to put the knowledge about this error in upper
- layers, like:
-
- int old = Report.Errors;
- x = new PropertyExpr (...);
- if (old != Report.Errors)
- return null;
- else
- return x;
-
- So the property expr is returned, but it is invalid, so the error
- will be flagged during the resolve process.
-
- * class.cs: Remove InheritablePropertySignatureCompare from the
- class, as we no longer depend on the property signature to compute
- whether it is possible to implement a method or not.
-
- The reason is that calling PropertyInfo.GetGetMethod will return
- null (in .NET, in Mono it works, and we should change this), in
- cases where the Get Method does not exist in that particular
- class.
-
- So this code:
-
- class X { public virtual int A { get { return 1; } } }
- class Y : X { }
- class Z : Y { public override int A { get { return 2; } } }
-
- Would fail in Z because the parent (Y) would not have the property
- defined. So we avoid this completely now (because the alternative
- fix was ugly and slow), and we now depend exclusively on the
- method names.
-
- (PropertyBase.CheckBase): Use a method-base mechanism to find our
- reference method, instead of using the property.
-
- * typemanager.cs (GetPropertyGetter, GetPropertySetter): These
- routines are gone now.
-
- * typemanager.cs (GetPropertyGetter, GetPropertySetter): swap the
- names, they were incorrectly named.
-
- * cs-tokenizer.cs: Return are more gentle token on failure.
-
- * pending.cs (PendingImplementation.InterfaceMethod): This routine
- had an out-of-sync index variable, which caused it to remove from
- the list of pending methods the wrong method sometimes.
-
-2002-10-22 Miguel de Icaza <miguel@ximian.com>
-
- * ecore.cs (PropertyExpr): Do not use PropertyInfo.CanRead,
- CanWrite, because those refer to this particular instance of the
- property, and do not take into account the fact that we can
- override single members of a property.
-
- Constructor requires an EmitContext. The resolution process does
- not happen here, but we need to compute the accessors before,
- because the resolution does not always happen for properties.
-
- * typemanager.cs (RealMemberLookup): Set private_ok if we are a
- subclass, before we did not update this flag, but we did update
- bindingflags.
-
- (GetAccessors): Drop this routine, as it did not work in the
- presence of partially overwritten set/get methods.
-
- Notice that this broke the cs1540 detection, but that will require
- more thinking.
-
-2002-10-22 Gonzalo Paniagua Javier <gonzalo@ximian.com>
-
- * class.cs:
- * codegen.cs:
- * driver.cs: issue a warning instead of an error if we don't support
- debugging for the platform. Also ignore a couple of errors that may
- arise when trying to write the symbols. Undo my previous patch.
-
-2002-10-22 Gonzalo Paniagua Javier <gonzalo@ximian.com>
-
- * driver.cs: ignore /debug switch except for Unix platforms.
-
-2002-10-23 Nick Drochak <ndrochak@gol.com>
-
- * makefile: Remove mcs2.exe and mcs3.exe on 'make clean'
-
-2002-10-21 Miguel de Icaza <miguel@ximian.com>
-
- * driver.cs: Do not make mcs-debug conditional, so we do not break
- builds that use it.
-
- * statement.cs (UsageVector.MergeChildren): I would like Martin to
- review this patch. But basically after all the children variables
- have been merged, the value of "Breaks" was not being set to
- new_breaks for Switch blocks. I think that it should be set after
- it has executed. Currently I set this to the value of new_breaks,
- but only if new_breaks is FlowReturn.ALWAYS, which is a bit
- conservative, but I do not understand this code very well.
-
- I did not break anything in the build, so that is good ;-)
-
- * cs-tokenizer.cs: Also allow \r in comments as a line separator.
-
-2002-10-20 Mark Crichton <crichton@gimp.org>
-
- * cfold.cs: Fixed compile blocker. Really fixed it this time.
-
-2002-10-20 Nick Drochak <ndrochak@gol.com>
-
- * cfold.cs: Fixed compile blocker.
-
-2002-10-20 Miguel de Icaza <miguel@ximian.com>
-
- * driver.cs: I was chekcing the key, not the file.
-
-2002-10-19 Ravi Pratap <ravi@ximian.com>
-
- * ecore.cs (UserDefinedConversion): Get rid of the bogus error
- message that we were generating - we just need to silently return
- a null.
-
-2002-10-19 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (Event.Define): Change my previous commit, as this
- breaks the debugger. This is a temporary hack, as it seems like
- the compiler is generating events incorrectly to begin with.
-
- * expression.cs (Binary.ResolveOperator): Added support for
- "U operator - (E x, E y)"
-
- * cfold.cs (BinaryFold): Added support for "U operator - (E x, E
- y)".
-
- * ecore.cs (FieldExpr.AddressOf): We had a special code path for
- init-only variables, but this path did not take into account that
- there might be also instance readonly variables. Correct this
- problem.
-
- This fixes bug 32253
-
- * delegate.cs (NewDelegate.DoResolve): Catch creation of unsafe
- delegates as well.
-
- * driver.cs: Change the extension for modules to `netmodule'
-
- * cs-parser.jay: Improved slightly the location tracking for
- the debugger symbols.
-
- * class.cs (Event.Define): Use Modifiers.FieldAttr on the
- modifiers that were specified instead of the hardcoded value
- (FamAndAssem). This was basically ignoring the static modifier,
- and others. Fixes 32429.
-
- * statement.cs (Switch.SimpleSwitchEmit): Simplified the code, and
- fixed a bug in the process (32476)
-
- * expression.cs (ArrayAccess.EmitAssign): Patch from
- hwang_rob@yahoo.ca that fixes bug 31834.3
-
-2002-10-18 Miguel de Icaza <miguel@ximian.com>
-
- * driver.cs: Make the module extension .netmodule.
-
-2002-10-16 Miguel de Icaza <miguel@ximian.com>
-
- * driver.cs: Report an error if the resource file is not found
- instead of crashing.
-
- * ecore.cs (PropertyExpr.EmitAssign): Pass IsBase instead of
- false, like Emit does.
-
-2002-10-16 Nick Drochak <ndrochak@gol.com>
-
- * typemanager.cs: Remove unused private member. Also reported mcs
- bug to report this as a warning like csc.
-
-2002-10-15 Martin Baulig <martin@gnome.org>
-
- * statement.cs (Statement.Emit): Made this a virtual method; emits
- the line number info and calls DoEmit().
- (Statement.DoEmit): New protected abstract method, formerly knows
- as Statement.Emit().
-
- * codegen.cs (EmitContext.Mark): Check whether we have a symbol writer.
-
-2002-10-11 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs: Following the comment from 2002-09-26 to AddMethod, I
- have fixed a remaining problem: not every AddXXXX was adding a
- fully qualified name.
-
- Now everyone registers a fully qualified name in the DeclSpace as
- being defined instead of the partial name.
-
- Downsides: we are slower than we need to be due to the excess
- copies and the names being registered this way.
-
- The reason for this is that we currently depend (on the corlib
- bootstrap for instance) that types are fully qualified, because
- we dump all the types in the namespace, and we should really have
- types inserted into the proper namespace, so we can only store the
- basenames in the defined_names array.
-
-2002-10-10 Martin Baulig <martin@gnome.org>
-
- * expression.cs (ArrayAccess.EmitStoreOpcode): Reverted the patch
- from bug #31834, see the bug report for a testcase which is
- miscompiled.
-
-2002-10-10 Martin Baulig <martin@gnome.org>
-
- * codegen.cs (EmitContext.Breaks): Removed, we're now using the
- flow analysis code for this.
-
- * statement.cs (Do, While, For): Tell the flow analysis code about
- infinite loops.
- (FlowBranching.UsageVector): Added support for infinite loops.
- (Block.Resolve): Moved the dead code elimination here and use flow
- analysis to do it.
-
-2002-10-09 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (Field.Define): Catch cycles on struct type
- definitions.
-
- * typemanager.cs (IsUnmanagedtype): Do not recursively check
- fields if the fields are static. We only need to check instance
- fields.
-
- * expression.cs (As.DoResolve): Test for reference type.
-
- * statement.cs (Using.ResolveExpression): Use
- ConvertImplicitRequired, not ConvertImplicit which reports an
- error on failture
- (Using.ResolveLocalVariableDecls): ditto.
-
- * expression.cs (Binary.ResolveOperator): Report errors in a few
- places where we had to.
-
- * typemanager.cs (IsUnmanagedtype): Finish implementation.
-
-2002-10-08 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs: Use StoreFromPtr instead of extracting the type
- and then trying to use Stelem. Patch is from hwang_rob@yahoo.ca
-
- * ecore.cs (ImplicitReferenceConversion): It is possible to assign
- an enumeration value to a System.Enum, but System.Enum is not a
- value type, but an class type, so we need to box.
-
- (Expression.ConvertExplicit): One codepath could return
- errors but not flag them. Fix this. Fixes #31853
-
- * parameter.cs (Resolve): Do not allow void as a parameter type.
-
-2002-10-06 Martin Baulig <martin@gnome.org>
-
- * statemenc.cs (FlowBranching.SetParameterAssigned): Don't crash
- if it's a class type and not a struct. Fixes #31815.
-
-2002-10-06 Martin Baulig <martin@gnome.org>
-
- * statement.cs: Reworked the flow analysis code a bit to make it
- usable for dead code elimination.
-
-2002-10-06 Gonzalo Paniagua Javier <gonzalo@ximian.com>
-
- * cs-parser.jay: allow empty source files. Fixes bug #31781.
-
-2002-10-04 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (ComposedCast.DoResolveType): A quick workaround
- to fix the test 165, will investigate deeper.
-
-2002-10-04 Martin Baulig <martin@gnome.org>
-
- * statement.cs (FlowBranching.UsageVector.MergeChildren): Make
- finally blocks actually work.
- (Try.Resolve): We don't need to create a sibling for `finally' if
- there is no finally block.
-
-2002-10-04 Martin Baulig <martin@gnome.org>
-
- * class.cs (Constructor.Define): The default accessibility for a
- non-default constructor is private, not public.
-
-2002-10-04 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (Constructor): Make AllowedModifiers public, add
- EXTERN.
-
- * cs-parser.jay: Perform the modifiers test here, as the
- constructor for the Constructor class usually receives a zero
- because of the way we create it (first we create, later we
- customize, and we were never checking the modifiers).
-
- * typemanager.cs (Typemanager.LookupTypeDirect): This new function
- is a version of LookupTypeReflection that includes the type-name
- cache. This can be used as a fast path for functions that know
- the fully qualified name and are only calling into *.GetType() to
- obtain a composed type.
-
- This is also used by TypeManager.LookupType during its type
- composition.
-
- (LookupType): We now also track the real type name, as sometimes
- we can get a quey for the real type name from things like
- ComposedCast. This fixes bug 31422.
-
- * expression.cs (ComposedCast.Resolve): Since we are obtaining a
- complete type fullname, it does not have to go through the type
- resolution system to obtain the composed version of the type (for
- obtaining arrays or pointers).
-
- (Conditional.Emit): Use the EmitBoolExpression to
- generate nicer code, as requested by Paolo.
-
- (ArrayCreation.CheckIndices): Use the patch from
- hwang_rob@yahoo.ca to validate the array initializers.
-
-2002-10-03 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (ConstructorInitializer.Emit): simplify code by using
- Invocation.EmitCall, and at the same time, fix the bugs in calling
- parent constructors that took variable arguments.
-
- * ecore.cs (Expression.ConvertNumericExplicit,
- Expression.ImplicitNumericConversion): Remove the code that
- manually wrapped decimal (InternalTypeConstructor call is now gone
- as well).
-
- * expression.cs (Cast.TryReduce): Also handle decimal types when
- trying to perform a constant fold on the type.
-
- * typemanager.cs (IsUnmanagedtype): Partially implemented.
-
- * parameter.cs: Removed ResolveAndDefine, as it was not needed, as
- that only turned off an error report, and did nothing else.
-
-2002-10-02 Miguel de Icaza <miguel@ximian.com>
-
- * driver.cs: Handle and ignore /fullpaths
-
-2002-10-01 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (Binary.ResolveOperator): Catch the case where
- DoNumericPromotions returns true,
-
- (Binary.DoNumericPromotions): Simplify the code, and the tests.
-
-2002-09-27 Miguel de Icaza <miguel@ximian.com>
-
- * ecore.cs (EventExpr.Emit): Instead of emitting an exception,
- report error 70.
-
-2002-09-26 Miguel de Icaza <miguel@ximian.com>
-
- * ecore.cs (ConvertNumericExplicit): It is not enough that the
- conversion exists, but it is also required that the conversion be
- performed. This manifested in "(Type64Enum) 2".
-
- * class.cs (TypeManager.AddMethod): The fix is not to change
- AddEnum, because that one was using a fully qualified name (every
- DeclSpace derivative does), but to change the AddMethod routine
- that was using an un-namespaced name. This now correctly reports
- the duplicated name.
-
- Revert patch until I can properly fix it. The issue
- is that we have a shared Type space across all namespaces
- currently, which is wrong.
-
- Options include making the Namespace a DeclSpace, and merge
- current_namespace/current_container in the parser.
-
-2002-09-25 Miguel de Icaza <miguel@ximian.com>
-
- * cs-parser.jay: Improve error reporting when we get a different
- kind of expression in local_variable_type and
- local_variable_pointer_type.
-
- Propagate this to avoid missleading errors being reported.
-
- * ecore.cs (ImplicitReferenceConversion): treat
- TypeManager.value_type as a target just like object_type. As
- code like this:
-
- ValueType v = 1;
-
- Is valid, and needs to result in the int 1 being boxed before it
- is assigned to the value type v.
-
- * class.cs (TypeContainer.AddEnum): Use the basename, not the name
- to validate the enumeration name.
-
- * expression.cs (ArrayAccess.EmitAssign): Mimic the same test from
- EmitDynamicInitializers for the criteria to use Ldelema. Thanks
- to hwang_rob@yahoo.ca for finding the bug and providing a patch.
-
- * ecore.cs (TryImplicitIntConversion): When doing an
- implicit-enumeration-conversion, check if the type is 64-bits and
- perform a conversion before passing to EnumConstant.
-
-2002-09-23 Miguel de Icaza <miguel@ximian.com>
-
- * decl.cs (Error_AmbiguousTypeReference); New routine used to
- report ambiguous type references. Unlike the MS version, we
- report what the ambiguity is. Innovation at work ;-)
-
- (DeclSpace.FindType): Require a location argument to
- display when we display an ambiguous error.
-
- * ecore.cs: (SimpleName.DoResolveType): Pass location to FindType.
-
- * interface.cs (GetInterfaceTypeByName): Pass location to FindType.
-
- * expression.cs (EmitDynamicInitializers): Apply patch from
- hwang_rob@yahoo.ca that fixes the order in which we emit our
- initializers.
-
-2002-09-21 Martin Baulig <martin@gnome.org>
-
- * delegate.cs (Delegate.VerifyApplicability): Make this work if the
- delegate takes no arguments.
-
-2002-09-20 Miguel de Icaza <miguel@ximian.com>
-
- * constant.cs: Use Conv_U8 instead of Conv_I8 when loading longs
- from integers.
-
- * expression.cs: Extract the underlying type.
-
- * ecore.cs (StoreFromPtr): Use TypeManager.IsEnumType instad of IsEnum
-
- * decl.cs (FindType): Sorry about this, fixed the type lookup bug.
-
-2002-09-19 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (TypeContainer.DefineType): We can not use the nice
- PackingSize with the size set to 1 DefineType method, because it
- will not allow us to define the interfaces that the struct
- implements.
-
- This completes the fixing of bug 27287
-
- * ecore.cs (Expresion.ImplicitReferenceConversion): `class-type S'
- means also structs. This fixes part of the problem.
- (Expresion.ImplicitReferenceConversionExists): ditto.
-
- * decl.cs (DeclSparce.ResolveType): Only report the type-not-found
- error if there were no errors reported during the type lookup
- process, to avoid duplicates or redundant errors. Without this
- you would get an ambiguous errors plus a type not found. We have
- beaten the user enough with the first error.
-
- (DeclSparce.FindType): Emit a warning if we have an ambiguous
- reference.
-
- * ecore.cs (SimpleName.DoResolveType): If an error is emitted
- during the resolution process, stop the lookup, this avoids
- repeated error reports (same error twice).
-
- * rootcontext.cs: Emit a warning if we have an ambiguous reference.
-
- * typemanager.cs (LookupType): Redo the type lookup code to match
- the needs of System.Reflection.
-
- The issue is that System.Reflection requires references to nested
- types to begin with a "+" sign instead of a dot. So toplevel
- types look like: "NameSpace.TopLevelClass", and nested ones look
- like "Namespace.TopLevelClass+Nested", with arbitrary nesting
- levels.
-
-2002-09-19 Martin Baulig <martin@gnome.org>
-
- * codegen.cs (EmitContext.EmitTopBlock): If control flow analysis
- says that a method always returns or always throws an exception,
- don't report the CS0161.
-
- * statement.cs (FlowBranching.UsageVector.MergeChildren): Always
- set `Returns = new_returns'.
-
-2002-09-19 Martin Baulig <martin@gnome.org>
-
- * expression.cs (MemberAccess.ResolveMemberAccess): When resolving
- to an enum constant, check for a CS0176.
-
-2002-09-18 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (TypeContainer.CheckPairedOperators): Now we check
- for operators that must be in pairs and report errors.
-
- * ecore.cs (SimpleName.DoResolveType): During the initial type
- resolution process, when we define types recursively, we must
- check first for types in our current scope before we perform
- lookups in the enclosing scopes.
-
- * expression.cs (MakeByteBlob): Handle Decimal blobs.
-
- (Invocation.VerifyArgumentsCompat): Call
- TypeManager.TypeToCoreType on the parameter_type.GetElementType.
- I thought we were supposed to always call this, but there are a
- few places in the code where we dont do it.
-
-2002-09-17 Miguel de Icaza <miguel@ximian.com>
-
- * driver.cs: Add support in -linkres and -resource to specify the
- name of the identifier.
-
-2002-09-16 Miguel de Icaza <miguel@ximian.com>
-
- * ecore.cs (StandardConversionExists): Sync with the conversion
- code: allow anything-* to void* conversions.
-
- (FindMostSpecificSource): Use an Expression argument
- instead of a Type, because we might be handed over a Literal which
- gets a few more implicit conversions that plain types do not. So
- this information was being lost.
-
- Also, we drop the temporary type-holder expression when not
- required.
-
-2002-09-17 Martin Baulig <martin@gnome.org>
-
- * class.cs (PropertyBase.CheckBase): Don't check the base class if
- this is an explicit interface implementation.
-
-2002-09-17 Martin Baulig <martin@gnome.org>
-
- * class.cs (PropertyBase.CheckBase): Make this work for indexers with
- different `IndexerName' attributes.
-
- * expression.cs (BaseIndexerAccess): Rewrote this class to use IndexerAccess.
- (IndexerAccess): Added special protected ctor for BaseIndexerAccess and
- virtual CommonResolve().
-
-2002-09-16 Miguel de Icaza <miguel@ximian.com>
-
- * enum.cs (LookupEnumValue): Use the EnumConstant declared type,
- and convert that to the UnderlyingType.
-
- * statement.cs (Foreach.Resolve): Indexers are just like variables
- or PropertyAccesses.
-
- * cs-tokenizer.cs (consume_string): Track line numbers and columns
- inside quoted strings, we were not doing this before.
-
-2002-09-16 Martin Baulig <martin@gnome.org>
-
- * ecore.cs (MethodGroupExpr.DoResolve): If we have an instance expression,
- resolve it. This is needed for the definite assignment check of the
- instance expression, fixes bug #29846.
- (PropertyExpr.DoResolve, EventExpr.DoResolve): Likewise.
-
-2002-09-16 Nick Drochak <ndrochak@gol.com>
-
- * parameter.cs: Fix compile error. Cannot reference static member
- from an instance object. Is this an mcs bug?
-
-2002-09-14 Martin Baulig <martin@gnome.org>
-
- * decl.cs (MemberCache.SetupCacheForInterface): Don't add an interface
- multiple times. Fixes bug #30295, added test-166.cs.
-
-2002-09-14 Martin Baulig <martin@gnome.org>
-
- * statement.cs (Block.Emit): Don't emit unreachable code.
- (Switch.SimpleSwitchEmit, Switch.TableSwitchEmit): Check for missing
- `break' statements.
- (Goto.Emit, Continue.Emit): Set ec.Breaks = true.
-
-2002-09-14 Martin Baulig <martin@gnome.org>
-
- * parameter.cs (Parameter.Attributes): Make this work if Modifier.ISBYREF
- is set.
-
-2002-09-14 Martin Baulig <martin@gnome.org>
-
- * typemanager.cs (TypeManager.IsNestedChildOf): This must return false
- if `type == parent' since in this case `type.IsSubclassOf (parent)' will
- be false on the ms runtime.
-
-2002-09-13 Martin Baulig <martin@gnome.org>
-
- * ecore.cs (SimpleName.SimpleNameResolve): Include the member name in
- the CS0038 error message.
-
-2002-09-12 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (CheckedExpr, UnCheckedExpr): If we have a
- constant inside, return it.
-
-2002-09-12 Martin Baulig <martin@gnome.org>
-
- * cfold.cs (ConstantFold.DoConstantNumericPromotions): Check whether an
- implicit conversion can be done between enum types.
-
- * enum.cs (Enum.LookupEnumValue): If the value is an EnumConstant,
- check whether an implicit conversion to the current enum's UnderlyingType
- exists and report an error if not.
-
- * codegen.cs (CodeGen.Init): Delete the symbol file when compiling
- without debugging support.
-
- * delegate.cs (Delegate.CloseDelegate): Removed, use CloseType instead.
- Fixes bug #30235. Thanks to Ricardo Fernández Pascual.
-
-2002-09-12 Martin Baulig <martin@gnome.org>
-
- * typemanager.cs (TypeManager.IsNestedChildOf): New method.
-
- * ecore.cs (IMemberExpr.DeclaringType): New property.
- (SimpleName.SimpleNameResolve): Check whether we're accessing a
- nonstatic member of an outer type (CS0038).
-
-2002-09-11 Miguel de Icaza <miguel@ximian.com>
-
- * driver.cs: Activate the using-error detector at warning level
- 4 (at least for MS-compatible APIs).
-
- * namespace.cs (VerifyUsing): Small buglett fix.
-
- * pending.cs (PendingImplementation): pass the container pointer.
-
- * interface.cs (GetMethods): Allow for recursive definition. Long
- term, I would like to move every type to support recursive
- definitions, not the current ordering mechanism that we have right
- now.
-
- The situation is this: Attributes are handled before interfaces,
- so we can apply attributes to interfaces. But some attributes
- implement interfaces, we will now handle the simple cases
- (recursive definitions will just get an error).
-
- * parameter.cs: Only invalidate types at the end if we fail to
- lookup all types.
-
-2002-09-09 Martin Baulig <martin@gnome.org>
-
- * ecore.cs (PropertyExpr.Emit): Also check for
- TypeManager.system_int_array_get_length so this'll also work when
- compiling corlib. Fixes #30003.
-
-2002-09-09 Martin Baulig <martin@gnome.org>
-
- * expression.cs (ArrayCreation.MakeByteBlob): Added support for enums
- and throw an exception if we can't get the type's size. Fixed #30040,
- added test-165.cs.
-
-2002-09-09 Martin Baulig <martin@gnome.org>
-
- * ecore.cs (PropertyExpr.DoResolve): Added check for static properies.
-
- * expression.cs (SizeOf.DoResolve): Sizeof is only allowed in unsafe
- context. Fixes bug #30027.
-
- * delegate.cs (NewDelegate.Emit): Use OpCodes.Ldvirtftn for
- virtual functions. Fixes bug #30043, added test-164.cs.
-
-2002-09-08 Ravi Pratap <ravi@ximian.com>
-
- * attribute.cs : Fix a small NullRef crash thanks to my stupidity.
-
-2002-09-08 Nick Drochak <ndrochak@gol.com>
-
- * driver.cs: Use an object to get the windows codepage since it's not a
- static property.
-
-2002-09-08 Miguel de Icaza <miguel@ximian.com>
-
- * statement.cs (For.Emit): for infinite loops (test == null)
- return whether there is a break inside, not always "true".
-
- * namespace.cs (UsingEntry): New struct to hold the name of the
- using definition, the location where it is defined, and whether it
- has been used in a successful type lookup.
-
- * rootcontext.cs (NamespaceLookup): Use UsingEntries instead of
- strings.
-
- * decl.cs: ditto.
-
-2002-09-06 Ravi Pratap <ravi@ximian.com>
-
- * attribute.cs : Fix incorrect code which relied on catching
- a NullReferenceException to detect a null being passed in
- where an object was expected.
-
-2002-09-06 Miguel de Icaza <miguel@ximian.com>
-
- * statement.cs (Try): flag the catch variable as assigned
-
- * expression.cs (Cast): Simplified by using ResolveType instead of
- manually resolving.
-
- * statement.cs (Catch): Fix bug by using ResolveType.
-
-2002-09-06 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (BetterConversion): Special case for when we have
- a NullLiteral as the argument and we have to choose between string
- and object types - we choose string the way csc does.
-
- * attribute.cs (Attribute.Resolve): Catch the
- NullReferenceException and report error #182 since the Mono
- runtime no more has the bug and having this exception raised means
- we tried to select a constructor which takes an object and is
- passed a null.
-
-2002-09-05 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (Invocation.OverloadResolve): Flag a nicer error
- message (1502, 1503) when we can't locate a method after overload
- resolution. This is much more informative and closes the bug
- Miguel reported.
-
- * interface.cs (PopulateMethod): Return if there are no argument
- types. Fixes a NullReferenceException bug.
-
- * attribute.cs (Attribute.Resolve): Ensure we allow TypeOf
- expressions too. Previously we were checking only in one place for
- positional arguments leaving out named arguments.
-
- * ecore.cs (ImplicitNumericConversion): Conversion from underlying
- type to the enum type is not allowed. Remove code corresponding to
- that.
-
- (ConvertNumericExplicit): Allow explicit conversions from
- the underlying type to enum type. This precisely follows the spec
- and closes a bug filed by Gonzalo.
-
-2002-09-04 Gonzalo Paniagua Javier <gonzalo@ximian.com>
-
- * compiler.csproj:
- * compiler.csproj.user: patch from Adam Chester (achester@bigpond.com).
-
-2002-09-03 Miguel de Icaza <miguel@ximian.com>
-
- * statement.cs (SwitchLabel.ResolveAndReduce): In the string case,
- it was important that we stored the right value after the
- reduction in `converted'.
-
-2002-09-04 Martin Baulig <martin@gnome.org>
-
- * location.cs (Location.SymbolDocument): Use full pathnames for the
- source files.
-
-2002-08-30 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (ComposedCast): Use DeclSparce.ResolveType instead
- of the expression resolve mechanism, because that will catch the
- SimpleName error failures.
-
- (Conditional): If we can not resolve the
- expression, return, do not crash.
-
-2002-08-29 Gonzalo Paniagua Javier <gonzalo@ximian.com>
-
- * cs-tokenizer.cs:
- (location): display token name instead of its number.
-
-2002-08-28 Martin Baulig <martin@gnome.org>
-
- * expression.cs (Binary.ResolveOperator): Don't silently return
- but return an error if an operator cannot be applied between two
- enum types.
-
-2002-08-28 Martin Baulig <martin@gnome.org>
-
- * class.cs (Constructor.Define): Set the permission attributes
- correctly instead of making all constructors public.
-
-2002-08-28 Martin Baulig <martin@gnome.org>
-
- * ecore.cs (Expression.DoResolve): Do a TypeManager.MemberLook
- for private members before reporting a CS0103; if we find anything,
- it's a CS0122.
-
-2002-08-28 Martin Baulig <martin@gnome.org>
-
- * typemanager.cs (TypeManager.FilterWithClosure): It's not enough
- to check whether `closure_start_type == closure_invocation_type',
- we also need to check whether `m.DeclaringType == closure_invocation_type'
- before bypassing the permission checks. We might be accessing
- protected/private members from the base class.
- (TypeManager.RealMemberLookup): Only set private_ok if private
- members were requested via BindingFlags.NonPublic.
-
- * ecore.cs (MethodGroupExpr.IsExplicitImpl): New property.
-
- * expression.cs (MemberAccess.ResolveMemberAccess): Set
- MethodGroupExpr.IsExplicitImpl if appropriate.
- (Invocation.DoResolve): Don't report the CS0120 for explicit
- interface implementations.
-
-2002-08-27 Martin Baulig <martin@gnome.org>
-
- * expression.cs (Invocation.DoResolve): If this is a static
- method and we don't have an InstanceExpression, we must report
- a CS0120.
-
-2002-08-25 Martin Baulig <martin@gnome.org>
-
- * expression.cs (Binary.ResolveOperator): Don't allow `!=' and
- `==' between a valuetype and an object.
-
-2002-08-25 Miguel de Icaza <miguel@ximian.com>
-
- * ecore.cs (TypeExpr): Provide a ToString method.
-
-2002-08-24 Martin Baulig <martin@gnome.org>
-
- * codegen.cs (CodeGen.InitMonoSymbolWriter): The symbol file is
- now called proggie.dbg and it's a binary file.
-
-2002-08-23 Martin Baulig <martin@gnome.org>
-
- * decl.cs (MemberCache.AddMethods): Ignore varargs methods.
-
-2002-08-23 Martin Baulig <martin@gnome.org>
-
- * struct.cs (MyStructInfo.ctor): Make this work with empty
- structs; it's not allowed to use foreach() on null.
-
-2002-08-23 Martin Baulig <martin@gnome.org>
-
- * codegen.cs (CodeGen.InitMonoSymbolWriter): Tell the symbol
- writer the full pathname of the generated assembly.
-
-2002-08-23 Martin Baulig <martin@gnome.org>
-
- * statements.cs (FlowBranching.UsageVector.MergeChildren):
- A `finally' block never returns or breaks; improved handling of
- unreachable code.
-
-2002-08-23 Martin Baulig <martin@gnome.org>
-
- * statement.cs (Throw.Resolve): Allow `throw null'.
-
-2002-08-23 Martin Baulig <martin@gnome.org>
-
- * expression.cs (MemberAccess.ResolveMemberAccess): If this is an
- EventExpr, don't do a DeclaredOnly MemberLookup, but check whether
- `ee.EventInfo.DeclaringType == ec.ContainerType'. The
- MemberLookup would return a wrong event if this is an explicit
- interface implementation and the class has an event with the same
- name.
-
-2002-08-23 Martin Baulig <martin@gnome.org>
-
- * statement.cs (Block.AddChildVariableNames): New public method.
- (Block.AddChildVariableName): Likewise.
- (Block.IsVariableNameUsedInChildBlock): Likewise.
- (Block.AddVariable): Check whether a variable name has already
- been used in a child block.
-
- * cs-parser.jay (declare_local_variables): Mark all variable names
- from the current block as being used in a child block in the
- implicit block.
-
-2002-08-23 Martin Baulig <martin@gnome.org>
-
- * codegen.cs (CodeGen.InitializeSymbolWriter): Abort if we can't
- find the symbol writer.
-
- * driver.cs: csc also allows the arguments to /define being
- separated by commas, not only by semicolons.
-
-2002-08-23 Martin Baulig <martin@gnome.org>
-
- * interface.cs (Interface.GetMembers): Added static check for events.
-
-2002-08-15 Martin Baulig <martin@gnome.org>
-
- * class.cs (MethodData.EmitDestructor): In the Expression.MemberLookup
- call, use ec.ContainerType.BaseType as queried_type and invocation_type.
-
- * ecore.cs (Expression.MemberLookup): Added documentation and explained
- why the MethodData.EmitDestructor() change was necessary.
-
-2002-08-20 Martin Baulig <martin@gnome.org>
-
- * class.cs (TypeContainer.FindMembers): Added static check for events.
-
- * decl.cs (MemberCache.AddMembers): Handle events like normal members.
-
- * typemanager.cs (TypeHandle.GetMembers): When queried for events only,
- use Type.GetEvents(), not Type.FindMembers().
-
-2002-08-20 Martin Baulig <martin@gnome.org>
-
- * decl.cs (MemberCache): Added a special method cache which will
- be used for method-only searched. This ensures that a method
- search will return a MethodInfo with the correct ReflectedType for
- inherited methods.
-
-2002-08-20 Martin Baulig <martin@gnome.org>
-
- * decl.cs (DeclSpace.FindMembers): Made this public.
-
-2002-08-20 Gonzalo Paniagua Javier <gonzalo@ximian.com>
-
- * delegate.cs: fixed build on windows.
- [FIXME: Filed as bug #29150: MCS must report these errors.]
-
-2002-08-19 Ravi Pratap <ravi@ximian.com>
-
- * ecore.cs (StandardConversionExists): Return a false
- if we are trying to convert the void type to anything else
- since that is not allowed.
-
- * delegate.cs (DelegateInvocation.DoResolve): Ensure that
- we flag error 70 in the event an event is trying to be accessed
- directly from outside the declaring type.
-
-2002-08-20 Martin Baulig <martin@gnome.org>
-
- * typemanager.cs, decl.cs: Moved MemberList, IMemberContainer and
- MemberCache from typemanager.cs to decl.cs.
-
-2002-08-19 Martin Baulig <martin@gnome.org>
-
- * class.cs (TypeContainer): Implement IMemberContainer.
- (TypeContainer.DefineMembers): Create the MemberCache.
- (TypeContainer.FindMembers): Do better BindingFlags checking; only
- return public members if BindingFlags.Public was given, check
- whether members are static.
-
-2002-08-16 Martin Baulig <martin@gnome.org>
-
- * decl.cs (DeclSpace.Define): Splitted this in Define and
- DefineMembers. DefineMembers is called first and initializes the
- MemberCache.
-
- * rootcontext.cs (RootContext.DefineMembers): New function. Calls
- DefineMembers() on all our DeclSpaces.
-
- * class.cs (TypeContainer.Define): Moved all code to DefineMembers(),
- but call DefineMembers() on all nested interfaces. We call their
- Define() in our new Define() function.
-
- * interface.cs (Interface): Implement IMemberContainer.
- (Interface.Define): Moved all code except the attribute stuf to
- DefineMembers().
- (Interface.DefineMembers): Initialize the member cache.
-
- * typemanager.cs (IMemberFinder): Removed this interface, we don't
- need this anymore since we can use MemberCache.FindMembers directly.
-
-2002-08-19 Martin Baulig <martin@gnome.org>
-
- * typemanager.cs (MemberCache): When creating the cache for an
- interface type, add all inherited members.
- (TypeManager.MemberLookup_FindMembers): Changed `ref bool searching'
- to `out bool used_cache' and documented it.
- (TypeManager.MemberLookup): If we already used the cache in the first
- iteration, we don't need to do the interfaces check.
-
-2002-08-19 Martin Baulig <martin@gnome.org>
-
- * decl.cs (DeclSpace.FindMembers): New abstract method. Moved this
- here from IMemberFinder and don't implement this interface anymore.
- (DeclSpace.MemberCache): Moved here from IMemberFinder.
-
- * typemanager.cs (IMemberFinder): This interface is now only used by
- classes which actually support the member cache.
- (TypeManager.builder_to_member_finder): Renamed to builder_to_declspace
- since we only put DeclSpaces into this Hashtable.
- (MemberLookup_FindMembers): Use `builder_to_declspace' if the type is
- a dynamic type and TypeHandle.GetTypeHandle() otherwise.
-
-2002-08-16 Martin Baulig <martin@gnome.org>
-
- * typemanager.cs (ICachingMemberFinder): Removed.
- (IMemberFinder.MemberCache): New property.
- (TypeManager.FindMembers): Merged this with RealFindMembers().
- This function will never be called from TypeManager.MemberLookup()
- so we can't use the cache here, just the IMemberFinder.
- (TypeManager.MemberLookup_FindMembers): Check whether the
- IMemberFinder has a MemberCache and call the cache's FindMembers
- function.
- (MemberCache): Rewrote larger parts of this yet another time and
- cleaned it up a bit.
-
-2002-08-15 Miguel de Icaza <miguel@ximian.com>
-
- * driver.cs (LoadArgs): Support quoting.
-
- (Usage): Show the CSC-like command line arguments.
-
- Improved a few error messages.
-
-2002-08-15 Martin Baulig <martin@gnome.org>
-
- * typemanager.cs (IMemberContainer.Type): New property.
- (IMemberContainer.IsInterface): New property.
-
- The following changes are conditional to BROKEN_RUNTIME, which is
- defined at the top of the file.
-
- * typemanager.cs (MemberCache.MemberCache): Don't add the base
- class'es members, but add all members from TypeHandle.ObjectType
- if we're an interface.
- (MemberCache.AddMembers): Set the Declared flag if member.DeclaringType
- is the current type.
- (MemberCache.CacheEntry.Container): Removed this field.
- (TypeHandle.GetMembers): Include inherited members.
-
-2002-08-14 Gonzalo Paniagua Javier <gonzalo@ximian.com>
-
- * typemanager.cs: fixed compilation and added a comment on a field that
- is never used.
-
-2002-08-15 Martin Baulig <martin@gnome.org>
-
- * class.cs (ConstructorInitializer.Resolve): In the
- Expression.MemberLookup call, use the queried_type as
- invocation_type.
-
- * typemanager.cs (IMemberContainer.GetMembers): Removed the `bool
- declared' attribute, it's always true.
- (IMemberContainer.Parent, IMemberContainer.Name): New properties.
- (TypeManager.MemberLookup_FindMembers): [FIXME FIXME FIXME] Added
- temporary wrapper for FindMembers which tells MemberLookup whether
- members from the base classes are included in the return value.
- This will go away soon.
- (TypeManager.MemberLookup): Use this temporary hack here; once the
- new MemberCache is completed, we don't need to do the DeclaredOnly
- looping here anymore since the MemberCache will take care of this.
- (TypeManager.IsSubclassOrNestedChildOf): Allow `type == parent'.
- (MemberCache): When creating the MemberCache for a class, get
- members from the current class and all its base classes.
- (MemberCache.CacheEntry.Container): New field. This is a
- temporary hack until the Mono runtime is fixed to distinguish
- between ReflectedType and DeclaringType. It allows us to use MCS
- with both the MS runtime and the unfixed Mono runtime without
- problems and without accecting performance.
- (MemberCache.SearchMembers): The DeclaredOnly looping from
- TypeManager.MemberLookup is now done here.
-
-2002-08-14 Martin Baulig <martin@gnome.org>
-
- * statement.cs (MyStructInfo.MyStructInfo): Don't call
- Type.GetFields on dynamic types but get the fields from the
- corresponding TypeContainer.
- (MyStructInfo.GetStructInfo): Added check for enum types.
-
- * typemanager.cs (MemberList.IsSynchronized): Implemented.
- (MemberList.SyncRoot): Implemented.
- (TypeManager.FilterWithClosure): No need to check permissions if
- closure_start_type == closure_invocation_type, don't crash if
- closure_invocation_type is null.
-
-2002-08-13 Martin Baulig <martin@gnome.org>
-
- Rewrote TypeContainer.FindMembers to use a member cache. This
- gives us a speed increase of about 35% for the self-hosting MCS
- build and of about 15-20% for the class libs (both on GNU/Linux).
-
- * report.cs (Timer): New class to get enhanced profiling. This
- whole class is "TIMER" conditional since it remarkably slows down
- compilation speed.
-
- * class.cs (MemberList): New class. This is an IList wrapper
- which we're now using instead of passing MemberInfo[]'s around to
- avoid copying this array unnecessarily.
- (IMemberFinder.FindMember): Return a MemberList, not a MemberInfo [].
- (ICachingMemberFinder, IMemberContainer): New interface.
- (TypeManager.FilterWithClosure): If `criteria' is null, the name
- has already been checked, otherwise use it for the name comparision.
- (TypeManager.FindMembers): Renamed to RealMemberFinder and
- provided wrapper which tries to use ICachingMemberFinder.FindMembers
- if possible. Returns a MemberList, not a MemberInfo [].
- (TypeHandle): New class, implements IMemberContainer. We create
- one instance of this class per type, it contains a MemberCache
- which is used to do the member lookups.
- (MemberCache): New class. Each instance of this class contains
- all members of a type and a name-based hash table.
- (MemberCache.FindMembers): This is our new member lookup
- function. First, it looks up all members of the requested name in
- the hash table. Then, it walks this list and sorts out all
- applicable members and returns them.
-
-2002-08-13 Martin Baulig <martin@gnome.org>
-
- In addition to a nice code cleanup, this gives us a performance
- increase of about 1.4% on GNU/Linux - not much, but it's already
- half a second for the self-hosting MCS compilation.
-
- * typemanager.cs (IMemberFinder): New interface. It is used by
- TypeManager.FindMembers to call FindMembers on a TypeContainer,
- Enum, Delegate or Interface.
- (TypeManager.finder_to_member_finder): New PtrHashtable.
- (TypeManager.finder_to_container): Removed.
- (TypeManager.finder_to_delegate): Removed.
- (TypeManager.finder_to_interface): Removed.
- (TypeManager.finder_to_enum): Removed.
-
- * interface.cs (Interface): Implement IMemberFinder.
-
- * delegate.cs (Delegate): Implement IMemberFinder.
-
- * enum.cs (Enum): Implement IMemberFinder.
-
- * class.cs (TypeContainer): Implement IMemberFinder.
-
-2002-08-12 Martin Baulig <martin@gnome.org>
-
- * ecore.cs (TypeExpr.DoResolveType): Mark this as virtual.
-
-2002-08-12 Martin Baulig <martin@gnome.org>
-
- * ecore.cs (ITypeExpression): New interface for expressions which
- resolve to a type.
- (TypeExpression): Renamed to TypeLookupExpression.
- (Expression.DoResolve): If we're doing a types-only lookup, the
- expression must implement the ITypeExpression interface and we
- call DoResolveType() on it.
- (SimpleName): Implement the new ITypeExpression interface.
- (SimpleName.SimpleNameResolve): Removed the ec.OnlyLookupTypes
- hack, the situation that we're only looking up types can't happen
- anymore when this method is called. Moved the type lookup code to
- DoResolveType() and call it.
- (SimpleName.DoResolveType): This ITypeExpression interface method
- is now doing the types-only lookup.
- (TypeExpr, TypeLookupExpression): Implement ITypeExpression.
- (ResolveFlags): Added MaskExprClass.
-
- * expression.cs (MemberAccess): Implement the ITypeExpression
- interface.
- (MemberAccess.DoResolve): Added support for a types-only lookup
- when we're called via ITypeExpression.DoResolveType().
- (ComposedCast): Implement the ITypeExpression interface.
-
- * codegen.cs (EmitContext.OnlyLookupTypes): Removed. Call
- Expression.Resolve() with ResolveFlags.Type instead.
-
-2002-08-12 Martin Baulig <martin@gnome.org>
-
- * interface.cs (Interface.Define): Apply attributes.
-
- * attribute.cs (Attribute.ApplyAttributes): Added support for
- interface attributes.
-
-2002-08-11 Martin Baulig <martin@gnome.org>
-
- * statement.cs (Block.Emit): Only check the "this" variable if we
- do not always throw an exception.
-
- * ecore.cs (PropertyExpr.DoResolveLValue): Implemented, check
- whether the property has a set accessor.
-
-2002-08-11 Martin Baulig <martin@gnome.org>
-
- Added control flow analysis support for structs.
-
- * ecore.cs (ResolveFlags): Added `DisableFlowAnalysis' to resolve
- with control flow analysis turned off.
- (IVariable): New interface.
- (SimpleName.SimpleNameResolve): If MemberAccess.ResolveMemberAccess
- returns an IMemberExpr, call DoResolve/DoResolveLValue on it.
- (FieldExpr.DoResolve): Resolve the instance expression with flow
- analysis turned off and do the definite assignment check after the
- resolving when we know what the expression will resolve to.
-
- * expression.cs (LocalVariableReference, ParameterReference):
- Implement the new IVariable interface, only call the flow analysis
- code if ec.DoFlowAnalysis is true.
- (This): Added constructor which takes a Block argument. Implement
- the new IVariable interface.
- (MemberAccess.DoResolve, MemberAccess.DoResolveLValue): Call
- DoResolve/DoResolveLValue on the result of ResolveMemberLookup().
- This does the definite assignment checks for struct members.
-
- * class.cs (Constructor.Emit): If this is a non-static `struct'
- constructor which doesn't have any initializer, call
- Block.AddThisVariable() to tell the flow analysis code that all
- struct elements must be initialized before control returns from
- the constructor.
-
- * statement.cs (MyStructInfo): New public class.
- (UsageVector.this [VariableInfo vi]): Added `int field_idx'
- argument to this indexer. If non-zero, check an individual struct
- member, not the whole struct.
- (FlowBranching.CheckOutParameters): Check struct members.
- (FlowBranching.IsVariableAssigned, SetVariableAssigned): Added
- overloaded versions of these methods which take an additional
- `int field_idx' argument to check struct members.
- (FlowBranching.IsParameterAssigned, SetParameterAssigned): Added
- overloaded versions of these methods which take an additional
- `string field_name' argument to check struct member.s
- (VariableInfo): Implement the IVariable interface.
- (VariableInfo.StructInfo): New public property. Returns the
- MyStructInfo instance of the variable if it's a struct or null.
- (Block.AddThisVariable): New public method. This is called from
- Constructor.Emit() for non-static `struct' constructor which do
- not have any initializer. It creates a special variable for the
- "this" instance variable which will be checked by the flow
- analysis code to ensure that all of the struct's fields are
- initialized before control returns from the constructor.
- (UsageVector): Added support for struct members. If a
- variable/parameter is a struct with N members, we reserve a slot
- in the usage vector for each member. A struct is considered fully
- initialized if either the struct itself (slot 0) or all its
- members are initialized.
-
-2002-08-08 Martin Baulig <martin@gnome.org>
-
- * driver.cs (Driver.MainDriver): Only report an error CS5001
- if there were no compilation errors.
-
- * codegen.cs (EmitContext.EmitContext): Use the DeclSpace's
- `UnsafeContext' property to determine whether the parent is in
- unsafe context rather than checking the parent's ModFlags:
- classes nested in an unsafe class are unsafe as well.
-
-2002-08-08 Martin Baulig <martin@gnome.org>
-
- * statement.cs (UsageVector.MergeChildren): Distinguish between
- `Breaks' and `Returns' everywhere, don't set `Breaks' anymore if
- we return. Added test17() and test18() to test-154.cs.
-
-2002-08-08 Martin Baulig <martin@gnome.org>
-
- * typemanager.cs (TypeManager.FilterWithClosure): If we have
- Family access, make sure the invoking type isn't a subclass of the
- queried type (that'd be a CS1540).
-
- * ecore.cs (Expression.MemberLookup): Added overloaded version of
- this method which takes an additional `Type invocation_type'.
-
- * expression.cs (BaseAccess.DoResolve): Use the base type as
- invocation and query type.
- (MemberAccess.DoResolve): If the lookup failed and we're about to
- report a CS0122, try a lookup with the ec.ContainerType - if this
- succeeds, we must report a CS1540.
-
-2002-08-08 Martin Baulig <martin@gnome.org>
-
- * ecore.cs (IMemberExpr): Added `bool IsInstance' property.
- (MethodGroupExpr): Implement the IMemberExpr interface.
-
- * expression (MemberAccess.ResolveMemberAccess): No need to have
- any special code for MethodGroupExprs anymore, they're now
- IMemberExprs.
-
-2002-08-08 Martin Baulig <martin@gnome.org>
-
- * typemanager.cs (TypeManager.FilterWithClosure): Check Assembly,
- Family, FamANDAssem and FamORAssem permissions.
- (TypeManager.IsSubclassOrNestedChildOf): New public method.
-
-2002-08-08 Martin Baulig <martin@gnome.org>
-
- * statement.cs (FlowBranchingType): Added LOOP_BLOCK.
- (UsageVector.MergeChildren): `break' breaks unless we're in a switch
- or loop block.
-
-Thu Aug 8 10:28:07 CEST 2002 Paolo Molaro <lupus@ximian.com>
-
- * driver.cs: implemented /resource option to embed managed resources.
-
-2002-08-07 Martin Baulig <martin@gnome.org>
-
- * class.cs (FieldBase.Initializer): Renamed to `init' and made private.
- (FieldBase.HasFieldInitializer): New public property.
- (FieldBase.GetInitializerExpression): New public method. Resolves and
- returns the field initializer and makes sure it is only resolved once.
- (TypeContainer.EmitFieldInitializers): Call
- FieldBase.GetInitializerExpression to get the initializer, this ensures
- that it isn't resolved multiple times.
-
- * codegen.cs (EmitContext): Added `bool IsFieldInitialier'. This tells
- the resolving process (SimpleName/MemberLookup) that we're currently
- emitting a field initializer (which must not access any instance members,
- this is an error CS0236).
-
- * ecore.cs (SimpleName.Error_ObjectRefRequired): Added EmitContext
- argument, if the `IsFieldInitializer' flag is set, we must report and
- error CS0236 and not an error CS0120.
-
-2002-08-07 Martin Baulig <martin@gnome.org>
-
- * ecore.cs (IMemberExpr): New public interface.
- (FieldExpr, PropertyExpr, EventExpr): Implement IMemberExpr.
- (SimpleName.SimpleNameResolve): Call MemberAccess.ResolveMemberAccess
- if the expression is an IMemberExpr.
-
- * expression.cs (MemberAccess.ResolveMemberAccess): Allow `left'
- to be null, implicitly default to `this' if we're non-static in
- this case. Simplified the code a lot by using the new IMemberExpr
- interface. Also fixed bug #28176 here.
-
-2002-08-06 Martin Baulig <martin@gnome.org>
-
- * cs-parser.jay (SimpleLookup): Removed. We need to create
- ParameterReferences during semantic analysis so that we can do a
- type-only search when resolving Cast, TypeOf and SizeOf.
- (block): Pass the `current_local_parameters' to the Block's
- constructor.
-
- * class.cs (ConstructorInitializer): Added `Parameters parameters'
- argument to the constructor.
- (ConstructorInitializer.Resolve): Create a temporary implicit
- block with the parameters.
-
- * ecore.cs (SimpleName.SimpleNameResolve): Resolve parameter
- references here if we aren't doing a type-only search.
-
- * statement.cs (Block): Added constructor which takes a
- `Parameters parameters' argument.
- (Block.Parameters): New public property.
-
- * support.cs (InternalParameters.Parameters): Renamed `parameters'
- to `Parameters' and made it public readonly.
-
-2002-08-06 Martin Baulig <martin@gnome.org>
-
- * ecore.cs (Expression.Warning): Made this public as well.
-
- * report.cs (Report.Debug): Print the contents of collections.
-
-2002-08-06 Martin Baulig <martin@gnome.org>
-
- * ecore.cs (Expression.ResolveFlags): New [Flags] enum. This is
- used to tell Resolve() which kinds of expressions it may return.
- (Expression.Resolve): Added overloaded version of this method which
- takes a `ResolveFlags flags' argument. This can be used to tell
- Resolve() which kinds of expressions it may return. Reports a
- CS0118 on error.
- (Expression.ResolveWithSimpleName): Removed, use Resolve() with
- ResolveFlags.SimpleName.
- (Expression.Error118): Added overloaded version of this method which
- takes a `ResolveFlags flags' argument. It uses the flags to determine
- which kinds of expressions are allowed.
-
- * expression.cs (Argument.ResolveMethodGroup): New public method.
- Resolves an argument, but allows a MethodGroup to be returned.
- This is used when invoking a delegate.
-
- * TODO: Updated a bit.
-
-2002-08-06 Gonzalo Paniagua Javier <gonzalo@ximian.com>
-
- Fixed compilation with csc.
-
- * ecore.cs: Expression.Error made public. Is this correct? Should
- Warning be made public too?
-
- * expression.cs: use ea.Location instead of ea.loc.
- [FIXME: Filed as bug #28607: MCS must report these errors.]
-
-2002-08-06 Martin Baulig <martin@gnome.org>
-
- * ecore.cs (Expression.loc): Moved the location here instead of
- duplicating it in all derived classes.
- (Expression.Location): New public property.
- (Expression.Error, Expression.Warning): Made them non-static and
- removed the location argument.
- (Expression.Warning): Added overloaded version which takes an
- `int level' argument.
- (Expression.Error118): Make this non-static and removed the
- expression and location arguments.
- (TypeExpr): Added location argument to the constructor.
-
- * expression.cs (StaticCallExpr): Added location argument to
- the constructor.
- (Indirection, PointerArithmetic): Likewise.
- (CheckedExpr, UnCheckedExpr): Likewise.
- (ArrayAccess, IndexerAccess, UserCast, ArrayPtr): Likewise.
- (StringPtr): Likewise.
-
-
-2002-08-05 Martin Baulig <martin@gnome.org>
-
- * expression.cs (BaseAccess.DoResolve): Actually report errors.
-
- * assign.cs (Assign.DoResolve): Check whether the source
- expression is a value or variable.
-
- * statement.cs (Try.Resolve): Set ec.InTry/InCatch/InFinally
- while resolving the corresponding blocks.
-
- * interface.cs (Interface.GetInterfaceTypeByName): Actually report
- an error, don't silently return null.
-
- * statement.cs (Block.AddVariable): Do the error reporting here
- and distinguish between CS0128 and CS0136.
- (Block.DoResolve): Report all unused labels (warning CS0164).
- (LabeledStatement): Pass the location to the constructor.
- (LabeledStatement.HasBeenReferenced): New property.
- (LabeledStatement.Resolve): Set it to true here.
-
- * statement.cs (Return.Emit): Return success even after reporting
- a type mismatch error (CS0126 or CS0127), this is what csc does and
- it avoids confusing the users with any consecutive errors.
-
-2002-08-05 Martin Baulig <martin@gnome.org>
-
- * enum.cs (Enum.LookupEnumValue): Catch circular definitions.
-
- * const.cs (Const.LookupConstantValue): Catch circular definitions.
-
- * expression.cs (MemberAccess.DoResolve): Silently return if an
- error has already been reported.
-
- * ecore.cs (Expression.MemberLookupFinal): Silently return if an
- error has already been reported.
-
-2002-08-05 Martin Baulig <martin@gnome.org>
-
- * statement.cs (UsageVector): Only initialize the `parameters'
- vector if we actually have any "out" parameters.
-
-2002-08-05 Martin Baulig <martin@gnome.org>
-
- * expression.cs (Binary.ResolveOperator): When combining delegates,
- they must have the same type.
-
-2002-08-05 Martin Baulig <martin@gnome.org>
-
- * typemanager.cs (TypeManager.GetArgumentTypes): Don't call
- PropertyInfo.GetIndexParameters() on dynamic types, this doesn't
- work with the ms runtime and we also don't need it: if we're a
- PropertyBuilder and not in the `indexer_arguments' hash, then we
- are a property and not an indexer.
-
- * class.cs (TypeContainer.AsAccessible): Use Type.IsArray,
- Type.IsPointer and Type.IsByRef instead of Type.HasElementType
- since the latter one doesn't work with the ms runtime.
-
-2002-08-03 Martin Baulig <martin@gnome.org>
-
- Fixed bugs #27998 and #22735.
-
- * class.cs (Method.IsOperator): New public field.
- (Method.CheckBase): Report CS0111 if there's already a method
- with the same parameters in the current class. Report CS0508 when
- attempting to change the return type of an inherited method.
- (MethodData.Emit): Report CS0179 if a method doesn't have a body
- and it's not marked abstract or extern.
- (PropertyBase): New abstract base class for Property and Indexer.
- (PropertyBase.CheckBase): Moved here from Property and made it work
- for indexers.
- (PropertyBase.Emit): Moved here from Property.Emit, Indexer.Emit is
- the same so we can reuse it there.
- (Property, Indexer): Derive from PropertyBase.
- (MethodSignature.inheritable_property_signature_filter): New delegate
- to find properties and indexers.
-
- * decl.cs (MemberCore.CheckMethodAgainstBase): Added `string name'
- argument and improved error reporting.
-
- * parameter.cs (Parameters.GetEmptyReadOnlyParameters): Renamed to
- EmptyReadOnlyParameters and made it a property.
-
- * typemanager.cs (TypeManager.GetArgumentTypes): Added overloaded
- version of this method which takes a `PropertyInfo indexer'.
- (TypeManager.RegisterIndexer): New method.
-
- * class.cs: Added myself as author of this file :-)
-
-2002-08-03 Gonzalo Paniagua Javier <gonzalo@ximian.com>
-
- * class.cs: fixed compilation on windoze.
-
-2002-08-03 Martin Baulig <martin@gnome.org>
-
- * interface.cs (Interface.GetInterfaceBases): Check whether all
- base interfaces are at least as accessible than the current one.
-
- * class.cs (TypeContainer.GetClassBases): Check whether base types
- are at least as accessible than the current type.
- (TypeContainer.AsAccessible): Implemented and made non-static.
- (MemberBase.CheckParameters): Report errors if the accessibility
- checks fail.
-
- * delegate.cs (Delegate.Delegate): The default visibility is
- internal for top-level types and private for nested types.
- (Delegate.Define): Report errors if the accessibility checks fail.
-
- * enum.cs (Enum.Enum): The default visibility is internal for
- top-level types and private for nested types.
- (Enum.DefineType): Compute the correct visibility.
-
- * modifiers.cs (Modifiers.TypeAttr): Added a version of this
- function which takes a `bool is_toplevel' instead of a TypeContainer.
-
- * typemanager.cs (TypeManager.IsBuiltinType): `void' is also a
- builtin type.
-
-2002-08-02 Martin Baulig <martin@gnome.org>
-
- * expression.cs (LocalVariableReferenc): Added constructor which
- takes additional `VariableInfo vi' and `bool is_readonly' arguments.
- (LocalVariableReference.IsReadOnly): New property.
- (LocalVariableReference.DoResolveLValue): Report a CS1604 if the
- variable is readonly, use our own readonly flag to do this; you can
- use the new constructor to get a writable reference to a read-only
- variable.
-
- * cs-parser.jay (foreach_statement, using_statement): Get a writable
- reference to the local variable.
-
-2002-08-01 Miguel de Icaza <miguel@ximian.com>
-
- * rootcontext.cs (ResolveCore): Also include System.Exception
-
- * statement.cs (Block.Emit): Do not emit the dead-code warnings if
- we reach an EmptyStatement.
-
- (Catch.DoResolve, Throw.DoResolve): Throwing the System.Exception
- is also fine.
-
- * expression.cs (Binary.ResolveOperator): Check error result in
- two places.
-
- use brtrue/brfalse directly and avoid compares to null.
-
-2002-08-02 Martin Baulig <martin@gnome.org>
-
- * class.cs (TypeContainer.Define): Define all nested interfaces here.
- Fixes bug #28407, added test-155.cs.
-
-2002-08-01 Martin Baulig <martin@gnome.org>
-
- * class.cs (Event.EmitDefaultMethod): Make this work with static
- events. Fixes #28311, added verify-3.cs.
-
-2002-08-01 Martin Baulig <martin@gnome.org>
-
- * statement.cs (ForeachHelperMethods): Added `enumerator_type' and
- `is_disposable' fields.
- (Foreach.GetEnumeratorFilter): Set `hm.enumerator_type' and
- `hm.is_disposable' if we're using the collection pattern.
- (Foreach.EmitCollectionForeach): Use the correct type for the
- enumerator's local variable, only emit the try/finally block if
- necessary (fixes #27713).
-
-2002-08-01 Martin Baulig <martin@gnome.org>
-
- * ecore.cs (Expression.report118): Renamed to Error118 and made
- it public static.
-
- * statement.cs (Throw.Resolve): Check whether the expression is of
- the correct type (CS0118) and whether the type derives from
- System.Exception (CS0155).
- (Catch.Resolve): New method. Do the type lookup here and check
- whether it derives from System.Exception (CS0155).
- (Catch.CatchType, Catch.IsGeneral): New public properties.
-
- * typemanager.cs (TypeManager.exception_type): Added.
-
-2002-07-31 Miguel de Icaza <miguel@ximian.com>
-
- * driver.cs: Updated About function.
-
-2002-07-31 Martin Baulig <martin@gnome.org>
-
- Implemented Control Flow Analysis.
-
- * codegen.cs (EmitContext.DoFlowAnalysis): New public variable.
- (EmitContext.CurrentBranching): Added.
- (EmitContext.StartFlowBranching): Added.
- (EmitContext.EndFlowBranching): Added.
- (EmitContext.KillFlowBranching): Added.
- (EmitContext.IsVariableAssigned): Added.
- (EmitContext.SetVariableAssigned): Added.
- (EmitContext.IsParameterAssigned): Added.
- (EmitContext.SetParameterAssigned): Added.
- (EmitContext.EmitTopBlock): Added `InternalParameters ip' argument.
- Added control flow analysis stuff here.
-
- * expression.cs (Unary.DoResolve): If the operator is Oper.AddressOf,
- resolve the expression as lvalue.
- (LocalVariableReference.DoResolve): Check whether the variable has
- already been assigned.
- (ParameterReference.DoResolveLValue): Override lvalue resolve to mark
- the parameter as assigned here.
- (ParameterReference.DoResolve): Check whether the parameter has already
- been assigned.
- (Argument.Resolve): If it's a `ref' or `out' argument, resolve the
- expression as lvalue.
-
- * statement.cs (FlowBranching): New class for the flow analysis code.
- (Goto): Resolve the label in Resolve, not in Emit; added flow analysis.
- (LabeledStatement.IsDefined): New public property.
- (LabeledStatement.AddUsageVector): New public method to tell flow
- analyis that the label may be reached via a forward jump.
- (GotoCase): Lookup and resolve the label in Resolve, not in Emit; added
- flow analysis.
- (VariableInfo.Number): New public field. This is used by flow analysis
- to number all locals of a block.
- (Block.CountVariables): New public property. This is the number of
- local variables in this block (including the locals from all parent
- blocks).
- (Block.EmitMeta): Number all the variables.
-
- * statement.cs: Added flow analysis support to all classes.
-
-2002-07-31 Martin Baulig <martin@gnome.org>
-
- * driver.cs: Added "--mcs-debug" argument if MCS_DEBUG is defined.
- To get debugging messages, compile mcs with /define:MCS_DEBUG and
- then use this argument.
-
- * report.cs (Report.Debug): Renamed to conditional to "MCS_DEBUG".
-
- * makefile.gnu (MCS_FLAGS): Include $(MCS_DEFINES), the user may
- use this to specify /define options.
-
-2002-07-29 Martin Baulig <martin@gnome.org>
-
- * statement.cs (Fixed): Moved all code that does variable lookups
- and resolvings from Emit to Resolve.
-
- * statement.cs (For): Moved all code that does variable lookups
- and resolvings from Emit to Resolve.
-
- * statement.cs (Using): Moved all code that does variable lookups
- and resolvings from Emit to Resolve.
-
-2002-07-29 Martin Baulig <martin@gnome.org>
-
- * attribute.cs (Attribute.Resolve): Explicitly catch a
- System.NullReferenceException when creating the
- CustromAttributeBuilder and report a different warning message.
-
-2002-07-29 Martin Baulig <martin@gnome.org>
-
- * support.cs (ParameterData.ParameterName): Added method to
- get the name of a parameter.
-
- * typemanager.cs (TypeManager.IsValueType): New public method.
-
-2002-07-29 Martin Baulig <martin@gnome.org>
-
- * parameter.cs (Parameter.Modifier): Added `ISBYREF = 8'. This
- is a flag which specifies that it's either ref or out.
- (Parameter.GetParameterInfo (DeclSpace, int, out bool)): Changed
- the out parameter to `out Parameter.Modifier mod', also set the
- Parameter.Modifier.ISBYREF flag on it if it's either ref or out.
-
- * support.cs (InternalParameters.ParameterModifier): Distinguish
- between Parameter.Modifier.OUT and Parameter.Modifier.REF, set the
- Parameter.Modifier.ISBYREF flag if it's either ref or out.
-
- * expression.cs (Argument.GetParameterModifier): Distinguish
- between Parameter.Modifier.OUT and Parameter.Modifier.REF, set the
- Parameter.Modifier.ISBYREF flag if it's either ref or out.
-
-2002-07-29 Martin Baulig <martin@gnome.org>
-
- * expression.cs (ParameterReference.ParameterReference): Added
- `Location loc' argument to the constructor.
-
- * cs-parser.jay: Pass location to ParameterReference.
-
-2002-07-28 Miguel de Icaza <miguel@ximian.com>
-
- * statement.cs (Try): Initialize the location.
-
- * cs-parser.jay: pass location to Try.
-
- * expression.cs (Unary.Reduce): Change the prototype to return
- whether a constant fold could be performed or not. The result is
- returned in an out parameters. In the case of Indirection and
- AddressOf, we want to perform the full tests.
-
-2002-07-26 Miguel de Icaza <miguel@ximian.com>
-
- * statement.cs (Statement.Emit): Flag dead code.
-
-2002-07-27 Andrew Birkett <andy@nobugs.org>
-
- * expression.cs (Unary.Reduce): Handle AddressOf and Indirection.
-
-2002-07-27 Martin Baulig <martin@gnome.org>
-
- * class.cs (MethodData.Define): Put back call to
- TypeManager.AddMethod(), accidentally commented this out.
-
- * report.cs (Debug): New public method to print debugging information,
- this is `[Conditional ("DEBUG")]'.
-
-2002-07-26 Martin Baulig <martin@gnome.org>
-
- * cs-parser.jay (CSharpParser): Added `Stack switch_stack'.
- (switch_statement): Push the current_block to the switch_stack and
- pop it again when we're done with the switch.
- (switch_section): The new block is a child of the current_block.
- Fixes bug #24007, added test-152.cs.
-
-2002-07-27 Martin Baulig <martin@gnome.org>
-
- * expression.cs (Invocation.EmitArguments): When calling a varargs
- function with only its fixed arguments, we need to pass an empty
- array.
-
-2002-07-27 Martin Baulig <martin@gnome.org>
-
- Mono 0.13 has been released.
-
-2002-07-25 Miguel de Icaza <miguel@ximian.com>
-
- * driver.cs: Rename --resource to --linkres, because that is what
- we do currently, we dont support --resource yet.
-
- * cs-tokenizer.cs: Fix test for reporting endif mismatches.
-
-2002-07-25 Martin Baulig <martin@gnome.org>
-
- * class.cs (MethodData): New public class. This is a `method builder'
- class for a method or one accessor of a Property/Indexer/Event.
- (MethodData.GetMethodFlags): Moved here from MemberBase.
- (MethodData.ApplyAttributes): Likewise.
- (MethodData.ApplyObsoleteAttribute): Likewise.
- (MethodData.ApplyConditionalAttribute): Likewise.
- (MethodData.ApplyDllImportAttribute): Likewise.
- (MethodData.CheckAbstractAndExternal): Likewise.
- (MethodData.Define): Formerly knows as MemberBase.DefineMethod().
- (MethodData.Emit): Formerly known as Method.Emit().
- (MemberBase): Moved everything which was specific to a single
- accessor/method to MethodData.
- (Method): Create a new MethodData and call Define() and Emit() on it.
- (Property, Indexer, Event): Create a new MethodData objects for each
- accessor and call Define() and Emit() on them.
-
-2002-07-25 Martin Baulig <martin@gnome.org>
-
- Made MethodCore derive from MemberBase to reuse the code from there.
- MemberBase now also checks for attributes.
-
- * class.cs (MethodCore): Derive from MemberBase, not MemberCore.
- (MemberBase.GetMethodFlags): Moved here from class Method and marked
- as virtual.
- (MemberBase.DefineAccessor): Renamed to DefineMethod(), added
- `CallingConventions cc' and `Attributes opt_attrs' arguments.
- (MemberBase.ApplyAttributes): New virtual method; applies the
- attributes to a method or accessor.
- (MemberBase.ApplyObsoleteAttribute): New protected virtual method.
- (MemberBase.ApplyConditionalAttribute): Likewise.
- (MemberBase.ApplyDllImportAttribute): Likewise.
- (MemberBase.CheckAbstractAndExternal): Likewise.
- (MethodCore.ParameterTypes): This is now a property instead of a
- method, it's initialized from DoDefineParameters().
- (MethodCore.ParameterInfo): Removed the set accessor.
- (MethodCore.DoDefineParameters): New protected virtual method to
- initialize ParameterTypes and ParameterInfo.
- (Method.GetReturnType): We can now simply return the MemberType.
- (Method.GetMethodFlags): Override the MemberBase version and add
- the conditional flags.
- (Method.CheckBase): Moved some code from Define() here, call
- DoDefineParameters() here.
- (Method.Define): Use DoDefine() and DefineMethod() from MemberBase
- here to avoid some larger code duplication.
- (Property.Emit, Indexer.Emit): Call CheckAbstractAndExternal() to
- ensure that abstract and external accessors don't declare a body.
-
- * attribute.cs (Attribute.GetValidPieces): Make this actually work:
- `System.Attribute.GetCustomAttributes (attr.Type)' does a recursive
- lookup in the attribute's parent classes, so we need to abort as soon
- as we found the first match.
- (Attribute.Obsolete_GetObsoleteMessage): Return the empty string if
- the attribute has no arguments.
-
- * typemanager.cs (TypeManager.AddMethod): Now takes a MemberBase instead
- of a Method.
-
-2002-07-24 Gonzalo Paniagua Javier <gonzalo@ximian.com>
-
- * cs-parser.jay: reverted previous patch.
-
-2002-07-24 Gonzalo Paniagua Javier <gonzalo@ximian.com>
-
- * cs-parser.jay: fixed bug #22119.
-
-2002-07-24 Gonzalo Paniagua Javier <gonzalo@ximian.com>
-
- * attribute.cs: fixed compilation. The error was:
- "attribute.cs(571,17): error CS0177: The out parameter 'is_error' must
- be assigned to before control leaves the current method."
- [FIXME: Filed as bug #28186: MCS must report this error.]
-
-2002-07-25 Martin Baulig <martin@gnome.org>
-
- * attribute.cs (Attribute.Conditional_GetConditionName): New static
- method to pull the condition name ouf of a Conditional attribute.
- (Attribute.Obsolete_GetObsoleteMessage): New static method to pull
- the obsolete message and error flag out of an Obsolete attribute.
-
- * class.cs (Method.GetMethodFlags): New public method to get the
- TypeManager.MethodFlags for this method.
- (Method.ApplyConditionalAttribute, Method.ApplyObsoleteAttribute): New
- private methods.
- (Method.Define): Get and apply the Obsolete and Conditional attributes;
- if we're overriding a virtual function, set the new private variable
- `parent_method'; call the new TypeManager.AddMethod().
-
- * typemanager.cs (TypeManager.AddMethod): New static method. Stores
- the MethodBuilder and the Method in a PtrHashtable.
- (TypeManager.builder_to_method): Added for this purpose.
- (TypeManager.MethodFlags): Added IsObsoleteError.
- (TypeManager.GetMethodFlags): Added `Location loc' argument. Lookup
- Obsolete and Conditional arguments in MethodBuilders. If we discover
- an Obsolete attribute, emit an appropriate warning 618 / error 619 with
- the message from the attribute.
-
-2002-07-24 Martin Baulig <martin@gnome.org>
-
- * cs-tokenizer.cs: Eat up trailing whitespaces and one-line comments in
- preprocessor directives, ensure that the argument to #define/#undef is
- exactly one identifier and that it's actually an identifier.
-
- Some weeks ago I did a `#define DEBUG 1' myself and wondered why this
- did not work ....
-
-2002-07-24 Martin Baulig <martin@gnome.org>
-
- * statement.cs (Foreach.ForeachHelperMethods): Added `Type element_type',
- initialize it to TypeManager.object_type in the constructor.
- (Foreach.GetEnumeratorFilter): Set `hm.element_type' to the return type
- of the `hm.get_current' method if we're using the collection pattern.
- (Foreach.EmitCollectionForeach): Use `hm.element_type' as the source type
- for the explicit conversion to make it work when we're using the collection
- pattern and the `Current' property has a different return type than `object'.
- Fixes #27713.
-
-2002-07-24 Martin Baulig <martin@gnome.org>
-
- * delegate.cs (Delegate.VerifyMethod): Simply return null if the method
- does not match, but don't report any errors. This method is called in
- order for all methods in a MethodGroupExpr until a matching method is
- found, so we don't want to bail out if the first method doesn't match.
- (NewDelegate.DoResolve): If none of the methods in the MethodGroupExpr
- matches, report the 123. Fixes #28070.
-
-2002-07-24 Martin Baulig <martin@gnome.org>
-
- * expression.cs (ArrayAccess.EmitStoreOpcode): Moved the
- TypeManager.TypeToCoreType() to the top of the method so the
- following equality checks will work. Fixes #28107.
-
-2002-07-24 Martin Baulig <martin@gnome.org>
-
- * cfold.cs (ConstantFold.DoConstantNumericPromotions): "If either
- operand is of type uint, and the other operand is of type sbyte,
- short or int, the operands are converted to type long." -
- Actually do what this comment already told us. Fixes bug #28106,
- added test-150.cs.
-
-2002-07-24 Martin Baulig <martin@gnome.org>
-
- * class.cs (MethodBase): New abstract class. This is now a base
- class for Property, Indexer and Event to avoid some code duplication
- in their Define() and DefineMethods() methods.
- (MethodBase.DoDefine, MethodBase.DefineAccessor): Provide virtual
- generic methods for Define() and DefineMethods().
- (FieldBase): Derive from MemberBase, not MemberCore.
- (Property): Derive from MemberBase, not MemberCore.
- (Property.DefineMethod): Moved all the code from this method to the
- new MethodBase.DefineAccessor(), just call it with appropriate
- argumetnts.
- (Property.Define): Call the new Property.DoDefine(), this does some
- sanity checks and we don't need to duplicate the code everywhere.
- (Event): Derive from MemberBase, not MemberCore.
- (Event.Define): Use the new MethodBase.DefineAccessor() to define the
- accessors, this will also make them work with interface events.
- (Indexer): Derive from MemberBase, not MemberCore.
- (Indexer.DefineMethod): Removed, call MethodBase.DefineAccessor() insstead.
- (Indexer.Define): Use the new MethodBase functions.
-
- * interface.cs (InterfaceEvent.InterfaceEvent): Added `Location loc'
- argument to the constructor.
- (Interface.FindMembers): Added support for interface events.
- (Interface.PopluateEvent): Implemented.
-
- Added test-149.cs for this. This also fixes bugs #26067 and #24256.
-
-2002-07-22 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (TypeContainer.AddMethod): Adding methods do not use IsValid,
- but this is required to check for a method name being the same as
- the containing class.
-
- Handle this now.
-
-2002-07-22 Gonzalo Paniagua Javier <gonzalo@ximian.com>
-
- * interface.cs: initialize variable.
-
-2002-07-23 Martin Baulig <martin@gnome.org>
-
- Implemented the IndexerName attribute in interfaces.
-
- * class.cs (TypeContainer.DefineIndexers): Don't set the indexer
- name if this is an explicit interface implementation.
- (Indexer.InterfaceIndexerName): New public variable. If we're
- implementing an interface indexer, this is the IndexerName in that
- interface. Otherwise, it's the IndexerName.
- (Indexer.DefineMethod): If we're implementing interface indexer,
- set InterfaceIndexerName. Use the new Pending.IsInterfaceIndexer
- and Pending.ImplementIndexer methods.
- (Indexer.Define): Also define the PropertyBuilder if we're
- implementing an interface indexer and this is neither an explicit
- interface implementation nor do the IndexerName match the one in
- the interface.
-
- * pending.cs (TypeAndMethods): Added `MethodInfo [] need_proxy'.
- If a method is defined here, then we always need to create a proxy
- for it. This is used when implementing interface indexers.
- (Pending.IsInterfaceIndexer): New public method.
- (Pending.ImplementIndexer): New public method.
- (Pending.InterfaceMethod): Added `MethodInfo need_proxy' argument.
- This is used when implementing interface indexers to define a proxy
- if necessary.
- (Pending.VerifyPendingMethods): Look in the `need_proxy' array and
- define a proxy if necessary.
-
- * interface.cs (Interface.IndexerName): New public variable.
- (Interface.PopulateIndexer): Set the IndexerName.
- (Interface.DefineIndexers): New private method. Populate all the
- indexers and make sure their IndexerNames match.
-
- * typemanager.cs (IndexerPropertyName): Added support for interface
- indexers.
-
-2002-07-22 Martin Baulig <martin@gnome.org>
-
- * codegen.cs (EmitContext.HasReturnLabel): New public variable.
- (EmitContext.EmitTopBlock): Always mark the ReturnLabel and emit a
- ret if HasReturnLabel.
- (EmitContext.TryCatchLevel, LoopBeginTryCatchLevel): New public
- variables.
-
- * statement.cs (Do.Emit, While.Emit, For.Emit, Foreach.Emit): Save
- and set the ec.LoopBeginTryCatchLevel.
- (Try.Emit): Increment the ec.TryCatchLevel while emitting the block.
- (Continue.Emit): If the ec.LoopBeginTryCatchLevel is smaller than
- the current ec.TryCatchLevel, the branch goes out of an exception
- block. In this case, we need to use Leave and not Br.
-
-2002-07-22 Martin Baulig <martin@gnome.org>
-
- * statement.cs (Try.Emit): Emit an explicit ret after the end of the
- block unless the block does not always return or it is contained in
- another try { ... } catch { ... } block. Fixes bug #26506.
- Added verify-1.cs to the test suite.
-
-2002-07-22 Martin Baulig <martin@gnome.org>
-
- * statement.cs (Switch.TableSwitchEmit): If we don't have a default,
- then we do not always return. Fixes bug #24985.
-
-2002-07-22 Martin Baulig <martin@gnome.org>
-
- * expression.cs (Invocation.OverloadedResolve): Do the BetterFunction()
- lookup on a per-class level; ie. walk up the class hierarchy until we
- found at least one applicable method, then choose the best among them.
- Fixes bug #24463 and test-29.cs.
-
-2002-07-22 Martin Baulig <martin@gnome.org>
-
- * typemanager.cs (TypeManager.ArrayContainsMethod): Don't check the
- return types of the methods. The return type is not part of the
- signature and we must not check it to make the `new' modifier work.
- Fixes bug #27999, also added test-147.cs.
- (TypeManager.TypeToCoreType): Added TypeManager.type_type.
-
- * expression.cs (Invocation.DoResolve): Call TypeManager.TypeToCoreType()
- on the method's return type.
-
-2002-07-21 Martin Baulig <martin@gnome.org>
-
- * assign.cs: Make this work if the rightmost source is a constant and
- we need to do an implicit type conversion. Also adding a few more tests
- to test-38.cs which should have caught this.
-
- * makefile.gnu: Disable debugging, there's already the mcs-mono2.exe
- target in the makefile for this. The makefile.gnu is primarily intended
- for end-users who don't want to debug the compiler.
-
-2002-07-21 Martin Baulig <martin@gnome.org>
-
- * assign.cs: Improved the Assign class so it can now handle embedded
- assignments (X = Y = Z = something). As a side-effect this'll now also
- consume less local variables. test-38.cs now passes with MCS, added
- a few new test cases to that test.
-
-2002-07-20 Martin Baulig <martin@gnome.org>
-
- * expression.cs (Binary.EmitBranchable): Emit correct unsigned branch
- instructions. Fixes bug #27977, also added test-146.cs.
-
-2002-07-19 Gonzalo Paniagua Javier <gonzalo@ximian.com>
-
- * cs-tokenizer.cs: fixed getHex ().
-
-2002-07-19 Martin Baulig <martin@gnome.org>
-
- * expression.cs (Invocation.EmitParams): Use TypeManager.LookupType(),
- not Type.GetType() to lookup the array type. This is needed when
- we're constructing an array of a user-defined type.
- (ArrayAccess.EmitDynamicInitializers): Only emit the Ldelema for
- single-dimensional arrays, but also for single-dimensial arrays of
- type decimal.
-
-2002-07-19 Martin Baulig <martin@gnome.org>
-
- * expression.cs (New.DoEmit): Create a new LocalTemporary each time
- this function is called, it's not allowed to share LocalBuilders
- among ILGenerators.
-
-2002-07-19 Martin Baulig <martin@gnome.org>
-
- * expression.cs (Argument.Resolve): Report an error 118 when trying
- to pass a type as argument.
-
-2002-07-18 Martin Baulig <martin@gnome.org>
-
- * ecore.cs (Expression.ImplicitNumericConversion): Don't emit a
- Conv_R_Un for the signed `long' type.
-
-2002-07-15 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (MemberAccess.DoResolve): Do not reuse the field
- `expr' for the temporary result, as that will fail if we do
- multiple resolves on the same expression.
-
-2002-07-05 Miguel de Icaza <miguel@ximian.com>
-
- * ecore.cs (SimpleNameResolve): Use ec.DeclSpace instead of
- ec.TypeContainer for looking up aliases.
-
- * class.cs (TypeContainer): Remove LookupAlias from here.
-
- * decl.cs (DeclSpace); Move here.
-
-2002-07-01 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (FindMembers): Only call filter if the constructor
- bulider is not null.
-
- Also handle delegates in `NestedTypes' now. Now we will perform
- type lookups using the standard resolution process. This also
- fixes a bug.
-
- * decl.cs (DeclSpace.ResolveType): New type resolution routine.
- This uses Expressions (the limited kind that can be parsed by the
- tree) instead of strings.
-
- * expression.cs (ComposedCast.ToString): Implement, used to flag
- errors since now we have to render expressions.
-
- (ArrayCreation): Kill FormElementType. Use ComposedCasts in
- FormArrayType.
-
- * ecore.cs (SimpleName.ToString): ditto.
-
- * cs-parser.jay: Instead of using strings to assemble types, use
- Expressions to assemble the type (using SimpleName, ComposedCast,
- MemberAccess). This should fix the type lookups in declarations,
- because we were using a different code path for this.
-
- * statement.cs (Block.Resolve): Continue processing statements
- even when there is an error.
-
-2002-07-17 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (Event.Define): Also remove the `remove' method from
- the list of pending items.
-
- * expression.cs (ParameterReference): Use ldarg.N (0..3) to
- generate more compact code.
-
-2002-07-17 Martin Baulig <martin@gnome.org>
-
- * const.cs (Const.LookupConstantValue): Add support for constant
- `unchecked' and `checked' expressions.
- Also adding test case test-140.cs for this.
-
-2002-07-17 Martin Baulig <martin@gnome.org>
-
- * statement.cs (Foreach.GetEnumeratorFilter): When compiling corlib,
- check whether mi.ReturnType implements the IEnumerator interface; the
- `==' and the IsAssignableFrom() will fail in this situation.
-
-2002-07-16 Ravi Pratap <ravi@ximian.com>
-
- * ecore.cs (SimpleName.SimpleNameResolve) : Apply Gonzalo's fix
- here too.
-
-2002-07-16 Gonzalo Paniagua Javier <gonzalo@ximian.com>
-
- * expression.cs: fixed bug #27811.
-
-2002-07-14 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (ParameterReference.AddressOf): Patch from Paolo
- Molaro: when we are a ref, the value already contains a pointer
- value, do not take the address of it.
-
-2002-07-14 Rafael Teixeira <rafaelteixeirabr@hotmail.com>
- * removed mb-parser.jay and mb-tokenizer.cs
-
-Sat Jul 13 19:38:03 CEST 2002 Paolo Molaro <lupus@ximian.com>
-
- * expression.cs: check against the building corlib void type.
-
-Sat Jul 13 19:35:58 CEST 2002 Paolo Molaro <lupus@ximian.com>
-
- * ecore.cs: fix for valuetype static readonly fields: when
- initializing them, we need their address, not the address of a copy.
-
-Sat Jul 13 17:32:53 CEST 2002 Paolo Molaro <lupus@ximian.com>
-
- * typemanager.cs: register also enum_type in corlib.
-
-Sat Jul 13 15:59:47 CEST 2002 Paolo Molaro <lupus@ximian.com>
-
- * class.cs: allow calling this (but not base) initializers in structs.
-
-Sat Jul 13 15:12:06 CEST 2002 Paolo Molaro <lupus@ximian.com>
-
- * ecore.cs: make sure we compare against the building base types
- in GetTypeSize ().
-
-Sat Jul 13 15:10:32 CEST 2002 Paolo Molaro <lupus@ximian.com>
-
- * typemanager.cs: fix TypeToCoreType() to handle void and object
- (corlib gets no more typerefs after this change).
-
-2002-07-12 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (ArrayCreation.EmitArrayArguments): use
- Conv.Ovf.U4 for unsigned and Conv.Ovf.I4 for signed.
-
- (ArrayAccess.LoadArrayAndArguments): Use Conv_Ovf_I and
- Conv_Ovf_I_Un for the array arguments. Even if C# allows longs as
- array indexes, the runtime actually forbids them.
-
- * ecore.cs (ExpressionToArrayArgument): Move the conversion code
- for array arguments here.
-
- * expression.cs (EmitLoadOpcode): System.Char is a U2, use that
- instead of the default for ValueTypes.
-
- (New.DoEmit): Use IsValueType instead of
- IsSubclassOf (value_type)
- (New.DoResolve): ditto.
- (Invocation.EmitCall): ditto.
-
- * assign.cs (Assign): ditto.
-
- * statement.cs (Unsafe): Ok, so I got the semantics wrong.
- Statements *are* currently doing part of their resolution during
- Emit.
-
- Expressions do always resolve during resolve, but statements are
- only required to propagate resolution to their children.
-
-2002-07-11 Miguel de Icaza <miguel@ximian.com>
-
- * driver.cs (CSCParseOption): Finish the /r: and /lib: support.
-
- (LoadAssembly): Do not add the dll if it is already specified
-
- (MainDriver): Add the System directory to the link path at the end,
- after all the other -L arguments.
-
- * expression.cs (ArrayAccess.EmitLoadOpcode): I was using the
- wrong opcode for loading bytes and bools (ldelem.i1 instead of
- ldelem.u1) and using the opposite for sbytes.
-
- This fixes Digger, and we can finally run it.
-
- * driver.cs (UnixParseOption): Move the option parsing here.
- (CSCParseOption): Implement CSC-like parsing of options.
-
- We now support both modes of operation, the old Unix way, and the
- new CSC-like way. This should help those who wanted to make cross
- platform makefiles.
-
- The only thing broken is that /r:, /reference: and /lib: are not
- implemented, because I want to make those have the same semantics
- as the CSC compiler has, and kill once and for all the confussion
- around this. Will be doing this tomorrow.
-
- * statement.cs (Unsafe.Resolve): The state is checked during
- resolve, not emit, so we have to set the flags for IsUnsfe here.
-
-2002-07-10 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (MemberAccess.ResolveMemberAccess): Since we can
- not catch the Error_ObjectRefRequired in SimpleName (as it is
- possible to have a class/instance variable name that later gets
- deambiguated), we have to check this here.
-
-2002-07-10 Ravi Pratap <ravi@ximian.com>
-
- * class.cs (TypeContainer.GetFieldFromEvent): Move away from here,
- make static and put into Expression.
-
- (Event.Define): Register the private field of the event with the
- TypeManager so that GetFieldFromEvent can get at it.
-
- (TypeManager.RegisterPrivateFieldOfEvent): Implement to
- keep track of the private field associated with an event which
- has no accessors.
-
- (TypeManager.GetPrivateFieldOfEvent): Implement to get at the
- private field.
-
- * ecore.cs (GetFieldFromEvent): RE-write to use the above methods.
-
-2002-07-10 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (Binary.EmitBranchable): this routine emits the
- Binary expression in a branchable context. This basically means:
- we need to branch somewhere, not just get the value on the stack.
-
- This works together with Statement.EmitBoolExpression.
-
- * statement.cs (Statement.EmitBoolExpression): Use
- EmitBranchable.
-
-2002-07-09 Miguel de Icaza <miguel@ximian.com>
-
- * statement.cs (For): Reduce the number of jumps in loops.
-
- (For): Implement loop inversion for the For statement.
-
- (Break): We can be breaking out of a Try/Catch controlled section
- (foreach might have an implicit try/catch clause), so we need to
- use Leave instead of Br.
-
- * ecore.cs (FieldExpr.AddressOf): Fix for test-139 (augmented
- now). If the instace expression supports IMemoryLocation, we use
- the AddressOf method from the IMemoryLocation to extract the
- address instead of emitting the instance.
-
- This showed up with `This', as we were emitting the instance
- always (Emit) instead of the Address of This. Particularly
- interesting when This is a value type, as we dont want the Emit
- effect (which was to load the object).
-
-2002-07-08 Miguel de Icaza <miguel@ximian.com>
-
- * attribute.cs: Pass the entry point to the DefinePInvokeMethod
-
- * statement.cs (Checked): Set the CheckedState during the resolve
- process too, as the ConvCast operations track the checked state on
- the resolve process, and not emit.
-
- * cs-parser.jay (namespace_member_declaration): Flag that we have
- found a declaration when we do. This is used to flag error 1529
-
- * driver.cs: Report ok when we display the help only.
-
-2002-07-06 Andrew Birkett <adb@tardis.ed.ac.uk>
-
- * cs-tokenizer.cs (xtoken): Improve handling of string literals.
-
-2002-07-04 Miguel de Icaza <miguel@ximian.com>
-
- * cs-tokenizer.cs (define): We also have to track locally the
- defines. AllDefines is just used for the Conditional Attribute,
- but we also need the local defines for the current source code.
-
-2002-07-03 Miguel de Icaza <miguel@ximian.com>
-
- * statement.cs (While, For, Do): These loops can exit through a
- Break statement, use this information to tell whether the
- statement is the last piece of code.
-
- (Break): Flag that we break.
-
- * codegen.cs (EmitContexts): New `Breaks' state variable.
-
-2002-07-03 Martin Baulig <martin@gnome.org>
-
- * class.cs (TypeContainer.MethodModifiersValid): Allow override
- modifiers in method declarations in structs. Otherwise, you won't
- be able to override things like Object.Equals().
-
-2002-07-02 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (Method, Property, Indexer): Do not allow the public
- modifier to be used in explicit interface implementations.
-
- (TypeContainer.MethodModifiersValid): Catch virtual, abstract and
- override modifiers in method declarations in structs
-
-2002-07-02 Andrew Birkett <adb@tardis.ed.ac.uk>
-
- * cs-tokenizer.cs (adjust_int, adjust_real): Do not abort on
- integer or real overflow, report an error
-
-2002-07-02 Martin Baulig <martin@gnome.org>
-
- * typemanager.cs (TypeManager.InitCoreTypes): When compiling
- corlib, dynamically call AssemblyBuilder.SetCorlibTypeBuilders()
- to tell the runtime about our newly created System.Object and
- System.ValueType types.
-
-2002-07-02 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (This): Use Stobj/Ldobj when we are a member of a
- struct instead of Ldarg/Starg.
-
-2002-07-02 Martin Baulig <martin@gnome.org>
-
- * expression.cs (Indirection.Indirection): Call
- TypeManager.TypeToCoreType() on `expr.Type.GetElementType ()'.
-
-2002-07-02 Martin Baulig <martin@gnome.org>
-
- * expression.cs (ArrayAccess.EmitStoreOpcode): If the type is a
- ValueType, call TypeManager.TypeToCoreType() on it.
- (Invocations.EmitParams): Call TypeManager.TypeToCoreType() on
- the OpCodes.Newarr argument.
-
-2002-07-02 Martin Baulig <martin@gnome.org>
-
- * expression.cs (Invocation.EmitCall): When compiling corlib,
- replace all calls to the system's System.Array type to calls to
- the newly created one.
-
- * typemanager.cs (TypeManager.InitCodeHelpers): Added a few more
- System.Array methods.
- (TypeManager.InitCoreTypes): When compiling corlib, get the methods
- from the system's System.Array type which must be replaced.
-
-Tue Jul 2 19:05:05 CEST 2002 Paolo Molaro <lupus@ximian.com>
-
- * typemanager.cs: load unverifiable_code_ctor so we can build
- corlib using the correct type. Avoid using GetTypeCode() with
- TypeBuilders.
- * rootcontext.cs: uses TypeManager.unverifiable_code_ctor and
- TypeManager.object_type to allow building corlib.
-
-Tue Jul 2 19:03:19 CEST 2002 Paolo Molaro <lupus@ximian.com>
-
- * ecore.cs: handle System.Enum separately in LoadFromPtr().
-
-2002-07-01 Martin Baulig <martin@gnome.org>
-
- * class.cs: Make the last change actually work, we need to check
- whether `ifaces != null' to avoid a crash.
-
-Mon Jul 1 16:15:03 CEST 2002 Paolo Molaro <lupus@ximian.com>
-
- * class.cs: when we build structs without fields that implement
- interfaces, we need to add the interfaces separately, since there is
- no API to both set the size and add the interfaces at type creation
- time.
-
-Mon Jul 1 14:50:47 CEST 2002 Paolo Molaro <lupus@ximian.com>
-
- * expression.cs: the dimension arguments to the array constructors
- need to be converted if they are a long.
-
-Mon Jul 1 12:26:12 CEST 2002 Paolo Molaro <lupus@ximian.com>
-
- * class.cs: don't emit ldarg.0 if there is no parent constructor
- (fixes showstopper for corlib).
-
-2002-06-29 Martin Baulig <martin@gnome.org>
-
- MCS now compiles corlib on GNU/Linux :-)
-
- * attribute.cs (Attribute.ApplyAttributes): Treat Accessors like Method,
- ie. check for MethodImplOptions.InternalCall.
-
- * class.cs (TypeContainer.DefineType): When compiling corlib, both parent
- and TypeManager.attribute_type are null, so we must explicitly check
- whether parent is not null to find out whether it's an attribute type.
- (Property.Emit): Always call Attribute.ApplyAttributes() on the GetBuilder
- and SetBuilder, not only if the property is neither abstract nor external.
- This is necessary to set the MethodImplOptions on the accessor methods.
- (Indexer.Emit): Call Attribute.ApplyAttributes() on the GetBuilder and
- SetBuilder, see Property.Emit().
-
- * rootcontext.cs (RootContext.PopulateTypes): When compiling corlib, don't
- populate "System.Object", "System.ValueType" and "System.Attribute" since
- they've already been populated from BootCorlib_PopulateCoreTypes().
-
-2002-06-29 Martin Baulig <martin@gnome.org>
-
- * ecore.cs (Expression.ImplicitReferenceConversionExists): If expr
- is the NullLiteral, we also need to make sure that target_type is not
- an enum type.
-
-2002-06-29 Martin Baulig <martin@gnome.org>
-
- * rootcontext.cs (RootContext.ResolveCore): We must initialize
- `TypeManager.multicast_delegate_type' and `TypeManager.delegate_type'
- before calling BootstrapCorlib_ResolveDelegate ().
-
-2002-06-27 Gonzalo Paniagua Javier <gonzalo@ximian.com>
-
- * statement.cs: fixed build-breaker. All tests passed ok.
-
-2002-06-27 Martin Baulig <martin@gnome.org>
-
- * typemanager.cs (TypeManager.VerifyUnManaged): Added explicit check
- for System.Decimal when compiling corlib.
-
-2002-06-27 Martin Baulig <martin@gnome.org>
-
- * statement.cs (Switch.TableSwitchEmit): Make this work with empty
- switch blocks which contain nothing but a default clause.
-
-2002-06-26 Andrew <adb@tardis.ed.ac.uk>
-
- * ../errors/cs1501-3.cs: Added new test for struct ctr typechecks.
-
-2002-06-27 Martin Baulig <martin@gnome.org>
-
- * ecore.cs (PropertyExpr.PropertyExpr): Call
- TypeManager.TypeToCoreType() on the `pi.PropertyType'.
-
- * typemanager.cs (TypeManager.TypeToCoreType): Return if the type
- is already a TypeBuilder.
-
-2002-06-27 Martin Baulig <martin@gnome.org>
-
- * ecore.cs (Expression.ImplicitReferenceConversionExists): Use
- `target_type == TypeManager.array_type', not IsAssignableFrom() in
- the "from an array-type to System.Array" case. This makes it work
- when compiling corlib.
-
-2002-06-27 Martin Baulig <martin@gnome.org>
-
- * ecore.cs (Expression.SimpleNameResolve): If the expression is a
- non-static PropertyExpr, set its InstanceExpression. This makes
- the `ICollection.Count' property work in System/Array.cs.
-
-2002-06-25 Andrew Birkett <adb@tardis.ed.ac.uk>
-
- * driver.cs: Made error handling more consistent. Errors now
- tracked by Report class, so many methods which used to return int
- now return void. Main() now prints success/failure and
- errors/warnings message.
-
- Renamed '--probe' compiler argument to '--expect-error'. Removed
- the magic number return values (123 and 124). Now, if the
- expected error occurs, the compiler exits with success (exit value
- 0). If the compilation completes without seeing that particular
- error, the compiler exits with failure (exit value 1). The
- makefile in mcs/errors has been changed to handle the new behaviour.
-
- * report.cs: Made 'expected error' number a property and renamed
- it from 'Probe' to 'ExpectedError'.
-
- * genericparser.cs: Removed error handling support, since it is
- now all done by Report class.
-
- * cs-parser.jay, mb-parser.jay: Errors are tracked by Report
- class, so parse() no longer returns an int.
-
- * namespace.cs: Use Report.Error instead of GenericParser.error
-
-2002-06-22 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (TypeContainer.AddMethod, TypeContainer.AddIndexer,
- TypeContainer.AddOperator): At the front of the list put the
- explicit implementations, so they get resolved/defined first.
-
-2002-06-21 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (TypeContainer.VerifyImplements): Verifies that a given
- interface type is implemented by this TypeContainer. Used during
- explicit interface implementation.
-
- (Property.Define, Indexer.Define, Method.Define): Validate that
- the given interface in the explicit implementation is one of the
- base classes for the containing type.
-
- Also if we are explicitly implementing an interface, but there is
- no match in the pending implementation table, report an error.
-
- (Property.Define): Only define the property if we are
- not explicitly implementing a property from an interface. Use the
- correct name also for those properties (the same CSC uses,
- although that is really not needed).
-
- (Property.Emit): Do not emit attributes for explicitly implemented
- properties, as there is no TypeBuilder.
-
- (Indexer.Emit): ditto.
-
- Hiding then means that we do not really *implement* a pending
- implementation, which makes code fail.
-
-2002-06-22 Martin Baulig <martin@gnome.org>
-
- * ecore.cs (Expression.Constantify): Call TypeManager.TypeToCoreType() on
- the return value of Object.GetType(). [FIXME: we need to do this whenever
- we get a type back from the reflection library].
-
-Fri Jun 21 13:37:57 CEST 2002 Paolo Molaro <lupus@ximian.com>
-
- * typemanager.cs: make ExpandInterfaces() slip duplicated interfaces.
-
-2002-06-20 Miguel de Icaza <miguel@ximian.com>
-
- * attribute.cs: Return null if we can not look up the type.
-
- * class.cs (TypeContainer.GetClassBases): Use ExpandInterfaces on
- the interface types found.
-
- * interface.cs (Interface.GetInterfaceBases): Use ExpandInterfaces on the
- interface types found.
-
- * typemanager.cs (GetInterfaces): Make this routine returns alll
- the interfaces and work around the lame differences between
- System.Type and System.Reflection.Emit.TypeBuilder in the results
- result for GetInterfaces.
-
- (ExpandInterfaces): Given an array of interface types, expand and
- eliminate repeated ocurrences of an interface. This expands in
- context like: IA; IB : IA; IC : IA, IB; the interface "IC" to
- be IA, IB, IC.
-
-2002-06-21 Martin Baulig <martin@gnome.org>
-
- * typemanager.cs (TypeManager.EnumToUnderlying): It's now safe to call this function
- on System.Enum.
-
-2002-06-21 Martin Baulig <martin@gnome.org>
-
- * typemanager.cs (TypeManager.TypeToCoreType): New function. When compiling corlib
- and called with one of the core types, return the corresponding typebuilder for
- that type.
-
- * expression.cs (ArrayAccess.DoResolve): Call TypeManager.TypeToCoreType() on the
- element type.
-
-2002-06-21 Martin Baulig <martin@gnome.org>
-
- * ecore.cs (Expression.ExplicitReferenceConversionExists): Use
- `target_type.IsArray' instead of `target_type.IsSubclassOf (TypeManager.array_type)'.
- (Expression.ConvertReferenceExplicit): Likewise.
-
- * expression.cs (ElementAccess.DoResolve): Likewise.
- (ElementAccess.DoResolveLValue): Likewise.
-
-2002-06-10 Martin Baulig <martin@gnome.org>
-
- * interface.cs (Interface.PopulateIndexer): When creating the setter, we need to
- add the "value" parameter to the parameter list.
-
- * statement.cs (Fixed.Emit): Pass the return value of the child block's Emit()
- to our caller.
-
-2002-06-19 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (ArrayCreation.ExpressionToArrayArgument): Convert
- the argument to an int, uint, long or ulong, per the spec. Also
- catch negative constants in array creation.
-
-Thu Jun 20 17:56:48 CEST 2002 Paolo Molaro <lupus@ximian.com>
-
- * class.cs: do not allow the same interface to appear twice in
- the definition list.
-
-Wed Jun 19 22:33:37 CEST 2002 Paolo Molaro <lupus@ximian.com>
-
- * ecore.cs: don't use ldlen with System.Array.
-
-Wed Jun 19 20:57:40 CEST 2002 Paolo Molaro <lupus@ximian.com>
-
- * ecore.cs: stobj requires a type argument. Handle indirect stores on enums.
-
-Wed Jun 19 20:17:59 CEST 2002 Paolo Molaro <lupus@ximian.com>
-
- * modifiers.cs: produce correct field attributes for protected
- internal. Easy fix so miguel can work on ther harder stuff:-)
-
-2002-06-18 Miguel de Icaza <miguel@ximian.com>
-
- * pending.cs: New file. Move the code from class.cs here.
- Support clearning the pending flag for all methods (when not doing
- explicit interface implementation).
-
-Tue Jun 18 10:36:22 CEST 2002 Paolo Molaro <lupus@ximian.com>
-
- * rootcontext.cs: added a couple more types needed to bootstrap.
-
-2002-06-17 Miguel de Icaza <miguel@ximian.com>
-
- * typemanager.cs (GetConstructor): Use DeclaredOnly to look the
- constructor in the type, instead of any constructor in the type
- hierarchy. Thanks to Paolo for finding this bug (it showed up as
- a bug in the Mono runtime when applying the params attribute).
-
-2002-06-16 Rafael Teixeira <rafaelteixeirabr@hotmail.com>
- * changed namespace.cs to use "GenericParser.error(...)" instead of "CSharpParser.error(...)"
-
-2002-06-14 Rachel Hestilow <hestilow@ximian.com>
-
- * expression.cs (Unary.ResolveOperator): Use TypeManager
- to resolve the type.
-
-2002-06-13 Ravi Pratap <ravi@ximian.com>
-
- * cs-parser.jay (enum_member_declaration): Pass in the attributes
- attached.
-
- * enum.cs (AddEnumMember): Add support to store the attributes associated
- with each member too.
-
- * attribute.cs (CheckAttribute, ApplyAttributes): Update to handle
- field builders too - this takes care of the enum member case.
-
-2002-06-10 Rachel Hestilow <hestilow@ximian.com>
-
- * typemanager.cs (TypeManager.VerifyUnManaged): Allow
- address-of operator on both value types and pointers.
-
-2002-06-10 Martin Baulig <martin@gnome.org>
-
- * interface.cs (Interface.PopulateIndexer): Add the indexer's
- PropertyBuilder to the `property_builders' list.
-
- * expression.cs (Indexers.GetIndexersForTypeOrInterface): New private method.
- (Indexers.GetIndexersForType): Call GetIndexersForTypeOrInterface() on the
- `lookup_type' and all its interfaces. Unfortunately, Type.FindMembers() won't
- find any indexers which are inherited from an interface.
-
-2002-06-09 Martin Baulig <martin@gnome.org>
-
- * const.cs (Const.LookupConstantValue): Convert `Expr' to a literal of
- the same type as the constant if necessary. There's also a test-130.cs
- for this.
-
- * enum.cs (Enum.ChangeEnumType): Moved to typemanager.cs and made public.
-
- * typemanager.cs (TypeManager.ChangeType): Previously known as
- Enum.ChangeEnumType().
-
-2002-06-09 Martin Baulig <martin@gnome.org>
-
- * expression.cs (Cast.TryReduce): Added support for consts.
-
-2002-06-08 Ravi Pratap <ravi@ximian.com>
-
- * class.cs (Accessor): Hold attributes information so we can pass
- it along.
-
- * cs-parser.jay (get_accessor_declaration, set_accessor_declaration):
- Modify to pass in attributes attached to the methods.
-
- (add_accessor_declaration, remove_accessor_declaration): Ditto.
-
- * attribute.cs (ApplyAttributes, CheckAttribute): Update accordingly
- to handle the Accessor kind :-)
-
- * class.cs (Property.Emit, Event.Emit): Apply attributes to the accessors
-
-2002-06-08 Martin Baulig <martin@gnome.org>
-
- * expression.cs (Unary.TryReduceNegative): Added support for
- ULongConstants.
-
-2002-06-08 Martin Baulig <martin@gnome.org>
-
- * enum.cs (Enum.LookupEnumValue): Don't report an error if the
- name can't be found in the `defined_names' - the caller will do a
- MemberLookup in this case and thus find methods in System.Enum
- such as Enum.IsDefined().
-
-2002-06-08 Martin Baulig <martin@gnome.org>
-
- * enum.cs (Enum.ChangeEnumType): This is a custom version of
- Convert.ChangeType() which works with TypeBuilder created types.
- (Enum.LookupEnumValue, Enum.Define): Use it here.
-
- * class.cs (TypeContainer.RegisterRequiredImplementations): Added
- `TypeBuilder.BaseType != null' check.
- (TypeContainer.FindMembers): Only lookup parent members if we
- actually have a parent.
- (Method.EmitDestructor): Added `ec.ContainerType.BaseType != null' check.
- (ConstructorInitializer.Resolve): Likewise.
-
- * interface.cs (Interface.FindMembers): Added
- `TypeBuilder.BaseType != null' check.
-
- * rootcontext.cs (RootContext.ResolveCore): Added
- "System.Runtime.CompilerServices.IndexerNameAttribute" to
- classes_second_stage.
-
- * typemanager.cs (TypeManager.InitCoreTypes): Don't initialize
- debug_type and trace_type when compiling with --nostdlib.
-
-2002-06-07 Martin Baulig <martin@gnome.org>
-
- * class.cs (TypeContainer): Added `have_nonstatic_fields' field.
- (AddField): Set it to true when adding a non-static field.
- (DefineType): Use `have_nonstatic_fields' to find out whether we
- have non-static fields, not `Fields != null'.
-
-2002-06-02 Miguel de Icaza <miguel@ximian.com>
-
- * ecore.cs (SimpleNameResolve): Removed simple bug (we were
- dereferencing a null on the static-field code path)
-
-2002-05-30 Martin Baulig <martin@gnome.org>
-
- * codegen.cs (InitMonoSymbolWriter): Added `string[] args' argument
- to take command line arguments. Use reflection to call the new
- custom `Initialize' function on the symbol writer and pass it the
- command line arguments.
-
- * driver.cs (--debug-args): New command line argument to pass command
- line arguments to the symbol writer.
-
-2002-05-28 Miguel de Icaza <miguel@ximian.com>
-
- * assign.cs (DoResolve): Forgot to do the implicit conversion to
- the target type for indexers and properties. Thanks to Joe for
- catching this.
-
-2002-05-27 Miguel de Icaza <miguel@ximian.com>
-
- * typemanager.cs (MethodFlags): returns the method flags
- (Obsolete/ShouldIgnore) that control warning emission and whether
- the invocation should be made, or ignored.
-
- * expression.cs (Invocation.Emit): Remove previous hack, we should
- not do this on matching a base type, we should do this based on an attribute
-
- Only emit calls to System.Diagnostics.Debug and
- System.Diagnostics.Trace if the TRACE and DEBUG defines are passed
- on the command line.
-
- * rootcontext.cs: Global settings for tracing and debugging.
-
- * cs-tokenizer.cs (define): New utility function to track
- defines. Set the global settings for TRACE and DEBUG if found.
-
-2002-05-25 Ravi Pratap <ravi@ximian.com>
-
- * interface.cs (Populate*): Pass in the TypeContainer as well as
- the DeclSpace as parameters so that we can create EmitContexts and
- then use that to apply attributes etc.
-
- (PopulateMethod, PopulateEvent, PopulateProperty)
- (PopulateIndexer): Apply attributes everywhere.
-
- * attribute.cs (CheckAttribute): Include InterfaceMethod, InterfaceEvent
- etc.
-
- (ApplyAttributes): Update accordingly.
-
- We now apply interface attributes for all members too.
-
-2002-05-26 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (Indexer.Define); Correctly check if we are explicit
- implementation (instead of checking the Name for a ".", we
- directly look up if the InterfaceType was specified).
-
- Delay the creation of the PropertyBuilder.
-
- Only create the PropertyBuilder if we are not an explicit
- interface implementation. This means that explicit interface
- implementation members do not participate in regular function
- lookups, and hence fixes another major ambiguity problem in
- overload resolution (that was the visible effect).
-
- (DefineMethod): Return whether we are doing an interface
- implementation.
-
- * typemanager.cs: Temporary hack until we get attributes in
- interfaces (Ravi is working on that) and we get IndexerName
- support in interfaces.
-
- * interface.cs: Register the indexers as properties.
-
- * attribute.cs (Attribute.Resolve): Catch the error, and emit a
- warning, I have verified that this is a bug in the .NET runtime
- (JavaScript suffers of the same problem).
-
- * typemanager.cs (MemberLookup): When looking up members for
- interfaces, the parent of an interface is the implicit
- System.Object (so we succeed in searches of Object methods in an
- interface method invocation. Example: IEnumerable x; x.ToString
- ())
-
-2002-05-25 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (Event): Events should also register if they do
- implement the methods that an interface requires.
-
- * typemanager.cs (MemberLookup); use the new GetInterfaces
- method.
-
- (GetInterfaces): The code used to lookup interfaces for a type is
- used in more than one place, factor it here.
-
- * driver.cs: Track the errors at the bottom of the file, we kept
- on going.
-
- * delegate.cs (NewDelegate.Emit): We have to emit a null as the
- instance if the method we are calling is static!
-
-2002-05-24 Miguel de Icaza <miguel@ximian.com>
-
- * attribute.cs (ApplyAttributes): Make this function filter out
- the IndexerName attribute (as that attribute in reality is never
- applied) and return the string constant for the IndexerName
- attribute.
-
- * class.cs (TypeContainer.Emit): Validate that all the indexers
- have the same IndexerName attribute, and if so, set the
- DefaultName attribute on the class.
-
- * typemanager.cs: The return value might contain other stuff (not
- only methods). For instance, consider a method with an "Item"
- property and an Item method.
-
- * class.cs: If there is a problem with the parameter types,
- return.
-
-2002-05-24 Ravi Pratap <ravi@ximian.com>
-
- * ecore.cs (ImplicitConversionExists): Wrapper function which also
- looks at user defined conversion after making a call to
- StandardConversionExists - we need this for overload resolution.
-
- * expression.cs : Update accordingly the various method calls.
-
- This fixes 2 bugs filed against implicit user defined conversions
-
-2002-05-22 Miguel de Icaza <miguel@ximian.com>
-
- * statement.cs: Track the result of the assignment.
-
-2002-05-21 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (MemberAccess): Improved error reporting for
- inaccessible members.
-
-2002-05-22 Martin Baulig <martin@gnome.org>
-
- * makefile (mcs-mono2.exe): New target. This is mcs compiled with
- itself with debugging support.
-
-2002-05-22 Martin Baulig <martin@gnome.org>
-
- * typemanager.cs ("System.Runtime.InteropServices.StructLayoutAttribute"):
- Removed, this isn't needed anymore.
-
-2002-05-20 Martin Baulig <martin@gnome.org>
-
- * typemanager.cs (InitEnumUnderlyingTypes): "System.Char" can't
- be underlying type for an enum.
-
-2002-05-20 Miguel de Icaza <miguel@ximian.com>
-
- * typemanager.cs (InitEnumUnderlyingTypes): New helper function
- that splits out the loading of just the core types.
-
- * rootcontext.cs (ResolveCore): Split the struct resolution in
- two, so we can load the enumeration underlying types before any
- enums are used.
-
- * expression.cs (Is): Bandaid until we fix properly Switch (see
- bug #24985 for details).
-
- * typemanager.cs (ImplementsInterface): The hashtable will contain
- a null if there are no interfaces implemented.
-
-2002-05-18 Miguel de Icaza <miguel@ximian.com>
-
- * cs-parser.jay (indexer_declarator): It is fine to have array
- parameters
-
-2002-05-17 Miguel de Icaza <miguel@ximian.com>
-
- * typemanager.cs: (RegisterBuilder): New function used to register
- TypeBuilders that implement interfaces. Since
- TypeBuilder.GetInterfaces (as usual) does not work with lame
- Reflection.Emit.
- (AddUserType): register interfaces.
-
- (ImplementsInterface): Use the builder_to_ifaces hash if we are
- dealing with TypeBuilder. Also, arrays are showing up as
- SymbolTypes, which are not TypeBuilders, but whose GetInterfaces
- methods can not be invoked on them!
-
- * ecore.cs (ExplicitReferenceConversionExists): Made public.
- (ImplicitReferenceConversionExists): Split out from
- StandardConversionExists.
-
- * expression.cs (As): We were only implementing one of the three
- cases for the as operator. We now implement them all.
- (Is): Implement the various other cases for Is as well.
-
- * typemanager.cs (CACHE): New define used to control if we want or
- not the FindMembers cache. Seems to have a negative impact on
- performance currently
-
- (MemberLookup): Nested types have full acess to
- enclosing type members
-
- Remove code that coped with instance/static returns for events, we
- now catch this in RealFindMembers.
-
- (RealFindMembers): only perform static lookup if the instance
- lookup did not return a type or an event.
-
-2002-05-17 Miguel de Icaza <miguel@ximian.com>
-
- * assign.cs (CompoundAssign): We pass more semantic information
- now to Compound Assignments than we did before: now we have all
- the information at hand, and now we resolve the target *before* we
- do the expression expansion, which allows the "CacheValue" method
- to have the effect we intended (before, a [x] += 1 would generate
- two differen ArrayAccess expressions from the ElementAccess,
- during the resolution process).
-
- (CompoundAssign.DoResolve): Resolve target and original_source here.
-
-2002-05-16 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (ArrayAccess): dropped debugging information.
-
- * typemanager.cs: Small bug fix: I was always returning i_members,
- instead of one of i_members or s_members (depending on which had
- the content).
-
- * assign.cs (IAssignMethod.CacheTemporaries): New method. This
- method is invoked before any code generation takes place, and it
- is a mechanism to inform that the expression will be invoked more
- than once, and that the method should use temporary values to
- avoid having side effects
-
- (Assign.Emit): Call CacheTemporaries in the IAssignMethod.
-
- * ecore.cs (Expression.CacheTemporaries): Provide empty default
- implementation.
-
- * expression.cs (Indirection, ArrayAccess): Add support for
- CacheTemporaries in these two bad boys.
-
- * ecore.cs (LoadFromPtr): figure out on our own if we need to use
- ldobj or ldind_ref.
- (StoreFromPtr): Handle stobj as well.
-
- * expression.cs (UnaryMutator): Share more code.
-
- * typemanager.cs (FindMembers): Thanks to Paolo for tracking this
- down: I was not tracking the Filter function as well, which
- was affecting the results of the cache.
-
-2002-05-15 Miguel de Icaza <miguel@ximian.com>
-
- * attribute.cs: Remove the hack to handle the CharSet property on
- StructLayouts.
-
-2002-05-14 Miguel de Icaza <miguel@ximian.com>
-
- * attribute.cs (DoResolve): More uglyness, we now only try to
- resolve the attribute partially, to extract the CharSet
- information (only if we are a StructLayout attribute). Otherwise
-
- (GetExtraTypeInfo): Add some code to conditionally kill in the
- future this. I am more and more convinced that the .NET
- framework has special code to handle the attribute setting on
- certain elements.
-
- * expression.cs (IsParamsMethodApplicable): Revert my previous
- foreach change here, it was wrong.
-
-2002-05-13 Miguel de Icaza <miguel@ximian.com>
-
- * cs-tokenizer.cs: (pp_primary): Eat the ')' at the end.
- (pp_expr): do not abort on unknown input, just return.
- (eval): abort if there are pending chars.
-
- * attribute.cs (Attribute.Resolve): Positional parameters are
- optional. Deal with that case.
-
- * class.cs (DefineType): Call Attribute.GetExtraTypeInfo to fetch
- the Ansi/Unicode/Auto information for the type.
-
- (TypeContainer.DefineType): instantiate the EmitContext here, as
- we will be using it during the type definition (to resolve
- attributes) and during the emit phase.
-
- * attribute.cs (Attribute.GetExtraTypeInfo): This routine is used
- to pull type information out of the attributes
-
- (Attribute.Resolve): track the constructor builder, and allow for
- multiple invocations (structs and classes will use this).
-
- * ecore.cs (MemberLookupFinal): new version with all the
- parameters customizable.
-
- * expression.cs (New.DoResolve): Use MemberLookupFinal to locate
- constructors. Return if the result value is null (as the error
- would have been flagged already by MemberLookupFinal)
-
- Do not allow instances of abstract classes or interfaces to be
- created.
-
- * class.cs: (MethodSignature.InheritableMemberSignatureCompare):
- We have to compare the assembly property here when dealing with
- FamANDAssem and Assembly access modifiers, because we might be
- creating an assembly from *modules* (that means that we are not
- getting TypeBuilders for types defined in other modules that are
- part of this assembly).
-
- (Method.Emit): If the method is marked abstract and has a body,
- emit an error.
-
- (TypeContainer.DefineMembers): If both the defined member and the
- parent name match are methods, then do not emit any warnings: let
- the Method.Define routine take care of flagging warnings. But if
- there is a mismatch (method overrides something else, or method is
- overriwritten by something, then emit warning).
-
- (MethodSignature.MemberSignatureCompare): If the sig.ret_type is
- set to null, this means `do not check for the return type on the
- signature'.
-
- (Method.Define): set the return type for the method signature to
- null, so that we get methods with the same name and parameters and
- different return types. This is used to flag warning 114 (you are
- hiding a method, and you probably want to use the new/override
- keywords instead).
-
- * typemanager.cs (MemberLookup): Implemented proper access
- control, closing a long standing set of bug reports. The problem
- was that the Framework only has two bits: Public and NonPublic,
- and NonPublic includes private and protected methods, but we need
- to enforce the FamANDAssem, FamOrAssem and Family.
-
-2002-05-11 Miguel de Icaza <miguel@ximian.com>
-
- * statement.cs (GotoCase): Return true: Ammounts to giving up
- knowledge on whether we return or not, and letting the other case
- be responsible for it.
-
-2002-05-10 Miguel de Icaza <miguel@ximian.com>
-
- * driver.cs: Do not load directories for each file processed, only
- do it if there is a pattern.
-
- * ecore.cs: Report readonly assigns here as well, as we might have
- been resolved only by MemberAccess.
-
- (SimpleName.SimpleNameResolve): Also be useful for LValue
- resolution. We need this to propagate assign to local readonly variables
-
- * typemanager.cs: Use a ptrhashtable for the criteria, because we
- do not want to reuse potential criteria memory.
-
- * class.cs (MyEventBuilder): Set reflected_type;
-
- * ecore.cs (Constantify): Added support for constifying bools.
-
- (RootContext.LookupType): Added a cache for values looked up in
- the declaration space.
-
- * typemanager.cs (FindMembers): Now is a front-end to
- RealFindMembers, and provides a two-level hashtable-based cache to
- the request.
-
- 15% performance improvement: from 22.5 to 19.2 seconds.
-
- * expression.cs (IsParamsMethodApplicable): use foreach.
- (Invocation.DoResolve): ditto.
- (New.DoResolve): ditto.
- (ArrayCreation.DoResolve): ditto.
-
- * ecore.cs (FindMostEncompassingType): use foreach.
-
- * delegate.cs (NewDelegate.DoResolve): Use foreach
-
- * ecore.cs (Expression.FindMostSpecificSource): Use foreach.
- (RemoveMethods): use foreach.
-
- * expression.cs (Invocation.MakeUnionSet): Optimization: Use two
- nested foreach statements instead of for, and also break out of
- the inner loop once a match is found.
-
- (Invocation.OverloadResolve): Use foreach, simplify the code.
-
-2002-05-08 Miguel de Icaza <miguel@ximian.com>
-
- * cfold.cs (BinaryFold): During an enumeration evaluation context,
- we actually unwrap the expression to allow for extra information
- to be extracted.
-
- * expression.cs: Use Shr_Un on unsigned operations.
-
-2002-05-08 Ravi Pratap <ravi@ximian.com>
-
- * ecore.cs (FindMostEncompass*): Fix trivial bug where the set of
- applicable operators was not being considered correctly. This closes
- the bug Miguel reported.
-
-Wed May 8 16:40:50 CEST 2002 Paolo Molaro <lupus@ximian.com>
-
- * attribute.cs: check that the type derives from System.Attribute
- and report the correct error in that case (moved the duplicate code to
- its own method, too).
-
-Wed May 8 11:50:31 CEST 2002 Paolo Molaro <lupus@ximian.com>
-
- * attribute.cs: lookup attribute type name as the spec says: first the
- bare attribute name and then name + "Attribute" (nant compiles with
- mcs after this fix).
-
-2002-05-07 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (Unary.TryReduceNegative): Ah! Tricky! Tricky!
- Because of the way we parse things, we should try to see if a
- UIntConstant can fit in an integer.
-
-2002-05-07 Ravi Pratap <ravi@ximian.com>
-
- * ecore.cs (GetConversionOperators): Do not pick up op_True operators
- when we are in an explicit context.
-
- (ConvertReferenceExplicit): When converting from Iface type S to Class
- T make sure the rules are implemented as an OR.
-
- * parameter.cs (ParameterType): Make it a property for now although the
- purpose really isn't anything immediate.
-
- * expression.cs (Is*Applicable): Do better checking on the parameter type
- of a ref/out parameter. The ones from the system assemblies are already
- marked with the correct type so we don't need to do any correction.
-
- * ecore.cs (StandardConversionExists): Conversion from Interface types to
- the object type is standard too so include that.
-
-2002-05-06 Miguel de Icaza <miguel@ximian.com>
-
- * ecore.cs (StandardConversionExists): Augment with missing code:
- deal with IntConstant, LongConstants and Enumerations.
-
- * assign.cs: Report the error, instead of failing silently
-
- * rootcontext.cs (AddGlobalAttributes): Track attributes on the
- typecontainer that they are declared, because the
- typecontainer/namespace will have the list of using clauses that
- need to be applied.
-
- Assembly Attributes were escaping the normal registration
- mechanism.
-
- (EmitCode): Apply attributes within an EmitContext that represents
- the container they were declared on.
-
- * cs-parser.jay: Track bases for structs. How did I get this wrong?
-
-2002-05-06 Ravi Pratap <ravi@ximian.com>
-
- * ecore.cs (FindMostEncompassingType, FindMostEncompassedType):
- Revamp completely - make much cleaner as we now operate only
- on a set of Types.
-
- (FindMostSpecificSource, FindMostSpecificTarget): New methods
- to implement the logic detailed in the spec more correctly.
-
- (UserDefinedConversion): Update accordingly.
-
-2002-05-06 Miguel de Icaza <miguel@ximian.com>
-
- * statement.cs: Return flow analysis information up.
-
- * cs-tokenizer.cs (adjust_real): Share code between LITERAL_DOUBLE
- and the default.
-
- (token): Do not consume an extra character before calling
- decimal_digits.
-
-2002-05-06 Piers Haken <piersh@friskit.com>
-
- * cs-parser.jay: add 'override' attribute to System.Object.Finalize
-
-2002-05-06 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (Constructor.Emit): Set the IsStatic flag in the
- EmitContext during the instance constructor initializer
- resolution, to stop access to instance variables.
-
- This is mandated by the spec, last paragraph of the `constructor
- initializers' section.
-
-2002-05-05 Miguel de Icaza <miguel@ximian.com>
-
- * cs-parser.jay, class.cs (Accessor): new class used to represent
- an accessor (get or set). In the past we used `null' to represent
- a missing accessor. But this is ambiguous because there was no
- way to tell in abstract indexers/properties if one of them was
- specified.
-
- Now there is a way of addressing that.
-
- * expression.cs (Indexers.GetIndexersForType): Use TypeManager.MemberLookup
- instead of FindMembers.
-
- * class.cs (TypeContainer.EmitFieldInitializer): Do not typecast
- the result of Assign.Resolve as Assign, but rather as ExpressionStatement.
-
- * attribute.cs: Treat indexers and properties as the same in terms
- of applying attributes
-
- * ecore.cs (FindMostEncompassedType): Use statically initialized
- EmptyExpressions()s like we do elsewhere to avoid creating useless
- objects (and we take this out of the tight loop).
-
- (GetConversionOperators): Move the code to extract the actual
- operators to a separate routine to clean things up.
-
-2002-05-04 Miguel de Icaza <miguel@ximian.com>
-
- * ecore.cs (FieldExpr): Remove un-needed tests for null, since now
- events are always registered FieldBuilders.
-
- * class.cs (FieldBase): New class shared by Fields
-
- * delegate.cs: If we are a toplevel delegate, use our full name.
- If we are a nested delegate, then only use our tail name.
-
-2002-05-02 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (IsApplicable): Ensure that we add the "&" to
- ref/out types before comparing it with the type of the argument.
-
- (IsParamsMethodApplicable): Ditto.
-
- (Argument.Type): Use TypeManager.LookupType instead of Type.GetType -
- silly me ;-)
-
- * delegate.cs : Handle the case when we have more than one applicable
- method. Flag an error only when we finish checking all.
-
-2002-05-02 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs: Add support for boolean static initializers.
-
-2002-05-01 Miguel de Icaza <miguel@ximian.com>
-
- * attribute.cs: Use proper cast for Events, since we use a MyEventBuilder.
-
- * parameter.cs (ComputeParameterTypes,
- ComputeAndDefineParameterTypes): Better error handling: now we
- clear the `types' cache if we fail during any of the type lookups.
- We also return the status code correctly to our caller
-
- * delegate.cs: If we fail to define a delegate, abort the extra
- steps.
-
- * expression.cs (Binary.ResolveOperator): for
- operator==(object,object) and operator !=(object, object) we also
- have to verify that there is an implicit conversion from one to
- the other.
-
- (ArrayAccess.DoResolve): Array Access can operate on
- non-variables.
-
-2002-04-30 Miguel de Icaza <miguel@ximian.com>
-
- * assign.cs (CompoundAssign): A new class used as a "flag" that
- the assignment actually is happening as part of a compound
- assignment operator.
-
- During compound assignment, a few new rules exist to enable things
- like:
-
- byte b |= 1 + 2
-
- From the spec:
-
- x op= y can be evaluated as x = (T) (x op y) (ie, an explicit cast
- to the type of x) if y is implicitly convertible to the type of x,
- and the operator is a builtin operator and the return type of the
- operator is explicitly convertible to the type of x.
-
- * rootcontext.cs: Reset warning level to 2. 4 catches various
- "interesting" features in mcs, we must clean this up at some
- point, but currently am trying to kill other bugs ;-)
-
- * ecore.cs (SimpleName.SimpleNameResolve): Perform member lookups
- in container classes as well.
-
- * expression.cs (Binary.ResolveOperator): Handle string case
- before anything else (as operator overloading does emit an error
- before doing anything else).
-
- This code could go away when we move to a table driven model, but
- i could not come up with a good plan last night.
-
-2002-04-30 Lawrence Pit <loz@cable.a2000.nl>
-
- * typemanager.cs (CSharpName): reimplementation using regex.
- * class.cs: added null check for fields in Emit
- * rootcontext.cs: set warninglevel to 4
-
-2002-04-29 Miguel de Icaza <miguel@ximian.com>
-
- * typemanager.cs (CSharpName): reimplemented with Lupus
- suggestion.
-
-2002-04-28 Miguel de Icaza <miguel@ximian.com>
-
- * statement.cs (If): correclty implement Resolve, because we were
- not catching sem errors in there. The same process is needed
- everywhere else.
- (Return, StatementExpression, For, While, Do, Throw, Lock): Implement Resolve
-
-
- (Statement.Warning_DeadCodeFound): Factorize code.
- (While): Report dead code here too.
-
- (Statement): Added Resolve virtual method to allow
- for resolution split from the emit code.
-
-2002-04-26 Miguel de Icaza <miguel@ximian.com>
-
- * statement.cs (EmitBoolExpression): No longer try to resolve the
- expression here.
- (MakeBoolean): New utility function that resolve, implicitly
- converts to boolean and tags the expression.
-
-
- (If, Do): Implement dead code elimination.
- (While): Implement loop inversion
-
- (Do, While, For, If): Resolve the expression prior to calling our
- code generation.
-
-2002-04-22 Lawrence Pit <loz@cable.a2000.nl>
-
- * class.cs:
- - added method Report28 (warning: program has more than one entry point)
- - added method IsEntryPoint, implements paragraph 10.1 of the spec
- - modified method Method.Define, the part at the end of the method
-
- * rootcontext.cs: added static public Location EntryPointLocation;
-
- * ../errors/cs0028.cs : Add test case for the above warning.
-
- * typemanager.cs:
- - modified method CSharpName to allow arrays of primitive type to
- be printed nicely (e.g. instead of System.Int32[][] it now prints
- int[][])
- - added method CSharpSignature: returns the signature of a method
- in string format to be used in reporting errors, warnings, etc.
-
- * support.cs: InternalParameters.ParameterDesc variable tmp initialized
- with String.Empty.
-
-2002-04-26 Ravi Pratap <ravi@ximian.com>
-
- * delegate.cs (Define): Fix extremely silly bug where I was
- setting the type of the 'object' parameter of the BeginInvoke
- method to System.IAsyncResult instead of System.Object ;-)
-
-2002-04-26 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (ConstructorInitializer.Resolve): Also use DeclaredOnly
- here.
-
- (Constructor.Emit): return if we fail to initialize the
- constructor. Another door closed!
-
- * expression.cs (New.DoResolve): Improve error message (from -6 to
- 1501). Use DeclaredOnly lookup to find the exact constructor.
-
- * typemanager.cs (MemberLookup): If DeclaredOnly is set, do not
- loop. This is useful.
-
- * cs-parser.jay: Adjust the default parameters so that destructors
- have the proper signature.
-
-2002-04-26 Martin Baulig <martin@gnome.org>
-
- * driver.cs (LoadAssembly): If `assembly' contains any characters
- which are only valid in path names and not in assembly names
- (currently slash, backslash and point), use Assembly.LoadFrom ()
- instead of Assembly.Load () on the `assembly' (before iteration
- over the link_paths).
-
-2002-04-26 Martin Baulig <martin@gnome.org>
-
- * cs-tokenizer.cs (is_hex): Correctly handle lowercase chars.
-
-2002-04-25 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (Property): use the new typemanager.MemberLookup
-
- (TypeContainer.MemberLookup): Implement using the
- TypeManager.MemberLookup now.
-
- * typemanager.cs: Make MemberLookup a function of the TypeManager,
- and return MemberInfos, so that these can be used without an
- EmitContext (what we had before).
-
-2002-04-24 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs: Fix the case where the argument to params if the
- type of the params. I omitted handling this before. Fixed
-
-2002-04-22 Miguel de Icaza <miguel@ximian.com>
-
- * driver.cs: Call BootCorlib_PopulateCoreType
-
- * class.cs (Property.CheckBase): Check for properties only, not
- for all members.
-
- * interface.cs: Temporary hack: try/catch around the
- CustomAttributeBuilder, because I am getting an exception that I
- do not understand.
-
- * rootcontext.cs (BootCorlib_PopulateCoreType): Populate some
- types whose definitions are required to be there (attributes are
- defined before standard types).
-
- Compute definitions as we boot the various types, as they are used
- immediately (value_type class will need object_type, but if we do
- not initialize object_type, we will pass a null, which will let
- the runtime pick the System.Object from the existing corlib, which
- is not what we want).
-
-2002-04-22 Patrik Torstensson <totte@labs2.com>
-
- * cs-tokenizer.cs: fixed a number of trim() issues.
-
-2002-04-22 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (Argument.Type): Ensure that we return the correct
- type when we have out or ref parameters [in which case we
- append a "&"].
-
-2002-04-22 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (Property, Indexer): Allow extern modifier in there.
-
- * typemanager.cs (InitBaseTypes): Initializes object_type and
- value_type, since those will be used early on during the bootstrap
- process to compile corlib.
-
- (InitCoreTypes): Move code from here to InitBaseTypes.
-
-2002-04-21 Miguel de Icaza <miguel@ximian.com>
-
- * ecore.cs (PropertyExpr): Optimize calls to Array::get_Length on
- single-dimension arrays as using the ldlen opcode.
-
- Daniel Lewis discovered this optimization.
-
- * typemanager.cs: Add signature for System.Array::get_Length
-
-2002-04-20 Gonzalo Paniagua Javier <gonzalo@ximian.com>
-
- * statement.cs: report the error when the foreach does not apply to an
- array nor a collection.
-
-2002-04-19 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs: Add implicit conversions to the operator ~.
-
- * constant.cs (DecimalConstant.Emit): Emit decimal value.
-
- * typemanager.cs: Locate the decimal constructor.
-
-2002-04-17 Gonzalo Paniagua Javier <gonzalo@ximian.com>
-
- * attribute.cs: use the new property of TypeOf.
- * expression.cs: added 'get' property around typearg.
-
- These changes fix a build breaker reported by NickD. Is this the
- correct way to fix? If not, please, revert my changes and make it
- work :-).
-
-2002-04-17 Miguel de Icaza <miguel@ximian.com>
-
- * attribute.cs: Add support for typeof in attribute invocations.
- I am not sure that this is right though.
-
-2002-04-14 Duncan Mak <duncan@ximian.com>
-
- * cfold.cs (BinaryFold): Catch DivideByZeroException in the
- Binary.Operator.Division case.
-
-2002-04-13 Ravi Pratap <ravi@ximian.com>
-
- * class.cs (DefineType): Ensure that we do a proper check on
- attribute types and also register it with the TypeManager.
-
- (TypeContainer.Targets): The default for attribute types is
- AttributeTargets.All.
-
- * attribute.cs (ApplyAttributes): Registering the attribute type
- is done elsewhere, not when we discover we have a Usage attribute.
-
-2002-04-12 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (VerifyArgumentsCompat): Implement Miguel's suggestion
- and get rid of is_delegate parameter.
-
- * everywhere : update.
-
-2002-04-12 Ravi Pratap <ravi@ximian.com>
-
- * cs-parser.jay (compilation_unit): Revamp completely to use
- some new ideas that I got from Rhys' grammar to solve the problems
- with assembly level attributes.
-
- (outer_declaration): New grammar production.
-
- (attribute_sections): Add.
-
- (opt_attributes): Base on attribute_sections
-
- (namespace_declaration): Allow opt_attributes to tackle the case
- when we have assembly level attributes - we are clever in this
- regard now ;-)
-
- * attribute.cs (ApplyAttributes): Do not worry about assembly
- attributes in the non-global context.
-
- * rootcontext.cs (AddGlobalAttributes): Go back to using this
- instead of SetGlobalAttributes.
-
- * class.cs, rootcontext.cs : Ensure we define and generate
- attribute types before anything else.
-
- * attribute.cs (CheckAttribute and GetValidPlaces): Handle the exception
- and flag the new error -20 for the case when the attribute type
- does not have valid targets specified. csc does not catch this.
-
- * ../errors/errors.txt : update for error # -20
-
-2002-04-11 Ravi Pratap <ravi@ximian.com>
-
- * support.cs (InternalParameters.ParameterModifier): Do some null
- checking and return sane values.
-
- * class.cs (Method.Define): If we are a PInvoke method, ensure
- that we are static and extern. Report error # 601
-
- * ../errors/cs0601.cs : Add test case for the above error.
-
-2002-04-07 Ravi Pratap <ravi@ximian.com>
-
- * rootcontext.cs (attribute_types): We need to keep type of
- all attribute types separately and emit code for them first.
-
- (RegisterAttribute) : Implement.
-
- * class.cs (DefineType): Check if the current Type is a custom
- attribute type and register it accordingly.
-
- * rootcontext.cs (AddGlobalAttributes): Fix silly bug where we were
- adding the first attribute twice and rename to
-
- (SetGlobalAttributes): this.
-
- * rootcontext.cs (NamespaceLookup): Run through the aliases too and perform
- lookups.
-
- * attribute.cs (ApplyAttributes): Take an additional argument telling us
- if we are processing global arguments. Hmm, I am unsure of this.
-
-2002-04-12 Gonzalo Paniagua Javier <gonzalo@ximian.com>
-
- * expression.cs: added static array of strings to avoid calling
- Enum.ToString () for Operator in Binary. Significant recover of
- performance.
-
-2002-04-10 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (FindMembers): Allow the Builders of the various
- members to be null. If they are skip them. This only happens
- during the PInvoke declaration.
-
-2002-04-09 Miguel de Icaza <miguel@ximian.com>
-
- * parameter.cs (Parameters.ComputeParameterTypes): Flag the
- failure, so we do not keep going afterwards.
-
- * expression.cs: (Invocation.OverloadResolve): I believe Ravi
- wanted to pass `false' as the `is_delegate' argument. If this is
- the case, why not use delegate_type == null to mean `is_delegate =
- false' and anything else as is_delegate = true.
-
-Tue Apr 9 05:40:12 2002 Piers Haken <piersh@friskit.com>
-
- * statement.cs: fixed SimpleSwitchEmit to make 'goto case' goto the
- code for the section, not the beginning of the tests.
-
-2002-04-08 Miguel de Icaza <miguel@ximian.com>
-
- * cfold.cs: Handle operator + (Enum x, Underlying x)
-
- * expression.cs (Binary): same. Warn about errors where we have
- Enum/Enum in operator + as well.
-
-Mon Apr 8 06:29:03 2002 Piers Haken <piersh@friskit.com>
-
- * statement.cs:
- - added support for switch(bool)
- - optimize loading of I8/U8 constants (ldc.i4, iconv_i8)
- - add TableSwitchEmit() to handle table-based switch statements
-
-2002-04-05 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (Invocation.OverloadResolve): Factor out code which
- does parameter compatibility checking with arguments so that we can
- re-use the code even from Delegate.VerifyApplicability
-
- (VerifyArgumentsCompat): Move above code here.
-
- * delegate.cs (VerifyApplicability): Get rid of duplicate code
- and instead make a call to the above method.
-
-2002-03-31 Ravi Pratap <ravi@ximian.com>
-
- * typemanager.cs (attribute_type): Corresponds to System.Attribute.
- We use it to keep track of classes which are attribute types.
-
-2002-04-02 Miguel de Icaza <miguel@ximian.com>
-
- * delegate.cs (Delegate.Define): Correctly define the types in the
- presence of fixed and array parameters.
-
- * class.cs (TypeContainers.FindMembers): Use NonPublic flag while
- doing FindMembers.
-
- * ecore.cs (Expression.MemberLookup): Reset binding flags to not
- include NonPublic after the first iteration.
-
- * class.cs (Indexer.CheckBase): Only check if both parents are
- non-null.
-
- * cs-parser.jay (accessor_body): If empty, set to null.
-
- * ecore.cs (SimpleName.SimpleNameResolve): We did not have the
- same code path here to resolve constants names that we did have in
- MemberAccess.DoResolve. There is too much code duplicated here.
-
-2002-04-01 Miguel de Icaza <miguel@ximian.com>
-
- * statement.cs, makefile: Drop Statementcollection and just use ArrayLists
-
- * ecore.cs: Optimize UserDefinedConversion by minimizing the calls
- to MakeUnionSet.
-
- * cs-tokenizer.cs: Reuse a single StringBuilder for assembling
- tokens, numbers and strings.
-
- * ecore.cs (MethodGroupExpr): Make Emit warn about missing
- parenthesis.
-
- * delegate.cs: Use ComputeAndDefineParameterTypes for both the
- asyncronous parameters and the regular parameters.
-
- * codegen.cs (CodeGen.Init): Use the constructor that allows us to
- specify the target directory.
-
- * expression.cs: (This.DoResolve): Simplify
- (As.Emit): Optimize, do not generate IsInst if the expression is
- always of the given type.
-
- (Is.DoResolve): Bug fix, we were reporting both always/never for
- the is expression.
-
- * (Invocation.MakeUnionSet): Simplify vastly and optimize, we were
- creating too many unnecessary arrays.
-
-2002-03-31 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (EmitFieldInitializer): Use Assign expression to assign
- fields instead of rolling our own initializer. Takes care of all
- implicit conversions, and drops unnecessary static checks/argument.
-
-2002-03-31 Dick Porter <dick@ximian.com>
-
- * driver.cs: use the GetDirectories() return values properly, and
- use "/" as path separator.
-
-2002-03-30 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (Unary): Optimize - - expr into expr.
- (Binary): Optimize a + (-b) into a -b.
-
- * codegen.cs (CodeGen): Made all methods static.
-
-2002-03-29 Miguel de Icaza <miguel@ximian.com>
-
- * rootcontext.cs:
-
- * decl.cs: Rename `definition' into `TypeBuilder' and drop the
- TypeBuilder property.
-
- * cs-parser.jay: Drop the use of RecordXXX and use RecordDecl
- instead.
-
- * tree.cs: Removed the various RecordXXXX, and replaced with a
- single RecordDecl. Removed all the accessor methods, and just
- left a single access point Type
-
- * enum.cs: Rename DefineEnum to DefineType.
-
- * decl.cs: New abstract method `DefineType' used to unify the
- Defines for Enumerations, Interfaces, TypeContainers and
- Delegates.
-
- (FindType): Moved LookupInterfaceOrClass here. Moved the
- LookupBaseClasses method that used to live in class.cs and
- interface.cs here, and renamed to FindType.
-
- * delegate.cs: Implement DefineType. Take advantage of the
- refactored pattern for locating the parent builder without taking
- the parent_builder argument (which we know does not work if we are
- nested, and triggering a toplevel definition).
-
-2002-03-28 Miguel de Icaza <miguel@ximian.com>
-
- * decl.cs (MemberCore.CheckMethodAgainstBase): Test if the
- accessibility of a member has changed during override and report
- an error if so.
-
- * class.cs (Method.Define, Property.Define): Only complain on
- overrides if the method is private, any other accessibility is
- fine (and since we just checked the permission is the same, we are
- good to go).
-
- * cs-tokenizer.cs: only line, region, endregion, if, endif, else
- and elif are processed always. The other pre-processing
- directives are only processed if we are "taking" the path
-
-2002-03-29 Martin Baulig <martin@gnome.org>
-
- * class.cs (Method.Emit): Only emit symbolic debugging info if the
- current location is not Null.
-
- * codegen.cs (CodeGen.SaveSymbols): Split out symbol writing code into
- a separate method so we can profile it.
-
- * driver.cs (ShowTime): We need to use `(int) span.TotalSeconds' since
- `span.Seconds' are just seconds, but no minutes or hours.
- (MainDriver): Profile the CodeGen.SaveSymbols calls.
-
-2002-03-28 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (Method.Define), (Property.Define), (Indexer.Define):
- Remove the gratuitous set of Final:
-
- // If an interface implementation, then we can set Final.
- if (((flags & MethodAttributes.Abstract) == 0) &&
- implementing.DeclaringType.IsInterface)
- flags |= MethodAttributes.Final;
-
- I do not know what I was smoking when I used that.
-
-
- * cs-parser.jay, delegate.cs: Make Delegate be a DeclSpace, first
- step into fixing the name resolution issues for delegates and
- unifying the toplevel name resolution.
-
-2002-03-28 Martin Baulig <martin@gnome.org>
-
- * class.cs (Method.Emit): If we have a symbol writer, call its
- OpenMethod(), CloseMethod() and SetMethodSourceRange() methods to
- tell it about the current method.
-
- * codegen.cs (EmitContext.Mark): New public method. Tell the symbol
- writer that we're going to emit the first byte of IL code for a new
- statement (a new source line).
- (EmitContext.EmitTopBlock): If we have a symbol writer, call
- EmitContext.Mark() before emitting any code.
-
- * location.cs (SymbolDocument): Return null when we're Null.
-
- * statement.cs (Statement): Moved the `Location loc' variable here.
- (Statement.EmitBoolExpression): If we have a symbol writer, call
- ec.Mark() before emitting any code to tell it that we're at the
- beginning of a new statement.
- (StatementExpression): Added `Location' argument to the constructor.
- (Block): Added public readonly variable `StartLocation' and public
- variable `EndLocation'. The latter is to be set using SetEndLocation().
- (Block): Added constructor which takes a start and end location.
- (Block.SetEndLocation): New method. This sets the end location.
- (Block.EmitMeta): If we have a symbol writer, tell it the names of the
- local variables we create.
- (Block.Emit): If we have a symbol writer, call ec.Mark() before emitting
- each statement and do also mark the begin and end of the block.
-
- * cs-parser.jay (block : OPEN_BRACE): Use the new `Block' constructor to
- tell it the current lexer.Location, use Location.Null for the end of the
- block.
- (block : OPEN_BRACE opt_statement_list CLOSE_BRACE): When closing the
- current block, set its end location using SetEndLocation().
- (statement_expression): StatementExpression constructor now takes the
- lexer.Location as additional argument.
- (for_statement, declare_local_variables): Likewise.
- (declare_local_variables): When creating a new implicit block, use the
- new Block constructor and pass it the lexer.Location.
-
-2002-03-28 Miguel de Icaza <miguel@ximian.com>
-
- * ecore.cs (Expression.MemberLookup): On interfaces, lookup
- members also on the parent interfaces recursively.
-
-2002-03-27 Miguel de Icaza <miguel@ximian.com>
-
- * report.cs: Use new formats, since Gonzalo finished the missing
- bits.
-
- * expression.cs (Binary.ResolveOperator): added missing operator|
- operator& and operator^ for bool/bool.
-
- * cs-parser.jay: CheckDef now takes a Location argument that is
- used to report errors more precisly (instead of reporting the end
- of a definition, we try to track something which is a lot closer
- to the source of the problem).
-
- * cs-tokenizer.cs: Track global token use, so we can properly flag
- the use of #define/#undef after the first token has been seen.
-
- Also, rename the reportXXXX to Error_DescriptiveName
-
- * decl.cs (DeclSpace.IsTopLevel): Move property here from
- TypeContainer, so that Enum and Interface can use this too.
-
- * class.cs (TypeContainer.LookupInterfaceOrClass,
- GetInterfaceOrClass, GetClassBases, DefineType): Drop the
- `builder' argument. Typically this was used to pass the parent
- builder (a ModuleBuilder or a TypeBuilder from whoever triggered
- the definition).
-
- The problem is that a nested class could trigger the definition of
- a toplevel class, and the builder would be obviously wrong in that
- case.
-
- So we drop this argument, and we compute dynamically the
- TypeBuilder/ModuleBuilder (the correct information was available
- to us anyways from DeclSpace.Parent)
-
- * interface.cs (Interface.DefineInterface): Drop builder
- parameter cleanup like class.cs
-
- * enum.cs (Enum.DefineEnum): Drop builder parameter. Clean up
- like class.cs
-
- * statement.cs (Switch.EmitObjectInteger): Emit short/ushort
- values.
-
- (Try.Emit): Propagate the returns value from the statement.
-
- (Return.Emit): Even if we are leavning
-
- * driver.cs: Catch IOExpcetion for Directory.GetFiles as well.
-
- * modifiers.cs: Fix the computation of MethodAttributes flags.
-
-Tue Mar 26 21:14:36 CET 2002 Paolo Molaro <lupus@ximian.com>
-
- * driver.cs: allow compilation of files that start with '/'.
- Add a default case when checking the argument of --target.
-
-2002-03-25 Miguel de Icaza <miguel@ximian.com>
-
- * interface.cs: Implement the same search algorithm for types in
- the interface code.
-
- * delegate.cs: Do not allow multiple definition.
-
- * Recovered ChangeLog that got accidentally amputated
-
- * interface.cs (Interface.DefineInterface): Prevent from double definitions.
-
- * rootcontext.cs: Load manually enum to allow core classes to
- contain enumerations.
-
- * enum.cs, ecore.cs, driver.cs, attribute.cs, class.cs, expression.cs:
- Update to new static methods in TypeManager.
-
- * typemanager.cs (GetMethod, GetConstructor): Use our
- implementation of FindMembers to find the members, since during
- corlib compilation, the types are TypeBuilders and GetMethod and
- GetConstructor do not work.
-
- Make all methods in TypeManager static.
-
- (InitCodeHelpers): Split the functionality from
- the InitCodeTypes function.
-
- * driver.cs: Call InitCodeHelpers after we have populated the
- types.
-
- * cs-parser.jay (delegate_declaration): we did not used to compute
- the delegate name correctly for void delegates.
-
-2002-03-24 Miguel de Icaza <miguel@ximian.com>
-
- * rootcontext.cs (RootContext): Init the interface_resolve_order
- and type_container_resolve_order always.
-
- (ResolveCore, BootstrapCorlib_ResolveClass,
- BootstrapCorlib_ResolveStruct): New functions to bootstrap the
- compiler when compiling with --nostdlib
-
- * class.cs (TypeContainer.DefineType): Check that our parent is
- not null. This test is most important when we are bootstraping
- the core types.
-
- * codegen.cs: Split out the symbol writing code.
-
-2002-03-25 Martin Baulig <martin@gnome.org>
-
- * driver.cs (-g): Made -g an alias for --debug.
-
-2002-03-24 Martin Baulig <martin@gnome.org>
-
- * codegen.cs (SymbolWriter): New public variable. Returns the
- current symbol writer.
- (CodeGen): Added `bool want_debugging_support' argument to the
- constructor. If true, tell the ModuleBuild that we want debugging
- support and ask it for the ISymbolWriter.
- (Save): If we have a symbol writer, call it's Close() method after
- saving the assembly.
-
- * driver.c (--debug): New command line argument to create a
- debugger information file.
-
- * location.cs (SymbolDocument): New public property. Returns an
- ISymbolDocumentWriter object for the current source file or null
- if we don't have a symbol writer.
-
-2002-03-21 Miguel de Icaza <miguel@ximian.com>
-
- * driver.cs (LoadAssembly): Correctly return when all the paths
- have been tried and not before.
-
- * statement.cs (Switch.Emit): return the actual coverage for this
- statement (returns/not-returns)
-
- (Switch.SimpleSwitchEmit): Do not generate jumps to the end of the
- switch of the statement if we are the last switch section. That
- kills two problems: try/catch problems (we used to emit an empty
- nop at the end) and switch statements where all branches would
- return.
-
-2002-03-19 Miguel de Icaza <miguel@ximian.com>
-
- * driver.cs: Add default assemblies (the equivalent to the
- Microsoft CSC.RSP file)
-
- * cs-tokenizer.cs: When updating `cols and setting it to zero,
- also update tokens_seen and set it to false.
-
- * driver.cs: Implement --recurse for Mike.
-
- * driver.cs (SplitPathAndPattern): Small bug fix, I was not
- correctly splitting out the paths.
-
-2002-03-18 Miguel de Icaza <miguel@ximian.com>
-
- * interface.cs (Interface.PopulateProperty): Instead of using
- `parent' as the declaration space for the set parameters, use
- `this'
-
- * support.cs (InternalParameters): InternalParameters constructor
- takes a DeclSpace instead of a TypeContainer.
-
- * expression.cs (ArrayCreation.EmitDynamicInitializers): If value
- types are being initialized, load the address of it before calling
- the function.
-
- (New): Provide a mechanism to disable the generation of local
- value type temporaries when the caller will be providing us with
- an address to store it.
-
- (ArrayCreation.EmitDynamicInitializers): Use it.
-
-2002-03-17 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (Invocation.EmitArguments): Only probe for array
- property if there is more than one argument. Sorry about that.
-
- * class.cs (Invocation.EmitArguments): Fix to emit arguments for
- empty param arrays.
-
- * class.cs (Method.LabelParameters): Fix incorrect code path that
- prevented the `ParamArrayAttribute' from being applied to the
- params attribute.
-
-2002-03-16 Miguel de Icaza <miguel@ximian.com>
-
- * support.cs (ReflectionParameters): Correctly compute whether the
- last argument is a params array. Fixes the problem with
- string.Split ('a')
-
- * typemanager.cs: Make the assemblies array always be non-null
- (empty, but non-null)
-
- * tree.cs (RecordDecl): New function that abstracts the recording
- of names. This reports error 101, and provides a pointer to the
- previous declaration. Fixes a crash in the compiler.
-
- * cs-parser.jay (constructor_declaration): Update to new grammar,
- and provide a constructor_body that can be empty.
-
-2002-03-15 Miguel de Icaza <miguel@ximian.com>
-
- * driver.cs: Add support for --resources.
-
- * expression.cs: (FetchGetMethod, FetchAddressMethod, EmitAssign):
- Make all types for the various array helper methods be integer.
-
- * ecore.cs (Expression.ConvertNumericExplicit): Pass the
- CheckState to ConvCast.
-
- (ConvCast): Now it takes a `checked' state argument, to avoid
- depending on the emit context for the conversion, and just using
- the resolve time setting.
-
- * expression.cs (ArrayCreation.EmitArrayArguments): New function,
- instead of Invocation.EmitArguments. We do not emit the original
- arguments, instead we emit those which have been converted to
- unsigned int expressions.
-
- * statement.cs (Block.EmitMeta): Drop tracking of indexes.
-
- * codegen.cs: ditto.
-
- * expression.cs (LocalVariableReference): Drop the use of the
- Store function that depended on the variable index.
-
- * statement.cs (VariableInfo): Drop the `Idx' property from this
- class, as this is not taking into account the indexes for
- temporaries tat we generate during the execution, getting the
- indexes wrong.
-
- * class.cs: First emit class initializers, then call the parent
- constructor.
-
- * expression.cs (Binary): Fix opcode emision.
- (UnaryMutator.EmitCode): Support checked code generation
-
- * ecore.cs (MemberLookup): TypeManager.FindMembers will return
- matches for events for both the Static and Instance scans,
- pointing to the same element. Fix that.
-
-2002-03-14 Miguel de Icaza <miguel@ximian.com>
-
- * rootcontext.cs (ResolveTree): Always set the
- interface_resolve_order, because nested interfaces will be calling
- into us.
-
- * class.cs (GetInterfaceOrClass): Track the same resolution
- process used by TypeManager.LookupType. This fixes the nested
- type lookups in class declarations (separate path from
- LookupType).
-
- (TypeContainer.DefineType): Also define nested interfaces.
- (TypeContainer.RegisterOrder): New public function used to
- register the order in which child interfaces need to be closed.
-
- Nested interfaces need to be closed after their parents have been
- created.
-
- * interface.cs (InterfaceAttr): Put all the logic for computing
- the interface attribute here.
-
- (DefineInterface): Register our interface order with the
- RootContext or with the TypeContainer depending on the case.
-
-2002-03-12 Miguel de Icaza <miguel@ximian.com>
-
- * cs-parser.jay: rework foreach statement to work with the new
- changes to the policy on SimpleNames.
-
- * report.cs: support Stacktrace on warnings as well.
-
- * makefile: drop --unsafe and /unsafe from the compile.
-
-2002-03-13 Ravi Pratap <ravi@ximian.com>
-
- * ecore.cs (StandardConversionExists): Modify to take an Expression
- as the first parameter. Ensure we do null -> reference type conversion
- checking.
-
- * Everywhere : update calls accordingly, making use of MyEmptyExpr to store
- temporary Expression objects.
-
-Wed Mar 13 12:32:40 CET 2002 Paolo Molaro <lupus@ximian.com>
-
- * interface.cs: workaround bug in method overloading resolution
- (there is already a bugzilla bug for it).
-
-2002-03-12 Miguel de Icaza <miguel@ximian.com>
-
- We could also solve this problem by having a separate path for
- performing type lookups, instead of DoResolve, we could have a
- ResolveType entry point, and only participating pieces of the
- production (simplename, deref, array) would implement this.
-
- * codegen.cs (EmitContext): New field OnlyLookupTypes used to
- signal SimpleName to only resolve type names and not attempt to
- resolve anything else.
-
- * expression.cs (Cast): Set the flag.
-
- * ecore.cs (SimpleName): Use the OnlyLookupTypes flag
-
- * class.cs: Only report 108 if there is no `new' modifier.
-
- * cs-parser.jay: rework foreach statement to work with the new
- changes to the policy on SimpleNames.
-
- * report.cs: support Stacktrace on warnings as well.
-
- * makefile: drop --unsafe and /unsafe from the compile.
-
-2002-03-11 Miguel de Icaza <miguel@ximian.com>
-
- * ecore.cs (SimpleName.SimpleNameResolve): Perform local variable
- lookups here, instead of doing that at parse time. This means
- that our grammar will not introduce `LocalVariableReferences' as
- expressions at this point. That solves the problem of code like
- this:
-
- class X {
- static void Main ()
- { int X = 1;
- { X x = null }}}
-
- This is only half the fix. The full fix requires parameters to
- also be handled in this way.
-
- * Everywhere: Use ec.DeclSpace on calls to LookupType, as this
- makes the use more obvious of the DeclSpace. The
- ec.TypeContainer.TypeBuilder is now only used to pull the
- TypeBuilder for it.
-
- My theory is that I can get rid of the TypeBuilder completely from
- the EmitContext, and have typecasts where it is used (from
- DeclSpace to where it matters).
-
- The only pending problem is that the code that implements Aliases
- is on TypeContainer, and probably should go in DeclSpace.
-
- * ecore.cs (SimpleName.SimpleNameResolve): Perform local variable
- lookups here, instead of doing that at parse time. This means
- that our grammar will not introduce `LocalVariableReferences' as
- expressions at this point. That solves the problem of code like
- this:
-
- class X {
- static void Main ()
- { int X = 1;
- { X x = null }}}
-
- This is only half the fix. The full fix requires parameters to
- also be handled in this way.
-
- * class.cs (Property.DefineMethod): When implementing an interface
- method, set newslot, when implementing an abstract method, do not
- set the flag (before we tried never setting it, or always setting
- it, which is the difference).
- (Indexer.DefineMethod): same.
- (Method.DefineMethod): same.
-
- * ecore.cs: Only set the status used flag if we get back a Field.
-
- * attribute.cs: Temporary hack, so Paolo can keep working.
-
-2002-03-08 Ravi Pratap <ravi@ximian.com>
-
- * attribute.cs (Attribute.UnmanagedType): This is to keep track of
- the unmanaged type in the case we have a MarshalAs attribute.
-
- (Resolve): Handle the case when we are parsing the special MarshalAs
- attribute [we need to store the unmanaged type to use later]
-
- * typemanager.cs (marshal_as_attr_type): Built in type for the
- MarshalAs Attribute.
-
- * attribute.cs (ApplyAttributes): Recognize the MarshalAs attribute
- on parameters and accordingly set the marshalling info.
-
-2002-03-09 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs: Optimizing slightly by removing redundant code after
- we switched to the `NoTypes' return value.
- (Property.DefineMethod): use NoTypes here too.
-
- This fixes the bug I introduced in my last batch of changes.
-
-2002-03-05 Ravi Pratap <ravi@ximian.com>
-
- * tree.cs (RecordEnum): Add. We now keep track of enums too.
-
- * class.cs (LookupInterfaceOrClass): Check against the list of recorded
- Enums since those are types too.
-
- * cs-parser.jay (enum_declaration): Record enums as we parse them.
-
- * enum.cs (DefineEnum): Return if the TypeBuilder has already been defined
- thanks to a call during the lookup process.
-
-2002-03-07 Miguel de Icaza <miguel@ximian.com>
-
- * statement.cs (Foreach): Lots of work to accomodate a particular
- kind of foreach statement that I had not kept in mind. It is
- possible to have foreachs on classes that provide a GetEnumerator
- method that return objects that implement the "pattern" for using
- a foreach, there is no need to support GetEnumerator
- specifically.
-
- This is needed to compile nant.
-
- * decl.cs: Only report 114 if the member is not `Finalize' and if
- the warning level is at least 2.
-
- * class.cs: Moved the compare function from Method to
- MethodSignature.
-
- (MethodSignature.InheritableMemberSignatureCompare): Add new
- filter function that is used to extract inheritable methods from a
- class.
-
- (Method.Define): Use the new `inheritable_method_signature_filter'
- delegate
-
- * cs-tokenizer.cs (get_cmd_arg): Do not add white space to the
- command.
-
-2002-03-06 Miguel de Icaza <miguel@ximian.com>
-
- * ecore.cs (Expression.ConvertReferenceExplicit): Removed dead code.
-
- * cs-parser.jay: Add opt_semicolon to the interface declaration.
-
- * expression.cs: Pass location information to
- ConvertImplicitStandard.
-
- * class.cs: Added debugging code to track return values from
- interfaces.
-
-2002-03-05 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (Is.DoResolve): If either side of the `is' is an
- interface, do not flag the warning.
-
- * ecore.cs (ImplicitReferenceConversion): We need a separate test
- for interfaces
-
- * report.cs: Allow for --fatal to be used with --probe.
-
- * typemanager.cs (NoTypes): Move the definition for the empty Type
- array here.
-
- * class.cs (TypeContainer.FindMembers): Also look for methods defined by
- properties.
- (TypeContainer.DefineProxy): New function used to proxy to parent
- implementations when implementing interfaces.
- (TypeContainer.ParentImplements): used to lookup if our parent
- implements a public function that is required by an interface.
- (TypeContainer.VerifyPendingMethods): Hook this up.
-
- * typemanager.cs (TypeManager, AddModule, AddAssembly): Make the
- `modules' and `assemblies' arraylists into arrays. We only grow
- these are the very early start up of the program, so this improves
- the speedof LookupType (nicely measured).
-
- * expression.cs (MakeByteBlob): Replaced unsafe code with
- BitConverter, as suggested by Paolo.
-
- * cfold.cs (ConstantFold.Binary): Special case: perform constant
- folding of string concatenation, but if either side is a string,
- and the other is not, then return null, and let the runtime use
- the concatenation on the string plus the object (using
- `Object.ToString').
-
-2002-03-04 Miguel de Icaza <miguel@ximian.com>
-
- Constant Folding has been implemented now.
-
- * expression.cs (Unary.Reduce): Do not throw an exception, catch
- the error instead on types that are not supported in one's
- complement.
-
- * constant.cs (Constant and all children): New set of functions to
- perform implict and explicit conversions.
-
- * ecore.cs (EnumConstant): Implement the new functions to perform
- conversion by proxying to the child expression.
-
- * codegen.cs: (ConstantCheckState): Constant evaluation has its
- own separate setting that can not be turned off from the command
- line using --unchecked or --checked and is only controlled using
- the checked/unchecked statements and expressions. This setting is
- used by the constant folder to flag errors.
-
- * expression.cs (CheckedExpr, UncheckedExpr): Set the
- ConstantCheckState as well.
-
- During Resolve, they also have to flag the state, because the
- constant folder runs completely in the Resolve phase.
-
- * statement.cs (Checked, Unchecked): Set the ConstantCheckState as
- well.
-
-2002-03-01 Miguel de Icaza <miguel@ximian.com>
-
- * cfold.cs: New file, this file contains the constant folder.
-
- * ecore.cs (IMemoryLocation.AddressOf): Now takes an extra
- argument to track whether we are using the resulting address to
- load or store a value and provide better error messages.
-
- (FieldExpr.Emit, FieldExpr.EmitAssign, FieldExpr.AddressOf): Use
- new AddressOf arguments.
-
- * statement.cs (Foreach.EmitCollectionForeach): Update
-
- * expression.cs (Argument.Emit): Call AddressOf with proper
- arguments to track usage.
-
- (New.DoEmit): Call AddressOf with new arguments.
-
- (Unary.Emit): Adjust AddressOf call.
-
-2002-03-01 Ravi Pratap <ravi@ximian.com>
-
- * cs-parser.jay (member_access): Change the case for pre-defined types
- to use a MemberAccess instead of a SimpleName. Thanks to Felix again for
- this suggestion.
-
- * class.cs (Operator::Emit): If we are abstract or extern, we don't have
- a method body.
-
- * attribute.cs (CheckAttribute, ApplyAttribute): Ensure that we treat operators
- essentially like methods and apply attributes like MethodImplOptions to them too.
-
- * ecore.cs (SimpleName.SimpleNameResolve): Perform a check on ec.TypeContainer.TypeBuilder
- not being null.
-
- * codegen.cs (EmitContext): The constructor now takes in an extra argument specifying the
- DeclSpace as the distinction is important. We provide sane defaults as usually the TypeContainer
- is the DeclSpace.
-
- * Update code everywhere accordingly.
-
- * ecore.cs : Change references to ec.TypeContainer to ec.DeclSpace where appropriate.
-
- * cs-parser.jay (enum_declaration): Set the current namespace of the enum.
-
-2002-02-28 Ravi Pratap <ravi@ximian.com>
-
- * rootcontext.cs (LookupType): As we cycle through the chain of namespaces
- try performing lookups against those instead of jumping straight into using
- the 'using' clauses.
-
- (ImplicitParent): Add. Thanks to Felix Arrese-Igor for this idea.
-
- (LookupType): Perform lookups in implicit parents too.
-
- * class.cs (GetInterfaceOrClass): Modify to perform the exact same lookup
- sequence as RootContext.LookupType.
-
- * rootcontext.cs (NamespaceLookup): Split out code from LookupType which tries
- the various cases of namespace lookups into this method.
-
-2002-03-01 Miguel de Icaza <miguel@ximian.com>
-
- * cs-parser.jay: Add support for [Attribute ()] (empty arguments
- in positional arguments)
-
- * class.cs (Operator): Update the AllowedModifiers to contain
- extern.
-
- * cs-parser.jay: Update operator declaration to allow for the
- operator body to be empty.
-
- * cs-tokenizer.cs: Added '\u' unicode support in strings and hex
- values.
-
-2002-02-27 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (Method.Emit): Label parameters.
-
- * driver.cs: Return 1 or 0 as the program exit code.
-
-2002-02-26 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs: Special case the `null' object when trying to
- auto-compute the type, as anything can be explicitly converted to
- that.
-
- * ecore.cs (Expression.ConvertExplicit): Bug fix, thanks for
- spotting this Paolo.
-
- (Expression.ImplicitNumericConversion): Perform comparissions of
- the type using the underlying type in the case of an enumeration
- rather than using the enumeration type for the compare.
-
- Cope with the underlying == type case, which is not possible to
- catch before.
-
- (Expression.ConvertNumericExplicit): Perform comparissions of
- the type using the underlying type in the case of an enumeration
- rather than using the enumeration type for the compare.
-
- * driver.cs: If the user does not supply an extension, assume .exe
-
- * cs-parser.jay (if_statement): Rewrote so that we can track the
- location for the if statement.
-
- * expression.cs (Binary.ConstantFold): Only concat strings when
- the operation is "+", not everything ;-)
-
- * statement.cs (Statement.EmitBoolExpression): Take a location
- argument.
- (If, While, Do): Track location.
-
- * expression.cs (Binary.ResolveOperator): In the object + string
- case, I was missing a call to ConvertImplicit
-
-2002-02-25 Ravi Pratap <ravi@ximian.com>
-
- * parameter.cs (Parameter.ExternalType): Take in extra DeclSpace and
- Location arguments. Ensure we use RootContext.LookupType to do our work
- and not try to do a direct Type.GetType and ModuleBuilder.GetType
-
- * interface.cs (PopulateMethod): Handle the type of the parameter being
- null gracefully.
-
- * expression.cs (Invocation.BetterFunction): Handle the case when we
- have a params method with no fixed arguments and a call is made with no
- arguments.
-
-2002-02-25 Miguel de Icaza <miguel@ximian.com>
-
- * cs-tokenizer.cs: Add support for the quote-escape-sequence in
- the verbatim-string-literal
-
- * support.cs (InternalParameters.ParameterModifier): handle null
- fixed parameters.
- (InternalParameters.ParameterType): ditto.
-
- * parameter.cs (VerifyArgs): Also check if the fixed parameter is
- duplicating the name of the variable parameter.
- (GetParameterByName): Fix bug where we were not looking up array
- paramters if they were the only present (thanks Paolo!).
- (GetParameterInfo): We only have an empty set of types if both
- fixed and array are set to null.
- (GetParameterInfo-idx): Handle FixedParameter == null
-
- * cs-parser.jay: Handle the case where there is no catch
- statements (missing null test).
-
-2002-02-22 Miguel de Icaza <miguel@ximian.com>
-
- * driver.cs (MainDriver): Be conservative on our command line
- handling.
-
- Catch DirectoryNotFoundException when calling GetFiles.
-
- (SplitPathAndPattern): Used to split the input specification into
- a path and a pattern that we can feed to Directory.GetFiles.
-
-2002-02-21 Miguel de Icaza <miguel@ximian.com>
-
- * statement.cs (Fixed): Implement the last case of the Fixed
- statement (string handling).
-
- * expression.cs (StringPtr): New class used to return a char * to
- a string; Used by the Fixed statement.
-
- * typemanager.cs: Add char_ptr_type. Add get_OffsetToStringData method.
-
- * expression.cs (Binary.ResolveOperator): Remove redundant
- MemberLookup pn parent type.
- Optimize union call, we do not need a union if the types are the same.
- (Unary.ResolveOperator): REmove redundant MemberLookup on parent
- type.
-
- Specialize the use of MemberLookup everywhere, instead of using
- the default settings.
-
- (StackAlloc): Implement stackalloc keyword.
-
- * cs-parser.jay: Add rule to parse stackalloc.
-
- * driver.cs: Handle /h, /help, /?
-
- * expression.cs (MakeByteBlob): Removed the hacks we had in place
- before we supported unsafe code.
-
- * makefile: add --unsafe to the self compilation of mcs.
-
-2002-02-20 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (PointerArithmetic): New class that is used to
- perform pointer arithmetic.
- (Binary.Resolve): Handle pointer arithmetic
- Handle pointer comparission.
- (ArrayPtr): Utility expression class that is used to take the
- address of an array.
-
- (ElementAccess): Implement array access for pointers
-
- * statement.cs (Fixed): Implement fixed statement for arrays, we
- are missing one more case before we are done.
-
- * expression.cs (Indirection): Implement EmitAssign and set the
- ExprClass to Variable. This allows pointer dereferences to be
- treated as variables, and to have values assigned to them.
-
- * ecore.cs (Expression.StoreFromPtr): New utility function to
- store values dereferencing.
-
-2002-02-20 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (Binary.ResolveOperator): Ensure that we are
- not trying to operate on a void type - this fixes the reported
- bug.
-
- * decl.cs (CheckMethodAgainstBase): Do not allow overriding if
- the parent implementation is sealed.
-
- * ../errors/cs0239.cs : Add.
-
- * attribute.cs (ApplyAttributes): Handle Modulebuilders too.
-
- * typemanager.cs (unverifiable_code_type): Corresponds to
- System.Security.UnverifiableCodeAttribute. We need to emit this for modules
- which have unsafe code in them.
-
- * rootcontext.cs (EmitCode): Emit the above attribute when we are in an
- unsafe context.
-
-2002-02-19 Miguel de Icaza <miguel@ximian.com>
-
- * cs-tokenizer.cs: Add support for @"litreal strings"
-
- Make tokenizer accept pre-processor directives
- on any column (remove the old C-like limitation).
-
- * rootcontext.cs (EmitCode): Emit any global attributes.
- (AddGlobalAttributes): Used to keep track of assembly attributes.
-
- * attribute.cs (ApplyAttributes): Support AssemblyAttributes.
-
- * cs-parser.jay: Add support for global attributes.
-
-2002-02-17 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (Indirection): New helper class. Unary will
- create Indirection classes to be able to implement the
- IMemoryLocation interface on it.
-
-2002-02-16 Miguel de Icaza <miguel@ximian.com>
-
- * cs-parser.jay (fixed_statement): reference the right statement.
-
- * statement.cs (Fixed.Emit): Finish implementing the fixed
- statement for the &x case.
-
-2002-02-14 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (Property.Define, Method.Define): Remove newslot when
- `implementing'.
-
- * modifiers.cs: My use of NewSlot when `Abstract' was set was
- wrong. NewSlot should only be used if the `new' keyword is present.
-
- * driver.cs (GetSystemDir): Use CodeBase instead of FullName for
- locating our system dir. Sorry about this.
-
-2002-02-13 Miguel de Icaza <miguel@ximian.com>
-
- * driver.cs (GetSystemDir): Compute correctly the location of our
- system assemblies. I was using the compiler directory instead of
- the library directory.
-
-2002-02-13 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (BetterFunction): Put back in what Miguel commented out
- since it is the correct fix. The problem is elsewhere ;-)
-
- (IsParamsMethodApplicable): Fix bug where we were not checking that the fixed
- parameters of the parms method are themselves compatible or not !
-
- (StandardConversionExists): Fix very dangerous bug where we were forgetting
- to check that a class implements an interface before saying that an implicit
- conversion was allowed. Use ImplementsInterface to do the checking.
-
-2002-02-13 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (Method.Define): Track whether we are an explicit
- implementation or not. And only call DefineMethodOverride if we
- are an explicit implementation.
-
- (Property.DefineMethod): Ditto.
-
-2002-02-11 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (BetterFunction): Catch hideous bug which was
- preventing us from detecting ambiguous calls due to implicit casts i.e
- cs0121.
-
-2002-01-29 Miguel de Icaza <miguel@ximian.com>
-
- * support.cs (Pair): Remove un-needed method. I figured why I was
- getting the error in cs-parser.jay, the variable in a foreach loop
- is readonly, and the compiler does not really treat this as a variable.
-
- * cs-parser.jay (fixed_statement): Fix grammar. Use ASSIGN
- instead of EQUALS in grammar.
-
- * typemanager.cs (VerifyUnmanaged): Report correct error (208)
-
- * expression.cs (Unary.DoResolve): Check whether the argument is
- managed or not.
-
-2002-01-28 Miguel de Icaza <miguel@ximian.com>
-
- * support.cs: Api for Pair to set a value. Despite the fact that
- the variables are public the MS C# compiler refuses to compile
- code that accesses the field if the variable is part of a foreach
- statement.
-
- * statement.cs (Fixed): Begin implementation of the fixed
- statement.
-
- (Block.AddVariable): Return the VariableInfo on success and null
- on failure instead of true/false.
-
- * cs-parser.jay (foreach): Catch errors on variables already
- defined (we were ignoring this value before) and properly unwind
- the block hierarchy
-
- (fixed_statement): grammar for the fixed statement.
-
-2002-01-25 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (UnaryMutator.IsIncrementableNumber): Allow also
- pointer types to be incretemented.
-
- (SizeOf): Implement.
-
- * cs-parser.jay (pointer_member_access): Implement
- expr->IDENTIFIER production.
-
- * expression.cs (IndexerAccess.DoResolve, ArrayAccess.DoResolve,
- MemberAccess.DoResolve, Invocation.DoResolve): Check for pointers
- on safe contexts.
-
- (Unary): Implement indirection.
-
- * ecore.cs (Expression.UnsafeError): Reports error 214 (pointer
- use in non-unsafe context).
-
- (SimpleName.DoResolve): Check for pointers in field access on safe
- contexts.
-
- (Expression.LoadFromPtr): Factor the load-indirect code in this
- function. This was duplicated in UnboxCast and ParameterReference
-
-2002-01-24 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (ComposedCast): report an error if a pointer cast
- is used in a safe region.
-
- * ecore.cs (Expression.ConvertExplicit): Add rules for implicit
- pointer type casts in unsafe context.
-
- * codegen.cs (EmitContext): Set up IsUnsafe.
-
- * cs-parser.jay (non_expression_type): Add productions for pointer
- casts.
-
- * expression.cs (Invocation.EmitCall): Remove chunk of buggy
- code. We should not use force into static mode if the method is
- not virtual. Fixes bug in MIS
-
- * statement.cs (Do.Emit, While.Emit, For.Emit,
- Statement.EmitBoolExpression): Add support to Do and While to
- propagate infinite loop as `I do return' semantics.
-
- Improve the For case to also test for boolean constants.
-
- * attribute.cs (Attribute.ApplyAttributes): Add ParameterBuilder
- to the list of attributes we can add.
-
- Remove `EmitContext' argument.
-
- * class.cs (Method.Define): Apply parameter attributes.
- (Constructor.Define): Apply parameter attributes.
- (MethodCore.LabelParameters): Move here the core of labeling
- parameters.
-
- * support.cs (ReflectionParameters.ParameterModifier,
- InternalParameters.ParameterModifier): Use IsByRef on the type and
- only return the OUT bit for these parameters instead of in/out/ref
- flags.
-
- This is because I miss-understood things. The ParameterInfo.IsIn
- and IsOut represent whether the parameter has the [In] and [Out]
- attributes set.
-
-2002-01-22 Miguel de Icaza <miguel@ximian.com>
-
- * ecore.cs (FieldExpr.Emit): Release temporaries.
-
- * assign.cs (LocalTemporary.Release): new function.
-
- * codegen.cs (EmitContext.GetTemporaryStorage,
- EmitContext.FreeTemporaryStorage): Rework the way we deal with
- temporary storage. Now we can "put back" localbuilders when we
- are done with them
-
-2002-01-21 Miguel de Icaza <miguel@ximian.com>
-
- * ecore.cs (FieldExpr.Emit): Handle initonly fields specially: we
- need to make a copy of the variable to generate verifiable code.
-
-2002-01-19 Miguel de Icaza <miguel@ximian.com>
-
- * driver.cs: Compute dynamically the system directory.
-
- * ecore.cs (CopyNewMethods): reworked, exposed, made public.
- Slower, but more generally useful. Used by the abstract
- registering implementation.
-
- * expression.cs (ResolveMemberAccess): Reorder the way we evaluate
- the rules for the special rule on Type/instances. First check if
- we have the same name, and if so, try that special static path
- rather than the instance path.
-
-2002-01-18 Miguel de Icaza <miguel@ximian.com>
-
- * cs-parser.jay: Emit 642 (warning: possible empty statement) for
- for, while and if.
-
- * class.cs (TypeBuilder.DefineType): Do not allow inheritance from
- Enum, ValueType, Delegate or Array for non-corlib compiles.
-
- * cs-tokenizer.cs: Catch long identifiers (645)
-
- * typemanager.cs (IndexerPropetyName): Ravi never tested this
- piece of code.
-
- * class.cs (TypeContainer.RegisterRequiredImplementations): Bug
- fix, we were returning too early, so we were not registering
- pending methods from abstract classes.
-
- Do not register pending methods if the class is abstract.
-
- * expression.cs (Conditional.DoResolve): Report circular implicit
- conversions when we neecd to compute it for conditional
- expressions.
-
- (Is.DoResolve): If the expression is always of the provided type,
- flag warning 183. If the expression can not ever be of the
- provided type flag warning 184.
-
- * class.cs: Catch 169 as well.
-
- * ecore.cs (FieldExpr): For now in AddressOf mark as assigned and
- read.
-
-2002-01-18 Nick Drochak <ndrochak@gol.com>
-
- * makefile: remove path to beta2 csc.exe. path to csc.exe must be in PATH instead.
-
-2002-01-17 Miguel de Icaza <miguel@ximian.com>
-
- * interface.cs: (PopulateMethod): Check for pointers being defined
- only if the unsafe context is active.
- (PopulateProperty): ditto.
- (PopulateIndexer): ditto.
-
- * class.cs (Method, Method.Define): Allow `unsafe' modifier to be
- specified. If pointers are present, make sure that they are
- present in an unsafe context.
- (Constructor, Constructor.Define): ditto.
- (Field, Field.Define): ditto.
- (Property, Property.Define): ditto.
- (Event, Event.Define): ditto.
-
- * interface.cs (Interface.GetInterfaceTypeByName): Only lookup the
- hashtable if there are classes or structs defined.
-
- * expression.cs (LocalVariableReference.DoResolve): Simplify this
- code, as the constant resolution moved.
-
- * statement.cs (Block.EmitMeta): Resolve all constants as we emit
- the metadata, so we can flag error 133.
-
- * decl.cs (MemberCore.UnsafeOK): New function to test that a
- pointer is being declared in an unsafe context.
-
-2002-01-16 Miguel de Icaza <miguel@ximian.com>
-
- * modifiers.cs (Modifiers.Check): Require a Location argument.
- Report error 227 for Unsafe use.
-
- * typemanager.cs: Remove IsPointerType, we should be using Type.IsPointer
-
- * statement.cs (For.Emit): If the test is null, then report that
- we do `return', as we wont reach anything afterwards.
-
- (Switch.SwitchGoverningType): Track the expression that matched
- the conversion.
-
- * driver.cs: Allow negative numbers as an error code to flag.
-
- * cs-parser.jay: Handle 1551.
-
- * namespace.cs: Add 1537 checking (repeated using alias namespaces).
-
-2002-01-15 Miguel de Icaza <miguel@ximian.com>
-
- * cs-parser.jay: Report 1518 (type declaration can only contain
- class, struct, interface, enum or delegate)
-
- (switch_label): Report 1523 (keywords `case' or `default' must
- preced code)
-
- (opt_switch_sections): Report 1522 (empty switch)
-
- * driver.cs: Report 1515 (response file specified multiple times)
- Report 1516 (Source file specified multiple times).
-
- * expression.cs (Argument.Resolve): Signal 1510
-
- (BaseAccess.Resolve, BaseIndexer.Resolve): Signal 1511 (base
- access not allowed in static code)
-
-2002-01-11 Ravi Pratap <ravi@ximian.com>
-
- * typemanager.cs (IsPointerType): Utility method which we are going
- to need a lot.
-
- * ecore.cs (ImplicitReferenceConversion): A pointer type cannot be cast to
- the object type, so we take care of that.
-
- * expression.cs (FullMethodDesc): Also include the return type in descriptions.
-
- * support.cs (ParameterDesc): Fix minor bug which was causing params tags to be
- added to non-params parameters :-)
-
- * typemanager.cs (CSharpName): Include 'void' type too.
-
- (void_ptr_type): Include in the set of core types.
-
- * ecore.cs (ConvertImplicit): Make use of ConvertImplicitStandard instead of
- duplicating code.
-
- (ConvertImplicitStandard): Handle standard implicit pointer conversions when we have
- an unsafe context.
-
- * cs-parser.jay (local_variable_pointer_type): Add support for 'void *' as I had
- completely forgotten about it.
-
-2002-01-10 Ravi Pratap <ravi@ximian.com>
-
- * cs-parser.jay (pointer_type): Add. This begins our implementation
- of parsing rules for unsafe code.
-
- (unsafe_statement): Implement.
-
- (embedded_statement): Modify to include the above.
-
- * statement.cs (Unsafe): Implement new class for unsafe blocks.
-
- * codegen.cs (EmitContext.InUnsafe): Add. This determines
- if the current context is an unsafe one.
-
- * cs-parser.jay (local_variable_pointer_type): Since local variable types
- are handled differently, we need separate rules for them.
-
- (local_variable_declaration): Update to use local_variable_pointer_type
- to allow variable declarations of unmanaged pointer types.
-
- * expression.cs (Unary.ResolveOperator): Ensure that the '&' operator is used only
- in unsafe contexts.
-
- * ../errors/cs0214.cs : Add.
-
-2002-01-16 Nick Drochak <ndrochak@gol.com>
-
- * makefile: remove 'response' file when cleaning.
-
-2002-01-15 Miguel de Icaza <miguel@ximian.com>
-
- * cs-parser.jay: Report 1524.
-
-2002-01-14 Miguel de Icaza <miguel@ximian.com>
-
- * typemanager.cs (RegisterMethod): drop checking if we have
- registered this from here
-
-2002-01-12 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (Method.EmitDestructor): Implement calling our base
- destructor.
-
- * statement.cs (Try.Emit): Fix to reset the InFinally to the old
- value of InFinally.
-
- * codegen.cs (EmitContext.EmitTopBlock): Destructors will call
- this routine and will wrap the call in a try/catch block. Deal
- with the case.
-
-2002-01-11 Miguel de Icaza <miguel@ximian.com>
-
- * ecore.cs (Expression.MemberLookup): instead of taking a
- parameter `same_type' that was used to tell whether we could
- access private members we compute our containing type from the
- EmitContext.
-
- (FieldExpr): Added partial support for volatile fields. This does
- not work for volatile fields exposed from assemblies, as I can not
- figure out how to extract the modreq from it.
-
- Updated all the source files to use this.
-
- * codegen.cs (EmitContext): Compute ContainerType ahead of time,
- because it is referenced by MemberLookup very often.
-
-2002-01-09 Ravi Pratap <ravi@ximian.com>
-
- * typemanager.cs (IndexerPropertyName): If we have a TypeBuilder, use
- TypeBuilder.GetCustomAttributes to retrieve what we need.
-
- Get rid of redundant default_member_attr_type as this is the same as
- default_member_type which already exists.
-
- * interface.cs, attribute.cs : Update accordingly.
-
-2002-01-08 Miguel de Icaza <miguel@ximian.com>
-
- * typemanager.cs: Enable IndexerPropertyName again. It does not
- work for TYpeBuilders though. Ravi, can you please fix this?
-
- * cs-tokenizer.cs: Accept _ as a name in pp-expressions.
-
- * expression.cs (Argument.Emit): Handle the case of ref objects
- being passed to ref functions;
-
- (ParameterReference.EmitLoad): Loads the content of the pointer
- without dereferencing.
-
-2002-01-07 Miguel de Icaza <miguel@ximian.com>
-
- * cs-tokenizer.cs: Implemented the pre-processing expressions.
-
-2002-01-08 Ravi Pratap <ravi@ximian.com>
-
- * class.cs (Indexer.DefineMethod): Incorporate the interface
- type in the name of the method if we are doing explicit interface
- implementation.
-
- * expression.cs (ConversionExists): Remove as it is completely obsolete.
-
- (BetterConversion): Fix extremely trivial bug where we were referring to
- ConversionExists instead of StandardConversionExists ! Hooray, things are fine
- again !
-
- * ../errors/bug16.cs : Add although we have fixed it.
-
-2002-01-07 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (BaseIndexer): Begin implementation.
-
- * class.cs (TypeContainer.IsInterfaceMethod): Bug fix.
-
- * cs-parser.jay (indexer_declarator): Use qualified_identifier
- production directly to remove a shift/reduce, and implement
- explicit interface implementation.
-
- * cs-tokenizer.cs: Fix tokenizer, it was consuming one extra char
- after a floating point suffix.
-
- * expression.cs (DoNumericPromotions): Improved the conversion for
- uint/uint. If we have a constant, we avoid doing a typecast to a
- larger type.
-
- * class.cs (Indexer): Implement explicit interface implementation
- for indexers.
-
-Sat Jan 5 16:08:23 CET 2002 Paolo Molaro <lupus@ximian.com>
-
- * class.cs: make the default instance constructor public and hidebysig.
-
-2001-01-03 Ravi Pratap <ravi@ximian.com>
-
- * interface.cs (EmitDefaultMemberAttr): Make this helper method static
- so we can call it from elsewhere.
-
- * class.cs (TypeContainer.Emit): Emit the attribute here too. The rule is that
- we emit it internally if the class has a defined indexer; otherwise the user
- emits it by decorating the class definition with the DefaultMemberAttribute.
-
- * attribute.cs (ApplyAttributes): Perform checks to see that the DefaultMember
- attribute is not used on a type which defines an indexer.
-
- * cs-tokenizer.cs (get_cmd_arg): Ensure we trim whitespace and also include the tab
- character when we skip whitespace.
-
- * ../errors/cs0646.cs : Add.
-
-2002-01-03 Miguel de Icaza <miguel@ximian.com>
-
- * ecore.cs (SimpleName.ResolveSimpleName): Report error 120
- again.
-
- * makefile: Add practical target `mcs3.exe' which builds the third
- generation compiler.
-
- * expression.cs (New): Fix structures constructor calling.
-
- * class.cs (Property, Method, Indexer): Emit Final flag on the
- method if we are an interface implementation and we are not
- abstract.
-
- * ecore.cs (PropertyExpr): New public field `IsBase', tells
- whether this property is referencing a `base' method.
-
- * expression.cs (Invocation.EmitCall): take an extra argument:
- is_base, this is used to determine whether the `call' or
- `callvirt' opcode should be used.
-
-
- * delegate.cs: update EmitCall.
-
- * class.cs (Method.Define): Set NewSlot for the cases where we are
- not implementing an interface method.
-
- (Property.Define): ditto.
-
-2002-01-02 Miguel de Icaza <miguel@ximian.com>
-
- * cs-tokenizer.cs: (Tokenizer.escape): Escape '\r' as '\r' not as
- 'r'. Allows mcs to parse itself fully.
-
-2002-01-02 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (ArrayCreation.num_automatic_initializers): Keep track
- of the number of initializers that require the InitializeArray method.
-
- (CheckIndices): Store the Expression in all cases - not the plain value. Also
- update the above field where necessary.
-
- (MakeByteBlob): Update accordingly.
-
- (DoEmit): Call EmitStaticInitializers only if the number of initializers is
- greater than 2.
-
- (EmitDynamicInitializers): Update in accordance with the new optimization.
-
- (ArrayAccess.EmitStoreOpcode): Include char type along with short and ushort - the
- same OpCode applies.
-
- * cs-parser.jay : Fix some glaring errors I introduced.
-
-2002-01-01 Ravi Pratap <ravi@ximian.com>
-
- * parameters.cs (AddVariable, AddConstant): Pass in current_local_parameters
- so that we can check for name clashes there too.
-
- * typemanager.cs (default_member_attr_type): The attribute that we need to emit
- for interface indexers.
-
- * interfaces.cs (Define): Emit the default member attribute.
-
- * expression.cs (MakeByteBlob): Fix extremely trivial bug where the wrong
- variable was being referred to while setting the value ;-)
-
-2002-01-01 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (MakeByteBlob): Optimize: we do not need to fill
- byte-by-byte information when we know the data is zero.
-
- Make the block always a multiple of 4, because
- DefineInitializedData has a bug.
-
- * assign.cs: Fix, we should assign from the temporary, not from
- the source.
-
- * expression.cs (MakeByteBlob): Fix my incorrect code.
-
-2001-12-31 Miguel de Icaza <miguel@ximian.com>
-
- * typemanager.cs (EnumToUnderlying): This function is used to get
- the underlying type from an enumeration, because it does not
- always work.
-
- * constant.cs: Use the I4_S form for values between -128 and 127.
-
- * statement.cs (Block.LookupLabel): Looks up a label.
- (Block): Drop support for labeled blocks.
-
- (LabeledStatement): New kind of statement that represents a label
- only.
-
- (Goto): Finally implement this bad boy.
-
- * cs-parser.jay: Update to reflect new mechanism to implement
- labels.
-
-2001-12-30 Miguel de Icaza <miguel@ximian.com>
-
- * codegen.cs (EmitContext.This): a codegen property that keeps the
- a single instance of this instead of creating many different this
- instances.
-
- * delegate.cs (Delegate.DoResolve): Update to use the property;
-
- * ecore.cs (SimpleName.SimpleNameResolve): Ditto
-
- * expression.cs (BaseAccess.DoResolve): Ditto.
-
-2001-12-29 Ravi Pratap <ravi@ximian.com>
-
- * typemanager.cs (methodimpl_attr_type): Add to hold the type
- corresponding to System.Runtime.CompilerServices.MethodImplAttribute.
-
- (InitCoreTypes): Update accordingly.
-
- * attribute.cs (Resolve): Remember if the attribute is a MethodImplAttribute
- so we can quickly store the state.
-
- (ApplyAttributes): Set the correct implementation flags
- for InternalCall methods.
-
-2001-12-29 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (EmitCall): if a method is not virtual, then do
- not use callvirt on it.
-
- (ArrayAccess.EmitAssign): storing non-builtin value types (ie,
- user defined stuff) requires the use of stobj, which takes an
- address on the stack instead of an array and an index. So emit
- the Ldelema operation for it.
-
- (EmitStoreOpcode): Use stobj for valuetypes.
-
- (UnaryMutator.EmitCode): Use the right 1 value depending on
- whether we are dealing with int64/uint64, float or doubles.
-
- * class.cs (TypeContainer.AddConstructor): Fix the logic to define
- constructors that I implemented last night.
-
- (Constructor.IsDefault): Fix to work properly for static
- constructors.
-
- * cs-parser.jay (CheckDef): report method signature errors.
- Update error number 103 to be 132.
-
- * decl.cs: New AdditionResult enumeration value: MethodExists.
- Although we do this check for methods later on in the semantic
- analysis, catching repeated default constructors is so easy that
- we catch these here.
-
- * expression.cs (Binary.DoNumericPromotions): Fix the uint64 type
- promotions code.
-
- (ParameterReference.EmitAssign, Emit): handle
- bools as bytes.
-
- (ArrayAccess.EmitLoadOpcode): Handle bool type here.
- (ArrayAccess.EmitStoreOpcode): ditto.
-
- * cs-tokenizer.cs (is_punct): Eliminated empty computation.
-
- * expression.cs (MakeByteBlob): Complete all the missing types
- (uint, short, ushort, byte, sbyte)
-
- * class.cs: Only init instance field initializers on instance
- constructors.
-
- Rename `constructors' to instance_constructors.
-
- (TypeContainer.AddConstructor): Only add constructors to the list
- if it is not static.
-
- Make sure that we handle default_static_constructor independently
- everywhere where we handle instance_constructors
-
-2001-12-28 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs: Do not lookup or create a base initializer for a
- static constructor.
-
- (ConstructorInitializer.Resolve): use the proper type to lookup
- for constructors.
-
- * cs-parser.jay: Report error 1585 (modifiers between type and name).
-
- * enum.cs, interface.cs: Remove CloseType, this is taken care by
- in DeclSpace.
-
- * decl.cs: CloseType is now an virtual method, the default
- implementation just closes this type.
-
-2001-12-28 Ravi Pratap <ravi@ximian.com>
-
- * attribute.cs (DefinePInvokeMethod): Set the implementation flags
- to PreserveSig by default. Also emit HideBySig on such methods.
-
- Basically, set the defaults to standard values.
-
- * expression.cs (Invocation.BetterFunction): We need to make sure that for each
- argument, if candidate is better, it can't be worse than the best !
-
- (Invocation): Re-write bits to differentiate between methods being
- applicable in their expanded form and their normal form - for params
- methods of course.
-
- Get rid of use_standard everywhere as only standard conversions are allowed
- in overload resolution.
-
- More spec conformance.
-
-2001-12-27 Miguel de Icaza <miguel@ximian.com>
-
- * driver.cs: Add --timestamp, to see where the compiler spends
- most of its time.
-
- * ecore.cs (SimpleName.DoResolve): Do not create an implicit
- `this' in static code.
-
- (SimpleName.DoResolve): Implement in terms of a helper function
- that allows static-references to be passed upstream to
- MemberAccess.
-
- (Expression.ResolveWithSimpleName): Resolve specially simple
- names when called by MemberAccess to implement the special
- semantics.
-
- (Expression.ImplicitReferenceConversion): Handle conversions from
- Null to reference types before others, as Null's type is
- System.Object.
-
- * expression.cs (Invocation.EmitCall): Handle the special case of
- calling methods declared on a reference type from a ValueType
- (Base classes System.Object and System.Enum)
-
- (MemberAccess.Resolve): Only perform lookups on Enumerations if
- the left hand side is a TypeExpr, not on every enumeration.
-
- (Binary.Resolve): If types are reference types, then do a cast to
- object on operators != and == of both arguments.
-
- * typemanager.cs (FindMembers): Extract instance and static
- members if requested.
-
- * interface.cs (PopulateProperty): Use void_type instead of null
- as the return type for the setter method.
-
- (PopulateIndexer): ditto.
-
-2001-12-27 Ravi Pratap <ravi@ximian.com>
-
- * support.cs (ReflectionParameters): Fix minor bug where we
- were examining the wrong parameter for the ParamArray attribute.
-
- Cope with requests for the type of the parameter at position
- greater than the params parameter's. We now return the element
- type of the params array as that makes more sense.
-
- * expression.cs (Invocation.IsParamsMethodApplicable): Update
- accordingly as we no longer have to extract the element type
- ourselves.
-
- (Invocation.OverloadResolve): Update.
-
-2001-12-27 Miguel de Icaza <miguel@ximian.com>
-
- * statement.cs (Foreach.GetEnumeratorFilter): Do not compare
- against IEnumerator, test whether the return value is a descendant
- of the IEnumerator interface.
-
- * class.cs (Indexer.Define): Use an auxiliary method to implement
- the other bits of the method definition. Begin support for
- explicit interface implementation.
-
- (Property.DefineMethod): Use TypeManager.void_type instead of null
- for an empty return value.
-
-2001-12-26 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (MemberAccess.ResolveMemberAccess): if we are
- dealing with a FieldExpr which is composed of a FieldBuilder, in
- the code path we did extract the constant, but we should have
- obtained the underlying value to be able to cast it (otherwise we
- end up in an infinite loop, this is what Ravi was running into).
-
- (ArrayCreation.UpdateIndices): Arrays might be empty.
-
- (MemberAccess.ResolveMemberAccess): Add support for section
- 14.5.4.1 that deals with the special case of E.I when E is a type
- and something else, that I can be a reference to a static member.
-
- (ArrayCreation.MakeByteBlob): It is not an error to not be able to
- handle a particular array type to create byte blobs, it is just
- something we dont generate byteblobs for.
-
- * cs-tokenizer.cs (get_cmd_arg): Ignore \r in commands and
- arguments.
-
- * location.cs (Push): remove the key from the hashtable that we
- are about to add. This happens for empty files.
-
- * driver.cs: Dispose files after we have parsed them.
-
- (tokenize): new function that only runs the tokenizer on its
- input, for speed testing.
-
-2001-12-26 Ravi Pratap <ravi@ximian.com>
-
- * class.cs (Event.Define): Define the private field only if there
- are no accessors defined.
-
- * expression.cs (ResolveMemberAccess): If there is no associated
- field with the event, that means we have an event defined with its
- own accessors and we should flag error cs0070 since transforming
- ourselves into a field is not valid in that case.
-
- * ecore.cs (SimpleName.DoResolve): Same as above.
-
- * attribute.cs (DefinePInvokeMethod): Set the default calling convention
- and charset to sane values.
-
-2001-12-25 Ravi Pratap <ravi@ximian.com>
-
- * assign.cs (DoResolve): Perform check on events only if they
- are being accessed outside the declaring type.
-
- * cs-parser.jay (event_declarations): Update rules to correctly
- set the type of the implicit parameter etc.
-
- (add_accessor, remove_accessor): Set current local parameters.
-
- * expression.cs (Binary): For delegate addition and subtraction,
- cast the return value from the method into the appropriate delegate
- type.
-
-2001-12-24 Ravi Pratap <ravi@ximian.com>
-
- * typemanager.cs (RegisterDelegateData, GetDelegateData): Get rid
- of these as the workaround is unnecessary.
-
- * delegate.cs (NewDelegate.DoResolve): Get rid of bits which registered
- delegate data - none of that is needed at all.
-
- Re-write bits to extract the instance expression and the delegate method
- correctly.
-
- * expression.cs (Binary.ResolveOperator): Handle the '-' binary operator
- on delegates too.
-
- * attribute.cs (ApplyAttributes): New method to take care of common tasks
- of attaching attributes instead of duplicating code everywhere.
-
- * everywhere : Update code to do attribute emission using the above method.
-
-2001-12-23 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (IsParamsMethodApplicable): if there are not
- parameters, return immediately.
-
- * ecore.cs: The 0 literal can be implicity converted to an enum
- type.
-
- (SimpleName.DoResolve): First lookup the type, then lookup the
- members.
-
- (FieldExpr.Emit): If the InstanceExpression is a ValueType, we
- want to get its address. If the InstanceExpression is not
- addressable, store the result in a temporary variable, then get
- the address of it.
-
- * codegen.cs: Only display 219 errors on warning level or above.
-
- * expression.cs (ArrayAccess): Make it implement the
- IMemoryLocation interface.
-
- (Binary.DoResolve): handle the operator == (object a, object b)
- and operator != (object a, object b) without incurring into a
- BoxedCast (because 5 != o should never be performed).
-
- Handle binary enumerator operators.
-
- (EmitLoadOpcode): Use Ldelema if the object we are loading is a
- value type, otherwise use Ldelem_ref.
-
- Use precomputed names;
-
- (AddressOf): Implement address of
-
- * cs-parser.jay (labeled_statement): Fix recursive block
- addition by reworking the production.
-
- * expression.cs (New.DoEmit): New has a special case:
-
- If we are dealing with a ValueType, we have a few
- situations to deal with:
-
- * The target of New is a ValueType variable, that is
- easy, we just pass this as the variable reference
-
- * The target of New is being passed as an argument,
- to a boxing operation or a function that takes a
- ValueType.
-
- In this case, we need to create a temporary variable
- that is the argument of New.
-
-
-2001-12-23 Ravi Pratap <ravi@ximian.com>
-
- * rootcontext.cs (LookupType): Check that current_type is not null before
- going about looking at nested types.
-
- * ecore.cs (EventExpr.EmitAddOrRemove): Rename from EmitAssign as we do
- not implement the IAssignMethod interface any more.
-
- * expression.cs (MemberAccess.ResolveMemberAccess): Handle EventExprs specially
- where we tranform them into FieldExprs if they are being resolved from within
- the declaring type.
-
- * ecore.cs (SimpleName.DoResolve): Do the same here.
-
- * assign.cs (DoResolve, Emit): Clean up code considerably.
-
- * ../errors/bug10.cs : Add.
-
- * ../errors/cs0070.cs : Add.
-
- * typemanager.cs : Use PtrHashtable for Delegate data hashtable etc.
-
- * assign.cs : Get rid of EventIsLocal everywhere.
-
-2001-12-23 Miguel de Icaza <miguel@ximian.com>
-
- * ecore.cs (ConvertIntLiteral): finished the implementation.
-
- * statement.cs (SwitchLabel): Convert the value we are using as a
- key before looking up the table.
-
-2001-12-22 Miguel de Icaza <miguel@ximian.com>
-
- * codegen.cs (EmitTopBlock): Require a Location argument now.
-
- * cs-parser.jay (constructor_declarator): We need to setup
- current_local_parameters before we parse the
- opt_constructor_initializer, to allow the variables to be bound
- to the constructor arguments.
-
- * rootcontext.cs (LookupType): First lookup nested classes in our
- class and our parents before we go looking outside our class.
-
- * expression.cs (ConstantFold): Extract/debox the values at the
- beginnning.
-
- * rootcontext.cs (EmitCode): Resolve the constants first before we
- resolve the types. This is not really needed, but it helps debugging.
-
- * statement.cs: report location.
-
- * cs-parser.jay: pass location to throw statement.
-
- * driver.cs: Small bug fix.
-
- * report.cs: Updated format to be 4-zero filled digits.
-
-2001-12-22 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (CheckIndices): Fix minor bug where the wrong
- variable was being referred to ;-)
-
- (DoEmit): Do not call EmitStaticInitializers when the
- underlying type is System.Object.
-
-2001-12-21 Ravi Pratap <ravi@ximian.com>
-
- * ecore.cs (EventExpr.Resolve): Implement to correctly set the type
- and do the usual workaround for SRE.
-
- * class.cs (MyEventBuilder.EventType): New member to get at the type
- of the event, quickly.
-
- * expression.cs (Binary.ResolveOperator): Handle delegate addition.
-
- * assign.cs (Assign.DoResolve): Handle the case when the target
- is an EventExpr and perform the necessary checks.
-
- * ecore.cs (EventExpr.EmitAssign): Implement the IAssignMethod
- interface.
-
- (SimpleName.MemberStaticCheck): Include check for EventExpr.
-
- (EventExpr): Set the type in the constructor itself since we
- are meant to be born fully resolved.
-
- (EventExpr.Define): Revert code I wrote earlier.
-
- * delegate.cs (NewDelegate.Resolve): Handle the case when the MethodGroup's
- instance expression is null. The instance expression is a This in that case
- or a null, depending on whether it is a static method or not.
-
- Also flag an error if the reference to a method is ambiguous i.e the MethodGroupExpr
- refers to more than one method.
-
- * assign.cs (DoResolve): Check whether the event belongs to the same Type container
- and accordingly flag errors.
-
-2001-12-21 Miguel de Icaza <miguel@ximian.com>
-
- * statement.cs (Throw.Emit): Add support for re-throwing exceptions.
-
-2001-12-22 Miguel de Icaza <miguel@ximian.com>
-
- * location.cs (ToString): Provide useful rutine.
-
-2001-12-21 Miguel de Icaza <miguel@ximian.com>
-
- * ecore.cs (Expression.ConvertIntLiteral): Do not return Constant
- objects, return the actual integral boxed.
-
- * statement.cs (SwitchLabel): define an ILLabel for each
- SwitchLabel.
-
- (Switch.CheckSwitch): If the value is a Literal, extract
- the underlying literal.
-
- Also in the unused hashtable we had, add the SwitchLabel so we can
- quickly look this value up.
-
- * constant.cs: Implement a bunch of new constants. Rewrite
- Literal based on this. Made changes everywhere to adapt to this.
-
- * expression.cs (Expression.MakeByteBlob): Optimize routine by
- dereferencing array only once, and also copes with enumrations.
-
- bytes are two bytes wide, not one.
-
- (Cast): Perform constant conversions.
-
- * ecore.cs (TryImplicitIntConversion): Return literals instead of
- wrappers to the literals here.
-
- * expression.cs (DoNumericPromotions): long literals can converted
- to ulong implicity (this is taken care of elsewhere, but I was
- missing this spot).
-
- * ecore.cs (Expression.Literalize): Make the return type Literal,
- to improve type checking.
-
- * rootcontext.cs: Lookup for nested classes in our class hierarchy.
-
-2001-12-20 Miguel de Icaza <miguel@ximian.com>
-
- * literal.cs: Revert code from ravi that checked the bounds. The
- bounds are sane by the definition of the type itself.
-
- * typemanager.cs: Fix implementation of ImplementsInterface. We
- need to actually look up in our parent hierarchy for interfaces
- implemented.
-
- * const.cs: Use the underlying type for enumerations
-
- * delegate.cs: Compute the basename for the delegate creation,
- that should fix the delegate test case, and restore the correct
- Type Lookup semantics in rootcontext
-
- * rootcontext.cs: Revert Ravi's last patch. The correct way of
- referencing a nested type with the Reflection API is using the "+"
- sign.
-
- * cs-parser.jay: Do not require EOF token at the end.
-
-2001-12-20 Ravi Pratap <ravi@ximian.com>
-
- * rootcontext.cs (LookupType): Concatenate type names with
- a '.' instead of a '+' The test suite passes again.
-
- * enum.cs (Enum.DefineEnum): Set RTSpecialName on the 'value__'
- field of the enumeration.
-
- * expression.cs (MemberAccess.ResolveMemberAccess): Add support for
- the case when the member is an EventExpr.
-
- * ecore.cs (EventExpr.InstanceExpression): Every event which is not
- static has an associated instance expression.
-
- * typemanager.cs (RegisterEvent): The usual workaround, now for events.
-
- (GetAddMethod, GetRemoveMethod): Workarounds, as usual.
-
- * class.cs (Event.Define): Register event and perform appropriate checks
- for error #111.
-
- We define the Add and Remove methods even if the use provides none because
- in that case, we provide default implementations ourselves.
-
- Define a private field of the type of the event. This is done by the CSC compiler
- and we should be doing it too ;-)
-
- * typemanager.cs (delegate_combine_delegate_delegate, delegate_remove_delegate_delegate):
- More methods we use in code we generate.
-
- (multicast_delegate_type, delegate_type): Two separate types since the distinction
- is important.
-
- (InitCoreTypes): Update accordingly for the above.
-
- * class.cs (Event.Emit): Generate code for default accessors that we provide
-
- (EmitDefaultMethod): Do the job in the above.
-
- * delegate.cs (DefineDelegate): Use TypeManager.multicast_delegate_type in the
- appropriate place.
-
-2001-12-20 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (Indexer.Define): Fix bug, we were setting both Get/Set
- builders even if we were missing one.
-
- * interface.cs, class.cs, enum.cs: When calling DefineNestedType
- pass the Basename as our class name instead of the Name. The
- basename will be correctly composed for us.
-
- * parameter.cs (Paramters): Now takes a Location argument.
-
- * decl.cs (DeclSpace.LookupType): Removed convenience function and
- make all the code call directly LookupType in RootContext and take
- this chance to pass the Location information everywhere.
-
- * Everywhere: pass Location information.
-
-2001-12-19 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (Constructor.Define): Updated way of detecting the
- length of the parameters.
-
- (TypeContainer.DefineType): Use basename as the type name for
- nested types.
-
- (TypeContainer.Define): Do not recursively define types here, as
- definition is taken care in order by the RootContext.
-
- * tree.cs: Keep track of namespaces in a per-file basis.
-
- * parameter.cs (Parameter.ComputeSignature): Update to use
- DeclSpace.
-
- (Parameters.GetSignature): ditto.
-
- * interface.cs (InterfaceMethod.GetSignature): Take a DeclSpace
- instead of a TypeContainer.
-
- (Interface.SemanticAnalysis): Use `this' instead of our parent to
- resolve names. Because we need to be resolve in our context, not
- our parents.
-
- * driver.cs: Implement response files.
-
- * class.cs (TypeContainer.DefineType): If we are defined, do not
- redefine ourselves.
-
- (Event.Emit): Emit the code for add/remove handlers.
- (Event.Define): Save the MethodBuilders for add/remove.
-
- * typemanager.cs: Use pair here too.
-
- * cs-parser.jay: Replaced use of DictionaryEntry for Pair because
- DictionaryEntry requires the first argument to be non-null.
-
- (enum_declaration): Compute full name for registering the
- enumeration.
-
- (delegate_declaration): Instead of using
- formal_parameter_list, use opt_formal_parameter_list as the list
- can be empty.
-
- * cs-tokenizer.cs (PropertyParsing): renamed from `properties'
- (EventParsing): New property that controls whether `add' and
- `remove' are returned as tokens or identifiers (for events);
-
-2001-12-19 Ravi Pratap <ravi@ximian.com>
-
- * class.cs (Event.Define): Revamp use of EventBuilder completely. We now
- use MyEventBuilder only and let it wrap the real builder for us.
-
- (MyEventBuilder): Revamp constructor etc.
-
- Implement all operations that we perform on EventBuilder in precisely the same
- way here too.
-
- (FindMembers): Update to use the EventBuilder member.
-
- (Event.Emit): Update accordingly.
-
-2001-12-18 Ravi Pratap <ravi@ximian.com>
-
- * class.cs (MyEventBuilder.Set*): Chain to the underlying builder
- by calling the appropriate methods.
-
- (GetCustomAttributes): Make stubs as they cannot possibly do anything
- useful.
-
- (Event.Emit): Use MyEventBuilder everywhere - even to set attributes.
-
-2001-12-17 Ravi Pratap <ravi@ximian.com>
-
- * delegate.cs (Delegate.Populate): Check that the return type
- and various parameters types are indeed accessible.
-
- * class.cs (Constructor.Define): Same here.
-
- (Field.Define): Ditto.
-
- (Event.Define): Ditto.
-
- (Operator.Define): Check that the underlying Method defined itself
- correctly - so it's MethodBuilder should not be null.
-
- * delegate.cs (DelegateInvocation.DoResolve): Bale out if the type of the Instance
- expression happens to be null.
-
- * class.cs (MyEventBuilder): Workaround for SRE lameness. Implement various abstract
- members but as of now we don't seem to be able to do anything really useful with it.
-
- (FindMembers): Handle events separately by returning the MyEventBuilder of the event,
- not the EventBuilder.
-
-2001-12-18 Miguel de Icaza <miguel@ximian.com>
-
- * cs-tokenizer.cs: Add support for defines.
- Add support for #if, #elif, #else, #endif
-
- (eval_var): evaluates a variable.
- (eval): stubbed for evaluating functions.
-
- * cs-parser.jay: Pass the defines information
-
- * driver.cs: Add --define command line option.
-
- * decl.cs: Move MemberCore here.
-
- Make it the base class for DeclSpace. This allows us to catch and
- report 108 and 109 for everything now.
-
- * class.cs (TypeContainer.Define): Extract all the members
- before populating and emit the warning 108 (new keyword required
- to override) instead of having each member implement this.
-
- (MemberCore.Define): New abstract method, we will be using this in
- the warning reporting engine in Populate.
-
- (Operator.Define): Adjust to new MemberCore protocol.
-
- * const.cs (Const): This does not derive from Expression, it is a
- temporary object we use to create fields, it is a MemberCore.
-
- * class.cs (Method.Define): Allow the entry point to be in a
- specific class.
-
- * driver.cs: Rewrite the argument handler to clean it up a bit.
-
- * rootcontext.cs: Made it just an auxiliary namespace feature by
- making everything static.
-
- * driver.cs: Adapt code to use RootContext type name instead of
- instance variable.
-
- * delegate.cs: Remove RootContext argument.
-
- * class.cs: (Struct, TypeContainer, Class): Remove RootContext
- argument.
-
- * class.cs (Event.Define): The lookup can fail.
-
- * cs-tokenizer.cs: Begin implementation of pre-procesor.
-
- * expression.cs: Resolve the this instance before invoking the code.
-
-2001-12-17 Miguel de Icaza <miguel@ximian.com>
-
- * cs-parser.jay: Add a production in element_access that allows
- the thing to become a "type" reference. This way we can parse
- things like "(string [])" as a type.
-
- Note that this still does not handle the more complex rules of
- casts.
-
-
- * delegate.cs (Delegate.Populate): Register the delegage constructor builder here.
-
- * ecore.cs: (CopyNewMethods): new utility function used to
- assemble the list of methods from running FindMembers.
-
- (MemberLookup): Rework FindMembers so that
-
-2001-12-16 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (TypeContainer): Remove Delegates who fail to be
- defined.
-
- * delegate.cs (Populate): Verify that we dont get null return
- values. TODO: Check for AsAccessible.
-
- * cs-parser.jay: Use basename to emit error 574 (destructor should
- have the same name as container class), not the full name.
-
- * cs-tokenizer.cs (adjust_int): Fit the integer in the best
- possible representation.
-
- Also implements integer type suffixes U and L.
-
-2001-12-15 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (ArrayCreation.DoResolve): We need to do the
- argument resolution *always*.
-
- * decl.cs: Make this hold the namespace. Hold the root context as
- well.
- (LookupType): Move here.
-
- * enum.cs, class.cs, interface.cs: Adapt to new hierarchy.
-
- * location.cs (Row, Name): Fixed the code, it was always returning
- references to the first file.
-
- * interface.cs: Register properties defined through interfaces.
-
- * driver.cs: Add support for globbing on the command line
-
- * class.cs (Field): Make it derive from MemberCore as well.
- (Event): ditto.
-
-2001-12-15 Ravi Pratap <ravi@ximian.com>
-
- * class.cs (Event::Define): Check that the type of the event is a delegate
- type else flag error #66.
-
- Also, re-use TypeContainer.MethodModifiersValid here too as the rules are the
- same.
-
- * attribute.cs (DefinePInvokeMethod): Handle named arguments and process
- values of EntryPoint, CharSet etc etc.
-
- Pass in the values to TypeBuilder.DefinePInvokeMethod; determine Type etc neatly.
-
- * class.cs (FindMembers): If a method is in transit, its MethodBuilder will
- be null and we should ignore this. I am not sure if this is really clean. Apparently,
- there's no way of avoiding hitting this because the call is coming from SimpleName.DoResolve,
- which needs this to do its work.
-
- * ../errors/cs0066.cs : Add.
-
-2001-12-14 Miguel de Icaza <miguel@ximian.com>
-
- * typemanager.cs: (GetPropertyGetter, GetPropertyGetter): New
- helper functions.
-
- * class.cs: (MethodSignature.MethodSignature): Removed hack that
- clears out the parameters field.
- (MemberSignatureCompare): Cleanup
-
- (MemberCore): New base class used to share code between MethodCore
- and Property.
-
- (RegisterRequiredImplementations) BindingFlags.Public requires
- either BindingFlags.Instace or Static. Use instance here.
-
- (Property): Refactored code to cope better with the full spec.
-
- * parameter.cs (GetParameterInfo): Return an empty array instead
- of null on error.
-
- * class.cs (Property): Abstract or extern properties have no bodies.
-
- * parameter.cs (GetParameterInfo): return a zero-sized array.
-
- * class.cs (TypeContainer.MethodModifiersValid): Move all the
- method modifier validation to the typecontainer so we can reuse
- this on properties.
-
- (MethodCore.ParameterTypes): return an empty sized array of types.
-
- (Property.Define): Test property modifier validity.
-
- Add tests for sealed/override too.
-
- (Method.Emit): abstract or extern methods have no bodies.
-
-2001-12-14 Ravi Pratap <ravi@ximian.com>
-
- * class.cs (Method.IsPInvoke): Get rid of it as it is an expensive
- thing.
-
- (Method::Define, ::Emit): Modify accordingly.
-
- * expression.cs (Invocation::OverloadResolve): Handle error # 121.
-
- (ArrayCreation::MakeByteBlob): Handle floats and doubles.
-
- * makefile: Pass in /unsafe.
-
-2001-12-13 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (MakeKey): Kill routine.
-
- * class.cs (TypeContainer.Define): Correctly define explicit
- method implementations (they require the full interface name plus
- the method name).
-
- * typemanager.cs: Deply the PtrHashtable here and stop using the
- lame keys. Things work so much better.
-
- This of course broke everyone who depended on `RegisterMethod' to
- do the `test for existance' test. This has to be done elsewhere.
-
- * support.cs (PtrHashtable): A hashtable that avoid comparing with
- the object stupid Equals method (because, that like fails all over
- the place). We still do not use it.
-
- * class.cs (TypeContainer.SetRequiredInterface,
- TypeContainer.RequireMethods): Killed these two routines and moved
- all the functionality to RegisterRequiredImplementations.
-
- (TypeContainer.RegisterRequiredImplementations): This routine now
- registers all the implementations required in an array for the
- interfaces and abstract methods. We use an array of structures
- which can be computed ahead of time to reduce memory usage and we
- also assume that lookups are cheap as most classes will not
- implement too many interfaces.
-
- We also avoid creating too many MethodSignatures.
-
- (TypeContainer.IsInterfaceMethod): Update and optionally does not
- clear the "pending" bit if we find that there are problems with
- the declaration.
-
- (TypeContainer.VerifyPendingMethods): Update to report errors of
- methods that look like implementations but are not.
-
- (TypeContainer.Define): Add support for explicit interface method
- implementation.
-
-2001-12-12 Miguel de Icaza <miguel@ximian.com>
-
- * typemanager.cs: Keep track of the parameters here instead of
- being a feature of the TypeContainer.
-
- * class.cs: Drop the registration of parameters here, as
- InterfaceMethods are also interface declarations.
-
- * delegate.cs: Register methods with the TypeManager not only with
- the TypeContainer. This code was buggy.
-
- * interface.cs: Full registation here.
-
-2001-12-11 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs: Remove reducer for binary expressions, it can not
- be done this way.
-
- * const.cs: Put here the code that used to go into constant.cs
-
- * constant.cs: Put here the code for constants, this is a new base
- class for Literals.
-
- * literal.cs: Make Literal derive from Constant.
-
-2001-12-09 Miguel de Icaza <miguel@ximian.com>
-
- * statement.cs (Return.Emit): Report error 157 if the user
- attempts to return from a finally block.
-
- (Return.Emit): Instead of emitting a return, jump to the end of
- the function.
-
- * codegen.cs (EmitContext): ReturnValue, ReturnLabel: new
- LocalBuilder to store the result of the function. ReturnLabel is
- the target where we jump.
-
-
-2001-12-09 Radek Doulik <rodo@ximian.com>
-
- * cs-parser.jay: remember alias in current namespace
-
- * ecore.cs (SimpleName::DoResolve): use aliases for types or
- namespaces
-
- * class.cs (LookupAlias): lookup alias in my_namespace
-
- * namespace.cs (UsingAlias): add alias, namespace_or_type pair to
- aliases hashtable
- (LookupAlias): lookup alias in this and if needed in parent
- namespaces
-
-2001-12-08 Miguel de Icaza <miguel@ximian.com>
-
- * support.cs:
-
- * rootcontext.cs: (ModuleBuilder) Made static, first step into
- making things static. I need this to avoid passing the
- TypeContainer when calling ParameterType.
-
- * support.cs (InternalParameters.ParameterType): Remove ugly hack
- that did string manipulation to compute the type and then call
- GetType. Use Parameter.ParameterType instead.
-
- * cs-tokenizer.cs: Consume the suffix for floating values.
-
- * expression.cs (ParameterReference): figure out whether this is a
- reference parameter or not. Kill an extra variable by computing
- the arg_idx during emission.
-
- * parameter.cs (Parameters.GetParameterInfo): New overloaded
- function that returns whether a parameter is an out/ref value or not.
-
- (Parameter.ParameterType): The type of the parameter (base,
- without ref/out applied).
-
- (Parameter.Resolve): Perform resolution here.
- (Parameter.ExternalType): The full type (with ref/out applied).
-
- * statement.cs (Using.Emit, Using.EmitExpression): Implement
- support for expressions on the using statement.
-
-2001-12-07 Miguel de Icaza <miguel@ximian.com>
-
- * statement.cs (Using.EmitLocalVariableDecls): Split the
- localvariable handling of the using statement.
-
- (Block.EmitMeta): Keep track of variable count across blocks. We
- were reusing slots on separate branches of blocks.
-
- (Try.Emit): Emit the general code block, we were not emitting it.
-
- Check the type of the declaration to be an IDisposable or
- something that can be implicity converted to it.
-
- Emit conversions if required.
-
- * ecore.cs (EmptyExpression): New utility class.
- (Expression.ImplicitConversionExists): New utility function.
-
-2001-12-06 Miguel de Icaza <miguel@ximian.com>
-
- * statement.cs (Using): Implement.
-
- * expression.cs (LocalVariableReference): Support read only variables.
-
- * statement.cs: Remove the explicit emit for the Leave opcode.
- (VariableInfo): Add a readonly field.
-
-2001-12-05 Miguel de Icaza <miguel@ximian.com>
-
- * ecore.cs (ConvCast): new class used to encapsulate the various
- explicit integer conversions that works in both checked and
- unchecked contexts.
-
- (Expression.ConvertNumericExplicit): Use new ConvCast class to
- properly generate the overflow opcodes.
-
-2001-12-04 Miguel de Icaza <miguel@ximian.com>
-
- * statement.cs: The correct type for the EmptyExpression is the
- element_type, not the variable type. Ravi pointed this out.
-
-2001-12-04 Ravi Pratap <ravi@ximian.com>
-
- * class.cs (Method::Define): Handle PInvoke methods specially
- by using DefinePInvokeMethod instead of the usual one.
-
- * attribute.cs (DefinePInvokeMethod): Implement as this is what is called
- above to do the task of extracting information and defining the method.
-
-2001-12-04 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (ArrayCreation::EmitStaticInitializers): Get rid
- of the condition for string type.
-
- (Emit): Move that here.
-
- (ArrayCreation::CheckIndices): Keep string literals in their expression
- form.
-
- (EmitDynamicInitializers): Handle strings appropriately.
-
-2001-12-04 Miguel de Icaza <miguel@ximian.com>
-
- * codegen.cs (EmitContext): Replace multiple variables with a
- single pointer to the current Switch statement.
-
- * statement.cs (GotoDefault, Switch): Adjust to cleaned up
- EmitContext.
-
-2001-12-03 Miguel de Icaza <miguel@ximian.com>
-
- * statement.cs
-
- * statement.cs (GotoDefault), cs-parser.jay: Implement `goto
- default'.
-
- (Foreach.Emit): Foreach on arrays was not setting
- up the loop variables (for break/continue).
-
- (GotoCase): Semi-implented.
-
-2001-12-03 Ravi Pratap <ravi@ximian.com>
-
- * attribute.cs (CheckAttribute): Handle system attributes by using
- Attribute.GetAttributes to examine information we need.
-
- (GetValidPlaces): Same here.
-
- * class.cs (Method::Define): Catch invalid use of extern and abstract together.
-
- * typemanager.cs (dllimport_type): Core type for System.DllImportAttribute.
-
- * class.cs (Method.IsPinvoke): Used to determine if we are a PInvoke method.
-
- (Method::Define): Set appropriate flags if we have a DllImport attribute.
-
- (Method::Emit): Handle the case when we are a PInvoke method.
-
-2001-12-03 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs: Use ResolveWithSimpleName on compound names.
-
-2001-12-02 Ravi Pratap <ravi@ximian.com>
-
- * constant.cs (EmitConstant): Make sure we resolve the associated expression
- before trying to reduce it.
-
- * typemanager.cs (RegisterConstant, LookupConstant): Implement.
-
- * constant.cs (LookupConstantValue): Implement.
-
- (EmitConstant): Use the above in emitting the constant.
-
- * expression.cs (MemberAccess::ResolveMemberAccess): Handle constants
- that are user-defined by doing a LookupConstantValue on them.
-
- (SimpleName::DoResolve): When we have a FieldExpr, cope with constants
- too, like above.
-
-2001-11-29 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (BaseAccess, BaseIndexer): Also split this out.
-
- (BaseAccess.DoResolve): Implement.
-
- (MemberAccess.DoResolve): Split this routine into a
- ResolveMemberAccess routine that can be used independently
-
-2001-11-28 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (Probe, Is, As): Split Probe in two classes Is and
- As that share bits of the implementation. Is returns a boolean,
- while As returns the Type that is being probed.
-
-2001-12-01 Ravi Pratap <ravi@ximian.com>
-
- * enum.cs (LookupEnumValue): Re-write various bits, return an object value
- instead of a Literal - much easier.
-
- (EnumInTransit): Remove - utterly useless :-)
-
- (Populate): Re-write bits - remove duplicate code etc. The code is much neater now.
-
- * expression.cs (MemberLookup): Cope with user-defined enums when they are in transit.
-
- * enum.cs (LookupEnumValue): Auto-compute next values by going down the dependency
- chain when we have no associated expression.
-
-2001-11-30 Ravi Pratap <ravi@ximian.com>
-
- * constant.cs (Define): Use Location while reporting the errror.
-
- Also emit a warning when 'new' is used and there is no inherited
- member to hide.
-
- * enum.cs (EnumInTransit): Used to tell if an enum type is in the process of being
- populated.
-
- (LookupEnumValue): Implement to lookup an enum member's value and define it
- if necessary.
-
- (Populate): Re-write accordingly to use the above routine.
-
-2001-11-27 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (This): Fix prototype for DoResolveLValue to
- override the base class DoResolveLValue.
-
- * cs-parser.cs: Report errors cs574 and cs575 (destructor
- declarations)
-
- * ecore.cs (FieldExpr.EmitAssign): Handle value types specially
- (we need to load the address of the field here). This fixes
- test-22.
-
- (FieldExpr.DoResolveLValue): Call the DoResolve
- function to initialize the Instance expression.
-
- * statement.cs (Foreach.Emit): Fix the bug where we did not invoke
- correctly the GetEnumerator operation on a value type.
-
- * cs-parser.jay: Add more simple parsing error catches.
-
- * statement.cs (Switch): Add support for string switches.
- Handle null specially.
-
- * literal.cs (NullLiteral): Make NullLiteral objects singletons.
-
-2001-11-28 Ravi Pratap <ravi@ximian.com>
-
- * cs-parser.jay (local_constant_declaration): Use declare_local_constant.
-
- (declare_local_constant): New helper function.
-
- * statement.cs (AddConstant): Keep a separate record of constants
-
- (IsConstant): Implement to determine if a variable is a constant.
-
- (GetConstantExpression): Implement.
-
- * expression.cs (LocalVariableReference): Handle the case when it is a constant.
-
- * statement.cs (IsVariableDefined): Re-write.
-
-2001-11-27 Ravi Pratap <ravi@ximian.com>
-
- * class.cs (TypeContainer::FindMembers): Look for constants
- in the case when we are looking for MemberTypes.Field
-
- * expression.cs (MemberAccess::DoResolve): Check that in the
- case we are a FieldExpr and a Literal, we are not being accessed
- by an instance reference.
-
- * cs-parser.jay (local_constant_declaration): Implement.
-
- (declaration_statement): Implement for constant declarations.
-
-2001-11-26 Miguel de Icaza <miguel@ximian.com>
-
- * statement.cs (Switch): Catch double defaults.
-
- (Switch): More work on the switch() statement
- implementation. It works for integral values now, need to finish
- string support.
-
-
-2001-11-24 Miguel de Icaza <miguel@ximian.com>
-
- * ecore.cs (Expression.ConvertIntLiteral): New function to convert
- integer literals into other integer literals. To be used by
- switch.
-
-2001-11-24 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (ArrayCreation): Get rid of ArrayExprs : we save
- some memory.
-
- (EmitDynamicInitializers): Cope with the above since we extract data
- directly from ArrayData now.
-
- (ExpectInitializers): Keep track of whether initializers are mandatory
- or not.
-
- (Bounds): Make it a hashtable to prevent the same dimension being
- recorded for every element in that dimension.
-
- (EmitDynamicInitializers): Fix bug which prevented the Set array method
- from being found.
-
- Also fix bug which was causing the indices to be emitted in the reverse
- order.
-
-2001-11-24 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (ArrayCreation): Implement the bits that Ravi left
- unfinished. They do not work, because the underlying code is
- sloppy.
-
-2001-11-22 Miguel de Icaza <miguel@ximian.com>
-
- * cs-parser.jay: Remove bogus fixme.
-
- * statement.cs (Switch, SwitchSection, SwithLabel): Started work
- on Switch statement.
-
-2001-11-23 Ravi Pratap <ravi@ximian.com>
-
- * typemanager.cs (IsDelegateType, IsEnumType): Fix logic to determine
- the same.
-
- * expression.cs (ArrayCreation::CheckIndices): Get rid of the require_constant
- parameter. Apparently, any expression is allowed.
-
- (ValidateInitializers): Update accordingly.
-
- (CheckIndices): Fix some tricky bugs thanks to recursion.
-
- * delegate.cs (NewDelegate::DoResolve): Re-write large portions as
- I was being completely brain-dead.
-
- (VerifyMethod, VerifyApplicability, VerifyDelegate): Make static
- and re-write acordingly.
-
- (DelegateInvocation): Re-write accordingly.
-
- * expression.cs (ArrayCreation::Emit): Handle string initialization separately.
-
- (MakeByteBlob): Handle types more correctly.
-
- * expression.cs (ArrayCreation:Emit): Write preliminary code to do
- initialization from expressions but it is incomplete because I am a complete
- Dodo :-|
-
-2001-11-22 Miguel de Icaza <miguel@ximian.com>
-
- * statement.cs (If.Emit): Fix a bug that generated incorrect code
- on If. Basically, we have to return `true' (ie, we do return to
- our caller) only if both branches of the if return.
-
- * expression.cs (Binary.Emit): LogicalOr and LogicalAnd are
- short-circuit operators, handle them as short circuit operators.
-
- (Cast.DoResolve): Resolve type.
- (Cast.Cast): Take an expression as the target type.
-
- * cs-parser.jay (cast_expression): Remove old hack that only
- allowed a limited set of types to be handled. Now we take a
- unary_expression and we resolve to a type during semantic
- analysis.
-
- Use the grammar productions from Rhys to handle casts (this is
- not complete like Rhys syntax yet, we fail to handle that corner
- case that C# has regarding (-x), but we will get there.
-
-2001-11-22 Ravi Pratap <ravi@ximian.com>
-
- * class.cs (EmitFieldInitializer): Take care of the case when we have a
- field which is an array type.
-
- * cs-parser.jay (declare_local_variables): Support array initialization too.
-
- * typemanager.cs (MakeKey): Implement.
-
- (everywhere): Use the above appropriately.
-
- * cs-parser.jay (for_statement): Update for array initialization while
- declaring variables.
-
- * ecore.cs : The error message was correct, it's the variable's names that
- were misleading ;-) Make the code more readable.
-
- (MemberAccess::DoResolve): Fix the code which handles Enum literals to set
- the correct type etc.
-
- (ConvertExplicit): Handle Enum types by examining the underlying type.
-
-2001-11-21 Ravi Pratap <ravi@ximian.com>
-
- * parameter.cs (GetCallingConvention): Always return
- CallingConventions.Standard for now.
-
-2001-11-22 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (Binary.ResolveOperator): Update the values of `l'
- and `r' after calling DoNumericPromotions.
-
- * ecore.cs: Fix error message (the types were in the wrong order).
-
- * statement.cs (Foreach.ProbeCollectionType): Need to pass
- BindingFlags.Instance as well
-
- * ecore.cs (Expression.TryImplicitIntConversion): Wrap the result
- implicit int literal conversion in an empty cast so that we
- propagate the right type upstream.
-
- (UnboxCast): new class used to unbox value types.
- (Expression.ConvertExplicit): Add explicit type conversions done
- by unboxing.
-
- (Expression.ImplicitNumericConversion): Oops, forgot to test for
- the target type before applying the implicit LongLiterals to ULong
- literal cast.
-
-2001-11-21 Miguel de Icaza <miguel@ximian.com>
-
- * cs-parser.jay (for_statement): Reworked the way For works: now
- we declare manually any variables that are introduced in
- for_initializer to solve the problem of having out-of-band code
- emition (that is what got for broken).
-
- (declaration_statement): Perform the actual variable declaration
- that used to be done in local_variable_declaration here.
-
- (local_variable_declaration): Do not declare anything, just pass
- the information on a DictionaryEntry
-
-2001-11-20 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (ArrayCreation::CheckIndices): The story continues :-) Complete
- re-write of the logic to now make it recursive.
-
- (UpdateIndices): Re-write accordingly.
-
- Store element data in a separate ArrayData list in the above methods.
-
- (MakeByteBlob): Implement to dump the array data into a byte array.
-
-2001-11-19 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (ArrayCreation): Factor out some code from ValidateInitializers
- into CheckIndices.
-
- * constant.cs (Define): Implement.
-
- (EmitConstant): Re-write fully.
-
- Pass in location info.
-
- * class.cs (Populate, Emit): Call Constant::Define and Constant::EmitConstant
- respectively.
-
- * cs-parser.jay (constant_declarator): Use VariableDeclaration instead of
- DictionaryEntry since we need location info too.
-
- (constant_declaration): Update accordingly.
-
- * expression.cs (ArrayCreation): Make ValidateInitializers simpler by factoring
- code into another method : UpdateIndices.
-
-2001-11-18 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (ArrayCreation::ValidateInitializers): Update to perform
- some type checking etc.
-
-2001-11-17 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (ArrayCreation::ValidateInitializers): Implement
- bits to provide dimension info if the user skips doing that.
-
- Update second constructor to store the rank correctly.
-
-2001-11-16 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (ArrayCreation::ValidateInitializers): Poke around
- and try to implement.
-
- * ../errors/cs0150.cs : Add.
-
- * ../errors/cs0178.cs : Add.
-
-2001-11-16 Miguel de Icaza <miguel@ximian.com>
-
- * statement.cs: Implement foreach on multi-dimensional arrays.
-
- * parameter.cs (Parameters.GetParameterByName): Also lookup the
- name of the params argument.
-
- * expression.cs: Use EmitStoreOpcode to get the right opcode while
- initializing the array.
-
- (ArrayAccess.EmitStoreOpcode): move the opcode generation here, so
- we can use this elsewhere.
-
- * statement.cs: Finish implementation of foreach for single
- dimension arrays.
-
- * cs-parser.jay: Use an out-of-band stack to pass information
- around, I wonder why I need this.
-
- foreach_block: Make the new foreach_block the current_block.
-
- * parameter.cs (Parameters.GetEmptyReadOnlyParameters): New
- function used to return a static Parameters structure. Used for
- empty parameters, as those are created very frequently.
-
- * cs-parser.jay, class.cs: Use GetEmptyReadOnlyParameters
-
-2001-11-15 Ravi Pratap <ravi@ximian.com>
-
- * interface.cs : Default modifier is private, not public. The
- make verify test passes again.
-
-2001-11-15 Ravi Pratap <ravi@ximian.com>
-
- * support.cs (ReflectionParameters): Fix logic to determine
- whether the last parameter is a params one. Test 9 passes again.
-
- * delegate.cs (Populate): Register the builders we define with
- RegisterParameterForBuilder. Test 19 passes again.
-
- * cs-parser.jay (property_declaration): Reference $6 instead
- of $$ to get at the location.
-
- (indexer_declaration): Similar stuff.
-
- (attribute): Ditto.
-
- * class.cs (Property): Register parameters for the Get and Set methods
- if they exist. Test 23 passes again.
-
- * expression.cs (ArrayCreation::Emit): Pass null for the method in the
- call to EmitArguments as we are sure there aren't any params arguments.
- Test 32 passes again.
-
- * suppor.cs (ParameterDesc, ParameterModifier): Fix trivial bug causing
- IndexOutOfRangeException.
-
- * class.cs (Property::Define): Register property using TypeManager.RegisterProperty
- Test 33 now passes again.
-
-2001-11-15 Miguel de Icaza <miguel@ximian.com>
-
- * cs-parser.jay: Kill horrendous hack ($??? = lexer.Location) that
- broke a bunch of things. Will have to come up with a better way
- of tracking locations.
-
- * statement.cs: Implemented foreach for single dimension arrays.
-
-2001-11-09 Miguel de Icaza <miguel@ximian.com>
-
- * enum.cs (Enum.Emit): Delay the lookup of loc until we run into
- an error. This removes the lookup from the critical path.
-
- * cs-parser.jay: Removed use of temporary_loc, which is completely
- broken.
-
-2001-11-14 Miguel de Icaza <miguel@ximian.com>
-
- * support.cs (ReflectionParameters.ParameterModifier): Report
- whether the argument is a PARAMS argument or not.
-
- * class.cs: Set the attribute `ParamArrayAttribute' on the
- parameter argument.
-
- * typemanager.cs: Define param_array_type (ParamArrayAttribute)
- and cons_param_array_attribute (ConstructorInfo for
- ParamArrayAttribute).,
-
- * codegen.cs: Emit the return using the `Return' statement, that
- way we can report the error correctly for missing return values.
-
- * class.cs (Method.Emit): Clean up.
-
- * expression.cs (Argument.Resolve): Take another argument: the
- location where this argument is used. Notice that this is not
- part of the "Argument" class as to reduce the size of the
- structure (we know the approximate location anyways).
-
- Test if the argument is a variable-reference, if not, then
- complain with a 206.
-
- (Argument.Emit): Emit addresses of variables.
-
- (Argument.FullDesc): Simplify.
-
- (Invocation.DoResolve): Update for Argument.Resolve.
-
- (ElementAccess.DoResolve): ditto.
-
- * delegate.cs (DelegateInvocation.Emit): Invocation of Invoke
- method should be virtual, as this method is always virtual.
-
- (NewDelegate.DoResolve): Update for Argument.Resolve.
-
- * class.cs (ConstructorInitializer.DoResolve): ditto.
-
- * attribute.cs (Attribute.Resolve): ditto.
-
-2001-11-13 Miguel de Icaza <miguel@ximian.com>
-
- * statement.cs (Foreach.Emit): Use EmitAssign instead of Store.
-
- * expression.cs (ParameterReference): Drop IStackStorage and implement
- IAssignMethod instead.
-
- (LocalVariableReference): ditto.
-
- * ecore.cs (FieldExpr): Drop IStackStorage and implement
- IAssignMethod instead.
-
-2001-11-13 Miguel de Icaza <miguel@ximian.com>
-
- * parameter.cs, expression.cs, class.cs, ecore.cs: Made all
- enumerations that are used in heavily used structures derive from
- byte in a laughable and pathetic attempt to reduce memory usage.
- This is the kind of pre-optimzations that you should not do at
- home without adult supervision.
-
- * expression.cs (UnaryMutator): New class, used to handle ++ and
- -- separatedly from the other unary operators. Cleans up the
- code, and kills the ExpressionStatement dependency in Unary.
-
- (Unary): Removed `method' and `Arguments' from this class, making
- it smaller, and moving it all to SimpleCall, so I can reuse this
- code in other locations and avoid creating a lot of transient data
- strucutres when not required.
-
- * cs-parser.jay: Adjust for new changes.
-
-2001-11-11 Miguel de Icaza <miguel@ximian.com>
-
- * enum.cs (Enum.Populate): If there is a failure during
- definition, return
-
- * cs-parser.jay (opt_enum_base): we used to catch type errors
- here, but this is really incorrect. The type error should be
- catched during semantic analysis.
-
-2001-12-11 Ravi Pratap <ravi@ximian.com>
-
- * cs-parser.jay (operator_declarator, conversion_operator_declarator): Set
- current_local_parameters as expected since I, in my stupidity, had forgotten
- to do this :-)
-
- * attribute.cs (GetValidPlaces): Fix stupid bug.
-
- * class.cs (Method::Emit): Perform check on applicability of attributes.
-
- (Constructor::Emit): Ditto.
-
- (Field::Emit): Ditto.
-
- (Field.Location): Store location information.
-
- (Property, Event, Indexer, Operator): Ditto.
-
- * cs-parser.jay (field_declaration): Pass in location for each field.
-
- * ../errors/cs0592.cs : Add.
-
-2001-11-12 Ravi Pratap <ravi@ximian.com>
-
- * typemanager.cs (attribute_usage_type): New static member for System.AttributeUsage.
-
- (InitCoreTypes): Update accordingly.
-
- (RegisterAttrType, LookupAttr): Implement.
-
- * attribute.cs (Attribute.Targets, AllowMultiple, Inherited): New fields to hold
- info about the same.
-
- (Resolve): Update to populate the above as necessary.
-
- (Error592): Helper.
-
- (GetValidPlaces): Helper to the above.
-
- (CheckAttribute): Implement to perform validity of attributes on declarative elements.
-
- * class.cs (TypeContainer::Emit): Update attribute emission code to perform checking etc.
-
-2001-11-12 Ravi Pratap <ravi@ximian.com>
-
- * attribute.cs (Attribute::Resolve): Expand to handle named arguments too.
-
- * ../errors/cs0617.cs : Add.
-
-2001-11-11 Ravi Pratap <ravi@ximian.com>
-
- * enum.cs (Emit): Rename to Populate to be more consistent with what
- we expect it to do and when exactly it is called.
-
- * class.cs, rootcontext.cs : Update accordingly.
-
- * typemanager.cs (RegisterField, GetValue): Workarounds for the fact that
- FieldInfo.GetValue does not work on dynamic types ! S.R.E lameness strikes again !
-
- * enum.cs (Populate): Register fields with TypeManager.RegisterField.
-
- * expression.cs (MemberAccess.DoResolve): Adjust code to obtain the value
- of a fieldinfo using the above, when dealing with a FieldBuilder.
-
-2001-11-10 Ravi Pratap <ravi@ximian.com>
-
- * ../errors/cs0031.cs : Add.
-
- * ../errors/cs1008.cs : Add.
-
- * ../errrors/cs0543.cs : Add.
-
- * enum.cs (DefineEnum): Check the underlying type and report an error if not a valid
- enum type.
-
- (FindMembers): Implement.
-
- * typemanager.cs (FindMembers): Re-write to call the appropriate methods for
- enums and delegates too.
-
- (enum_types): Rename to builder_to_enum.
-
- (delegate_types): Rename to builder_to_delegate.
-
- * delegate.cs (FindMembers): Implement.
-
-2001-11-09 Ravi Pratap <ravi@ximian.com>
-
- * typemanager.cs (IsEnumType): Implement.
-
- * enum.cs (Emit): Re-write parts to account for the underlying type
- better and perform checking etc.
-
- (GetNextDefaultValue): Helper to ensure we don't overshoot max value
- of the underlying type.
-
- * literal.cs (GetValue methods everywhere): Perform bounds checking and return
- value
-
- * enum.cs (error31): Helper to report error #31.
-
- * cs-parser.jay (enum_declaration): Store location of each member too.
-
- * enum.cs (member_to_location): New hashtable.
-
- (AddEnumMember): Update location hashtable.
-
- (Emit): Use the location of each member while reporting errors.
-
-2001-11-09 Miguel de Icaza <miguel@ximian.com>
-
- * cs-parser.jay: A for_initializer if is a
- local_variable_declaration really ammount to have an implicit
- block with the variable declaration and no initializer for for.
-
- * statement.cs (For.Emit): Cope with null initializers.
-
- This fixes the infinite loop on for initializers.
-
-2001-11-08 Miguel de Icaza <miguel@ximian.com>
-
- * enum.cs: More cleanup.
-
- * ecore.cs: Remove dead code.
-
- * class.cs (Property.Emit): More simplification.
- (Event.Emit): ditto.
-
- Reworked to have less levels of indentation.
-
-2001-11-08 Ravi Pratap <ravi@ximian.com>
-
- * class.cs (Property): Emit attributes.
-
- (Field): Ditto.
-
- (Event): Ditto.
-
- (Indexer): Ditto.
-
- (Operator): Ditto.
-
- * enum.cs (Emit): Ditto.
-
- * rootcontext.cs (ResolveTree, EmitCode, CloseTypes): Do the same for
- Enums too.
-
- * class.cs (Field, Event, etc.): Move attribute generation into the
- Emit method everywhere.
-
- * enum.cs (Enum): Revamp to use the same definition semantics as delegates so
- we have a DefineEnum, CloseEnum etc. The previous way of doing things was not right
- as we had no way of defining nested enums !
-
- * rootcontext.cs : Adjust code accordingly.
-
- * typemanager.cs (AddEnumType): To keep track of enum types separately.
-
-2001-11-07 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (EvalConstantExpression): Move into ecore.cs
-
- * enum.cs (Enum): Rename some members and make them public and readonly
- according to our convention.
-
- * modifiers.cs (EnumAttr): Implement as we need to set only visibility flags,
- nothing else.
-
- * enum.cs (Enum::Define): Use the above instead of TypeAttr.
-
- (Enum::Emit): Write a simple version for now which doesn't try to compute
- expressions. I shall modify this to be more robust in just a while.
-
- * class.cs (TypeContainer::Emit): Make sure we include Enums too.
-
- (TypeContainer::CloseType): Create the Enum types too.
-
- * attribute.cs (Resolve): Use the new Reduce method instead of EvalConstantExpression.
-
- * expression.cs (EvalConstantExpression): Get rid of completely.
-
- * enum.cs (Enum::Emit): Use the new expression reducer. Implement assigning
- user-defined values and other cases.
-
- (IsValidEnumLiteral): Helper function.
-
- * expression.cs (ExprClassfromMemberInfo): Modify to not do any literalizing
- out there in the case we had a literal FieldExpr.
-
- (MemberAccess:DoResolve): Do the literalizing of the FieldExpr here.
-
- (Literalize): Revamp a bit to take two arguments.
-
- (EnumLiteral): New class which derives from Literal to wrap enum literals.
-
-2001-11-06 Ravi Pratap <ravi@ximian.com>
-
- * cs-parser.jay (compilation_unit): Remove extra opt_attributes for now.
-
- * expression.cs (ArrayCreation::ValidateInitializers): Implement.
-
- (Resolve): Use the above to ensure we have proper initializers.
-
-2001-11-05 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (Expression::EvalConstantExpression): New method to
- evaluate constant expressions.
-
- * attribute.cs (Attribute::Resolve): Modify bits to use the above function.
-
-2001-11-07 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (ArrayCreation.Emit): Some bits to initialize data
- in an array.
-
- (Binary.ResolveOperator): Handle operator != (object a, object b)
- and operator == (object a, object b);
-
- (Binary.DoNumericPromotions): Indicate whether the numeric
- promotion was possible.
-
- (ArrayAccess.DoResolve, ArrayAccess.Emit, ArrayAccess.EmitAssign):
- Implement.
-
- Made the ArrayAccess implement interface IAssignMethod instead of
- IStackStore as the order in which arguments are passed reflects
- this.
-
- * assign.cs: Instead of using expr.ExprClass to select the way of
- assinging, probe for the IStackStore/IAssignMethod interfaces.
-
- * typemanager.cs: Load InitializeArray definition.
-
- * rootcontext.cs (RootContext.MakeStaticData): Used to define
- static data that can be used to initialize arrays.
-
-2001-11-05 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs: Handle operator== and operator!= for booleans.
-
- (Conditioal.Reduce): Implement reducer for the ?: operator.
-
- (Conditional.Resolve): Implement dead code elimination.
-
- (Binary.Resolve): Catch string literals and return a new
- concatenated string.
-
- (Unary.Reduce): Implement reduction of unary expressions.
-
- * ecore.cs: Split out the expression core handling here.
-
- (Expression.Reduce): New method used to perform constant folding
- and CSE. This is needed to support constant-expressions.
-
- * statement.cs (Statement.EmitBoolExpression): Pass true and false
- targets, and optimize for !x.
-
-2001-11-04 Ravi Pratap <ravi@ximian.com>
-
- * attribute.cs (Attribute::Resolve): Implement guts. Note that resolution
- of an attribute gives us a CustomAttributeBuilder which we use accordingly to
- set custom atttributes.
-
- * literal.cs (Literal::GetValue): New abstract method to return the actual
- value of the literal, cast as an object.
-
- (*Literal): Implement GetValue method.
-
- * cs-parser.jay (positional_argument_list, named_argument_list): Add not just plain
- expressions to the arraylist but objects of type Argument.
-
- * class.cs (TypeContainer::Emit): Emit our attributes too.
-
- (Method::Emit, Constructor::Emit): Ditto.
-
- * cs-parser.jay (constructor_declaration): Set attributes too, which we seemed
- to be ignoring earlier.
-
-2001-11-03 Ravi Pratap <ravi@ximian.com>
-
- * attribute.cs (AttributeSection::Define): Implement to do the business
- of constructing a CustomAttributeBuilder.
-
- (Attribute): New trivial class. Increases readability of code.
-
- * cs-parser.jay : Update accordingly.
-
- (positional_argument_list, named_argument_list, named_argument): New rules
-
- (attribute_arguments): Use the above so that we are more correct.
-
-2001-11-02 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (Invocation::IsParamsMethodApplicable): Implement
- to perform all checks for a method with a params parameter.
-
- (Invocation::OverloadResolve): Update to use the above method and therefore
- cope correctly with params method invocations.
-
- * support.cs (InternalParameters::ParameterDesc): Provide a desc for
- params too.
-
- * class.cs (ConstructorInitializer::Resolve): Make sure we look for Non-public
- constructors in our parent too because we can't afford to miss out on
- protected ones ;-)
-
- * attribute.cs (AttributeSection): New name for the class Attribute
-
- Other trivial changes to improve readability.
-
- * cs-parser.jay (opt_attributes, attribute_section etc.): Modify to
- use the new class names.
-
-2001-11-01 Ravi Pratap <ravi@ximian.com>
-
- * class.cs (Method::Define): Complete definition for params types too
-
- (Indexer::Define): Ditto.
-
- * support.cs (InternalParameters::ParameterType, ParameterDesc, ParameterModifier):
- Cope everywhere with a request for info about the array parameter.
-
-2001-11-01 Ravi Pratap <ravi@ximian.com>
-
- * tree.cs (RecordNamespace): Fix up to check for the correct key.
-
- * cs-parser.jay (GetQualifiedIdentifier): New Helper method used in
- local_variable_type to extract the string corresponding to the type.
-
- (local_variable_type): Fixup the action to use the new helper method.
-
- * codegen.cs : Get rid of RefOrOutParameter, it's not the right way to
- go.
-
- * expression.cs : Clean out code which uses the above.
-
-2001-10-31 Ravi Pratap <ravi@ximian.com>
-
- * typemanager.cs (RegisterMethod): Check if we already have an existing key
- and bale out if necessary by returning a false.
-
- (RegisterProperty): Ditto.
-
- * class.cs (everywhere): Check the return value from TypeManager.RegisterMethod
- and print out appropriate error messages.
-
- * interface.cs (everywhere): Ditto.
-
- * cs-parser.jay (property_declaration, event_declaration, indexer_declaration): Pass
- location to constructor.
-
- * class.cs (Property, Event, Indexer): Update accordingly.
-
- * ../errors/cs111.cs : Added.
-
- * expression.cs (Invocation::IsApplicable): New static method to determine applicability
- of a method, as laid down by the spec.
-
- (Invocation::OverloadResolve): Use the above method.
-
-2001-10-31 Ravi Pratap <ravi@ximian.com>
-
- * support.cs (InternalParameters): Get rid of crap taking in duplicate info. We
- now take a TypeContainer and a Parameters object.
-
- (ParameterData): Modify return type of ParameterModifier method to be
- Parameter.Modifier and not a string.
-
- (ReflectionParameters, InternalParameters): Update accordingly.
-
- * expression.cs (Argument::GetParameterModifier): Same here.
-
- * support.cs (InternalParameters::ParameterType): Find a better way of determining
- if we are a ref/out parameter. Actually, the type shouldn't be holding the '&'
- symbol in it at all so maybe this is only for now.
-
-2001-10-30 Ravi Pratap <ravi@ximian.com>
-
- * support.cs (InternalParameters): Constructor now takes an extra argument
- which is the actual Parameters class.
-
- (ParameterDesc): Update to provide info on ref/out modifiers.
-
- * class.cs (everywhere): Update call to InternalParameters to pass in
- the second argument too.
-
- * support.cs (ParameterData): Add ParameterModifier, which is a method
- to return the modifier info [ref/out etc]
-
- (InternalParameters, ReflectionParameters): Implement the above.
-
- * expression.cs (Argument::ParameterModifier): Similar function to return
- info about the argument's modifiers.
-
- (Invocation::OverloadResolve): Update to take into account matching modifiers
- too.
-
- * class.cs (Indexer::Define): Actually define a Parameter object and put it onto
- a new SetFormalParameters object which we pass to InternalParameters.
-
-2001-10-30 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (NewArray): Merge into the ArrayCreation class.
-
-2001-10-29 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (NewArray): Merge classes NewBuiltinArray and
- NewUserdefinedArray into one as there wasn't much of a use in having
- two separate ones.
-
- * expression.cs (Argument): Change field's name to ArgType from Type.
-
- (Type): New readonly property which returns the proper type, taking into
- account ref/out modifiers.
-
- (everywhere): Adjust code accordingly for the above.
-
- * codegen.cs (EmitContext.RefOrOutParameter): New field to determine
- whether we are emitting for a ref or out parameter.
-
- * expression.cs (Argument::Emit): Use the above field to set the state.
-
- (LocalVariableReference::Emit): Update to honour the flag and emit the
- right stuff.
-
- * parameter.cs (Attributes): Set the correct flags for ref parameters.
-
- * expression.cs (Argument::FullDesc): New function to provide a full desc.
-
- * support.cs (ParameterData): Add method ParameterDesc to the interface.
-
- (ReflectionParameters, InternalParameters): Implement the above method.
-
- * expression.cs (Invocation::OverloadResolve): Use the new desc methods in
- reporting errors.
-
- (Invocation::FullMethodDesc): Ditto.
-
-2001-10-29 Miguel de Icaza <miguel@ximian.com>
-
- * cs-parser.jay: Add extra production for the second form of array
- creation.
-
- * expression.cs (ArrayCreation): Update to reflect the above
- change.
-
- * Small changes to prepare for Array initialization.
-
-2001-10-28 Miguel de Icaza <miguel@ximian.com>
-
- * typemanager.cs (ImplementsInterface): interface might be null;
- Deal with this problem;
-
- Also, we do store negative hits on the cache (null values), so use
- this instead of calling t.GetInterfaces on the type everytime.
-
-2001-10-28 Ravi Pratap <ravi@ximian.com>
-
- * typemanager.cs (IsBuiltinType): New method to help determine the same.
-
- * expression.cs (New::DoResolve): Get rid of array creation code and instead
- split functionality out into different classes.
-
- (New::FormArrayType): Move into NewBuiltinArray.
-
- (Invocation::EmitArguments): Get rid of the MethodBase argument. Appears
- quite useless.
-
- (NewBuiltinArray): New class to handle creation of built-in arrays.
-
- (NewBuiltinArray::DoResolve): Implement guts of array creation. Also take into
- account creation of one-dimensional arrays.
-
- (::Emit): Implement to use Newarr and Newobj opcodes accordingly.
-
- (NewUserdefinedArray::DoResolve): Implement.
-
- * cs-parser.jay (local_variable_type): Fix up to add the rank to the variable too.
-
- * typemanager.cs (AddModule): Used to add a ModuleBuilder to the list of modules
- we maintain inside the TypeManager. This is necessary to perform lookups on the
- module builder.
-
- (LookupType): Update to perform GetType on the module builders too.
-
- * driver.cs (Driver): Add the ModuleBuilder to the list maintained by the TypeManager.
-
- * exprssion.cs (NewUserdefinedArray::Emit): Implement.
-
-2001-10-23 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (New::DoResolve): Implement guts of array creation.
-
- (New::FormLookupType): Rename to FormArrayType and modify ever so slightly.
-
-2001-10-27 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs: Fix bug I introduced lsat night that broke
- Delegates.
-
- (Expression.Resolve): Report a 246 error (can not resolve name)
- if we find a SimpleName in the stream.
-
- (Expression.ResolveLValue): Ditto.
-
- (Expression.ResolveWithSimpleName): This function is a variant of
- ResolveName, this one allows SimpleNames to be returned without a
- warning. The only consumer of SimpleNames is MemberAccess
-
-2001-10-26 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (Invocation::DoResolve): Catch SimpleNames that
- might arrive here. I have my doubts that this is correct.
-
- * statement.cs (Lock): Implement lock statement.
-
- * cs-parser.jay: Small fixes to support `lock' and `using'
-
- * cs-tokenizer.cs: Remove extra space
-
- * driver.cs: New flag --checked, allows to turn on integer math
- checking.
-
- * typemanger.cs: Load methodinfos for Threading.Monitor.Enter and
- Threading.Monitor.Exit
-
-2001-10-23 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (IndexerAccess::DoResolveLValue): Set the
- Expression Class to be IndexerAccess.
-
- Notice that Indexer::DoResolve sets the eclass to Value.
-
-2001-10-22 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (TypeContainer::Emit): Emit code for indexers.
-
- * assign.cs (IAssignMethod): New interface implemented by Indexers
- and Properties for handling assignment.
-
- (Assign::Emit): Simplify and reuse code.
-
- * expression.cs (IndexerAccess, PropertyExpr): Implement
- IAssignMethod, clean up old code.
-
-2001-10-22 Ravi Pratap <ravi@ximian.com>
-
- * typemanager.cs (ImplementsInterface): New method to determine if a type
- implements a given interface. Provides a nice cache too.
-
- * expression.cs (ImplicitReferenceConversion): Update checks to use the above
- method.
-
- (ConvertReferenceExplicit): Ditto.
-
- * delegate.cs (Delegate::Populate): Update to define the parameters on the
- various methods, with correct names etc.
-
- * class.cs (Operator::OpType): New members Operator.UnaryPlus and
- Operator.UnaryNegation.
-
- * cs-parser.jay (operator_declarator): Be a little clever in the case where
- we have a unary plus or minus operator.
-
- * expression.cs (Unary): Rename memebers of Operator enum to UnaryPlus and
- UnaryMinus.
-
- * everywhere : update accordingly.
-
- * everywhere : Change Negate and BitComplement to LogicalNot and OnesComplement
- respectively.
-
- * class.cs (Method::Define): For the case where we are implementing a method
- inherited from an interface, we need to set the MethodAttributes.Final flag too.
- Also set MethodAttributes.NewSlot and MethodAttributes.HideBySig.
-
-2001-10-21 Ravi Pratap <ravi@ximian.com>
-
- * interface.cs (FindMembers): Implement to work around S.R.E
- lameness.
-
- * typemanager.cs (IsInterfaceType): Implement.
-
- (FindMembers): Update to handle interface types too.
-
- * expression.cs (ImplicitReferenceConversion): Re-write bits which
- use IsAssignableFrom as that is not correct - it doesn't work.
-
- * delegate.cs (DelegateInvocation): Derive from ExpressionStatement
- and accordingly override EmitStatement.
-
- * expression.cs (ConvertReferenceExplicit): Re-write similary, this time
- using the correct logic :-)
-
-2001-10-19 Ravi Pratap <ravi@ximian.com>
-
- * ../errors/cs-11.cs : Add to demonstrate error -11
-
-2001-10-17 Miguel de Icaza <miguel@ximian.com>
-
- * assign.cs (Assign::Resolve): Resolve right hand side first, and
- then pass this as a hint to ResolveLValue.
-
- * expression.cs (FieldExpr): Add Location information
-
- (FieldExpr::LValueResolve): Report assignment to readonly
- variable.
-
- (Expression::ExprClassFromMemberInfo): Pass location information.
-
- (Expression::ResolveLValue): Add new method that resolves an
- LValue.
-
- (Expression::DoResolveLValue): Default invocation calls
- DoResolve.
-
- (Indexers): New class used to keep track of indexers in a given
- Type.
-
- (IStackStore): Renamed from LValue, as it did not really describe
- what this did. Also ResolveLValue is gone from this interface and
- now is part of Expression.
-
- (ElementAccess): Depending on the element access type
-
- * typemanager.cs: Add `indexer_name_type' as a Core type
- (System.Runtime.CompilerServices.IndexerNameAttribute)
-
- * statement.cs (Goto): Take a location.
-
-2001-10-18 Ravi Pratap <ravi@ximian.com>
-
- * delegate.cs (Delegate::VerifyDelegate): New method to verify
- if two delegates are compatible.
-
- (NewDelegate::DoResolve): Update to take care of the case when
- we instantiate a delegate from another delegate.
-
- * typemanager.cs (FindMembers): Don't even try to look up members
- of Delegate types for now.
-
-2001-10-18 Ravi Pratap <ravi@ximian.com>
-
- * delegate.cs (NewDelegate): New class to take care of delegate
- instantiation.
-
- * expression.cs (New): Split the delegate related code out into
- the NewDelegate class.
-
- * delegate.cs (DelegateInvocation): New class to handle delegate
- invocation.
-
- * expression.cs (Invocation): Split out delegate related code into
- the DelegateInvocation class.
-
-2001-10-17 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (New::DoResolve): Implement delegate creation fully
- and according to the spec.
-
- (New::DoEmit): Update to handle delegates differently.
-
- (Invocation::FullMethodDesc): Fix major stupid bug thanks to me
- because of which we were printing out arguments in reverse order !
-
- * delegate.cs (VerifyMethod): Implement to check if the given method
- matches the delegate.
-
- (FullDelegateDesc): Implement.
-
- (VerifyApplicability): Implement.
-
- * expression.cs (Invocation::DoResolve): Update to accordingly handle
- delegate invocations too.
-
- (Invocation::Emit): Ditto.
-
- * ../errors/cs1593.cs : Added.
-
- * ../errors/cs1594.cs : Added.
-
- * delegate.cs (InstanceExpression, TargetMethod): New properties.
-
-2001-10-16 Ravi Pratap <ravi@ximian.com>
-
- * typemanager.cs (intptr_type): Core type for System.IntPtr
-
- (InitCoreTypes): Update for the same.
-
- (iasyncresult_type, asynccallback_type): Ditto.
-
- * delegate.cs (Populate): Fix to use System.Intptr as it is indeed
- correct.
-
- * typemanager.cs (AddDelegateType): Store a pointer to the Delegate class
- too.
-
- * delegate.cs (ConstructorBuilder, InvokeBuilder, ...): New members to hold
- the builders for the 4 members of a delegate type :-)
-
- (Populate): Define the BeginInvoke and EndInvoke methods on the delegate
- type.
-
- * expression.cs (New::DoResolve): Implement guts for delegate creation.
-
- * ../errors/errors.txt : Update for an error (-11) which only we catch :-)
-
-2001-10-15 Miguel de Icaza <miguel@ximian.com>
-
- * statement.cs (Break::Emit): Implement.
- (Continue::Emit): Implement.
-
- (For::Emit): Track old being/end loops; Set Begin loop, ack end loop
- (While::Emit): Track old being/end loops; Set Begin loop, ack end loop
- (Do::Emit): Track old being/end loops; Set Begin loop, ack end loop
- (Foreach::Emit): Track old being/end loops; Set Begin loop, ack
- end loop
-
- * codegen.cs (EmitContext::LoopEnd, EmitContext::LoopBegin): New
- properties that track the label for the current loop (begin of the
- loop and end of the loop).
-
-2001-10-15 Ravi Pratap <ravi@ximian.com>
-
- * delegate.cs (Emit): Get rid of it as there doesn't seem to be any ostensible
- use of emitting anything at all.
-
- * class.cs, rootcontext.cs : Get rid of calls to the same.
-
- * delegate.cs (DefineDelegate): Make sure the class we define is also sealed.
-
- (Populate): Define the constructor correctly and set the implementation
- attributes.
-
- * typemanager.cs (delegate_types): New hashtable to hold delegates that
- have been defined.
-
- (AddDelegateType): Implement.
-
- (IsDelegateType): Implement helper method.
-
- * delegate.cs (DefineDelegate): Use AddDelegateType instead of AddUserType.
-
- * expression.cs (New::DoResolve): Check if we are trying to instantiate a delegate type
- and accordingly handle it.
-
- * delegate.cs (Populate): Take TypeContainer argument.
- Implement bits to define the Invoke method. However, I still haven't figured out
- how to take care of the native int bit :-(
-
- * cs-parser.jay (delegate_declaration): Fixed the bug that I had introduced :-)
- Qualify the name of the delegate, not its return type !
-
- * expression.cs (ImplicitReferenceConversion): Implement guts of implicit array
- conversion.
-
- (StandardConversionExists): Checking for array types turns out to be recursive.
-
- (ConvertReferenceExplicit): Implement array conversion.
-
- (ExplicitReferenceConversionExists): New method to determine precisely that :-)
-
-2001-10-12 Ravi Pratap <ravi@ximian.com>
-
- * cs-parser.jay (delegate_declaration): Store the fully qualified
- name as it is a type declaration.
-
- * delegate.cs (ReturnType, Name): Rename members to these. Make them
- readonly.
-
- (DefineDelegate): Renamed from Define. Does the same thing essentially,
- as TypeContainer::DefineType.
-
- (Populate): Method in which all the definition of the various methods (Invoke)
- etc is done.
-
- (Emit): Emit any code, if necessary. I am not sure about this really, but let's
- see.
-
- (CloseDelegate): Finally creates the delegate.
-
- * class.cs (TypeContainer::DefineType): Update to define delegates.
- (Populate, Emit and CloseType): Do the same thing here too.
-
- * rootcontext.cs (ResolveTree, PopulateTypes, EmitCode, CloseTypes): Include
- delegates in all these operations.
-
-2001-10-14 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs: LocalTemporary: a new expression used to
- reference a temporary that has been created.
-
- * assign.cs: Handle PropertyAccess back here, so that we can
- provide the proper semantic access to properties.
-
- * expression.cs (Expression::ConvertReferenceExplicit): Implement
- a few more explicit conversions.
-
- * modifiers.cs: `NEW' modifier maps to HideBySig.
-
- * expression.cs (PropertyExpr): Make this into an
- ExpressionStatement, and support the EmitStatement code path.
-
- Perform get/set error checking, clean up the interface.
-
- * assign.cs: recognize PropertyExprs as targets, and if so, turn
- them into toplevel access objects.
-
-2001-10-12 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs: PropertyExpr::PropertyExpr: use work around the
- SRE.
-
- * typemanager.cs: Keep track here of our PropertyBuilders again to
- work around lameness in SRE.
-
-2001-10-11 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (LValue::LValueResolve): New method in the
- interface, used to perform a second resolution pass for LValues.
-
- (This::DoResolve): Catch the use of this in static methods.
-
- (This::LValueResolve): Implement.
-
- (This::Store): Remove warning, assigning to `this' in structures
- is
-
- (Invocation::Emit): Deal with invocation of
- methods on value types. We need to pass the address to structure
- methods rather than the object itself. (The equivalent code to
- emit "this" for structures leaves the entire structure on the
- stack instead of a pointer to it).
-
- (ParameterReference::DoResolve): Compute the real index for the
- argument based on whether the method takes or not a `this' pointer
- (ie, the method is static).
-
- * codegen.cs (EmitContext::GetTemporaryStorage): Used to store
- value types returned from functions when we need to invoke a
- method on the sturcture.
-
-
-2001-10-11 Ravi Pratap <ravi@ximian.com>
-
- * class.cs (TypeContainer::DefineType): Method to actually do the business of
- defining the type in the Modulebuilder or Typebuilder. This is to take
- care of nested types which need to be defined on the TypeBuilder using
- DefineNestedMethod.
-
- (TypeContainer::GetClassBases): Implement. Essentially the code from the
- methods in RootContext, only ported to be part of TypeContainer.
-
- (TypeContainer::GetInterfaceOrClass): Ditto.
-
- (TypeContainer::LookupInterfaceOrClass, ::MakeFQN): Ditto.
-
- * interface.cs (Interface::DefineInterface): New method. Does exactly
- what RootContext.CreateInterface did earlier, only it takes care of nested types
- too.
-
- (Interface::GetInterfaces): Move from RootContext here and port.
-
- (Interface::GetInterfaceByName): Same here.
-
- * rootcontext.cs (ResolveTree): Re-write.
-
- (PopulateTypes): Re-write.
-
- * class.cs (TypeContainer::Populate): Populate nested types too.
- (TypeContainer::Emit): Emit nested members too.
-
- * typemanager.cs (AddUserType): Do not make use of the FullName property,
- instead just use the name argument passed in as it is already fully
- qualified.
-
- (FindMembers): Check in the Builders to TypeContainer mapping instead of the name
- to TypeContainer mapping to see if a type is user-defined.
-
- * class.cs (TypeContainer::CloseType): Implement.
-
- (TypeContainer::DefineDefaultConstructor): Use Basename, not Name while creating
- the default constructor.
-
- (TypeContainer::Populate): Fix minor bug which led to creating default constructors
- twice.
-
- (Constructor::IsDefault): Fix up logic to determine if it is the default constructor
-
- * interface.cs (CloseType): Create the type here.
-
- * rootcontext.cs (CloseTypes): Re-write to recursively close types by running through
- the hierarchy.
-
- Remove all the methods which are now in TypeContainer.
-
-2001-10-10 Ravi Pratap <ravi@ximian.com>
-
- * delegate.cs (Define): Re-write bits to define the delegate
- correctly.
-
-2001-10-10 Miguel de Icaza <miguel@ximian.com>
-
- * makefile: Renamed the compiler to `mcs.exe' instead of compiler.exe
-
- * expression.cs (ImplicitReferenceConversion): handle null as well
- as a source to convert to any reference type.
-
- * statement.cs (Return): Perform any implicit conversions to
- expected return type.
-
- Validate use of return statement.
-
- * codegen.cs (EmitContext): Pass the expected return type here.
-
- * class.cs (Method, Constructor, Property): Pass expected return
- type to EmitContext.
-
-2001-10-09 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs: Make DoResolve take an EmitContext instead of a
- TypeContainer.
-
- Replaced `l' and `location' for `loc', for consistency.
-
- (Error, Warning): Remove unneeded Tc argument.
-
- * assign.cs, literal.cs, constant.cs: Update to new calling
- convention.
-
- * codegen.cs: EmitContext now contains a flag indicating whether
- code is being generated in a static method or not.
-
- * cs-parser.jay: DecomposeQI, new function that replaces the old
- QualifiedIdentifier. Now we always decompose the assembled
- strings from qualified_identifier productions into a group of
- memberaccesses.
-
-2001-10-08 Miguel de Icaza <miguel@ximian.com>
-
- * rootcontext.cs: Deal with field-less struct types correctly now
- by passing the size option to Define Type.
-
- * class.cs: Removed hack that created one static field.
-
-2001-10-07 Miguel de Icaza <miguel@ximian.com>
-
- * statement.cs: Moved most of the code generation here.
-
-2001-10-09 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (New::DoResolve): Revert changes for array creation, doesn't
- seem very right.
-
- (ElementAccess): Remove useless bits for now - keep checks as the spec
- says.
-
-2001-10-08 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (ElementAccess::DoResolve): Remove my crap code
- and start performing checks according to the spec.
-
-2001-10-07 Ravi Pratap <ravi@ximian.com>
-
- * cs-parser.jay (type_suffix*): Remove - they are redundant. Use
- rank_specifiers instead.
-
- (rank_specifiers): Change the order in which the rank specifiers are stored
-
- (local_variable_declaration): Use opt_rank_specifier instead of type_suffixes.
-
- * expression.cs (ElementAccess): Implement the LValue interface too.
-
-2001-10-06 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (ConvertExplicitStandard): Add. Same as ConvertExplicit
- except that user defined conversions are not included.
-
- (UserDefinedConversion): Update to use the ConvertExplicitStandard to
- perform the conversion of the return type, if necessary.
-
- (New::DoResolve): Check whether we are creating an array or an object
- and accordingly do the needful.
-
- (New::Emit): Same here.
-
- (New::DoResolve): Implement guts of array creation.
-
- (New::FormLookupType): Helper function.
-
-2001-10-07 Miguel de Icaza <miguel@ximian.com>
-
- * codegen.cs: Removed most of the code generation here, and move the
- corresponding code generation bits to the statement classes.
-
- Added support for try/catch/finalize and throw.
-
- * cs-parser.jay: Added support for try/catch/finalize.
-
- * class.cs: Catch static methods having the flags override,
- virtual or abstract.
-
- * expression.cs (UserCast): This user cast was not really doing
- what it was supposed to do. Which is to be born in fully resolved
- state. Parts of the resolution were being performed at Emit time!
-
- Fixed this code.
-
-2001-10-05 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs: Implicity convert the result from UserCast.
-
-2001-10-05 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (Expression::FindMostEncompassingType): Fix bug which
- prevented it from working correctly.
-
- (ConvertExplicit): Make the first try, a call to ConvertImplicitStandard, not
- merely ConvertImplicit.
-
-2001-10-05 Miguel de Icaza <miguel@ximian.com>
-
- * typemanager.cs: Make the LookupTypeContainer function static,
- and not per-instance.
-
- * class.cs: Make static FindMembers (the one that takes a Type
- argument).
-
- * codegen.cs: Add EmitForeach here.
-
- * cs-parser.jay: Make foreach a toplevel object instead of the
- inline expansion, as we need to perform semantic analysis on it.
-
-2001-10-05 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (Expression::ImplicitUserConversion): Rename to
- UserDefinedConversion.
-
- (Expression::UserDefinedConversion): Take an extra argument specifying
- whether we look for explicit user conversions too.
-
- (Expression::ImplicitUserConversion): Make it a call to UserDefinedConversion.
-
- (UserDefinedConversion): Incorporate support for user defined explicit conversions.
-
- (ExplicitUserConversion): Make it a call to UserDefinedConversion
- with the appropriate arguments.
-
- * cs-parser.jay (cast_expression): Record location too.
-
- * expression.cs (Cast): Record location info.
-
- (Expression::ConvertExplicit): Take location argument.
-
- (UserImplicitCast): Change name to UserCast. Take an extra constructor argument
- to determine if we are doing explicit conversions.
-
- (UserCast::Emit): Update accordingly.
-
- (Expression::ConvertExplicit): Report an error if everything fails.
-
- * ../errors/cs0030.cs : Add.
-
-2001-10-04 Miguel de Icaza <miguel@ximian.com>
-
- * modifiers.cs: If the ABSTRACT keyword is present, also set the
- virtual and newslot bits.
-
- * class.cs (TypeContainer::RegisterRequiredImplementations):
- Record methods we need.
-
- (TypeContainer::MakeKey): Helper function to make keys for
- MethodBases, since the Methodbase key is useless.
-
- (TypeContainer::Populate): Call RegisterRequiredImplementations
- before defining the methods.
-
- Create a mapping for method_builders_to_methods ahead of time
- instead of inside a tight loop.
-
- (::RequireMethods): Accept an object as the data to set into the
- hashtable so we can report interface vs abstract method mismatch.
-
-2001-10-03 Miguel de Icaza <miguel@ximian.com>
-
- * report.cs: Make all of it static.
-
- * rootcontext.cs: Drop object_type and value_type computations, as
- we have those in the TypeManager anyways.
-
- Drop report instance variable too, now it is a global.
-
- * driver.cs: Use try/catch on command line handling.
-
- Add --probe option to debug the error reporting system with a test
- suite.
-
- * report.cs: Add support for exiting program when a probe
- condition is reached.
-
-2001-10-03 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (Binary::DoNumericPromotions): Fix the case when
- we do a forcible conversion regardless of type, to check if
- ForceConversion returns a null.
-
- (Binary::error19): Use location to report error.
-
- (Unary::error23): Use location here too.
-
- * ../errors/cs0019.cs : Check in.
-
- * ../errors/cs0023.cs : Check in.
-
- * expression.cs (Expression.MemberLookup): Return null for a rather esoteric
- case of a non-null MethodInfo object with a length of 0 !
-
- (Binary::ResolveOperator): Flag error if overload resolution fails to find
- an applicable member - according to the spec :-)
- Also fix logic to find members in base types.
-
- (Unary::ResolveOperator): Same here.
-
- (Unary::report23): Change name to error23 and make first argument a TypeContainer
- as I was getting thoroughly confused between this and error19 :-)
-
- * expression.cs (Expression::ImplicitUserConversion): Re-write fully
- (::FindMostEncompassedType): Implement.
- (::FindMostEncompassingType): Implement.
- (::StandardConversionExists): Implement.
-
- (UserImplicitCast): Re-vamp. We now need info about most specific
- source and target types so that we can do the necessary conversions.
-
- (Invocation::MakeUnionSet): Completely re-write to make sure we form a proper
- mathematical union with no duplicates.
-
-2001-10-03 Miguel de Icaza <miguel@ximian.com>
-
- * rootcontext.cs (RootContext::PopulateTypes): Populate containers
- in order from base classes to child classes, so that we can in
- child classes look up in our parent for method names and
- attributes (required for handling abstract, virtual, new, override
- constructs: we need to instrospect our base class, and if we dont
- populate the classes in order, the introspection might be
- incorrect. For example, a method could query its parent before
- the parent has any methods and would determine that the parent has
- no abstract methods (while it could have had them)).
-
- (RootContext::CreateType): Record the order in which we define the
- classes.
-
-2001-10-02 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (TypeContainer::Populate): Also method definitions can
- fail now, keep track of this.
-
- (TypeContainer::FindMembers): Implement support for
- DeclaredOnly/noDeclaredOnly flag.
-
- (Constructor::Emit) Return the ConstructorBuilder.
-
- (Method::Emit) Return the MethodBuilder.
- Check for abstract or virtual methods to be public.
-
- * rootcontext.cs (RootContext::CreateType): Register all the
- abstract methods required for the class to be complete and the
- interface methods that must be implemented.
-
- * cs-parser.jay: Report error 501 (method requires body if it is
- not marked abstract or extern).
-
- * expression.cs (TypeOf::Emit): Implement.
-
- * typemanager.cs: runtime_handle_type, new global type.
-
- * class.cs (Property::Emit): Generate code for properties.
-
-2001-10-02 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (Unary::ResolveOperator): Find operators on base type
- too - we now conform exactly to the spec.
-
- (Binary::ResolveOperator): Same here.
-
- * class.cs (Operator::Define): Fix minor quirk in the tests.
-
- * ../errors/cs0215.cs : Added.
-
- * ../errors/cs0556.cs : Added.
-
- * ../errors/cs0555.cs : Added.
-
-2001-10-01 Miguel de Icaza <miguel@ximian.com>
-
- * cs-tokenizer.cs: Reimplemented Location to be a struct with a
- single integer which is really efficient
-
-2001-10-01 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (Expression::ImplicitUserConversion): Use location
- even in the case when we are examining True operators.
-
- * class.cs (Operator::Define): Perform extensive checks to conform
- with the rules for operator overloading in the spec.
-
- * expression.cs (Expression::ImplicitReferenceConversion): Implement
- some of the other conversions mentioned in the spec.
-
- * typemanager.cs (array_type): New static member for the System.Array built-in
- type.
-
- (cloneable_interface): For System.ICloneable interface.
-
- * driver.cs (Driver::Driver): Initialize TypeManager's core types even before
- we start resolving the tree and populating types.
-
- * ../errors/errors.txt : Update for error numbers -7, -8, -9, -10
-
-2001-10-01 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (Expression::ExprClassFromMemberInfo,
- Expression::Literalize): Create literal expressions from
- FieldInfos which are literals.
-
- (ConvertNumericExplicit, ImplicitNumericConversion): Fix a few
- type casts, because they were wrong. The test suite in tests
- caught these ones.
-
- (ImplicitNumericConversion): ushort to ulong requires a widening
- cast.
-
- Int32 constant to long requires widening cast as well.
-
- * literal.cs (LongLiteral::EmitLong): Do not generate i4 constants
- for integers because the type on the stack is not i4.
-
-2001-09-30 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (report118): require location argument.
-
- * parameter.cs: Do not dereference potential null value.
-
- * class.cs: Catch methods that lack the `new' keyword when
- overriding a name. Report warnings when `new' is used without
- anything being there to override.
-
- * modifiers.cs: Handle `NEW' as MethodAttributes.NewSlot.
-
- * class.cs: Only add constructor to hashtable if it is non-null
- (as now constructors can fail on define).
-
- (TypeManager, Class, Struct): Take location arguments.
-
- Catch field instance initialization in structs as errors.
-
- accepting_filter: a new filter for FindMembers that is static so
- that we dont create an instance per invocation.
-
- (Constructor::Define): Catch errors where a struct constructor is
- parameterless
-
- * cs-parser.jay: Pass location information for various new
- constructs.
-
- * delegate.cs (Delegate): take a location argument.
-
- * driver.cs: Do not call EmitCode if there were problesm in the
- Definition of the types, as many Builders wont be there.
-
- * decl.cs (Decl::Decl): Require a location argument.
-
- * cs-tokenizer.cs: Handle properly hex constants that can not fit
- into integers, and find the most appropiate integer for it.
-
- * literal.cs: Implement ULongLiteral.
-
- * rootcontext.cs: Provide better information about the location of
- failure when CreateType fails.
-
-2001-09-29 Miguel de Icaza <miguel@ximian.com>
-
- * rootcontext.cs (RootContext::PopulateTypes): Populates structs
- as well.
-
- * expression.cs (Binary::CheckShiftArguments): Add missing type
- computation.
- (Binary::ResolveOperator): Add type to the logical and and logical
- or, Bitwise And/Or and Exclusive Or code paths, it was missing
- before.
-
- (Binary::DoNumericPromotions): In the case where either argument
- is ulong (and most signed types combined with ulong cause an
- error) perform implicit integer constant conversions as well.
-
-2001-09-28 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (UserImplicitCast): Method should always be
- non-null.
- (Invocation::BetterConversion): Simplified test for IntLiteral.
-
- (Expression::ImplicitNumericConversion): Split this routine out.
- Put the code that performs implicit constant integer conversions
- here.
-
- (Expression::Resolve): Become a wrapper around DoResolve so we can
- check eclass and type being set after resolve.
-
- (Invocation::Badness): Remove this dead function
-
- (Binary::ResolveOperator): Do not compute the expensive argumnets
- unless we have a union for it.
-
- (Probe::Emit): Is needs to do an isinst and then
- compare against null.
-
- (::CanConvert): Added Location argument. If the Location argument
- is null (Location.Null), then we do not report errors. This is
- used by the `probe' mechanism of the Explicit conversion. We do
- not want to generate an error for something that the user
- explicitly requested to be casted. But the pipeline for an
- explicit cast first tests for potential implicit casts.
-
- So for now, if the Location is null, it means `Probe only' to
- avoid adding another argument. Might have to revise this
- strategy later.
-
- (ClassCast): New class used to type cast objects into arbitrary
- classes (used in Explicit Reference Conversions).
-
- Implement `as' as well.
-
- Reverted all the patches from Ravi below: they were broken:
-
- * The use of `level' as a mechanism to stop recursive
- invocations is wrong. That was there just to catch the
- bug with a strack trace but not as a way of addressing
- the problem.
-
- To fix the problem we have to *understand* what is going
- on and the interactions and come up with a plan, not
- just get things going.
-
- * The use of the type conversion cache that I proposed
- last night had an open topic: How does this work across
- protection domains. A user defined conversion might not
- be public in the location where we are applying the
- conversion, a different conversion might be selected
- (ie, private A->B (better) but public B->A (worse),
- inside A, A->B applies, but outside it, B->A will
- apply).
-
- * On top of that (ie, even if the above is solved),
- conversions in a cache need to be abstract. Ie, `To
- convert from an Int to a Short use an OpcodeCast', not
- `To convert from an Int to a Short use the OpcodeCast on
- the variable 5' (which is what this patch was doing).
-
-2001-09-28 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (Invocation::ConversionExists): Re-write to use
- the conversion cache
-
- (Expression::ConvertImplicit): Automatic bailing out if level != 0. Also
- cache all conversions done, not just user-defined ones.
-
- (Invocation::BetterConversion): The real culprit. Use ConversionExists
- to determine if a conversion exists instead of acutually trying to
- perform the conversion. It's faster too.
-
- (Expression::ConvertExplicit): Modify to use ConversionExists to check
- and only then attempt the implicit conversion.
-
-2001-09-28 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (ConvertImplicit): Use a cache for conversions
- already found. Check level of recursion and bail out if necessary.
-
-2001-09-28 Miguel de Icaza <miguel@ximian.com>
-
- * typemanager.cs (string_concat_string_string, string_concat_object_object):
- Export standard methods that we expect for string operations.
-
- * statement.cs (Block::UsageWarning): Track usage of variables and
- report the errors for not used variables.
-
- * expression.cs (Conditional::Resolve, ::Emit): Implement ?:
- operator.
-
-2001-09-27 Miguel de Icaza <miguel@ximian.com>
-
- * codegen.cs: remove unnneded code
-
- * expression.cs: Removed BuiltinTypeAccess class
-
- Fix the order in which implicit conversions are
- done.
-
- The previous fixed dropped support for boxed conversions (adding a
- test to the test suite now)
-
- (UserImplicitCast::CanConvert): Remove test for source being null,
- that code is broken. We should not feed a null to begin with, if
- we do, then we should track the bug where the problem originates
- and not try to cover it up here.
-
- Return a resolved expression of type UserImplicitCast on success
- rather than true/false. Ravi: this is what I was talking about,
- the pattern is to use a static method as a "constructor" for
- objects.
-
- Also, do not create arguments until the very last minute,
- otherwise we always create the arguments even for lookups that
- will never be performed.
-
- (UserImplicitCast::Resolve): Eliminate, objects of type
- UserImplicitCast are born in a fully resolved state.
-
- * typemanager.cs (InitCoreTypes): Init also value_type
- (System.ValueType).
-
- * expression.cs (Cast::Resolve): First resolve the child expression.
-
- (LValue): Add new method AddressOf to be used by
- the `&' operator.
-
- Change the argument of Store to take an EmitContext instead of an
- ILGenerator, because things like FieldExpr need to be able to call
- their children expression to generate the instance code.
-
- (Expression::Error, Expression::Warning): Sugar functions for
- reporting errors.
-
- (Expression::MemberLookup): Accept a TypeContainer instead of a
- Report as the first argument.
-
- (Expression::ResolvePrimary): Killed. I still want to improve
- this as currently the code is just not right.
-
- (Expression::ResolveMemberAccess): Simplify, but it is still
- wrong.
-
- (Unary::Resolve): Catch errors in AddressOf operators.
-
- (LocalVariableReference::Emit, ::Store, ::AddressOf): typecast
- index to a byte for the short-version, or the compiler will choose
- the wrong Emit call, which generates the wrong data.
-
- (ParameterReference::Emit, ::Store): same.
-
- (FieldExpr::AddressOf): Implement.
-
- * typemanager.cs: TypeManager: made public variable instead of
- property.
-
- * driver.cs: document --fatal.
-
- * report.cs (ErrorMessage, WarningMessage): new names for the old
- Error and Warning classes.
-
- * cs-parser.jay (member_access): Turn built-in access to types
- into a normal simplename
-
-2001-09-27 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (Invocation::BetterConversion): Fix to cope
- with q being null, since this was introducing a bug.
-
- * expression.cs (ConvertImplicit): Do built-in conversions first.
-
-2001-09-27 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (UserImplicitCast::Resolve): Fix bug.
-
-2001-09-27 Ravi Pratap <ravi@ximian.com>
-
- * class.cs (TypeContainer::AddConstructor): Fix a stupid bug
- I had introduced long ago (what's new ?).
-
- * expression.cs (UserImplicitCast::CanConvert): Static method to do
- the work of all the checking.
- (ConvertImplicit): Call CanConvert and only then create object if necessary.
- (UserImplicitCast::CanConvert, ::Resolve): Re-write.
-
- (Unary::Operator): Rename Add and Subtract to Addition and Subtraction because
- that is the right way.
-
- (Invocation::MakeUnionSet): Convenience function to make unions of sets for
- overloading resolution. Use everywhere instead of cutting and pasting code.
-
- (Binary::ResolveOperator): Use MakeUnionSet.
-
- (UserImplicitCast::CanConvert, ::Resolve): Update to take care of the case when
- we have to convert to bool types. Not complete yet.
-
-2001-09-27 Miguel de Icaza <miguel@ximian.com>
-
- * typemanager.cs (TypeManager::CSharpName): support ushort.
-
- * expression.cs (Expression::TryImplicitIntConversion): Attempts
- to provide an expression that performsn an implicit constant int
- conversion (section 6.1.6).
- (Expression::ConvertImplicitRequired): Reworked to include
- implicit constant expression conversions.
-
- (Expression::ConvertNumericExplicit): Finished.
-
- (Invocation::Emit): If InstanceExpression is null, then it means
- that we perform a call on this.
-
-2001-09-26 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (Unary::Emit): Remove some dead code.
- (Probe): Implement Resolve and Emit for `is'.
- (Expression::ConvertImplicitRequired): Attempt to do constant
- expression conversions here. Maybe should be moved to
- ConvertImplicit, but I am not sure.
- (Expression::ImplicitLongConstantConversionPossible,
- Expression::ImplicitIntConstantConversionPossible): New functions
- that tell whether is it possible to apply an implicit constant
- expression conversion.
-
- (ConvertNumericExplicit): Started work on explicit numeric
- conversions.
-
- * cs-parser.jay: Update operator constants.
-
- * parameter.cs (Parameters::GetParameterInfo): Hook up VerifyArgs
- (Parameters::GetSignature): Hook up VerifyArgs here.
- (Parameters::VerifyArgs): Verifies that no two arguments have the
- same name.
-
- * class.cs (Operator): Update the operator names to reflect the
- ones that the spec expects (as we are just stringizing the
- operator names).
-
- * expression.cs (Unary::ResolveOperator): Fix bug: Use
- MethodInfo's ReturnType instead of LookupMethodByBuilder as the
- previous usage did only work for our methods.
- (Expression::ConvertImplicit): Handle decimal implicit numeric
- conversions as well.
- (Expression::InternalTypeConstructor): Used to invoke constructors
- on internal types for default promotions.
-
- (Unary::Emit): Implement special handling for the pre/post
- increment/decrement for overloaded operators, as they need to have
- the same semantics as the other operators.
-
- (Binary::ResolveOperator): ditto.
- (Invocation::ConversionExists): ditto.
- (UserImplicitCast::Resolve): ditto.
-
-2001-09-26 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (Unary::Emit and Binary::Emit): If we have an overloaded
- operator, return after emitting body. Regression tests pass again !
-
- * expression.cs (ConvertImplicit): Take TypeContainer as first argument
- (Unary::ForceConversion, Binary::ForceConversion): Ditto.
- (Invocation::OverloadResolve): Ditto.
- (Invocation::BetterFunction, BetterConversion, ConversionExists): Ditto.
-
- * everywhere : update calls to the above methods accordingly.
-
-2001-09-26 Miguel de Icaza <miguel@ximian.com>
-
- * assign.cs (Assign): Make it inherit from ExpressionStatement.
-
- * expression.cs (ExpressionStatement): New base class used for
- expressions that can appear in statements, so that we can provide
- an alternate path to generate expression that do not leave a value
- on the stack.
-
- (Expression::Emit, and all the derivatives): We no longer return
- whether a value is left on the stack or not. Every expression
- after being emitted leaves a single value on the stack.
-
- * codegen.cs (EmitContext::EmitStatementExpression): Use the
- facilties of ExpressionStatement if possible.
-
- * cs-parser.jay: Update statement_expression.
-
-2001-09-25 Miguel de Icaza <miguel@ximian.com>
-
- * driver.cs: Change the wording of message
-
-2001-09-25 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (Binary::ResolveOperator): Had forgottten to set
- the type of the expression to the return type of the method if
- we have an overloaded operator match ! The regression tests pass again !
- (Unary::ResolveOperator): Ditto.
-
- * expression.cs (Invocation::ConversionExists): Correct the member lookup
- to find "op_Implicit", not "implicit" ;-)
- (UserImplicitCast): New class to take care of user-defined implicit conversions.
- (ConvertImplicit, ForceConversion): Take TypeContainer argument
-
- * everywhere : Correct calls to the above accordingly.
-
- * expression.cs (UserImplicitCast::Resolve, ::Emit): Implement.
- (ConvertImplicit): Do user-defined conversion if it exists.
-
-2001-09-24 Miguel de Icaza <miguel@ximian.com>
-
- * assign.cs: track location.
- (Resolve): Use implicit conversions on assignment.
-
- * literal.cs: Oops. Not good, Emit of short access values should
- pass (Bytes) or the wrong argument will be selected.
-
- * expression.cs (Unary::Emit): Emit code for -expr.
-
- (Unary::ResolveOperator): Handle `Substract' for non-constants
- (substract from zero from the non-constants).
- Deal with Doubles as well.
-
- (Expression::ConvertImplicitRequired): New routine that reports an
- error if no implicit conversion exists.
-
- (Invocation::OverloadResolve): Store the converted implicit
- expressions if we make them
-
-2001-09-24 Ravi Pratap <ravi@ximian.com>
-
- * class.cs (ConstructorInitializer): Take a Location argument.
- (ConstructorBaseInitializer): Same here.
- (ConstructorThisInitializer): Same here.
-
- * cs-parser.jay : Update all calls accordingly.
-
- * expression.cs (Unary, Binary, New): Take location argument.
- Update accordingly everywhere.
-
- * cs-parser.jay : Update all calls to the above to take a location
- argument.
-
- * class.cs : Ditto.
-
-2001-09-24 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (Invocation::BetterFunction): Take TypeContainer argument
- (Invocation::BetterConversion): Same here
- (Invocation::ConversionExists): Ditto.
-
- (Invocation::ConversionExists): Implement.
-
-2001-09-22 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (OverloadResolve): Improve some more to catch errors 1502 and 1503
- Also take an additional TypeContainer argument.
-
- * All over : Pass in TypeContainer as argument to OverloadResolve.
-
- * typemanager.cs (CSharpName): Update to check for the string type and return
- that too.
-
- * expression.cs (Invocation::FullMethodDesc): New static method to return a string fully describing
- a given method.
-
-2001-09-21 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (Invocation::OverloadResolve): Re-write to conform more to the spec.
- (Invocation::BetterFunction): Implement.
- (Invocation::BetterConversion): Implement.
- (Invocation::ConversionExists): Skeleton, no implementation yet.
-
- Okay, things work fine !
-
-2001-09-21 Miguel de Icaza <miguel@ximian.com>
-
- * typemanager.cs: declare and load enum_type, delegate_type and
- void_type.
-
- * expression.cs (Expression::Emit): Now emit returns a value that
- tells whether a value is left on the stack or not. This strategy
- might be reveted tomorrow with a mechanism that would address
- multiple assignments.
- (Expression::report118): Utility routine to report mismatches on
- the ExprClass.
-
- (Unary::Report23): Report impossible type/operator combination
- utility function.
-
- (Unary::IsIncrementableNumber): Whether the type can be
- incremented or decremented with add.
- (Unary::ResolveOperator): Also allow enumerations to be bitwise
- complemented.
- (Unary::ResolveOperator): Implement ++, !, ~,
-
- (Invocation::Emit): Deal with new Emit convetion.
-
- * All Expression derivatives: Updated their Emit method to return
- whether they leave values on the stack or not.
-
- * codegen.cs (CodeGen::EmitStatement): Pop values left on the
- stack for expressions that are statements.
-
-2001-09-20 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (LValue): New interface. Must be implemented by
- LValue objects.
- (LocalVariableReference, ParameterReference, FieldExpr): Implement
- LValue interface.
-
- * assign.cs (Assign::Emit, Assign::Resolve): Use new LValue
- interface for generating code, simplifies the code.
-
-2001-09-20 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (everywhere): Comment out return statements in ::Resolve
- methods to avoid the warnings.
-
-2001-09-20 Miguel de Icaza <miguel@ximian.com>
-
- * driver.cs (parse): Report error 2001 if we can not open the
- source file.
-
- * expression.cs (SimpleName::ResolveSimpleName): Error if we can
- not resolve it.
-
- * cs-parser.jay (QualifierIdentifier): Pass location to SimpleName
- object.
-
- * statement.cs (Block::EmitMeta): Reuse the count across all the variables,
- otherwise nested blocks end up with the same index.
-
- * codegen.cs (CodeGen::EmitTopBlock): Pass initial sequence
-
- * expression.cs: Instead of having FIXMEs in the Resolve
- functions, throw exceptions so it is obvious that we are facing a
- bug.
-
- * cs-parser.jay (invocation_expression): Pass Location information.
-
- * codegen.cs (CodeGen::Save, CodeGen::CodeGen, CodeGen::Basename):
- Use a basename for those routines because .NET does not like paths
- on them.
-
- * class.cs (TypeContainer::AddMethod): Do not call DefineName if the name was
- already defined.
-
-2001-09-19 Miguel de Icaza <miguel@ximian.com>
-
- * typemanager.cs (TypeManager::CoreLookupType): A function to make sure that we
- are loading the correct data types (throws an exception if not).
- (TypeManager::InitCoreTypes): Use CoreLookupType
-
- * expression.cs (Unary::ResolveOperator): return the child
- expression for expressions which are just +expr.
- (Unary::ResolveOperator): Return negative literals for -LITERAL
- expressions (otherwise they are Unary {Literal}).
- (Invocation::Badness): Take into account `Implicit constant
- expression conversions'.
-
- * literal.cs (LongLiteral): Implement long literal class.
- (IntLiteral): export the `Value' of the intliteral.
-
-2001-09-19 Ravi Pratap <ravi@ximian.com>
-
- * expression.cs (Binary::Emit): Finally get the emission right ! Woo!
-
- * class.cs (Operator::Define): Change the methodname prefix to 'op_'
- instead of 'Operator'
-
- * expression.cs (Binary::ResolveOperator): Update accordingly.
- (Unary::Operator): Change names to 'Add' and 'Subtract' instead 'Plus'
- and 'Minus'
-
- * cs-parser.jay (unary_expression): Update to use the new names.
-
- * gen-treedump.cs (GetUnary): Same here.
-
- * expression.cs (Unary::Resolve): Implement.
- (Binary::ResolveOperator): Re-write bits to quietly continue if no overloaded
- operators are found instead of making noise ;-)
- (Unary::ResolveOperator): New method to do precisely the same thing which
- Binary::ResolveOperator does for Binary expressions.
- (Unary.method, .Arguments): Add.
- (Unary::OperName): Implement.
- (Unary::ForceConversion): Copy and Paste !
-
- * class.cs (Operator::Define): Fix a small bug for the case when we have
- a unary operator.
-
- * expression.cs (Unary::Emit): Implement. Need to find the right Opcodes
- for the inbuilt operators. Only overloading works for now ;-)
-
-2001-09-18 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (CheckedExpr::Resolve, CheckedExpr::Emit,
- UnCheckedExpr::Resolve, UnCheckedExpr::Emit): Implement.
-
- * expression.cs (This::Emit): Implement.
- (This::Resolve): Implement.
- (TypeOf:Resolve): Implement.
- (Expression::ResolveSimpleName): Add an implicit this to instance
- field references.
- (MemberAccess::Resolve): Deal with Parameters and Fields.
- Bind instance variable to Field expressions.
- (FieldExpr::Instance): New field used to track the expression that
- represents the object instance.
- (FieldExpr::Resolve): Track potential errors from MemberLookup not
- binding
- (FieldExpr::Emit): Implement.
-
- * codegen.cs (EmitIf, EmitStatement, EmitBlock): Propagate whether
- the last instruction contains a return opcode to avoid generating
- the last `ret' instruction (this generates correct code, and it is
- nice to pass the peverify output).
-
- * class.cs (TypeContainer::EmitFieldInitializers): Implement field
- initializer for static and instance variables.
- (Constructor::Emit): Allow initializer to be null in the case of
- static constructors. Only emit initializer for instance
- constructors.
-
- (TypeContainer::FindMembers): Return a null array if there are no
- matches.
-
- Also fix the code for the MemberTypes.Method branch, as it was not
- scanning that for operators (or tried to access null variables before).
-
- * assign.cs (Assign::Emit): Handle instance and static fields.
-
- * TODO: Updated.
-
- * driver.cs: Stop compilation if there are parse errors.
-
- * cs-parser.jay (constructor_declaration): Provide default base
- initializer for non-static constructors.
- (constructor_declarator): Do not provide a default base
- initializers if none was specified.
- Catch the fact that constructors should not have parameters.
-
- * class.cs: Do not emit parent class initializers for static
- constructors, that should be flagged as an error.
-
-2001-09-18 Ravi Pratap <ravi@ximian.com>
-
- * class.cs (RegisterMethodBuilder): Remove : it's unnecessary.
- Move back code into TypeContainer::Populate.
-
-2001-09-18 Ravi Pratap <ravi@ximian.com>
-
- * class.cs (TypeContainer::AddConstructor): Fix the check to
- compare against Name, not Basename.
- (Operator::OpType): Change Plus and Minus to Add and Subtract.
-
- * cs-parser.jay : Update accordingly.
-
- * class.cs (TypeContainer::FindMembers): For the case where we are searching
- for methods, don't forget to look into the operators too.
- (RegisterMethodBuilder): Helper method to take care of this for
- methods, constructors and operators.
- (Operator::Define): Completely revamp.
- (Operator.OperatorMethod, MethodName): New fields.
- (TypeContainer::Populate): Move the registering of builders into
- RegisterMethodBuilder.
- (Operator::Emit): Re-write.
-
- * expression.cs (Binary::Emit): Comment out code path to emit method
- invocation stuff for the case when we have a user defined operator. I am
- just not able to get it right !
-
-2001-09-17 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (Expression::OverloadResolve): Drop TypeContainer
- argument.
-
- (Expression::MemberLookup): Provide a version that allows to
- specify the MemberTypes and BindingFlags.
-
- * statement.cs (Block::GetVariableInfo): Forgot to recurse here,
- so it was not fetching variable information from outer blocks.
-
- * modifiers.cs: (Modifiers::TypeAttr): Invert condition on
- Beforefieldinit as it was buggy.
-
- * rootcontext.cs (::LookupInterfaceOrClass): Removed an Error -200
- that Ravi put here.
-
- * class.cs (Constructor::Emit): Only emit if block is not null.
- (TypeContainer::EmitDefaultConstructor): Removed routine, now we
- deal with this by semantically definining it as if the user had
- done it.
-
- (TypeContainer::FindMembers): Removed ad-hoc hack to deal with
- constructors as we now "emit" them at a higher level.
-
- (TypeContainer::DefineDefaultConstructor): Used to define the
- default constructors if none was provided.
-
- (ConstructorInitializer): Add methods Resolve and Emit.
-
- * expression.cs: Cast to ConstructorInfo instead of MethodInfo
-
-2001-09-17 Ravi Pratap <ravi@ximian.com>
-
- * class.cs (TypeContainer::EmitDefaultConstructor): Register
- the default constructor builder with our hashtable for methodbuilders
- to methodcores.
-
- * expression.cs (Invocation::OverloadResolve): Add a check for pd == null
- and argument_count is 0 in which case we have a match.
- (Binary::ResolveOperator): More null checking and miscellaneous coding
- style cleanup.
-
-2001-09-17 Ravi Pratap <ravi@ximian.com>
-
- * rootcontext.cs (IsNameSpace): Compare against null.
-
- * everywhere : Correct spelling to 'Greater' and to 'Subtract'
-
- * class.cs (Operator::OpType): Change names to match the ones in Binary::Operator
- and Unary::Operator.
-
- * cs-parser.jay (operator_declaration, CheckBinaryOperator, CheckUnaryOperator): Update
- accordingly.
-
- * expression.cs (Binary::method): New member to hold the MethodBase for the case when
- we have overloaded operators.
- (Binary::ResolveOperator): Implement the part which does the operator overload
- resolution.
-
- * class.cs (Operator::Emit): Implement.
- (TypeContainer::Emit): Emit the operators we have too.
-
- * expression.cs (Binary::Emit): Update to emit the appropriate code for
- the case when we have a user-defined operator.
-
-2001-09-17 Miguel de Icaza <miguel@ximian.com>
-
- * rootcontext.cs: Fix bug: tree.Namespaces might be null.
-
-2001-09-16 Ravi Pratap <ravi@ximian.com>
-
- * class.cs (EmitStaticFieldInitializers, EmitFieldInitializers): Make public.
- (TypeContainer::EmitConstructor): Remove and move code into Contructor::Emit.
- (Constructor::Emit): Implement.
- (EmitStaticFieldInitializers, EmitFieldInitializers): Ensure we return immediately
- if we have no work to do.
- (TypeContainer::Emit): Pass in TypeContainer as argument to the constructor's
- Emit method.
-
- * interface.cs (Interface::InterfaceAttr): Re-write to be more correct and complete.
- (Interface::IsTopLevel): Add. Same as TypeContainer::IsTopLevel.
-
- * class.cs (TypeContainer::IsTopLevel): Modify to use parent.Parent instead
- of parent.parent.
-
-2001-09-15 Ravi Pratap <ravi@ximian.com>
-
- * tree.cs (Tree::namespaces): New hashtable to keep track of namespaces
- in the source.
- (Tree::RecordNamespace): Method to do what the name says ;-)
- (Tree::Namespaces): Property to get at the namespaces hashtable.
-
- * cs-parser.jay (namespace_declaration): Call RecordNamespace to
- keep track.
-
- * rootcontext.cs (IsNamespace): Fixed it :-)
-
-2001-09-14 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (TypeContainer::FindMembers): Add support for
- constructors.
- (MethodCore): New class that encapsulates both the shared aspects
- of a Constructor and a Method.
- (Method, Constructor): Factored pieces into MethodCore.
-
- * driver.cs: Added --fatal which makes errors throw exceptions.
- Load System assembly as well as part of the standard library.
-
- * report.cs: Allow throwing exceptions on errors for debugging.
-
- * modifiers.cs: Do not use `parent', instead use the real type
- container to evaluate permission settings.
-
- * class.cs: Put Ravi's patch back in. He is right, and we will
- have to cope with the
-
-2001-09-14 Ravi Pratap <ravi@ximian.com>
-
- * modifiers.cs (TypeAttr, MethodAttr, FieldAttr): Map protected internal to
- FamORAssem, not FamANDAssem.
-
-2001-09-14 Miguel de Icaza <miguel@ximian.com>
-
- * driver.cs: Added --parse option that only parses its input files
- and terminates.
-
- * class.cs: Reverted last change from Ravi to IsTopLevel. That is
- incorrect. IsTopLevel is not used to tell whether an object is
- root_types or not (that can be achieved by testing this ==
- root_types). But to see if this is a top-level *class* (not
- necessarly our "toplevel" container).
-
-2001-09-14 Ravi Pratap <ravi@ximian.com>
-
- * enum.cs (Enum::Define): Modify to call the Lookup method on the
- parent instead of a direct call to GetType.
-
-2001-09-14 Ravi Pratap <ravi@ximian.com>
-
- * class.cs (TypeContainer::TypeAttr): Remove property code and move it into
- Modifiers.TypeAttr. This should just be a call to that method.
-
- * modifiers.cs (TypeAttr): Re-write and take an extra argument, the TypeContainer
- object so that we can determine if we are top-level or not.
-
- * delegate.cs (Delegate::Define): Update call to TypeAttr method to pass in the
- TypeContainer too.
-
- * enum.cs (Enum::Define): Ditto.
-
- * modifiers.cs (FieldAttr): Re-write.
-
- * class.cs (TypeContainer::IsTopLevel): Change accessibility to public.
- (TypeContainer::HaveStaticConstructor): New property to provide access
- to precisely that info.
-
- * modifiers.cs (MethodAttr): Re-write.
- (EventAttr): Remove altogether as there seems to be no ostensible use for it.
-
- * class.cs (TypeContainer::IsTopLevel): Re-write. root_types doesn't seem to be the parent
- of top-level types as claimed.
-
-2001-09-13 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (MemberLookup): Fruitless attempt to lookup
- constructors. Maybe I need to emit default constructors? That
- might be it (currently .NET emits this for me automatically).
- (Invocation::OverloadResolve): Cope with Arguments == null.
- (Invocation::EmitArguments): new function, shared by the new
- constructor and us.
- (Invocation::Emit): Handle static and instance methods. Emit
- proper call instruction for virtual or non-virtual invocations.
- (New::Emit): Implement.
- (New::Resolve): Implement.
- (MemberAccess:Resolve): Implement.
- (MethodGroupExpr::InstanceExpression): used conforming to the spec
- to track instances.
- (FieldExpr::Resolve): Set type.
-
- * support.cs: Handle empty arguments.
-
- * cs-parser.jay (CompositeLookup, QualifierIdentifier,
- SimpleLookup): Auxiliary routines to help parse a qualifier
- identifier.
-
- Update qualifier_identifier rule.
-
- * codegen.cs: Removed debugging messages.
-
- * class.cs: Make this a global thing, this acts just as a "key" to
- objects that we might have around.
-
- (Populate): Only initialize method_builders_to_methods once.
-
- * expression.cs (PropertyExpr): Initialize type from the
- PropertyType.
-
- * codegen.cs (EmitContext::EmitBoolExpression): Use propper
- Resolve pattern. Attempt to implicitly convert value to boolean.
- Emit code.
-
- * expression.cs: Set the type for the int32/int32 argument case.
- (Binary::ResolveOperator): Set the return type to boolean for
- comparission operators
-
- * typemanager.cs: Remove debugging print code.
-
- (Invocation::Resolve): resolve type.
-
- * class.cs: Allocate a MemberInfo of the correct size, as the code
- elsewhere depends on the test to reflect the correct contents.
-
- (Method::) Keep track of parameters, due to System.Reflection holes
-
- (TypeContainer::Populate): Keep track of MethodBuilders to Method
- mapping here.
-
- (TypeContainer::FindMembers): Use ArrayList and then copy an array
- of the exact size and return that.
-
- (Class::LookupMethodByBuilder): New function that maps
- MethodBuilders to its methods. Required to locate the information
- on methods because System.Reflection bit us again.
-
- * support.cs: New file, contains an interface ParameterData and
- two implementations: ReflectionParameters and InternalParameters
- used to access Parameter information. We will need to grow this
- as required.
-
- * expression.cs (Invocation::GetParameterData): implement a cache
- and a wrapper around the ParameterData creation for methods.
- (Invocation::OverloadResolve): Use new code.
-
-2001-09-13 Ravi Pratap <ravi@ximian.com>
-
- * class.cs (TypeContainer::EmitField): Remove and move into
- (Field::Define): here and modify accordingly.
- (Field.FieldBuilder): New member.
- (TypeContainer::Populate): Update accordingly.
- (TypeContainer::FindMembers): Implement.
-
-2001-09-13 Miguel de Icaza <miguel@ximian.com>
-
- * statement.cs: (VariableInfo::VariableType): New field to be
- initialized with the full type once it is resolved.
-
-2001-09-12 Miguel de Icaza <miguel@ximian.com>
-
- * parameter.cs (GetParameterInfo): Use a type cache to compute
- things only once, and to reuse this information
-
- * expression.cs (LocalVariableReference::Emit): Implement.
- (OpcodeCast::Emit): fix.
-
- (ParameterReference::Resolve): Implement.
- (ParameterReference::Emit): Implement.
-
- * cs-parser.jay: Fix bug introduced by Ravi, variable initializers
- that are expressions need to stay as Expressions.
-
- * typemanager.cs (CSharpName): Returns the C# name of a type if
- possible.
-
- * expression.cs (Expression::ConvertImplicit): New function that
- implements implicit type conversions.
-
- (Expression::ImplicitReferenceConversion): Implements implicit
- reference conversions.
-
- (EmptyCast): New type for transparent casts.
-
- (OpcodeCast): New type for casts of types that are performed with
- a sequence of bytecodes.
-
- (BoxedCast): New type used for casting value types into reference
- types. Emits a box opcode.
-
- (Binary::DoNumericPromotions): Implements numeric promotions of
- and computation of the Binary::Type.
-
- (Binary::EmitBranchable): Optimization.
-
- (Binary::Emit): Implement code emission for expressions.
-
- * typemanager.cs (TypeManager): Added two new core types: sbyte
- and byte.
-
-2001-09-12 Ravi Pratap <ravi@ximian.com>
-
- * class.cs (TypeContainer::FindMembers): Method which does exactly
- what Type.FindMembers does, only we don't have to use reflection. No
- implementation yet.
-
- * typemanager.cs (typecontainers): New hashtable to hold the corresponding
- typecontainer objects as we need to get at them.
- (TypeManager::AddUserType): Overload to take an extra argument, the TypeContainer.
-
- * rootcontext.cs : Correspondingly modify called to AddUserType to pass the
- typecontainer object.
-
- * expression.cs (MemberLookup): Modify signature to take a RootContext object instead
- of just a Report object.
-
-2001-09-11 Ravi Pratap <ravi@ximian.com>
-
- * class.cs (Event::Define): Go back to using the prefixes "add_" and
- "remove_"
- (TypeContainer::Populate): Now define the delegates of the type too.
- (TypeContainer.Delegates): Property to access the list of delegates defined
- in the type.
-
- * delegates.cs (Delegate::Define): Implement partially.
-
- * modifiers.cs (TypeAttr): Handle more flags.
-
-2001-09-11 Ravi Pratap <ravi@ximian.com>
-
- * class.cs (Indexer::Define): Fix for loop iteration condition to be just <
- and not <=
- (Operator::Define): Re-write logic to get types by using the LookupType method
- instead of blindly doing a Type.GetType ! How stupid can I get ;-) ?
- (Indexer::Define): Ditto.
- (Event::Define): Ditto.
- (Property::Define): Ditto.
-
-2001-09-10 Ravi Pratap <ravi@ximian.com>
-
- * class.cs (TypeContainer::Populate): Now define operators too.
- (TypeContainer.Operators): New property to access the list of operators
- in a type.
- (Operator.OperatorMethodBuilder): New member to hold the method builder
- for the operator we are defining.
- (Operator::Define): Implement.
-
-2001-09-10 Ravi Pratap <ravi@ximian.com>
-
- * class.cs (Event::Define): Make the prefixes of the accessor methods
- addOn_ and removeOn_
-
- * genericparser.cs (GenericParser::error): Overloaded method to handle the case
- of the location being passed in too. Ideally, this should go later since all
- error reporting should be done through the Report object.
-
- * class.cs (TypeContainer.Indexers): New property to access the list of indexers.
- (Populate): Iterate thru the indexers we have and define them too.
- (Indexer.GetMethodBuilder, .SetMethodBuilder): New members to hold the method builders
- for the get and set accessors.
- (Indexer::Define): Implement.
-
-2001-09-09 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (Binary::Resolve): Beginning of it. I scratched
- my previous implementation, did not work.
-
- * typemanager.cs: Add a couple of missing types (the longs).
-
- * literal.cs: Use TypeManager.bool_type instead of getting it.
-
- * expression.cs (EventExpr): New kind of expressions.
- (Expressio::ExprClassFromMemberInfo): finish
-
-2001-09-08 Miguel de Icaza <miguel@ximian.com>
-
- * assign.cs: Emit stores to static fields differently.
-
-2001-09-08 Ravi Pratap <ravi@ximian.com>
-
- * Merge in changes and adjust code to tackle conflicts. Backed out my
- code in Assign::Resolve ;-)
-
-2001-09-08 Ravi Pratap <ravi@ximian.com>
-
- * cs-parser.jay (CheckAttributeTarget): Modify call to error to use
- instead Report.Error and also pass in the location.
- (CSharpParser::Lexer): New readonly property to return the reference
- to the Tokenizer object.
- (declare_local_variables): Use Report.Error with location instead of plain
- old error.
- (CheckDef): Ditto.
-
- * class.cs (Operator::CheckUnaryOperator): Move into cs-parser.jay.
- (Operator.CheckBinaryOperator): Ditto.
-
- * cs-parser.jay (operator_declarator): Update accordingly.
-
- * cs-parser.jay (CheckUnaryOperator): Modify to use Report.Error
- (CheckBinaryOperator): Same here.
-
- * rootcontext.cs (LookupType): Add an extra lookup which simply does a lookup
- on the name without any prefixes of namespace names etc. This is because we
- already might have something already fully qualified like
- 'System.Console.WriteLine'
-
- * assign.cs (Resolve): Begin implementation. Stuck ;-)
-
-2001-09-07 Ravi Pratap <ravi@ximian.com>
-
- * cs-tokenizer.cs (location): Return a string which also contains
- the file name.
-
- * expression.cs (ElementAccess): New class for expressions of the
- type 'element access.'
- (BaseAccess): New class for expressions of the type 'base access.'
- (CheckedExpr, UnCheckedExpr): New classes for Checked and Unchecked expressions
- respectively.
-
- * cs-parser.jay (element_access): Implement action.
- (base_access): Implement actions.
- (checked_expression, unchecked_expression): Implement.
-
- * cs-parser.jay (local_variable_type): Correct and implement.
- (type_suffixes, type_suffix_list, type_suffix): Implement actions.
-
- * cs-tokenizer.cs (real_type_suffix): Comment out the extra getchar.
-
- * cs-parser.jay (rank_specifiers): Remove space while concatenating the type's
- name and the specifiers.
-
- * interface.cs (InterfaceAttr): New property to return the corresponding TypeAttributes
-
- * rootcontext.cs (CreateInterface): Use the InterfaceAttr property instead of
- making them all public ;-)
-
- * cs-parser.jay (error): Remove entirely as we have an implementation in the base
- class anyways.
-
-2001-09-07 Miguel de Icaza <miguel@ximian.com>
-
- * expression.cs (ExprClassFromMemberInfo): Return FieldExpr and
- PropertyExprs.
- (FieldExpr, PropertyExprs): New resolved expressions.
- (SimpleName::MemberStaticCheck): Perform static checks for access
- to non-static fields on static methods. Maybe this should be
- generalized for MemberAccesses.
- (SimpleName::ResolveSimpleName): More work on simple name
- resolution.
-
- * cs-parser.jay (primary_expression/qualified_identifier): track
- the parameter index.
-
- * codegen.cs (CodeGen::Save): Catch save exception, report error.
- (EmitContext::EmitBoolExpression): Chain to expression generation
- instead of temporary hack.
- (::EmitStatementExpression): Put generic expression code generation.
-
- * assign.cs (Assign::Emit): Implement variable assignments to
- local variables, parameters and fields.
-
-2001-09-06 Miguel de Icaza <miguel@ximian.com>
-
- * statement.cs (Block::GetVariableInfo): New method, returns the
- VariableInfo for a variable name in a block.
- (Block::GetVariableType): Implement in terms of GetVariableInfo
-
- * literal.cs (IntLiteral::Emit, FloatLiteral::Emit,
- DoubleLiteral::Emit, CharLiteral::Emit, BoolLiteral::Emit): Implement
-
-2001-09-06 Ravi Pratap <ravi@ximian.com>
-
- * cs-parser.jay (operator_declaration): Continue on my quest : update
- to take attributes argument.
- (event_declaration): Ditto.
- (enum_declaration): Ditto.
- (indexer_declaration): Ditto.
-
- * class.cs (Operator::Operator): Update constructor accordingly.
- (Event::Event): Ditto.
-
- * delegate.cs (Delegate::Delegate): Same here.
-
- * enum.cs (Enum::Enum): Same here.
-
-2001-09-05 Ravi Pratap <ravi@ximian.com>
-
- * cs-parser.jay (CheckAttributeTarget): Update to use the right error number.
-
- * ../tests/cs0658.cs : New file to demonstrate error 0658.
-
- * attribute.cs (Attributes): New class to encapsulate all attributes which were
- being passed around as an arraylist.
- (Attributes::AddAttribute): Method to add attribute sections.
-
- * cs-parser.jay (opt_attributes): Modify actions to use the new Attributes class.
- (struct_declaration): Update accordingly.
- (constant_declaration): Update.
- (field_declaration): Update.
- (method_header): Update.
- (fixed_parameter): Update.
- (parameter_array): Ditto.
- (property_declaration): Ditto.
- (destructor_declaration): Ditto.
-
- * class.cs (Struct::Struct): Update constructors accordingly.
- (Class::Class): Ditto.
- (Field::Field): Ditto.
- (Method::Method): Ditto.
- (Property::Property): Ditto.
- (TypeContainer::OptAttribute): update property's return type.
-
- * interface.cs (Interface.opt_attributes): New member.
- (Interface::Interface): Update to take the extra Attributes argument.
-
- * parameter.cs (Parameter::Parameter): Ditto.
-
- * constant.cs (Constant::Constant): Ditto.
-
- * interface.cs (InterfaceMemberBase): New OptAttributes field.
- (InterfaceMemberBase::InterfaceMemberBase): Update constructor to take
- the attributes as a parameter.
- (InterfaceProperty): Update constructor call.
- (InterfaceEvent): Ditto.
- (InterfaceMethod): Ditto.
- (InterfaceIndexer): Ditto.
-
- * cs-parser.jay (interface_indexer_declaration): Update call to constructor to
- pass the attributes too.
- (interface_event_declaration): Ditto.
- (interface_property_declaration): Ditto.
- (interface_method_declaration): Ditto.
- (interface_declaration): Ditto.
-
-2001-09-05 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (Method::Define): Track the "static Main" definition to
- create an entry point.
-
- * rootcontext.cs (RootContext::EntryPoint): MethodInfo that holds the
- EntryPoint if we find it.
-
- * codegen.cs (EmitContext::EmitInvocation): Emit invocations.
- (EmitContext::ig): Make this variable public.
-
- * driver.cs: Make the default output file be the first file name
- with the .exe extension.
-
- Detect empty compilations
-
- Handle various kinds of output targets. Handle --target and
- rename -t to --dumper.
-
- * expression.cs, literal.cs, assign.cs, constant.cs: All `Resolve'
- methods inherited from Expression return now an Expression. This
- will is used during the tree rewriting as we resolve them during
- semantic analysis.
-
- (Expression::MemberLookup): Implements the MemberLookup (7.3) from
- the spec. Missing entirely is the information about
- accessability of elements of it.
-
- (Expression::ExprClassFromMemberInfo): New constructor for
- Expressions that creates a fully initialized Expression based on
- a MemberInfo that is one of Eventinfo, FieldINfo, PropertyInfo or
- a Type.
-
- (Invocation::Resolve): Begin implementing resolution of invocations.
-
- * literal.cs (StringLiteral): Implement Emit.
-
-2001-09-05 Ravi Pratap <ravi@ximian.com>
-
- * cs-parser.jay (error): Add new modifier because we are hiding an inherited
- member.
-
-2001-09-04 Ravi Pratap <ravi@ximian.com>
-
- * cs-parser.jay (attribute_arguments): Implement actions.
- (attribute): Fix bug in production. Implement action.
- (attribute_list): Implement.
- (attribute_target): Implement.
- (attribute_target_specifier, opt_target_specifier): Implement
- (CheckAttributeTarget): New method to check if the attribute target
- is valid.
- (attribute_section): Implement.
- (opt_attributes): Implement.
-
- * attribute.cs : New file to handle attributes.
- (Attribute): Class to hold attribute info.
-
- * cs-parser.jay (opt_attribute_target_specifier): Remove production
- (attribute_section): Modify production to use 2 different rules to
- achieve the same thing. 1 s/r conflict down !
- Clean out commented, useless, non-reducing dimension_separator rules.
-
- * class.cs (TypeContainer.attributes): New member to hold list
- of attributes for a type.
- (Struct::Struct): Modify to take one more argument, the attribute list.
- (Class::Class): Ditto.
- (Field::Field): Ditto.
- (Method::Method): Ditto.
- (Property::Property): Ditto.
-
- * cs-parser.jay (struct_declaration): Update constructor call to
- pass in the attributes too.
- (class_declaration): Ditto.
- (constant_declaration): Ditto.
- (field_declaration): Ditto.
- (method_header): Ditto.
- (fixed_parameter): Ditto.
- (parameter_array): Ditto.
- (property_declaration): Ditto.
-
- * constant.cs (Constant::Constant): Update constructor similarly.
- Use System.Collections.
-
- * parameter.cs (Parameter::Parameter): Update as above.
-
-2001-09-02 Ravi Pratap <ravi@ximian.com>
-
- * class.cs (TypeContainer::AddDelegate): New method to add a delegate.
- (TypeContainer.delegates): New member to hold list of delegates.
-
- * cs-parser.jay (delegate_declaration): Implement the action correctly
- this time as I seem to be on crack ;-)
-
-2001-09-02 Miguel de Icaza <miguel@ximian.com>
-
- * rootcontext.cs (RootContext::IsNamespace): new function, used to
- tell whether an identifier represents a namespace.
-
- * expression.cs (NamespaceExpr): A namespace expression, used only
- temporarly during expression resolution.
- (Expression::ResolveSimpleName, ::ResolvePrimary, ::ResolveName):
- utility functions to resolve names on expressions.
-
-2001-09-01 Miguel de Icaza <miguel@ximian.com>
-
- * codegen.cs: Add hook for StatementExpressions.
-
- * class.cs: Fix inverted test for static flag in methods.
-
-2001-09-02 Ravi Pratap <ravi@ximian.com>
-
- * class.cs (Operator::CheckUnaryOperator): Correct error number used
- to make it coincide with MS' number.
- (Operator::CheckBinaryOperator): Ditto.
-
- * ../errors/errors.txt : Remove error numbers added earlier.
-
- * ../errors/cs1019.cs : Test case for error # 1019
-
- * ../errros/cs1020.cs : Test case for error # 1020
-
- * cs-parser.jay : Clean out commented cruft.
- (dimension_separators, dimension_separator): Comment out. Ostensibly not
- used anywhere - non-reducing rule.
- (namespace_declarations): Non-reducing rule - comment out.
-
- * enum.cs (Enum::AddEnum): Rename to AddEnumMember as I was getting confused
- with TypeContainer::AddEnum.
-
- * delegate.cs : New file for delegate handling classes.
- (Delegate): Class for declaring delegates.
-
- * makefile : Update.
-
- * cs-parser.jay (delegate_declaration): Implement.
-
-2001-09-01 Ravi Pratap <ravi@che.iitm.ac.in>
-
- * class.cs (Event::Define): Implement.
- (Event.EventBuilder): New member.
-
- * class.cs (TypeContainer::Populate): Update to define all enums and events
- we have.
- (Events): New property for the events arraylist we hold. Shouldn't we move to using
- readonly fields for all these cases ?
-
-2001-08-31 Ravi Pratap <ravi@che.iitm.ac.in>
-
- * class.cs (Property): Revamp to use the convention of making fields readonly.
- Accordingly modify code elsewhere.
-
- * class.cs : Apply patch from Mr. Mandar <go_mono@hotmail.com> for implementing
- the Define method of the Property class.
-
- * class.cs : Clean up applied patch and update references to variables etc. Fix
- trivial bug.
- (TypeContainer::Populate): Update to define all the properties we have. Also
- define all enumerations.
-
- * enum.cs (Define): Implement.
-
-2001-08-31 Ravi Pratap <ravi@che.iitm.ac.in>
-
- * cs-parser.jay (overloadable_operator): The semantic value is an
- enum of the Operator class.
- (operator_declarator): Implement actions.
- (operator_declaration): Implement.
-
- * class.cs (Operator::CheckUnaryOperator): New static method to help in checking
- validity of definitions.
- (Operator::CheckBinaryOperator): Static method to check for binary operators
- (TypeContainer::AddOperator): New method to add an operator to a type.
-
- * cs-parser.jay (indexer_declaration): Added line to actually call the
- AddIndexer method so it gets added ;-)
-
- * ../errors/errors.txt : Update to include new error numbers. Are these numbers
- already taken care of by the MS compiler ?
-
-2001-08-29 Ravi Pratap <ravi@che.iitm.ac.in>
-
- * class.cs (Operator): New class for operator declarations.
- (Operator::OpType): Enum for the various operators.
-
-2001-08-29 Ravi Pratap <ravi@che.iitm.ac.in>
-
- * class.cs (TypeContainer::AddIndexer): Remove FIXME comment. We
- ostensibly handle this in semantic analysis.
-
- * cs-parser.jay (general_catch_clause): Comment out
- (specific_catch_clauses, specific_catch_clause): Ditto.
- (opt_general_catch_clause, opt_specific_catch_clauses): Ditto
- (catch_args, opt_catch_args): New productions.
- (catch_clause): Rewrite to use the new productions above
- (catch_clauses): Modify accordingly.
- (opt_catch_clauses): New production to use in try_statement
- (try_statement): Revamp. Basically, we get rid of one unnecessary rule
- and re-write the code in the actions to extract the specific and
- general catch clauses by being a little smart ;-)
-
- * ../tests/try.cs : Fix. It's not 'finalize' my friend, it's 'finally' !
- Hooray, try and catch statements parse fine !
-
-2001-08-28 Ravi Pratap <ravi@che.iitm.ac.in>
-
- * statement.cs (Block::GetVariableType): Fix logic to extract the type
- string from the hashtable of variables.
-
- * cs-parser.jay (event_accessor_declarations): Trivial fix. Man, how did
- I end up making that mistake ;-)
- (catch_clauses): Fixed gross error which made Key and Value of the
- DictionaryEntry the same : $1 !!
-
-2001-08-28 Ravi Pratap <ravi@che.iitm.ac.in>
-
- * cs-tokenizer.cs (initTokens): Add keywords 'add' and 'remove'
-
- * cs-parser.jay (event_declaration): Correct to remove the semicolon
- when the add and remove accessors are specified.
-
-2001-08-28 Ravi Pratap <ravi@che.iitm.ac.in>
-
- * cs-parser.jay (IndexerDeclaration): New helper class to hold
- information about indexer_declarator.
- (indexer_declarator): Implement actions.
- (parsing_indexer): New local boolean used to keep track of whether
- we are parsing indexers or properties. This is necessary because
- implicit_parameters come into picture even for the get accessor in the
- case of an indexer.
- (get_accessor_declaration, set_accessor_declaration): Correspondingly modified.
-
- * class.cs (Indexer): New class for indexer declarations.
- (TypeContainer::AddIndexer): New method to add an indexer to a type.
- (TypeContainer::indexers): New member to hold list of indexers for the
- type.
-
-2001-08-27 Ravi Pratap <ravi@che.iitm.ac.in>
-
- * cs-parser.jay (add_accessor_declaration): Implement action.
- (remove_accessor_declaration): Implement action.
- (event_accessors_declaration): Implement
- (variable_declarators): swap statements for first rule - trivial.
-
- * class.cs (Event): New class to hold information about event
- declarations.
- (TypeContainer::AddEvent): New method to add an event to a type
- (TypeContainer::events): New member to hold list of events.
-
- * cs-parser.jay (event_declaration): Implement actions.
-
-2001-08-27 Ravi Pratap <ravi@che.iitm.ac.in>
-
- * cs-parser.jay (dim_separators): Implement. Make it a string
- concatenating all the commas together, just as they appear.
- (opt_dim_separators): Modify accordingly
- (rank_specifiers): Update accordingly. Basically do the same
- thing - instead, collect the brackets here.
- (opt_rank_sepcifiers): Modify accordingly.
- (array_type): Modify to actually return the complete type string
- instead of ignoring the rank_specifiers.
- (expression_list): Implement to collect the expressions
- (variable_initializer): Implement. We make it a list of expressions
- essentially so that we can handle the array_initializer case neatly too.
- (variable_initializer_list): Implement.
- (array_initializer): Make it a list of variable_initializers
- (opt_array_initializer): Modify accordingly.
-
- * expression.cs (New::NType): Add enumeration to help us
- keep track of whether we have an object/delegate creation
- or an array creation.
- (New:NewType, New::Rank, New::Indices, New::Initializers): New
- members to hold data about array creation.
- (New:New): Modify to update NewType
- (New:New): New Overloaded contructor for the array creation
- case.
-
- * cs-parser.jay (array_creation_expression): Implement to call
- the overloaded New constructor.
-
-2001-08-26 Ravi Pratap <ravi@che.iitm.ac.in>
-
- * class.cs (TypeContainer::Constructors): Return member
- constructors instead of returning null.
-
-2001-08-26 Miguel de Icaza <miguel@ximian.com>
-
- * typemanager.cs (InitCoreTypes): Initialize the various core
- types after we have populated the type manager with the user
- defined types (this distinction will be important later while
- compiling corlib.dll)
-
- * expression.cs, literal.cs, assign.cs, constant.cs: Started work
- on Expression Classification. Now all expressions have a method
- `Resolve' and a method `Emit'.
-
- * codegen.cs, cs-parser.jay: Fixed the bug that stopped code
- generation from working. Also add some temporary debugging
- code.
-
-2001-08-24 Miguel de Icaza <miguel@ximian.com>
-
- * codegen.cs: Lots of code generation pieces. This is only the
- beginning, will continue tomorrow with more touches of polish. We
- handle the fundamentals of if, while, do, for, return. Others are
- trickier and I need to start working on invocations soon.
-
- * gen-treedump.cs: Bug fix, use s.Increment here instead of
- s.InitStatement.
-
- * codegen.cs (EmitContext): New struct, used during code
- emission to keep a context. Most of the code generation will be
- here.
-
- * cs-parser.jay: Add embedded blocks to the list of statements of
- this block. So code generation proceeds in a top down fashion.
-
-2001-08-23 Miguel de Icaza <miguel@ximian.com>
-
- * statement.cs: Add support for multiple child blocks.
-
-2001-08-22 Miguel de Icaza <miguel@ximian.com>
-
- * codegen.cs (EmitCode): New function, will emit the code for a
- Block of code given a TypeContainer and its ILGenerator.
-
- * statement.cs (Block): Standard public readonly optimization.
- (Block::Block constructors): Link children.
- (Block::Child): Child Linker.
- (Block::EmitVariables): Emits IL variable declarations.
-
- * class.cs: Drop support for MethodGroups here, delay until
- Semantic Analysis.
- (Method::): Applied the same simplification that I did before, and
- move from Properties to public readonly fields.
- (Method::ParameterTypes): Returns the parameter types for the
- function, and implements a cache that will be useful later when I
- do error checking and the semantic analysis on the methods is
- performed.
- (Constructor::GetCallingConvention): Renamed from CallingConvetion
- and made a method, optional argument tells whether this is a class
- or a structure to apply the `has-this' bit.
- (Method::GetCallingConvention): Implement, returns the calling
- convention.
- (Method::Define): Defines the type, a second pass is performed
- later to populate the methods.
-
- (Constructor::ParameterTypes): implement a cache similar to the
- one on Method::ParameterTypes, useful later when we do semantic
- analysis.
-
- (TypeContainer::EmitMethod): New method. Emits methods.
-
- * expression.cs: Removed MethodGroup class from here.
-
- * parameter.cs (Parameters::GetCallingConvention): new method.
-
-2001-08-21 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (TypeContainer::Populate): Drop RootContext from the
- argument.
-
- (Constructor::CallingConvention): Returns the calling convention.
- (Constructor::ParameterTypes): Returns the constructor parameter
- types.
-
- (TypeContainer::AddConstructor): Keep track of default constructor
- and the default static constructor.
-
- (Constructor::) Another class that starts using `public readonly'
- instead of properties.
-
- (Constructor::IsDefault): Whether this is a default constructor.
-
- (Field::) use readonly public fields instead of properties also.
-
- (TypeContainer::TypeAttr, TypeContainer::AddConstructor): Keep
- track of static constructors; If none is used, turn on
- BeforeFieldInit in the TypeAttributes.
-
- * cs-parser.jay (opt_argument_list): now the return can be null
- for the cases where there are no arguments.
-
- (constructor_declarator): If there is no implicit `base' or
- `this', then invoke the default parent constructor.
-
- * modifiers.cs (MethodAttr): New static function maps a set of
- modifiers flags into a MethodAttributes enum
- (FieldAttr): renamed from `Map'. So now we have FieldAttr,
- MethodAttr, TypeAttr to represent the various mappings where the
- modifiers are used.
- (FieldAttr): Map also `readonly' to `FieldAttributes.InitOnly'
-
-2001-08-19 Miguel de Icaza <miguel@ximian.com>
-
- * parameter.cs (GetParameterInfo): Fix bug where there would be no
- method arguments.
-
- * interface.cs (PopulateIndexer): Implemented the code generator
- for interface indexers.
-
-2001-08-17 Miguel de Icaza <miguel@ximian.com>
-
- * interface.cs (InterfaceMemberBase): Now we track the new status
- here.
-
- (PopulateProperty): Implement property population. Woohoo! Got
- Methods and Properties going today.
-
- Removed all the properties for interfaces, and replaced them with
- `public readonly' fields.
-
-2001-08-16 Miguel de Icaza <miguel@ximian.com>
-
- * interface.cs (AddEvent, AddMethod, AddIndexer, AddProperty):
- initialize their hashtables/arraylists only when they are needed
- instead of doing this always.
-
- * parameter.cs: Handle refs and out parameters.
-
- * cs-parser.jay: Use an ArrayList to construct the arguments
- instead of the ParameterCollection, and then cast that to a
- Parameter[] array.
-
- * parameter.cs: Drop the use of ParameterCollection and use
- instead arrays of Parameters.
-
- (GetParameterInfo): Use the Type, not the Name when resolving
- types.
-
-2001-08-13 Miguel de Icaza <miguel@ximian.com>
-
- * parameter.cs: Eliminate the properties Name, Type and ModFlags,
- and instead use public readonly fields.
-
- * class.cs: Put back walking code for type containers.
-
-2001-08-11 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (MakeConstant): Code to define constants.
-
- * rootcontext.cs (LookupType): New function. Used to locate types
-
-
-2001-08-08 Miguel de Icaza <miguel@ximian.com>
-
- * rootcontext.cs: OH MY! My trick works! It is amazing how nice
- this System.Reflection code is. Kudos to Microsoft
-
- * typemanager.cs: Implement a type cache and avoid loading all
- types at boot time. Wrap in LookupType the internals. This made
- the compiler so much faster. Wow. I rule!
-
- * driver.cs: Make sure we always load mscorlib first (for
- debugging purposes, nothing really important).
-
- * Renamespaced things that were on `CSC' to `CIR'. Maybe I should
- have moved to `CSC' rather than `CIR'. Oh man! The confussion!
-
- * rootcontext.cs: Lookup types on their namespace; Lookup types
- on namespaces that have been imported using the `using' keyword.
-
- * class.cs (TypeContainer::TypeAttr): Virtualize.
- (Class::TypeAttr): Return attributes suitable for this bad boy.
- (Struct::TypeAttr): ditto.
- Handle nested classes.
- (TypeContainer::) Remove all the type visiting code, it is now
- replaced with the rootcontext.cs code
-
- * rootcontext.cs (GetClassBases): Added support for structs.
-
-2001-08-06 Miguel de Icaza <miguel@ximian.com>
-
- * interface.cs, statement.cs, class.cs, parameter.cs,
- rootcontext.cs, gen-treedump.cs, enum.cs, cs-parse.jay:
- Drop use of TypeRefs, and use strings instead.
-
-2001-08-04 Miguel de Icaza <miguel@ximian.com>
-
- * rootcontext.cs:
-
- * class.cs (Struct::Struct): set the SEALED flags after
- checking the modifiers.
- (TypeContainer::TypeAttr): new property, returns the
- TypeAttributes for a class.
-
- * cs-parser.jay (type_list): Oops, list production was creating a
- new list of base types.
-
- * rootcontext.cs (StdLib): New property.
- (GetInterfaceTypeByName): returns an interface by type name, and
- encapsulates error handling here.
- (GetInterfaces): simplified.
- (ResolveTree): Encapsulated all the tree resolution here.
- (CreateClass, GetClassBases, GetInterfaceOrClass): Create class
- types.
-
- * driver.cs: Add support for --nostdlib, to avoid loading the
- default assemblies.
- (Main): Do not put tree resolution here.
-
- * rootcontext.cs: Beginning of the class resolution.
-
-2001-08-03 Miguel de Icaza <miguel@ximian.com>
-
- * rootcontext.cs: Provide better error reporting.
-
- * cs-parser.jay (interface_base): set our $$ to be interfaces.
-
- * rootcontext.cs (CreateInterface): Handle the case where there
- are no parent interfaces.
-
- (CloseTypes): Routine to flush types at the end.
- (CreateInterface): Track types.
- (GetInterfaces): Returns an array of Types from the list of
- defined interfaces.
-
- * typemanager.c (AddUserType): Mechanism to track user types (puts
- the type on the global type hash, and allows us to close it at the
- end).
-
-2001-08-02 Miguel de Icaza <miguel@ximian.com>
-
- * tree.cs: Removed RecordType, added RecordClass, RecordStruct and
- RecordInterface instead.
-
- * cs-parser.jay: Updated to reflect changes above.
-
- * decl.cs (Definition): Keep track of the TypeBuilder type that
- represents this type here. Not sure we will use it in the long
- run, but wont hurt for now.
-
- * driver.cs: Smaller changes to accomodate the new code.
-
- Call ResolveInterfaceBases, Call ResolveClassBases, Save assembly
- when done.
-
- * rootcontext.cs (CreateInterface): New method, used to create
- the System.TypeBuilder type for interfaces.
- (ResolveInterfaces): new entry point to resolve the interface
- hierarchy.
- (CodeGen): Property, used to keep track of the code generator.
-
-2001-07-26 Miguel de Icaza <miguel@ximian.com>
-
- * cs-parser.jay: Add a second production for delegate_declaration
- with `VOID'.
-
- (enum_body): Put an opt_comma here instead of putting it on
- enum_body or enum_member_declarations so we can handle trailing
- commas on enumeration members. Gets rid of a shift/reduce.
-
- (type_list): Need a COMMA in the middle.
-
- (indexer_declaration): Tell tokenizer to recognize get/set
-
- * Remove old targets.
-
- * Re-add the parser target.
-
-2001-07-13 Simon Cozens <simon@simon-cozens.org>
-
- * cs-parser.jay: Add precendence rules for a number of operators
- ot reduce the number of shift/reduce conflicts in the grammar.
-
-2001-07-17 Miguel de Icaza <miguel@ximian.com>
-
- * tree.cs: moved IGenerator interface and renamed it to ITreeDump
- and put it here.
-
- Get rid of old crufty code.
-
- * rootcontext.cs: Use this to keep track of the parsed
- representation and the defined types available to the program.
-
- * gen-treedump.cs: adjust for new convention.
-
- * type.cs: Split out the type manager, and the assembly builder
- from here.
-
- * typemanager.cs: the type manager will live here now.
-
- * cil-codegen.cs: And the code generator here.
-
-2001-07-14 Sean MacIsaac <macisaac@ximian.com>
-
- * makefile: Fixed up for easy making.
-
-2001-07-13 Simon Cozens <simon@simon-cozens.org>
-
- * cs-parser.jay (rank_specifier): Remove a conflict by reordering
- the
-
- (unary_expression): Expand pre_increment_expression and
- post_decrement_expression to reduce a shift/reduce.
-
-2001-07-11 Simon Cozens
-
- * cs-tokenizer.cs: Hex numbers should begin with a 0.
-
- Improve allow_keyword_as_indent name.
-
-2001-06-19 Miguel de Icaza <miguel@ximian.com>
-
- * Adjustments for Beta2.
-
-2001-06-13 Miguel de Icaza <miguel@ximian.com>
-
- * decl.cs: Added `Define' abstract method.
- (InTransit): new property, used to catch recursive definitions.
-
- * interface.cs: Implement `Define'.
-
- * modifiers.cs: Map Modifiers.constants to
- System.Reflection.TypeAttribute flags.
-
- * class.cs: Keep track of types and user-defined types.
- (BuilderInit): New method for creating an assembly
- (ResolveType): New function to launch the resolution process, only
- used by interfaces for now.
-
- * cs-parser.jay: Keep track of Classes, Structs and Interfaces
- that are inserted into the name space.
-
-2001-06-08 Miguel de Icaza <miguel@ximian.com>
-
- * ARGH. I have screwed up my tree so many times due to the use of
- rsync rather than using CVS. Going to fix this at once.
-
- * driver.cs: Objetify driver. Load assemblies, use assemblies to
- load types.
-
-2001-06-07 Miguel de Icaza <miguel@ximian.com>
-
- * Experiment successful: Use System.Type rather that our own
- version of Type.
-
-2001-05-25 Miguel de Icaza <miguel@ximian.com>
-
- * cs-parser.jay: Removed nsAliases from here.
-
- Use new namespaces, handle `using XXX;'
-
- * namespace.cs: Reimplemented namespace handling, use a recursive
- definition of the class. Now we can keep track of using clauses
- and catch invalid using clauses.
-
-2001-05-24 Miguel de Icaza <miguel@ximian.com>
-
- * gen-treedump.cs: Adapted for all the renaming.
-
- * expression.cs (Expression): this class now has a Type property
- which returns an expression Type.
-
- (Probe::, New::, TypeOf::, SizeOf::, Constant::): renamed from
- `Type', as this has a different meaning now in the base
-
-2001-05-22 Miguel de Icaza <miguel@ximian.com>
-
- * interface.cs, class.cs: Removed from all the sources the
- references to signature computation, as we can not do method
- signature computation during the parsing time, as we are not
- trying to solve at that point distinguishing:
-
- class X {
- void a (Blah x) {}
- void a (NS.Blah x) {}
- }
-
- Which depending on the context might be valid or not, as we do not
- know if Blah is the same thing as NS.Blah at that point.
-
- * Redid everything so the code uses TypeRefs now instead of
- Types. TypeRefs are just temporary type placeholders, that need
- to be resolved. They initially have a pointer to a string and the
- current scope in which they are used. This is used later by the
- compiler to resolve the reference to an actual Type.
-
- * DeclSpace is no longer a CIR.Type, and neither are
- TypeContainers (Class and Struct) nor Interfaces nor Enums. They
- are all DeclSpaces, but no Types.
-
- * type.cs (TypeRefManager): This implements the TypeRef manager,
- which keeps track of all the types that need to be resolved after
- the parsing has finished.
-
-2001-05-13 Miguel de Icaza <miguel@ximian.com>
-
- * ARGH. We are going to have to store `foreach' as a class rather
- than resolving it, as we need to verify error 1579 after name
- resolution. *OR* we could keep a flag that says `This request to
- IEnumerator comes from a foreach statement' which we can then use
- to generate the error.
-
-2001-05-10 Miguel de Icaza <miguel@ximian.com>
-
- * class.cs (TypeContainer.AddMethod): we now add methods to the
- MethodGroup instead of the method hashtable.
-
- * expression.cs: Add MethodGroup abstraction, which gets us one
- step closer to the specification in the way we handle method
- declarations.
-
- * cs-parser.jay (primary_expression): qualified_identifier now
- tried to match up an identifier to a local variable reference or
- to a parameter reference.
-
- current_local_parameters is now a parser global variable that
- points to the current parameters for the block, used during name
- lookup.
-
- (property_declaration): Now creates an implicit `value' argument to
- the set accessor.
-
-2001-05-09 Miguel de Icaza <miguel@ximian.com>
-
- * parameter.cs: Do not use `param' arguments as part of the
- signature, per the spec.
-
-2001-05-08 Miguel de Icaza <miguel@ximian.com>
-
- * decl.cs: Base class for classes, structs and interfaces. This
- is the "Declaration Space"
-
- * cs-parser.jay: Use CheckDef for checking declaration errors
- instead of having one on each function.
-
- * class.cs: Factor out some code for handling error handling in
- accordance to the "Declarations" section in the "Basic Concepts"
- chapter in the ECMA C# spec.
-
- * interface.cs: Make all interface member classes derive from
- InterfaceMemberBase.
-
-2001-05-07 Miguel de Icaza <miguel@ximian.com>
-
- * Many things: all interfaces are parsed and generated in
- gen-treedump. Support for member variables, constructors,
- destructors, properties, constants is there.
-
- Beginning of the IL backend, but very little done, just there for
- testing purposes.
-
-2001-04-29 Miguel de Icaza <miguel@ximian.com>
-
- * cs-parser.jay: Fix labeled statement.
-
- * cs-tokenizer.cs (escape): Escape " and ' always.
- ref_line, ref_name: keep track of the line/filename as instructed
- by #line by the compiler.
- Parse #line.
-
-2001-04-27 Miguel de Icaza <miguel@ximian.com>
-
- * System.CodeDOM/CodeBinaryOperatorExpression.cs: Rearrange enum
- to match the values in System.CodeDOM.
-
- Divid renamed to Divide.
-
- * System.CodeDOM/CodeForLoopStatement.cs: Always have valid
- statements.
- (Statements.set): remove.
-
- * System.CodeDOM/CodeCatchClause.cs: always have a valid
- statements.
-
- * System.CodeDOM/CodeIfStatement.cs: trueStatements and
- falseStatements always have valid values.
-
- * cs-parser.jay: Use System.CodeDOM now.
-
diff --git a/mcs/mcs/class.cs b/mcs/mcs/class.cs
deleted file mode 100755
index 674ce15fd6a..00000000000
--- a/mcs/mcs/class.cs
+++ /dev/null
@@ -1,4737 +0,0 @@
-//
-// class.cs: Class and Struct handlers
-//
-// Authors: Miguel de Icaza (miguel@gnu.org)
-// Martin Baulig (martin@gnome.org)
-//
-// Licensed under the terms of the GNU GPL
-//
-// (C) 2001, 2002 Ximian, Inc (http://www.ximian.com)
-//
-//
-// 2002-10-11 Miguel de Icaza <miguel@ximian.com>
-//
-// * class.cs: Following the comment from 2002-09-26 to AddMethod, I
-// have fixed a remaining problem: not every AddXXXX was adding a
-// fully qualified name.
-//
-// Now everyone registers a fully qualified name in the DeclSpace as
-// being defined instead of the partial name.
-//
-// Downsides: we are slower than we need to be due to the excess
-// copies and the names being registered this way.
-//
-// The reason for this is that we currently depend (on the corlib
-// bootstrap for instance) that types are fully qualified, because
-// we dump all the types in the namespace, and we should really have
-// types inserted into the proper namespace, so we can only store the
-// basenames in the defined_names array.
-//
-//
-#define CACHE
-using System;
-using System.Collections;
-using System.Reflection;
-using System.Reflection.Emit;
-using System.Runtime.CompilerServices;
-using System.Diagnostics.SymbolStore;
-
-namespace Mono.CSharp {
-
- /// <summary>
- /// This is the base class for structs and classes.
- /// </summary>
- public class TypeContainer : DeclSpace, IMemberContainer {
- // Holds a list of classes and structures
- ArrayList types;
-
- // Holds the list of properties
- ArrayList properties;
-
- // Holds the list of enumerations
- ArrayList enums;
-
- // Holds the list of delegates
- ArrayList delegates;
-
- // Holds the list of constructors
- ArrayList instance_constructors;
-
- // Holds the list of fields
- ArrayList fields;
-
- // Holds a list of fields that have initializers
- ArrayList initialized_fields;
-
- // Holds a list of static fields that have initializers
- ArrayList initialized_static_fields;
-
- // Holds the list of constants
- ArrayList constants;
-
- // Holds the list of
- ArrayList interfaces;
-
- // Holds order in which interfaces must be closed
- ArrayList interface_order;
-
- // Holds the methods.
- ArrayList methods;
-
- // Holds the events
- ArrayList events;
-
- // Holds the indexers
- ArrayList indexers;
-
- // Holds the operators
- ArrayList operators;
-
- // The emit context for toplevel objects.
- EmitContext ec;
-
- //
- // Pointers to the default constructor and the default static constructor
- //
- Constructor default_constructor;
- Constructor default_static_constructor;
-
- //
- // Whether we have seen a static constructor for this class or not
- //
- bool have_static_constructor = false;
-
- //
- // Whether we have at least one non-static field
- //
- bool have_nonstatic_fields = false;
-
- //
- // This one is computed after we can distinguish interfaces
- // from classes from the arraylist `type_bases'
- //
- string base_class_name;
-
- ArrayList type_bases;
-
- // Attributes for this type
- protected Attributes attributes;
-
- // Information in the case we are an attribute type
-
- public AttributeTargets Targets = AttributeTargets.All;
- public bool AllowMultiple = false;
- public bool Inherited;
-
- // The interfaces we implement.
- Type [] ifaces;
-
- // The parent member container and our member cache
- IMemberContainer parent_container;
- MemberCache member_cache;
-
- //
- // The indexer name for this class
- //
- public string IndexerName;
-
- public TypeContainer (TypeContainer parent, string name, Location l)
- : base (parent, name, l)
- {
- string n;
- types = new ArrayList ();
-
- if (parent == null)
- n = "";
- else
- n = parent.Name;
-
- base_class_name = null;
-
- //Console.WriteLine ("New class " + name + " inside " + n);
- }
-
- public AdditionResult AddConstant (Const constant)
- {
- AdditionResult res;
- string basename = constant.Name;
-
- if ((res = IsValid (basename)) != AdditionResult.Success)
- return res;
-
- if (constants == null)
- constants = new ArrayList ();
-
- constants.Add (constant);
- DefineName (Name + "." + basename, constant);
-
- return AdditionResult.Success;
- }
-
- public AdditionResult AddEnum (Mono.CSharp.Enum e)
- {
- AdditionResult res;
-
- if ((res = IsValid (e.Basename)) != AdditionResult.Success)
- return res;
-
- if (enums == null)
- enums = new ArrayList ();
-
- enums.Add (e);
- DefineName (e.Name, e);
-
- return AdditionResult.Success;
- }
-
- public AdditionResult AddClass (Class c)
- {
- AdditionResult res;
-
- if ((res = IsValid (c.Basename)) != AdditionResult.Success)
- return res;
-
- DefineName (c.Name, c);
- types.Add (c);
-
- return AdditionResult.Success;
- }
-
- public AdditionResult AddStruct (Struct s)
- {
- AdditionResult res;
-
- if ((res = IsValid (s.Basename)) != AdditionResult.Success)
- return res;
-
- DefineName (s.Name, s);
- types.Add (s);
-
- return AdditionResult.Success;
- }
-
- public AdditionResult AddDelegate (Delegate d)
- {
- AdditionResult res;
-
- if ((res = IsValid (d.Basename)) != AdditionResult.Success)
- return res;
-
- if (delegates == null)
- delegates = new ArrayList ();
-
- DefineName (d.Name, d);
- delegates.Add (d);
-
- return AdditionResult.Success;
- }
-
- public AdditionResult AddMethod (Method method)
- {
- string basename = method.Name;
- string fullname = Name + "." + basename;
-
- Object value = defined_names [fullname];
-
- if (value != null && (!(value is Method)))
- return AdditionResult.NameExists;
-
- if (basename == Basename)
- return AdditionResult.EnclosingClash;
-
- if (methods == null)
- methods = new ArrayList ();
-
- if (method.Name.IndexOf (".") != -1)
- methods.Insert (0, method);
- else
- methods.Add (method);
-
- if (value == null)
- DefineName (fullname, method);
-
- return AdditionResult.Success;
- }
-
- public AdditionResult AddConstructor (Constructor c)
- {
- if (c.Name != Basename)
- return AdditionResult.NotAConstructor;
-
- bool is_static = (c.ModFlags & Modifiers.STATIC) != 0;
-
- if (is_static){
- have_static_constructor = true;
- if (default_static_constructor != null){
- Console.WriteLine ("I have a static constructor already");
- Console.WriteLine (" " + default_static_constructor);
- return AdditionResult.MethodExists;
- }
-
- default_static_constructor = c;
- } else {
- if (c.IsDefault ()){
- if (default_constructor != null)
- return AdditionResult.MethodExists;
- default_constructor = c;
- }
-
- if (instance_constructors == null)
- instance_constructors = new ArrayList ();
-
- instance_constructors.Add (c);
- }
-
- return AdditionResult.Success;
- }
-
- public AdditionResult AddInterface (Interface iface)
- {
- AdditionResult res;
-
- if ((res = IsValid (iface.Basename)) != AdditionResult.Success)
- return res;
-
- if (interfaces == null)
- interfaces = new ArrayList ();
- interfaces.Add (iface);
- DefineName (iface.Name, iface);
-
- return AdditionResult.Success;
- }
-
- public AdditionResult AddField (Field field)
- {
- AdditionResult res;
- string basename = field.Name;
-
- if ((res = IsValid (basename)) != AdditionResult.Success)
- return res;
-
- if (fields == null)
- fields = new ArrayList ();
-
- fields.Add (field);
-
- if (field.HasInitializer){
- if ((field.ModFlags & Modifiers.STATIC) != 0){
- if (initialized_static_fields == null)
- initialized_static_fields = new ArrayList ();
-
- initialized_static_fields.Add (field);
-
- //
- // We have not seen a static constructor,
- // but we will provide static initialization of fields
- //
- have_static_constructor = true;
- } else {
- if (initialized_fields == null)
- initialized_fields = new ArrayList ();
-
- initialized_fields.Add (field);
- }
- }
-
- if ((field.ModFlags & Modifiers.STATIC) == 0)
- have_nonstatic_fields = true;
-
- DefineName (Name + "." + basename, field);
- return AdditionResult.Success;
- }
-
- public AdditionResult AddProperty (Property prop)
- {
- AdditionResult res;
- string basename = prop.Name;
-
- if ((res = IsValid (basename)) != AdditionResult.Success)
- return res;
-
- if (properties == null)
- properties = new ArrayList ();
-
- if (prop.Name.IndexOf (".") != -1)
- properties.Insert (0, prop);
- else
- properties.Add (prop);
- DefineName (Name + "." + basename, prop);
-
- return AdditionResult.Success;
- }
-
- public AdditionResult AddEvent (Event e)
- {
- AdditionResult res;
- string basename = e.Name;
-
- if ((res = IsValid (basename)) != AdditionResult.Success)
- return res;
-
- if (events == null)
- events = new ArrayList ();
-
- events.Add (e);
- DefineName (Name + "." + basename, e);
-
- return AdditionResult.Success;
- }
-
- public AdditionResult AddIndexer (Indexer i)
- {
- if (indexers == null)
- indexers = new ArrayList ();
-
- if (i.InterfaceType != null)
- indexers.Insert (0, i);
- else
- indexers.Add (i);
-
- return AdditionResult.Success;
- }
-
- public AdditionResult AddOperator (Operator op)
- {
- if (operators == null)
- operators = new ArrayList ();
-
- operators.Add (op);
-
- return AdditionResult.Success;
- }
-
- public void RegisterOrder (Interface iface)
- {
- if (interface_order == null)
- interface_order = new ArrayList ();
-
- interface_order.Add (iface);
- }
-
- public ArrayList Types {
- get {
- return types;
- }
- }
-
- public ArrayList Methods {
- get {
- return methods;
- }
- }
-
- public ArrayList Constants {
- get {
- return constants;
- }
- }
-
- public ArrayList Interfaces {
- get {
- return interfaces;
- }
- }
-
- public string Base {
- get {
- return base_class_name;
- }
- }
-
- public ArrayList Bases {
- get {
- return type_bases;
- }
-
- set {
- type_bases = value;
- }
- }
-
- public ArrayList Fields {
- get {
- return fields;
- }
-
- set {
- fields = value;
- }
- }
-
- public ArrayList InstanceConstructors {
- get {
- return instance_constructors;
- }
- }
-
- public ArrayList Properties {
- get {
- return properties;
- }
- }
-
- public ArrayList Events {
- get {
- return events;
- }
- }
-
- public ArrayList Enums {
- get {
- return enums;
- }
- }
-
- public ArrayList Indexers {
- get {
- return indexers;
- }
- }
-
- public ArrayList Operators {
- get {
- return operators;
- }
- }
-
- public ArrayList Delegates {
- get {
- return delegates;
- }
- }
-
- public Attributes OptAttributes {
- get {
- return attributes;
- }
- }
-
- public bool HaveStaticConstructor {
- get {
- return have_static_constructor;
- }
- }
-
- public virtual TypeAttributes TypeAttr {
- get {
- return Modifiers.TypeAttr (ModFlags, this);
- }
- }
-
- //
- // Emits the instance field initializers
- //
- public bool EmitFieldInitializers (EmitContext ec)
- {
- ArrayList fields;
- ILGenerator ig = ec.ig;
- Expression instance_expr;
-
- if (ec.IsStatic){
- fields = initialized_static_fields;
- instance_expr = null;
- } else {
- fields = initialized_fields;
- instance_expr = new This (Location.Null).Resolve (ec);
- }
-
- if (fields == null)
- return true;
-
- foreach (Field f in fields){
- Expression e = f.GetInitializerExpression (ec);
- if (e == null)
- return false;
-
- Location l = f.Location;
- FieldExpr fe = new FieldExpr (f.FieldBuilder, l);
- fe.InstanceExpression = instance_expr;
- Expression a = new Assign (fe, e, l);
-
- a = a.Resolve (ec);
- if (a == null)
- return false;
-
- if (a is ExpressionStatement)
- ((ExpressionStatement) a).EmitStatement (ec);
- else {
- throw new Exception ("Assign.Resolve returned a non ExpressionStatement");
- }
- }
-
- return true;
- }
-
- //
- // Defines the default constructors
- //
- void DefineDefaultConstructor (bool is_static)
- {
- Constructor c;
- int mods = 0;
-
- c = new Constructor (Basename, Parameters.EmptyReadOnlyParameters,
- new ConstructorBaseInitializer (
- null, Parameters.EmptyReadOnlyParameters,
- Location.Null),
- Location.Null);
-
- if (is_static)
- mods = Modifiers.STATIC;
-
- c.ModFlags = mods;
-
- AddConstructor (c);
-
- c.Block = new Block (null);
-
- }
-
- public void ReportStructInitializedInstanceError ()
- {
- string n = TypeBuilder.FullName;
-
- foreach (Field f in initialized_fields){
- Report.Error (
- 573, Location,
- "`" + n + "." + f.Name + "': can not have " +
- "instance field initializers in structs");
- }
- }
-
- /// <remarks>
- /// The pending methods that need to be implemented (interfaces or abstract methods)
- /// </remarks>
- public PendingImplementation Pending;
-
- /// <summary>
- /// This function computes the Base class and also the
- /// list of interfaces that the class or struct @c implements.
- ///
- /// The return value is an array (might be null) of
- /// interfaces implemented (as Types).
- ///
- /// The @parent argument is set to the parent object or null
- /// if this is `System.Object'.
- /// </summary>
- Type [] GetClassBases (bool is_class, out Type parent, out bool error)
- {
- ArrayList bases = Bases;
- int count;
- int start, j, i;
-
- error = false;
-
- if (is_class)
- parent = null;
- else
- parent = TypeManager.value_type;
-
- if (bases == null){
- if (is_class){
- if (RootContext.StdLib)
- parent = TypeManager.object_type;
- else if (Name != "System.Object")
- parent = TypeManager.object_type;
- } else {
- //
- // If we are compiling our runtime,
- // and we are defining ValueType, then our
- // parent is `System.Object'.
- //
- if (!RootContext.StdLib && Name == "System.ValueType")
- parent = TypeManager.object_type;
- }
-
- return null;
- }
-
- //
- // Bases should be null if there are no bases at all
- //
- count = bases.Count;
-
- if (is_class){
- Expression name = (Expression) bases [0];
- name = ResolveTypeExpr (name, false, Location);
-
- if (name == null){
- error = true;
- return null;
- }
-
- Type first = name.Type;
-
- if (first.IsClass){
- parent = first;
- start = 1;
- } else {
- parent = TypeManager.object_type;
- start = 0;
- }
-
- if (!AsAccessible (parent, ModFlags))
- Report.Error (60, Location,
- "Inconsistent accessibility: base class `" +
- TypeManager.CSharpName (parent) + "' is less " +
- "accessible than class `" +
- Name + "'");
-
- } else {
- start = 0;
- }
-
- Type [] ifaces = new Type [count-start];
-
- for (i = start, j = 0; i < count; i++, j++){
- Expression name = (Expression) bases [i];
- Expression resolved = ResolveTypeExpr (name, false, Location);
- if (resolved == null)
- return null;
-
- bases [i] = resolved;
- Type t = resolved.Type;
-
- if (t == null){
- error = true;
- return null;
- }
-
- if (is_class == false && !t.IsInterface){
- Report.Error (527, "In Struct `" + Name + "', type `"+
- name +"' is not an interface");
- error = true;
- return null;
- }
-
- if (t.IsSealed) {
- string detail = "";
-
- if (t.IsValueType)
- detail = " (a class can not inherit from a struct/enum)";
-
- Report.Error (509, "class `"+ Name +
- "': Cannot inherit from sealed class `"+
- bases [i]+"'"+detail);
- error = true;
- return null;
- }
-
- if (t.IsClass) {
- if (parent != null){
- Report.Error (527, "In Class `" + Name + "', type `"+
- name+"' is not an interface");
- error = true;
- return null;
- }
- }
-
- for (int x = 0; x < j; x++) {
- if (t == ifaces [x]) {
- Report.Error (528, "`" + name + "' is already listed in interface list");
- error = true;
- return null;
- }
- }
-
- ifaces [j] = t;
- }
-
- return TypeManager.ExpandInterfaces (ifaces);
- }
-
- //
- // Defines the type in the appropriate ModuleBuilder or TypeBuilder.
- //
- public override TypeBuilder DefineType ()
- {
- Type parent;
- bool error;
- bool is_class;
-
- if (TypeBuilder != null)
- return TypeBuilder;
-
- if (InTransit)
- return null;
-
- InTransit = true;
-
- if (this is Class)
- is_class = true;
- else
- is_class = false;
-
- ec = new EmitContext (this, Mono.CSharp.Location.Null, null, null, ModFlags);
-
- ifaces = GetClassBases (is_class, out parent, out error);
-
- if (error)
- return null;
-
- if (is_class && parent != null){
- if (parent == TypeManager.enum_type ||
- (parent == TypeManager.value_type && RootContext.StdLib) ||
- parent == TypeManager.delegate_type ||
- parent == TypeManager.array_type){
- Report.Error (
- 644, Location, "`" + Name + "' cannot inherit from " +
- "special class `" + TypeManager.CSharpName (parent) + "'");
- return null;
- }
- }
-
- if (!is_class && TypeManager.value_type == null)
- throw new Exception ();
-
- TypeAttributes type_attributes = TypeAttr;
-
- // if (parent_builder is ModuleBuilder) {
- if (IsTopLevel){
- ModuleBuilder builder = CodeGen.ModuleBuilder;
- TypeBuilder = builder.DefineType (
- Name, type_attributes, parent, ifaces);
-
- } else {
- TypeBuilder builder = Parent.TypeBuilder;
- TypeBuilder = builder.DefineNestedType (
- Basename, type_attributes, parent, ifaces);
- }
-
- //
- // Structs with no fields need to have at least one byte.
- // The right thing would be to set the PackingSize in a DefineType
- // but there are no functions that allow interfaces *and* the size to
- // be specified.
- //
-
- if (!is_class && !have_nonstatic_fields){
- TypeBuilder.DefineField ("$PRIVATE$", TypeManager.byte_type,
- FieldAttributes.Private);
- }
-
- // add interfaces that were not added at type creation (weird API issue)
- if (!is_class && !have_nonstatic_fields && (ifaces != null)) {
- foreach (Type i in ifaces)
- TypeBuilder.AddInterfaceImplementation (i);
- }
-
- //
- // Finish the setup for the EmitContext
- //
- ec.ContainerType = TypeBuilder;
-
- TypeManager.AddUserType (Name, TypeBuilder, this, ifaces);
-
- if ((parent != null) &&
- (parent == TypeManager.attribute_type ||
- parent.IsSubclassOf (TypeManager.attribute_type))) {
- RootContext.RegisterAttribute (this);
- TypeManager.RegisterAttrType (TypeBuilder, this);
- } else
- RootContext.RegisterOrder (this);
-
- if (Interfaces != null) {
- foreach (Interface iface in Interfaces)
- iface.DefineType ();
- }
-
- if (Types != null) {
- foreach (TypeContainer tc in Types)
- tc.DefineType ();
- }
-
- if (Delegates != null) {
- foreach (Delegate d in Delegates)
- d.DefineType ();
- }
-
- if (Enums != null) {
- foreach (Enum en in Enums)
- en.DefineType ();
- }
-
- InTransit = false;
- return TypeBuilder;
- }
-
-
- /// <summary>
- /// Defines the MemberCore objects that are in the `list' Arraylist
- ///
- /// The `defined_names' array contains a list of members defined in
- /// a base class
- /// </summary>
- static ArrayList remove_list = new ArrayList ();
- void DefineMembers (ArrayList list, MemberInfo [] defined_names)
- {
- int idx;
-
- remove_list.Clear ();
-
- foreach (MemberCore mc in list){
- if (!mc.Define (this)){
- remove_list.Add (mc);
- continue;
- }
-
- if (defined_names == null)
- continue;
-
- idx = Array.BinarySearch (defined_names, mc.Name, mif_compare);
- if (idx < 0){
- if (RootContext.WarningLevel >= 4){
- if ((mc.ModFlags & Modifiers.NEW) != 0)
- Warning_KewywordNewNotRequired (mc.Location, mc);
- }
- continue;
- }
-
- MemberInfo match = defined_names [idx];
-
- if (match is PropertyInfo && ((mc.ModFlags & Modifiers.OVERRIDE) != 0))
- continue;
-
- //
- // If we are both methods, let the method resolution emit warnings
- //
- if (match is MethodBase && mc is MethodCore)
- continue;
-
- if ((mc.ModFlags & Modifiers.NEW) == 0)
- Warning_KeywordNewRequired (mc.Location, defined_names [idx]);
- }
-
- foreach (object o in remove_list)
- list.Remove (o);
-
- remove_list.Clear ();
- }
-
- //
- // Defines the indexers, and also verifies that the IndexerNameAttribute in the
- // class is consisten. Either it is `Item' or it is the name defined by all the
- // indexers with the `IndexerName' attribute.
- //
- // Turns out that the IndexerNameAttribute is applied to each indexer,
- // but it is never emitted, instead a DefaultName attribute is attached
- // to the class.
- //
- void DefineIndexers ()
- {
- string class_indexer_name = null;
-
- foreach (Indexer i in Indexers){
- string name;
-
- i.Define (this);
-
- name = i.IndexerName;
-
- if (i.InterfaceType != null)
- continue;
-
- if (class_indexer_name == null){
- class_indexer_name = name;
- continue;
- }
-
- if (name == class_indexer_name)
- continue;
-
- Report.Error (
- 668, "Two indexers have different names, " +
- " you should use the same name for all your indexers");
- }
- if (class_indexer_name == null)
- class_indexer_name = "Item";
- IndexerName = class_indexer_name;
- }
-
- static void Error_KeywordNotAllowed (Location loc)
- {
- Report.Error (1530, loc, "Keyword new not allowed for namespace elements");
- }
-
- /// <summary>
- /// Populates our TypeBuilder with fields and methods
- /// </summary>
- public override bool DefineMembers (TypeContainer parent)
- {
- MemberInfo [] defined_names = null;
-
- if (interface_order != null){
- foreach (Interface iface in interface_order)
- if ((iface.ModFlags & Modifiers.NEW) == 0)
- iface.DefineMembers (this);
- else
- Error_KeywordNotAllowed (iface.Location);
- }
-
- if (RootContext.WarningLevel > 1){
- Type ptype;
-
- //
- // This code throws an exception in the comparer
- // I guess the string is not an object?
- //
- ptype = TypeBuilder.BaseType;
- if (ptype != null){
- defined_names = (MemberInfo []) FindMembers (
- ptype, MemberTypes.All & ~MemberTypes.Constructor,
- BindingFlags.Public | BindingFlags.Instance |
- BindingFlags.Static, null, null);
-
- Array.Sort (defined_names, mif_compare);
- }
- }
-
- if (constants != null)
- DefineMembers (constants, defined_names);
-
- if (fields != null)
- DefineMembers (fields, defined_names);
-
- if (this is Class){
- if (instance_constructors == null){
- if (default_constructor == null)
- DefineDefaultConstructor (false);
- }
-
- if (initialized_static_fields != null &&
- default_static_constructor == null)
- DefineDefaultConstructor (true);
- }
-
- if (this is Struct){
- //
- // Structs can not have initialized instance
- // fields
- //
- if (initialized_static_fields != null &&
- default_static_constructor == null)
- DefineDefaultConstructor (true);
-
- if (initialized_fields != null)
- ReportStructInitializedInstanceError ();
- }
-
- Pending = PendingImplementation.GetPendingImplementations (this);
-
- //
- // Constructors are not in the defined_names array
- //
- if (instance_constructors != null)
- DefineMembers (instance_constructors, null);
-
- if (default_static_constructor != null)
- default_static_constructor.Define (this);
-
- if (methods != null)
- DefineMembers (methods, defined_names);
-
- if (properties != null)
- DefineMembers (properties, defined_names);
-
- if (events != null)
- DefineMembers (events, defined_names);
-
- if (indexers != null) {
- DefineIndexers ();
- } else
- IndexerName = "Item";
-
- if (operators != null){
- DefineMembers (operators, null);
-
- CheckPairedOperators ();
- }
-
- if (enums != null)
- DefineMembers (enums, defined_names);
-
- if (delegates != null)
- DefineMembers (delegates, defined_names);
-
-#if CACHE
- if (TypeBuilder.BaseType != null)
- parent_container = TypeManager.LookupMemberContainer (TypeBuilder.BaseType);
-
- member_cache = new MemberCache (this);
-#endif
-
- return true;
- }
-
- public override bool Define (TypeContainer parent)
- {
- if (interface_order != null){
- foreach (Interface iface in interface_order)
- if ((iface.ModFlags & Modifiers.NEW) == 0)
- iface.Define (this);
- }
-
- return true;
- }
-
- /// <summary>
- /// This function is based by a delegate to the FindMembers routine
- /// </summary>
- static bool AlwaysAccept (MemberInfo m, object filterCriteria)
- {
- return true;
- }
-
- /// <summary>
- /// This filter is used by FindMembers, and we just keep
- /// a global for the filter to `AlwaysAccept'
- /// </summary>
- static MemberFilter accepting_filter;
-
-
- /// <summary>
- /// A member comparission method based on name only
- /// </summary>
- static IComparer mif_compare;
-
- static TypeContainer ()
- {
- accepting_filter = new MemberFilter (AlwaysAccept);
- mif_compare = new MemberInfoCompare ();
- }
-
- /// <summary>
- /// This method returns the members of this type just like Type.FindMembers would
- /// Only, we need to use this for types which are _being_ defined because MS'
- /// implementation can't take care of that.
- /// </summary>
- //
- // FIXME: return an empty static array instead of null, that cleans up
- // some code and is consistent with some coding conventions I just found
- // out existed ;-)
- //
- //
- // Notice that in various cases we check if our field is non-null,
- // something that would normally mean that there was a bug elsewhere.
- //
- // The problem happens while we are defining p-invoke methods, as those
- // will trigger a FindMembers, but this happens before things are defined
- //
- // Since the whole process is a no-op, it is fine to check for null here.
- //
- public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
- MemberFilter filter, object criteria)
- {
- ArrayList members = new ArrayList ();
-
- int modflags = 0;
- if ((bf & BindingFlags.Public) != 0)
- modflags |= Modifiers.PUBLIC | Modifiers.PROTECTED |
- Modifiers.INTERNAL;
- if ((bf & BindingFlags.NonPublic) != 0)
- modflags |= Modifiers.PRIVATE;
-
- int static_mask = 0, static_flags = 0;
- switch (bf & (BindingFlags.Static | BindingFlags.Instance)) {
- case BindingFlags.Static:
- static_mask = static_flags = Modifiers.STATIC;
- break;
-
- case BindingFlags.Instance:
- static_mask = Modifiers.STATIC;
- static_flags = 0;
- break;
-
- default:
- static_mask = static_flags = 0;
- break;
- }
-
- Timer.StartTimer (TimerType.TcFindMembers);
-
- if (filter == null)
- filter = accepting_filter;
-
- if ((mt & MemberTypes.Field) != 0) {
- if (fields != null) {
- foreach (Field f in fields) {
- if ((f.ModFlags & modflags) == 0)
- continue;
- if ((f.ModFlags & static_mask) != static_flags)
- continue;
-
- FieldBuilder fb = f.FieldBuilder;
- if (fb != null && filter (fb, criteria) == true)
- members.Add (fb);
- }
- }
-
- if (constants != null) {
- foreach (Const con in constants) {
- if ((con.ModFlags & modflags) == 0)
- continue;
- if ((con.ModFlags & static_mask) != static_flags)
- continue;
-
- FieldBuilder fb = con.FieldBuilder;
- if (fb != null && filter (fb, criteria) == true)
- members.Add (fb);
- }
- }
- }
-
- if ((mt & MemberTypes.Method) != 0) {
- if (methods != null) {
- foreach (Method m in methods) {
- if ((m.ModFlags & modflags) == 0)
- continue;
- if ((m.ModFlags & static_mask) != static_flags)
- continue;
-
- MethodBuilder mb = m.MethodBuilder;
-
- if (mb != null && filter (mb, criteria) == true)
- members.Add (mb);
- }
- }
-
- if (operators != null){
- foreach (Operator o in operators) {
- if ((o.ModFlags & modflags) == 0)
- continue;
- if ((o.ModFlags & static_mask) != static_flags)
- continue;
-
- MethodBuilder ob = o.OperatorMethodBuilder;
- if (ob != null && filter (ob, criteria) == true)
- members.Add (ob);
- }
- }
-
- if (properties != null){
- foreach (Property p in properties){
- if ((p.ModFlags & modflags) == 0)
- continue;
- if ((p.ModFlags & static_mask) != static_flags)
- continue;
-
- MethodBuilder b;
-
- b = p.GetBuilder;
- if (b != null && filter (b, criteria) == true)
- members.Add (b);
-
- b = p.SetBuilder;
- if (b != null && filter (b, criteria) == true)
- members.Add (b);
- }
- }
-
- if (indexers != null){
- foreach (Indexer ix in indexers){
- if ((ix.ModFlags & modflags) == 0)
- continue;
- if ((ix.ModFlags & static_mask) != static_flags)
- continue;
-
- MethodBuilder b;
-
- b = ix.GetBuilder;
- if (b != null && filter (b, criteria) == true)
- members.Add (b);
-
- b = ix.SetBuilder;
- if (b != null && filter (b, criteria) == true)
- members.Add (b);
- }
- }
- }
-
- if ((mt & MemberTypes.Event) != 0) {
- if (events != null)
- foreach (Event e in events) {
- if ((e.ModFlags & modflags) == 0)
- continue;
- if ((e.ModFlags & static_mask) != static_flags)
- continue;
-
- MemberInfo eb = e.EventBuilder;
- if (eb != null && filter (eb, criteria) == true)
- members.Add (e.EventBuilder);
- }
- }
-
- if ((mt & MemberTypes.Property) != 0){
- if (properties != null)
- foreach (Property p in properties) {
- if ((p.ModFlags & modflags) == 0)
- continue;
- if ((p.ModFlags & static_mask) != static_flags)
- continue;
-
- MemberInfo pb = p.PropertyBuilder;
- if (pb != null && filter (pb, criteria) == true) {
- members.Add (p.PropertyBuilder);
- }
- }
-
- if (indexers != null)
- foreach (Indexer ix in indexers) {
- if ((ix.ModFlags & modflags) == 0)
- continue;
- if ((ix.ModFlags & static_mask) != static_flags)
- continue;
-
- MemberInfo ib = ix.PropertyBuilder;
- if (ib != null && filter (ib, criteria) == true) {
- members.Add (ix.PropertyBuilder);
- }
- }
- }
-
- if ((mt & MemberTypes.NestedType) != 0) {
- if (types != null){
- foreach (TypeContainer t in types) {
- if ((t.ModFlags & modflags) == 0)
- continue;
-
- TypeBuilder tb = t.TypeBuilder;
- if (tb != null && (filter (tb, criteria) == true))
- members.Add (tb);
- }
- }
-
- if (enums != null){
- foreach (Enum en in enums){
- if ((en.ModFlags & modflags) == 0)
- continue;
-
- TypeBuilder tb = en.TypeBuilder;
- if (tb != null && (filter (tb, criteria) == true))
- members.Add (tb);
- }
- }
-
- if (delegates != null){
- foreach (Delegate d in delegates){
- if ((d.ModFlags & modflags) == 0)
- continue;
-
- TypeBuilder tb = d.TypeBuilder;
- if (tb != null && (filter (tb, criteria) == true))
- members.Add (tb);
- }
- }
-
- if (interfaces != null){
- foreach (Interface iface in interfaces){
- if ((iface.ModFlags & modflags) == 0)
- continue;
-
- TypeBuilder tb = iface.TypeBuilder;
- if (tb != null && (filter (tb, criteria) == true))
- members.Add (tb);
- }
- }
- }
-
- if ((mt & MemberTypes.Constructor) != 0){
- if (((bf & BindingFlags.Instance) != 0) && (instance_constructors != null)){
- foreach (Constructor c in instance_constructors){
- ConstructorBuilder cb = c.ConstructorBuilder;
- if (cb != null)
- if (filter (cb, criteria) == true)
- members.Add (cb);
- }
- }
-
- if (((bf & BindingFlags.Static) != 0) && (default_static_constructor != null)){
- ConstructorBuilder cb =
- default_static_constructor.ConstructorBuilder;
-
- if (cb != null)
- if (filter (cb, criteria) == true)
- members.Add (cb);
- }
- }
-
- //
- // Lookup members in parent if requested.
- //
- if (((bf & BindingFlags.DeclaredOnly) == 0) && (TypeBuilder.BaseType != null)) {
- MemberList list = FindMembers (TypeBuilder.BaseType, mt, bf, filter, criteria);
- members.AddRange (list);
- }
-
- Timer.StopTimer (TimerType.TcFindMembers);
-
- return new MemberList (members);
- }
-
- public override MemberCache MemberCache {
- get {
- return member_cache;
- }
- }
-
- public static MemberList FindMembers (Type t, MemberTypes mt, BindingFlags bf,
- MemberFilter filter, object criteria)
- {
- TypeContainer tc = TypeManager.LookupTypeContainer (t);
-
- if (tc != null)
- return tc.FindMembers (mt, bf, filter, criteria);
- else
- return new MemberList (t.FindMembers (mt, bf, filter, criteria));
- }
-
- //
- // FindMethods will look for methods not only in the type `t', but in
- // any interfaces implemented by the type.
- //
- public static MethodInfo [] FindMethods (Type t, BindingFlags bf,
- MemberFilter filter, object criteria)
- {
- return null;
- }
-
- /// <summary>
- /// Emits the values for the constants
- /// </summary>
- public void EmitConstants ()
- {
- if (constants != null)
- foreach (Const con in constants)
- con.EmitConstant (this);
- return;
- }
-
- /// <summary>
- /// Emits the code, this step is performed after all
- /// the types, enumerations, constructors
- /// </summary>
- public void Emit ()
- {
- if (instance_constructors != null)
- foreach (Constructor c in instance_constructors)
- c.Emit (this);
-
- if (default_static_constructor != null)
- default_static_constructor.Emit (this);
-
- if (methods != null)
- foreach (Method m in methods)
- m.Emit (this);
-
- if (operators != null)
- foreach (Operator o in operators)
- o.Emit (this);
-
- if (properties != null)
- foreach (Property p in properties)
- p.Emit (this);
-
- if (indexers != null){
- foreach (Indexer ix in indexers)
- ix.Emit (this);
-
- CustomAttributeBuilder cb = Interface.EmitDefaultMemberAttr (
- this, IndexerName, ModFlags, Location);
- TypeBuilder.SetCustomAttribute (cb);
- }
-
- if (fields != null)
- foreach (Field f in fields)
- f.Emit (this);
-
- if (events != null){
- foreach (Event e in Events)
- e.Emit (this);
- }
-
- if (Pending != null)
- if (Pending.VerifyPendingMethods ())
- return;
-
- Attribute.ApplyAttributes (ec, TypeBuilder, this, OptAttributes, Location);
-
- //
- // Check for internal or private fields that were never assigned
- //
- if (RootContext.WarningLevel >= 3) {
- if (fields != null){
- foreach (Field f in fields) {
- if ((f.ModFlags & Modifiers.PUBLIC) != 0)
- continue;
-
- if (f.status == 0){
- Report.Warning (
- 169, f.Location, "Private field " +
- MakeName (f.Name) + " is never used");
- continue;
- }
-
- //
- // Only report 649 on level 4
- //
- if (RootContext.WarningLevel < 4)
- continue;
-
- if ((f.status & Field.Status.ASSIGNED) != 0)
- continue;
-
- Report.Warning (
- 649, f.Location,
- "Field " + MakeName (f.Name) + " is never assigned " +
- " to and will always have its default value");
- }
- }
-
- if (events != null){
- foreach (Event e in events){
- if (e.status == 0)
- Report.Warning (67, "The event " + MakeName (e.Name) + " is never used");
- }
- }
- }
-
-// if (types != null)
-// foreach (TypeContainer tc in types)
-// tc.Emit ();
- }
-
- public override void CloseType ()
- {
- try {
- if (!Created){
- Created = true;
- TypeBuilder.CreateType ();
- }
- } catch (TypeLoadException){
- //
- // This is fine, the code still created the type
- //
-// Report.Warning (-20, "Exception while creating class: " + TypeBuilder.Name);
-// Console.WriteLine (e.Message);
- } catch {
- Console.WriteLine ("In type: " + Name);
- throw;
- }
-
- if (Enums != null)
- foreach (Enum en in Enums)
- en.CloseType ();
-
- if (interface_order != null){
- foreach (Interface iface in interface_order)
- iface.CloseType ();
- }
-
- if (Types != null){
- foreach (TypeContainer tc in Types)
- if (tc is Struct)
- tc.CloseType ();
-
- foreach (TypeContainer tc in Types)
- if (!(tc is Struct))
- tc.CloseType ();
- }
-
- if (Delegates != null)
- foreach (Delegate d in Delegates)
- d.CloseType ();
- }
-
- public string MakeName (string n)
- {
- return "`" + Name + "." + n + "'";
- }
-
- public void Warning_KeywordNewRequired (Location l, MemberInfo mi)
- {
- Report.Warning (
- 108, l, "The keyword new is required on " +
- MakeName (mi.Name) + " because it hides `" +
- mi.ReflectedType.Name + "." + mi.Name + "'");
- }
-
- public void Warning_KewywordNewNotRequired (Location l, MemberCore mc)
- {
- Report.Warning (
- 109, l, "The member " + MakeName (mc.Name) + " does not hide an " +
- "inherited member, the keyword new is not required");
- }
-
- public static int CheckMember (string name, MemberInfo mi, int ModFlags)
- {
- return 0;
- }
-
- //
- // Performs the validation on a Method's modifiers (properties have
- // the same properties).
- //
- public bool MethodModifiersValid (int flags, string n, Location loc)
- {
- const int vao = (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE);
- const int va = (Modifiers.VIRTUAL | Modifiers.ABSTRACT);
- const int nv = (Modifiers.NEW | Modifiers.VIRTUAL);
- bool ok = true;
- string name = MakeName (n);
-
- //
- // At most one of static, virtual or override
- //
- if ((flags & Modifiers.STATIC) != 0){
- if ((flags & vao) != 0){
- Report.Error (
- 112, loc, "static method " + name + "can not be marked " +
- "as virtual, abstract or override");
- ok = false;
- }
- }
-
- if (this is Struct){
- if ((flags & va) != 0){
- Modifiers.Error_InvalidModifier (loc, "virtual or abstract");
- ok = false;
- }
- }
-
- if ((flags & Modifiers.OVERRIDE) != 0 && (flags & nv) != 0){
- Report.Error (
- 113, loc, name +
- " marked as override cannot be marked as new or virtual");
- ok = false;
- }
-
- //
- // If the declaration includes the abstract modifier, then the
- // declaration does not include static, virtual or extern
- //
- if ((flags & Modifiers.ABSTRACT) != 0){
- if ((flags & Modifiers.EXTERN) != 0){
- Report.Error (
- 180, loc, name + " can not be both abstract and extern");
- ok = false;
- }
-
- if ((flags & Modifiers.VIRTUAL) != 0){
- Report.Error (
- 503, loc, name + " can not be both abstract and virtual");
- ok = false;
- }
-
- if ((ModFlags & Modifiers.ABSTRACT) == 0){
- Report.Error (
- 513, loc, name +
- " is abstract but its container class is not");
- ok = false;
-
- }
- }
-
- if ((flags & Modifiers.PRIVATE) != 0){
- if ((flags & vao) != 0){
- Report.Error (
- 621, loc, name +
- " virtual or abstract members can not be private");
- ok = false;
- }
- }
-
- if ((flags & Modifiers.SEALED) != 0){
- if ((flags & Modifiers.OVERRIDE) == 0){
- Report.Error (
- 238, loc, name +
- " cannot be sealed because it is not an override");
- ok = false;
- }
- }
-
- return ok;
- }
-
- // Access level of a type.
- enum AccessLevel {
- Public = 0,
- ProtectedInternal = 1,
- Internal = 2,
- Protected = 3,
- Private = 4
- }
-
- // Check whether `flags' denotes a more restricted access than `level'
- // and return the new level.
- static AccessLevel CheckAccessLevel (AccessLevel level, int flags)
- {
- AccessLevel old_level = level;
-
- if ((flags & Modifiers.INTERNAL) != 0) {
- if ((flags & Modifiers.PROTECTED) != 0) {
- if ((int) level < (int) AccessLevel.ProtectedInternal)
- level = AccessLevel.ProtectedInternal;
- } else {
- if ((int) level < (int) AccessLevel.Internal)
- level = AccessLevel.Internal;
- }
- } else if ((flags & Modifiers.PROTECTED) != 0) {
- if ((int) level < (int) AccessLevel.Protected)
- level = AccessLevel.Protected;
- } else if ((flags & Modifiers.PRIVATE) != 0)
- level = AccessLevel.Private;
-
- return level;
- }
-
- // Return the access level for a new member which is defined in the current
- // TypeContainer with access modifiers `flags'.
- AccessLevel GetAccessLevel (int flags)
- {
- if ((flags & Modifiers.PRIVATE) != 0)
- return AccessLevel.Private;
-
- AccessLevel level;
- if (!IsTopLevel && (Parent != null))
- level = Parent.GetAccessLevel (flags);
- else
- level = AccessLevel.Public;
-
- return CheckAccessLevel (CheckAccessLevel (level, flags), ModFlags);
- }
-
- // Return the access level for type `t', but don't give more access than `flags'.
- static AccessLevel GetAccessLevel (Type t, int flags)
- {
- if (((flags & Modifiers.PRIVATE) != 0) || t.IsNestedPrivate)
- return AccessLevel.Private;
-
- AccessLevel level;
- if (TypeManager.IsBuiltinType (t))
- return AccessLevel.Public;
- else if ((t.DeclaringType != null) && (t != t.DeclaringType))
- level = GetAccessLevel (t.DeclaringType, flags);
- else {
- level = CheckAccessLevel (AccessLevel.Public, flags);
- }
-
- if (t.IsNestedPublic)
- return level;
-
- if (t.IsNestedAssembly || t.IsNotPublic) {
- if ((int) level < (int) AccessLevel.Internal)
- level = AccessLevel.Internal;
- }
-
- if (t.IsNestedFamily) {
- if ((int) level < (int) AccessLevel.Protected)
- level = AccessLevel.Protected;
- }
-
- if (t.IsNestedFamORAssem) {
- if ((int) level < (int) AccessLevel.ProtectedInternal)
- level = AccessLevel.ProtectedInternal;
- }
-
- return level;
- }
-
- //
- // Returns true if `parent' is as accessible as the flags `flags'
- // given for this member.
- //
- public bool AsAccessible (Type parent, int flags)
- {
- while (parent.IsArray || parent.IsPointer || parent.IsByRef)
- parent = parent.GetElementType ();
-
- AccessLevel level = GetAccessLevel (flags);
- AccessLevel level2 = GetAccessLevel (parent, flags);
-
- return (int) level >= (int) level2;
- }
-
- Hashtable builder_and_args;
-
- public bool RegisterMethod (MethodBuilder mb, InternalParameters ip, Type [] args)
- {
- if (builder_and_args == null)
- builder_and_args = new Hashtable ();
- return true;
- }
-
- /// <summary>
- /// Performs checks for an explicit interface implementation. First it
- /// checks whether the `interface_type' is a base inteface implementation.
- /// Then it checks whether `name' exists in the interface type.
- /// </summary>
- public bool VerifyImplements (Type interface_type, string full, string name, Location loc)
- {
- bool found = false;
-
- if (ifaces != null){
- foreach (Type t in ifaces){
- if (t == interface_type){
- found = true;
- break;
- }
- }
- }
-
- if (!found){
- Report.Error (540, "`" + full + "': containing class does not implement interface `" + interface_type.FullName + "'");
- return false;
- }
-
- return true;
- }
-
- public static void Error_ExplicitInterfaceNotMemberInterface (Location loc, string name)
- {
- Report.Error (539, loc, "Explicit implementation: `" + name + "' is not a member of the interface");
- }
-
- //
- // IMemberContainer
- //
-
- string IMemberContainer.Name {
- get {
- return Name;
- }
- }
-
- Type IMemberContainer.Type {
- get {
- return TypeBuilder;
- }
- }
-
- IMemberContainer IMemberContainer.Parent {
- get {
- return parent_container;
- }
- }
-
- MemberCache IMemberContainer.MemberCache {
- get {
- return member_cache;
- }
- }
-
- bool IMemberContainer.IsInterface {
- get {
- return false;
- }
- }
-
- MemberList IMemberContainer.GetMembers (MemberTypes mt, BindingFlags bf)
- {
- return FindMembers (mt, bf | BindingFlags.DeclaredOnly, null, null);
- }
-
- //
- // Operator pair checking
- //
-
- class OperatorEntry {
- public int flags;
- public Type ret_type;
- public Type type1, type2;
- public Operator op;
- public Operator.OpType ot;
-
- public OperatorEntry (int f, Operator o)
- {
- flags = f;
-
- ret_type = o.OperatorMethod.GetReturnType ();
- Type [] pt = o.OperatorMethod.ParameterTypes;
- type1 = pt [0];
- type2 = pt [1];
- op = o;
- ot = o.OperatorType;
- }
-
- public override int GetHashCode ()
- {
- return ret_type.GetHashCode ();
- }
-
- public override bool Equals (object o)
- {
- OperatorEntry other = (OperatorEntry) o;
-
- if (other.ret_type != ret_type)
- return false;
- if (other.type1 != type1)
- return false;
- if (other.type2 != type2)
- return false;
- return true;
- }
- }
-
- //
- // Checks that some operators come in pairs:
- // == and !=
- // > and <
- // >= and <=
- //
- // They are matched based on the return type and the argument types
- //
- void CheckPairedOperators ()
- {
- Hashtable pairs = new Hashtable (null, null);
-
- // Register all the operators we care about.
- foreach (Operator op in operators){
- int reg = 0;
-
- switch (op.OperatorType){
- case Operator.OpType.Equality:
- reg = 1; break;
- case Operator.OpType.Inequality:
- reg = 2; break;
-
- case Operator.OpType.GreaterThan:
- reg = 1; break;
- case Operator.OpType.LessThan:
- reg = 2; break;
-
- case Operator.OpType.GreaterThanOrEqual:
- reg = 1; break;
- case Operator.OpType.LessThanOrEqual:
- reg = 2; break;
- }
- if (reg == 0)
- continue;
-
- OperatorEntry oe = new OperatorEntry (reg, op);
-
- object o = pairs [oe];
- if (o == null)
- pairs [oe] = oe;
- else {
- oe = (OperatorEntry) o;
- oe.flags |= reg;
- }
- }
-
- //
- // Look for the mistakes.
- //
- foreach (DictionaryEntry de in pairs){
- OperatorEntry oe = (OperatorEntry) de.Key;
-
- if (oe.flags == 3)
- continue;
-
- string s = "";
- switch (oe.ot){
- case Operator.OpType.Equality:
- s = "!=";
- break;
- case Operator.OpType.Inequality:
- s = "==";
- break;
- case Operator.OpType.GreaterThan:
- s = "<";
- break;
- case Operator.OpType.LessThan:
- s = ">";
- break;
- case Operator.OpType.GreaterThanOrEqual:
- s = "<=";
- break;
- case Operator.OpType.LessThanOrEqual:
- s = ">=";
- break;
- }
- Report.Error (216, oe.op.Location,
- "The operator `" + oe.op + "' requires a matching operator `" + s + "' to also be defined");
- }
- }
-
-
- }
-
- public class Class : TypeContainer {
- // <summary>
- // Modifiers allowed in a class declaration
- // </summary>
- public const int AllowedModifiers =
- Modifiers.NEW |
- Modifiers.PUBLIC |
- Modifiers.PROTECTED |
- Modifiers.INTERNAL |
- Modifiers.PRIVATE |
- Modifiers.ABSTRACT |
- Modifiers.SEALED |
- Modifiers.UNSAFE;
-
- public Class (TypeContainer parent, string name, int mod, Attributes attrs, Location l)
- : base (parent, name, l)
- {
- int accmods;
-
- if (parent.Parent == null)
- accmods = Modifiers.INTERNAL;
- else
- accmods = Modifiers.PRIVATE;
-
- this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
- this.attributes = attrs;
- }
-
- //
- // FIXME: How do we deal with the user specifying a different
- // layout?
- //
- public override TypeAttributes TypeAttr {
- get {
- return base.TypeAttr | TypeAttributes.AutoLayout | TypeAttributes.Class;
- }
- }
- }
-
- public class Struct : TypeContainer {
- // <summary>
- // Modifiers allowed in a struct declaration
- // </summary>
- public const int AllowedModifiers =
- Modifiers.NEW |
- Modifiers.PUBLIC |
- Modifiers.PROTECTED |
- Modifiers.INTERNAL |
- Modifiers.UNSAFE |
- Modifiers.PRIVATE;
-
- public Struct (TypeContainer parent, string name, int mod, Attributes attrs, Location l)
- : base (parent, name, l)
- {
- int accmods;
-
- if (parent.Parent == null)
- accmods = Modifiers.INTERNAL;
- else
- accmods = Modifiers.PRIVATE;
-
- this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
-
- this.ModFlags |= Modifiers.SEALED;
- this.attributes = attrs;
-
- }
-
- //
- // FIXME: Allow the user to specify a different set of attributes
- // in some cases (Sealed for example is mandatory for a class,
- // but what SequentialLayout can be changed
- //
- public override TypeAttributes TypeAttr {
- get {
- return base.TypeAttr |
- TypeAttributes.SequentialLayout |
- TypeAttributes.Sealed |
- TypeAttributes.BeforeFieldInit;
- }
- }
- }
-
- public abstract class MethodCore : MemberBase {
- public readonly Parameters Parameters;
- protected Block block;
-
- //
- // Parameters, cached for semantic analysis.
- //
- protected InternalParameters parameter_info;
- protected Type [] parameter_types;
-
- public MethodCore (Expression type, int mod, int allowed_mod, string name,
- Attributes attrs, Parameters parameters, Location loc)
- : base (type, mod, allowed_mod, name, attrs, loc)
- {
- Parameters = parameters;
- }
-
- //
- // Returns the System.Type array for the parameters of this method
- //
- public Type [] ParameterTypes {
- get {
- return parameter_types;
- }
- }
-
- public InternalParameters ParameterInfo
- {
- get {
- return parameter_info;
- }
- }
-
- public Block Block {
- get {
- return block;
- }
-
- set {
- block = value;
- }
- }
-
- protected virtual bool DoDefineParameters (TypeContainer parent)
- {
- // Check if arguments were correct
- parameter_types = Parameters.GetParameterInfo (parent);
- if ((parameter_types == null) || !CheckParameters (parent, parameter_types))
- return false;
-
- parameter_info = new InternalParameters (parent, Parameters);
-
- return true;
- }
-
- public CallingConventions GetCallingConvention (bool is_class)
- {
- CallingConventions cc = 0;
-
- cc = Parameters.GetCallingConvention ();
-
- if (is_class)
- if ((ModFlags & Modifiers.STATIC) == 0)
- cc |= CallingConventions.HasThis;
-
- // FIXME: How is `ExplicitThis' used in C#?
-
- return cc;
- }
-
- public void LabelParameters (EmitContext ec, Type [] parameters, MethodBase builder)
- {
- //
- // Define each type attribute (in/out/ref) and
- // the argument names.
- //
- Parameter [] p = Parameters.FixedParameters;
- int i = 0;
-
- MethodBuilder mb = null;
- ConstructorBuilder cb = null;
-
- if (builder is MethodBuilder)
- mb = (MethodBuilder) builder;
- else
- cb = (ConstructorBuilder) builder;
-
- if (p != null){
- for (i = 0; i < p.Length; i++) {
- ParameterBuilder pb;
-
- if (mb == null)
- pb = cb.DefineParameter (
- i + 1, p [i].Attributes, p [i].Name);
- else
- pb = mb.DefineParameter (
- i + 1, p [i].Attributes, p [i].Name);
-
- Attributes attr = p [i].OptAttributes;
- if (attr != null)
- Attribute.ApplyAttributes (ec, pb, pb, attr, Location);
- }
- }
-
- if (Parameters.ArrayParameter != null){
- ParameterBuilder pb;
- Parameter array_param = Parameters.ArrayParameter;
-
- if (mb == null)
- pb = cb.DefineParameter (
- i + 1, array_param.Attributes,
- array_param.Name);
- else
- pb = mb.DefineParameter (
- i + 1, array_param.Attributes,
- array_param.Name);
-
- CustomAttributeBuilder a = new CustomAttributeBuilder (
- TypeManager.cons_param_array_attribute, new object [0]);
-
- pb.SetCustomAttribute (a);
- }
- }
- }
-
- public class Method : MethodCore {
- public MethodBuilder MethodBuilder;
- public MethodData MethodData;
-
- /// <summary>
- /// Modifiers allowed in a class declaration
- /// </summary>
- const int AllowedModifiers =
- Modifiers.NEW |
- Modifiers.PUBLIC |
- Modifiers.PROTECTED |
- Modifiers.INTERNAL |
- Modifiers.PRIVATE |
- Modifiers.STATIC |
- Modifiers.VIRTUAL |
- Modifiers.SEALED |
- Modifiers.OVERRIDE |
- Modifiers.ABSTRACT |
- Modifiers.UNSAFE |
- Modifiers.EXTERN;
-
- //
- // return_type can be "null" for VOID values.
- //
- public Method (Expression return_type, int mod, string name, Parameters parameters,
- Attributes attrs, Location l)
- : base (return_type, mod, AllowedModifiers, name, attrs, parameters, l)
- { }
-
- //
- // Returns the `System.Type' for the ReturnType of this
- // function. Provides a nice cache. (used between semantic analysis
- // and actual code generation
- //
- public Type GetReturnType ()
- {
- return MemberType;
- }
-
- // Whether this is an operator method.
- public bool IsOperator;
-
- void DuplicateEntryPoint (MethodInfo b, Location location)
- {
- Report.Error (
- 17, location,
- "Program `" + CodeGen.FileName +
- "' has more than one entry point defined: `" +
- TypeManager.CSharpSignature(b) + "'");
- }
-
- void Report28 (MethodInfo b)
- {
- if (RootContext.WarningLevel < 4)
- return;
-
- Report.Warning (
- 28, Location,
- "`" + TypeManager.CSharpSignature(b) +
- "' has the wrong signature to be an entry point");
- }
-
- public bool IsEntryPoint (MethodBuilder b, InternalParameters pinfo)
- {
- if (b.ReturnType != TypeManager.void_type &&
- b.ReturnType != TypeManager.int32_type)
- return false;
-
- if (pinfo.Count == 0)
- return true;
-
- if (pinfo.Count > 1)
- return false;
-
- Type t = pinfo.ParameterType(0);
- if (t.IsArray &&
- (t.GetArrayRank() == 1) &&
- (t.GetElementType() == TypeManager.string_type) &&
- (pinfo.ParameterModifier(0) == Parameter.Modifier.NONE))
- return true;
- else
- return false;
- }
-
- //
- // Checks our base implementation if any
- //
- protected override bool CheckBase (TypeContainer parent)
- {
- // Check whether arguments were correct.
- if (!DoDefineParameters (parent))
- return false;
-
- MethodSignature ms = new MethodSignature (Name, null, ParameterTypes);
- if (!IsOperator) {
- MemberList mi_this;
-
- mi_this = TypeContainer.FindMembers (
- parent.TypeBuilder, MemberTypes.Method,
- BindingFlags.NonPublic | BindingFlags.Public |
- BindingFlags.Static | BindingFlags.Instance |
- BindingFlags.DeclaredOnly,
- MethodSignature.method_signature_filter, ms);
-
- if (mi_this.Count > 0) {
- Report.Error (111, Location, "Class `" + parent.Name + "' " +
- "already defines a member called `" + Name + "' " +
- "with the same parameter types");
- return false;
- }
- }
-
- //
- // Verify if the parent has a type with the same name, and then
- // check whether we have to create a new slot for it or not.
- //
- Type ptype = parent.TypeBuilder.BaseType;
-
- // ptype is only null for System.Object while compiling corlib.
- if (ptype != null){
- MemberList mi, mi_static, mi_instance;
-
- mi_static = TypeContainer.FindMembers (
- ptype, MemberTypes.Method,
- BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static,
- MethodSignature.inheritable_method_signature_filter, ms);
-
- mi_instance = TypeContainer.FindMembers (
- ptype, MemberTypes.Method,
- BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance,
- MethodSignature.inheritable_method_signature_filter,
- ms);
-
- if (mi_instance.Count > 0){
- mi = mi_instance;
- } else if (mi_static.Count > 0)
- mi = mi_static;
- else
- mi = null;
-
- if (mi != null && mi.Count > 0){
- parent_method = (MethodInfo) mi [0];
- string name = parent_method.DeclaringType.Name + "." +
- parent_method.Name;
-
- if (!CheckMethodAgainstBase (parent, flags, parent_method, name))
- return false;
-
- if ((ModFlags & Modifiers.NEW) == 0) {
- Type parent_ret = TypeManager.TypeToCoreType (
- parent_method.ReturnType);
-
- if (parent_ret != MemberType) {
- Report.Error (
- 508, parent.MakeName (Name) + ": cannot " +
- "change return type when overriding " +
- "inherited member " + name);
- return false;
- }
- }
- } else {
- if ((ModFlags & Modifiers.NEW) != 0)
- WarningNotHiding (parent);
-
- if ((ModFlags & Modifiers.OVERRIDE) != 0){
- Report.Error (115, Location,
- parent.MakeName (Name) +
- " no suitable methods found to override");
- }
- }
- } else if ((ModFlags & Modifiers.NEW) != 0)
- WarningNotHiding (parent);
-
- return true;
- }
-
- //
- // Creates the type
- //
- public override bool Define (TypeContainer parent)
- {
- if (!DoDefine (parent))
- return false;
-
- if (!CheckBase (parent))
- return false;
-
- CallingConventions cc = GetCallingConvention (parent is Class);
-
- MethodData = new MethodData (this, null, MemberType, ParameterTypes,
- ParameterInfo, cc, OptAttributes,
- ModFlags, flags, true);
-
- if (!MethodData.Define (parent))
- return false;
-
- MethodBuilder = MethodData.MethodBuilder;
-
- //
- // This is used to track the Entry Point,
- //
- if (Name == "Main" &&
- ((ModFlags & Modifiers.STATIC) != 0) &&
- (RootContext.MainClass == null ||
- RootContext.MainClass == parent.TypeBuilder.FullName)){
- if (IsEntryPoint (MethodBuilder, ParameterInfo)) {
- if (RootContext.EntryPoint == null) {
- RootContext.EntryPoint = MethodBuilder;
- RootContext.EntryPointLocation = Location;
- } else {
- DuplicateEntryPoint (RootContext.EntryPoint, RootContext.EntryPointLocation);
- DuplicateEntryPoint (MethodBuilder, Location);
- }
- } else
- Report28(MethodBuilder);
- }
-
- return true;
- }
-
- //
- // Emits the code
- //
- public void Emit (TypeContainer parent)
- {
- MethodData.Emit (parent, Block, this);
- }
- }
-
- public abstract class ConstructorInitializer {
- ArrayList argument_list;
- ConstructorInfo parent_constructor;
- Parameters parameters;
- Location loc;
-
- public ConstructorInitializer (ArrayList argument_list, Parameters parameters,
- Location loc)
- {
- this.argument_list = argument_list;
- this.parameters = parameters;
- this.loc = loc;
- }
-
- public ArrayList Arguments {
- get {
- return argument_list;
- }
- }
-
- public bool Resolve (EmitContext ec)
- {
- Expression parent_constructor_group;
- Type t;
-
- ec.CurrentBlock = new Block (null, true, parameters);
-
- if (argument_list != null){
- foreach (Argument a in argument_list){
- if (!a.Resolve (ec, loc))
- return false;
- }
- }
-
- ec.CurrentBlock = null;
-
- if (this is ConstructorBaseInitializer) {
- if (ec.ContainerType.BaseType == null)
- return true;
-
- t = ec.ContainerType.BaseType;
- if (ec.ContainerType.IsValueType) {
- Report.Error (522, loc,
- "structs cannot call base class constructors");
- return false;
- }
- } else
- t = ec.ContainerType;
-
- parent_constructor_group = Expression.MemberLookup (
- ec, t, null, t, ".ctor",
- MemberTypes.Constructor,
- BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
- loc);
-
- if (parent_constructor_group == null){
- Report.Error (1501, loc,
- "Can not find a constructor for this argument list");
- return false;
- }
-
- parent_constructor = (ConstructorInfo) Invocation.OverloadResolve (ec,
- (MethodGroupExpr) parent_constructor_group, argument_list, loc);
-
- if (parent_constructor == null){
- Report.Error (1501, loc,
- "Can not find a constructor for this argument list");
- return false;
- }
-
- return true;
- }
-
- public void Emit (EmitContext ec)
- {
- if (parent_constructor != null){
- if (ec.IsStatic)
- Invocation.EmitCall (ec, true, true, null, parent_constructor, argument_list, loc);
- else
- Invocation.EmitCall (ec, true, false, ec.This, parent_constructor, argument_list, loc);
- }
- }
- }
-
- public class ConstructorBaseInitializer : ConstructorInitializer {
- public ConstructorBaseInitializer (ArrayList argument_list, Parameters pars, Location l) :
- base (argument_list, pars, l)
- {
- }
- }
-
- public class ConstructorThisInitializer : ConstructorInitializer {
- public ConstructorThisInitializer (ArrayList argument_list, Parameters pars, Location l) :
- base (argument_list, pars, l)
- {
- }
- }
-
- public class Constructor : MethodCore {
- public ConstructorBuilder ConstructorBuilder;
- public ConstructorInitializer Initializer;
- new public Attributes OptAttributes;
-
- // <summary>
- // Modifiers allowed for a constructor.
- // </summary>
- public const int AllowedModifiers =
- Modifiers.PUBLIC |
- Modifiers.PROTECTED |
- Modifiers.INTERNAL |
- Modifiers.STATIC |
- Modifiers.UNSAFE |
- Modifiers.EXTERN |
- Modifiers.PRIVATE;
-
- //
- // The spec claims that static is not permitted, but
- // my very own code has static constructors.
- //
- public Constructor (string name, Parameters args, ConstructorInitializer init, Location l)
- : base (null, 0, AllowedModifiers, name, null, args, l)
- {
- Initializer = init;
- }
-
- //
- // Returns true if this is a default constructor
- //
- public bool IsDefault ()
- {
- if ((ModFlags & Modifiers.STATIC) != 0)
- return (Parameters.FixedParameters == null ? true : Parameters.Empty) &&
- (Parameters.ArrayParameter == null ? true : Parameters.Empty);
-
- else
- return (Parameters.FixedParameters == null ? true : Parameters.Empty) &&
- (Parameters.ArrayParameter == null ? true : Parameters.Empty) &&
- (Initializer is ConstructorBaseInitializer) &&
- (Initializer.Arguments == null);
- }
-
- //
- // Creates the ConstructorBuilder
- //
- public override bool Define (TypeContainer parent)
- {
- MethodAttributes ca = (MethodAttributes.RTSpecialName |
- MethodAttributes.SpecialName);
-
- // Check if arguments were correct.
- if (!DoDefineParameters (parent))
- return false;
-
- if ((ModFlags & Modifiers.STATIC) != 0)
- ca |= MethodAttributes.Static;
- else {
- if (parent is Struct && ParameterTypes.Length == 0){
- Report.Error (
- 568, Location,
- "Structs can not contain explicit parameterless " +
- "constructors");
- return false;
- }
- ca |= MethodAttributes.HideBySig;
-
- if ((ModFlags & Modifiers.PUBLIC) != 0)
- ca |= MethodAttributes.Public;
- else if ((ModFlags & Modifiers.PROTECTED) != 0){
- if ((ModFlags & Modifiers.INTERNAL) != 0)
- ca |= MethodAttributes.FamORAssem;
- else
- ca |= MethodAttributes.Family;
- } else if ((ModFlags & Modifiers.INTERNAL) != 0)
- ca |= MethodAttributes.Assembly;
- else if (IsDefault ())
- ca |= MethodAttributes.Public;
- else
- ca |= MethodAttributes.Private;
- }
-
- ConstructorBuilder = parent.TypeBuilder.DefineConstructor (
- ca, GetCallingConvention (parent is Class), ParameterTypes);
-
- //
- // HACK because System.Reflection.Emit is lame
- //
- if (!TypeManager.RegisterMethod (ConstructorBuilder, ParameterInfo, ParameterTypes)) {
- Report.Error (
- 111, Location,
- "Class `" +parent.Name+ "' already contains a definition with the " +
- "same return value and parameter types for constructor `" + Name
- + "'");
- return false;
- }
-
- return true;
- }
-
- //
- // Emits the code
- //
- public void Emit (TypeContainer parent)
- {
- ILGenerator ig = ConstructorBuilder.GetILGenerator ();
- EmitContext ec = new EmitContext (parent, Location, ig, null, ModFlags, true);
-
- //
- // extern methods have no bodies
- //
- if ((ModFlags & Modifiers.EXTERN) != 0) {
- if ((block != null) && ((ModFlags & Modifiers.EXTERN) != 0)) {
- Report.Error (
- 179, Location, "External constructor `" +
- TypeManager.CSharpSignature (ConstructorBuilder) +
- "' can not have a body");
- return;
- }
- } else if (block == null) {
- Report.Error (
- 501, Location, "Constructor `" +
- TypeManager.CSharpSignature (ConstructorBuilder) +
- "' must declare a body since it is not marked extern");
- return;
- }
-
- if ((ModFlags & Modifiers.STATIC) == 0){
- if (parent is Class && Initializer == null)
- Initializer = new ConstructorBaseInitializer (
- null, Parameters.EmptyReadOnlyParameters, parent.Location);
-
-
- //
- // Spec mandates that Initializers will not have
- // `this' access
- //
- ec.IsStatic = true;
- if (Initializer != null && !Initializer.Resolve (ec))
- return;
- ec.IsStatic = false;
- }
-
- LabelParameters (ec, ParameterTypes, ConstructorBuilder);
-
- //
- // Classes can have base initializers and instance field initializers.
- //
- if (parent is Class){
- if ((ModFlags & Modifiers.STATIC) == 0)
- parent.EmitFieldInitializers (ec);
- }
- if (Initializer != null)
- Initializer.Emit (ec);
-
- if ((ModFlags & Modifiers.STATIC) != 0)
- parent.EmitFieldInitializers (ec);
-
- Attribute.ApplyAttributes (ec, ConstructorBuilder, this, OptAttributes, Location);
-
- // If this is a non-static `struct' constructor and doesn't have any
- // initializer, it must initialize all of the struct's fields.
- if ((parent is Struct) && ((ModFlags & Modifiers.STATIC) == 0) &&
- (Initializer == null))
- Block.AddThisVariable (parent, Location);
-
- ec.EmitTopBlock (Block, ParameterInfo, Location);
- }
- }
-
- public class MethodData {
- //
- // The return type of this method
- //
- public readonly Type ReturnType;
- public readonly Type[] ParameterTypes;
- public readonly InternalParameters ParameterInfo;
- public readonly CallingConventions CallingConventions;
- public readonly Attributes OptAttributes;
- public readonly Location Location;
-
- //
- // Are we implementing an interface ?
- //
- public bool IsImplementing = false;
-
- //
- // Protected data.
- //
- protected MemberBase member;
- protected int modifiers;
- protected MethodAttributes flags;
- protected bool is_method;
- protected string accessor_name;
- ArrayList conditionals;
-
- MethodBuilder builder = null;
- public MethodBuilder MethodBuilder {
- get {
- return builder;
- }
- }
-
- public MethodData (MemberBase member, string name, Type return_type,
- Type [] parameter_types, InternalParameters parameters,
- CallingConventions cc, Attributes opt_attrs,
- int modifiers, MethodAttributes flags, bool is_method)
- {
- this.member = member;
- this.accessor_name = name;
- this.ReturnType = return_type;
- this.ParameterTypes = parameter_types;
- this.ParameterInfo = parameters;
- this.CallingConventions = cc;
- this.OptAttributes = opt_attrs;
- this.modifiers = modifiers;
- this.flags = flags;
- this.is_method = is_method;
- this.Location = member.Location;
- this.conditionals = new ArrayList ();
- }
-
- //
- // Attributes.
- //
- Attribute dllimport_attribute = null;
- string obsolete = null;
- bool obsolete_error = false;
-
- public virtual bool ApplyAttributes (Attributes opt_attrs, bool is_method)
- {
- if ((opt_attrs == null) || (opt_attrs.AttributeSections == null))
- return true;
-
- foreach (AttributeSection asec in opt_attrs.AttributeSections) {
- if (asec.Attributes == null)
- continue;
-
- foreach (Attribute a in asec.Attributes) {
- if (a.Name == "Conditional") {
- if (!ApplyConditionalAttribute (a))
- return false;
- } else if (a.Name == "Obsolete") {
- if (!ApplyObsoleteAttribute (a))
- return false;
- } else if (a.Name.IndexOf ("DllImport") != -1) {
- if (!is_method) {
- a.Type = TypeManager.dllimport_type;
- Attribute.Error_AttributeNotValidForElement (a, Location);
- return false;
- }
- if (!ApplyDllImportAttribute (a))
- return false;
- }
- }
- }
-
- return true;
- }
-
- //
- // Applies the `DllImport' attribute to the method.
- //
- protected virtual bool ApplyDllImportAttribute (Attribute a)
- {
- const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
- if ((modifiers & extern_static) != extern_static) {
- Report.Error (601, Location,
- "The DllImport attribute must be specified on a method " +
- "marked `static' and `extern'.");
- return false;
- }
-
- flags |= MethodAttributes.PinvokeImpl;
- dllimport_attribute = a;
- return true;
- }
-
- //
- // Applies the `Obsolete' attribute to the method.
- //
- protected virtual bool ApplyObsoleteAttribute (Attribute a)
- {
- if (obsolete != null) {
- Report.Error (579, Location, "Duplicate `Obsolete' attribute");
- return false;
- }
-
- obsolete = a.Obsolete_GetObsoleteMessage (out obsolete_error);
- return obsolete != null;
- }
-
- //
- // Applies the `Conditional' attribute to the method.
- //
- protected virtual bool ApplyConditionalAttribute (Attribute a)
- {
- // The Conditional attribute is only valid on methods.
- if (!is_method) {
- Attribute.Error_AttributeNotValidForElement (a, Location);
- return false;
- }
-
- string condition = a.Conditional_GetConditionName ();
-
- if (condition == null)
- return false;
-
- if (ReturnType != TypeManager.void_type) {
- Report.Error (578, Location,
- "Conditional not valid on `" + member.Name + "' " +
- "because its return type is not void");
- return false;
- }
-
- if ((modifiers & Modifiers.OVERRIDE) != 0) {
- Report.Error (243, Location,
- "Conditional not valid on `" + member.Name + "' " +
- "because it is an override method");
- return false;
- }
-
- if (member.IsExplicitImpl) {
- Report.Error (577, Location,
- "Conditional not valid on `" + member.Name + "' " +
- "because it is an explicit interface implementation");
- return false;
- }
-
- if (IsImplementing) {
- Report.Error (623, Location,
- "Conditional not valid on `" + member.Name + "' " +
- "because it is an interface method");
- return false;
- }
-
- conditionals.Add (condition);
-
- return true;
- }
-
- //
- // Checks whether this method should be ignored due to its Conditional attributes.
- //
- bool ShouldIgnore (Location loc)
- {
- // When we're overriding a virtual method, we implicitly inherit the
- // Conditional attributes from our parent.
- if (member.ParentMethod != null) {
- TypeManager.MethodFlags flags = TypeManager.GetMethodFlags (
- member.ParentMethod, loc);
-
- if ((flags & TypeManager.MethodFlags.ShouldIgnore) != 0)
- return true;
- }
-
- foreach (string condition in conditionals)
- if (RootContext.AllDefines [condition] == null)
- return true;
-
- return false;
- }
-
- //
- // Returns the TypeManager.MethodFlags for this method.
- // This emits an error 619 / warning 618 if the method is obsolete.
- // In the former case, TypeManager.MethodFlags.IsObsoleteError is returned.
- //
- public virtual TypeManager.MethodFlags GetMethodFlags (Location loc)
- {
- TypeManager.MethodFlags flags = 0;
-
- if (obsolete != null) {
- if (obsolete_error) {
- Report.Error (619, loc, "Method `" + member.Name +
- "' is obsolete: `" + obsolete + "'");
- return TypeManager.MethodFlags.IsObsoleteError;
- } else
- Report.Warning (618, loc, "Method `" + member.Name +
- "' is obsolete: `" + obsolete + "'");
-
- flags |= TypeManager.MethodFlags.IsObsolete;
- }
-
- if (ShouldIgnore (loc))
- flags |= TypeManager.MethodFlags.ShouldIgnore;
-
- return flags;
- }
-
- public virtual bool Define (TypeContainer parent)
- {
- MethodInfo implementing = null;
- string method_name, name, prefix;
-
- if (OptAttributes != null)
- if (!ApplyAttributes (OptAttributes, is_method))
- return false;
-
- if (member.IsExplicitImpl)
- prefix = member.InterfaceType.FullName + ".";
- else
- prefix = "";
-
- if (accessor_name != null)
- name = accessor_name + "_" + member.ShortName;
- else
- name = member.ShortName;
- method_name = prefix + name;
-
- if (parent.Pending != null){
- if (member is Indexer)
- implementing = parent.Pending.IsInterfaceIndexer (
- member.InterfaceType, ReturnType, ParameterTypes);
- else
- implementing = parent.Pending.IsInterfaceMethod (
- member.InterfaceType, name, ReturnType, ParameterTypes);
-
- if (member.InterfaceType != null && implementing == null){
- TypeContainer.Error_ExplicitInterfaceNotMemberInterface (
- Location, name);
- return false;
- }
- }
-
- //
- // For implicit implementations, make sure we are public, for
- // explicit implementations, make sure we are private.
- //
- if (implementing != null){
- //
- // Setting null inside this block will trigger a more
- // verbose error reporting for missing interface implementations
- //
- // The "candidate" function has been flagged already
- // but it wont get cleared
- //
- if (!member.IsExplicitImpl){
- //
- // We already catch different accessibility settings
- // so we just need to check that we are not private
- //
- if ((modifiers & Modifiers.PRIVATE) != 0)
- implementing = null;
-
- //
- // Static is not allowed
- //
- if ((modifiers & Modifiers.STATIC) != 0)
- implementing = null;
- } else {
- if ((modifiers & (Modifiers.PUBLIC | Modifiers.ABSTRACT | Modifiers.VIRTUAL)) != 0){
- Modifiers.Error_InvalidModifier (Location, "public, virtual or abstract");
- implementing = null;
- }
- }
- }
-
- //
- // If implementing is still valid, set flags
- //
- if (implementing != null){
- //
- // When implementing interface methods, set NewSlot.
- //
- if (implementing.DeclaringType.IsInterface)
- flags |= MethodAttributes.NewSlot;
-
- flags |=
- MethodAttributes.Virtual |
- MethodAttributes.HideBySig;
-
- // Get the method name from the explicit interface.
- if (member.InterfaceType != null) {
- name = implementing.Name;
- method_name = prefix + name;
- }
-
- IsImplementing = true;
- }
-
- //
- // Create the MethodBuilder for the method
- //
- if ((flags & MethodAttributes.PinvokeImpl) != 0) {
- if ((modifiers & Modifiers.STATIC) == 0) {
- Report.Error (601, Location,
- "The DllImport attribute must be specified on " +
- "a method marked 'static' and 'extern'.");
- return false;
- }
-
- EmitContext ec = new EmitContext (
- parent, Location, null, ReturnType, modifiers);
-
- builder = dllimport_attribute.DefinePInvokeMethod (
- ec, parent.TypeBuilder, method_name, flags,
- ReturnType, ParameterTypes);
- } else
- builder = parent.TypeBuilder.DefineMethod (
- method_name, flags, CallingConventions,
- ReturnType, ParameterTypes);
-
- if (builder == null)
- return false;
-
- if (IsImplementing) {
- //
- // clear the pending implemntation flag
- //
- if (member is Indexer) {
- parent.Pending.ImplementIndexer (
- member.InterfaceType, builder, ReturnType,
- ParameterTypes, true);
- } else
- parent.Pending.ImplementMethod (
- member.InterfaceType, name, ReturnType,
- ParameterTypes, member.IsExplicitImpl);
-
- if (member.IsExplicitImpl)
- parent.TypeBuilder.DefineMethodOverride (
- builder, implementing);
- }
-
- if (!TypeManager.RegisterMethod (builder, ParameterInfo, ParameterTypes)) {
- Report.Error (111, Location,
- "Class `" + parent.Name +
- "' already contains a definition with the " +
- "same return value and parameter types as the " +
- "'get' method of property `" + member.Name + "'");
- return false;
- }
-
- TypeManager.AddMethod (builder, this);
-
- return true;
- }
-
- //
- // Emits the code
- //
- public virtual void Emit (TypeContainer parent, Block block, object kind)
- {
- ILGenerator ig;
- EmitContext ec;
-
- if ((flags & MethodAttributes.PinvokeImpl) == 0)
- ig = builder.GetILGenerator ();
- else
- ig = null;
-
- ec = new EmitContext (parent, Location, ig, ReturnType, modifiers);
-
- if (OptAttributes != null)
- Attribute.ApplyAttributes (ec, builder, kind, OptAttributes, Location);
-
- if (member is MethodCore)
- ((MethodCore) member).LabelParameters (ec, ParameterTypes, MethodBuilder);
-
- //
- // abstract or extern methods have no bodies
- //
- if ((modifiers & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0){
- if (block == null)
- return;
-
- //
- // abstract or extern methods have no bodies.
- //
- if ((modifiers & Modifiers.ABSTRACT) != 0)
- Report.Error (
- 500, Location, "Abstract method `" +
- TypeManager.CSharpSignature (builder) +
- "' can not have a body");
-
- if ((modifiers & Modifiers.EXTERN) != 0)
- Report.Error (
- 179, Location, "External method `" +
- TypeManager.CSharpSignature (builder) +
- "' can not have a body");
-
- return;
- }
-
- //
- // Methods must have a body unless they're extern or abstract
- //
- if (block == null) {
- Report.Error (
- 501, Location, "Method `" +
- TypeManager.CSharpSignature (builder) +
- "' must declare a body since it is not marked " +
- "abstract or extern");
- return;
- }
-
- //
- // Handle destructors specially
- //
- // FIXME: This code generates buggy code
- //
- if (member.Name == "Finalize" && ReturnType == TypeManager.void_type)
- EmitDestructor (ec, block);
- else {
- ISymbolWriter sw = CodeGen.SymbolWriter;
-
- if ((sw != null) && !Location.IsNull (Location) &&
- !Location.IsNull (block.EndLocation)) {
- Location end = block.EndLocation;
- MethodToken token = MethodBuilder.GetToken ();
- sw.OpenMethod (new SymbolToken (token.Token));
- // Avoid error if we don't support debugging for the platform
- try {
- sw.SetMethodSourceRange (Location.SymbolDocument,
- Location.Row, 0,
- end.SymbolDocument,
- end.Row, 0);
- } catch (Exception) {
- }
-
- ec.EmitTopBlock (block, ParameterInfo, Location);
-
- sw.CloseMethod ();
- } else
- ec.EmitTopBlock (block, ParameterInfo, Location);
- }
- }
-
- void EmitDestructor (EmitContext ec, Block block)
- {
- ILGenerator ig = ec.ig;
-
- Label finish = ig.DefineLabel ();
- bool old_in_try = ec.InTry;
-
- ig.BeginExceptionBlock ();
- ec.InTry = true;
- ec.ReturnLabel = finish;
- ec.HasReturnLabel = true;
- ec.EmitTopBlock (block, null, Location);
- ec.InTry = old_in_try;
-
- // ig.MarkLabel (finish);
- bool old_in_finally = ec.InFinally;
- ec.InFinally = true;
- ig.BeginFinallyBlock ();
-
- if (ec.ContainerType.BaseType != null) {
- Expression member_lookup = Expression.MemberLookup (
- ec, ec.ContainerType.BaseType, null, ec.ContainerType.BaseType,
- "Finalize", MemberTypes.Method, Expression.AllBindingFlags, Location);
-
- if (member_lookup != null){
- MethodGroupExpr parent_destructor = ((MethodGroupExpr) member_lookup);
-
- ig.Emit (OpCodes.Ldarg_0);
- ig.Emit (OpCodes.Call, (MethodInfo) parent_destructor.Methods [0]);
- }
- }
- ec.InFinally = old_in_finally;
-
- ig.EndExceptionBlock ();
- //ig.MarkLabel (ec.ReturnLabel);
- ig.Emit (OpCodes.Ret);
- }
- }
-
- abstract public class MemberBase : MemberCore {
- public Expression Type;
- public readonly Attributes OptAttributes;
-
- protected MethodAttributes flags;
-
- //
- // The "short" name of this property / indexer / event. This is the
- // name without the explicit interface.
- //
- public string ShortName;
-
- //
- // The type of this property / indexer / event
- //
- public Type MemberType;
-
- //
- // If true, this is an explicit interface implementation
- //
- public bool IsExplicitImpl = false;
-
- //
- // The name of the interface we are explicitly implementing
- //
- public string ExplicitInterfaceName = null;
-
- //
- // If true, the interface type we are explicitly implementing
- //
- public Type InterfaceType = null;
-
- //
- // The method we're overriding if this is an override method.
- //
- protected MethodInfo parent_method = null;
- public MethodInfo ParentMethod {
- get {
- return parent_method;
- }
- }
-
- //
- // The constructor is only exposed to our children
- //
- protected MemberBase (Expression type, int mod, int allowed_mod, string name,
- Attributes attrs, Location loc)
- : base (name, loc)
- {
- Type = type;
- ModFlags = Modifiers.Check (allowed_mod, mod, Modifiers.PRIVATE, loc);
- OptAttributes = attrs;
- }
-
- protected virtual bool CheckBase (TypeContainer parent)
- {
- return true;
- }
-
- protected virtual bool CheckParameters (TypeContainer parent, Type [] parameters)
- {
- bool error = false;
-
- foreach (Type partype in parameters){
- if (partype.IsPointer && !UnsafeOK (parent))
- error = true;
-
- if (parent.AsAccessible (partype, ModFlags))
- continue;
-
- if (this is Indexer)
- Report.Error (55, Location,
- "Inconsistent accessibility: parameter type `" +
- TypeManager.CSharpName (partype) + "' is less " +
- "accessible than indexer `" + Name + "'");
- else
- Report.Error (51, Location,
- "Inconsistent accessibility: parameter type `" +
- TypeManager.CSharpName (partype) + "' is less " +
- "accessible than method `" + Name + "'");
- error = true;
- }
-
- return !error;
- }
-
- protected virtual bool DoDefine (TypeContainer parent)
- {
- if (Name == null)
- Name = "this";
-
- if (!parent.MethodModifiersValid (ModFlags, Name, Location))
- return false;
-
- flags = Modifiers.MethodAttr (ModFlags);
-
- // Lookup Type, verify validity
- MemberType = parent.ResolveType (Type, false, Location);
- if (MemberType == null)
- return false;
-
- // verify accessibility
- if (!parent.AsAccessible (MemberType, ModFlags)) {
- if (this is Property)
- Report.Error (53, Location,
- "Inconsistent accessibility: property type `" +
- TypeManager.CSharpName (MemberType) + "' is less " +
- "accessible than property `" + Name + "'");
- else if (this is Indexer)
- Report.Error (54, Location,
- "Inconsistent accessibility: indexer return type `" +
- TypeManager.CSharpName (MemberType) + "' is less " +
- "accessible than indexer `" + Name + "'");
- else if (this is Method)
- Report.Error (50, Location,
- "Inconsistent accessibility: return type `" +
- TypeManager.CSharpName (MemberType) + "' is less " +
- "accessible than method `" + Name + "'");
- else
- Report.Error (52, Location,
- "Inconsistent accessibility: field type `" +
- TypeManager.CSharpName (MemberType) + "' is less " +
- "accessible than field `" + Name + "'");
- return false;
- }
-
- if (MemberType.IsPointer && !UnsafeOK (parent))
- return false;
-
- //
- // Check for explicit interface implementation
- //
- if ((ExplicitInterfaceName == null) && (Name.IndexOf (".") != -1)){
- int pos = Name.LastIndexOf (".");
-
- ExplicitInterfaceName = Name.Substring (0, pos);
- ShortName = Name.Substring (pos + 1);
- } else
- ShortName = Name;
-
- if (ExplicitInterfaceName != null) {
- InterfaceType = RootContext.LookupType (
- parent, ExplicitInterfaceName, false, Location);
- if (InterfaceType == null)
- return false;
-
- // Compute the full name that we need to export.
- Name = InterfaceType.FullName + "." + ShortName;
-
- if (!parent.VerifyImplements (InterfaceType, ShortName, Name, Location))
- return false;
-
- IsExplicitImpl = true;
- } else
- IsExplicitImpl = false;
-
- return true;
- }
- }
-
- //
- // Fields and Events both generate FieldBuilders, we use this to share
- // their common bits. This is also used to flag usage of the field
- //
- abstract public class FieldBase : MemberBase {
- public FieldBuilder FieldBuilder;
- public Status status;
-
- [Flags]
- public enum Status : byte { ASSIGNED = 1, USED = 2 }
-
- //
- // The constructor is only exposed to our children
- //
- protected FieldBase (Expression type, int mod, int allowed_mod, string name,
- object init, Attributes attrs, Location loc)
- : base (type, mod, allowed_mod, name, attrs, loc)
- {
- this.init = init;
- }
-
- //
- // Whether this field has an initializer.
- //
- public bool HasInitializer {
- get {
- return init != null;
- }
- }
-
- // Private.
- readonly Object init;
- Expression init_expr;
- bool init_expr_initialized = false;
-
- //
- // Resolves and returns the field initializer.
- //
- public Expression GetInitializerExpression (EmitContext ec)
- {
- if (init_expr_initialized)
- return init_expr;
-
- Expression e;
- if (init is Expression)
- e = (Expression) init;
- else
- e = new ArrayCreation (Type, "", (ArrayList)init, Location);
-
- ec.IsFieldInitializer = true;
- e = e.DoResolve (ec);
- ec.IsFieldInitializer = false;
-
- init_expr = e;
- init_expr_initialized = true;
-
- return init_expr;
- }
- }
-
- //
- // The Field class is used to represents class/struct fields during parsing.
- //
- public class Field : FieldBase {
- // <summary>
- // Modifiers allowed in a class declaration
- // </summary>
- const int AllowedModifiers =
- Modifiers.NEW |
- Modifiers.PUBLIC |
- Modifiers.PROTECTED |
- Modifiers.INTERNAL |
- Modifiers.PRIVATE |
- Modifiers.STATIC |
- Modifiers.VOLATILE |
- Modifiers.UNSAFE |
- Modifiers.READONLY;
-
- public Field (Expression type, int mod, string name, Object expr_or_array_init,
- Attributes attrs, Location loc)
- : base (type, mod, AllowedModifiers, name, expr_or_array_init, attrs, loc)
- {
- }
-
- public override bool Define (TypeContainer parent)
- {
- Type t = parent.ResolveType (Type, false, Location);
-
- if (t == null)
- return false;
-
- if (!parent.AsAccessible (t, ModFlags)) {
- Report.Error (52, Location,
- "Inconsistent accessibility: field type `" +
- TypeManager.CSharpName (t) + "' is less " +
- "accessible than field `" + Name + "'");
- return false;
- }
-
- if (t.IsPointer && !UnsafeOK (parent))
- return false;
-
- if (RootContext.WarningLevel > 1){
- Type ptype = parent.TypeBuilder.BaseType;
-
- // ptype is only null for System.Object while compiling corlib.
- if (ptype != null){
- TypeContainer.FindMembers (
- ptype, MemberTypes.Method,
- BindingFlags.Public |
- BindingFlags.Static | BindingFlags.Instance,
- System.Type.FilterName, Name);
- }
- }
-
- if ((ModFlags & Modifiers.VOLATILE) != 0){
- if (!t.IsClass){
- if (TypeManager.IsEnumType (t))
- t = TypeManager.EnumToUnderlying (t);
-
- if (!((t == TypeManager.bool_type) ||
- (t == TypeManager.sbyte_type) ||
- (t == TypeManager.byte_type) ||
- (t == TypeManager.short_type) ||
- (t == TypeManager.ushort_type) ||
- (t == TypeManager.int32_type) ||
- (t == TypeManager.uint32_type) ||
- (t == TypeManager.char_type) ||
- (t == TypeManager.float_type))){
- Report.Error (
- 677, Location, parent.MakeName (Name) +
- " A volatile field can not be of type `" +
- TypeManager.CSharpName (t) + "'");
- return false;
- }
- }
- }
-
- FieldAttributes fa = Modifiers.FieldAttr (ModFlags);
-
- if (parent is Struct &&
- ((fa & FieldAttributes.Static) == 0) &&
- t == parent.TypeBuilder &&
- !TypeManager.IsBuiltinType (t)){
- Report.Error (523, Location, "Struct member `" + parent.Name + "." + Name +
- "' causes a cycle in the structure layout");
- return false;
- }
- FieldBuilder = parent.TypeBuilder.DefineField (
- Name, t, Modifiers.FieldAttr (ModFlags));
-
- TypeManager.RegisterFieldBase (FieldBuilder, this);
- return true;
- }
-
- public void Emit (TypeContainer tc)
- {
- EmitContext ec = new EmitContext (tc, Location, null,
- FieldBuilder.FieldType, ModFlags);
-
- Attribute.ApplyAttributes (ec, FieldBuilder, this, OptAttributes, Location);
- }
- }
-
- //
- // `set' and `get' accessors are represented with an Accessor.
- //
- public class Accessor {
- //
- // Null if the accessor is empty, or a Block if not
- //
- public Block Block;
- public Attributes OptAttributes;
-
- public Accessor (Block b, Attributes attrs)
- {
- Block = b;
- OptAttributes = attrs;
- }
- }
-
- //
- // Properties and Indexers both generate PropertyBuilders, we use this to share
- // their common bits.
- //
- abstract public class PropertyBase : MethodCore {
- public Accessor Get, Set;
- public PropertyBuilder PropertyBuilder;
- public MethodBuilder GetBuilder, SetBuilder;
- public MethodData GetData, SetData;
-
- protected EmitContext ec;
-
- public PropertyBase (Expression type, string name, int mod_flags, int allowed_mod,
- Parameters parameters, Accessor get_block, Accessor set_block,
- Attributes attrs, Location loc)
- : base (type, mod_flags, allowed_mod, name, attrs, parameters, loc)
- {
- Get = get_block;
- Set = set_block;
- }
-
- protected override bool DoDefine (TypeContainer parent)
- {
- if (!base.DoDefine (parent))
- return false;
-
- ec = new EmitContext (parent, Location, null, MemberType, ModFlags);
-
- return true;
- }
-
- //
- // Checks our base implementation if any
- //
- protected override bool CheckBase (TypeContainer parent)
- {
- // Check whether arguments were correct.
- if (!DoDefineParameters (parent))
- return false;
-
- if (IsExplicitImpl)
- return true;
-
- string report_name;
- MethodSignature ms, base_ms;
- if (this is Indexer) {
- string name, base_name;
-
- report_name = "this";
- name = TypeManager.IndexerPropertyName (parent.TypeBuilder);
- ms = new MethodSignature (name, null, ParameterTypes);
- base_name = TypeManager.IndexerPropertyName (parent.TypeBuilder.BaseType);
- base_ms = new MethodSignature (base_name, null, ParameterTypes);
- } else {
- report_name = Name;
- ms = base_ms = new MethodSignature (Name, null, ParameterTypes);
- }
-
- //
- // Verify if the parent has a type with the same name, and then
- // check whether we have to create a new slot for it or not.
- //
- Type ptype = parent.TypeBuilder.BaseType;
-
- // ptype is only null for System.Object while compiling corlib.
- if (ptype == null) {
- if ((ModFlags & Modifiers.NEW) != 0)
- WarningNotHiding (parent);
-
- return true;
- }
-
- MemberList props_this;
-
- props_this = TypeContainer.FindMembers (
- parent.TypeBuilder, MemberTypes.Property,
- BindingFlags.NonPublic | BindingFlags.Public |
- BindingFlags.Static | BindingFlags.Instance |
- BindingFlags.DeclaredOnly,
- MethodSignature.method_signature_filter, ms);
-
- if (props_this.Count > 0) {
- Report.Error (111, Location, "Class `" + parent.Name + "' " +
- "already defines a member called `" + report_name + "' " +
- "with the same parameter types");
- return false;
- }
-
- MemberList mi_props;
-
- mi_props = TypeContainer.FindMembers (
- ptype, MemberTypes.Property,
- BindingFlags.NonPublic | BindingFlags.Public |
- BindingFlags.Instance | BindingFlags.Static,
- MethodSignature.inheritable_method_signature_filter, base_ms);
-
- if (mi_props.Count > 0){
- PropertyInfo parent_property = (PropertyInfo) mi_props [0];
- string name = parent_property.DeclaringType.Name + "." +
- parent_property.Name;
-
- MethodInfo get, set, parent_method;
- get = parent_property.GetGetMethod (true);
- set = parent_property.GetSetMethod (true);
-
- if (get != null)
- parent_method = get;
- else if (set != null)
- parent_method = set;
- else
- throw new Exception ("Internal error!");
-
- if (!CheckMethodAgainstBase (parent, flags, parent_method, name))
- return false;
-
- if ((ModFlags & Modifiers.NEW) == 0) {
- Type parent_type = TypeManager.TypeToCoreType (
- parent_property.PropertyType);
-
- if (parent_type != MemberType) {
- Report.Error (
- 508, parent.MakeName (Name) + ": cannot " +
- "change return type when overriding " +
- "inherited member " + name);
- return false;
- }
- }
- } else {
- if ((ModFlags & Modifiers.NEW) != 0)
- WarningNotHiding (parent);
-
- if ((ModFlags & Modifiers.OVERRIDE) != 0){
- if (this is Indexer)
- Report.Error (115, Location,
- parent.MakeName (Name) +
- " no suitable indexers found to override");
- else
- Report.Error (115, Location,
- parent.MakeName (Name) +
- " no suitable properties found to override");
- return false;
- }
- }
- return true;
- }
-
- public void Emit (TypeContainer tc)
- {
- //
- // The PropertyBuilder can be null for explicit implementations, in that
- // case, we do not actually emit the ".property", so there is nowhere to
- // put the attribute
- //
- if (PropertyBuilder != null)
- Attribute.ApplyAttributes (ec, PropertyBuilder, this, OptAttributes, Location);
-
- if (GetData != null)
- GetData.Emit (tc, Get.Block, Get);
-
- if (SetData != null)
- SetData.Emit (tc, Set.Block, Set);
- }
- }
-
- public class Property : PropertyBase {
- const int AllowedModifiers =
- Modifiers.NEW |
- Modifiers.PUBLIC |
- Modifiers.PROTECTED |
- Modifiers.INTERNAL |
- Modifiers.PRIVATE |
- Modifiers.STATIC |
- Modifiers.SEALED |
- Modifiers.OVERRIDE |
- Modifiers.ABSTRACT |
- Modifiers.UNSAFE |
- Modifiers.EXTERN |
- Modifiers.VIRTUAL;
-
- public Property (Expression type, string name, int mod_flags,
- Accessor get_block, Accessor set_block,
- Attributes attrs, Location loc)
- : base (type, name, mod_flags, AllowedModifiers,
- Parameters.EmptyReadOnlyParameters,
- get_block, set_block, attrs, loc)
- {
- }
-
- public override bool Define (TypeContainer parent)
- {
- if (!DoDefine (parent))
- return false;
-
- if (!CheckBase (parent))
- return false;
-
- flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
-
- if (Get != null) {
- Type [] parameters = TypeManager.NoTypes;
-
- InternalParameters ip = new InternalParameters (
- parent, Parameters.EmptyReadOnlyParameters);
-
- GetData = new MethodData (this, "get", MemberType,
- parameters, ip, CallingConventions.Standard,
- Get.OptAttributes, ModFlags, flags, false);
-
- if (!GetData.Define (parent))
- return false;
-
- GetBuilder = GetData.MethodBuilder;
- }
-
- if (Set != null) {
- Type [] parameters = new Type [1];
- parameters [0] = MemberType;
-
- Parameter [] parms = new Parameter [1];
- parms [0] = new Parameter (Type, "value", Parameter.Modifier.NONE, null);
- InternalParameters ip = new InternalParameters (
- parent, new Parameters (parms, null, Location));
-
- SetData = new MethodData (this, "set", TypeManager.void_type,
- parameters, ip, CallingConventions.Standard,
- Set.OptAttributes, ModFlags, flags, false);
-
- if (!SetData.Define (parent))
- return false;
-
- SetBuilder = SetData.MethodBuilder;
- SetBuilder.DefineParameter (1, ParameterAttributes.None, "value");
- }
-
- // FIXME - PropertyAttributes.HasDefault ?
-
- PropertyAttributes prop_attr =
- PropertyAttributes.RTSpecialName |
- PropertyAttributes.SpecialName;
-
- if (!IsExplicitImpl){
- PropertyBuilder = parent.TypeBuilder.DefineProperty (
- Name, prop_attr, MemberType, null);
-
- if (Get != null)
- PropertyBuilder.SetGetMethod (GetBuilder);
-
- if (Set != null)
- PropertyBuilder.SetSetMethod (SetBuilder);
-
- //
- // HACK for the reasons exposed above
- //
- if (!TypeManager.RegisterProperty (PropertyBuilder, GetBuilder, SetBuilder)) {
- Report.Error (
- 111, Location,
- "Class `" + parent.Name +
- "' already contains a definition for the property `" +
- Name + "'");
- return false;
- }
- }
- return true;
- }
- }
-
- /// </summary>
- /// Gigantic workaround for lameness in SRE follows :
- /// This class derives from EventInfo and attempts to basically
- /// wrap around the EventBuilder so that FindMembers can quickly
- /// return this in it search for members
- /// </summary>
- public class MyEventBuilder : EventInfo {
-
- //
- // We use this to "point" to our Builder which is
- // not really a MemberInfo
- //
- EventBuilder MyBuilder;
-
- //
- // We "catch" and wrap these methods
- //
- MethodInfo raise, remove, add;
-
- EventAttributes attributes;
- Type declaring_type, reflected_type, event_type;
- string name;
-
- Event my_event;
-
- public MyEventBuilder (Event ev, TypeBuilder type_builder, string name, EventAttributes event_attr, Type event_type)
- {
- MyBuilder = type_builder.DefineEvent (name, event_attr, event_type);
-
- // And now store the values in our own fields.
-
- declaring_type = type_builder;
-
- reflected_type = type_builder;
-
- attributes = event_attr;
- this.name = name;
- my_event = ev;
- this.event_type = event_type;
- }
-
- //
- // Methods that you have to override. Note that you only need
- // to "implement" the variants that take the argument (those are
- // the "abstract" methods, the others (GetAddMethod()) are
- // regular.
- //
- public override MethodInfo GetAddMethod (bool nonPublic)
- {
- return add;
- }
-
- public override MethodInfo GetRemoveMethod (bool nonPublic)
- {
- return remove;
- }
-
- public override MethodInfo GetRaiseMethod (bool nonPublic)
- {
- return raise;
- }
-
- //
- // These methods make "MyEventInfo" look like a Builder
- //
- public void SetRaiseMethod (MethodBuilder raiseMethod)
- {
- raise = raiseMethod;
- MyBuilder.SetRaiseMethod (raiseMethod);
- }
-
- public void SetRemoveOnMethod (MethodBuilder removeMethod)
- {
- remove = removeMethod;
- MyBuilder.SetRemoveOnMethod (removeMethod);
- }
-
- public void SetAddOnMethod (MethodBuilder addMethod)
- {
- add = addMethod;
- MyBuilder.SetAddOnMethod (addMethod);
- }
-
- public void SetCustomAttribute (CustomAttributeBuilder cb)
- {
- MyBuilder.SetCustomAttribute (cb);
- }
-
- public override object [] GetCustomAttributes (bool inherit)
- {
- // FIXME : There's nothing which can be seemingly done here because
- // we have no way of getting at the custom attribute objects of the
- // EventBuilder !
- return null;
- }
-
- public override object [] GetCustomAttributes (Type t, bool inherit)
- {
- // FIXME : Same here !
- return null;
- }
-
- public override bool IsDefined (Type t, bool b)
- {
- return true;
- }
-
- public override EventAttributes Attributes {
- get {
- return attributes;
- }
- }
-
- public override string Name {
- get {
- return name;
- }
- }
-
- public override Type DeclaringType {
- get {
- return declaring_type;
- }
- }
-
- public override Type ReflectedType {
- get {
- return reflected_type;
- }
- }
-
- public Type EventType {
- get {
- return event_type;
- }
- }
-
- public void SetUsed ()
- {
- if (my_event != null)
- my_event.status = (FieldBase.Status.ASSIGNED | FieldBase.Status.USED);
- }
- }
-
- public class Event : FieldBase {
- const int AllowedModifiers =
- Modifiers.NEW |
- Modifiers.PUBLIC |
- Modifiers.PROTECTED |
- Modifiers.INTERNAL |
- Modifiers.PRIVATE |
- Modifiers.STATIC |
- Modifiers.VIRTUAL |
- Modifiers.SEALED |
- Modifiers.OVERRIDE |
- Modifiers.UNSAFE |
- Modifiers.ABSTRACT;
-
- public readonly Accessor Add;
- public readonly Accessor Remove;
- public MyEventBuilder EventBuilder;
-
- MethodBuilder AddBuilder, RemoveBuilder;
- MethodData AddData, RemoveData;
-
- public Event (Expression type, string name, Object init, int mod, Accessor add,
- Accessor remove, Attributes attrs, Location loc)
- : base (type, mod, AllowedModifiers, name, init, attrs, loc)
- {
- Add = add;
- Remove = remove;
- }
-
- public override bool Define (TypeContainer parent)
- {
- EventAttributes e_attr = EventAttributes.RTSpecialName | EventAttributes.SpecialName;
-
- if (!DoDefine (parent))
- return false;
-
- if (!MemberType.IsSubclassOf (TypeManager.delegate_type)) {
- Report.Error (66, Location, "'" + parent.Name + "." + Name +
- "' : event must be of a delegate type");
- return false;
- }
-
- Type [] parameter_types = new Type [1];
- parameter_types [0] = MemberType;
-
- Parameter [] parms = new Parameter [1];
- parms [0] = new Parameter (Type, "value", Parameter.Modifier.NONE, null);
- InternalParameters ip = new InternalParameters (
- parent, new Parameters (parms, null, Location));
-
- if (!CheckBase (parent))
- return false;
-
- //
- // Now define the accessors
- //
- AddData = new MethodData (this, "add", TypeManager.void_type,
- parameter_types, ip, CallingConventions.Standard,
- (Add != null) ? Add.OptAttributes : null,
- ModFlags, flags, false);
-
- if (!AddData.Define (parent))
- return false;
-
- AddBuilder = AddData.MethodBuilder;
- AddBuilder.DefineParameter (1, ParameterAttributes.None, "value");
-
- RemoveData = new MethodData (this, "remove", TypeManager.void_type,
- parameter_types, ip, CallingConventions.Standard,
- (Remove != null) ? Remove.OptAttributes : null,
- ModFlags, flags, false);
-
- if (!RemoveData.Define (parent))
- return false;
-
- RemoveBuilder = RemoveData.MethodBuilder;
- RemoveBuilder.DefineParameter (1, ParameterAttributes.None, "value");
-
- if (!IsExplicitImpl){
- EventBuilder = new MyEventBuilder (this,
- parent.TypeBuilder, Name, e_attr, MemberType);
-
- if (Add == null && Remove == null) {
- FieldBuilder = parent.TypeBuilder.DefineField (
- Name, MemberType,
- FieldAttributes.FamANDAssem | ((ModFlags & Modifiers.STATIC) != 0 ? FieldAttributes.Static : 0));
- TypeManager.RegisterPrivateFieldOfEvent (
- (EventInfo) EventBuilder, FieldBuilder);
- TypeManager.RegisterFieldBase (FieldBuilder, this);
- }
-
- EventBuilder.SetAddOnMethod (AddBuilder);
- EventBuilder.SetRemoveOnMethod (RemoveBuilder);
-
- if (!TypeManager.RegisterEvent (EventBuilder, AddBuilder, RemoveBuilder)) {
- Report.Error (111, Location,
- "Class `" + parent.Name +
- "' already contains a definition for the event `" +
- Name + "'");
- return false;
- }
- }
-
- return true;
- }
-
- void EmitDefaultMethod (EmitContext ec, bool is_add)
- {
- ILGenerator ig = ec.ig;
- MethodInfo method = null;
-
- if (is_add)
- method = TypeManager.delegate_combine_delegate_delegate;
- else
- method = TypeManager.delegate_remove_delegate_delegate;
-
- if ((ModFlags & Modifiers.STATIC) != 0) {
- ig.Emit (OpCodes.Ldsfld, (FieldInfo) FieldBuilder);
- ig.Emit (OpCodes.Ldarg_0);
- ig.Emit (OpCodes.Call, method);
- ig.Emit (OpCodes.Castclass, MemberType);
- ig.Emit (OpCodes.Stsfld, (FieldInfo) FieldBuilder);
- } else {
- ig.Emit (OpCodes.Ldarg_0);
- ig.Emit (OpCodes.Ldarg_0);
- ig.Emit (OpCodes.Ldfld, (FieldInfo) FieldBuilder);
- ig.Emit (OpCodes.Ldarg_1);
- ig.Emit (OpCodes.Call, method);
- ig.Emit (OpCodes.Castclass, MemberType);
- ig.Emit (OpCodes.Stfld, (FieldInfo) FieldBuilder);
- }
- ig.Emit (OpCodes.Ret);
- }
-
- public void Emit (TypeContainer tc)
- {
- EmitContext ec;
-
- ec = new EmitContext (tc, Location, null, MemberType, ModFlags);
- Attribute.ApplyAttributes (ec, EventBuilder, this, OptAttributes, Location);
-
- if (Add != null)
- AddData.Emit (tc, Add.Block, Add);
- else {
- ILGenerator ig = AddData.MethodBuilder.GetILGenerator ();
- ec = new EmitContext (tc, Location, ig, TypeManager.void_type, ModFlags);
- EmitDefaultMethod (ec, true);
- }
-
- if (Remove != null)
- RemoveData.Emit (tc, Remove.Block, Remove);
- else {
- ILGenerator ig = RemoveData.MethodBuilder.GetILGenerator ();
- ec = new EmitContext (tc, Location, ig, TypeManager.void_type, ModFlags);
- EmitDefaultMethod (ec, false);
- }
- }
-
- }
-
- //
- // FIXME: This does not handle:
- //
- // int INTERFACENAME [ args ]
- // Does not
- //
- // Only:
- //
- // int this [ args ]
-
- public class Indexer : PropertyBase {
-
- const int AllowedModifiers =
- Modifiers.NEW |
- Modifiers.PUBLIC |
- Modifiers.PROTECTED |
- Modifiers.INTERNAL |
- Modifiers.PRIVATE |
- Modifiers.VIRTUAL |
- Modifiers.SEALED |
- Modifiers.OVERRIDE |
- Modifiers.UNSAFE |
- Modifiers.EXTERN |
- Modifiers.ABSTRACT;
-
- public string IndexerName;
- public string InterfaceIndexerName;
-
- //
- // Are we implementing an interface ?
- //
- bool IsImplementing = false;
-
- public Indexer (Expression type, string int_type, int flags, Parameters parameters,
- Accessor get_block, Accessor set_block, Attributes attrs, Location loc)
- : base (type, "", flags, AllowedModifiers, parameters, get_block, set_block,
- attrs, loc)
- {
- ExplicitInterfaceName = int_type;
- }
-
- public override bool Define (TypeContainer parent)
- {
- PropertyAttributes prop_attr =
- PropertyAttributes.RTSpecialName |
- PropertyAttributes.SpecialName;
-
- if (!DoDefine (parent))
- return false;
-
- IndexerName = Attribute.ScanForIndexerName (ec, OptAttributes);
- if (IndexerName == null)
- IndexerName = "Item";
- else if (IsExplicitImpl)
- Report.Error (592, Location,
- "Attribute 'IndexerName' is not valid on this declaration " +
- "type. It is valid on `property' declarations only.");
-
- ShortName = IndexerName;
- if (IsExplicitImpl) {
- InterfaceIndexerName = TypeManager.IndexerPropertyName (InterfaceType);
- Name = InterfaceType.FullName + "." + IndexerName;
- } else {
- InterfaceIndexerName = IndexerName;
- Name = ShortName;
- }
-
- if (!CheckBase (parent))
- return false;
-
- if (Get != null){
- InternalParameters ip = new InternalParameters (parent, Parameters);
-
- GetData = new MethodData (this, "get", MemberType,
- ParameterTypes, ip, CallingConventions.Standard,
- Get.OptAttributes, ModFlags, flags, false);
-
- if (!GetData.Define (parent))
- return false;
-
- GetBuilder = GetData.MethodBuilder;
- }
-
- if (Set != null){
- int top = ParameterTypes.Length;
- Type [] set_pars = new Type [top + 1];
- ParameterTypes.CopyTo (set_pars, 0);
- set_pars [top] = MemberType;
-
- Parameter [] fixed_parms = Parameters.FixedParameters;
-
- if (fixed_parms == null){
- throw new Exception ("We currently do not support only array arguments in an indexer");
- // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
- // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
- //
- // Here is the problem: the `value' parameter has
- // to come *after* the array parameter in the declaration
- // like this:
- // X (object [] x, Type value)
- // .param [0]
- //
- // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
- // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
-
- }
-
- Parameter [] tmp = new Parameter [fixed_parms.Length + 1];
-
-
- fixed_parms.CopyTo (tmp, 0);
- tmp [fixed_parms.Length] = new Parameter (
- Type, "value", Parameter.Modifier.NONE, null);
-
- Parameters set_formal_params = new Parameters (tmp, null, Location);
-
- InternalParameters ip = new InternalParameters (parent, set_formal_params);
-
- SetData = new MethodData (this, "set", TypeManager.void_type,
- set_pars, ip, CallingConventions.Standard,
- Set.OptAttributes, ModFlags, flags, false);
-
- if (!SetData.Define (parent))
- return false;
-
- SetBuilder = SetData.MethodBuilder;
- }
-
- //
- // Now name the parameters
- //
- Parameter [] p = Parameters.FixedParameters;
- if (p != null) {
- int i;
-
- for (i = 0; i < p.Length; ++i) {
- if (Get != null)
- GetBuilder.DefineParameter (
- i + 1, p [i].Attributes, p [i].Name);
-
- if (Set != null)
- SetBuilder.DefineParameter (
- i + 1, p [i].Attributes, p [i].Name);
- }
-
- if (Set != null)
- SetBuilder.DefineParameter (
- i + 1, ParameterAttributes.None, "value");
-
- if (i != ParameterTypes.Length) {
- Parameter array_param = Parameters.ArrayParameter;
- SetBuilder.DefineParameter (
- i + 1, array_param.Attributes, array_param.Name);
- }
- }
-
- if (GetData != null)
- IsImplementing = GetData.IsImplementing;
- else if (SetData != null)
- IsImplementing = SetData.IsImplementing;
-
- //
- // 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 (
- IndexerName, prop_attr, MemberType, ParameterTypes);
-
- if (GetData != null)
- PropertyBuilder.SetGetMethod (GetBuilder);
-
- if (SetData != null)
- PropertyBuilder.SetSetMethod (SetBuilder);
-
- TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder,
- ParameterTypes);
- }
-
- return true;
- }
- }
-
- public class Operator : MemberCore {
-
- const int AllowedModifiers =
- Modifiers.PUBLIC |
- Modifiers.UNSAFE |
- Modifiers.EXTERN |
- Modifiers.STATIC;
-
- const int RequiredModifiers =
- Modifiers.PUBLIC |
- Modifiers.STATIC;
-
- public enum OpType : byte {
-
- // Unary operators
- LogicalNot,
- OnesComplement,
- Increment,
- Decrement,
- True,
- False,
-
- // Unary and Binary operators
- Addition,
- Subtraction,
-
- UnaryPlus,
- UnaryNegation,
-
- // Binary operators
- Multiply,
- Division,
- Modulus,
- BitwiseAnd,
- BitwiseOr,
- ExclusiveOr,
- LeftShift,
- RightShift,
- Equality,
- Inequality,
- GreaterThan,
- LessThan,
- GreaterThanOrEqual,
- LessThanOrEqual,
-
- // Implicit and Explicit
- Implicit,
- Explicit
- };
-
- public readonly OpType OperatorType;
- public readonly Expression ReturnType;
- public readonly Expression FirstArgType, SecondArgType;
- public readonly string FirstArgName, SecondArgName;
- public readonly Block Block;
- public Attributes OptAttributes;
- public MethodBuilder OperatorMethodBuilder;
-
- public string MethodName;
- public Method OperatorMethod;
-
- public Operator (OpType type, Expression ret_type, int flags,
- Expression arg1type, string arg1name,
- Expression arg2type, string arg2name,
- Block block, Attributes attrs, Location loc)
- : base ("", loc)
- {
- OperatorType = type;
- ReturnType = ret_type;
- ModFlags = Modifiers.Check (AllowedModifiers, flags, Modifiers.PUBLIC, loc);
- FirstArgType = arg1type;
- FirstArgName = arg1name;
- SecondArgType = arg2type;
- SecondArgName = arg2name;
- Block = block;
- OptAttributes = attrs;
- }
-
- string Prototype (TypeContainer parent)
- {
- return parent.Name + ".operator " + OperatorType + " (" + FirstArgType + "," +
- SecondArgType + ")";
- }
-
- public override bool Define (TypeContainer parent)
- {
- int length = 1;
- MethodName = "op_" + OperatorType;
-
- if (SecondArgType != null)
- length = 2;
-
- Parameter [] param_list = new Parameter [length];
-
- if ((ModFlags & RequiredModifiers) != RequiredModifiers){
- Report.Error (
- 558, Location,
- "User defined operators `" +
- Prototype (parent) +
- "' must be declared static and public");
- return false;
- }
-
- param_list[0] = new Parameter (FirstArgType, FirstArgName,
- Parameter.Modifier.NONE, null);
- if (SecondArgType != null)
- param_list[1] = new Parameter (SecondArgType, SecondArgName,
- Parameter.Modifier.NONE, null);
-
- OperatorMethod = new Method (ReturnType, ModFlags, MethodName,
- new Parameters (param_list, null, Location),
- OptAttributes, Mono.CSharp.Location.Null);
-
- OperatorMethod.IsOperator = true;
- OperatorMethod.Define (parent);
-
- if (OperatorMethod.MethodBuilder == null)
- return false;
-
- OperatorMethodBuilder = OperatorMethod.MethodBuilder;
-
- Type [] param_types = OperatorMethod.ParameterTypes;
- Type declaring_type = OperatorMethodBuilder.DeclaringType;
- Type return_type = OperatorMethod.GetReturnType ();
- Type first_arg_type = param_types [0];
-
- // Rules for conversion operators
-
- if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
- if (first_arg_type == return_type && first_arg_type == declaring_type){
- Report.Error (
- 555, Location,
- "User-defined conversion cannot take an object of the " +
- "enclosing type and convert to an object of the enclosing" +
- " type");
- return false;
- }
-
- if (first_arg_type != declaring_type && return_type != declaring_type){
- Report.Error (
- 556, Location,
- "User-defined conversion must convert to or from the " +
- "enclosing type");
- return false;
- }
-
- if (first_arg_type == TypeManager.object_type ||
- return_type == TypeManager.object_type){
- Report.Error (
- -8, Location,
- "User-defined conversion cannot convert to or from " +
- "object type");
- return false;
- }
-
- if (first_arg_type.IsInterface || return_type.IsInterface){
- Report.Error (
- 552, Location,
- "User-defined conversion cannot convert to or from an " +
- "interface type");
- return false;
- }
-
- if (first_arg_type.IsSubclassOf (return_type) ||
- return_type.IsSubclassOf (first_arg_type)){
- Report.Error (
- -10, Location,
- "User-defined conversion cannot convert between types " +
- "that derive from each other");
- return false;
- }
- } else if (SecondArgType == null) {
- // Checks for Unary operators
-
- if (first_arg_type != declaring_type){
- Report.Error (
- 562, Location,
- "The parameter of a unary operator must be the " +
- "containing type");
- return false;
- }
-
- if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
- if (return_type != declaring_type){
- Report.Error (
- 559, Location,
- "The parameter and return type for ++ and -- " +
- "must be the containing type");
- return false;
- }
-
- }
-
- if (OperatorType == OpType.True || OperatorType == OpType.False) {
- if (return_type != TypeManager.bool_type){
- Report.Error (
- 215, Location,
- "The return type of operator True or False " +
- "must be bool");
- return false;
- }
- }
-
- } else {
- // Checks for Binary operators
-
- if (first_arg_type != declaring_type &&
- param_types [1] != declaring_type){
- Report.Error (
- 563, Location,
- "One of the parameters of a binary operator must " +
- "be the containing type");
- return false;
- }
- }
-
- return true;
- }
-
- public void Emit (TypeContainer parent)
- {
- EmitContext ec = new EmitContext (parent, Location, null, null, ModFlags);
- Attribute.ApplyAttributes (ec, OperatorMethodBuilder, this, OptAttributes, Location);
-
- //
- // abstract or extern methods have no bodies
- //
- if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
- return;
-
- OperatorMethod.Block = Block;
- OperatorMethod.Emit (parent);
- }
-
- public static string GetName (OpType ot)
- {
- switch (ot){
- case OpType.LogicalNot:
- return "!";
- case OpType.OnesComplement:
- return "~";
- case OpType.Increment:
- return "++";
- case OpType.Decrement:
- return "--";
- case OpType.True:
- return "true";
- case OpType.False:
- return "false";
- case OpType.Addition:
- return "+";
- case OpType.Subtraction:
- return "-";
- case OpType.UnaryPlus:
- return "+";
- case OpType.UnaryNegation:
- return "-";
- case OpType.Multiply:
- return "*";
- case OpType.Division:
- return "/";
- case OpType.Modulus:
- return "%";
- case OpType.BitwiseAnd:
- return "&";
- case OpType.BitwiseOr:
- return "|";
- case OpType.ExclusiveOr:
- return "^";
- case OpType.LeftShift:
- return "<<";
- case OpType.RightShift:
- return ">>";
- case OpType.Equality:
- return "==";
- case OpType.Inequality:
- return "!=";
- case OpType.GreaterThan:
- return ">";
- case OpType.LessThan:
- return "<";
- case OpType.GreaterThanOrEqual:
- return ">=";
- case OpType.LessThanOrEqual:
- return "<=";
- case OpType.Implicit:
- return "implicit";
- case OpType.Explicit:
- return "explicit";
- default: return "";
- }
- }
-
- public override string ToString ()
- {
- Type return_type = OperatorMethod.GetReturnType();
- Type [] param_types = OperatorMethod.ParameterTypes;
-
- if (SecondArgType == null)
- return String.Format (
- "{0} operator {1}({2})",
- TypeManager.CSharpName (return_type),
- GetName (OperatorType),
- param_types [0]);
- else
- return String.Format (
- "{0} operator {1}({2}, {3})",
- TypeManager.CSharpName (return_type),
- GetName (OperatorType),
- param_types [0], param_types [1]);
- }
- }
-
- //
- // This is used to compare method signatures
- //
- struct MethodSignature {
- public string Name;
- public Type RetType;
- public Type [] Parameters;
-
- /// <summary>
- /// This delegate is used to extract methods which have the
- /// same signature as the argument
- /// </summary>
- public static MemberFilter method_signature_filter;
-
- /// <summary>
- /// This delegate is used to extract inheritable methods which
- /// have the same signature as the argument. By inheritable,
- /// this means that we have permissions to override the method
- /// from the current assembly and class
- /// </summary>
- public static MemberFilter inheritable_method_signature_filter;
-
- static MethodSignature ()
- {
- method_signature_filter = new MemberFilter (MemberSignatureCompare);
- inheritable_method_signature_filter = new MemberFilter (
- InheritableMemberSignatureCompare);
- }
-
- public MethodSignature (string name, Type ret_type, Type [] parameters)
- {
- Name = name;
- RetType = ret_type;
-
- if (parameters == null)
- Parameters = TypeManager.NoTypes;
- else
- Parameters = parameters;
- }
-
- public override int GetHashCode ()
- {
- return Name.GetHashCode ();
- }
-
- public override bool Equals (Object o)
- {
- MethodSignature other = (MethodSignature) o;
-
- if (other.Name != Name)
- return false;
-
- if (other.RetType != RetType)
- return false;
-
- if (Parameters == null){
- if (other.Parameters == null)
- return true;
- return false;
- }
-
- if (other.Parameters == null)
- return false;
-
- int c = Parameters.Length;
- if (other.Parameters.Length != c)
- return false;
-
- for (int i = 0; i < c; i++)
- if (other.Parameters [i] != Parameters [i])
- return false;
-
- return true;
- }
-
- static bool MemberSignatureCompare (MemberInfo m, object filter_criteria)
- {
- MethodSignature sig = (MethodSignature) filter_criteria;
-
- if (m.Name != sig.Name)
- return false;
-
- Type ReturnType;
- MethodInfo mi = m as MethodInfo;
- PropertyInfo pi = m as PropertyInfo;
-
- if (mi != null)
- ReturnType = mi.ReturnType;
- else if (pi != null)
- ReturnType = pi.PropertyType;
- else
- return false;
-
- //
- // we use sig.RetType == null to mean `do not check the
- // method return value.
- //
- if (sig.RetType != null)
- if (ReturnType != sig.RetType)
- return false;
-
- Type [] args;
- if (mi != null)
- args = TypeManager.GetArgumentTypes (mi);
- else
- args = TypeManager.GetArgumentTypes (pi);
- Type [] sigp = sig.Parameters;
-
- if (args.Length != sigp.Length)
- return false;
-
- for (int i = args.Length; i > 0; ){
- i--;
- if (args [i] != sigp [i])
- return false;
- }
- return true;
- }
-
- //
- // This filter should be used when we are requesting methods that
- // we want to override.
- //
- // This makes a number of assumptions, for example
- // that the methods being extracted are of a parent
- // class (this means we know implicitly that we are
- // being called to find out about members by a derived
- // class).
- //
- static bool InheritableMemberSignatureCompare (MemberInfo m, object filter_criteria)
- {
- if (!MemberSignatureCompare (m, filter_criteria))
- return false;
-
- MethodInfo mi;
- PropertyInfo pi = m as PropertyInfo;
-
- if (pi != null) {
- mi = pi.GetGetMethod (true);
- if (mi == null)
- mi = pi.GetSetMethod (true);
- } else
- mi = m as MethodInfo;
-
- if (mi == null){
- Console.WriteLine ("Nothing found");
- }
-
- MethodAttributes prot = mi.Attributes & MethodAttributes.MemberAccessMask;
-
- // If only accessible to the current class.
- if (prot == MethodAttributes.Private)
- return false;
-
- // If only accessible to the defining assembly or
- if (prot == MethodAttributes.FamANDAssem ||
- prot == MethodAttributes.Assembly){
- if (m.DeclaringType.Assembly == CodeGen.AssemblyBuilder)
- return true;
- else
- return false;
- }
-
- // Anything else (FamOrAssembly and Public) is fine
- return true;
- }
- }
-}
diff --git a/mcs/mcs/expression.cs b/mcs/mcs/expression.cs
deleted file mode 100755
index 3b770362870..00000000000
--- a/mcs/mcs/expression.cs
+++ /dev/null
@@ -1,7390 +0,0 @@
-//
-// expression.cs: Expression representation for the IL tree.
-//
-// Author:
-// Miguel de Icaza (miguel@ximian.com)
-//
-// (C) 2001 Ximian, Inc.
-//
-//
-#define USE_OLD
-
-namespace Mono.CSharp {
- using System;
- using System.Collections;
- using System.Reflection;
- using System.Reflection.Emit;
- using System.Text;
-
- /// <summary>
- /// This is just a helper class, it is generated by Unary, UnaryMutator
- /// when an overloaded method has been found. It just emits the code for a
- /// static call.
- /// </summary>
- public class StaticCallExpr : ExpressionStatement {
- ArrayList args;
- MethodInfo mi;
-
- StaticCallExpr (MethodInfo m, ArrayList a, Location l)
- {
- mi = m;
- args = a;
-
- type = m.ReturnType;
- eclass = ExprClass.Value;
- loc = l;
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- //
- // We are born fully resolved
- //
- return this;
- }
-
- public override void Emit (EmitContext ec)
- {
- if (args != null)
- Invocation.EmitArguments (ec, mi, args);
-
- ec.ig.Emit (OpCodes.Call, mi);
- return;
- }
-
- static public Expression MakeSimpleCall (EmitContext ec, MethodGroupExpr mg,
- Expression e, Location loc)
- {
- ArrayList args;
- MethodBase method;
-
- args = new ArrayList (1);
- args.Add (new Argument (e, Argument.AType.Expression));
- method = Invocation.OverloadResolve (ec, (MethodGroupExpr) mg, args, loc);
-
- if (method == null)
- return null;
-
- return new StaticCallExpr ((MethodInfo) method, args, loc);
- }
-
- public override void EmitStatement (EmitContext ec)
- {
- Emit (ec);
- if (TypeManager.TypeToCoreType (type) != TypeManager.void_type)
- ec.ig.Emit (OpCodes.Pop);
- }
- }
-
- /// <summary>
- /// Unary expressions.
- /// </summary>
- ///
- /// <remarks>
- /// Unary implements unary expressions. It derives from
- /// ExpressionStatement becuase the pre/post increment/decrement
- /// operators can be used in a statement context.
- /// </remarks>
- public class Unary : Expression {
- public enum Operator : byte {
- UnaryPlus, UnaryNegation, LogicalNot, OnesComplement,
- Indirection, AddressOf, TOP
- }
-
- public Operator Oper;
- public Expression Expr;
-
- public Unary (Operator op, Expression expr, Location loc)
- {
- this.Oper = op;
- this.Expr = expr;
- this.loc = loc;
- }
-
- /// <summary>
- /// Returns a stringified representation of the Operator
- /// </summary>
- static public string OperName (Operator oper)
- {
- switch (oper){
- case Operator.UnaryPlus:
- return "+";
- case Operator.UnaryNegation:
- return "-";
- case Operator.LogicalNot:
- return "!";
- case Operator.OnesComplement:
- return "~";
- case Operator.AddressOf:
- return "&";
- case Operator.Indirection:
- return "*";
- }
-
- return oper.ToString ();
- }
-
- static string [] oper_names;
-
- static Unary ()
- {
- oper_names = new string [(int)Operator.TOP];
-
- oper_names [(int) Operator.UnaryPlus] = "op_UnaryPlus";
- oper_names [(int) Operator.UnaryNegation] = "op_UnaryNegation";
- oper_names [(int) Operator.LogicalNot] = "op_LogicalNot";
- oper_names [(int) Operator.OnesComplement] = "op_OnesComplement";
- oper_names [(int) Operator.Indirection] = "op_Indirection";
- oper_names [(int) Operator.AddressOf] = "op_AddressOf";
- }
-
- void Error23 (Type t)
- {
- Error (
- 23, "Operator " + OperName (Oper) +
- " cannot be applied to operand of type `" +
- TypeManager.CSharpName (t) + "'");
- }
-
- /// <remarks>
- /// The result has been already resolved:
- ///
- /// FIXME: a minus constant -128 sbyte cant be turned into a
- /// constant byte.
- /// </remarks>
- static Expression TryReduceNegative (Constant expr)
- {
- Expression e = null;
-
- if (expr is IntConstant)
- e = new IntConstant (-((IntConstant) expr).Value);
- else if (expr is UIntConstant){
- uint value = ((UIntConstant) expr).Value;
-
- if (value < 2147483649)
- return new IntConstant (-(int)value);
- else
- e = new LongConstant (value);
- }
- else if (expr is LongConstant)
- e = new LongConstant (-((LongConstant) expr).Value);
- else if (expr is ULongConstant){
- ulong value = ((ULongConstant) expr).Value;
-
- if (value < 9223372036854775809)
- return new LongConstant(-(long)value);
- }
- else if (expr is FloatConstant)
- e = new FloatConstant (-((FloatConstant) expr).Value);
- else if (expr is DoubleConstant)
- e = new DoubleConstant (-((DoubleConstant) expr).Value);
- else if (expr is DecimalConstant)
- e = new DecimalConstant (-((DecimalConstant) expr).Value);
- else if (expr is ShortConstant)
- e = new IntConstant (-((ShortConstant) expr).Value);
- else if (expr is UShortConstant)
- e = new IntConstant (-((UShortConstant) expr).Value);
- return e;
- }
-
- // <summary>
- // This routine will attempt to simplify the unary expression when the
- // argument is a constant. The result is returned in `result' and the
- // function returns true or false depending on whether a reduction
- // was performed or not
- // </summary>
- bool Reduce (EmitContext ec, Constant e, out Expression result)
- {
- Type expr_type = e.Type;
-
- switch (Oper){
- case Operator.UnaryPlus:
- result = e;
- return true;
-
- case Operator.UnaryNegation:
- result = TryReduceNegative (e);
- return true;
-
- case Operator.LogicalNot:
- if (expr_type != TypeManager.bool_type) {
- result = null;
- Error23 (expr_type);
- return false;
- }
-
- BoolConstant b = (BoolConstant) e;
- result = new BoolConstant (!(b.Value));
- return true;
-
- case Operator.OnesComplement:
- if (!((expr_type == TypeManager.int32_type) ||
- (expr_type == TypeManager.uint32_type) ||
- (expr_type == TypeManager.int64_type) ||
- (expr_type == TypeManager.uint64_type) ||
- (expr_type.IsSubclassOf (TypeManager.enum_type)))){
- result = null;
- Error23 (expr_type);
- return false;
- }
-
- if (e is EnumConstant){
- EnumConstant enum_constant = (EnumConstant) e;
- Expression reduced;
-
- if (Reduce (ec, enum_constant.Child, out reduced)){
- result = new EnumConstant ((Constant) reduced, enum_constant.Type);
- return true;
- } else {
- result = null;
- return false;
- }
- }
-
- if (expr_type == TypeManager.int32_type){
- result = new IntConstant (~ ((IntConstant) e).Value);
- } else if (expr_type == TypeManager.uint32_type){
- result = new UIntConstant (~ ((UIntConstant) e).Value);
- } else if (expr_type == TypeManager.int64_type){
- result = new LongConstant (~ ((LongConstant) e).Value);
- } else if (expr_type == TypeManager.uint64_type){
- result = new ULongConstant (~ ((ULongConstant) e).Value);
- } else {
- result = null;
- Error23 (expr_type);
- return false;
- }
- return true;
-
- case Operator.AddressOf:
- result = this;
- return false;
-
- case Operator.Indirection:
- result = this;
- return false;
- }
- throw new Exception ("Can not constant fold: " + Oper.ToString());
- }
-
- Expression ResolveOperator (EmitContext ec)
- {
- Type expr_type = Expr.Type;
-
- //
- // Step 1: Perform Operator Overload location
- //
- Expression mg;
- string op_name;
-
- op_name = oper_names [(int) Oper];
-
- mg = MemberLookup (ec, expr_type, op_name, MemberTypes.Method, AllBindingFlags, loc);
-
- if (mg != null) {
- Expression e = StaticCallExpr.MakeSimpleCall (
- ec, (MethodGroupExpr) mg, Expr, loc);
-
- if (e == null){
- Error23 (expr_type);
- return null;
- }
-
- return e;
- }
-
- // Only perform numeric promotions on:
- // +, -
-
- if (expr_type == null)
- return null;
-
- //
- // Step 2: Default operations on CLI native types.
- //
-
- // Attempt to use a constant folding operation.
- if (Expr is Constant){
- Expression result;
-
- if (Reduce (ec, (Constant) Expr, out result))
- return result;
- }
-
- switch (Oper){
- case Operator.LogicalNot:
- if (expr_type != TypeManager.bool_type) {
- Error23 (Expr.Type);
- return null;
- }
-
- type = TypeManager.bool_type;
- return this;
-
- case Operator.OnesComplement:
- if (!((expr_type == TypeManager.int32_type) ||
- (expr_type == TypeManager.uint32_type) ||
- (expr_type == TypeManager.int64_type) ||
- (expr_type == TypeManager.uint64_type) ||
- (expr_type.IsSubclassOf (TypeManager.enum_type)))){
- Expression e;
-
- e = ConvertImplicit (ec, Expr, TypeManager.int32_type, loc);
- if (e != null){
- type = TypeManager.int32_type;
- return this;
- }
- e = ConvertImplicit (ec, Expr, TypeManager.uint32_type, loc);
- if (e != null){
- type = TypeManager.uint32_type;
- return this;
- }
- e = ConvertImplicit (ec, Expr, TypeManager.int64_type, loc);
- if (e != null){
- type = TypeManager.int64_type;
- return this;
- }
- e = ConvertImplicit (ec, Expr, TypeManager.uint64_type, loc);
- if (e != null){
- type = TypeManager.uint64_type;
- return this;
- }
- Error23 (expr_type);
- return null;
- }
- type = expr_type;
- return this;
-
- case Operator.AddressOf:
- if (Expr.eclass != ExprClass.Variable){
- Error (211, "Cannot take the address of non-variables");
- return null;
- }
-
- if (!ec.InUnsafe) {
- UnsafeError (loc);
- return null;
- }
-
- if (!TypeManager.VerifyUnManaged (Expr.Type, loc)){
- return null;
- }
-
- string ptr_type_name = Expr.Type.FullName + "*";
- type = TypeManager.LookupType (ptr_type_name);
-
- return this;
-
- case Operator.Indirection:
- if (!ec.InUnsafe){
- UnsafeError (loc);
- return null;
- }
-
- if (!expr_type.IsPointer){
- Error (
- 193,
- "The * or -> operator can only be applied to pointers");
- return null;
- }
-
- //
- // We create an Indirection expression, because
- // it can implement the IMemoryLocation.
- //
- return new Indirection (Expr, loc);
-
- case Operator.UnaryPlus:
- //
- // A plus in front of something is just a no-op, so return the child.
- //
- return Expr;
-
- case Operator.UnaryNegation:
- //
- // Deals with -literals
- // int operator- (int x)
- // long operator- (long x)
- // float operator- (float f)
- // double operator- (double d)
- // decimal operator- (decimal d)
- //
- Expression expr = null;
-
- //
- // transform - - expr into expr
- //
- if (Expr is Unary){
- Unary unary = (Unary) Expr;
-
- if (unary.Oper == Operator.UnaryNegation)
- return unary.Expr;
- }
-
- //
- // perform numeric promotions to int,
- // long, double.
- //
- //
- // The following is inneficient, because we call
- // ConvertImplicit too many times.
- //
- // It is also not clear if we should convert to Float
- // or Double initially.
- //
- if (expr_type == TypeManager.uint32_type){
- //
- // FIXME: handle exception to this rule that
- // permits the int value -2147483648 (-2^31) to
- // bt wrote as a decimal interger literal
- //
- type = TypeManager.int64_type;
- Expr = ConvertImplicit (ec, Expr, type, loc);
- return this;
- }
-
- if (expr_type == TypeManager.uint64_type){
- //
- // FIXME: Handle exception of `long value'
- // -92233720368547758087 (-2^63) to be wrote as
- // decimal integer literal.
- //
- Error23 (expr_type);
- return null;
- }
-
- if (expr_type == TypeManager.float_type){
- type = expr_type;
- return this;
- }
-
- expr = ConvertImplicit (ec, Expr, TypeManager.int32_type, loc);
- if (expr != null){
- Expr = expr;
- type = expr.Type;
- return this;
- }
-
- expr = ConvertImplicit (ec, Expr, TypeManager.int64_type, loc);
- if (expr != null){
- Expr = expr;
- type = expr.Type;
- return this;
- }
-
- expr = ConvertImplicit (ec, Expr, TypeManager.double_type, loc);
- if (expr != null){
- Expr = expr;
- type = expr.Type;
- return this;
- }
-
- Error23 (expr_type);
- return null;
- }
-
- Error (187, "No such operator '" + OperName (Oper) + "' defined for type '" +
- TypeManager.CSharpName (expr_type) + "'");
- return null;
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- if (Oper == Operator.AddressOf)
- Expr = Expr.ResolveLValue (ec, new EmptyExpression ());
- else
- Expr = Expr.Resolve (ec);
-
- if (Expr == null)
- return null;
-
- eclass = ExprClass.Value;
- return ResolveOperator (ec);
- }
-
- public override void Emit (EmitContext ec)
- {
- ILGenerator ig = ec.ig;
- Type expr_type = Expr.Type;
-
- switch (Oper) {
- case Operator.UnaryPlus:
- throw new Exception ("This should be caught by Resolve");
-
- case Operator.UnaryNegation:
- Expr.Emit (ec);
- ig.Emit (OpCodes.Neg);
- break;
-
- case Operator.LogicalNot:
- Expr.Emit (ec);
- ig.Emit (OpCodes.Ldc_I4_0);
- ig.Emit (OpCodes.Ceq);
- break;
-
- case Operator.OnesComplement:
- Expr.Emit (ec);
- ig.Emit (OpCodes.Not);
- break;
-
- case Operator.AddressOf:
- ((IMemoryLocation)Expr).AddressOf (ec, AddressOp.LoadStore);
- break;
-
- default:
- throw new Exception ("This should not happen: Operator = "
- + Oper.ToString ());
- }
- }
-
- /// <summary>
- /// This will emit the child expression for `ec' avoiding the logical
- /// not. The parent will take care of changing brfalse/brtrue
- /// </summary>
- public void EmitLogicalNot (EmitContext ec)
- {
- if (Oper != Operator.LogicalNot)
- throw new Exception ("EmitLogicalNot can only be called with !expr");
-
- Expr.Emit (ec);
- }
-
- public override string ToString ()
- {
- return "Unary (" + Oper + ", " + Expr + ")";
- }
-
- }
-
- //
- // Unary operators are turned into Indirection expressions
- // after semantic analysis (this is so we can take the address
- // of an indirection).
- //
- public class Indirection : Expression, IMemoryLocation, IAssignMethod {
- Expression expr;
- LocalTemporary temporary;
- bool have_temporary;
-
- public Indirection (Expression expr, Location l)
- {
- this.expr = expr;
- this.type = TypeManager.TypeToCoreType (expr.Type.GetElementType ());
- eclass = ExprClass.Variable;
- loc = l;
- }
-
- void LoadExprValue (EmitContext ec)
- {
- }
-
- public override void Emit (EmitContext ec)
- {
- ILGenerator ig = ec.ig;
-
- if (temporary != null){
- if (have_temporary){
- temporary.Emit (ec);
- return;
- }
- expr.Emit (ec);
- ec.ig.Emit (OpCodes.Dup);
- temporary.Store (ec);
- have_temporary = true;
- } else
- expr.Emit (ec);
-
- LoadFromPtr (ig, Type);
- }
-
- public void EmitAssign (EmitContext ec, Expression source)
- {
- if (temporary != null){
- if (have_temporary){
- temporary.Emit (ec);
- return;
- }
- expr.Emit (ec);
- ec.ig.Emit (OpCodes.Dup);
- temporary.Store (ec);
- have_temporary = true;
- } else
- expr.Emit (ec);
-
- source.Emit (ec);
- StoreFromPtr (ec.ig, type);
- }
-
- public void AddressOf (EmitContext ec, AddressOp Mode)
- {
- if (temporary != null){
- if (have_temporary){
- temporary.Emit (ec);
- return;
- }
- expr.Emit (ec);
- ec.ig.Emit (OpCodes.Dup);
- temporary.Store (ec);
- have_temporary = true;
- } else
- expr.Emit (ec);
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- //
- // Born fully resolved
- //
- return this;
- }
-
- public new void CacheTemporaries (EmitContext ec)
- {
- temporary = new LocalTemporary (ec, type);
- }
- }
-
- /// <summary>
- /// Unary Mutator expressions (pre and post ++ and --)
- /// </summary>
- ///
- /// <remarks>
- /// UnaryMutator implements ++ and -- expressions. It derives from
- /// ExpressionStatement becuase the pre/post increment/decrement
- /// operators can be used in a statement context.
- ///
- /// FIXME: Idea, we could split this up in two classes, one simpler
- /// for the common case, and one with the extra fields for more complex
- /// classes (indexers require temporary access; overloaded require method)
- ///
- /// </remarks>
- public class UnaryMutator : ExpressionStatement {
- [Flags]
- public enum Mode : byte {
- IsIncrement = 0,
- IsDecrement = 1,
- IsPre = 0,
- IsPost = 2,
-
- PreIncrement = 0,
- PreDecrement = IsDecrement,
- PostIncrement = IsPost,
- PostDecrement = IsPost | IsDecrement
- }
-
- Mode mode;
- Expression expr;
- LocalTemporary temp_storage;
-
- //
- // This is expensive for the simplest case.
- //
- Expression method;
-
- public UnaryMutator (Mode m, Expression e, Location l)
- {
- mode = m;
- loc = l;
- expr = e;
- }
-
- static string OperName (Mode mode)
- {
- return (mode == Mode.PreIncrement || mode == Mode.PostIncrement) ?
- "++" : "--";
- }
-
- void Error23 (Type t)
- {
- Error (
- 23, "Operator " + OperName (mode) +
- " cannot be applied to operand of type `" +
- TypeManager.CSharpName (t) + "'");
- }
-
- /// <summary>
- /// Returns whether an object of type `t' can be incremented
- /// or decremented with add/sub (ie, basically whether we can
- /// use pre-post incr-decr operations on it, but it is not a
- /// System.Decimal, which we require operator overloading to catch)
- /// </summary>
- static bool IsIncrementableNumber (Type t)
- {
- return (t == TypeManager.sbyte_type) ||
- (t == TypeManager.byte_type) ||
- (t == TypeManager.short_type) ||
- (t == TypeManager.ushort_type) ||
- (t == TypeManager.int32_type) ||
- (t == TypeManager.uint32_type) ||
- (t == TypeManager.int64_type) ||
- (t == TypeManager.uint64_type) ||
- (t == TypeManager.char_type) ||
- (t.IsSubclassOf (TypeManager.enum_type)) ||
- (t == TypeManager.float_type) ||
- (t == TypeManager.double_type) ||
- (t.IsPointer && t != TypeManager.void_ptr_type);
- }
-
- Expression ResolveOperator (EmitContext ec)
- {
- Type expr_type = expr.Type;
-
- //
- // Step 1: Perform Operator Overload location
- //
- Expression mg;
- string op_name;
-
- if (mode == Mode.PreIncrement || mode == Mode.PostIncrement)
- op_name = "op_Increment";
- else
- op_name = "op_Decrement";
-
- mg = MemberLookup (ec, expr_type, op_name, MemberTypes.Method, AllBindingFlags, loc);
-
- if (mg == null && expr_type.BaseType != null)
- mg = MemberLookup (ec, expr_type.BaseType, op_name,
- MemberTypes.Method, AllBindingFlags, loc);
-
- if (mg != null) {
- method = StaticCallExpr.MakeSimpleCall (
- ec, (MethodGroupExpr) mg, expr, loc);
-
- type = method.Type;
- return this;
- }
-
- //
- // The operand of the prefix/postfix increment decrement operators
- // should be an expression that is classified as a variable,
- // a property access or an indexer access
- //
- type = expr_type;
- if (expr.eclass == ExprClass.Variable){
- if (IsIncrementableNumber (expr_type) ||
- expr_type == TypeManager.decimal_type){
- return this;
- }
- } else if (expr.eclass == ExprClass.IndexerAccess){
- IndexerAccess ia = (IndexerAccess) expr;
-
- temp_storage = new LocalTemporary (ec, expr.Type);
-
- expr = ia.ResolveLValue (ec, temp_storage);
- if (expr == null)
- return null;
-
- return this;
- } else if (expr.eclass == ExprClass.PropertyAccess){
- PropertyExpr pe = (PropertyExpr) expr;
-
- if (pe.VerifyAssignable ())
- return this;
-
- return null;
- } else {
- expr.Error118 ("variable, indexer or property access");
- return null;
- }
-
- Error (187, "No such operator '" + OperName (mode) + "' defined for type '" +
- TypeManager.CSharpName (expr_type) + "'");
- return null;
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- expr = expr.Resolve (ec);
-
- if (expr == null)
- return null;
-
- eclass = ExprClass.Value;
- return ResolveOperator (ec);
- }
-
- static int PtrTypeSize (Type t)
- {
- return GetTypeSize (t.GetElementType ());
- }
-
- //
- // Loads the proper "1" into the stack based on the type, then it emits the
- // opcode for the operation requested
- //
- void LoadOneAndEmitOp (EmitContext ec, Type t)
- {
- ILGenerator ig = ec.ig;
-
- if (t == TypeManager.uint64_type || t == TypeManager.int64_type)
- LongConstant.EmitLong (ig, 1);
- else if (t == TypeManager.double_type)
- ig.Emit (OpCodes.Ldc_R8, 1.0);
- else if (t == TypeManager.float_type)
- ig.Emit (OpCodes.Ldc_R4, 1.0F);
- else if (t.IsPointer){
- int n = PtrTypeSize (t);
-
- if (n == 0)
- ig.Emit (OpCodes.Sizeof, t);
- else
- IntConstant.EmitInt (ig, n);
- } else
- ig.Emit (OpCodes.Ldc_I4_1);
-
- //
- // Now emit the operation
- //
- if (ec.CheckState){
- if (t == TypeManager.int32_type ||
- t == TypeManager.int64_type){
- if ((mode & Mode.IsDecrement) != 0)
- ig.Emit (OpCodes.Sub_Ovf);
- else
- ig.Emit (OpCodes.Add_Ovf);
- } else if (t == TypeManager.uint32_type ||
- t == TypeManager.uint64_type){
- if ((mode & Mode.IsDecrement) != 0)
- ig.Emit (OpCodes.Sub_Ovf_Un);
- else
- ig.Emit (OpCodes.Add_Ovf_Un);
- } else {
- if ((mode & Mode.IsDecrement) != 0)
- ig.Emit (OpCodes.Sub_Ovf);
- else
- ig.Emit (OpCodes.Add_Ovf);
- }
- } else {
- if ((mode & Mode.IsDecrement) != 0)
- ig.Emit (OpCodes.Sub);
- else
- ig.Emit (OpCodes.Add);
- }
- }
-
- void EmitCode (EmitContext ec, bool is_expr)
- {
- ILGenerator ig = ec.ig;
- IAssignMethod ia = (IAssignMethod) expr;
- Type expr_type = expr.Type;
-
- ia.CacheTemporaries (ec);
-
- if (temp_storage == null)
- temp_storage = new LocalTemporary (ec, expr_type);
-
- switch (mode){
- case Mode.PreIncrement:
- case Mode.PreDecrement:
- if (method == null){
- expr.Emit (ec);
-
- LoadOneAndEmitOp (ec, expr_type);
- } else
- method.Emit (ec);
-
- temp_storage.Store (ec);
- ia.EmitAssign (ec, temp_storage);
- if (is_expr)
- temp_storage.Emit (ec);
- break;
-
- case Mode.PostIncrement:
- case Mode.PostDecrement:
- if (is_expr)
- expr.Emit (ec);
-
- if (method == null){
- if (!is_expr)
- expr.Emit (ec);
- else
- ig.Emit (OpCodes.Dup);
-
- LoadOneAndEmitOp (ec, expr_type);
- } else {
- method.Emit (ec);
- }
-
- temp_storage.Store (ec);
- ia.EmitAssign (ec, temp_storage);
- break;
- }
- }
-
- public override void Emit (EmitContext ec)
- {
- EmitCode (ec, true);
-
- }
-
- public override void EmitStatement (EmitContext ec)
- {
- EmitCode (ec, false);
- }
-
- }
-
- /// <summary>
- /// Base class for the `Is' and `As' classes.
- /// </summary>
- ///
- /// <remarks>
- /// FIXME: Split this in two, and we get to save the `Operator' Oper
- /// size.
- /// </remarks>
- public abstract class Probe : Expression {
- public readonly Expression ProbeType;
- protected Expression expr;
- protected Type probe_type;
-
- public Probe (Expression expr, Expression probe_type, Location l)
- {
- ProbeType = probe_type;
- loc = l;
- this.expr = expr;
- }
-
- public Expression Expr {
- get {
- return expr;
- }
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- probe_type = ec.DeclSpace.ResolveType (ProbeType, false, loc);
-
- if (probe_type == null)
- return null;
-
- expr = expr.Resolve (ec);
-
- return this;
- }
- }
-
- /// <summary>
- /// Implementation of the `is' operator.
- /// </summary>
- public class Is : Probe {
- public Is (Expression expr, Expression probe_type, Location l)
- : base (expr, probe_type, l)
- {
- }
-
- enum Action {
- AlwaysTrue, AlwaysNull, AlwaysFalse, LeaveOnStack, Probe
- }
-
- Action action;
-
- public override void Emit (EmitContext ec)
- {
- ILGenerator ig = ec.ig;
-
- expr.Emit (ec);
-
- switch (action){
- case Action.AlwaysFalse:
- ig.Emit (OpCodes.Pop);
- IntConstant.EmitInt (ig, 0);
- return;
- case Action.AlwaysTrue:
- ig.Emit (OpCodes.Pop);
- IntConstant.EmitInt (ig, 1);
- return;
- case Action.LeaveOnStack:
- // the `e != null' rule.
- return;
- case Action.Probe:
- ig.Emit (OpCodes.Isinst, probe_type);
- ig.Emit (OpCodes.Ldnull);
- ig.Emit (OpCodes.Cgt_Un);
- return;
- }
- throw new Exception ("never reached");
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- Expression e = base.DoResolve (ec);
-
- if ((e == null) || (expr == null))
- return null;
-
- Type etype = expr.Type;
- bool warning_always_matches = false;
- bool warning_never_matches = false;
-
- type = TypeManager.bool_type;
- eclass = ExprClass.Value;
-
- //
- // First case, if at compile time, there is an implicit conversion
- // then e != null (objects) or true (value types)
- //
- e = ConvertImplicitStandard (ec, expr, probe_type, loc);
- if (e != null){
- expr = e;
- if (etype.IsValueType)
- action = Action.AlwaysTrue;
- else
- action = Action.LeaveOnStack;
-
- warning_always_matches = true;
- } else if (ExplicitReferenceConversionExists (etype, probe_type)){
- //
- // Second case: explicit reference convresion
- //
- if (expr is NullLiteral)
- action = Action.AlwaysFalse;
- else
- action = Action.Probe;
- } else {
- action = Action.AlwaysFalse;
- warning_never_matches = true;
- }
-
- if (RootContext.WarningLevel >= 1){
- if (warning_always_matches)
- Warning (
- 183,
- "The expression is always of type `" +
- TypeManager.CSharpName (probe_type) + "'");
- else if (warning_never_matches){
- if (!(probe_type.IsInterface || expr.Type.IsInterface))
- Warning (
- 184,
- "The expression is never of type `" +
- TypeManager.CSharpName (probe_type) + "'");
- }
- }
-
- return this;
- }
- }
-
- /// <summary>
- /// Implementation of the `as' operator.
- /// </summary>
- public class As : Probe {
- public As (Expression expr, Expression probe_type, Location l)
- : base (expr, probe_type, l)
- {
- }
-
- bool do_isinst = false;
-
- public override void Emit (EmitContext ec)
- {
- ILGenerator ig = ec.ig;
-
- expr.Emit (ec);
-
- if (do_isinst)
- ig.Emit (OpCodes.Isinst, probe_type);
- }
-
- static void Error_CannotConvertType (Type source, Type target, Location loc)
- {
- Report.Error (
- 39, loc, "as operator can not convert from `" +
- TypeManager.CSharpName (source) + "' to `" +
- TypeManager.CSharpName (target) + "'");
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- Expression e = base.DoResolve (ec);
-
- if (e == null)
- return null;
-
- type = probe_type;
- eclass = ExprClass.Value;
- Type etype = expr.Type;
-
- if (TypeManager.IsValueType (probe_type)){
- Report.Error (77, loc, "The as operator should be used with a reference type only (" +
- TypeManager.CSharpName (probe_type) + " is a value type");
- return null;
-
- }
-
- e = ConvertImplicit (ec, expr, probe_type, loc);
- if (e != null){
- expr = e;
- do_isinst = false;
- return this;
- }
-
- if (ExplicitReferenceConversionExists (etype, probe_type)){
- do_isinst = true;
- return this;
- }
-
- Error_CannotConvertType (etype, probe_type, loc);
- return null;
- }
- }
-
- /// <summary>
- /// This represents a typecast in the source language.
- ///
- /// FIXME: Cast expressions have an unusual set of parsing
- /// rules, we need to figure those out.
- /// </summary>
- public class Cast : Expression {
- Expression target_type;
- Expression expr;
-
- public Cast (Expression cast_type, Expression expr, Location loc)
- {
- this.target_type = cast_type;
- this.expr = expr;
- this.loc = loc;
- }
-
- public Expression TargetType {
- get {
- return target_type;
- }
- }
-
- public Expression Expr {
- get {
- return expr;
- }
- set {
- expr = value;
- }
- }
-
- bool CheckRange (EmitContext ec, long value, Type type, long min, long max)
- {
- if (!ec.ConstantCheckState)
- return true;
-
- if ((value < min) || (value > max)) {
- Error (221, "Constant value `" + value + "' cannot be converted " +
- "to a `" + TypeManager.CSharpName (type) + "' (use `unchecked' " +
- "syntax to override)");
- return false;
- }
-
- return true;
- }
-
- bool CheckRange (EmitContext ec, ulong value, Type type, ulong max)
- {
- if (!ec.ConstantCheckState)
- return true;
-
- if (value > max) {
- Error (221, "Constant value `" + value + "' cannot be converted " +
- "to a `" + TypeManager.CSharpName (type) + "' (use `unchecked' " +
- "syntax to override)");
- return false;
- }
-
- return true;
- }
-
- bool CheckUnsigned (EmitContext ec, long value, Type type)
- {
- if (!ec.ConstantCheckState)
- return true;
-
- if (value < 0) {
- Error (221, "Constant value `" + value + "' cannot be converted " +
- "to a `" + TypeManager.CSharpName (type) + "' (use `unchecked' " +
- "syntax to override)");
- return false;
- }
-
- return true;
- }
-
- /// <summary>
- /// Attempts to do a compile-time folding of a constant cast.
- /// </summary>
- Expression TryReduce (EmitContext ec, Type target_type)
- {
- if (expr is ByteConstant){
- byte v = ((ByteConstant) expr).Value;
-
- if (target_type == TypeManager.sbyte_type) {
- if (!CheckRange (ec, v, target_type, SByte.MinValue, SByte.MaxValue))
- return null;
- return new SByteConstant ((sbyte) v);
- }
- if (target_type == TypeManager.short_type)
- return new ShortConstant ((short) v);
- if (target_type == TypeManager.ushort_type)
- return new UShortConstant ((ushort) v);
- if (target_type == TypeManager.int32_type)
- return new IntConstant ((int) v);
- if (target_type == TypeManager.uint32_type)
- return new UIntConstant ((uint) v);
- if (target_type == TypeManager.int64_type)
- return new LongConstant ((long) v);
- if (target_type == TypeManager.uint64_type)
- return new ULongConstant ((ulong) v);
- if (target_type == TypeManager.float_type)
- return new FloatConstant ((float) v);
- if (target_type == TypeManager.double_type)
- return new DoubleConstant ((double) v);
- if (target_type == TypeManager.char_type)
- return new CharConstant ((char) v);
- if (target_type == TypeManager.decimal_type)
- return new DecimalConstant ((decimal) v);
- }
- if (expr is SByteConstant){
- sbyte v = ((SByteConstant) expr).Value;
-
- if (target_type == TypeManager.byte_type) {
- if (!CheckUnsigned (ec, v, target_type))
- return null;
- return new ByteConstant ((byte) v);
- }
- if (target_type == TypeManager.short_type)
- return new ShortConstant ((short) v);
- if (target_type == TypeManager.ushort_type) {
- if (!CheckUnsigned (ec, v, target_type))
- return null;
- return new UShortConstant ((ushort) v);
- } if (target_type == TypeManager.int32_type)
- return new IntConstant ((int) v);
- if (target_type == TypeManager.uint32_type) {
- if (!CheckUnsigned (ec, v, target_type))
- return null;
- return new UIntConstant ((uint) v);
- } if (target_type == TypeManager.int64_type)
- return new LongConstant ((long) v);
- if (target_type == TypeManager.uint64_type) {
- if (!CheckUnsigned (ec, v, target_type))
- return null;
- return new ULongConstant ((ulong) v);
- }
- if (target_type == TypeManager.float_type)
- return new FloatConstant ((float) v);
- if (target_type == TypeManager.double_type)
- return new DoubleConstant ((double) v);
- if (target_type == TypeManager.char_type) {
- if (!CheckUnsigned (ec, v, target_type))
- return null;
- return new CharConstant ((char) v);
- }
- if (target_type == TypeManager.decimal_type)
- return new DecimalConstant ((decimal) v);
- }
- if (expr is ShortConstant){
- short v = ((ShortConstant) expr).Value;
-
- if (target_type == TypeManager.byte_type) {
- if (!CheckRange (ec, v, target_type, Byte.MinValue, Byte.MaxValue))
- return null;
- return new ByteConstant ((byte) v);
- }
- if (target_type == TypeManager.sbyte_type) {
- if (!CheckRange (ec, v, target_type, SByte.MinValue, SByte.MaxValue))
- return null;
- return new SByteConstant ((sbyte) v);
- }
- if (target_type == TypeManager.ushort_type) {
- if (!CheckUnsigned (ec, v, target_type))
- return null;
- return new UShortConstant ((ushort) v);
- }
- if (target_type == TypeManager.int32_type)
- return new IntConstant ((int) v);
- if (target_type == TypeManager.uint32_type) {
- if (!CheckUnsigned (ec, v, target_type))
- return null;
- return new UIntConstant ((uint) v);
- }
- if (target_type == TypeManager.int64_type)
- return new LongConstant ((long) v);
- if (target_type == TypeManager.uint64_type) {
- if (!CheckUnsigned (ec, v, target_type))
- return null;
- return new ULongConstant ((ulong) v);
- }
- if (target_type == TypeManager.float_type)
- return new FloatConstant ((float) v);
- if (target_type == TypeManager.double_type)
- return new DoubleConstant ((double) v);
- if (target_type == TypeManager.char_type) {
- if (!CheckRange (ec, v, target_type, Char.MinValue, Char.MaxValue))
- return null;
- return new CharConstant ((char) v);
- }
- if (target_type == TypeManager.decimal_type)
- return new DecimalConstant ((decimal) v);
- }
- if (expr is UShortConstant){
- ushort v = ((UShortConstant) expr).Value;
-
- if (target_type == TypeManager.byte_type) {
- if (!CheckRange (ec, v, target_type, Byte.MinValue, Byte.MaxValue))
- return null;
- return new ByteConstant ((byte) v);
- }
- if (target_type == TypeManager.sbyte_type) {
- if (!CheckRange (ec, v, target_type, SByte.MinValue, SByte.MaxValue))
- return null;
- return new SByteConstant ((sbyte) v);
- }
- if (target_type == TypeManager.short_type) {
- if (!CheckRange (ec, v, target_type, Int16.MinValue, Int16.MaxValue))
- return null;
- return new ShortConstant ((short) v);
- }
- if (target_type == TypeManager.int32_type)
- return new IntConstant ((int) v);
- if (target_type == TypeManager.uint32_type)
- return new UIntConstant ((uint) v);
- if (target_type == TypeManager.int64_type)
- return new LongConstant ((long) v);
- if (target_type == TypeManager.uint64_type)
- return new ULongConstant ((ulong) v);
- if (target_type == TypeManager.float_type)
- return new FloatConstant ((float) v);
- if (target_type == TypeManager.double_type)
- return new DoubleConstant ((double) v);
- if (target_type == TypeManager.char_type) {
- if (!CheckRange (ec, v, target_type, Char.MinValue, Char.MaxValue))
- return null;
- return new CharConstant ((char) v);
- }
- if (target_type == TypeManager.decimal_type)
- return new DecimalConstant ((decimal) v);
- }
- if (expr is IntConstant){
- int v = ((IntConstant) expr).Value;
-
- if (target_type == TypeManager.byte_type) {
- if (!CheckRange (ec, v, target_type, Byte.MinValue, Byte.MaxValue))
- return null;
- return new ByteConstant ((byte) v);
- }
- if (target_type == TypeManager.sbyte_type) {
- if (!CheckRange (ec, v, target_type, SByte.MinValue, SByte.MaxValue))
- return null;
- return new SByteConstant ((sbyte) v);
- }
- if (target_type == TypeManager.short_type) {
- if (!CheckRange (ec, v, target_type, Int16.MinValue, Int16.MaxValue))
- return null;
- return new ShortConstant ((short) v);
- }
- if (target_type == TypeManager.ushort_type) {
- if (!CheckRange (ec, v, target_type, UInt16.MinValue, UInt16.MaxValue))
- return null;
- return new UShortConstant ((ushort) v);
- }
- if (target_type == TypeManager.uint32_type) {
- if (!CheckRange (ec, v, target_type, Int32.MinValue, Int32.MaxValue))
- return null;
- return new UIntConstant ((uint) v);
- }
- if (target_type == TypeManager.int64_type)
- return new LongConstant ((long) v);
- if (target_type == TypeManager.uint64_type) {
- if (!CheckUnsigned (ec, v, target_type))
- return null;
- return new ULongConstant ((ulong) v);
- }
- if (target_type == TypeManager.float_type)
- return new FloatConstant ((float) v);
- if (target_type == TypeManager.double_type)
- return new DoubleConstant ((double) v);
- if (target_type == TypeManager.char_type) {
- if (!CheckRange (ec, v, target_type, Char.MinValue, Char.MaxValue))
- return null;
- return new CharConstant ((char) v);
- }
- if (target_type == TypeManager.decimal_type)
- return new DecimalConstant ((decimal) v);
- }
- if (expr is UIntConstant){
- uint v = ((UIntConstant) expr).Value;
-
- if (target_type == TypeManager.byte_type) {
- if (!CheckRange (ec, v, target_type, Char.MinValue, Char.MaxValue))
- return null;
- return new ByteConstant ((byte) v);
- }
- if (target_type == TypeManager.sbyte_type) {
- if (!CheckRange (ec, v, target_type, SByte.MinValue, SByte.MaxValue))
- return null;
- return new SByteConstant ((sbyte) v);
- }
- if (target_type == TypeManager.short_type) {
- if (!CheckRange (ec, v, target_type, Int16.MinValue, Int16.MaxValue))
- return null;
- return new ShortConstant ((short) v);
- }
- if (target_type == TypeManager.ushort_type) {
- if (!CheckRange (ec, v, target_type, UInt16.MinValue, UInt16.MaxValue))
- return null;
- return new UShortConstant ((ushort) v);
- }
- if (target_type == TypeManager.int32_type) {
- if (!CheckRange (ec, v, target_type, Int32.MinValue, Int32.MaxValue))
- return null;
- return new IntConstant ((int) v);
- }
- if (target_type == TypeManager.int64_type)
- return new LongConstant ((long) v);
- if (target_type == TypeManager.uint64_type)
- return new ULongConstant ((ulong) v);
- if (target_type == TypeManager.float_type)
- return new FloatConstant ((float) v);
- if (target_type == TypeManager.double_type)
- return new DoubleConstant ((double) v);
- if (target_type == TypeManager.char_type) {
- if (!CheckRange (ec, v, target_type, Char.MinValue, Char.MaxValue))
- return null;
- return new CharConstant ((char) v);
- }
- if (target_type == TypeManager.decimal_type)
- return new DecimalConstant ((decimal) v);
- }
- if (expr is LongConstant){
- long v = ((LongConstant) expr).Value;
-
- if (target_type == TypeManager.byte_type) {
- if (!CheckRange (ec, v, target_type, Byte.MinValue, Byte.MaxValue))
- return null;
- return new ByteConstant ((byte) v);
- }
- if (target_type == TypeManager.sbyte_type) {
- if (!CheckRange (ec, v, target_type, SByte.MinValue, SByte.MaxValue))
- return null;
- return new SByteConstant ((sbyte) v);
- }
- if (target_type == TypeManager.short_type) {
- if (!CheckRange (ec, v, target_type, Int16.MinValue, Int16.MaxValue))
- return null;
- return new ShortConstant ((short) v);
- }
- if (target_type == TypeManager.ushort_type) {
- if (!CheckRange (ec, v, target_type, UInt16.MinValue, UInt16.MaxValue))
- return null;
- return new UShortConstant ((ushort) v);
- }
- if (target_type == TypeManager.int32_type) {
- if (!CheckRange (ec, v, target_type, Int32.MinValue, Int32.MaxValue))
- return null;
- return new IntConstant ((int) v);
- }
- if (target_type == TypeManager.uint32_type) {
- if (!CheckRange (ec, v, target_type, UInt32.MinValue, UInt32.MaxValue))
- return null;
- return new UIntConstant ((uint) v);
- }
- if (target_type == TypeManager.uint64_type) {
- if (!CheckUnsigned (ec, v, target_type))
- return null;
- return new ULongConstant ((ulong) v);
- }
- if (target_type == TypeManager.float_type)
- return new FloatConstant ((float) v);
- if (target_type == TypeManager.double_type)
- return new DoubleConstant ((double) v);
- if (target_type == TypeManager.char_type) {
- if (!CheckRange (ec, v, target_type, Char.MinValue, Char.MaxValue))
- return null;
- return new CharConstant ((char) v);
- }
- if (target_type == TypeManager.decimal_type)
- return new DecimalConstant ((decimal) v);
- }
- if (expr is ULongConstant){
- ulong v = ((ULongConstant) expr).Value;
-
- if (target_type == TypeManager.byte_type) {
- if (!CheckRange (ec, v, target_type, Byte.MaxValue))
- return null;
- return new ByteConstant ((byte) v);
- }
- if (target_type == TypeManager.sbyte_type) {
- if (!CheckRange (ec, v, target_type, (ulong) SByte.MaxValue))
- return null;
- return new SByteConstant ((sbyte) v);
- }
- if (target_type == TypeManager.short_type) {
- if (!CheckRange (ec, v, target_type, (ulong) Int16.MaxValue))
- return null;
- return new ShortConstant ((short) v);
- }
- if (target_type == TypeManager.ushort_type) {
- if (!CheckRange (ec, v, target_type, UInt16.MaxValue))
- return null;
- return new UShortConstant ((ushort) v);
- }
- if (target_type == TypeManager.int32_type) {
- if (!CheckRange (ec, v, target_type, Int32.MaxValue))
- return null;
- return new IntConstant ((int) v);
- }
- if (target_type == TypeManager.uint32_type) {
- if (!CheckRange (ec, v, target_type, UInt32.MaxValue))
- return null;
- return new UIntConstant ((uint) v);
- }
- if (target_type == TypeManager.int64_type) {
- if (!CheckRange (ec, v, target_type, (ulong) Int64.MaxValue))
- return null;
- return new LongConstant ((long) v);
- }
- if (target_type == TypeManager.float_type)
- return new FloatConstant ((float) v);
- if (target_type == TypeManager.double_type)
- return new DoubleConstant ((double) v);
- if (target_type == TypeManager.char_type) {
- if (!CheckRange (ec, v, target_type, Char.MaxValue))
- return null;
- return new CharConstant ((char) v);
- }
- if (target_type == TypeManager.decimal_type)
- return new DecimalConstant ((decimal) v);
- }
- if (expr is FloatConstant){
- float v = ((FloatConstant) expr).Value;
-
- if (target_type == TypeManager.byte_type)
- return new ByteConstant ((byte) v);
- if (target_type == TypeManager.sbyte_type)
- return new SByteConstant ((sbyte) v);
- if (target_type == TypeManager.short_type)
- return new ShortConstant ((short) v);
- if (target_type == TypeManager.ushort_type)
- return new UShortConstant ((ushort) v);
- if (target_type == TypeManager.int32_type)
- return new IntConstant ((int) v);
- if (target_type == TypeManager.uint32_type)
- return new UIntConstant ((uint) v);
- if (target_type == TypeManager.int64_type)
- return new LongConstant ((long) v);
- if (target_type == TypeManager.uint64_type)
- return new ULongConstant ((ulong) v);
- if (target_type == TypeManager.double_type)
- return new DoubleConstant ((double) v);
- if (target_type == TypeManager.char_type)
- return new CharConstant ((char) v);
- if (target_type == TypeManager.decimal_type)
- return new DecimalConstant ((decimal) v);
- }
- if (expr is DoubleConstant){
- double v = ((DoubleConstant) expr).Value;
-
- if (target_type == TypeManager.byte_type)
- return new ByteConstant ((byte) v);
- if (target_type == TypeManager.sbyte_type)
- return new SByteConstant ((sbyte) v);
- if (target_type == TypeManager.short_type)
- return new ShortConstant ((short) v);
- if (target_type == TypeManager.ushort_type)
- return new UShortConstant ((ushort) v);
- if (target_type == TypeManager.int32_type)
- return new IntConstant ((int) v);
- if (target_type == TypeManager.uint32_type)
- return new UIntConstant ((uint) v);
- if (target_type == TypeManager.int64_type)
- return new LongConstant ((long) v);
- if (target_type == TypeManager.uint64_type)
- return new ULongConstant ((ulong) v);
- if (target_type == TypeManager.float_type)
- return new FloatConstant ((float) v);
- if (target_type == TypeManager.char_type)
- return new CharConstant ((char) v);
- if (target_type == TypeManager.decimal_type)
- return new DecimalConstant ((decimal) v);
- }
-
- return null;
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- expr = expr.Resolve (ec);
- if (expr == null)
- return null;
-
- int errors = Report.Errors;
-
- type = ec.DeclSpace.ResolveType (target_type, false, Location);
-
- if (type == null)
- return null;
-
- eclass = ExprClass.Value;
-
- if (expr is Constant){
- Expression e = TryReduce (ec, type);
-
- if (e != null)
- return e;
- }
-
- expr = ConvertExplicit (ec, expr, type, loc);
- return expr;
- }
-
- public override void Emit (EmitContext ec)
- {
- //
- // This one will never happen
- //
- throw new Exception ("Should not happen");
- }
- }
-
- /// <summary>
- /// Binary operators
- /// </summary>
- public class Binary : Expression {
- public enum Operator : byte {
- Multiply, Division, Modulus,
- Addition, Subtraction,
- LeftShift, RightShift,
- LessThan, GreaterThan, LessThanOrEqual, GreaterThanOrEqual,
- Equality, Inequality,
- BitwiseAnd,
- ExclusiveOr,
- BitwiseOr,
- LogicalAnd,
- LogicalOr,
- TOP
- }
-
- Operator oper;
- Expression left, right;
-
- //
- // After resolution, method might contain the operator overload
- // method.
- //
- protected MethodBase method;
- ArrayList Arguments;
-
- bool DelegateOperation;
-
- // This must be kept in sync with Operator!!!
- static string [] oper_names;
-
- static Binary ()
- {
- oper_names = new string [(int) Operator.TOP];
-
- oper_names [(int) Operator.Multiply] = "op_Multiply";
- oper_names [(int) Operator.Division] = "op_Division";
- oper_names [(int) Operator.Modulus] = "op_Modulus";
- oper_names [(int) Operator.Addition] = "op_Addition";
- oper_names [(int) Operator.Subtraction] = "op_Subtraction";
- oper_names [(int) Operator.LeftShift] = "op_LeftShift";
- oper_names [(int) Operator.RightShift] = "op_RightShift";
- oper_names [(int) Operator.LessThan] = "op_LessThan";
- oper_names [(int) Operator.GreaterThan] = "op_GreaterThan";
- oper_names [(int) Operator.LessThanOrEqual] = "op_LessThanOrEqual";
- oper_names [(int) Operator.GreaterThanOrEqual] = "op_GreaterThanOrEqual";
- oper_names [(int) Operator.Equality] = "op_Equality";
- oper_names [(int) Operator.Inequality] = "op_Inequality";
- oper_names [(int) Operator.BitwiseAnd] = "op_BitwiseAnd";
- oper_names [(int) Operator.BitwiseOr] = "op_BitwiseOr";
- oper_names [(int) Operator.ExclusiveOr] = "op_ExclusiveOr";
- oper_names [(int) Operator.LogicalOr] = "op_LogicalOr";
- oper_names [(int) Operator.LogicalAnd] = "op_LogicalAnd";
- }
-
- public Binary (Operator oper, Expression left, Expression right, Location loc)
- {
- this.oper = oper;
- this.left = left;
- this.right = right;
- this.loc = loc;
- }
-
- public Operator Oper {
- get {
- return oper;
- }
- set {
- oper = value;
- }
- }
-
- public Expression Left {
- get {
- return left;
- }
- set {
- left = value;
- }
- }
-
- public Expression Right {
- get {
- return right;
- }
- set {
- right = value;
- }
- }
-
-
- /// <summary>
- /// Returns a stringified representation of the Operator
- /// </summary>
- static string OperName (Operator oper)
- {
- switch (oper){
- case Operator.Multiply:
- return "*";
- case Operator.Division:
- return "/";
- case Operator.Modulus:
- return "%";
- case Operator.Addition:
- return "+";
- case Operator.Subtraction:
- return "-";
- case Operator.LeftShift:
- return "<<";
- case Operator.RightShift:
- return ">>";
- case Operator.LessThan:
- return "<";
- case Operator.GreaterThan:
- return ">";
- case Operator.LessThanOrEqual:
- return "<=";
- case Operator.GreaterThanOrEqual:
- return ">=";
- case Operator.Equality:
- return "==";
- case Operator.Inequality:
- return "!=";
- case Operator.BitwiseAnd:
- return "&";
- case Operator.BitwiseOr:
- return "|";
- case Operator.ExclusiveOr:
- return "^";
- case Operator.LogicalOr:
- return "||";
- case Operator.LogicalAnd:
- return "&&";
- }
-
- return oper.ToString ();
- }
-
- public override string ToString ()
- {
- return "operator " + OperName (oper) + "(" + left.ToString () + ", " +
- right.ToString () + ")";
- }
-
- Expression ForceConversion (EmitContext ec, Expression expr, Type target_type)
- {
- if (expr.Type == target_type)
- return expr;
-
- return ConvertImplicit (ec, expr, target_type, loc);
- }
-
- public static void Error_OperatorAmbiguous (Location loc, Operator oper, Type l, Type r)
- {
- Report.Error (
- 34, loc, "Operator `" + OperName (oper)
- + "' is ambiguous on operands of type `"
- + TypeManager.CSharpName (l) + "' "
- + "and `" + TypeManager.CSharpName (r)
- + "'");
- }
-
- bool IsOfType (EmitContext ec, Type l, Type r, Type t, bool check_user_conversions)
- {
- if ((l == t) || (r == t))
- return true;
-
- if (!check_user_conversions)
- return false;
-
- if (ImplicitUserConversionExists (ec, l, t))
- return true;
- else if (ImplicitUserConversionExists (ec, r, t))
- return true;
- else
- return false;
- }
-
- //
- // Note that handling the case l == Decimal || r == Decimal
- // is taken care of by the Step 1 Operator Overload resolution.
- //
- // If `check_user_conv' is true, we also check whether a user-defined conversion
- // exists. Note that we only need to do this if both arguments are of a user-defined
- // type, otherwise ConvertImplict() already finds the user-defined conversion for us,
- // so we don't explicitly check for performance reasons.
- //
- bool DoNumericPromotions (EmitContext ec, Type l, Type r, bool check_user_conv)
- {
- if (IsOfType (ec, l, r, TypeManager.double_type, check_user_conv)){
- //
- // If either operand is of type double, the other operand is
- // conveted to type double.
- //
- if (r != TypeManager.double_type)
- right = ConvertImplicit (ec, right, TypeManager.double_type, loc);
- if (l != TypeManager.double_type)
- left = ConvertImplicit (ec, left, TypeManager.double_type, loc);
-
- type = TypeManager.double_type;
- } else if (IsOfType (ec, l, r, TypeManager.float_type, check_user_conv)){
- //
- // if either operand is of type float, the other operand is
- // converted to type float.
- //
- if (r != TypeManager.double_type)
- right = ConvertImplicit (ec, right, TypeManager.float_type, loc);
- if (l != TypeManager.double_type)
- left = ConvertImplicit (ec, left, TypeManager.float_type, loc);
- type = TypeManager.float_type;
- } else if (IsOfType (ec, l, r, TypeManager.uint64_type, check_user_conv)){
- Expression e;
- Type other;
- //
- // If either operand is of type ulong, the other operand is
- // converted to type ulong. or an error ocurrs if the other
- // operand is of type sbyte, short, int or long
- //
- if (l == TypeManager.uint64_type){
- if (r != TypeManager.uint64_type){
- if (right is IntConstant){
- IntConstant ic = (IntConstant) right;
-
- e = TryImplicitIntConversion (l, ic);
- if (e != null)
- right = e;
- } else if (right is LongConstant){
- long ll = ((LongConstant) right).Value;
-
- if (ll > 0)
- right = new ULongConstant ((ulong) ll);
- } else {
- e = ImplicitNumericConversion (ec, right, l, loc);
- if (e != null)
- right = e;
- }
- }
- other = right.Type;
- } else {
- if (left is IntConstant){
- e = TryImplicitIntConversion (r, (IntConstant) left);
- if (e != null)
- left = e;
- } else if (left is LongConstant){
- long ll = ((LongConstant) left).Value;
-
- if (ll > 0)
- left = new ULongConstant ((ulong) ll);
- } else {
- e = ImplicitNumericConversion (ec, left, r, loc);
- if (e != null)
- left = e;
- }
- other = left.Type;
- }
-
- if ((other == TypeManager.sbyte_type) ||
- (other == TypeManager.short_type) ||
- (other == TypeManager.int32_type) ||
- (other == TypeManager.int64_type))
- Error_OperatorAmbiguous (loc, oper, l, r);
- type = TypeManager.uint64_type;
- } else if (IsOfType (ec, l, r, TypeManager.int64_type, check_user_conv)){
- //
- // If either operand is of type long, the other operand is converted
- // to type long.
- //
- if (l != TypeManager.int64_type)
- left = ConvertImplicit (ec, left, TypeManager.int64_type, loc);
- if (r != TypeManager.int64_type)
- right = ConvertImplicit (ec, right, TypeManager.int64_type, loc);
-
- type = TypeManager.int64_type;
- } else if (IsOfType (ec, l, r, TypeManager.uint32_type, check_user_conv)){
- //
- // If either operand is of type uint, and the other
- // operand is of type sbyte, short or int, othe operands are
- // converted to type long.
- //
- Type other = null;
-
- if (l == TypeManager.uint32_type){
- if (right is IntConstant){
- IntConstant ic = (IntConstant) right;
- int val = ic.Value;
-
- if (val >= 0)
- right = new UIntConstant ((uint) val);
-
- type = l;
- return true;
- }
- other = r;
- }
- else if (r == TypeManager.uint32_type){
- if (left is IntConstant){
- IntConstant ic = (IntConstant) left;
- int val = ic.Value;
-
- if (val >= 0)
- left = new UIntConstant ((uint) val);
-
- type = r;
- return true;
- }
-
- other = l;
- }
-
- if ((other == TypeManager.sbyte_type) ||
- (other == TypeManager.short_type) ||
- (other == TypeManager.int32_type)){
- left = ForceConversion (ec, left, TypeManager.int64_type);
- right = ForceConversion (ec, right, TypeManager.int64_type);
- type = TypeManager.int64_type;
- } else {
- //
- // if either operand is of type uint, the other
- // operand is converd to type uint
- //
- left = ForceConversion (ec, left, TypeManager.uint32_type);
- right = ForceConversion (ec, right, TypeManager.uint32_type);
- type = TypeManager.uint32_type;
- }
- } else if (l == TypeManager.decimal_type || r == TypeManager.decimal_type){
- if (l != TypeManager.decimal_type)
- left = ConvertImplicit (ec, left, TypeManager.decimal_type, loc);
-
- if (r != TypeManager.decimal_type)
- right = ConvertImplicit (ec, right, TypeManager.decimal_type, loc);
- type = TypeManager.decimal_type;
- } else {
- left = ForceConversion (ec, left, TypeManager.int32_type);
- right = ForceConversion (ec, right, TypeManager.int32_type);
-
- type = TypeManager.int32_type;
- }
-
- return (left != null) && (right != null);
- }
-
- static public void Error_OperatorCannotBeApplied (Location loc, string name, Type l, Type r)
- {
- Report.Error (19, loc,
- "Operator " + name + " cannot be applied to operands of type `" +
- TypeManager.CSharpName (l) + "' and `" +
- TypeManager.CSharpName (r) + "'");
- }
-
- void Error_OperatorCannotBeApplied ()
- {
- Error_OperatorCannotBeApplied (loc, OperName (oper), left.Type, right.Type);
- }
-
- static bool is_32_or_64 (Type t)
- {
- return (t == TypeManager.int32_type || t == TypeManager.uint32_type ||
- t == TypeManager.int64_type || t == TypeManager.uint64_type);
- }
-
- static bool is_unsigned (Type t)
- {
- return (t == TypeManager.uint32_type || t == TypeManager.uint64_type ||
- t == TypeManager.short_type || t == TypeManager.byte_type);
- }
-
- static bool is_user_defined (Type t)
- {
- if (t.IsSubclassOf (TypeManager.value_type) &&
- (!TypeManager.IsBuiltinType (t) || t == TypeManager.decimal_type))
- return true;
- else
- return false;
- }
-
- Expression CheckShiftArguments (EmitContext ec)
- {
- Expression e;
- Type l = left.Type;
- Type r = right.Type;
-
- e = ForceConversion (ec, right, TypeManager.int32_type);
- if (e == null){
- Error_OperatorCannotBeApplied ();
- return null;
- }
- right = e;
-
- if (((e = ConvertImplicit (ec, left, TypeManager.int32_type, loc)) != null) ||
- ((e = ConvertImplicit (ec, left, TypeManager.uint32_type, loc)) != null) ||
- ((e = ConvertImplicit (ec, left, TypeManager.int64_type, loc)) != null) ||
- ((e = ConvertImplicit (ec, left, TypeManager.uint64_type, loc)) != null)){
- left = e;
- type = e.Type;
-
- return this;
- }
- Error_OperatorCannotBeApplied ();
- return null;
- }
-
- Expression ResolveOperator (EmitContext ec)
- {
- Type l = left.Type;
- Type r = right.Type;
-
- bool overload_failed = false;
-
- //
- // Special cases: string comapred to null
- //
- if (oper == Operator.Equality || oper == Operator.Inequality){
- if ((l == TypeManager.string_type && (right is NullLiteral)) ||
- (r == TypeManager.string_type && (left is NullLiteral))){
- Type = TypeManager.bool_type;
-
- return this;
- }
- }
-
- //
- // Do not perform operator overload resolution when both sides are
- // built-in types
- //
- if (!(TypeManager.IsCLRType (l) && TypeManager.IsCLRType (r))){
- //
- // Step 1: Perform Operator Overload location
- //
- Expression left_expr, right_expr;
-
- string op = oper_names [(int) oper];
-
- MethodGroupExpr union;
- left_expr = MemberLookup (ec, l, op, MemberTypes.Method, AllBindingFlags, loc);
- if (r != l){
- right_expr = MemberLookup (
- ec, r, op, MemberTypes.Method, AllBindingFlags, loc);
- union = Invocation.MakeUnionSet (left_expr, right_expr, loc);
- } else
- union = (MethodGroupExpr) left_expr;
-
- if (union != null) {
- Arguments = new ArrayList ();
- Arguments.Add (new Argument (left, Argument.AType.Expression));
- Arguments.Add (new Argument (right, Argument.AType.Expression));
-
- method = Invocation.OverloadResolve (ec, union, Arguments, Location.Null);
- if (method != null) {
- MethodInfo mi = (MethodInfo) method;
-
- type = mi.ReturnType;
- return this;
- } else {
- overload_failed = true;
- }
- }
- }
-
- //
- // Step 2: Default operations on CLI native types.
- //
-
- //
- // Step 0: String concatenation (because overloading will get this wrong)
- //
- if (oper == Operator.Addition){
- //
- // If any of the arguments is a string, cast to string
- //
-
- if (l == TypeManager.string_type){
-
- if (r == TypeManager.void_type) {
- Error_OperatorCannotBeApplied ();
- return null;
- }
-
- if (r == TypeManager.string_type){
- if (left is Constant && right is Constant){
- StringConstant ls = (StringConstant) left;
- StringConstant rs = (StringConstant) right;
-
- return new StringConstant (
- ls.Value + rs.Value);
- }
-
- if (left is Binary){
- Binary b = (Binary) left;
-
- //
- // Call String.Concat (string, string, string) or
- // String.Concat (string, string, string, string)
- // if possible.
- //
- if (b.oper == Operator.Addition &&
- (b.method == TypeManager.string_concat_string_string_string ||
- b.method == TypeManager.string_concat_string_string_string_string)){
- ArrayList bargs = b.Arguments;
- int count = bargs.Count;
-
- if (count == 2){
- Arguments = bargs;
- Arguments.Add (new Argument (right, Argument.AType.Expression));
- type = TypeManager.string_type;
- method = TypeManager.string_concat_string_string_string;
-
- return this;
- } else if (count == 3){
- Arguments = bargs;
- Arguments.Add (new Argument (right, Argument.AType.Expression));
- type = TypeManager.string_type;
- method = TypeManager.string_concat_string_string_string_string;
- return this;
- }
- }
- }
-
- // string + string
- method = TypeManager.string_concat_string_string;
- } else {
- // string + object
- method = TypeManager.string_concat_object_object;
- right = ConvertImplicit (ec, right,
- TypeManager.object_type, loc);
- if (right == null){
- Error_OperatorCannotBeApplied (loc, OperName (oper), l, r);
- return null;
- }
- }
- type = TypeManager.string_type;
-
- Arguments = new ArrayList ();
- Arguments.Add (new Argument (left, Argument.AType.Expression));
- Arguments.Add (new Argument (right, Argument.AType.Expression));
-
- return this;
-
- } else if (r == TypeManager.string_type){
- // object + string
-
- if (l == TypeManager.void_type) {
- Error_OperatorCannotBeApplied ();
- return null;
- }
-
- method = TypeManager.string_concat_object_object;
- left = ConvertImplicit (ec, left, TypeManager.object_type, loc);
- if (left == null){
- Error_OperatorCannotBeApplied (loc, OperName (oper), l, r);
- return null;
- }
- Arguments = new ArrayList ();
- Arguments.Add (new Argument (left, Argument.AType.Expression));
- Arguments.Add (new Argument (right, Argument.AType.Expression));
-
- type = TypeManager.string_type;
-
- return this;
- }
-
- //
- // Transform a + ( - b) into a - b
- //
- if (right is Unary){
- Unary right_unary = (Unary) right;
-
- if (right_unary.Oper == Unary.Operator.UnaryNegation){
- oper = Operator.Subtraction;
- right = right_unary.Expr;
- r = right.Type;
- }
- }
- }
-
- if (oper == Operator.Equality || oper == Operator.Inequality){
- if (l == TypeManager.bool_type || r == TypeManager.bool_type){
- if (r != TypeManager.bool_type || l != TypeManager.bool_type){
- Error_OperatorCannotBeApplied ();
- return null;
- }
-
- type = TypeManager.bool_type;
- return this;
- }
-
- //
- // operator != (object a, object b)
- // operator == (object a, object b)
- //
- // For this to be used, both arguments have to be reference-types.
- // Read the rationale on the spec (14.9.6)
- //
- // Also, if at compile time we know that the classes do not inherit
- // one from the other, then we catch the error there.
- //
- if (!(l.IsValueType || r.IsValueType)){
- type = TypeManager.bool_type;
-
- if (l == r)
- return this;
-
- if (l.IsSubclassOf (r) || r.IsSubclassOf (l))
- return this;
-
- //
- // Also, a standard conversion must exist from either one
- //
- if (!(StandardConversionExists (left, r) ||
- StandardConversionExists (right, l))){
- Error_OperatorCannotBeApplied ();
- return null;
- }
- //
- // We are going to have to convert to an object to compare
- //
- if (l != TypeManager.object_type)
- left = new EmptyCast (left, TypeManager.object_type);
- if (r != TypeManager.object_type)
- right = new EmptyCast (right, TypeManager.object_type);
-
- //
- // FIXME: CSC here catches errors cs254 and cs252
- //
- return this;
- }
-
- //
- // One of them is a valuetype, but the other one is not.
- //
- if (!l.IsValueType || !r.IsValueType) {
- Error_OperatorCannotBeApplied ();
- return null;
- }
- }
-
- // Only perform numeric promotions on:
- // +, -, *, /, %, &, |, ^, ==, !=, <, >, <=, >=
- //
- if (oper == Operator.Addition || oper == Operator.Subtraction) {
- if (l.IsSubclassOf (TypeManager.delegate_type) &&
- r.IsSubclassOf (TypeManager.delegate_type)) {
-
- Arguments = new ArrayList ();
- Arguments.Add (new Argument (left, Argument.AType.Expression));
- Arguments.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;
- }
-
- DelegateOperation = true;
- type = l;
- return this;
- }
-
- //
- // Pointer arithmetic:
- //
- // T* operator + (T* x, int y);
- // T* operator + (T* x, uint y);
- // T* operator + (T* x, long y);
- // T* operator + (T* x, ulong y);
- //
- // T* operator + (int y, T* x);
- // T* operator + (uint y, T *x);
- // T* operator + (long y, T *x);
- // T* operator + (ulong y, T *x);
- //
- // T* operator - (T* x, int y);
- // T* operator - (T* x, uint y);
- // T* operator - (T* x, long y);
- // T* operator - (T* x, ulong y);
- //
- // long operator - (T* x, T *y)
- //
- if (l.IsPointer){
- if (r.IsPointer && oper == Operator.Subtraction){
- if (r == l)
- return new PointerArithmetic (
- false, left, right, TypeManager.int64_type,
- loc);
- } else if (is_32_or_64 (r))
- return new PointerArithmetic (
- oper == Operator.Addition, left, right, l, loc);
- } else if (r.IsPointer && is_32_or_64 (l) && oper == Operator.Addition)
- return new PointerArithmetic (
- true, right, left, r, loc);
- }
-
- //
- // Enumeration operators
- //
- bool lie = TypeManager.IsEnumType (l);
- bool rie = TypeManager.IsEnumType (r);
- if (lie || rie){
- Expression temp;
-
- // U operator - (E e, E f)
- if (lie && rie && oper == Operator.Subtraction){
- if (l == r){
- type = TypeManager.EnumToUnderlying (l);
- return this;
- }
- Error_OperatorCannotBeApplied ();
- return null;
- }
-
- //
- // operator + (E e, U x)
- // operator - (E e, U x)
- //
- if (oper == Operator.Addition || oper == Operator.Subtraction){
- Type enum_type = lie ? l : r;
- Type other_type = lie ? r : l;
- Type underlying_type = TypeManager.EnumToUnderlying (enum_type);
-;
-
- if (underlying_type != other_type){
- Error_OperatorCannotBeApplied ();
- return null;
- }
-
- type = enum_type;
- return this;
- }
-
- if (!rie){
- temp = ConvertImplicit (ec, right, l, loc);
- if (temp != null)
- right = temp;
- else {
- Error_OperatorCannotBeApplied ();
- return null;
- }
- } if (!lie){
- temp = ConvertImplicit (ec, left, r, loc);
- if (temp != null){
- left = temp;
- l = r;
- } else {
- Error_OperatorCannotBeApplied ();
- return null;
- }
- }
-
- if (oper == Operator.Equality || oper == Operator.Inequality ||
- oper == Operator.LessThanOrEqual || oper == Operator.LessThan ||
- oper == Operator.GreaterThanOrEqual || oper == Operator.GreaterThan){
- type = TypeManager.bool_type;
- return this;
- }
-
- if (oper == Operator.BitwiseAnd ||
- oper == Operator.BitwiseOr ||
- oper == Operator.ExclusiveOr){
- type = l;
- return this;
- }
- Error_OperatorCannotBeApplied ();
- return null;
- }
-
- if (oper == Operator.LeftShift || oper == Operator.RightShift)
- return CheckShiftArguments (ec);
-
- if (oper == Operator.LogicalOr || oper == Operator.LogicalAnd){
- if (l != TypeManager.bool_type || r != TypeManager.bool_type){
- Error_OperatorCannotBeApplied ();
- return null;
- }
-
- type = TypeManager.bool_type;
- return this;
- }
-
- //
- // operator & (bool x, bool y)
- // operator | (bool x, bool y)
- // operator ^ (bool x, bool y)
- //
- if (l == TypeManager.bool_type && r == TypeManager.bool_type){
- if (oper == Operator.BitwiseAnd ||
- oper == Operator.BitwiseOr ||
- oper == Operator.ExclusiveOr){
- type = l;
- return this;
- }
- }
-
- //
- // Pointer comparison
- //
- if (l.IsPointer && r.IsPointer){
- if (oper == Operator.Equality || oper == Operator.Inequality ||
- oper == Operator.LessThan || oper == Operator.LessThanOrEqual ||
- oper == Operator.GreaterThan || oper == Operator.GreaterThanOrEqual){
- type = TypeManager.bool_type;
- return this;
- }
- }
-
- //
- // We are dealing with numbers
- //
- if (overload_failed){
- Error_OperatorCannotBeApplied ();
- return null;
- }
-
- //
- // This will leave left or right set to null if there is an error
- //
- bool check_user_conv = is_user_defined (l) && is_user_defined (r);
- DoNumericPromotions (ec, l, r, check_user_conv);
- if (left == null || right == null){
- Error_OperatorCannotBeApplied (loc, OperName (oper), l, r);
- return null;
- }
-
- //
- // reload our cached types if required
- //
- l = left.Type;
- r = right.Type;
-
- if (oper == Operator.BitwiseAnd ||
- oper == Operator.BitwiseOr ||
- oper == Operator.ExclusiveOr){
- if (l == r){
- if (!((l == TypeManager.int32_type) ||
- (l == TypeManager.uint32_type) ||
- (l == TypeManager.int64_type) ||
- (l == TypeManager.uint64_type)))
- type = l;
- } else {
- Error_OperatorCannotBeApplied ();
- return null;
- }
- }
-
- if (oper == Operator.Equality ||
- oper == Operator.Inequality ||
- oper == Operator.LessThanOrEqual ||
- oper == Operator.LessThan ||
- oper == Operator.GreaterThanOrEqual ||
- oper == Operator.GreaterThan){
- type = TypeManager.bool_type;
- }
-
- return this;
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- left = left.Resolve (ec);
- right = right.Resolve (ec);
-
- if (left == null || right == null)
- return null;
-
- eclass = ExprClass.Value;
-
- Constant rc = right as Constant;
- Constant lc = left as Constant;
-
- if (rc != null & lc != null){
- Expression e = ConstantFold.BinaryFold (
- ec, oper, lc, rc, loc);
- if (e != null)
- return e;
- }
-
- return ResolveOperator (ec);
- }
-
- /// <remarks>
- /// EmitBranchable is called from Statement.EmitBoolExpression in the
- /// context of a conditional bool expression. This function will return
- /// false if it is was possible to use EmitBranchable, or true if it was.
- ///
- /// The expression's code is generated, and we will generate a branch to `target'
- /// if the resulting expression value is equal to isTrue
- /// </remarks>
- public bool EmitBranchable (EmitContext ec, Label target, bool onTrue)
- {
- if (method != null)
- return false;
-
- ILGenerator ig = ec.ig;
-
- //
- // This is more complicated than it looks, but its just to avoid
- // duplicated tests: basically, we allow ==, !=, >, <, >= and <=
- // but on top of that we want for == and != to use a special path
- // if we are comparing against null
- //
- if (oper == Operator.Equality || oper == Operator.Inequality){
- bool my_on_true = oper == Operator.Inequality ? onTrue : !onTrue;
-
- if (left is NullLiteral){
- right.Emit (ec);
- if (my_on_true)
- ig.Emit (OpCodes.Brtrue, target);
- else
- ig.Emit (OpCodes.Brfalse, target);
- return true;
- } else if (right is NullLiteral){
- left.Emit (ec);
- if (my_on_true)
- ig.Emit (OpCodes.Brtrue, target);
- else
- ig.Emit (OpCodes.Brfalse, target);
- return true;
- } else if (left is BoolConstant){
- right.Emit (ec);
- if (my_on_true != ((BoolConstant) left).Value)
- ig.Emit (OpCodes.Brtrue, target);
- else
- ig.Emit (OpCodes.Brfalse, target);
- return true;
- } else if (right is BoolConstant){
- left.Emit (ec);
- if (my_on_true != ((BoolConstant) right).Value)
- ig.Emit (OpCodes.Brtrue, target);
- else
- ig.Emit (OpCodes.Brfalse, target);
- return true;
- }
-
- } else if (oper == Operator.LogicalAnd){
- if (left is Binary){
- Binary left_binary = (Binary) left;
-
- if (onTrue){
- Label tests_end = ig.DefineLabel ();
-
- if (left_binary.EmitBranchable (ec, tests_end, false)){
- if (right is Binary){
- Binary right_binary = (Binary) right;
-
- if (right_binary.EmitBranchable (ec, target, true)){
- ig.MarkLabel (tests_end);
- return true;
- }
- }
- right.Emit (ec);
- ig.Emit (OpCodes.Brtrue, target);
- ig.MarkLabel (tests_end);
- return true;
- }
- } else {
- if (left_binary.EmitBranchable (ec, target, false)){
- if (right is Binary){
- Binary right_binary = (Binary) right;
-
- if (right_binary.EmitBranchable (ec, target, false))
- return true;
- }
- right.Emit (ec);
- if (onTrue)
- ig.Emit (OpCodes.Brtrue, target);
- else
- ig.Emit (OpCodes.Brfalse, target);
- return true;
- }
- }
- //
- // Give up, and let the regular Emit work, but we could
- // also optimize the left-non-Branchable, but-right-Branchable
- //
- }
- return false;
- } else if (oper == Operator.LogicalOr){
- if (left is Binary){
- Binary left_binary = (Binary) left;
-
- if (onTrue){
- if (left_binary.EmitBranchable (ec, target, true)){
- if (right is Binary){
- Binary right_binary = (Binary) right;
-
- if (right_binary.EmitBranchable (ec, target, true))
- return true;
- }
- right.Emit (ec);
- ig.Emit (OpCodes.Brtrue, target);
- return true;
- }
-
- //
- // Give up, and let the regular Emit work, but we could
- // also optimize the left-non-Branchable, but-right-Branchable
- //
- } else {
- Label tests_end = ig.DefineLabel ();
-
- if (left_binary.EmitBranchable (ec, tests_end, true)){
- if (right is Binary){
- Binary right_binary = (Binary) right;
-
- if (right_binary.EmitBranchable (ec, target, false)){
- ig.MarkLabel (tests_end);
- return true;
- }
- }
- right.Emit (ec);
- ig.Emit (OpCodes.Brfalse, target);
- ig.MarkLabel (tests_end);
- return true;
- }
- }
- }
-
- return false;
- } else if (!(oper == Operator.LessThan ||
- oper == Operator.GreaterThan ||
- oper == Operator.LessThanOrEqual ||
- oper == Operator.GreaterThanOrEqual))
- return false;
-
- left.Emit (ec);
- right.Emit (ec);
-
- bool isUnsigned = is_unsigned (left.Type);
-
- switch (oper){
- case Operator.Equality:
- if (onTrue)
- ig.Emit (OpCodes.Beq, target);
- else
- ig.Emit (OpCodes.Bne_Un, target);
- break;
-
- case Operator.Inequality:
- if (onTrue)
- ig.Emit (OpCodes.Bne_Un, target);
- else
- ig.Emit (OpCodes.Beq, target);
- break;
-
- case Operator.LessThan:
- if (onTrue)
- if (isUnsigned)
- ig.Emit (OpCodes.Blt_Un, target);
- else
- ig.Emit (OpCodes.Blt, target);
- else
- if (isUnsigned)
- ig.Emit (OpCodes.Bge_Un, target);
- else
- ig.Emit (OpCodes.Bge, target);
- break;
-
- case Operator.GreaterThan:
- if (onTrue)
- if (isUnsigned)
- ig.Emit (OpCodes.Bgt_Un, target);
- else
- ig.Emit (OpCodes.Bgt, target);
- else
- if (isUnsigned)
- ig.Emit (OpCodes.Ble_Un, target);
- else
- ig.Emit (OpCodes.Ble, target);
- break;
-
- case Operator.LessThanOrEqual:
- if (onTrue)
- if (isUnsigned)
- ig.Emit (OpCodes.Ble_Un, target);
- else
- ig.Emit (OpCodes.Ble, target);
- else
- if (isUnsigned)
- ig.Emit (OpCodes.Bgt_Un, target);
- else
- ig.Emit (OpCodes.Bgt, target);
- break;
-
-
- case Operator.GreaterThanOrEqual:
- if (onTrue)
- if (isUnsigned)
- ig.Emit (OpCodes.Bge_Un, target);
- else
- ig.Emit (OpCodes.Bge, target);
- else
- if (isUnsigned)
- ig.Emit (OpCodes.Blt_Un, target);
- else
- ig.Emit (OpCodes.Blt, target);
- break;
-
- default:
- return false;
- }
-
- return true;
- }
-
- public override void Emit (EmitContext ec)
- {
- ILGenerator ig = ec.ig;
- Type l = left.Type;
- Type r = right.Type;
- OpCode opcode;
-
- if (method != null) {
-
- // Note that operators are static anyway
-
- if (Arguments != null)
- Invocation.EmitArguments (ec, method, Arguments);
-
- if (method is MethodInfo)
- ig.Emit (OpCodes.Call, (MethodInfo) method);
- else
- ig.Emit (OpCodes.Call, (ConstructorInfo) method);
-
- if (DelegateOperation)
- ig.Emit (OpCodes.Castclass, type);
-
- return;
- }
-
- //
- // Handle short-circuit operators differently
- // than the rest
- //
- if (oper == Operator.LogicalAnd){
- Label load_zero = ig.DefineLabel ();
- Label end = ig.DefineLabel ();
- bool process = true;
-
- if (left is Binary){
- Binary left_binary = (Binary) left;
-
- if (left_binary.EmitBranchable (ec, load_zero, false)){
- right.Emit (ec);
- ig.Emit (OpCodes.Br, end);
- process = false;
- }
- }
-
- if (process){
- left.Emit (ec);
- ig.Emit (OpCodes.Brfalse, load_zero);
- right.Emit (ec);
- ig.Emit (OpCodes.Br, end);
- }
- ig.MarkLabel (load_zero);
- ig.Emit (OpCodes.Ldc_I4_0);
- ig.MarkLabel (end);
- return;
- } else if (oper == Operator.LogicalOr){
- Label load_one = ig.DefineLabel ();
- Label end = ig.DefineLabel ();
- bool process = true;
-
- if (left is Binary){
- Binary left_binary = (Binary) left;
-
- if (left_binary.EmitBranchable (ec, load_one, true)){
- right.Emit (ec);
- ig.Emit (OpCodes.Br, end);
- process = false;
- }
- }
-
- if (process){
- left.Emit (ec);
- ig.Emit (OpCodes.Brtrue, load_one);
- right.Emit (ec);
- ig.Emit (OpCodes.Br, end);
- }
- ig.MarkLabel (load_one);
- ig.Emit (OpCodes.Ldc_I4_1);
- ig.MarkLabel (end);
- return;
- }
-
- left.Emit (ec);
- right.Emit (ec);
-
- bool isUnsigned = is_unsigned (left.Type);
- switch (oper){
- case Operator.Multiply:
- if (ec.CheckState){
- if (l == TypeManager.int32_type || l == TypeManager.int64_type)
- opcode = OpCodes.Mul_Ovf;
- else if (isUnsigned)
- opcode = OpCodes.Mul_Ovf_Un;
- else
- opcode = OpCodes.Mul;
- } else
- opcode = OpCodes.Mul;
-
- break;
-
- case Operator.Division:
- if (isUnsigned)
- opcode = OpCodes.Div_Un;
- else
- opcode = OpCodes.Div;
- break;
-
- case Operator.Modulus:
- if (isUnsigned)
- opcode = OpCodes.Rem_Un;
- else
- opcode = OpCodes.Rem;
- break;
-
- case Operator.Addition:
- if (ec.CheckState){
- if (l == TypeManager.int32_type || l == TypeManager.int64_type)
- opcode = OpCodes.Add_Ovf;
- else if (isUnsigned)
- opcode = OpCodes.Add_Ovf_Un;
- else
- opcode = OpCodes.Add;
- } else
- opcode = OpCodes.Add;
- break;
-
- case Operator.Subtraction:
- if (ec.CheckState){
- if (l == TypeManager.int32_type || l == TypeManager.int64_type)
- opcode = OpCodes.Sub_Ovf;
- else if (isUnsigned)
- opcode = OpCodes.Sub_Ovf_Un;
- else
- opcode = OpCodes.Sub;
- } else
- opcode = OpCodes.Sub;
- break;
-
- case Operator.RightShift:
- if (isUnsigned)
- opcode = OpCodes.Shr_Un;
- else
- opcode = OpCodes.Shr;
- break;
-
- case Operator.LeftShift:
- opcode = OpCodes.Shl;
- break;
-
- case Operator.Equality:
- opcode = OpCodes.Ceq;
- break;
-
- case Operator.Inequality:
- ig.Emit (OpCodes.Ceq);
- ig.Emit (OpCodes.Ldc_I4_0);
-
- opcode = OpCodes.Ceq;
- break;
-
- case Operator.LessThan:
- if (isUnsigned)
- opcode = OpCodes.Clt_Un;
- else
- opcode = OpCodes.Clt;
- break;
-
- case Operator.GreaterThan:
- if (isUnsigned)
- opcode = OpCodes.Cgt_Un;
- else
- opcode = OpCodes.Cgt;
- break;
-
- case Operator.LessThanOrEqual:
- if (isUnsigned)
- ig.Emit (OpCodes.Cgt_Un);
- else
- ig.Emit (OpCodes.Cgt);
- ig.Emit (OpCodes.Ldc_I4_0);
-
- opcode = OpCodes.Ceq;
- break;
-
- case Operator.GreaterThanOrEqual:
- if (isUnsigned)
- ig.Emit (OpCodes.Clt_Un);
- else
- ig.Emit (OpCodes.Clt);
-
- ig.Emit (OpCodes.Ldc_I4_1);
-
- opcode = OpCodes.Sub;
- break;
-
- case Operator.BitwiseOr:
- opcode = OpCodes.Or;
- break;
-
- case Operator.BitwiseAnd:
- opcode = OpCodes.And;
- break;
-
- case Operator.ExclusiveOr:
- opcode = OpCodes.Xor;
- break;
-
- default:
- throw new Exception ("This should not happen: Operator = "
- + oper.ToString ());
- }
-
- ig.Emit (opcode);
- }
-
- public bool IsBuiltinOperator {
- get {
- return method == null;
- }
- }
- }
-
- public class PointerArithmetic : Expression {
- Expression left, right;
- bool is_add;
-
- //
- // We assume that `l' is always a pointer
- //
- public PointerArithmetic (bool is_addition, Expression l, Expression r, Type t,
- Location loc)
- {
- type = t;
- eclass = ExprClass.Variable;
- this.loc = loc;
- left = l;
- right = r;
- is_add = is_addition;
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- //
- // We are born fully resolved
- //
- return this;
- }
-
- public override void Emit (EmitContext ec)
- {
- Type op_type = left.Type;
- ILGenerator ig = ec.ig;
- int size = GetTypeSize (op_type.GetElementType ());
-
- if (right.Type.IsPointer){
- //
- // handle (pointer - pointer)
- //
- left.Emit (ec);
- right.Emit (ec);
- ig.Emit (OpCodes.Sub);
-
- if (size != 1){
- if (size == 0)
- ig.Emit (OpCodes.Sizeof, op_type);
- else
- IntLiteral.EmitInt (ig, size);
- ig.Emit (OpCodes.Div);
- }
- ig.Emit (OpCodes.Conv_I8);
- } else {
- //
- // handle + and - on (pointer op int)
- //
- left.Emit (ec);
- ig.Emit (OpCodes.Conv_I);
- right.Emit (ec);
- if (size != 1){
- if (size == 0)
- ig.Emit (OpCodes.Sizeof, op_type);
- else
- IntLiteral.EmitInt (ig, size);
- ig.Emit (OpCodes.Mul);
- }
- if (is_add)
- ig.Emit (OpCodes.Add);
- else
- ig.Emit (OpCodes.Sub);
- }
- }
- }
-
- /// <summary>
- /// Implements the ternary conditional operator (?:)
- /// </summary>
- public class Conditional : Expression {
- Expression expr, trueExpr, falseExpr;
-
- public Conditional (Expression expr, Expression trueExpr, Expression falseExpr, Location l)
- {
- this.expr = expr;
- this.trueExpr = trueExpr;
- this.falseExpr = falseExpr;
- this.loc = l;
- }
-
- public Expression Expr {
- get {
- return expr;
- }
- }
-
- public Expression TrueExpr {
- get {
- return trueExpr;
- }
- }
-
- public Expression FalseExpr {
- get {
- return falseExpr;
- }
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- expr = expr.Resolve (ec);
-
- if (expr == null)
- return null;
-
- if (expr.Type != TypeManager.bool_type)
- expr = Expression.ConvertImplicitRequired (
- ec, expr, TypeManager.bool_type, loc);
-
- trueExpr = trueExpr.Resolve (ec);
- falseExpr = falseExpr.Resolve (ec);
-
- if (trueExpr == null || falseExpr == null)
- return null;
-
- eclass = ExprClass.Value;
- if (trueExpr.Type == falseExpr.Type)
- type = trueExpr.Type;
- else {
- Expression conv;
- Type true_type = trueExpr.Type;
- Type false_type = falseExpr.Type;
-
- if (trueExpr is NullLiteral){
- type = false_type;
- return this;
- } else if (falseExpr is NullLiteral){
- type = true_type;
- return this;
- }
-
- //
- // First, if an implicit conversion exists from trueExpr
- // to falseExpr, then the result type is of type falseExpr.Type
- //
- conv = ConvertImplicit (ec, trueExpr, false_type, loc);
- if (conv != null){
- //
- // Check if both can convert implicitl to each other's type
- //
- if (ConvertImplicit (ec, falseExpr, true_type, loc) != null){
- Error (172,
- "Can not compute type of conditional expression " +
- "as `" + TypeManager.CSharpName (trueExpr.Type) +
- "' and `" + TypeManager.CSharpName (falseExpr.Type) +
- "' convert implicitly to each other");
- return null;
- }
- type = false_type;
- trueExpr = conv;
- } else if ((conv = ConvertImplicit(ec, falseExpr, true_type,loc))!= null){
- type = true_type;
- falseExpr = conv;
- } else {
- Error (173, "The type of the conditional expression can " +
- "not be computed because there is no implicit conversion" +
- " from `" + TypeManager.CSharpName (trueExpr.Type) + "'" +
- " and `" + TypeManager.CSharpName (falseExpr.Type) + "'");
- return null;
- }
- }
-
- if (expr is BoolConstant){
- BoolConstant bc = (BoolConstant) expr;
-
- if (bc.Value)
- return trueExpr;
- else
- return falseExpr;
- }
-
- return this;
- }
-
- public override void Emit (EmitContext ec)
- {
- ILGenerator ig = ec.ig;
- Label false_target = ig.DefineLabel ();
- Label end_target = ig.DefineLabel ();
-
- Statement.EmitBoolExpression (ec, expr, false_target, false);
- trueExpr.Emit (ec);
- ig.Emit (OpCodes.Br, end_target);
- ig.MarkLabel (false_target);
- falseExpr.Emit (ec);
- ig.MarkLabel (end_target);
- }
-
- }
-
- /// <summary>
- /// Local variables
- /// </summary>
- public class LocalVariableReference : Expression, IAssignMethod, IMemoryLocation, IVariable {
- public readonly string Name;
- public readonly Block Block;
- VariableInfo variable_info;
- bool is_readonly;
-
- public LocalVariableReference (Block block, string name, Location l)
- {
- Block = block;
- Name = name;
- loc = 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,
- VariableInfo variable_info, bool is_readonly)
- : this (block, name, l)
- {
- this.variable_info = variable_info;
- this.is_readonly = is_readonly;
- }
-
- public VariableInfo VariableInfo {
- get {
- if (variable_info == null) {
- variable_info = Block.GetVariableInfo (Name);
- is_readonly = variable_info.ReadOnly;
- }
- return variable_info;
- }
- }
-
- public bool IsAssigned (EmitContext ec, Location loc)
- {
- return VariableInfo.IsAssigned (ec, loc);
- }
-
- public bool IsFieldAssigned (EmitContext ec, string name, Location loc)
- {
- return VariableInfo.IsFieldAssigned (ec, name, loc);
- }
-
- public void SetAssigned (EmitContext ec)
- {
- VariableInfo.SetAssigned (ec);
- }
-
- public void SetFieldAssigned (EmitContext ec, string name)
- {
- VariableInfo.SetFieldAssigned (ec, name);
- }
-
- public bool IsReadOnly {
- get {
- if (variable_info == null) {
- variable_info = Block.GetVariableInfo (Name);
- is_readonly = variable_info.ReadOnly;
- }
- return is_readonly;
- }
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- VariableInfo vi = VariableInfo;
- Expression e;
-
- e = Block.GetConstantExpression (Name);
- if (e != null) {
- vi.Used = true;
- return e;
- }
-
- if (ec.DoFlowAnalysis && !IsAssigned (ec, loc))
- return null;
-
- type = vi.VariableType;
- return this;
- }
-
- override public Expression DoResolveLValue (EmitContext ec, Expression right_side)
- {
- VariableInfo vi = VariableInfo;
-
- if (ec.DoFlowAnalysis)
- ec.SetVariableAssigned (vi);
-
- Expression e = DoResolve (ec);
-
- if (e == null)
- return null;
-
- if (is_readonly){
- Error (1604, "cannot assign to `" + Name + "' because it is readonly");
- return null;
- }
-
- return this;
- }
-
- public override void Emit (EmitContext ec)
- {
- VariableInfo vi = VariableInfo;
- ILGenerator ig = ec.ig;
-
- ig.Emit (OpCodes.Ldloc, vi.LocalBuilder);
- vi.Used = true;
- }
-
- public void EmitAssign (EmitContext ec, Expression source)
- {
- ILGenerator ig = ec.ig;
- VariableInfo vi = VariableInfo;
-
- vi.Assigned = true;
-
- source.Emit (ec);
-
- ig.Emit (OpCodes.Stloc, vi.LocalBuilder);
- }
-
- public void AddressOf (EmitContext ec, AddressOp mode)
- {
- VariableInfo vi = VariableInfo;
-
- ec.ig.Emit (OpCodes.Ldloca, vi.LocalBuilder);
- }
- }
-
- /// <summary>
- /// This represents a reference to a parameter in the intermediate
- /// representation.
- /// </summary>
- public class ParameterReference : Expression, IAssignMethod, IMemoryLocation, IVariable {
- Parameters pars;
- String name;
- int idx;
- public Parameter.Modifier mod;
- public bool is_ref, is_out;
-
- public ParameterReference (Parameters pars, int idx, string name, Location loc)
- {
- this.pars = pars;
- this.idx = idx;
- this.name = name;
- this.loc = loc;
- eclass = ExprClass.Variable;
- }
-
- public bool IsAssigned (EmitContext ec, Location loc)
- {
- if (!is_out || !ec.DoFlowAnalysis)
- return true;
-
- if (!ec.CurrentBranching.IsParameterAssigned (idx)) {
- Report.Error (165, loc,
- "Use of unassigned local variable `" + name + "'");
- return false;
- }
-
- return true;
- }
-
- public bool IsFieldAssigned (EmitContext ec, string field_name, Location loc)
- {
- if (!is_out || !ec.DoFlowAnalysis)
- return true;
-
- if (ec.CurrentBranching.IsParameterAssigned (idx))
- return true;
-
- if (!ec.CurrentBranching.IsParameterAssigned (idx, field_name)) {
- Report.Error (170, loc,
- "Use of possibly unassigned field `" + field_name + "'");
- return false;
- }
-
- return true;
- }
-
- public void SetAssigned (EmitContext ec)
- {
- if (is_out && ec.DoFlowAnalysis)
- ec.CurrentBranching.SetParameterAssigned (idx);
- }
-
- public void SetFieldAssigned (EmitContext ec, string field_name)
- {
- if (is_out && ec.DoFlowAnalysis)
- ec.CurrentBranching.SetParameterAssigned (idx, field_name);
- }
-
- //
- // Notice that for ref/out parameters, the type exposed is not the
- // same type exposed externally.
- //
- // for "ref int a":
- // externally we expose "int&"
- // here we expose "int".
- //
- // We record this in "is_ref". This means that the type system can treat
- // the type as it is expected, but when we generate the code, we generate
- // the alternate kind of code.
- //
- public override Expression DoResolve (EmitContext ec)
- {
- 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 && ec.DoFlowAnalysis && !IsAssigned (ec, loc))
- return null;
-
- return this;
- }
-
- override public Expression DoResolveLValue (EmitContext ec, Expression right_side)
- {
- 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 && ec.DoFlowAnalysis)
- ec.SetParameterAssigned (idx);
-
- return this;
- }
-
- static void EmitLdArg (ILGenerator ig, int x)
- {
- if (x <= 255){
- switch (x){
- case 0: ig.Emit (OpCodes.Ldarg_0); break;
- case 1: ig.Emit (OpCodes.Ldarg_1); break;
- case 2: ig.Emit (OpCodes.Ldarg_2); break;
- case 3: ig.Emit (OpCodes.Ldarg_3); break;
- default: ig.Emit (OpCodes.Ldarg_S, (byte) x); break;
- }
- } else
- ig.Emit (OpCodes.Ldarg, x);
- }
-
- //
- // This method is used by parameters that are references, that are
- // being passed as references: we only want to pass the pointer (that
- // is already stored in the parameter, not the address of the pointer,
- // and not the value of the variable).
- //
- public void EmitLoad (EmitContext ec)
- {
- ILGenerator ig = ec.ig;
- int arg_idx = idx;
-
- if (!ec.IsStatic)
- arg_idx++;
-
- EmitLdArg (ig, arg_idx);
- }
-
- public override void Emit (EmitContext ec)
- {
- ILGenerator ig = ec.ig;
- int arg_idx = idx;
-
- if (!ec.IsStatic)
- arg_idx++;
-
- EmitLdArg (ig, arg_idx);
-
- if (!is_ref)
- return;
-
- //
- // If we are a reference, we loaded on the stack a pointer
- // Now lets load the real value
- //
- LoadFromPtr (ig, type);
- }
-
- public void EmitAssign (EmitContext ec, Expression source)
- {
- ILGenerator ig = ec.ig;
- int arg_idx = idx;
-
- if (!ec.IsStatic)
- arg_idx++;
-
- if (is_ref)
- EmitLdArg (ig, arg_idx);
-
- source.Emit (ec);
-
- if (is_ref)
- StoreFromPtr (ig, type);
- else {
- if (arg_idx <= 255)
- ig.Emit (OpCodes.Starg_S, (byte) arg_idx);
- else
- ig.Emit (OpCodes.Starg, arg_idx);
- }
- }
-
- public void AddressOf (EmitContext ec, AddressOp mode)
- {
- int arg_idx = idx;
-
- if (!ec.IsStatic)
- arg_idx++;
-
- if (is_ref){
- if (arg_idx <= 255)
- ec.ig.Emit (OpCodes.Ldarg_S, (byte) arg_idx);
- else
- ec.ig.Emit (OpCodes.Ldarg, arg_idx);
- } else {
- if (arg_idx <= 255)
- ec.ig.Emit (OpCodes.Ldarga_S, (byte) arg_idx);
- else
- ec.ig.Emit (OpCodes.Ldarga, arg_idx);
- }
- }
-
- }
-
- /// <summary>
- /// Used for arguments to New(), Invocation()
- /// </summary>
- public class Argument {
- public enum AType : byte {
- Expression,
- Ref,
- Out
- };
-
- public readonly AType ArgType;
- public Expression Expr;
-
- public Argument (Expression expr, AType type)
- {
- this.Expr = expr;
- this.ArgType = type;
- }
-
- public Type Type {
- get {
- if (ArgType == AType.Ref || ArgType == AType.Out)
- return TypeManager.LookupType (Expr.Type.ToString () + "&");
- else
- return Expr.Type;
- }
- }
-
- public Parameter.Modifier GetParameterModifier ()
- {
- switch (ArgType) {
- case AType.Out:
- return Parameter.Modifier.OUT | Parameter.Modifier.ISBYREF;
-
- case AType.Ref:
- return Parameter.Modifier.REF | Parameter.Modifier.ISBYREF;
-
- default:
- return Parameter.Modifier.NONE;
- }
- }
-
- public static string FullDesc (Argument a)
- {
- return (a.ArgType == AType.Ref ? "ref " :
- (a.ArgType == AType.Out ? "out " : "")) +
- TypeManager.CSharpName (a.Expr.Type);
- }
-
- public bool ResolveMethodGroup (EmitContext ec, Location loc)
- {
- // FIXME: csc doesn't report any error if you try to use `ref' or
- // `out' in a delegate creation expression.
- Expr = Expr.Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup);
- if (Expr == null)
- return false;
-
- return true;
- }
-
- public bool Resolve (EmitContext ec, Location loc)
- {
- if (ArgType == AType.Ref) {
- Expr = Expr.Resolve (ec);
- if (Expr == null)
- return false;
-
- Expr = Expr.ResolveLValue (ec, Expr);
- } else if (ArgType == AType.Out)
- Expr = Expr.ResolveLValue (ec, new EmptyExpression ());
- else
- Expr = Expr.Resolve (ec);
-
- if (Expr == null)
- return false;
-
- if (ArgType == AType.Expression)
- return true;
-
- if (Expr.eclass != ExprClass.Variable){
- //
- // We just probe to match the CSC output
- //
- if (Expr.eclass == ExprClass.PropertyAccess ||
- Expr.eclass == ExprClass.IndexerAccess){
- Report.Error (
- 206, loc,
- "A property or indexer can not be passed as an out or ref " +
- "parameter");
- } else {
- Report.Error (
- 1510, loc,
- "An lvalue is required as an argument to out or ref");
- }
- return false;
- }
-
- return true;
- }
-
- public void Emit (EmitContext ec)
- {
- //
- // Ref and Out parameters need to have their addresses taken.
- //
- // ParameterReferences might already be references, so we want
- // to pass just the value
- //
- if (ArgType == AType.Ref || ArgType == AType.Out){
- AddressOp mode = AddressOp.Store;
-
- if (ArgType == AType.Ref)
- mode |= AddressOp.Load;
-
- if (Expr is ParameterReference){
- ParameterReference pr = (ParameterReference) Expr;
-
- if (pr.is_ref)
- pr.EmitLoad (ec);
- else {
-
- pr.AddressOf (ec, mode);
- }
- } else
- ((IMemoryLocation)Expr).AddressOf (ec, mode);
- } else
- Expr.Emit (ec);
- }
- }
-
- /// <summary>
- /// Invocation of methods or delegates.
- /// </summary>
- public class Invocation : ExpressionStatement {
- public readonly ArrayList Arguments;
-
- Expression expr;
- MethodBase method = null;
- bool is_base;
-
- static Hashtable method_parameter_cache;
-
- static Invocation ()
- {
- method_parameter_cache = new PtrHashtable ();
- }
-
- //
- // arguments is an ArrayList, but we do not want to typecast,
- // as it might be null.
- //
- // FIXME: only allow expr to be a method invocation or a
- // delegate invocation (7.5.5)
- //
- public Invocation (Expression expr, ArrayList arguments, Location l)
- {
- this.expr = expr;
- Arguments = arguments;
- loc = l;
- }
-
- public Expression Expr {
- get {
- return expr;
- }
- }
-
- /// <summary>
- /// Returns the Parameters (a ParameterData interface) for the
- /// Method `mb'
- /// </summary>
- public static ParameterData GetParameterData (MethodBase mb)
- {
- object pd = method_parameter_cache [mb];
- object ip;
-
- if (pd != null)
- return (ParameterData) pd;
-
-
- ip = TypeManager.LookupParametersByBuilder (mb);
- if (ip != null){
- method_parameter_cache [mb] = ip;
-
- return (ParameterData) ip;
- } else {
- ParameterInfo [] pi = mb.GetParameters ();
- ReflectionParameters rp = new ReflectionParameters (pi);
- method_parameter_cache [mb] = rp;
-
- return (ParameterData) rp;
- }
- }
-
- /// <summary>
- /// Determines "better conversion" as specified in 7.4.2.3
- /// Returns : 1 if a->p is better
- /// 0 if a->q or neither is better
- /// </summary>
- static int BetterConversion (EmitContext ec, Argument a, Type p, Type q, Location loc)
- {
- Type argument_type = a.Type;
- Expression argument_expr = a.Expr;
-
- if (argument_type == null)
- throw new Exception ("Expression of type " + a.Expr + " does not resolve its type");
-
- //
- // This is a special case since csc behaves this way. I can't find
- // it anywhere in the spec but oh well ...
- //
- 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;
-
- if (p == q)
- return 0;
-
- if (argument_type == p)
- return 1;
-
- if (argument_type == q)
- return 0;
-
- //
- // Now probe whether an implicit constant expression conversion
- // can be used.
- //
- // An implicit constant expression conversion permits the following
- // conversions:
- //
- // * A constant-expression of type `int' can be converted to type
- // sbyte, byute, short, ushort, uint, ulong provided the value of
- // of the expression is withing the range of the destination type.
- //
- // * A constant-expression of type long can be converted to type
- // ulong, provided the value of the constant expression is not negative
- //
- // FIXME: Note that this assumes that constant folding has
- // taken place. We dont do constant folding yet.
- //
-
- if (argument_expr is IntConstant){
- IntConstant ei = (IntConstant) argument_expr;
- int value = ei.Value;
-
- if (p == TypeManager.sbyte_type){
- if (value >= SByte.MinValue && value <= SByte.MaxValue)
- return 1;
- } else if (p == TypeManager.byte_type){
- if (q == TypeManager.sbyte_type &&
- value >= SByte.MinValue && value <= SByte.MaxValue)
- return 0;
- else if (Byte.MinValue >= 0 && value <= Byte.MaxValue)
- return 1;
- } else if (p == TypeManager.short_type){
- if (value >= Int16.MinValue && value <= Int16.MaxValue)
- return 1;
- } else if (p == TypeManager.ushort_type){
- if (q == TypeManager.short_type &&
- value >= Int16.MinValue && value <= Int16.MaxValue)
- return 0;
- else if (value >= UInt16.MinValue && value <= UInt16.MaxValue)
- return 1;
- } else if (p == TypeManager.int32_type){
- if (value >= Int32.MinValue && value <= Int32.MaxValue)
- return 1;
- } else if (p == TypeManager.uint32_type){
- //
- // we can optimize this case: a positive int32
- // always fits on a uint32
- //
- if (value >= 0)
- return 1;
- } else if (p == TypeManager.uint64_type){
- //
- // we can optimize this case: a positive int32
- // always fits on a uint64
- //
- if (q == TypeManager.int64_type)
- return 0;
- else if (value >= 0)
- return 1;
- } else if (p == TypeManager.int64_type){
- return 1;
- }
- } else if (argument_type == TypeManager.int64_type && argument_expr is LongConstant){
- LongConstant lc = (LongConstant) argument_expr;
-
- if (p == TypeManager.uint64_type){
- if (lc.Value > 0)
- return 1;
- }
- }
-
- if (q == null) {
- Expression tmp = ConvertImplicit (ec, argument_expr, p, loc);
-
- if (tmp != null)
- return 1;
- else
- return 0;
- }
-
- Expression p_tmp = new EmptyExpression (p);
- Expression q_tmp = new EmptyExpression (q);
-
- if (ImplicitConversionExists (ec, p_tmp, q) == true &&
- 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 1;
-
- if (p == TypeManager.short_type)
- if (q == TypeManager.ushort_type || q == TypeManager.uint32_type ||
- q == TypeManager.uint64_type)
- return 1;
-
- if (p == TypeManager.int32_type)
- if (q == TypeManager.uint32_type || q == TypeManager.uint64_type)
- return 1;
-
- if (p == TypeManager.int64_type)
- if (q == TypeManager.uint64_type)
- return 1;
-
- return 0;
- }
-
- /// <summary>
- /// Determines "Better function"
- /// </summary>
- /// <remarks>
- /// and returns an integer indicating :
- /// 0 if candidate ain't better
- /// 1 if candidate is better than the current best match
- /// </remarks>
- static int BetterFunction (EmitContext ec, ArrayList args,
- MethodBase candidate, MethodBase best,
- bool expanded_form, Location loc)
- {
- ParameterData candidate_pd = GetParameterData (candidate);
- ParameterData best_pd;
- int argument_count;
-
- if (args == null)
- argument_count = 0;
- else
- argument_count = args.Count;
-
- int cand_count = candidate_pd.Count;
-
- if (cand_count == 0 && argument_count == 0)
- return 1;
-
- if (candidate_pd.ParameterModifier (cand_count - 1) != Parameter.Modifier.PARAMS)
- if (cand_count != argument_count)
- return 0;
-
- if (best == null) {
- int x = 0;
-
- if (argument_count == 0 && cand_count == 1 &&
- candidate_pd.ParameterModifier (cand_count - 1) == Parameter.Modifier.PARAMS)
- return 1;
-
- for (int j = argument_count; j > 0;) {
- j--;
-
- Argument a = (Argument) args [j];
- Type t = candidate_pd.ParameterType (j);
-
- if (candidate_pd.ParameterModifier (j) == Parameter.Modifier.PARAMS)
- if (expanded_form)
- t = t.GetElementType ();
-
- x = BetterConversion (ec, a, t, null, loc);
-
- if (x <= 0)
- break;
- }
-
- if (x > 0)
- return 1;
- else
- return 0;
- }
-
- best_pd = GetParameterData (best);
-
- int rating1 = 0, rating2 = 0;
-
- for (int j = 0; j < argument_count; ++j) {
- int x, y;
-
- Argument a = (Argument) args [j];
-
- Type ct = candidate_pd.ParameterType (j);
- Type bt = best_pd.ParameterType (j);
-
- if (candidate_pd.ParameterModifier (j) == Parameter.Modifier.PARAMS)
- if (expanded_form)
- ct = ct.GetElementType ();
-
- if (best_pd.ParameterModifier (j) == Parameter.Modifier.PARAMS)
- if (expanded_form)
- bt = bt.GetElementType ();
-
- x = BetterConversion (ec, a, ct, bt, loc);
- y = BetterConversion (ec, a, bt, ct, loc);
-
- if (x < y)
- return 0;
-
- rating1 += x;
- rating2 += y;
- }
-
- if (rating1 > rating2)
- return 1;
- else
- return 0;
- }
-
- public static string FullMethodDesc (MethodBase mb)
- {
- string ret_type = "";
-
- if (mb is MethodInfo)
- ret_type = TypeManager.CSharpName (((MethodInfo) mb).ReturnType);
-
- StringBuilder sb = new StringBuilder (ret_type);
- sb.Append (" ");
- sb.Append (mb.ReflectedType.ToString ());
- sb.Append (".");
- sb.Append (mb.Name);
-
- ParameterData pd = GetParameterData (mb);
-
- int count = pd.Count;
- sb.Append (" (");
-
- for (int i = count; i > 0; ) {
- i--;
-
- sb.Append (pd.ParameterDesc (count - i - 1));
- if (i != 0)
- sb.Append (", ");
- }
-
- sb.Append (")");
- return sb.ToString ();
- }
-
- public static MethodGroupExpr MakeUnionSet (Expression mg1, Expression mg2, Location loc)
- {
- MemberInfo [] miset;
- MethodGroupExpr union;
-
- if (mg1 == null){
- if (mg2 == null)
- return null;
- return (MethodGroupExpr) mg2;
- } else {
- if (mg2 == null)
- return (MethodGroupExpr) mg1;
- }
-
- MethodGroupExpr left_set = null, right_set = null;
- int length1 = 0, length2 = 0;
-
- left_set = (MethodGroupExpr) mg1;
- length1 = left_set.Methods.Length;
-
- right_set = (MethodGroupExpr) mg2;
- length2 = right_set.Methods.Length;
-
- ArrayList common = new ArrayList ();
-
- foreach (MethodBase l in left_set.Methods){
- foreach (MethodBase r in right_set.Methods){
- if (l != r)
- continue;
- common.Add (r);
- break;
- }
- }
-
- miset = new MemberInfo [length1 + length2 - common.Count];
- left_set.Methods.CopyTo (miset, 0);
-
- int k = length1;
-
- foreach (MemberInfo mi in right_set.Methods){
- if (!common.Contains (mi))
- miset [k++] = mi;
- }
-
- union = new MethodGroupExpr (miset, loc);
-
- return union;
- }
-
- /// <summary>
- /// Determines is the candidate method, if a params method, is applicable
- /// in its expanded form to the given set of arguments
- /// </summary>
- static bool IsParamsMethodApplicable (EmitContext ec, ArrayList arguments, MethodBase candidate)
- {
- int arg_count;
-
- if (arguments == null)
- arg_count = 0;
- else
- arg_count = arguments.Count;
-
- ParameterData pd = GetParameterData (candidate);
-
- int pd_count = pd.Count;
-
- if (pd_count == 0)
- return false;
-
- if (pd.ParameterModifier (pd_count - 1) != Parameter.Modifier.PARAMS)
- return false;
-
- if (pd_count - 1 > arg_count)
- return false;
-
- if (pd_count == 1 && arg_count == 0)
- return true;
-
- //
- // If we have come this far, the case which remains is when the number of parameters
- // is less than or equal to the argument count.
- //
- for (int i = 0; i < pd_count - 1; ++i) {
-
- Argument a = (Argument) arguments [i];
-
- Parameter.Modifier a_mod = a.GetParameterModifier () &
- ~(Parameter.Modifier.OUT | Parameter.Modifier.REF);
- Parameter.Modifier p_mod = pd.ParameterModifier (i) &
- ~(Parameter.Modifier.OUT | Parameter.Modifier.REF);
-
- if (a_mod == p_mod) {
-
- if (a_mod == Parameter.Modifier.NONE)
- if (!ImplicitConversionExists (ec, a.Expr, pd.ParameterType (i)))
- return false;
-
- if ((a_mod & Parameter.Modifier.ISBYREF) != 0) {
- Type pt = pd.ParameterType (i);
-
- if (!pt.IsByRef)
- pt = TypeManager.LookupType (pt.FullName + "&");
-
- if (pt != a.Type)
- return false;
- }
- } else
- return false;
-
- }
-
- Type element_type = pd.ParameterType (pd_count - 1).GetElementType ();
-
- for (int i = pd_count - 1; i < arg_count; i++) {
- Argument a = (Argument) arguments [i];
-
- if (!StandardConversionExists (a.Expr, element_type))
- return false;
- }
-
- return true;
- }
-
- /// <summary>
- /// Determines if the candidate method is applicable (section 14.4.2.1)
- /// to the given set of arguments
- /// </summary>
- static bool IsApplicable (EmitContext ec, ArrayList arguments, MethodBase candidate)
- {
- int arg_count;
-
- if (arguments == null)
- arg_count = 0;
- else
- arg_count = arguments.Count;
-
- ParameterData pd = GetParameterData (candidate);
-
- int pd_count = pd.Count;
-
- if (arg_count != pd.Count)
- return false;
-
- for (int i = arg_count; i > 0; ) {
- i--;
-
- Argument a = (Argument) arguments [i];
-
- Parameter.Modifier a_mod = a.GetParameterModifier () &
- ~(Parameter.Modifier.OUT | Parameter.Modifier.REF);
- Parameter.Modifier p_mod = pd.ParameterModifier (i) &
- ~(Parameter.Modifier.OUT | Parameter.Modifier.REF);
-
- if (a_mod == p_mod ||
- (a_mod == Parameter.Modifier.NONE && p_mod == Parameter.Modifier.PARAMS)) {
- if (a_mod == Parameter.Modifier.NONE)
- if (!ImplicitConversionExists (ec, a.Expr, pd.ParameterType (i)))
- return false;
-
- if ((a_mod & Parameter.Modifier.ISBYREF) != 0) {
- Type pt = pd.ParameterType (i);
-
- if (!pt.IsByRef)
- pt = TypeManager.LookupType (pt.FullName + "&");
-
- if (pt != a.Type)
- return false;
- }
- } else
- return false;
- }
-
- return true;
- }
-
-
-
- /// <summary>
- /// Find the Applicable Function Members (7.4.2.1)
- ///
- /// me: Method Group expression with the members to select.
- /// it might contain constructors or methods (or anything
- /// that maps to a method).
- ///
- /// Arguments: ArrayList containing resolved Argument objects.
- ///
- /// loc: The location if we want an error to be reported, or a Null
- /// location for "probing" purposes.
- ///
- /// Returns: The MethodBase (either a ConstructorInfo or a MethodInfo)
- /// that is the best match of me on Arguments.
- ///
- /// </summary>
- public static MethodBase OverloadResolve (EmitContext ec, MethodGroupExpr me,
- ArrayList Arguments, Location loc)
- {
- ArrayList afm = new ArrayList ();
- MethodBase method = null;
- Type current_type = null;
- int argument_count;
- ArrayList candidates = new ArrayList ();
-
-
- foreach (MethodBase candidate in me.Methods){
- int x;
-
- // If we're going one level higher in the class hierarchy, abort if
- // we already found an applicable method.
- if (candidate.DeclaringType != current_type) {
- current_type = candidate.DeclaringType;
- if (method != null)
- break;
- }
-
- // Check if candidate is applicable (section 14.4.2.1)
- if (!IsApplicable (ec, Arguments, candidate))
- continue;
-
- candidates.Add (candidate);
- x = BetterFunction (ec, Arguments, candidate, method, false, loc);
-
- if (x == 0)
- continue;
-
- method = candidate;
- }
-
- if (Arguments == null)
- argument_count = 0;
- else
- argument_count = Arguments.Count;
-
- //
- // Now we see if we can find params functions, applicable in their expanded form
- // since if they were applicable in their normal form, they would have been selected
- // above anyways
- //
- bool chose_params_expanded = false;
-
- if (method == null) {
- candidates = new ArrayList ();
- foreach (MethodBase candidate in me.Methods){
- if (!IsParamsMethodApplicable (ec, Arguments, candidate))
- continue;
-
- candidates.Add (candidate);
-
- int x = BetterFunction (ec, Arguments, candidate, method, true, loc);
- if (x == 0)
- continue;
-
- method = candidate;
- chose_params_expanded = true;
- }
- }
-
- if (method == null) {
- //
- // Okay so we have failed to find anything so we
- // return by providing info about the closest match
- //
- for (int i = 0; i < me.Methods.Length; ++i) {
-
- MethodBase c = (MethodBase) me.Methods [i];
- ParameterData pd = GetParameterData (c);
-
- if (pd.Count != argument_count)
- continue;
-
- VerifyArgumentsCompat (ec, Arguments, argument_count, c, false,
- null, loc);
- }
-
- return null;
- }
-
- //
- // Now check that there are no ambiguities i.e the selected method
- // should be better than all the others
- //
-
- foreach (MethodBase candidate in candidates){
- if (candidate == method)
- continue;
-
- //
- // If a normal method is applicable in the sense that it has the same
- // number of arguments, then the expanded params method is never applicable
- // so we debar the params method.
- //
- if (IsParamsMethodApplicable (ec, Arguments, candidate) &&
- IsApplicable (ec, Arguments, method))
- continue;
-
- int x = BetterFunction (ec, Arguments, method, candidate,
- chose_params_expanded, loc);
-
- if (x != 1) {
- Report.Error (
- 121, loc,
- "Ambiguous call when selecting function due to implicit casts");
- return null;
- }
- }
-
- //
- // And now check if the arguments are all compatible, perform conversions
- // if necessary etc. and return if everything is all right
- //
-
- if (!VerifyArgumentsCompat (ec, Arguments, argument_count, method,
- chose_params_expanded, null, loc))
- return null;
-
- return method;
- }
-
- public static bool VerifyArgumentsCompat (EmitContext ec, ArrayList Arguments,
- int argument_count,
- MethodBase method,
- bool chose_params_expanded,
- Type delegate_type,
- Location loc)
- {
- ParameterData pd = GetParameterData (method);
- int pd_count = pd.Count;
-
- for (int j = 0; j < argument_count; j++) {
- Argument a = (Argument) Arguments [j];
- Expression a_expr = a.Expr;
- Type parameter_type = pd.ParameterType (j);
-
- if (pd.ParameterModifier (j) == Parameter.Modifier.PARAMS &&
- chose_params_expanded)
- parameter_type = TypeManager.TypeToCoreType (parameter_type.GetElementType ());
-
- if (a.Type != parameter_type){
- Expression conv;
-
- conv = ConvertImplicit (ec, a_expr, parameter_type, loc);
-
- if (conv == null) {
- if (!Location.IsNull (loc)) {
- if (delegate_type == null)
- Report.Error (1502, loc,
- "The best overloaded match for method '" +
- FullMethodDesc (method) +
- "' has some invalid arguments");
- else
- Report.Error (1594, loc,
- "Delegate '" + delegate_type.ToString () +
- "' has some invalid arguments.");
- Report.Error (1503, loc,
- "Argument " + (j+1) +
- ": Cannot convert from '" + Argument.FullDesc (a)
- + "' to '" + pd.ParameterDesc (j) + "'");
- }
-
- return false;
- }
-
- //
- // Update the argument with the implicit conversion
- //
- if (a_expr != conv)
- a.Expr = conv;
- }
-
- Parameter.Modifier a_mod = a.GetParameterModifier () &
- ~(Parameter.Modifier.OUT | Parameter.Modifier.REF);
- Parameter.Modifier p_mod = pd.ParameterModifier (j) &
- ~(Parameter.Modifier.OUT | Parameter.Modifier.REF);
-
-
- if (a_mod != p_mod &&
- pd.ParameterModifier (pd_count - 1) != Parameter.Modifier.PARAMS) {
- if (!Location.IsNull (loc)) {
- Console.WriteLine ("A:P: " + a.GetParameterModifier ());
- Console.WriteLine ("PP:: " + pd.ParameterModifier (j));
- Console.WriteLine ("PT: " + parameter_type.IsByRef);
- Report.Error (1502, loc,
- "The best overloaded match for method '" + FullMethodDesc (method)+
- "' has some invalid arguments");
- Report.Error (1503, loc,
- "Argument " + (j+1) +
- ": Cannot convert from '" + Argument.FullDesc (a)
- + "' to '" + pd.ParameterDesc (j) + "'");
- }
-
- return false;
- }
- }
-
- return true;
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- //
- // First, resolve the expression that is used to
- // trigger the invocation
- //
- if (expr is BaseAccess)
- is_base = true;
-
- expr = expr.Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup);
- if (expr == null)
- return null;
-
- if (!(expr is MethodGroupExpr)) {
- Type expr_type = expr.Type;
-
- if (expr_type != null){
- bool IsDelegate = TypeManager.IsDelegateType (expr_type);
- if (IsDelegate)
- return (new DelegateInvocation (
- this.expr, Arguments, loc)).Resolve (ec);
- }
- }
-
- if (!(expr is MethodGroupExpr)){
- expr.Error118 (ResolveFlags.MethodGroup);
- return null;
- }
-
- //
- // Next, evaluate all the expressions in the argument list
- //
- if (Arguments != null){
- foreach (Argument a in Arguments){
- if (!a.Resolve (ec, loc))
- return null;
- }
- }
-
- MethodGroupExpr mg = (MethodGroupExpr) expr;
- method = OverloadResolve (ec, mg, Arguments, loc);
-
- if (method == null){
- Error (-6,
- "Could not find any applicable function for this argument list");
- return null;
- }
-
- MethodInfo mi = method as MethodInfo;
- if (mi != null) {
- type = TypeManager.TypeToCoreType (mi.ReturnType);
- if (!mi.IsStatic && !mg.IsExplicitImpl && (mg.InstanceExpression == null))
- SimpleName.Error_ObjectRefRequired (ec, loc, mi.Name);
- }
-
- if (type.IsPointer){
- if (!ec.InUnsafe){
- UnsafeError (loc);
- return null;
- }
- }
-
- //
- // Only base will allow this invocation to happen.
- //
- if (is_base && method.IsAbstract){
- Report.Error (205, loc, "Cannot call an abstract base member: " +
- FullMethodDesc (method));
- return null;
- }
-
- eclass = ExprClass.Value;
- return this;
- }
-
- // <summary>
- // Emits the list of arguments as an array
- // </summary>
- static void EmitParams (EmitContext ec, int idx, ArrayList arguments)
- {
- ILGenerator ig = ec.ig;
- int count = arguments.Count - idx;
- Argument a = (Argument) arguments [idx];
- Type t = a.Expr.Type;
- string array_type = t.FullName + "[]";
- LocalBuilder array;
-
- array = ig.DeclareLocal (TypeManager.LookupType (array_type));
- IntConstant.EmitInt (ig, count);
- ig.Emit (OpCodes.Newarr, TypeManager.TypeToCoreType (t));
- ig.Emit (OpCodes.Stloc, array);
-
- int top = arguments.Count;
- for (int j = idx; j < top; j++){
- a = (Argument) arguments [j];
-
- ig.Emit (OpCodes.Ldloc, array);
- IntConstant.EmitInt (ig, j - idx);
-
- bool is_stobj;
- OpCode op = ArrayAccess.GetStoreOpcode (t, out is_stobj);
- if (is_stobj)
- ig.Emit (OpCodes.Ldelema, t);
-
- a.Emit (ec);
-
- if (is_stobj)
- ig.Emit (OpCodes.Stobj, t);
- else
- ig.Emit (op);
- }
- ig.Emit (OpCodes.Ldloc, array);
- }
-
- /// <summary>
- /// Emits a list of resolved Arguments that are in the arguments
- /// ArrayList.
- ///
- /// The MethodBase argument might be null if the
- /// emission of the arguments is known not to contain
- /// a `params' field (for example in constructors or other routines
- /// that keep their arguments in this structure)
- /// </summary>
- public static void EmitArguments (EmitContext ec, MethodBase mb, ArrayList arguments)
- {
- ParameterData pd;
- if (mb != null)
- pd = GetParameterData (mb);
- else
- pd = null;
-
- //
- // If we are calling a params method with no arguments, special case it
- //
- if (arguments == null){
- if (pd != null && pd.Count > 0 &&
- pd.ParameterModifier (0) == Parameter.Modifier.PARAMS){
- ILGenerator ig = ec.ig;
-
- IntConstant.EmitInt (ig, 0);
- ig.Emit (OpCodes.Newarr, pd.ParameterType (0).GetElementType ());
- }
-
- return;
- }
-
- int top = arguments.Count;
-
- for (int i = 0; i < top; i++){
- Argument a = (Argument) arguments [i];
-
- if (pd != null){
- if (pd.ParameterModifier (i) == Parameter.Modifier.PARAMS){
- //
- // Special case if we are passing the same data as the
- // params argument, do not put it in an array.
- //
- if (pd.ParameterType (i) == a.Type)
- a.Emit (ec);
- else
- EmitParams (ec, i, arguments);
- return;
- }
- }
-
- a.Emit (ec);
- }
-
- if (pd != null && pd.Count > top &&
- pd.ParameterModifier (top) == Parameter.Modifier.PARAMS){
- ILGenerator ig = ec.ig;
-
- IntConstant.EmitInt (ig, 0);
- ig.Emit (OpCodes.Newarr, pd.ParameterType (top).GetElementType ());
- }
- }
-
- /// <remarks>
- /// is_base tells whether we want to force the use of the `call'
- /// opcode instead of using callvirt. Call is required to call
- /// a specific method, while callvirt will always use the most
- /// recent method in the vtable.
- ///
- /// is_static tells whether this is an invocation on a static method
- ///
- /// instance_expr is an expression that represents the instance
- /// it must be non-null if is_static is false.
- ///
- /// method is the method to invoke.
- ///
- /// Arguments is the list of arguments to pass to the method or constructor.
- /// </remarks>
- public static void EmitCall (EmitContext ec, bool is_base,
- bool is_static, Expression instance_expr,
- MethodBase method, ArrayList Arguments, Location loc)
- {
- ILGenerator ig = ec.ig;
- bool struct_call = false;
-
- Type decl_type = method.DeclaringType;
-
- if (!RootContext.StdLib) {
- // Replace any calls to the system's System.Array type with calls to
- // the newly created one.
- if (method == TypeManager.system_int_array_get_length)
- method = TypeManager.int_array_get_length;
- else if (method == TypeManager.system_int_array_get_rank)
- method = TypeManager.int_array_get_rank;
- else if (method == TypeManager.system_object_array_clone)
- method = TypeManager.object_array_clone;
- else if (method == TypeManager.system_int_array_get_length_int)
- method = TypeManager.int_array_get_length_int;
- else if (method == TypeManager.system_int_array_get_lower_bound_int)
- method = TypeManager.int_array_get_lower_bound_int;
- else if (method == TypeManager.system_int_array_get_upper_bound_int)
- method = TypeManager.int_array_get_upper_bound_int;
- else if (method == TypeManager.system_void_array_copyto_array_int)
- method = TypeManager.void_array_copyto_array_int;
- }
-
- //
- // This checks the `ConditionalAttribute' on the method, and the
- // ObsoleteAttribute
- //
- TypeManager.MethodFlags flags = TypeManager.GetMethodFlags (method, loc);
- if ((flags & TypeManager.MethodFlags.IsObsoleteError) != 0)
- return;
- if ((flags & TypeManager.MethodFlags.ShouldIgnore) != 0)
- return;
-
- if (!is_static){
- if (decl_type.IsValueType)
- struct_call = true;
- //
- // If this is ourselves, push "this"
- //
- if (instance_expr == null){
- ig.Emit (OpCodes.Ldarg_0);
- } else {
- //
- // Push the instance expression
- //
- if (instance_expr.Type.IsValueType){
- //
- // Special case: calls to a function declared in a
- // reference-type with a value-type argument need
- // to have their value boxed.
-
- struct_call = true;
- if (decl_type.IsValueType){
- //
- // If the expression implements IMemoryLocation, then
- // we can optimize and use AddressOf on the
- // return.
- //
- // If not we have to use some temporary storage for
- // it.
- if (instance_expr is IMemoryLocation){
- ((IMemoryLocation)instance_expr).
- AddressOf (ec, AddressOp.LoadStore);
- }
- else {
- Type t = instance_expr.Type;
-
- instance_expr.Emit (ec);
- LocalBuilder temp = ig.DeclareLocal (t);
- ig.Emit (OpCodes.Stloc, temp);
- ig.Emit (OpCodes.Ldloca, temp);
- }
- } else {
- instance_expr.Emit (ec);
- ig.Emit (OpCodes.Box, instance_expr.Type);
- }
- } else
- instance_expr.Emit (ec);
- }
- }
-
- EmitArguments (ec, method, Arguments);
-
- if (is_static || struct_call || is_base){
- if (method is MethodInfo) {
- ig.Emit (OpCodes.Call, (MethodInfo) method);
- } else
- ig.Emit (OpCodes.Call, (ConstructorInfo) method);
- } else {
- if (method is MethodInfo)
- ig.Emit (OpCodes.Callvirt, (MethodInfo) method);
- else
- ig.Emit (OpCodes.Callvirt, (ConstructorInfo) method);
- }
- }
-
- public override void Emit (EmitContext ec)
- {
- MethodGroupExpr mg = (MethodGroupExpr) this.expr;
-
- EmitCall (
- ec, is_base, method.IsStatic, mg.InstanceExpression, method, Arguments, loc);
- }
-
- public override void EmitStatement (EmitContext ec)
- {
- Emit (ec);
-
- //
- // Pop the return value if there is one
- //
- if (method is MethodInfo){
- Type ret = ((MethodInfo)method).ReturnType;
- if (TypeManager.TypeToCoreType (ret) != TypeManager.void_type)
- ec.ig.Emit (OpCodes.Pop);
- }
- }
- }
-
- //
- // This class is used to "disable" the code generation for the
- // temporary variable when initializing value types.
- //
- class EmptyAddressOf : EmptyExpression, IMemoryLocation {
- public void AddressOf (EmitContext ec, AddressOp Mode)
- {
- // nothing
- }
- }
-
- /// <summary>
- /// Implements the new expression
- /// </summary>
- public class New : ExpressionStatement {
- public readonly ArrayList Arguments;
- public readonly Expression RequestedType;
-
- MethodBase method = null;
-
- //
- // If set, the new expression is for a value_target, and
- // we will not leave anything on the stack.
- //
- Expression value_target;
- bool value_target_set = false;
-
- public New (Expression requested_type, ArrayList arguments, Location l)
- {
- RequestedType = requested_type;
- Arguments = arguments;
- loc = l;
- }
-
- public Expression ValueTypeVariable {
- get {
- return value_target;
- }
-
- set {
- value_target = value;
- value_target_set = true;
- }
- }
-
- //
- // This function is used to disable the following code sequence for
- // value type initialization:
- //
- // AddressOf (temporary)
- // Construct/Init
- // LoadTemporary
- //
- // Instead the provide will have provided us with the address on the
- // stack to store the results.
- //
- static Expression MyEmptyExpression;
-
- public void DisableTemporaryValueType ()
- {
- if (MyEmptyExpression == null)
- MyEmptyExpression = new EmptyAddressOf ();
-
- //
- // To enable this, look into:
- // test-34 and test-89 and self bootstrapping.
- //
- // For instance, we can avoid a copy by using `newobj'
- // instead of Call + Push-temp on value types.
-// value_target = MyEmptyExpression;
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- type = ec.DeclSpace.ResolveType (RequestedType, false, loc);
-
- if (type == null)
- return null;
-
- bool IsDelegate = TypeManager.IsDelegateType (type);
-
- if (IsDelegate)
- return (new NewDelegate (type, Arguments, loc)).Resolve (ec);
-
- if (type.IsInterface || type.IsAbstract){
- Error (
- 144, "It is not possible to create instances of interfaces " +
- "or abstract classes");
- return null;
- }
-
- bool is_struct = false;
- is_struct = type.IsValueType;
- eclass = ExprClass.Value;
-
- //
- // SRE returns a match for .ctor () on structs (the object constructor),
- // so we have to manually ignore it.
- //
- if (is_struct && Arguments == null)
- return this;
-
- Expression ml;
- ml = MemberLookupFinal (ec, null, type, ".ctor",
- MemberTypes.Constructor,
- AllBindingFlags | BindingFlags.DeclaredOnly, loc);
-
- if (ml == null)
- return null;
-
- if (! (ml is MethodGroupExpr)){
- if (!is_struct){
- ml.Error118 ("method group");
- return null;
- }
- }
-
- if (ml != null) {
- if (Arguments != null){
- foreach (Argument a in Arguments){
- if (!a.Resolve (ec, loc))
- return null;
- }
- }
-
- method = Invocation.OverloadResolve (ec, (MethodGroupExpr) ml,
- Arguments, loc);
-
- }
-
- if (method == null) {
- if (!is_struct || Arguments.Count > 0) {
- Error (1501,
- "New invocation: Can not find a constructor for " +
- "this argument list");
- return null;
- }
- }
- return this;
- }
-
- //
- // This DoEmit can be invoked in two contexts:
- // * As a mechanism that will leave a value on the stack (new object)
- // * As one that wont (init struct)
- //
- // You can control whether a value is required on the stack by passing
- // need_value_on_stack. The code *might* leave a value on the stack
- // so it must be popped manually
- //
- // If we are dealing with a ValueType, we have a few
- // situations to deal with:
- //
- // * The target is a ValueType, and we have been provided
- // the instance (this is easy, we are being assigned).
- //
- // * The target of New is being passed as an argument,
- // to a boxing operation or a function that takes a
- // ValueType.
- //
- // In this case, we need to create a temporary variable
- // that is the argument of New.
- //
- // Returns whether a value is left on the stack
- //
- bool DoEmit (EmitContext ec, bool need_value_on_stack)
- {
- bool is_value_type = type.IsValueType;
- ILGenerator ig = ec.ig;
-
- if (is_value_type){
- IMemoryLocation ml;
-
- // Allow DoEmit() to be called multiple times.
- // We need to create a new LocalTemporary each time since
- // you can't share LocalBuilders among ILGeneators.
- if (!value_target_set)
- value_target = new LocalTemporary (ec, type);
-
- ml = (IMemoryLocation) value_target;
- ml.AddressOf (ec, AddressOp.Store);
- }
-
- if (method != null)
- Invocation.EmitArguments (ec, method, Arguments);
-
- if (is_value_type){
- if (method == null)
- ig.Emit (OpCodes.Initobj, type);
- else
- ig.Emit (OpCodes.Call, (ConstructorInfo) method);
- if (need_value_on_stack){
- value_target.Emit (ec);
- return true;
- }
- return false;
- } else {
- ig.Emit (OpCodes.Newobj, (ConstructorInfo) method);
- return true;
- }
- }
-
- public override void Emit (EmitContext ec)
- {
- DoEmit (ec, true);
- }
-
- public override void EmitStatement (EmitContext ec)
- {
- if (DoEmit (ec, false))
- ec.ig.Emit (OpCodes.Pop);
- }
- }
-
- /// <summary>
- /// 14.5.10.2: Represents an array creation expression.
- /// </summary>
- ///
- /// <remarks>
- /// There are two possible scenarios here: one is an array creation
- /// expression that specifies the dimensions and optionally the
- /// initialization data and the other which does not need dimensions
- /// specified but where initialization data is mandatory.
- /// </remarks>
- public class ArrayCreation : ExpressionStatement {
- Expression requested_base_type;
- ArrayList initializers;
-
- //
- // The list of Argument types.
- // This is used to construct the `newarray' or constructor signature
- //
- ArrayList arguments;
-
- //
- // Method used to create the array object.
- //
- MethodBase new_method = null;
-
- Type array_element_type;
- Type underlying_type;
- bool is_one_dimensional = false;
- bool is_builtin_type = false;
- bool expect_initializers = false;
- int num_arguments = 0;
- int dimensions = 0;
- string rank;
-
- ArrayList array_data;
-
- Hashtable bounds;
-
- //
- // The number of array initializers that we can handle
- // via the InitializeArray method - through EmitStaticInitializers
- //
- int num_automatic_initializers;
-
- const int max_automatic_initializers = 6;
-
- public ArrayCreation (Expression requested_base_type, ArrayList exprs, string rank, ArrayList initializers, Location l)
- {
- this.requested_base_type = requested_base_type;
- this.initializers = initializers;
- this.rank = rank;
- loc = l;
-
- arguments = new ArrayList ();
-
- foreach (Expression e in exprs) {
- arguments.Add (new Argument (e, Argument.AType.Expression));
- num_arguments++;
- }
- }
-
- public ArrayCreation (Expression requested_base_type, string rank, ArrayList initializers, Location l)
- {
- this.requested_base_type = requested_base_type;
- this.initializers = initializers;
- this.rank = rank;
- loc = l;
-
- //this.rank = rank.Substring (0, rank.LastIndexOf ("["));
- //
- //string tmp = rank.Substring (rank.LastIndexOf ("["));
- //
- //dimensions = tmp.Length - 1;
- expect_initializers = true;
- }
-
- public Expression FormArrayType (Expression base_type, int idx_count, string rank)
- {
- StringBuilder sb = new StringBuilder (rank);
-
- sb.Append ("[");
- for (int i = 1; i < idx_count; i++)
- sb.Append (",");
-
- sb.Append ("]");
-
- return new ComposedCast (base_type, sb.ToString (), loc);
- }
-
- void Error_IncorrectArrayInitializer ()
- {
- Error (178, "Incorrectly structured array initializer");
- }
-
- public bool CheckIndices (EmitContext ec, ArrayList probe, int idx, bool specified_dims)
- {
- if (specified_dims) {
- Argument a = (Argument) arguments [idx];
-
- if (!a.Resolve (ec, loc))
- return false;
-
- if (!(a.Expr is Constant)) {
- Error (150, "A constant value is expected");
- return false;
- }
-
- int value = (int) ((Constant) a.Expr).GetValue ();
-
- if (value != probe.Count) {
- Error_IncorrectArrayInitializer ();
- return false;
- }
-
- bounds [idx] = value;
- }
-
- int child_bounds = -1;
- foreach (object o in probe) {
- if (o is ArrayList) {
- int current_bounds = ((ArrayList) o).Count;
-
- if (child_bounds == -1)
- child_bounds = current_bounds;
-
- else if (child_bounds != current_bounds){
- Error_IncorrectArrayInitializer ();
- return false;
- }
- bool ret = CheckIndices (ec, (ArrayList) o, idx + 1, specified_dims);
- if (!ret)
- return false;
- } else {
- if (child_bounds != -1){
- Error_IncorrectArrayInitializer ();
- return false;
- }
-
- Expression tmp = (Expression) o;
- tmp = tmp.Resolve (ec);
- if (tmp == null)
- continue;
-
- // Console.WriteLine ("I got: " + tmp);
- // Handle initialization from vars, fields etc.
-
- Expression conv = ConvertImplicitRequired (
- ec, tmp, underlying_type, loc);
-
- if (conv == null)
- return false;
-
- if (conv is StringConstant)
- array_data.Add (conv);
- else if (conv is Constant) {
- array_data.Add (conv);
- num_automatic_initializers++;
- } else
- array_data.Add (conv);
- }
- }
-
- return true;
- }
-
- public void UpdateIndices (EmitContext ec)
- {
- int i = 0;
- for (ArrayList probe = initializers; probe != null;) {
- if (probe.Count > 0 && probe [0] is ArrayList) {
- Expression e = new IntConstant (probe.Count);
- arguments.Add (new Argument (e, Argument.AType.Expression));
-
- bounds [i++] = probe.Count;
-
- probe = (ArrayList) probe [0];
-
- } else {
- Expression e = new IntConstant (probe.Count);
- arguments.Add (new Argument (e, Argument.AType.Expression));
-
- bounds [i++] = probe.Count;
- probe = null;
- }
- }
-
- }
-
- public bool ValidateInitializers (EmitContext ec, Type array_type)
- {
- if (initializers == null) {
- if (expect_initializers)
- return false;
- else
- return true;
- }
-
- if (underlying_type == null)
- return false;
-
- //
- // We use this to store all the date values in the order in which we
- // will need to store them in the byte blob later
- //
- array_data = new ArrayList ();
- bounds = new Hashtable ();
-
- bool ret;
-
- if (arguments != null) {
- ret = CheckIndices (ec, initializers, 0, true);
- return ret;
- } else {
- arguments = new ArrayList ();
-
- ret = CheckIndices (ec, initializers, 0, false);
-
- if (!ret)
- return false;
-
- UpdateIndices (ec);
-
- if (arguments.Count != dimensions) {
- Error_IncorrectArrayInitializer ();
- return false;
- }
-
- return ret;
- }
- }
-
- void Error_NegativeArrayIndex ()
- {
- Error (284, "Can not create array with a negative size");
- }
-
- //
- // Converts `source' to an int, uint, long or ulong.
- //
- Expression ExpressionToArrayArgument (EmitContext ec, Expression source)
- {
- Expression target;
-
- bool old_checked = ec.CheckState;
- ec.CheckState = true;
-
- target = ConvertImplicit (ec, source, TypeManager.int32_type, loc);
- if (target == null){
- target = ConvertImplicit (ec, source, TypeManager.uint32_type, loc);
- if (target == null){
- target = ConvertImplicit (ec, source, TypeManager.int64_type, loc);
- if (target == null){
- target = ConvertImplicit (ec, source, TypeManager.uint64_type, loc);
- if (target == null)
- Expression.Error_CannotConvertImplicit (loc, source.Type, TypeManager.int32_type);
- }
- }
- }
- ec.CheckState = old_checked;
-
- //
- // Only positive constants are allowed at compile time
- //
- if (target is Constant){
- if (target is IntConstant){
- if (((IntConstant) target).Value < 0){
- Error_NegativeArrayIndex ();
- return null;
- }
- }
-
- if (target is LongConstant){
- if (((LongConstant) target).Value < 0){
- Error_NegativeArrayIndex ();
- return null;
- }
- }
-
- }
-
- return target;
- }
-
- //
- // Creates the type of the array
- //
- bool LookupType (EmitContext ec)
- {
- StringBuilder array_qualifier = new StringBuilder (rank);
-
- //
- // `In the first form allocates an array instace of the type that results
- // from deleting each of the individual expression from the expression list'
- //
- if (num_arguments > 0) {
- array_qualifier.Append ("[");
- for (int i = num_arguments-1; i > 0; i--)
- array_qualifier.Append (",");
- array_qualifier.Append ("]");
- }
-
- //
- // Lookup the type
- //
- Expression array_type_expr;
- array_type_expr = new ComposedCast (requested_base_type, array_qualifier.ToString (), loc);
- type = ec.DeclSpace.ResolveType (array_type_expr, false, loc);
-
- if (type == null)
- return false;
-
- underlying_type = type;
- if (underlying_type.IsArray)
- underlying_type = TypeManager.TypeToCoreType (underlying_type.GetElementType ());
- dimensions = type.GetArrayRank ();
-
- return true;
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- int arg_count;
-
- if (!LookupType (ec))
- return null;
-
- //
- // First step is to validate the initializers and fill
- // in any missing bits
- //
- if (!ValidateInitializers (ec, type))
- return null;
-
- if (arguments == null)
- arg_count = 0;
- else {
- arg_count = arguments.Count;
- foreach (Argument a in arguments){
- if (!a.Resolve (ec, loc))
- return null;
-
- Expression real_arg = ExpressionToArrayArgument (ec, a.Expr, loc);
- if (real_arg == null)
- return null;
-
- a.Expr = real_arg;
- }
- }
-
- array_element_type = TypeManager.TypeToCoreType (type.GetElementType ());
-
- if (arg_count == 1) {
- is_one_dimensional = true;
- eclass = ExprClass.Value;
- return this;
- }
-
- is_builtin_type = TypeManager.IsBuiltinType (type);
-
- if (is_builtin_type) {
- Expression ml;
-
- ml = MemberLookup (ec, type, ".ctor", MemberTypes.Constructor,
- AllBindingFlags, loc);
-
- if (!(ml is MethodGroupExpr)) {
- ml.Error118 ("method group");
- return null;
- }
-
- if (ml == null) {
- Error (-6, "New invocation: Can not find a constructor for " +
- "this argument list");
- return null;
- }
-
- new_method = Invocation.OverloadResolve (ec, (MethodGroupExpr) ml, arguments, loc);
-
- if (new_method == null) {
- Error (-6, "New invocation: Can not find a constructor for " +
- "this argument list");
- return null;
- }
-
- eclass = ExprClass.Value;
- return this;
- } else {
- ModuleBuilder mb = CodeGen.ModuleBuilder;
- ArrayList args = new ArrayList ();
-
- if (arguments != null) {
- for (int i = 0; i < arg_count; i++)
- args.Add (TypeManager.int32_type);
- }
-
- Type [] arg_types = null;
-
- if (args.Count > 0)
- arg_types = new Type [args.Count];
-
- args.CopyTo (arg_types, 0);
-
- new_method = mb.GetArrayMethod (type, ".ctor", CallingConventions.HasThis, null,
- arg_types);
-
- if (new_method == null) {
- Error (-6, "New invocation: Can not find a constructor for " +
- "this argument list");
- return null;
- }
-
- eclass = ExprClass.Value;
- return this;
- }
- }
-
- public static byte [] MakeByteBlob (ArrayList array_data, Type underlying_type, Location loc)
- {
- int factor;
- byte [] data;
- byte [] element;
- int count = array_data.Count;
-
- if (underlying_type.IsEnum)
- underlying_type = TypeManager.EnumToUnderlying (underlying_type);
-
- factor = GetTypeSize (underlying_type);
- if (factor == 0)
- throw new Exception ("unrecognized type in MakeByteBlob: " + underlying_type);
-
- data = new byte [(count * factor + 4) & ~3];
- int idx = 0;
-
- for (int i = 0; i < count; ++i) {
- object v = array_data [i];
-
- if (v is EnumConstant)
- v = ((EnumConstant) v).Child;
-
- if (v is Constant && !(v is StringConstant))
- v = ((Constant) v).GetValue ();
- else {
- idx += factor;
- continue;
- }
-
- if (underlying_type == TypeManager.int64_type){
- if (!(v is Expression)){
- long val = (long) v;
-
- for (int j = 0; j < factor; ++j) {
- data [idx + j] = (byte) (val & 0xFF);
- val = (val >> 8);
- }
- }
- } else if (underlying_type == TypeManager.uint64_type){
- if (!(v is Expression)){
- ulong val = (ulong) v;
-
- for (int j = 0; j < factor; ++j) {
- data [idx + j] = (byte) (val & 0xFF);
- val = (val >> 8);
- }
- }
- } else if (underlying_type == TypeManager.float_type) {
- if (!(v is Expression)){
- element = BitConverter.GetBytes ((float) v);
-
- for (int j = 0; j < factor; ++j)
- data [idx + j] = element [j];
- }
- } else if (underlying_type == TypeManager.double_type) {
- if (!(v is Expression)){
- element = BitConverter.GetBytes ((double) v);
-
- for (int j = 0; j < factor; ++j)
- data [idx + j] = element [j];
- }
- } else if (underlying_type == TypeManager.char_type){
- if (!(v is Expression)){
- int val = (int) ((char) v);
-
- data [idx] = (byte) (val & 0xff);
- data [idx+1] = (byte) (val >> 8);
- }
- } else if (underlying_type == TypeManager.short_type){
- if (!(v is Expression)){
- int val = (int) ((short) v);
-
- data [idx] = (byte) (val & 0xff);
- data [idx+1] = (byte) (val >> 8);
- }
- } else if (underlying_type == TypeManager.ushort_type){
- if (!(v is Expression)){
- int val = (int) ((ushort) v);
-
- data [idx] = (byte) (val & 0xff);
- data [idx+1] = (byte) (val >> 8);
- }
- } else if (underlying_type == TypeManager.int32_type) {
- if (!(v is Expression)){
- int val = (int) v;
-
- data [idx] = (byte) (val & 0xff);
- data [idx+1] = (byte) ((val >> 8) & 0xff);
- data [idx+2] = (byte) ((val >> 16) & 0xff);
- data [idx+3] = (byte) (val >> 24);
- }
- } else if (underlying_type == TypeManager.uint32_type) {
- if (!(v is Expression)){
- uint val = (uint) v;
-
- data [idx] = (byte) (val & 0xff);
- data [idx+1] = (byte) ((val >> 8) & 0xff);
- data [idx+2] = (byte) ((val >> 16) & 0xff);
- data [idx+3] = (byte) (val >> 24);
- }
- } else if (underlying_type == TypeManager.sbyte_type) {
- if (!(v is Expression)){
- sbyte val = (sbyte) v;
- data [idx] = (byte) val;
- }
- } else if (underlying_type == TypeManager.byte_type) {
- if (!(v is Expression)){
- byte val = (byte) v;
- data [idx] = (byte) val;
- }
- } else if (underlying_type == TypeManager.bool_type) {
- if (!(v is Expression)){
- bool val = (bool) v;
- data [idx] = (byte) (val ? 1 : 0);
- }
- } else if (underlying_type == TypeManager.decimal_type){
- if (!(v is Expression)){
- int [] bits = Decimal.GetBits ((decimal) v);
- int p = idx;
-
- for (int j = 0; j < 4; j++){
- data [p++] = (byte) (bits [j] & 0xff);
- data [p++] = (byte) ((bits [j] >> 8) & 0xff);
- data [p++] = (byte) ((bits [j] >> 16) & 0xff);
- data [p++] = (byte) (bits [j] >> 24);
- }
- }
- } else
- throw new Exception ("Unrecognized type in MakeByteBlob: " + underlying_type);
-
- idx += factor;
- }
-
- return data;
- }
-
- //
- // Emits the initializers for the array
- //
- void EmitStaticInitializers (EmitContext ec, bool is_expression)
- {
- //
- // First, the static data
- //
- FieldBuilder fb;
- ILGenerator ig = ec.ig;
-
- byte [] data = MakeByteBlob (array_data, underlying_type, loc);
-
- fb = RootContext.MakeStaticData (data);
-
- if (is_expression)
- ig.Emit (OpCodes.Dup);
- ig.Emit (OpCodes.Ldtoken, fb);
- ig.Emit (OpCodes.Call,
- TypeManager.void_initializearray_array_fieldhandle);
- }
-
- //
- // Emits pieces of the array that can not be computed at compile
- // time (variables and string locations).
- //
- // This always expect the top value on the stack to be the array
- //
- void EmitDynamicInitializers (EmitContext ec, bool is_expression)
- {
- ILGenerator ig = ec.ig;
- int dims = bounds.Count;
- int [] current_pos = new int [dims];
- int top = array_data.Count;
- LocalBuilder temp = ig.DeclareLocal (type);
-
- ig.Emit (OpCodes.Stloc, temp);
-
- MethodInfo set = null;
-
- if (dims != 1){
- Type [] args;
- ModuleBuilder mb = null;
- mb = CodeGen.ModuleBuilder;
- args = new Type [dims + 1];
-
- int j;
- for (j = 0; j < dims; j++)
- args [j] = TypeManager.int32_type;
-
- args [j] = array_element_type;
-
- set = mb.GetArrayMethod (
- type, "Set",
- CallingConventions.HasThis | CallingConventions.Standard,
- TypeManager.void_type, args);
- }
-
- for (int i = 0; i < top; i++){
-
- Expression e = null;
-
- if (array_data [i] is Expression)
- e = (Expression) array_data [i];
-
- if (e != null) {
- //
- // Basically we do this for string literals and
- // other non-literal expressions
- //
- if (e is EnumConstant){
- e = ((EnumConstant) e).Child;
- }
-
- if (e is StringConstant || !(e is Constant) ||
- num_automatic_initializers <= max_automatic_initializers) {
- Type etype = e.Type;
-
- ig.Emit (OpCodes.Ldloc, temp);
-
- for (int idx = 0; idx < dims; idx++)
- IntConstant.EmitInt (ig, current_pos [idx]);
-
- //
- // If we are dealing with a struct, get the
- // address of it, so we can store it.
- //
- if ((dims == 1) &&
- etype.IsSubclassOf (TypeManager.value_type) &&
- (!TypeManager.IsBuiltinType (etype) ||
- etype == TypeManager.decimal_type)) {
- if (e is New){
- New n = (New) e;
-
- //
- // Let new know that we are providing
- // the address where to store the results
- //
- n.DisableTemporaryValueType ();
- }
-
- ig.Emit (OpCodes.Ldelema, etype);
- }
-
- e.Emit (ec);
-
- if (dims == 1)
- ArrayAccess.EmitStoreOpcode (ig, array_element_type);
- else
- ig.Emit (OpCodes.Call, set);
- }
- }
-
- //
- // Advance counter
- //
- for (int j = dims - 1; j >= 0; j--){
- current_pos [j]++;
- if (current_pos [j] < (int) bounds [j])
- break;
- current_pos [j] = 0;
- }
- }
-
- if (is_expression)
- ig.Emit (OpCodes.Ldloc, temp);
- }
-
- void EmitArrayArguments (EmitContext ec)
- {
- ILGenerator ig = ec.ig;
-
- foreach (Argument a in arguments) {
- Type atype = a.Type;
- a.Emit (ec);
-
- if (atype == TypeManager.uint64_type)
- ig.Emit (OpCodes.Conv_Ovf_U4);
- else if (atype == TypeManager.int64_type)
- ig.Emit (OpCodes.Conv_Ovf_I4);
- }
- }
-
- void DoEmit (EmitContext ec, bool is_statement)
- {
- ILGenerator ig = ec.ig;
-
- EmitArrayArguments (ec);
- if (is_one_dimensional)
- ig.Emit (OpCodes.Newarr, array_element_type);
- else {
- if (is_builtin_type)
- ig.Emit (OpCodes.Newobj, (ConstructorInfo) new_method);
- else
- ig.Emit (OpCodes.Newobj, (MethodInfo) new_method);
- }
-
- if (initializers != null){
- //
- // FIXME: Set this variable correctly.
- //
- bool dynamic_initializers = true;
-
- if (underlying_type != TypeManager.string_type &&
- underlying_type != TypeManager.object_type) {
- if (num_automatic_initializers > max_automatic_initializers)
- EmitStaticInitializers (ec, dynamic_initializers || !is_statement);
- }
-
- if (dynamic_initializers)
- EmitDynamicInitializers (ec, !is_statement);
- }
- }
-
- public override void Emit (EmitContext ec)
- {
- DoEmit (ec, false);
- }
-
- public override void EmitStatement (EmitContext ec)
- {
- DoEmit (ec, true);
- }
-
- }
-
- /// <summary>
- /// Represents the `this' construct
- /// </summary>
- public class This : Expression, IAssignMethod, IMemoryLocation, IVariable {
-
- Block block;
- VariableInfo vi;
-
- public This (Block block, Location loc)
- {
- this.loc = loc;
- this.block = block;
- }
-
- public This (Location loc)
- {
- this.loc = loc;
- }
-
- public bool IsAssigned (EmitContext ec, Location loc)
- {
- if (vi == null)
- return true;
-
- return vi.IsAssigned (ec, loc);
- }
-
- public bool IsFieldAssigned (EmitContext ec, string field_name, Location loc)
- {
- if (vi == null)
- return true;
-
- return vi.IsFieldAssigned (ec, field_name, loc);
- }
-
- public void SetAssigned (EmitContext ec)
- {
- if (vi != null)
- vi.SetAssigned (ec);
- }
-
- public void SetFieldAssigned (EmitContext ec, string field_name)
- {
- if (vi != null)
- vi.SetFieldAssigned (ec, field_name);
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- eclass = ExprClass.Variable;
- type = ec.ContainerType;
-
- if (ec.IsStatic){
- Error (26, "Keyword this not valid in static code");
- return null;
- }
-
- if (block != null)
- vi = block.ThisVariable;
-
- return this;
- }
-
- override public Expression DoResolveLValue (EmitContext ec, Expression right_side)
- {
- DoResolve (ec);
-
- VariableInfo vi = ec.CurrentBlock.ThisVariable;
- if (vi != null)
- vi.SetAssigned (ec);
-
- if (ec.TypeContainer is Class){
- Error (1604, "Cannot assign to `this'");
- return null;
- }
-
- return this;
- }
-
- public override void Emit (EmitContext ec)
- {
- ILGenerator ig = ec.ig;
-
- ig.Emit (OpCodes.Ldarg_0);
- if (ec.TypeContainer is Struct)
- ig.Emit (OpCodes.Ldobj, type);
- }
-
- public void EmitAssign (EmitContext ec, Expression source)
- {
- ILGenerator ig = ec.ig;
-
- if (ec.TypeContainer is Struct){
- ig.Emit (OpCodes.Ldarg_0);
- source.Emit (ec);
- ig.Emit (OpCodes.Stobj, type);
- } else {
- source.Emit (ec);
- ig.Emit (OpCodes.Starg, 0);
- }
- }
-
- public void AddressOf (EmitContext ec, AddressOp mode)
- {
- ec.ig.Emit (OpCodes.Ldarg_0);
-
- // FIMXE
- // FIGURE OUT WHY LDARG_S does not work
- //
- // consider: struct X { int val; int P { set { val = value; }}}
- //
- // Yes, this looks very bad. Look at `NOTAS' for
- // an explanation.
- // ec.ig.Emit (OpCodes.Ldarga_S, (byte) 0);
- }
- }
-
- /// <summary>
- /// Implements the typeof operator
- /// </summary>
- public class TypeOf : Expression {
- public readonly Expression QueriedType;
- Type typearg;
-
- public TypeOf (Expression queried_type, Location l)
- {
- QueriedType = queried_type;
- loc = l;
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- typearg = ec.DeclSpace.ResolveType (QueriedType, false, loc);
-
- if (typearg == null)
- return null;
-
- type = TypeManager.type_type;
- eclass = ExprClass.Type;
- return this;
- }
-
- public override void Emit (EmitContext ec)
- {
- ec.ig.Emit (OpCodes.Ldtoken, typearg);
- ec.ig.Emit (OpCodes.Call, TypeManager.system_type_get_type_from_handle);
- }
-
- public Type TypeArg {
- get { return typearg; }
- }
- }
-
- /// <summary>
- /// Implements the sizeof expression
- /// </summary>
- public class SizeOf : Expression {
- public readonly Expression QueriedType;
- Type type_queried;
-
- public SizeOf (Expression queried_type, Location l)
- {
- this.QueriedType = queried_type;
- loc = l;
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- if (!ec.InUnsafe) {
- Error (233, "Sizeof may only be used in an unsafe context " +
- "(consider using System.Runtime.InteropServices.Marshal.Sizeof");
- return null;
- }
-
- type_queried = ec.DeclSpace.ResolveType (QueriedType, false, loc);
- if (type_queried == null)
- return null;
-
- if (!TypeManager.IsUnmanagedType (type_queried)){
- Report.Error (208, "Cannot take the size of an unmanaged type (" + TypeManager.CSharpName (type_queried) + ")");
- return null;
- }
-
- type = TypeManager.int32_type;
- eclass = ExprClass.Value;
- return this;
- }
-
- public override void Emit (EmitContext ec)
- {
- int size = GetTypeSize (type_queried);
-
- if (size == 0)
- ec.ig.Emit (OpCodes.Sizeof, type_queried);
- else
- IntConstant.EmitInt (ec.ig, size);
- }
- }
-
- /// <summary>
- /// Implements the member access expression
- /// </summary>
- public class MemberAccess : Expression, ITypeExpression {
- public readonly string Identifier;
- Expression expr;
- Expression member_lookup;
-
- public MemberAccess (Expression expr, string id, Location l)
- {
- this.expr = expr;
- Identifier = id;
- loc = l;
- }
-
- public Expression Expr {
- get {
- return expr;
- }
- }
-
- static void error176 (Location loc, string name)
- {
- Report.Error (176, loc, "Static member `" +
- name + "' cannot be accessed " +
- "with an instance reference, qualify with a " +
- "type name instead");
- }
-
- static bool IdenticalNameAndTypeName (EmitContext ec, Expression left_original, Location loc)
- {
- if (left_original == null)
- return false;
-
- if (!(left_original is SimpleName))
- return false;
-
- SimpleName sn = (SimpleName) left_original;
-
- Type t = RootContext.LookupType (ec.DeclSpace, sn.Name, true, loc);
- if (t != null)
- return true;
-
- return false;
- }
-
- public static Expression ResolveMemberAccess (EmitContext ec, Expression member_lookup,
- Expression left, Location loc,
- Expression left_original)
- {
- bool left_is_type, left_is_explicit;
-
- // If `left' is null, then we're called from SimpleNameResolve and this is
- // a member in the currently defining class.
- if (left == null) {
- left_is_type = ec.IsStatic || ec.IsFieldInitializer;
- left_is_explicit = false;
-
- // Implicitly default to `this' unless we're static.
- if (!ec.IsStatic && !ec.IsFieldInitializer && !ec.InEnumContext)
- left = ec.This;
- } else {
- left_is_type = left is TypeExpr;
- left_is_explicit = true;
- }
-
- if (member_lookup is FieldExpr){
- FieldExpr fe = (FieldExpr) member_lookup;
- FieldInfo fi = fe.FieldInfo;
- Type decl_type = fi.DeclaringType;
-
- if (fi is FieldBuilder) {
- Const c = TypeManager.LookupConstant ((FieldBuilder) fi);
-
- if (c != null) {
- object o = c.LookupConstantValue (ec);
- object real_value = ((Constant) c.Expr).GetValue ();
-
- return Constantify (real_value, fi.FieldType);
- }
- }
-
- if (fi.IsLiteral) {
- Type t = fi.FieldType;
-
- object o;
-
- if (fi is FieldBuilder)
- o = TypeManager.GetValue ((FieldBuilder) fi);
- else
- o = fi.GetValue (fi);
-
- if (decl_type.IsSubclassOf (TypeManager.enum_type)) {
- if (left_is_explicit && !left_is_type &&
- !IdenticalNameAndTypeName (ec, left_original, loc)) {
- error176 (loc, fe.FieldInfo.Name);
- return null;
- }
-
- Expression enum_member = MemberLookup (
- ec, decl_type, "value__", MemberTypes.Field,
- AllBindingFlags, loc);
-
- Enum en = TypeManager.LookupEnum (decl_type);
-
- Constant c;
- if (en != null)
- c = Constantify (o, en.UnderlyingType);
- else
- c = Constantify (o, enum_member.Type);
-
- return new EnumConstant (c, decl_type);
- }
-
- Expression exp = Constantify (o, t);
-
- if (left_is_explicit && !left_is_type) {
- error176 (loc, fe.FieldInfo.Name);
- return null;
- }
-
- return exp;
- }
-
- if (fi.FieldType.IsPointer && !ec.InUnsafe){
- UnsafeError (loc);
- return null;
- }
- }
-
- if (member_lookup is EventExpr) {
-
- EventExpr ee = (EventExpr) member_lookup;
-
- //
- // If the event is local to this class, we transform ourselves into
- // a FieldExpr
- //
-
- if (ee.EventInfo.DeclaringType == ec.ContainerType) {
- MemberInfo mi = GetFieldFromEvent (ee);
-
- if (mi == null) {
- //
- // If this happens, then we have an event with its own
- // accessors and private field etc so there's no need
- // to transform ourselves : we should instead flag an error
- //
- Assign.error70 (ee.EventInfo, loc);
- return null;
- }
-
- Expression ml = ExprClassFromMemberInfo (ec, mi, loc);
-
- if (ml == null) {
- Report.Error (-200, loc, "Internal error!!");
- return null;
- }
-
- return ResolveMemberAccess (ec, ml, left, loc, left_original);
- }
- }
-
- if (member_lookup is IMemberExpr) {
- IMemberExpr me = (IMemberExpr) member_lookup;
-
- if (left_is_type){
- MethodGroupExpr mg = me as MethodGroupExpr;
- if ((mg != null) && left_is_explicit && left.Type.IsInterface)
- mg.IsExplicitImpl = left_is_explicit;
-
- if (!me.IsStatic){
- if (IdenticalNameAndTypeName (ec, left_original, loc))
- return member_lookup;
-
- SimpleName.Error_ObjectRefRequired (ec, loc, me.Name);
- return null;
- }
-
- } else {
- if (!me.IsInstance){
- if (IdenticalNameAndTypeName (ec, left_original, loc))
- return member_lookup;
-
- if (left_is_explicit) {
- error176 (loc, me.Name);
- return null;
- }
- }
-
- //
- // Since we can not check for instance objects in SimpleName,
- // becaue of the rule that allows types and variables to share
- // the name (as long as they can be de-ambiguated later, see
- // IdenticalNameAndTypeName), we have to check whether left
- // is an instance variable in a static context
- //
- // However, if the left-hand value is explicitly given, then
- // it is already our instance expression, so we aren't in
- // static context.
- //
-
- if (ec.IsStatic && !left_is_explicit && left is IMemberExpr){
- IMemberExpr mexp = (IMemberExpr) left;
-
- if (!mexp.IsStatic){
- SimpleName.Error_ObjectRefRequired (ec, loc, mexp.Name);
- return null;
- }
- }
-
- me.InstanceExpression = left;
- }
-
- return member_lookup;
- }
-
- if (member_lookup is TypeExpr){
- member_lookup.Resolve (ec, ResolveFlags.Type);
- return member_lookup;
- }
-
- Console.WriteLine ("Left is: " + left);
- Report.Error (-100, loc, "Support for [" + member_lookup + "] is not present yet");
- Environment.Exit (0);
- return null;
- }
-
- public Expression DoResolve (EmitContext ec, Expression right_side, ResolveFlags flags)
- {
- if (type != null)
- throw new Exception ();
- //
- // Resolve the expression with flow analysis turned off, we'll do the definite
- // assignment checks later. This is because we don't know yet what the expression
- // will resolve to - it may resolve to a FieldExpr and in this case we must do the
- // definite assignment check on the actual field and not on the whole struct.
- //
-
- Expression original = expr;
- expr = expr.Resolve (ec, flags | ResolveFlags.DisableFlowAnalysis);
-
- if (expr == null)
- return null;
-
- if (expr is SimpleName){
- SimpleName child_expr = (SimpleName) expr;
-
- Expression new_expr = new SimpleName (child_expr.Name, Identifier, loc);
-
- return new_expr.Resolve (ec, flags);
- }
-
- //
- // TODO: I mailed Ravi about this, and apparently we can get rid
- // of this and put it in the right place.
- //
- // Handle enums here when they are in transit.
- // Note that we cannot afford to hit MemberLookup in this case because
- // it will fail to find any members at all
- //
-
- int errors = Report.Errors;
-
- Type expr_type = expr.Type;
- if ((expr is TypeExpr) && (expr_type.IsSubclassOf (TypeManager.enum_type))){
-
- Enum en = TypeManager.LookupEnum (expr_type);
-
- if (en != null) {
- object value = en.LookupEnumValue (ec, Identifier, loc);
-
- if (value != null){
- Constant c = Constantify (value, en.UnderlyingType);
- return new EnumConstant (c, expr_type);
- }
- }
- }
-
- if (expr_type.IsPointer){
- Error (23, "The `.' operator can not be applied to pointer operands (" +
- TypeManager.CSharpName (expr_type) + ")");
- return null;
- }
-
- member_lookup = MemberLookupFinal (ec, expr_type, expr_type, Identifier, loc);
- if (member_lookup == null)
- return null;
-
- if (member_lookup is TypeExpr){
- member_lookup.Resolve (ec, ResolveFlags.Type);
- return member_lookup;
- } else if ((flags & ResolveFlags.MaskExprClass) == ResolveFlags.Type)
- return null;
-
- member_lookup = ResolveMemberAccess (ec, member_lookup, expr, loc, original);
- if (member_lookup == null)
- return null;
-
- // The following DoResolve/DoResolveLValue will do the definite assignment
- // check.
-
- if (right_side != null)
- member_lookup = member_lookup.DoResolveLValue (ec, right_side);
- else
- member_lookup = member_lookup.DoResolve (ec);
-
- return member_lookup;
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- return DoResolve (ec, null, ResolveFlags.VariableOrValue |
- ResolveFlags.SimpleName | ResolveFlags.Type);
- }
-
- public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
- {
- return DoResolve (ec, right_side, ResolveFlags.VariableOrValue |
- ResolveFlags.SimpleName | ResolveFlags.Type);
- }
-
- public Expression DoResolveType (EmitContext ec)
- {
- return DoResolve (ec, null, ResolveFlags.Type);
- }
-
- public override void Emit (EmitContext ec)
- {
- throw new Exception ("Should not happen");
- }
-
- public override string ToString ()
- {
- return expr + "." + Identifier;
- }
- }
-
- /// <summary>
- /// Implements checked expressions
- /// </summary>
- public class CheckedExpr : Expression {
-
- public Expression Expr;
-
- public CheckedExpr (Expression e, Location l)
- {
- Expr = e;
- loc = l;
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- bool last_const_check = ec.ConstantCheckState;
-
- ec.ConstantCheckState = true;
- Expr = Expr.Resolve (ec);
- ec.ConstantCheckState = last_const_check;
-
- if (Expr == null)
- return null;
-
- if (Expr is Constant)
- return Expr;
-
- eclass = Expr.eclass;
- type = Expr.Type;
- return this;
- }
-
- public override void Emit (EmitContext ec)
- {
- bool last_check = ec.CheckState;
- bool last_const_check = ec.ConstantCheckState;
-
- ec.CheckState = true;
- ec.ConstantCheckState = true;
- Expr.Emit (ec);
- ec.CheckState = last_check;
- ec.ConstantCheckState = last_const_check;
- }
-
- }
-
- /// <summary>
- /// Implements the unchecked expression
- /// </summary>
- public class UnCheckedExpr : Expression {
-
- public Expression Expr;
-
- public UnCheckedExpr (Expression e, Location l)
- {
- Expr = e;
- loc = l;
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- bool last_const_check = ec.ConstantCheckState;
-
- ec.ConstantCheckState = false;
- Expr = Expr.Resolve (ec);
- ec.ConstantCheckState = last_const_check;
-
- if (Expr == null)
- return null;
-
- if (Expr is Constant)
- return Expr;
-
- eclass = Expr.eclass;
- type = Expr.Type;
- return this;
- }
-
- public override void Emit (EmitContext ec)
- {
- bool last_check = ec.CheckState;
- bool last_const_check = ec.ConstantCheckState;
-
- ec.CheckState = false;
- ec.ConstantCheckState = false;
- Expr.Emit (ec);
- ec.CheckState = last_check;
- ec.ConstantCheckState = last_const_check;
- }
-
- }
-
- /// <summary>
- /// An Element Access expression.
- ///
- /// During semantic analysis these are transformed into
- /// IndexerAccess or ArrayAccess
- /// </summary>
- public class ElementAccess : Expression {
- public ArrayList Arguments;
- public Expression Expr;
-
- public ElementAccess (Expression e, ArrayList e_list, Location l)
- {
- Expr = e;
-
- loc = l;
-
- if (e_list == null)
- return;
-
- Arguments = new ArrayList ();
- foreach (Expression tmp in e_list)
- Arguments.Add (new Argument (tmp, Argument.AType.Expression));
-
- }
-
- bool CommonResolve (EmitContext ec)
- {
- Expr = Expr.Resolve (ec);
-
- if (Expr == null)
- return false;
-
- if (Arguments == null)
- return false;
-
- foreach (Argument a in Arguments){
- if (!a.Resolve (ec, loc))
- return false;
- }
-
- return true;
- }
-
- Expression MakePointerAccess ()
- {
- Type t = Expr.Type;
-
- if (t == TypeManager.void_ptr_type){
- Error (
- 242,
- "The array index operation is not valid for void pointers");
- return null;
- }
- if (Arguments.Count != 1){
- Error (
- 196,
- "A pointer must be indexed by a single value");
- return null;
- }
- Expression p = new PointerArithmetic (true, Expr, ((Argument)Arguments [0]).Expr,
- t, loc);
- return new Indirection (p, loc);
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- if (!CommonResolve (ec))
- return null;
-
- //
- // We perform some simple tests, and then to "split" the emit and store
- // code we create an instance of a different class, and return that.
- //
- // I am experimenting with this pattern.
- //
- Type t = Expr.Type;
-
- if (t.IsArray)
- return (new ArrayAccess (this, loc)).Resolve (ec);
- else if (t.IsPointer)
- return MakePointerAccess ();
- else
- return (new IndexerAccess (this, loc)).Resolve (ec);
- }
-
- public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
- {
- if (!CommonResolve (ec))
- return null;
-
- Type t = Expr.Type;
- if (t.IsArray)
- return (new ArrayAccess (this, loc)).ResolveLValue (ec, right_side);
- else if (t.IsPointer)
- return MakePointerAccess ();
- else
- return (new IndexerAccess (this, loc)).ResolveLValue (ec, right_side);
- }
-
- public override void Emit (EmitContext ec)
- {
- throw new Exception ("Should never be reached");
- }
- }
-
- /// <summary>
- /// Implements array access
- /// </summary>
- public class ArrayAccess : Expression, IAssignMethod, IMemoryLocation {
- //
- // Points to our "data" repository
- //
- ElementAccess ea;
-
- LocalTemporary [] cached_locations;
-
- public ArrayAccess (ElementAccess ea_data, Location l)
- {
- ea = ea_data;
- eclass = ExprClass.Variable;
- loc = l;
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- ExprClass eclass = ea.Expr.eclass;
-
-#if false
- // As long as the type is valid
- if (!(eclass == ExprClass.Variable || eclass == ExprClass.PropertyAccess ||
- eclass == ExprClass.Value)) {
- ea.Expr.Error118 ("variable or value");
- return null;
- }
-#endif
-
- Type t = ea.Expr.Type;
- if (t.GetArrayRank () != ea.Arguments.Count){
- ea.Error (22,
- "Incorrect number of indexes for array " +
- " expected: " + t.GetArrayRank () + " got: " +
- ea.Arguments.Count);
- return null;
- }
- type = TypeManager.TypeToCoreType (t.GetElementType ());
- if (type.IsPointer && !ec.InUnsafe){
- UnsafeError (ea.Location);
- return null;
- }
-
- foreach (Argument a in ea.Arguments){
- Type argtype = a.Type;
-
- if (argtype == TypeManager.int32_type ||
- argtype == TypeManager.uint32_type ||
- argtype == TypeManager.int64_type ||
- argtype == TypeManager.uint64_type)
- continue;
-
- //
- // Mhm. This is strage, because the Argument.Type is not the same as
- // Argument.Expr.Type: the value changes depending on the ref/out setting.
- //
- // Wonder if I will run into trouble for this.
- //
- a.Expr = ExpressionToArrayArgument (ec, a.Expr, ea.Location);
- if (a.Expr == null)
- return null;
- }
-
- eclass = ExprClass.Variable;
-
- return this;
- }
-
- /// <summary>
- /// Emits the right opcode to load an object of Type `t'
- /// from an array of T
- /// </summary>
- static public void EmitLoadOpcode (ILGenerator ig, Type type)
- {
- if (type == TypeManager.byte_type || type == TypeManager.bool_type)
- ig.Emit (OpCodes.Ldelem_U1);
- else if (type == TypeManager.sbyte_type)
- ig.Emit (OpCodes.Ldelem_I1);
- else if (type == TypeManager.short_type)
- ig.Emit (OpCodes.Ldelem_I2);
- else if (type == TypeManager.ushort_type || type == TypeManager.char_type)
- ig.Emit (OpCodes.Ldelem_U2);
- else if (type == TypeManager.int32_type)
- ig.Emit (OpCodes.Ldelem_I4);
- else if (type == TypeManager.uint32_type)
- ig.Emit (OpCodes.Ldelem_U4);
- else if (type == TypeManager.uint64_type)
- ig.Emit (OpCodes.Ldelem_I8);
- else if (type == TypeManager.int64_type)
- ig.Emit (OpCodes.Ldelem_I8);
- else if (type == TypeManager.float_type)
- ig.Emit (OpCodes.Ldelem_R4);
- else if (type == TypeManager.double_type)
- ig.Emit (OpCodes.Ldelem_R8);
- else if (type == TypeManager.intptr_type)
- ig.Emit (OpCodes.Ldelem_I);
- else if (type.IsValueType){
- ig.Emit (OpCodes.Ldelema, type);
- ig.Emit (OpCodes.Ldobj, type);
- } else
- ig.Emit (OpCodes.Ldelem_Ref);
- }
-
- /// <summary>
- /// Emits the right opcode to store an object of Type `t'
- /// from an array of T.
- /// </summary>
- static public void EmitStoreOpcode (ILGenerator ig, Type t)
- {
- bool is_stobj;
- OpCode op = GetStoreOpcode (t, out is_stobj);
- if (is_stobj)
- ig.Emit (OpCodes.Stobj, t);
- else
- ig.Emit (op);
- }
-
- /// <summary>
- /// Returns the right opcode to store an object of Type `t'
- /// from an array of T.
- /// </summary>
- static public OpCode GetStoreOpcode (Type t, out bool is_stobj)
- {
- is_stobj = false;
- t = TypeManager.TypeToCoreType (t);
- if (TypeManager.IsEnumType (t) && t != TypeManager.enum_type)
- t = TypeManager.EnumToUnderlying (t);
- if (t == TypeManager.byte_type || t == TypeManager.sbyte_type ||
- t == TypeManager.bool_type)
- return OpCodes.Stelem_I1;
- else if (t == TypeManager.short_type || t == TypeManager.ushort_type ||
- t == TypeManager.char_type)
- return OpCodes.Stelem_I2;
- else if (t == TypeManager.int32_type || t == TypeManager.uint32_type)
- return OpCodes.Stelem_I4;
- else if (t == TypeManager.int64_type || t == TypeManager.uint64_type)
- return OpCodes.Stelem_I8;
- else if (t == TypeManager.float_type)
- return OpCodes.Stelem_R4;
- else if (t == TypeManager.double_type)
- return OpCodes.Stelem_R8;
- else if (t == TypeManager.intptr_type)
- return OpCodes.Stelem_I;
- else if (t.IsValueType) {
- is_stobj = true;
- return OpCodes.Stobj;
- } else
- return OpCodes.Stelem_Ref;
- }
-
- MethodInfo FetchGetMethod ()
- {
- ModuleBuilder mb = CodeGen.ModuleBuilder;
- int arg_count = ea.Arguments.Count;
- Type [] args = new Type [arg_count];
- MethodInfo get;
-
- for (int i = 0; i < arg_count; i++){
- //args [i++] = a.Type;
- args [i] = TypeManager.int32_type;
- }
-
- get = mb.GetArrayMethod (
- ea.Expr.Type, "Get",
- CallingConventions.HasThis |
- CallingConventions.Standard,
- type, args);
- return get;
- }
-
-
- MethodInfo FetchAddressMethod ()
- {
- ModuleBuilder mb = CodeGen.ModuleBuilder;
- int arg_count = ea.Arguments.Count;
- Type [] args = new Type [arg_count];
- MethodInfo address;
- string ptr_type_name;
- Type ret_type;
-
- ptr_type_name = type.FullName + "&";
- ret_type = Type.GetType (ptr_type_name);
-
- //
- // It is a type defined by the source code we are compiling
- //
- if (ret_type == null){
- ret_type = mb.GetType (ptr_type_name);
- }
-
- for (int i = 0; i < arg_count; i++){
- //args [i++] = a.Type;
- args [i] = TypeManager.int32_type;
- }
-
- address = mb.GetArrayMethod (
- ea.Expr.Type, "Address",
- CallingConventions.HasThis |
- CallingConventions.Standard,
- ret_type, args);
-
- return address;
- }
-
- //
- // Load the array arguments into the stack.
- //
- // If we have been requested to cache the values (cached_locations array
- // initialized), then load the arguments the first time and store them
- // in locals. otherwise load from local variables.
- //
- void LoadArrayAndArguments (EmitContext ec)
- {
- ILGenerator ig = ec.ig;
-
- if (cached_locations == null){
- ea.Expr.Emit (ec);
- foreach (Argument a in ea.Arguments){
- Type argtype = a.Expr.Type;
-
- a.Expr.Emit (ec);
-
- if (argtype == TypeManager.int64_type)
- ig.Emit (OpCodes.Conv_Ovf_I);
- else if (argtype == TypeManager.uint64_type)
- ig.Emit (OpCodes.Conv_Ovf_I_Un);
- }
- return;
- }
-
- if (cached_locations [0] == null){
- cached_locations [0] = new LocalTemporary (ec, ea.Expr.Type);
- ea.Expr.Emit (ec);
- ig.Emit (OpCodes.Dup);
- cached_locations [0].Store (ec);
-
- int j = 1;
-
- foreach (Argument a in ea.Arguments){
- Type argtype = a.Expr.Type;
-
- cached_locations [j] = new LocalTemporary (ec, TypeManager.intptr_type /* a.Expr.Type */);
- a.Expr.Emit (ec);
- if (argtype == TypeManager.int64_type)
- ig.Emit (OpCodes.Conv_Ovf_I);
- else if (argtype == TypeManager.uint64_type)
- ig.Emit (OpCodes.Conv_Ovf_I_Un);
-
- ig.Emit (OpCodes.Dup);
- cached_locations [j].Store (ec);
- j++;
- }
- return;
- }
-
- foreach (LocalTemporary lt in cached_locations)
- lt.Emit (ec);
- }
-
- public new void CacheTemporaries (EmitContext ec)
- {
- cached_locations = new LocalTemporary [ea.Arguments.Count + 1];
- }
-
- public override void Emit (EmitContext ec)
- {
- int rank = ea.Expr.Type.GetArrayRank ();
- ILGenerator ig = ec.ig;
-
- LoadArrayAndArguments (ec);
-
- if (rank == 1)
- EmitLoadOpcode (ig, type);
- else {
- MethodInfo method;
-
- method = FetchGetMethod ();
- ig.Emit (OpCodes.Call, method);
- }
- }
-
- public void EmitAssign (EmitContext ec, Expression source)
- {
- int rank = ea.Expr.Type.GetArrayRank ();
- ILGenerator ig = ec.ig;
- Type t = source.Type;
-
- LoadArrayAndArguments (ec);
-
- //
- // The stobj opcode used by value types will need
- // an address on the stack, not really an array/array
- // pair
- //
- if (rank == 1){
- if (t == TypeManager.enum_type || t == TypeManager.decimal_type ||
- (t.IsSubclassOf (TypeManager.value_type) && !TypeManager.IsEnumType (t) && !TypeManager.IsBuiltinType (t)))
- ig.Emit (OpCodes.Ldelema, t);
- }
-
- source.Emit (ec);
-
- if (rank == 1)
- EmitStoreOpcode (ig, t);
- else {
- ModuleBuilder mb = CodeGen.ModuleBuilder;
- int arg_count = ea.Arguments.Count;
- Type [] args = new Type [arg_count + 1];
- MethodInfo set;
-
- for (int i = 0; i < arg_count; i++){
- //args [i++] = a.Type;
- args [i] = TypeManager.int32_type;
- }
-
- args [arg_count] = type;
-
- set = mb.GetArrayMethod (
- ea.Expr.Type, "Set",
- CallingConventions.HasThis |
- CallingConventions.Standard,
- TypeManager.void_type, args);
-
- ig.Emit (OpCodes.Call, set);
- }
- }
-
- public void AddressOf (EmitContext ec, AddressOp mode)
- {
- int rank = ea.Expr.Type.GetArrayRank ();
- ILGenerator ig = ec.ig;
-
- LoadArrayAndArguments (ec);
-
- if (rank == 1){
- ig.Emit (OpCodes.Ldelema, type);
- } else {
- MethodInfo address = FetchAddressMethod ();
- ig.Emit (OpCodes.Call, address);
- }
- }
- }
-
-
- class Indexers {
- public ArrayList getters, setters;
- static Hashtable map;
-
- static Indexers ()
- {
- map = new Hashtable ();
- }
-
- Indexers (MemberInfo [] mi)
- {
- foreach (PropertyInfo property in mi){
- MethodInfo get, set;
-
- get = property.GetGetMethod (true);
- if (get != null){
- if (getters == null)
- getters = new ArrayList ();
-
- getters.Add (get);
- }
-
- set = property.GetSetMethod (true);
- if (set != null){
- if (setters == null)
- setters = new ArrayList ();
- setters.Add (set);
- }
- }
- }
-
- static private Indexers GetIndexersForTypeOrInterface (Type caller_type, Type lookup_type)
- {
- Indexers ix = (Indexers) map [lookup_type];
-
- if (ix != null)
- return ix;
-
- string p_name = TypeManager.IndexerPropertyName (lookup_type);
-
- MemberInfo [] mi = TypeManager.MemberLookup (
- caller_type, caller_type, lookup_type, MemberTypes.Property,
- BindingFlags.Public | BindingFlags.Instance |
- BindingFlags.DeclaredOnly, p_name);
-
- if (mi == null || mi.Length == 0)
- return null;
-
- ix = new Indexers (mi);
- map [lookup_type] = ix;
-
- return ix;
- }
-
- static public Indexers GetIndexersForType (Type caller_type, Type lookup_type, Location loc)
- {
- Indexers ix = (Indexers) map [lookup_type];
-
- if (ix != null)
- return ix;
-
- ix = GetIndexersForTypeOrInterface (caller_type, lookup_type);
- if (ix != null)
- return ix;
-
- Type [] ifaces = TypeManager.GetInterfaces (lookup_type);
- if (ifaces != null) {
- foreach (Type itype in ifaces) {
- ix = GetIndexersForTypeOrInterface (caller_type, itype);
- if (ix != null)
- return ix;
- }
- }
-
- return null;
- }
- }
-
- /// <summary>
- /// Expressions that represent an indexer call.
- /// </summary>
- public class IndexerAccess : Expression, IAssignMethod {
- //
- // Points to our "data" repository
- //
- MethodInfo get, set;
- Indexers ilist;
- ArrayList set_arguments;
- bool is_base_indexer;
-
- protected Type indexer_type;
- protected Type current_type;
- protected Expression instance_expr;
- protected ArrayList arguments;
-
- public IndexerAccess (ElementAccess ea, Location loc)
- : this (ea.Expr, false, loc)
- {
- this.arguments = ea.Arguments;
- }
-
- protected IndexerAccess (Expression instance_expr, bool is_base_indexer,
- Location loc)
- {
- this.instance_expr = instance_expr;
- this.is_base_indexer = is_base_indexer;
- this.eclass = ExprClass.Value;
- this.loc = loc;
- }
-
- protected virtual bool CommonResolve (EmitContext ec)
- {
- indexer_type = instance_expr.Type;
- current_type = ec.ContainerType;
-
- return true;
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- if (!CommonResolve (ec))
- return null;
-
- //
- // Step 1: Query for all `Item' *properties*. Notice
- // that the actual methods are pointed from here.
- //
- // This is a group of properties, piles of them.
-
- bool found_any = false, found_any_getters = false;
- Type lookup_type = indexer_type;
- while (lookup_type != null) {
- ilist = Indexers.GetIndexersForType (current_type, lookup_type, loc);
-
- if (ilist == null) {
- lookup_type = lookup_type.BaseType;
- continue;
- }
-
- found_any = true;
-
- //
- // Step 2: find the proper match
- //
- if (ilist.getters != null && ilist.getters.Count > 0) {
- found_any_getters = true;
- get = (MethodInfo) Invocation.OverloadResolve (
- ec, new MethodGroupExpr (ilist.getters, loc), arguments, loc);
-
- if (get != null)
- break;
- }
-
- lookup_type = lookup_type.BaseType;
- }
-
- if (!found_any) {
- Report.Error (21, loc,
- "Type `" + TypeManager.CSharpName (indexer_type) +
- "' does not have any indexers defined");
- return null;
- }
-
- if (!found_any_getters) {
- Error (154, "indexer can not be used in this context, because " +
- "it lacks a `get' accessor");
- return null;
- }
-
- if (get == null) {
- Error (1501, "No Overload for method `this' takes `" +
- arguments.Count + "' arguments");
- return null;
- }
-
- //
- // Only base will allow this invocation to happen.
- //
- if (get.IsAbstract && this is BaseIndexerAccess){
- Report.Error (205, loc, "Cannot call an abstract base indexer: " + Invocation.FullMethodDesc (get));
- return null;
- }
-
- type = get.ReturnType;
- if (type.IsPointer && !ec.InUnsafe){
- UnsafeError (loc);
- return null;
- }
-
- eclass = ExprClass.IndexerAccess;
- return this;
- }
-
- public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
- {
- if (!CommonResolve (ec))
- return null;
-
- Type right_type = right_side.Type;
-
- bool found_any = false, found_any_setters = false;
- Type lookup_type = indexer_type;
- while (lookup_type != null) {
- ilist = Indexers.GetIndexersForType (current_type, lookup_type, loc);
-
- if (ilist == null) {
- lookup_type = lookup_type.BaseType;
- continue;
- }
-
- found_any = true;
-
- if (ilist.setters != null && ilist.setters.Count > 0) {
- found_any_setters = true;
-
- set_arguments = (ArrayList) arguments.Clone ();
- set_arguments.Add (new Argument (right_side, Argument.AType.Expression));
- set = (MethodInfo) Invocation.OverloadResolve (
- ec, new MethodGroupExpr (ilist.setters, loc), set_arguments, loc);
-
- if (set != null)
- break;
- }
-
-
- lookup_type = lookup_type.BaseType;
- }
-
- if (!found_any) {
- Report.Error (21, loc,
- "Type `" + TypeManager.CSharpName (indexer_type) +
- "' does not have any indexers defined");
- return null;
- }
-
- if (!found_any_setters) {
- Error (154, "indexer can not be used in this context, because " +
- "it lacks a `set' accessor");
- return null;
- }
-
- if (set == null) {
- Error (1501, "No Overload for method `this' takes `" +
- arguments.Count + "' arguments");
- return null;
- }
-
- //
- // Only base will allow this invocation to happen.
- //
- if (set.IsAbstract && this is BaseIndexerAccess){
- Report.Error (205, loc, "Cannot call an abstract base indexer: " + Invocation.FullMethodDesc (set));
- return null;
- }
- type = TypeManager.void_type;
- eclass = ExprClass.IndexerAccess;
- return this;
- }
-
- public override void Emit (EmitContext ec)
- {
- Invocation.EmitCall (ec, false, false, instance_expr, get, arguments, loc);
- }
-
- //
- // source is ignored, because we already have a copy of it from the
- // LValue resolution and we have already constructed a pre-cached
- // version of the arguments (ea.set_arguments);
- //
- public void EmitAssign (EmitContext ec, Expression source)
- {
- Invocation.EmitCall (ec, false, false, instance_expr, set, set_arguments, loc);
- }
- }
-
- /// <summary>
- /// The base operator for method names
- /// </summary>
- public class BaseAccess : Expression {
- string member;
-
- public BaseAccess (string member, Location l)
- {
- this.member = member;
- loc = l;
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- Expression c = CommonResolve (ec);
-
- if (c == null)
- return null;
-
- //
- // MethodGroups use this opportunity to flag an error on lacking ()
- //
- if (!(c is MethodGroupExpr))
- return c.Resolve (ec);
- return c;
- }
-
- public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
- {
- Expression c = CommonResolve (ec);
-
- if (c == null)
- return null;
-
- //
- // MethodGroups use this opportunity to flag an error on lacking ()
- //
- if (! (c is MethodGroupExpr))
- return c.DoResolveLValue (ec, right_side);
-
- return c;
- }
-
- Expression CommonResolve (EmitContext ec)
- {
- Expression member_lookup;
- Type current_type = ec.ContainerType;
- Type base_type = current_type.BaseType;
- Expression e;
-
- if (ec.IsStatic){
- Error (1511, "Keyword base is not allowed in static method");
- return null;
- }
-
- member_lookup = MemberLookup (ec, ec.ContainerType, null, base_type, member,
- AllMemberTypes, AllBindingFlags, loc);
- if (member_lookup == null) {
- MemberLookupFailed (ec, base_type, base_type, member, null, loc);
- return null;
- }
-
- Expression left;
-
- if (ec.IsStatic)
- left = new TypeExpr (base_type, loc);
- else
- left = ec.This;
-
- e = MemberAccess.ResolveMemberAccess (ec, member_lookup, left, loc, null);
-
- if (e is PropertyExpr){
- PropertyExpr pe = (PropertyExpr) e;
-
- pe.IsBase = true;
- }
-
- return e;
- }
-
- public override void Emit (EmitContext ec)
- {
- throw new Exception ("Should never be called");
- }
- }
-
- /// <summary>
- /// The base indexer operator
- /// </summary>
- public class BaseIndexerAccess : IndexerAccess {
- public BaseIndexerAccess (ArrayList args, Location loc)
- : base (null, true, loc)
- {
- arguments = new ArrayList ();
- foreach (Expression tmp in args)
- arguments.Add (new Argument (tmp, Argument.AType.Expression));
- }
-
- protected override bool CommonResolve (EmitContext ec)
- {
- instance_expr = ec.This;
-
- current_type = ec.ContainerType.BaseType;
- indexer_type = current_type;
-
- foreach (Argument a in arguments){
- if (!a.Resolve (ec, loc))
- return false;
- }
-
- return true;
- }
- }
-
- /// <summary>
- /// This class exists solely to pass the Type around and to be a dummy
- /// that can be passed to the conversion functions (this is used by
- /// foreach implementation to typecast the object return value from
- /// get_Current into the proper type. All code has been generated and
- /// we only care about the side effect conversions to be performed
- ///
- /// This is also now used as a placeholder where a no-action expression
- /// is needed (the `New' class).
- /// </summary>
- public class EmptyExpression : Expression {
- public EmptyExpression ()
- {
- type = TypeManager.object_type;
- eclass = ExprClass.Value;
- loc = Location.Null;
- }
-
- public EmptyExpression (Type t)
- {
- type = t;
- eclass = ExprClass.Value;
- loc = Location.Null;
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- return this;
- }
-
- public override void Emit (EmitContext ec)
- {
- // nothing, as we only exist to not do anything.
- }
-
- //
- // This is just because we might want to reuse this bad boy
- // instead of creating gazillions of EmptyExpressions.
- // (CanConvertImplicit uses it)
- //
- public void SetType (Type t)
- {
- type = t;
- }
- }
-
- public class UserCast : Expression {
- MethodBase method;
- Expression source;
-
- public UserCast (MethodInfo method, Expression source, Location l)
- {
- this.method = method;
- this.source = source;
- type = method.ReturnType;
- eclass = ExprClass.Value;
- loc = l;
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- //
- // We are born fully resolved
- //
- return this;
- }
-
- public override void Emit (EmitContext ec)
- {
- ILGenerator ig = ec.ig;
-
- source.Emit (ec);
-
- if (method is MethodInfo)
- ig.Emit (OpCodes.Call, (MethodInfo) method);
- else
- ig.Emit (OpCodes.Call, (ConstructorInfo) method);
-
- }
- }
-
- // <summary>
- // This class is used to "construct" the type during a typecast
- // operation. Since the Type.GetType class in .NET can parse
- // the type specification, we just use this to construct the type
- // one bit at a time.
- // </summary>
- public class ComposedCast : Expression, ITypeExpression {
- Expression left;
- string dim;
-
- public ComposedCast (Expression left, string dim, Location l)
- {
- this.left = left;
- this.dim = dim;
- loc = l;
- }
-
- public Expression DoResolveType (EmitContext ec)
- {
- Type ltype = ec.DeclSpace.ResolveType (left, false, loc);
- if (ltype == null)
- return null;
-
- //
- // ltype.Fullname is already fully qualified, so we can skip
- // a lot of probes, and go directly to TypeManager.LookupType
- //
- string cname = ltype.FullName + dim;
- type = TypeManager.LookupTypeDirect (cname);
- if (type == null){
- //
- // For arrays of enumerations we are having a problem
- // with the direct lookup. Need to investigate.
- //
- // For now, fall back to the full lookup in that case.
- //
- type = RootContext.LookupType (
- ec.DeclSpace, cname, false, loc);
-
- if (type == null)
- 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;
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- return DoResolveType (ec);
- }
-
- public override void Emit (EmitContext ec)
- {
- throw new Exception ("This should never be called");
- }
-
- public override string ToString ()
- {
- return left + dim;
- }
- }
-
- //
- // This class is used to represent the address of an array, used
- // only by the Fixed statement, this is like the C "&a [0]" construct.
- //
- public class ArrayPtr : Expression {
- Expression array;
-
- public ArrayPtr (Expression array, Location l)
- {
- Type array_type = array.Type.GetElementType ();
-
- this.array = array;
-
- string array_ptr_type_name = array_type.FullName + "*";
-
- type = Type.GetType (array_ptr_type_name);
- if (type == null){
- ModuleBuilder mb = CodeGen.ModuleBuilder;
-
- type = mb.GetType (array_ptr_type_name);
- }
-
- eclass = ExprClass.Value;
- loc = l;
- }
-
- public override void Emit (EmitContext ec)
- {
- ILGenerator ig = ec.ig;
-
- array.Emit (ec);
- IntLiteral.EmitInt (ig, 0);
- ig.Emit (OpCodes.Ldelema, array.Type.GetElementType ());
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- //
- // We are born fully resolved
- //
- return this;
- }
- }
-
- //
- // Used by the fixed statement
- //
- public class StringPtr : Expression {
- LocalBuilder b;
-
- public StringPtr (LocalBuilder b, Location l)
- {
- this.b = b;
- eclass = ExprClass.Value;
- type = TypeManager.char_ptr_type;
- loc = l;
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- // This should never be invoked, we are born in fully
- // initialized state.
-
- return this;
- }
-
- public override void Emit (EmitContext ec)
- {
- ILGenerator ig = ec.ig;
-
- ig.Emit (OpCodes.Ldloc, b);
- ig.Emit (OpCodes.Conv_I);
- ig.Emit (OpCodes.Call, TypeManager.int_get_offset_to_string_data);
- ig.Emit (OpCodes.Add);
- }
- }
-
- //
- // Implements the `stackalloc' keyword
- //
- public class StackAlloc : Expression {
- Type otype;
- Expression t;
- Expression count;
-
- public StackAlloc (Expression type, Expression count, Location l)
- {
- t = type;
- this.count = count;
- loc = l;
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- count = count.Resolve (ec);
- if (count == null)
- return null;
-
- if (count.Type != TypeManager.int32_type){
- count = ConvertImplicitRequired (ec, count, TypeManager.int32_type, loc);
- if (count == null)
- return null;
- }
-
- if (ec.InCatch || ec.InFinally){
- Error (255,
- "stackalloc can not be used in a catch or finally block");
- return null;
- }
-
- otype = ec.DeclSpace.ResolveType (t, false, loc);
-
- if (otype == null)
- return null;
-
- if (!TypeManager.VerifyUnManaged (otype, loc))
- return null;
-
- string ptr_name = otype.FullName + "*";
- type = Type.GetType (ptr_name);
- if (type == null){
- ModuleBuilder mb = CodeGen.ModuleBuilder;
-
- type = mb.GetType (ptr_name);
- }
- eclass = ExprClass.Value;
-
- return this;
- }
-
- public override void Emit (EmitContext ec)
- {
- int size = GetTypeSize (otype);
- ILGenerator ig = ec.ig;
-
- if (size == 0)
- ig.Emit (OpCodes.Sizeof, otype);
- else
- IntConstant.EmitInt (ig, size);
- count.Emit (ec);
- ig.Emit (OpCodes.Mul);
- ig.Emit (OpCodes.Localloc);
- }
- }
-}