Imported Upstream version 3.10.0

Former-commit-id: 172c8e3c300b39d5785c7a3e8dfb08ebdbc1a99b
This commit is contained in:
Jo Shields
2014-10-04 11:27:48 +01:00
parent fe777c5c82
commit 8b9b85e7f5
970 changed files with 20242 additions and 31308 deletions

View File

@@ -34,6 +34,11 @@ namespace Mono.CSharp
Default = 3, // argument created from default parameter value
DynamicTypeName = 4, // System.Type argument for dynamic binding
ExtensionType = 5, // Instance expression inserted as the first argument
// Conditional instance expression inserted as the first argument
ExtensionTypeConditionalAccess = 5 | ConditionalAccessFlag,
ConditionalAccessFlag = 1 << 7
}
public readonly AType ArgType;
@@ -60,6 +65,12 @@ namespace Mono.CSharp
get { return ArgType == AType.Default; }
}
public bool IsExtensionType {
get {
return (ArgType & AType.ExtensionType) == AType.ExtensionType;
}
}
public Parameter.Modifier Modifier {
get {
switch (ArgType) {
@@ -105,7 +116,13 @@ namespace Mono.CSharp
public virtual void Emit (EmitContext ec)
{
if (!IsByRef) {
Expr.Emit (ec);
if (ArgType == AType.ExtensionTypeConditionalAccess) {
var ie = new InstanceEmitter (Expr, false);
ie.Emit (ec, true);
} else {
Expr.Emit (ec);
}
return;
}

View File

@@ -819,7 +819,7 @@ namespace Mono.CSharp
args.Add (new Argument (awaiter, Argument.AType.Ref));
args.Add (new Argument (new CompilerGeneratedThis (CurrentType, Location), Argument.AType.Ref));
using (ec.With (BuilderContext.Options.OmitDebugInfo, true)) {
mg.EmitCall (ec, args);
mg.EmitCall (ec, args, true);
}
}
@@ -897,7 +897,7 @@ namespace Mono.CSharp
args.Add (new Argument (exceptionVariable));
using (ec.With (BuilderContext.Options.OmitDebugInfo, true)) {
mg.EmitCall (ec, args);
mg.EmitCall (ec, args, true);
}
}
@@ -921,7 +921,7 @@ namespace Mono.CSharp
}
using (ec.With (BuilderContext.Options.OmitDebugInfo, true)) {
mg.EmitCall (ec, args);
mg.EmitCall (ec, args, true);
}
}

View File

@@ -861,9 +861,22 @@ namespace Mono.CSharp {
((IntConstant) right).Value);
return new IntConstant (ec.BuiltinTypes, res, left.Location);
} else {
throw new Exception ( "Unexepected modulus input: " + left);
}
if (left is DecimalConstant) {
decimal res;
if (ec.ConstantCheckState)
res = checked (((DecimalConstant) left).Value %
((DecimalConstant) right).Value);
else
res = unchecked (((DecimalConstant) left).Value %
((DecimalConstant) right).Value);
return new DecimalConstant (ec.BuiltinTypes, res, left.Location);
}
throw new Exception ( "Unexepected modulus input: " + left);
} catch (DivideByZeroException){
ec.Report.Error (20, loc, "Division by constant zero");
} catch (OverflowException){

View File

@@ -1 +1 @@
cda04c0e840c340724df311555d8b98032efd8bf
b1db2644e3be19de5f04184f3f8ac5e55b99f6e9

View File

@@ -121,6 +121,8 @@ namespace Mono.CSharp
}
}
public ConditionalAccessContext ConditionalAccess { get; set; }
public TypeSpec CurrentType {
get { return member_context.CurrentType; }
}
@@ -350,6 +352,15 @@ namespace Mono.CSharp
#endif
}
public void CloseConditionalAccess (TypeSpec type)
{
if (type != null)
Emit (OpCodes.Newobj, Nullable.NullableInfo.GetConstructor (type));
MarkLabel (ConditionalAccess.EndLabel);
ConditionalAccess = null;
}
//
// Creates a nested container in this context for all dynamic compiler generated stuff
//
@@ -978,12 +989,25 @@ namespace Mono.CSharp
}
}
public class ConditionalAccessContext
{
public ConditionalAccessContext (TypeSpec type, Label endLabel)
{
Type = type;
EndLabel = endLabel;
}
public bool Statement { get; set; }
public Label EndLabel { get; private set; }
public TypeSpec Type { get; private set; }
}
struct CallEmitter
{
public Expression InstanceExpression;
//
// When set leaves an extra copy of all arguments on the stack
// When call has to leave an extra copy of all arguments on the stack
//
public bool DuplicateArguments;
@@ -998,6 +1022,8 @@ namespace Mono.CSharp
//
public bool HasAwaitArguments;
public bool ConditionalAccess;
//
// When dealing with await arguments the original arguments are converted
// into a new set with hoisted stack results
@@ -1006,10 +1032,15 @@ namespace Mono.CSharp
public void Emit (EmitContext ec, MethodSpec method, Arguments Arguments, Location loc)
{
EmitPredefined (ec, method, Arguments, loc);
EmitPredefined (ec, method, Arguments, false, loc);
}
public void EmitPredefined (EmitContext ec, MethodSpec method, Arguments Arguments, Location? loc = null)
public void EmitStatement (EmitContext ec, MethodSpec method, Arguments Arguments, Location loc)
{
EmitPredefined (ec, method, Arguments, true, loc);
}
public void EmitPredefined (EmitContext ec, MethodSpec method, Arguments Arguments, bool statement = false, Location? loc = null)
{
Expression instance_copy = null;
@@ -1026,23 +1057,23 @@ namespace Mono.CSharp
if (method.IsStatic) {
call_op = OpCodes.Call;
} else {
if (IsVirtualCallRequired (InstanceExpression, method)) {
call_op = OpCodes.Callvirt;
} else {
call_op = OpCodes.Call;
}
call_op = IsVirtualCallRequired (InstanceExpression, method) ? OpCodes.Callvirt : OpCodes.Call;
if (HasAwaitArguments) {
instance_copy = InstanceExpression.EmitToField (ec);
if (Arguments == null)
EmitCallInstance (ec, instance_copy, method.DeclaringType, call_op);
var ie = new InstanceEmitter (instance_copy, IsAddressCall (instance_copy, call_op, method.DeclaringType));
if (Arguments == null) {
ie.EmitLoad (ec);
}
} else if (!InstanceExpressionOnStack) {
var instance_on_stack_type = EmitCallInstance (ec, InstanceExpression, method.DeclaringType, call_op);
var ie = new InstanceEmitter (InstanceExpression, IsAddressCall (InstanceExpression, call_op, method.DeclaringType));
ie.Emit (ec, ConditionalAccess);
if (DuplicateArguments) {
ec.Emit (OpCodes.Dup);
if (Arguments != null && Arguments.Count != 0) {
lt = new LocalTemporary (instance_on_stack_type);
lt = new LocalTemporary (ie.GetStackType (ec));
lt.Store (ec);
instance_copy = lt;
}
@@ -1054,7 +1085,8 @@ namespace Mono.CSharp
EmittedArguments = Arguments.Emit (ec, DuplicateArguments, HasAwaitArguments);
if (EmittedArguments != null) {
if (instance_copy != null) {
EmitCallInstance (ec, instance_copy, method.DeclaringType, call_op);
var ie = new InstanceEmitter (instance_copy, IsAddressCall (instance_copy, call_op, method.DeclaringType));
ie.Emit (ec, ConditionalAccess);
if (lt != null)
lt.Release (ec);
@@ -1085,55 +1117,21 @@ namespace Mono.CSharp
if (method.Parameters.HasArglist) {
var varargs_types = GetVarargsTypes (method, Arguments);
ec.Emit (call_op, method, varargs_types);
return;
}
//
// If you have:
// this.DoFoo ();
// and DoFoo is not virtual, you can omit the callvirt,
// because you don't need the null checking behavior.
//
ec.Emit (call_op, method);
}
static TypeSpec EmitCallInstance (EmitContext ec, Expression instance, TypeSpec declaringType, OpCode callOpcode)
{
var instance_type = instance.Type;
//
// Push the instance expression
//
if ((instance_type.IsStructOrEnum && (callOpcode == OpCodes.Callvirt || (callOpcode == OpCodes.Call && declaringType.IsStruct))) ||
instance_type.IsGenericParameter || declaringType.IsNullableType) {
} else {
//
// If the expression implements IMemoryLocation, then
// we can optimize and use AddressOf on the
// return.
// If you have:
// this.DoFoo ();
// and DoFoo is not virtual, you can omit the callvirt,
// because you don't need the null checking behavior.
//
// If not we have to use some temporary storage for
// it.
var iml = instance as IMemoryLocation;
if (iml != null) {
iml.AddressOf (ec, AddressOp.Load);
} else {
LocalTemporary temp = new LocalTemporary (instance_type);
instance.Emit (ec);
temp.Store (ec);
temp.AddressOf (ec, AddressOp.Load);
}
return ReferenceContainer.MakeType (ec.Module, instance_type);
ec.Emit (call_op, method);
}
if (instance_type.IsStructOrEnum) {
instance.Emit (ec);
ec.Emit (OpCodes.Box, instance_type);
return ec.BuiltinTypes.Object;
}
instance.Emit (ec);
return instance_type;
//
// Pop the return value if there is one and stack should be empty
//
if (statement && method.ReturnType.Kind != MemberKind.Void)
ec.Emit (OpCodes.Pop);
}
static MetaType[] GetVarargsTypes (MethodSpec method, Arguments arguments)
@@ -1169,11 +1167,199 @@ namespace Mono.CSharp
// It's non-virtual and will never be null and it can be determined
// whether it's known value or reference type by verifier
//
if (!method.IsVirtual && (instance is This || instance is New || instance is ArrayCreation || instance is DelegateCreation) &&
!instance.Type.IsGenericParameter)
if (!method.IsVirtual && Expression.IsNeverNull (instance) && !instance.Type.IsGenericParameter)
return false;
return true;
}
static bool IsAddressCall (Expression instance, OpCode callOpcode, TypeSpec declaringType)
{
var instance_type = instance.Type;
return (instance_type.IsStructOrEnum && (callOpcode == OpCodes.Callvirt || (callOpcode == OpCodes.Call && declaringType.IsStruct))) ||
instance_type.IsGenericParameter || declaringType.IsNullableType;
}
}
public struct InstanceEmitter
{
readonly Expression instance;
readonly bool addressRequired;
public InstanceEmitter (Expression instance, bool addressLoad)
{
this.instance = instance;
this.addressRequired = addressLoad;
}
public void Emit (EmitContext ec, bool conditionalAccess)
{
Label NullOperatorLabel;
Nullable.Unwrap unwrap;
if (conditionalAccess && Expression.IsNeverNull (instance))
conditionalAccess = false;
if (conditionalAccess) {
NullOperatorLabel = ec.DefineLabel ();
unwrap = instance as Nullable.Unwrap;
} else {
NullOperatorLabel = new Label ();
unwrap = null;
}
IMemoryLocation instance_address = null;
bool conditional_access_dup = false;
if (unwrap != null) {
unwrap.Store (ec);
unwrap.EmitCheck (ec);
ec.Emit (OpCodes.Brtrue_S, NullOperatorLabel);
} else {
if (conditionalAccess && addressRequired) {
//
// Don't allocate temp variable when instance load is cheap and load and load-address
// operate on same memory
//
instance_address = instance as VariableReference;
if (instance_address == null)
instance_address = instance as LocalTemporary;
if (instance_address == null) {
EmitLoad (ec);
ec.Emit (OpCodes.Dup);
ec.EmitLoadFromPtr (instance.Type);
conditional_access_dup = true;
} else {
instance.Emit (ec);
}
if (instance.Type.Kind == MemberKind.TypeParameter)
ec.Emit (OpCodes.Box, instance.Type);
} else {
EmitLoad (ec);
if (conditionalAccess) {
conditional_access_dup = !IsInexpensiveLoad ();
if (conditional_access_dup)
ec.Emit (OpCodes.Dup);
}
}
if (conditionalAccess) {
ec.Emit (OpCodes.Brtrue_S, NullOperatorLabel);
if (conditional_access_dup)
ec.Emit (OpCodes.Pop);
}
}
if (conditionalAccess) {
if (!ec.ConditionalAccess.Statement) {
if (ec.ConditionalAccess.Type.IsNullableType)
Nullable.LiftedNull.Create (ec.ConditionalAccess.Type, Location.Null).Emit (ec);
else
ec.EmitNull ();
}
ec.Emit (OpCodes.Br, ec.ConditionalAccess.EndLabel);
ec.MarkLabel (NullOperatorLabel);
if (instance_address != null) {
instance_address.AddressOf (ec, AddressOp.Load);
} else if (unwrap != null) {
unwrap.Emit (ec);
var tmp = ec.GetTemporaryLocal (unwrap.Type);
ec.Emit (OpCodes.Stloc, tmp);
ec.Emit (OpCodes.Ldloca, tmp);
ec.FreeTemporaryLocal (tmp, unwrap.Type);
} else if (!conditional_access_dup) {
instance.Emit (ec);
}
}
}
public void EmitLoad (EmitContext ec)
{
var instance_type = instance.Type;
//
// Push the instance expression
//
if (addressRequired) {
//
// 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.
var iml = instance as IMemoryLocation;
if (iml != null) {
iml.AddressOf (ec, AddressOp.Load);
} else {
LocalTemporary temp = new LocalTemporary (instance_type);
instance.Emit (ec);
temp.Store (ec);
temp.AddressOf (ec, AddressOp.Load);
}
return;
}
instance.Emit (ec);
// Only to make verifier happy
if (RequiresBoxing ())
ec.Emit (OpCodes.Box, instance_type);
}
public TypeSpec GetStackType (EmitContext ec)
{
var instance_type = instance.Type;
if (addressRequired)
return ReferenceContainer.MakeType (ec.Module, instance_type);
if (instance_type.IsStructOrEnum)
return ec.Module.Compiler.BuiltinTypes.Object;
return instance_type;
}
bool RequiresBoxing ()
{
var instance_type = instance.Type;
if (instance_type.IsGenericParameter && !(instance is This) && TypeSpec.IsReferenceType (instance_type))
return true;
if (instance_type.IsStructOrEnum)
return true;
return false;
}
bool IsInexpensiveLoad ()
{
if (instance is Constant)
return instance.IsSideEffectFree;
if (RequiresBoxing ())
return false;
var vr = instance as VariableReference;
if (vr != null)
return !vr.IsRef;
if (instance is LocalTemporary)
return true;
var fe = instance as FieldExpr;
if (fe != null)
return fe.IsStatic || fe.InstanceExpression is This;
return false;
}
}
}

View File

@@ -2031,8 +2031,6 @@ namespace Mono.CSharp {
}
public class StringConstant : Constant {
public readonly string Value;
public StringConstant (BuiltinTypes types, string s, Location loc)
: this (types.String, s, loc)
{
@@ -2047,6 +2045,13 @@ namespace Mono.CSharp {
Value = s;
}
protected StringConstant (Location loc)
: base (loc)
{
}
public string Value { get; protected set; }
public override object GetValue ()
{
return Value;
@@ -2129,6 +2134,113 @@ namespace Mono.CSharp {
}
}
class NameOf : StringConstant
{
readonly SimpleName name;
public NameOf (SimpleName name)
: base (name.Location)
{
this.name = name;
}
protected override Expression DoResolve (ResolveContext rc)
{
throw new NotSupportedException ();
}
bool ResolveArgumentExpression (ResolveContext rc, Expression expr)
{
var sn = expr as SimpleName;
if (sn != null) {
Value = sn.Name;
if (rc.Module.Compiler.Settings.Version < LanguageVersion.V_6)
rc.Report.FeatureIsNotAvailable (rc.Module.Compiler, Location, "nameof operator");
if (sn.HasTypeArguments) {
// TODO: csc compatible but unhelpful error message
rc.Report.Error (1001, loc, "Identifier expected");
return true;
}
sn.LookupNameExpression (rc, MemberLookupRestrictions.IgnoreArity | MemberLookupRestrictions.IgnoreAmbiguity);
return true;
}
var ma = expr as MemberAccess;
if (ma != null) {
FullNamedExpression fne = ma.LeftExpression as ATypeNameExpression;
if (fne == null) {
var qam = ma as QualifiedAliasMember;
if (qam == null)
return false;
fne = qam.CreateExpressionFromAlias (rc);
if (fne == null)
return true;
}
Value = ma.Name;
if (rc.Module.Compiler.Settings.Version < LanguageVersion.V_6)
rc.Report.FeatureIsNotAvailable (rc.Module.Compiler, Location, "nameof operator");
if (ma.HasTypeArguments) {
// TODO: csc compatible but unhelpful error message
rc.Report.Error (1001, loc, "Identifier expected");
return true;
}
var left = fne.ResolveAsTypeOrNamespace (rc, true);
if (left == null)
return true;
var ns = left as NamespaceExpression;
if (ns != null) {
FullNamedExpression retval = ns.LookupTypeOrNamespace (rc, ma.Name, 0, LookupMode.NameOf, loc);
if (retval == null)
ns.Error_NamespaceDoesNotExist (rc, ma.Name, 0);
return true;
}
if (left.Type.IsGenericOrParentIsGeneric && left.Type.GetDefinition () != left.Type) {
rc.Report.Error (8071, loc, "Type arguments are not allowed in the nameof operator");
}
var mexpr = MemberLookup (rc, false, left.Type, ma.Name, 0, MemberLookupRestrictions.IgnoreArity | MemberLookupRestrictions.IgnoreAmbiguity, loc);
if (mexpr == null) {
ma.Error_IdentifierNotFound (rc, left.Type);
return true;
}
return true;
}
return false;
}
public Expression ResolveOverload (ResolveContext rc, Arguments args)
{
if (args == null || args.Count != 1) {
name.Error_NameDoesNotExist (rc);
return null;
}
var arg = args [0];
var res = ResolveArgumentExpression (rc, arg.Expr);
if (!res) {
name.Error_NameDoesNotExist (rc);
return null;
}
type = rc.BuiltinTypes.String;
eclass = ExprClass.Value;
return this;
}
}
//
// Null constant can have its own type, think of `default (Foo)'
//

View File

@@ -14,6 +14,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Diagnostics;
namespace Mono.CSharp
{
@@ -21,7 +22,8 @@ namespace Mono.CSharp
{
Normal = 0,
Probing = 1,
IgnoreAccessibility = 2
IgnoreAccessibility = 2,
NameOf = 3
}
//
@@ -188,6 +190,8 @@ namespace Mono.CSharp
TryWithCatchScope = 1 << 15,
ConditionalAccessReceiver = 1 << 16,
///
/// Indicates the current context is in probing mode, no errors are reported.
///
@@ -442,6 +446,7 @@ namespace Mono.CSharp
public class FlowAnalysisContext
{
readonly CompilerContext ctx;
DefiniteAssignmentBitSet conditional_access;
public FlowAnalysisContext (CompilerContext ctx, ParametersBlock parametersBlock, int definiteAssignmentLength)
{
@@ -483,6 +488,19 @@ namespace Mono.CSharp
return dat;
}
public void BranchConditionalAccessDefiniteAssignment ()
{
if (conditional_access == null)
conditional_access = BranchDefiniteAssignment ();
}
public void ConditionalAccessEnd ()
{
Debug.Assert (conditional_access != null);
DefiniteAssignment = conditional_access;
conditional_access = null;
}
public bool IsDefinitelyAssigned (VariableInfo variable)
{
return variable.IsAssigned (DefiniteAssignment);

View File

@@ -345,7 +345,7 @@ namespace Mono.CSharp {
if (target_type.Kind == MemberKind.InternalCompilerType)
return target_type.BuiltinType == BuiltinTypeSpec.Type.Dynamic;
return TypeSpec.IsReferenceType (target_type);
return TypeSpec.IsReferenceType (target_type) || target_type.Kind == MemberKind.PointerType;
}
//

View File

@@ -1 +1 @@
2cfa7f1846374357ed745eab43bf41e85fa4e9d3
726b1f6dcdd3a442f01b3273228c570a4dc5f031

View File

@@ -202,7 +202,6 @@ namespace Mono.CSharp
bool handle_get_set = false;
bool handle_remove_add = false;
bool handle_where;
bool handle_typeof = false;
bool lambda_arguments_parsing;
List<Location> escaped_identifiers;
int parsing_generic_less_than;
@@ -320,11 +319,6 @@ namespace Mono.CSharp
get { return handle_where; }
set { handle_where = value; }
}
public bool TypeOfParsing {
get { return handle_typeof; }
set { handle_typeof = value; }
}
public XmlCommentState doc_state {
get { return xml_doc_state; }
@@ -729,6 +723,7 @@ namespace Mono.CSharp
case Token.BYTE:
case Token.CHAR:
case Token.DECIMAL:
case Token.DOUBLE:
case Token.FLOAT:
case Token.LONG:
case Token.OBJECT:
@@ -1144,7 +1139,7 @@ namespace Mono.CSharp
return true;
}
bool parse_less_than ()
bool parse_less_than (ref int genericDimension)
{
start:
int the_token = token ();
@@ -1181,10 +1176,23 @@ namespace Mono.CSharp
case Token.VOID:
break;
case Token.OP_GENERICS_GT:
genericDimension = 1;
return true;
case Token.IN:
case Token.OUT:
return true;
case Token.COMMA:
do {
++genericDimension;
the_token = token ();
} while (the_token == Token.COMMA);
if (the_token == Token.OP_GENERICS_GT) {
++genericDimension;
return true;
}
return false;
default:
return false;
}
@@ -1198,7 +1206,7 @@ namespace Mono.CSharp
else if (the_token == Token.INTERR_NULLABLE || the_token == Token.STAR)
goto again;
else if (the_token == Token.OP_GENERICS_LT) {
if (!parse_less_than ())
if (!parse_less_than (ref genericDimension))
return false;
goto again;
} else if (the_token == Token.OPEN_BRACKET) {
@@ -1214,22 +1222,6 @@ namespace Mono.CSharp
return false;
}
bool parse_generic_dimension (out int dimension)
{
dimension = 1;
again:
int the_token = token ();
if (the_token == Token.OP_GENERICS_GT)
return true;
else if (the_token == Token.COMMA) {
dimension++;
goto again;
}
return false;
}
public int peek_token ()
{
int the_token;
@@ -1260,13 +1252,8 @@ namespace Mono.CSharp
return Token.OP_COALESCING;
}
switch (current_token) {
case Token.CLOSE_PARENS:
case Token.TRUE:
case Token.FALSE:
case Token.NULL:
case Token.LITERAL:
return Token.INTERR;
if (d == '.') {
return Token.INTERR_OPERATOR;
}
if (d != ' ') {
@@ -1280,8 +1267,14 @@ namespace Mono.CSharp
current_token = Token.NONE;
int next_token;
int parens = 0;
int generics = 0;
switch (xtoken ()) {
var nt = xtoken ();
switch (nt) {
case Token.DOT:
case Token.OPEN_BRACKET_EXPR:
next_token = Token.INTERR_OPERATOR;
break;
case Token.LITERAL:
case Token.TRUE:
case Token.FALSE:
@@ -1308,7 +1301,14 @@ namespace Mono.CSharp
next_token = -1;
++parens;
break;
case Token.OP_GENERICS_LT:
case Token.OP_GENERICS_LT_DECL:
case Token.GENERIC_DIMENSION:
next_token = -1;
++generics;
break;
default:
next_token = -1;
break;
@@ -1334,11 +1334,18 @@ namespace Mono.CSharp
++parens;
goto default;
case Token.OP_GENERICS_LT:
case Token.OP_GENERICS_LT_DECL:
case Token.GENERIC_DIMENSION:
++generics;
goto default;
default:
int ntoken;
int interrs = 1;
int colons = 0;
int braces = 0;
int brackets = 0;
//
// All shorcuts failed, do it hard way
//
@@ -1355,12 +1362,33 @@ namespace Mono.CSharp
case Token.CLOSE_BRACE:
--braces;
continue;
case Token.OP_GENERICS_LT:
case Token.OP_GENERICS_LT_DECL:
case Token.GENERIC_DIMENSION:
++generics;
continue;
case Token.OPEN_BRACKET:
case Token.OPEN_BRACKET_EXPR:
++brackets;
continue;
case Token.CLOSE_BRACKET:
--brackets;
continue;
case Token.CLOSE_PARENS:
if (parens > 0) {
--parens;
continue;
}
PopPosition ();
return Token.INTERR_NULLABLE;
case Token.OP_GENERICS_GT:
if (generics > 0) {
--generics;
continue;
}
PopPosition ();
return Token.INTERR_NULLABLE;
}
@@ -1373,6 +1401,14 @@ namespace Mono.CSharp
if (parens != 0)
continue;
if (ntoken == Token.COMMA) {
if (generics != 0 || brackets != 0)
continue;
PopPosition ();
return Token.INTERR_NULLABLE;
}
if (ntoken == Token.COLON) {
if (++colons == interrs)
@@ -3669,22 +3705,20 @@ namespace Mono.CSharp
int TokenizeLessThan ()
{
int d;
if (handle_typeof) {
PushPosition ();
if (parse_generic_dimension (out d)) {
val = d;
DiscardPosition ();
return Token.GENERIC_DIMENSION;
}
PopPosition ();
}
// Save current position and parse next token.
PushPosition ();
if (parse_less_than ()) {
int generic_dimension = 0;
if (parse_less_than (ref generic_dimension)) {
if (parsing_generic_declaration && (parsing_generic_declaration_doc || token () != Token.DOT)) {
d = Token.OP_GENERICS_LT_DECL;
} else {
if (generic_dimension > 0) {
val = generic_dimension;
DiscardPosition ();
return Token.GENERIC_DIMENSION;
}
d = Token.OP_GENERICS_LT;
}
PopPosition ();

View File

@@ -195,11 +195,6 @@ namespace Mono.CSharp {
return name + "`" + args.Count;
}
public static string MakeName (string name, int count)
{
return name + "`" + count;
}
}
public class SimpleMemberName

View File

@@ -439,6 +439,7 @@ namespace Mono.CSharp {
//
public abstract class DelegateCreation : Expression, OverloadResolver.IErrorHandler
{
bool conditional_access_receiver;
protected MethodSpec constructor_method;
protected MethodGroupExpr method_group;
@@ -507,8 +508,19 @@ namespace Mono.CSharp {
var invoke_method = Delegate.GetInvokeMethod (type);
if (!ec.HasSet (ResolveContext.Options.ConditionalAccessReceiver)) {
if (method_group.HasConditionalAccess ()) {
conditional_access_receiver = true;
ec.Set (ResolveContext.Options.ConditionalAccessReceiver);
}
}
Arguments arguments = CreateDelegateMethodArguments (ec, invoke_method.Parameters, invoke_method.Parameters.Types, loc);
method_group = method_group.OverloadResolve (ec, ref arguments, this, OverloadResolver.Restrictions.CovariantDelegate);
if (conditional_access_receiver)
ec.With (ResolveContext.Options.ConditionalAccessReceiver, false);
if (method_group == null)
return null;
@@ -564,10 +576,15 @@ namespace Mono.CSharp {
public override void Emit (EmitContext ec)
{
if (method_group.InstanceExpression == null)
if (conditional_access_receiver)
ec.ConditionalAccess = new ConditionalAccessContext (type, ec.DefineLabel ());
if (method_group.InstanceExpression == null) {
ec.EmitNull ();
else
method_group.InstanceExpression.Emit (ec);
} else {
var ie = new InstanceEmitter (method_group.InstanceExpression, false);
ie.Emit (ec, method_group.ConditionalAccess);
}
var delegate_method = method_group.BestCandidate;
@@ -580,11 +597,18 @@ namespace Mono.CSharp {
}
ec.Emit (OpCodes.Newobj, constructor_method);
if (conditional_access_receiver)
ec.CloseConditionalAccess (null);
}
public override void FlowAnalysis (FlowAnalysisContext fc) {
public override void FlowAnalysis (FlowAnalysisContext fc)
{
base.FlowAnalysis (fc);
method_group.FlowAnalysis (fc);
if (conditional_access_receiver)
fc.ConditionalAccessEnd ();
}
void Error_ConversionFailed (ResolveContext ec, MethodSpec method, Expression return_type)
@@ -830,13 +854,15 @@ namespace Mono.CSharp {
class DelegateInvocation : ExpressionStatement
{
readonly Expression InstanceExpr;
readonly bool conditionalAccessReceiver;
Arguments arguments;
MethodSpec method;
public DelegateInvocation (Expression instance_expr, Arguments args, Location loc)
public DelegateInvocation (Expression instance_expr, Arguments args, bool conditionalAccessReceiver, Location loc)
{
this.InstanceExpr = instance_expr;
this.arguments = args;
this.conditionalAccessReceiver = conditionalAccessReceiver;
this.loc = loc;
}
@@ -877,29 +903,45 @@ namespace Mono.CSharp {
return null;
type = method.ReturnType;
if (conditionalAccessReceiver)
type = LiftMemberType (ec, type);
eclass = ExprClass.Value;
return this;
}
public override void Emit (EmitContext ec)
{
if (conditionalAccessReceiver) {
ec.ConditionalAccess = new ConditionalAccessContext (type, ec.DefineLabel ());
}
//
// Invocation on delegates call the virtual Invoke member
// so we are always `instance' calls
//
var call = new CallEmitter ();
call.InstanceExpression = InstanceExpr;
call.EmitPredefined (ec, method, arguments, loc);
call.Emit (ec, method, arguments, loc);
if (conditionalAccessReceiver)
ec.CloseConditionalAccess (type.IsNullableType && type != method.ReturnType ? type : null);
}
public override void EmitStatement (EmitContext ec)
{
Emit (ec);
//
// Pop the return value if there is one
//
if (type.Kind != MemberKind.Void)
ec.Emit (OpCodes.Pop);
if (conditionalAccessReceiver) {
ec.ConditionalAccess = new ConditionalAccessContext (type, ec.DefineLabel ()) {
Statement = true
};
}
var call = new CallEmitter ();
call.InstanceExpression = InstanceExpr;
call.EmitStatement (ec, method, arguments, loc);
if (conditionalAccessReceiver)
ec.CloseConditionalAccess (null);
}
public override System.Linq.Expressions.Expression MakeExpression (BuilderContext ctx)

View File

@@ -48,7 +48,7 @@ namespace Mono.CSharp
this.loc = loc;
}
public override TypeSpec ResolveAsType (IMemberContext ec)
public override TypeSpec ResolveAsType (IMemberContext ec, bool allowUnboundTypeArguments)
{
eclass = ExprClass.Type;
type = ec.Module.Compiler.BuiltinTypes.Dynamic;
@@ -534,7 +534,7 @@ namespace Mono.CSharp
}
}
Expression target = new DelegateInvocation (new MemberAccess (site_field_expr, "Target", loc).Resolve (bc), args, loc).Resolve (bc);
Expression target = new DelegateInvocation (new MemberAccess (site_field_expr, "Target", loc).Resolve (bc), args, false, loc).Resolve (bc);
if (target != null)
target.Emit (ec);
}

View File

@@ -1 +1 @@
f0a9de98b6103af652e3d63bcae44183a33246f7
5729e21b3e7e9275a1fe18a577598f104e3fe16e

View File

@@ -28,7 +28,7 @@ namespace Mono.CSharp {
{
class EnumTypeExpr : TypeExpr
{
public override TypeSpec ResolveAsType (IMemberContext ec)
public override TypeSpec ResolveAsType (IMemberContext ec, bool allowUnboundTypeArguments)
{
type = ec.CurrentType;
eclass = ExprClass.Type;
@@ -64,11 +64,12 @@ namespace Mono.CSharp {
if (expr is EnumConstant)
expr = ((EnumConstant) expr).Child;
var underlying = ((Enum) Parent).UnderlyingType;
var en = (Enum)Parent;
var underlying = en.UnderlyingType;
if (expr != null) {
expr = expr.ImplicitConversionRequired (rc, underlying);
if (expr != null && !IsValidEnumType (expr.Type)) {
Enum.Error_1008 (Location, Report);
en.Error_UnderlyingType (Location);
expr = null;
}
}
@@ -217,7 +218,7 @@ namespace Mono.CSharp {
AddMember (em);
}
public static void Error_1008 (Location loc, Report Report)
public void Error_UnderlyingType (Location loc)
{
Report.Error (1008, loc,
"Type byte, sbyte, short, ushort, int, uint, long or ulong expected");
@@ -225,7 +226,21 @@ namespace Mono.CSharp {
protected override void DoDefineContainer ()
{
((EnumSpec) spec).UnderlyingType = underlying_type_expr == null ? Compiler.BuiltinTypes.Int : underlying_type_expr.Type;
TypeSpec ut;
if (underlying_type_expr != null) {
ut = underlying_type_expr.ResolveAsType (this);
if (!EnumSpec.IsValidUnderlyingType (ut)) {
Error_UnderlyingType (underlying_type_expr.Location);
ut = null;
}
} else {
ut = null;
}
if (ut == null)
ut = Compiler.BuiltinTypes.Int;
((EnumSpec) spec).UnderlyingType = ut;
TypeBuilder.DefineField (UnderlyingValueField, UnderlyingType.GetMetaInfo (),
FieldAttributes.Public | FieldAttributes.SpecialName | FieldAttributes.RTSpecialName);

View File

@@ -1277,7 +1277,7 @@ namespace Mono.CSharp
if (current_container.Containers != null)
{
var existing = current_container.Containers.FirstOrDefault (l => l.Basename == tc.Basename);
var existing = current_container.Containers.FirstOrDefault (l => l.MemberName.Basename == tc.MemberName.Basename);
if (existing != null) {
current_container.RemoveContainer (existing);
undo_actions.Add (() => current_container.AddTypeContainer (existing));

View File

@@ -1 +1 @@
0ab48acb382e4c47a8494814726d8a2c6ce99dff
4fa922c0110f8f4278cecea17e40d6b036d503ac

View File

@@ -709,7 +709,7 @@ namespace Mono.CSharp
loc = parameter.Location;
}
public override TypeSpec ResolveAsType (IMemberContext mc)
public override TypeSpec ResolveAsType (IMemberContext mc, bool allowUnboundTypeArguments)
{
return parameter.Type;
}

View File

@@ -106,7 +106,7 @@ namespace Mono.CSharp {
throw new NotImplementedException ();
}
public override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext ec)
public override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext mc, bool allowUnboundTypeArguments)
{
throw new NotImplementedException ();
}
@@ -1147,7 +1147,7 @@ namespace Mono.CSharp {
if (other.targs != null) {
foreach (var otarg in other.targs) {
if (TypeSpecComparer.Override.IsEqual (BaseType, otarg)) {
if (TypeSpecComparer.Override.IsEqual (iface, otarg)) {
found = true;
break;
}
@@ -2426,7 +2426,7 @@ namespace Mono.CSharp {
return type.GetSignatureForError ();
}
public override TypeSpec ResolveAsType (IMemberContext mc)
public override TypeSpec ResolveAsType (IMemberContext mc, bool allowUnboundTypeArguments = false)
{
if (eclass != ExprClass.Unresolved)
return type;

View File

@@ -1287,6 +1287,23 @@ namespace Mono.CSharp
public string DefaultIndexerName;
public bool? CLSAttributeValue;
public TypeSpec CoClass;
static bool HasMissingType (ConstructorInfo ctor)
{
#if STATIC
//
// Mimic odd csc behaviour where missing type on predefined
// attributes means the attribute is silently ignored. This can
// happen with PCL facades
//
foreach (var p in ctor.GetParameters ()) {
if (p.ParameterType.__ContainsMissingType)
return true;
}
#endif
return false;
}
public static AttributesBag Read (MemberInfo mi, MetadataImporter importer)
{
@@ -1361,6 +1378,9 @@ namespace Mono.CSharp
if (dt.Namespace != "System")
continue;
if (HasMissingType (a.Constructor))
continue;
if (bag == null)
bag = new AttributesBag ();
@@ -1379,6 +1399,9 @@ namespace Mono.CSharp
if (dt.Namespace != "System.Runtime.InteropServices")
continue;
if (HasMissingType (a.Constructor))
continue;
if (bag == null)
bag = new AttributesBag ();

Some files were not shown because too many files have changed in this diff Show More