diff --git a/ICSharpCode.Decompiler/DecompilerSettings.cs b/ICSharpCode.Decompiler/DecompilerSettings.cs
index 5e8858356..62247af52 100644
--- a/ICSharpCode.Decompiler/DecompilerSettings.cs
+++ b/ICSharpCode.Decompiler/DecompilerSettings.cs
@@ -29,7 +29,7 @@ namespace ICSharpCode.Decompiler
public class DecompilerSettings : INotifyPropertyChanged
{
bool anonymousMethods = true;
-
+
///
/// Decompile anonymous methods/lambdas.
///
@@ -59,7 +59,7 @@ namespace ICSharpCode.Decompiler
}
bool expressionTrees = true;
-
+
///
/// Decompile expression trees.
///
@@ -72,9 +72,9 @@ namespace ICSharpCode.Decompiler
}
}
}
-
+
bool yieldReturn = true;
-
+
///
/// Decompile enumerators.
///
@@ -87,9 +87,9 @@ namespace ICSharpCode.Decompiler
}
}
}
-
+
bool asyncAwait = true;
-
+
///
/// Decompile async methods.
///
@@ -134,7 +134,7 @@ namespace ICSharpCode.Decompiler
}
bool automaticProperties = true;
-
+
///
/// Decompile automatic properties
///
@@ -147,9 +147,9 @@ namespace ICSharpCode.Decompiler
}
}
}
-
+
bool automaticEvents = true;
-
+
///
/// Decompile automatic events
///
@@ -162,9 +162,9 @@ namespace ICSharpCode.Decompiler
}
}
}
-
+
bool usingStatement = true;
-
+
///
/// Decompile using statements.
///
@@ -177,9 +177,9 @@ namespace ICSharpCode.Decompiler
}
}
}
-
+
bool forEachStatement = true;
-
+
///
/// Decompile foreach statements.
///
@@ -192,9 +192,9 @@ namespace ICSharpCode.Decompiler
}
}
}
-
+
bool lockStatement = true;
-
+
///
/// Decompile lock statements.
///
@@ -207,9 +207,9 @@ namespace ICSharpCode.Decompiler
}
}
}
-
+
bool switchStatementOnString = true;
-
+
public bool SwitchStatementOnString {
get { return switchStatementOnString; }
set {
@@ -219,9 +219,9 @@ namespace ICSharpCode.Decompiler
}
}
}
-
+
bool usingDeclarations = true;
-
+
public bool UsingDeclarations {
get { return usingDeclarations; }
set {
@@ -231,9 +231,9 @@ namespace ICSharpCode.Decompiler
}
}
}
-
+
bool queryExpressions = true;
-
+
public bool QueryExpressions {
get { return queryExpressions; }
set {
@@ -262,7 +262,7 @@ namespace ICSharpCode.Decompiler
}
bool fullyQualifyAmbiguousTypeNames = true;
-
+
public bool FullyQualifyAmbiguousTypeNames {
get { return fullyQualifyAmbiguousTypeNames; }
set {
@@ -272,9 +272,9 @@ namespace ICSharpCode.Decompiler
}
}
}
-
+
bool useDebugSymbols = true;
-
+
///
/// Gets/Sets whether to use variable names from debug symbols, if available.
///
@@ -287,9 +287,9 @@ namespace ICSharpCode.Decompiler
}
}
}
-
+
bool objectCollectionInitializers = true;
-
+
///
/// Gets/Sets whether to use C# 3.0 object/collection initializers
///
@@ -302,9 +302,9 @@ namespace ICSharpCode.Decompiler
}
}
}
-
+
bool showXmlDocumentation = true;
-
+
///
/// Gets/Sets whether to include XML documentation comments in the decompiled code
///
@@ -319,7 +319,7 @@ namespace ICSharpCode.Decompiler
}
bool foldBraces = false;
-
+
public bool FoldBraces {
get { return foldBraces; }
set {
@@ -329,10 +329,10 @@ namespace ICSharpCode.Decompiler
}
}
}
-
+
#region Options to aid VB decompilation
bool introduceIncrementAndDecrement = true;
-
+
///
/// Gets/Sets whether to use increment and decrement operators
///
@@ -345,9 +345,9 @@ namespace ICSharpCode.Decompiler
}
}
}
-
+
bool makeAssignmentExpressions = true;
-
+
///
/// Gets/Sets whether to use assignment expressions such as in while ((count = Do()) != 0) ;
///
@@ -360,9 +360,9 @@ namespace ICSharpCode.Decompiler
}
}
}
-
+
bool alwaysGenerateExceptionVariableForCatchBlocks = false;
-
+
///
/// Gets/Sets whether to always generate exception variables in catch blocks
///
@@ -390,6 +390,20 @@ namespace ICSharpCode.Decompiler
#endregion
+ #region Options to aid F# decompilation
+ bool removeDeadCode = false;
+
+ public bool RemoveDeadCode {
+ get { return removeDeadCode; }
+ set {
+ if (removeDeadCode != value) {
+ removeDeadCode = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+ #endregion
+
#region Assembly Load and Resolve options
bool loadInMemory = false;
@@ -419,7 +433,7 @@ namespace ICSharpCode.Decompiler
#endregion
CSharpFormattingOptions csharpFormattingOptions;
-
+
public CSharpFormattingOptions CSharpFormattingOptions {
get {
if (csharpFormattingOptions == null) {
@@ -440,14 +454,14 @@ namespace ICSharpCode.Decompiler
}
public event PropertyChangedEventHandler PropertyChanged;
-
+
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
if (PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
-
+
public DecompilerSettings Clone()
{
DecompilerSettings settings = (DecompilerSettings)MemberwiseClone();
diff --git a/ICSharpCode.Decompiler/IL/Transforms/RemoveDeadVariableInit.cs b/ICSharpCode.Decompiler/IL/Transforms/RemoveDeadVariableInit.cs
index e5d1831bf..91ed54025 100644
--- a/ICSharpCode.Decompiler/IL/Transforms/RemoveDeadVariableInit.cs
+++ b/ICSharpCode.Decompiler/IL/Transforms/RemoveDeadVariableInit.cs
@@ -44,22 +44,24 @@ namespace ICSharpCode.Decompiler.IL.Transforms
// This is necessary to remove useless stores generated by some compilers, e.g., the F# compiler.
// In yield return + async, the C# compiler tends to store null/default(T) to variables
// when the variable goes out of scope.
- var variableQueue = new Queue(function.Variables);
- while (variableQueue.Count > 0) {
- var v = variableQueue.Dequeue();
- if (v.Kind != VariableKind.Local && v.Kind != VariableKind.StackSlot)
- continue;
- if (v.LoadCount != 0 || v.AddressCount != 0)
- continue;
- foreach (var stloc in v.StoreInstructions.OfType().ToArray()) {
- if (stloc.Parent is Block block) {
- if (SemanticHelper.IsPure(stloc.Value.Flags)) {
- block.Instructions.Remove(stloc);
- } else {
- stloc.ReplaceWith(stloc.Value);
- }
- if (stloc.Value is LdLoc ldloc) {
- variableQueue.Enqueue(ldloc.Variable);
+ if (function.IsAsync || function.IsIterator || context.Settings.RemoveDeadCode) {
+ var variableQueue = new Queue(function.Variables);
+ while (variableQueue.Count > 0) {
+ var v = variableQueue.Dequeue();
+ if (v.Kind != VariableKind.Local && v.Kind != VariableKind.StackSlot)
+ continue;
+ if (v.LoadCount != 0 || v.AddressCount != 0)
+ continue;
+ foreach (var stloc in v.StoreInstructions.OfType().ToArray()) {
+ if (stloc.Parent is Block block) {
+ if (SemanticHelper.IsPure(stloc.Value.Flags)) {
+ block.Instructions.Remove(stloc);
+ } else {
+ stloc.ReplaceWith(stloc.Value);
+ }
+ if (stloc.Value is LdLoc ldloc) {
+ variableQueue.Enqueue(ldloc.Variable);
+ }
}
}
}
diff --git a/ILSpy/Options/DecompilerSettingsPanel.xaml b/ILSpy/Options/DecompilerSettingsPanel.xaml
index e43c553d3..4d76de14e 100644
--- a/ILSpy/Options/DecompilerSettingsPanel.xaml
+++ b/ILSpy/Options/DecompilerSettingsPanel.xaml
@@ -14,5 +14,6 @@
Show info from debug symbols, if available
Show XML documentation in decompiled code
Enable folding on all blocks in braces
+ Remove dead and side effect free code.
\ No newline at end of file