@ -327,17 +327,21 @@ namespace Mono.CSharp {
@@ -327,17 +327,21 @@ namespace Mono.CSharp {
EmbeddedStatement . Emit ( ec ) ;
ec . MarkLabel ( ec . LoopBegin ) ;
// Mark start of while condition
ec . Mark ( expr . Location ) ;
//
// Dead code elimination
//
if ( expr is Constant ) {
if ( expr is Constant ) {
bool res = ! ( ( Constant ) expr ) . IsDefaultValue ;
expr . EmitSideEffect ( ec ) ;
if ( res )
ec . Emit ( OpCodes . Br , loop ) ;
} else
ec . Emit ( OpCodes . Br , loop ) ;
} else {
expr . EmitBranchable ( ec , loop , true ) ;
}
ec . MarkLabel ( ec . LoopEnd ) ;
@ -427,9 +431,13 @@ namespace Mono.CSharp {
@@ -427,9 +431,13 @@ namespace Mono.CSharp {
//
// Inform whether we are infinite or not
//
if ( expr is Constant ) {
if ( expr is Constant ) {
// expr is 'true', since the 'empty' case above handles the 'false' case
ec . MarkLabel ( ec . LoopBegin ) ;
if ( ec . EmitAccurateDebugInfo )
ec . Emit ( OpCodes . Nop ) ;
expr . EmitSideEffect ( ec ) ;
Statement . Emit ( ec ) ;
ec . Emit ( OpCodes . Br , ec . LoopBegin ) ;
@ -448,8 +456,8 @@ namespace Mono.CSharp {
@@ -448,8 +456,8 @@ namespace Mono.CSharp {
Statement . Emit ( ec ) ;
ec . MarkLabel ( ec . LoopBegin ) ;
ec . Mark ( loc ) ;
ec . Mark ( expr . Location ) ;
expr . EmitBranchable ( ec , while_loop , true ) ;
ec . MarkLabel ( ec . LoopEnd ) ;
@ -459,11 +467,6 @@ namespace Mono.CSharp {
@@ -459,11 +467,6 @@ namespace Mono.CSharp {
ec . LoopEnd = old_end ;
}
public override void Emit ( EmitContext ec )
{
DoEmit ( ec ) ;
}
protected override void CloneTo ( CloneContext clonectx , Statement t )
{
While target = ( While ) t ;
@ -592,7 +595,9 @@ namespace Mono.CSharp {
@@ -592,7 +595,9 @@ namespace Mono.CSharp {
// If test is null, there is no test, and we are just
// an infinite loop
//
if ( Condition ! = null ) {
if ( Condition ! = null ) {
ec . Mark ( Condition . Location ) ;
//
// The Resolve code already catches the case for
// Test == Constant (false) so we know that
@ -1853,7 +1858,7 @@ namespace Mono.CSharp {
@@ -1853,7 +1858,7 @@ namespace Mono.CSharp {
// All fixed variabled are pinned, a slot has to be alocated
//
builder = ec . DeclareLocal ( Type , IsFixed ) ;
if ( SymbolWriter . HasSymbolWriter )
if ( ! ec . HasSet ( BuilderContext . Options . OmitDebugInfo ) & & ( flags & Flags . CompilerGenerated ) = = 0 )
ec . DefineLocalVariable ( name , builder ) ;
}
@ -2057,6 +2062,9 @@ namespace Mono.CSharp {
@@ -2057,6 +2062,9 @@ namespace Mono.CSharp {
get {
return ( flags & Flags . HasRet ) ! = 0 ;
}
set {
flags = value ? flags | Flags . HasRet : flags & ~ Flags . HasRet ;
}
}
public Block Original {
@ -2453,7 +2461,7 @@ namespace Mono.CSharp {
@@ -2453,7 +2461,7 @@ namespace Mono.CSharp {
if ( scope_initializers ! = null )
EmitScopeInitializers ( ec ) ;
if ( ec . EmitAccurateDebugInfo & & ec . Mark ( StartLocation ) ) {
if ( ec . EmitAccurateDebugInfo & & ! IsCompilerGenerated & & ec . Mark ( StartLocation ) ) {
ec . Emit ( OpCodes . Nop ) ;
}
@ -2469,7 +2477,7 @@ namespace Mono.CSharp {
@@ -2469,7 +2477,7 @@ namespace Mono.CSharp {
if ( emit_debug_info )
ec . EndScope ( ) ;
if ( ec . EmitAccurateDebugInfo & & ! HasUnreachableClosingBrace & & ec . Mark ( EndLocation ) ) {
if ( ec . EmitAccurateDebugInfo & & ! HasUnreachableClosingBrace & & ! IsCompilerGenerated & & ec . Mark ( EndLocation ) ) {
ec . Emit ( OpCodes . Nop ) ;
}
}
@ -2942,8 +2950,7 @@ namespace Mono.CSharp {
@@ -2942,8 +2950,7 @@ namespace Mono.CSharp {
public void WrapIntoIterator ( IMethodData method , TypeDefinition host , TypeSpec iterator_type , bool is_enumerable )
{
ParametersBlock pb = new ParametersBlock ( this , ParametersCompiled . EmptyReadOnlyParameters , StartLocation ) ;
pb . EndLocation = EndLocation ;
ParametersBlock pb = new ParametersBlock ( this , ParametersCompiled . EmptyReadOnlyParameters , Location . Null ) ;
pb . statements = statements ;
pb . Original = this ;
@ -2953,6 +2960,7 @@ namespace Mono.CSharp {
@@ -2953,6 +2960,7 @@ namespace Mono.CSharp {
statements = new List < Statement > ( 1 ) ;
AddStatement ( new Return ( iterator , iterator . Location ) ) ;
flags & = ~ Flags . YieldBlock ;
IsCompilerGenerated = true ;
}
public void WrapIntoAsyncTask ( IMemberContext context , TypeDefinition host , TypeSpec returnType )
@ -4078,7 +4086,10 @@ namespace Mono.CSharp {
@@ -4078,7 +4086,10 @@ namespace Mono.CSharp {
}
}
simple_stmt = new If ( cond , s . Block , simple_stmt , loc ) ;
//
// Compiler generated, hide from symbol file
//
simple_stmt = new If ( cond , s . Block , simple_stmt , Location . Null ) ;
}
// It's null for empty switch
@ -4166,7 +4177,9 @@ namespace Mono.CSharp {
@@ -4166,7 +4177,9 @@ namespace Mono.CSharp {
// Check if string dictionary is initialized and initialize
//
switch_cache_field . EmitBranchable ( ec , l_initialized , true ) ;
string_dictionary . EmitStatement ( ec ) ;
using ( ec . With ( BuilderContext . Options . OmitDebugInfo , true ) ) {
string_dictionary . EmitStatement ( ec ) ;
}
ec . MarkLabel ( l_initialized ) ;
LocalTemporary string_switch_variable = new LocalTemporary ( ec . BuiltinTypes . Int ) ;
@ -4210,6 +4223,9 @@ namespace Mono.CSharp {
@@ -4210,6 +4223,9 @@ namespace Mono.CSharp {
protected override void DoEmit ( EmitContext ec )
{
// Workaround broken flow-analysis
block . HasUnreachableClosingBrace = true ;
//
// Needed to emit anonymous storey initialization
// Otherwise it does not contain any statements for now
@ -5117,17 +5133,13 @@ namespace Mono.CSharp {
@@ -5117,17 +5133,13 @@ namespace Mono.CSharp {
//
if ( li . HoistedVariant ! = null ) {
LocalTemporary lt = new LocalTemporary ( li . Type ) ;
SymbolWriter . OpenCompilerGeneratedBlock ( ec ) ;
lt . Store ( ec ) ;
SymbolWriter . CloseCompilerGeneratedBlock ( ec ) ;
// switch to assigning from the temporary variable and not from top of the stack
assign . UpdateSource ( lt ) ;
}
} else {
SymbolWriter . OpenCompilerGeneratedBlock ( ec ) ;
ec . Emit ( OpCodes . Pop ) ;
SymbolWriter . CloseCompilerGeneratedBlock ( ec ) ;
}
Block . Emit ( ec ) ;
@ -5152,8 +5164,11 @@ namespace Mono.CSharp {
@@ -5152,8 +5164,11 @@ namespace Mono.CSharp {
if ( li . Type . IsGenericParameter )
source = new UnboxCast ( source , li . Type ) ;
assign = new CompilerAssign ( new LocalVariableReference ( li , loc ) , source , loc ) ;
Block . AddScopeStatement ( new StatementExpression ( assign ) ) ;
//
// Uses Location.Null to hide from symbol file
//
assign = new CompilerAssign ( new LocalVariableReference ( li , Location . Null ) , source , Location . Null ) ;
Block . AddScopeStatement ( new StatementExpression ( assign , Location . Null ) ) ;
}
}
@ -5479,7 +5494,10 @@ namespace Mono.CSharp {
@@ -5479,7 +5494,10 @@ namespace Mono.CSharp {
new Cast ( new TypeExpression ( idt , loc ) , lvr , loc ) . Resolve ( bc ) :
lvr ;
Statement dispose = new StatementExpression ( new Invocation ( dispose_mg , null ) ) ;
//
// Hide it from symbol file via null location
//
Statement dispose = new StatementExpression ( new Invocation ( dispose_mg , null ) , Location . Null ) ;
// Add conditional call when disposing possible null variable
if ( ! type . IsStruct | | type . IsNullableType )
@ -5546,6 +5564,14 @@ namespace Mono.CSharp {
@@ -5546,6 +5564,14 @@ namespace Mono.CSharp {
#endregion
public override void Emit ( EmitContext ec )
{
//
// Don't emit sequence point it will be set on variable declaration
//
DoEmit ( ec ) ;
}
protected override void EmitTryBodyPrepare ( EmitContext ec )
{
decl . Emit ( ec ) ;
@ -5998,7 +6024,7 @@ namespace Mono.CSharp {
@@ -5998,7 +6024,7 @@ namespace Mono.CSharp {
return null ;
}
return MethodGroupExpr . CreatePredefined ( ms , enumerator . ReturnType , l oc) ;
return MethodGroupExpr . CreatePredefined ( ms , enumerator . ReturnType , expr . L ocation ) ;
}
PropertySpec ResolveCurrent ( ResolveContext rc , MethodSpec enumerator )
@ -6077,7 +6103,7 @@ namespace Mono.CSharp {
@@ -6077,7 +6103,7 @@ namespace Mono.CSharp {
var init = new Invocation ( get_enumerator_mg , null ) ;
statement = new While ( new BooleanExpression ( new Invocation ( move_next_mg , null ) ) ,
new Body ( variable . Type , variable , current_pe , statement , loc ) , loc ) ;
new Body ( variable . Type , variable , current_pe , statement , variab le . L ocation ) , Location . Null ) ;
var enum_type = enumerator_variable . Type ;
@ -6089,23 +6115,23 @@ namespace Mono.CSharp {
@@ -6089,23 +6115,23 @@ namespace Mono.CSharp {
//
// Runtime Dispose check
//
var vd = new RuntimeDispose ( enumerator_variable . LocalInfo , loc ) ;
var vd = new RuntimeDispose ( enumerator_variable . LocalInfo , Location . Null ) ;
vd . Initializer = init ;
statement = new Using ( vd , statement , loc ) ;
statement = new Using ( vd , statement , Location . Null ) ;
} else {
//
// No Dispose call needed
//
this . init = new SimpleAssign ( enumerator_variable , init ) ;
this . init = new SimpleAssign ( enumerator_variable , init , Location . Null ) ;
this . init . Resolve ( ec ) ;
}
} else {
//
// Static Dispose check
//
var vd = new Using . VariableDeclaration ( enumerator_variable . LocalInfo , loc ) ;
var vd = new Using . VariableDeclaration ( enumerator_variable . LocalInfo , Location . Null ) ;
vd . Initializer = init ;
statement = new Using ( vd , statement , loc ) ;
statement = new Using ( vd , statement , Location . Null ) ;
}
return statement . Resolve ( ec ) ;
@ -6126,7 +6152,7 @@ namespace Mono.CSharp {
@@ -6126,7 +6152,7 @@ namespace Mono.CSharp {
bool OverloadResolver . IErrorHandler . AmbiguousCandidates ( ResolveContext ec , MemberSpec best , MemberSpec ambiguous )
{
ec . Report . SymbolRelatedToPreviousError ( best ) ;
ec . Report . Warning ( 2 7 8 , 2 , l oc,
ec . Report . Warning ( 2 7 8 , 2 , expr . L ocation ,
"`{0}' contains ambiguous implementation of `{1}' pattern. Method `{2}' is ambiguous with method `{3}'" ,
expr . Type . GetSignatureForError ( ) , "enumerable" ,
best . GetSignatureForError ( ) , ambiguous . GetSignatureForError ( ) ) ;