+2001-09-30 Miguel de Icaza <miguel@ximian.com>
+
+ * 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
// Attributes for this type
protected Attributes attributes;
- public TypeContainer (RootContext rc, TypeContainer parent, string name) : base (name)
+ public TypeContainer (RootContext rc, TypeContainer parent, string name, Location l)
+ : base (name, l)
{
string n;
types = new ArrayList ();
int mods = 0;
c = new Constructor (Name, new Parameters (null, null),
- new ConstructorBaseInitializer (null, new Location ("", 0, 0)));
+ new ConstructorBaseInitializer (null, new Location ("", 0, 0)),
+ new Location ("Internal", 1, 1));
AddConstructor (c);
c.Block = new Block (null);
c.ModFlags = mods;
}
+ public void ReportStructInitializedInstanceError ()
+ {
+ string n = TypeBuilder.FullName;
+
+ foreach (Field f in initialized_fields){
+ RootContext.Report.Error (
+ 573, Location,
+ "`" + n + "." + f.Name + "': can not have " +
+ "instance field initializers in structs");
+ }
+ }
+
//
// Populates our TypeBuilder with fields and methods
//
f.Define (this);
}
- if (default_constructor == null)
- DefineDefaultConstructor (false);
+ if (this is Class){
+ if (default_constructor == null)
+ DefineDefaultConstructor (false);
- if (initialized_static_fields != null && default_static_constructor == null)
- DefineDefaultConstructor (true);
+ 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 ();
+ }
if (Constructors != null){
foreach (Constructor c in Constructors){
c.Define (this);
if (method_builders_to_methods == null)
method_builders_to_methods = new Hashtable ();
- method_builders_to_methods.Add (c.ConstructorBuilder, c);
+ object key = c.ConstructorBuilder;
+ if (key != null)
+ method_builders_to_methods.Add (key, c);
}
}
return RootContext.LookupType (this, name, silent);
}
- bool AlwaysAccept (MemberInfo m, object filterCriteria)
+ //
+ // This function is based by a delegate to the FindMembers routine
+ //
+ static bool AlwaysAccept (MemberInfo m, object filterCriteria)
{
return true;
}
+ //
+ // This filter is used by FindMembers, and we just keep
+ // a global for the filter to `AlwaysAccept'
+ //
+ static MemberFilter accepting_filter;
+
+ static TypeContainer ()
+ {
+ accepting_filter = new MemberFilter (AlwaysAccept);
+ }
+
// <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'
ArrayList members = new ArrayList ();
if (filter == null)
- filter = new MemberFilter (AlwaysAccept);
+ filter = accepting_filter;
if ((mt & MemberTypes.Field) != 0 && Fields != null) {
foreach (Field f in Fields) {
Modifiers.ABSTRACT |
Modifiers.SEALED;
- public Class (RootContext rc, TypeContainer parent, string name, int mod, Attributes attrs)
- : base (rc, parent, name)
+ public Class (RootContext rc, TypeContainer parent, string name, int mod,
+ Attributes attrs, Location l)
+ : base (rc, parent, name, l)
{
int accmods;
Modifiers.INTERNAL |
Modifiers.PRIVATE;
- public Struct (RootContext rc, TypeContainer parent, string name, int mod, Attributes attrs)
- : base (rc, parent, name)
+ public Struct (RootContext rc, TypeContainer parent, string name, int mod,
+ Attributes attrs, Location l)
+ : base (rc, parent, name, l)
{
int accmods;
public readonly string Name;
public int ModFlags;
Block block;
+ public readonly Location Location;
//
// Parameters, cached for semantic analysis.
//
InternalParameters parameter_info;
- public MethodCore (string name, Parameters parameters)
+ public MethodCore (string name, Parameters parameters, Location l)
{
Name = name;
Parameters = parameters;
+ Location = l;
}
//
// return_type can be "null" for VOID values.
public Method (string return_type, int mod, string name, Parameters parameters,
- Attributes attrs)
- : base (name, parameters)
+ Attributes attrs, Location l)
+ : base (name, parameters, l)
{
ReturnType = return_type;
ModFlags = Modifiers.Check (AllowedModifiers, mod, 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)
- : base (name, args)
+ public Constructor (string name, Parameters args, ConstructorInitializer init, Location l)
+ : base (name, args, l)
{
Initializer = init;
}
{
MethodAttributes ca = (MethodAttributes.RTSpecialName |
MethodAttributes.SpecialName);
+
Type [] parameters = ParameterTypes (parent);
-
+
+ if (parent is Struct && parameters == null){
+ parent.RootContext.Report.Error (
+ 568, Location,
+ "Structs can not contain explicit parameterless constructors");
+ return;
+ }
+
if ((ModFlags & Modifiers.STATIC) != 0)
ca |= MethodAttributes.Static;
//
public void Emit (TypeContainer parent)
{
- if (Initializer != null)
+ if (parent is Class){
+ if (Initializer == null)
+ Initializer = new ConstructorBaseInitializer (null, parent.Location);
if (!Initializer.Resolve (parent))
return;
+ }
ILGenerator ig = ConstructorBuilder.GetILGenerator ();
EmitContext ec = new EmitContext (parent, ig);
- if ((ModFlags & Modifiers.STATIC) == 0)
- Initializer.Emit (ec);
+ //
+ // Classes can have base initializers and instance field initializers.
+ //
+ if (parent is Class){
+ if ((ModFlags & Modifiers.STATIC) == 0)
+ Initializer.Emit (ec);
+ parent.EmitFieldInitializers (ec, false);
+ }
if ((ModFlags & Modifiers.STATIC) != 0)
parent.EmitFieldInitializers (ec, true);
- else
- parent.EmitFieldInitializers (ec, false);
ec.EmitTopBlock (Block);
}
Parameter.Modifier.NONE, null);
OperatorMethod = new Method (ReturnType, ModFlags, MethodName,
- new Parameters (param_list, null), OptAttributes);
+ new Parameters (param_list, null),
+ OptAttributes, null);
OperatorMethod.Define (parent);
OperatorMethodBuilder = OperatorMethod.MethodBuilder;
Struct new_struct;\r
string full_struct_name = MakeName ((string) $4);\r
\r
- new_struct = new Struct (rc, current_container, full_struct_name, (int) $2, (Attributes) $1);\r
+ new_struct = new Struct (rc, current_container, full_struct_name, (int) $2, \r
+ (Attributes) $1, lexer.Location);\r
current_container = new_struct;\r
current_container.Namespace = current_namespace;\r
tree.RecordStruct (full_struct_name, new_struct);\r
member_name\r
OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS \r
{\r
- Method method = new Method ((string) $3, (int) $2, (string) $4, (Parameters) $6, (Attributes) $1);\r
+ Method method = new Method ((string) $3, (int) $2, (string) $4, \r
+ (Parameters) $6, (Attributes) $1, lexer.Location);\r
\r
current_local_parameters = (Parameters) $6;\r
\r
member_name\r
OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS \r
{\r
- Method method = new Method ("System.Void", (int) $2, (string) $4, (Parameters) $6, (Attributes) $1);\r
+ Method method = new Method ("System.Void", (int) $2, (string) $4, \r
+ (Parameters) $6, (Attributes) $1, lexer.Location);\r
\r
current_local_parameters = (Parameters) $6;\r
$$ = method;\r
Interface new_interface;\r
string full_interface_name = MakeName ((string) $4);\r
\r
- new_interface = new Interface (current_container, full_interface_name, (int) $2, (Attributes) $1);\r
+ new_interface = new Interface (current_container, full_interface_name, (int) $2, \r
+ (Attributes) $1, lexer.Location);\r
if (current_interface != null) {\r
Location l = lexer.Location;\r
rc.Report.Error (-2, l, "Internal compiler error: interface inside interface");\r
Location l = lexer.Location;\r
rc.Report.Error (103, l, "Static constructors should not have parameters");\r
}\r
- } else {\r
- if (c.Initializer == null)\r
- c.Initializer = new ConstructorBaseInitializer (null, lexer.Location);\r
- }\r
+ } \r
\r
CheckDef (current_container.AddConstructor (c), c.Name);\r
\r
OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS \r
opt_constructor_initializer\r
{\r
- $$ = new Constructor ((string) $1, (Parameters) $3, (ConstructorInitializer) $5);\r
+ Location l = lexer.Location;\r
+\r
+ $$ = new Constructor ((string) $1, (Parameters) $3, (ConstructorInitializer) $5, l);\r
\r
current_local_parameters = (Parameters) $3;\r
}\r
destructor_declaration\r
: opt_attributes TILDE IDENTIFIER OPEN_PARENS CLOSE_PARENS block\r
{\r
- Method d = new Method ("System.Void", 0, "Finalize", new Parameters (null, null), (Attributes) $1);\r
+ Method d = new Method ("System.Void", 0, "Finalize", \r
+ new Parameters (null, null), (Attributes) $1, lexer.Location);\r
\r
d.Block = (Block) $6;\r
CheckDef (current_container.AddMethod (d), d.Name);\r
opt_semicolon\r
{ \r
string name = (string) $4;\r
- Enum e = new Enum ((string) $5, (int) $2, name, (Attributes) $1);\r
+ Enum e = new Enum ((string) $5, (int) $2, name, (Attributes) $1, lexer.Location);\r
\r
foreach (VariableDeclaration ev in (ArrayList) $6){\r
CheckDef (e.AddEnumMember (ev.identifier, \r
CLOSE_PARENS \r
SEMICOLON\r
{\r
- Delegate del = new Delegate ((string) $4, (int) $2, (string) $5, (Parameters) $7, (Attributes) $1);\r
+ Delegate del = new Delegate ((string) $4, (int) $2, (string) $5, (Parameters) $7, \r
+ (Attributes) $1, lexer.Location);\r
\r
CheckDef (current_container.AddDelegate (del), del.Name);\r
} \r
CLOSE_PARENS \r
SEMICOLON\r
{\r
- Delegate del = new Delegate (null, (int) $2, (string) $5, (Parameters) $7, (Attributes) $1);\r
+ Delegate del = new Delegate (null, (int) $2, (string) $5, (Parameters) $7, \r
+ (Attributes) $1, lexer.Location);\r
\r
CheckDef (current_container.AddDelegate (del), del.Name);\r
}\r
;\r
\r
integer_literal\r
- : LITERAL_INTEGER { $$ = new IntLiteral ((Int32) lexer.Value); }\r
+ : LITERAL_INTEGER { \r
+ object v = lexer.Value;\r
+\r
+ // \r
+ // FIXME: Possible optimization would be to \r
+ // compute the *Literal objects directly in the scanner\r
+ //\r
+ if (v is int)\r
+ $$ = new IntLiteral ((Int32) v); \r
+ else if (v is uint)\r
+ $$ = new UIntLiteral ((UInt32) v);\r
+ else if (v is long)\r
+ $$ = new LongLiteral ((Int64) v);\r
+ else if (v is ulong)\r
+ $$ = new ULongLiteral ((UInt64) v);\r
+ else\r
+ Console.WriteLine ("OOPS. Unexpected result from scanner");\r
+ }\r
;\r
\r
boolean_literal\r
Class new_class;\r
string full_class_name = MakeName ((string) $4);\r
\r
- new_class = new Class (rc, current_container, full_class_name, (int) $2, (Attributes) $1);\r
+ new_class = new Class (rc, current_container, full_class_name, (int) $2, \r
+ (Attributes) $1, lexer.Location);\r
current_container = new_class;\r
current_container.Namespace = current_namespace;\r
tree.RecordClass (full_class_name, new_class);\r
\r
if (Char.IsDigit ((char)c)){\r
if (c == '0' && peekChar () == 'x' || peekChar () == 'X'){\r
+ ulong ul;\r
getChar ();\r
hex_digits (-1);\r
- val = new System.Int32 ();\r
- val = System.Int32.Parse (number.ToString (), NumberStyles.HexNumber);\r
+\r
+ string s = number.ToString ();\r
+\r
+ ul = System.UInt64.Parse (s, NumberStyles.HexNumber);\r
+ if ((ul & 0xffffffff00000000) == 0){\r
+ uint ui = (uint) ul;\r
+ \r
+ if ((ui & 0x80000000) != 0)\r
+ val = ui;\r
+ else\r
+ val = (int) ui;\r
+ } else {\r
+ if ((ul & 0x8000000000000000) != 0)\r
+ val = ul;\r
+ else\r
+ val = (long) ul;\r
+ }\r
+\r
return integer_type_suffix (peekChar ());\r
}\r
decimal_digits (c);\r
// created with System.Reflection.Emit
// </summary>
TypeBuilder definition;
+
+ // <summary>
+ // Location where this declaration happens
+ // </summary>
+ public readonly Location Location;
string name, basename;
// </summary>
protected Hashtable defined_names;
- public DeclSpace (string name)
+ public DeclSpace (string name, Location l)
{
this.name = name;
this.basename = name.Substring (1 + name.LastIndexOf ('.'));
defined_names = new Hashtable ();
+ Location = l;
}
// <summary>
definition = value;
}
}
+
}
}
+
+
+
+
+
+
Modifiers.PRIVATE;\r
\r
public Delegate (string type, int mod_flags, string name, Parameters param_list,\r
- Attributes attrs) : base (name)\r
+ Attributes attrs, Location l) : base (name, l)\r
{\r
this.name = name;\r
this.type = type;\r
//\r
context.TypeManager.InitCoreTypes ();\r
\r
+ if (context.Report.Errors > 0){\r
+ error ("Compilation failed");\r
+ return;\r
+ }\r
+ \r
//\r
// The code generator\r
//\r
Modifiers.INTERNAL |
Modifiers.PRIVATE;
- public Enum (string type, int mod_flags, string name, Attributes attrs) : base (name)
+ public Enum (string type, int mod_flags, string name, Attributes attrs, Location l)
+ : base (name, l)
{
this.type = type;
this.name = name;
left = ConvertImplicit (tc, left, TypeManager.float_type, location);
type = TypeManager.float_type;
} else if (l == TypeManager.uint64_type || r == TypeManager.uint64_type){
+ 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
//
- Type other = null;
- if (l == TypeManager.uint64_type)
- other = r;
- else if (r == TypeManager.uint64_type)
- other = l;
+ if (l == TypeManager.uint64_type){
+ if (r != TypeManager.uint64_type && right is IntLiteral){
+ e = TryImplicitIntConversion (l, (IntLiteral) right);
+ if (e != null)
+ right = e;
+ }
+ other = right.Type;
+ } else {
+ if (left is IntLiteral){
+ e = TryImplicitIntConversion (r, (IntLiteral) left);
+ if (e != null)
+ left = e;
+ }
+ other = left.Type;
+ }
if ((other == TypeManager.sbyte_type) ||
(other == TypeManager.short_type) ||
(other == TypeManager.int64_type)){
string oper = OperName ();
- Error (tc, 34, "Operator `" + OperName ()
+ Error (tc, 34, location, "Operator `" + OperName ()
+ "' is ambiguous on operands of type `"
+ TypeManager.CSharpName (l) + "' "
+ "and `" + TypeManager.CSharpName (r)
// operand is converd to type uint
//
left = ForceConversion (tc, left, TypeManager.uint32_type);
- right = ForceConversion (tc, left, TypeManager.uint32_type);
+ right = ForceConversion (tc, right, TypeManager.uint32_type);
type = TypeManager.uint32_type;
}
} else if (l == TypeManager.decimal_type || r == TypeManager.decimal_type){
((e = ConvertImplicit (tc, left, TypeManager.int64_type, loc)) != null) ||
((e = ConvertImplicit (tc, left, TypeManager.uint64_type, loc)) != null)){
left = e;
+ type = e.Type;
return this;
}
if (l != TypeManager.bool_type || r != TypeManager.bool_type)
error19 (tc);
+ type = TypeManager.bool_type;
return this;
}
error19 (tc);
return null;
}
+ type = l;
}
if (oper == Operator.Equality ||
return null;
if (left.Type == null)
- throw new Exception ("Resolve returned non null, but did not set the type!");
+ throw new Exception (
+ "Resolve returned non null, but did not set the type! (" +
+ left + ")");
if (right.Type == null)
- throw new Exception ("Resolve returned non null, but did not set the type!");
+ throw new Exception (
+ "Resolve returned non null, but did not set the type! (" +
+ right + ")");
eclass = ExprClass.Value;
Modifiers.INTERNAL |
Modifiers.PRIVATE;
- public Interface (TypeContainer parent, string name, int mod, Attributes attrs) : base (name)
+ public Interface (TypeContainer parent, string name, int mod, Attributes attrs, Location l)
+ : base (name, l)
{
this.mod_flags = Modifiers.Check (AllowedModifiers, mod, Modifiers.PUBLIC);
this.parent = parent;
}
}
+ public class ULongLiteral : Literal {
+ public readonly ulong Value;
+
+ public ULongLiteral (ulong l)
+ {
+ Value = l;
+ }
+
+ override public string AsString ()
+ {
+ return Value.ToString ();
+ }
+
+ public override Expression DoResolve (TypeContainer tc)
+ {
+ type = TypeManager.uint64_type;
+
+ return this;
+ }
+
+ public override void Emit (EmitContext ec)
+ {
+ ILGenerator ig = ec.ig;
+
+ LongLiteral.EmitLong (ig, unchecked ((long) Value));
+ }
+ }
+
public class FloatLiteral : Literal {
public readonly float Value;
public Parameter GetParameterByName (string name, out int idx)
{
idx = 0;
-
+
if (FixedParameters == null)
return null;
public void CloseTypes ()
{
foreach (TypeBuilder t in TypeManager.UserTypes){
- t.CreateType ();
+ try {
+ t.CreateType ();
+ } catch (Exception e){
+ Console.WriteLine ("Caught Exception while creating type for " + t);
+ Console.WriteLine (e);
+ }
}
}
// have been defined through `ResolveTree'
public void PopulateTypes ()
{
- Hashtable ifaces, classes;
+ Hashtable ifaces, classes, structs;
if ((ifaces = tree.Interfaces) != null){
foreach (DictionaryEntry de in ifaces){
tc.Populate ();
}
}
+
+ if ((structs = tree.Structs) != null){
+ foreach (DictionaryEntry de in structs){
+ TypeContainer tc = (TypeContainer) de.Value;
+
+ tc.Populate ();
+ }
+ }
}
public void EmitCode ()
{
- Hashtable classes;
+ Hashtable classes, structs;
if ((classes = tree.Classes) != null){
foreach (DictionaryEntry de in classes){
tc.Emit ();
}
}
+
+ if ((structs = tree.Structs) != null){
+ foreach (DictionaryEntry de in structs){
+ TypeContainer tc = (TypeContainer) de.Value;
+
+ tc.Emit ();
+ }
+ }
}
// <summary>
public Tree (RootContext rc)
{
- root_types = new TypeContainer (rc, null, "");
+ root_types = new TypeContainer (rc, null, "", new Location ("Internal", 1, 1));
this.rc = rc;
}