From f33bc85d3e99204338a69a50af045e7eb977eda7 Mon Sep 17 00:00:00 2001 Message-ID: In-Reply-To: <3f8af65f72871d61fa85e6939f46cb8dac185c70.1732707288.git.unmush@hashbang.sh> References: <3f8af65f72871d61fa85e6939f46cb8dac185c70.1732707288.git.unmush@hashbang.sh> From: unmush Date: Wed, 27 Nov 2024 00:54:28 Subject: [PATCH 19/21] gnu: Add mono-5.10.0. * gnu/packages/dotnet.scm (mono-5.10.0-external-repo-specs, mono-5.10.0): New variables. * gnu/packages/patches/mono-5.10.0-later-mcs-changes.patch: New patch. * gnu/local.mk (dist_patch_DATA): Register new patch. Change-Id: Ic5e123c2cd12f9b77d012cd7d73f9be0b5a608ec --- gnu/local.mk | 1 + gnu/packages/dotnet.scm | 119 + .../mono-5.10.0-later-mcs-changes.patch | 4601 +++++++++++++++++ 3 files changed, 4721 insertions(+) create mode 100644 gnu/packages/patches/mono-5.10.0-later-mcs-changes.patch diff --git a/gnu/local.mk b/gnu/local.mk index 7e26416e78..6b0ebdf2d7 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -1771,6 +1771,7 @@ dist_patch_DATA = \ %D%/packages/patches/mono-4.9.0-fix-runtimemetadataversion.patch \ %D%/packages/patches/mono-5.4.0-patches.patch \ %D%/packages/patches/mono-5.8.0-patches.patch \ + %D%/packages/patches/mono-5.10.0-later-mcs-changes.patch \ %D%/packages/patches/mono-mcs-patches-from-5.10.0.patch \ %D%/packages/patches/mosaicatcher-unbundle-htslib.patch \ %D%/packages/patches/mrrescue-support-love-11.patch \ diff --git a/gnu/packages/dotnet.scm b/gnu/packages/dotnet.scm index 439e9779bb..3309cec3f5 100644 --- a/gnu/packages/dotnet.scm +++ b/gnu/packages/dotnet.scm @@ -1472,3 +1472,122 @@ (define-public mono-pre-5.10.0 (search-patches "mono-mcs-patches-from-5.10.0.patch")))) (native-inputs (modify-inputs (package-native-inputs mono-5.8.0) (replace "mono" mono-5.8.0)))))) + +(define mono-5.10.0-external-repo-specs + '(("api-doc-tools" "d03e819838c6241f92f90655cb448cc47c9e8791" + "1riki79f3ig3cxigviss81dz601hn92a1gifglm0mzjbs76sf3fj" + #:recursive? #t) + ("api-snapshot" "da8bb8c7b970383ce26c9b09ce3689d843a6222e" + "00kxw09yirdh0bzkvs0v3h6bkdjv9d4g9agn3b8640awvpym3yqw") + ("aspnetwebstack" "e77b12e6cc5ed260a98447f609e887337e44e299" + "0rks344qr4fmp3fs1264d2qkmm348m8d1kjd7z4l94iiirwn1fq1") + (("reference-assemblies" "binary-reference-assemblies") + "e048fe4a88d237d105ae02fe0363a68296099362" + "0i87i3x694f4g8s2flflv0ah88blxds7gbiyrwrmscqdjsifhy49") + ("bockbuild" "1908d43ec630544189bd11630a59ec4ef571db28" + "1h13lgic2dwnbzc58nqhjhagn0f100nl5mhzryjdmypgrf3cr1b3") + ("boringssl" "3e0770e18835714708860ba9fe1af04a932971ff" + "139a0gl91a52k2r6na6ialzkqykaj1rk88zjrkaz3sdxx7nmmg6y") + ("cecil" "dfee11e80d59e1a3d6d9c914c3f277c726bace52" + "1y2f59v988y2llqpqi0zl9ly0lkym8zw0a4vkav7cpp6m5mkq208") + (("cecil" "cecil-legacy") "33d50b874fd527118bc361d83de3d494e8bb55e1" + "1p4hl1796ib26ykyf5snl6cj0lx0v7mjh0xqhjw6qdh753nsjyhb") + ("corefx" "e327d2855ed74dac96f684797e4820345297a690" + "11pinnn8zwf4hi0gfj98cyqkmh7wrmd5mhcdm84gkl9s2g18iaq0") + ("corert" "aa64b376c1a2238b1a768e158d1b11dac77d722a" + "1gg4m49s0ry5yx96dwjary7r395ypzzg4ssz1ajld2x5g7ggvwgg") + ("ikdasm" "465c0815558fd43c0110f8d00fc186ac0044ac6a" + "0xir7pcgq04hb7s8g9wsqdrypb6l29raj3iz5rcqzdm0056k75w2") + (("ikvm-fork" "ikvm") "847e05fced5c9a41ff0f24f1f9d40d5a8a5772c1" + "1fl9bm3lmzf8iqv3x4iqkz9fc54mwdvrxisxg2nvwwcsi4saffpi") + ("linker" "84d37424cde6e66bbf997110a4dbdba7e60038e9" + "07ffkc9ijzsdvbkrc1fn5sb25sgxyabs54kzyblwkzparwj047qr") + ("Newtonsoft.Json" "471c3e0803a9f40a0acc8aeceb31de6ff93a52c4" + "0dgngd5hqk6yhlg40kabn6qdnknm32zcx9q6bm2w31csnsk5978s") + (("NuGet.BuildTasks" "nuget-buildtasks") + "b2c30bc81b2a7733a4eeb252a55f6b4d50cfc3a1" + "01vajrfx6y12f525xdiwfbn9qzmym2s65rbiqpy9d9xw0pnq7gbl") + (("NUnitLite" "nunit-lite") "70bb70b0ffd0109aadaa6e4ea178972d4fb63ea3" + "0ln7rn1960cdwmfqcscp2d2ncpwnknhq9rf8v53ay8g2c3g6gh4q") + ;; ("roslyn-binaries" "00da53c4746250988a92055ef3ac653ccf84fc40" + ;; "") + ("rx" "b29a4b0fda609e0af33ff54ed13652b6ccf0e05e" + "1n1jwhmsbkcv2d806immcpzkb72rz04xy98myw355a8w5ah25yiv") + ;; ("xunit-binaries" "c5a907be25c201cda38bec99f6c82548ab3d9b5a" + ;; "") + )) + +(define-public mono-5.10.0 + (package + (inherit mono-pre-5.10.0) + (version "5.10.0.179") + (name "mono") + (source (origin + (method git-fetch) + (uri + (git-reference + (url "https://gitlab.winehq.org/mono/mono.git") + (commit "mono-5.10.0.179"))) + (file-name (git-file-name name version)) + (sha256 + (base32 + "1zvib164w4mzrsk06ym9my0208ccdanja2fx6x6mlyib358h3626")) + (modules '((guix build utils) + (ice-9 string-fun))) + (snippet #~(begin + #$(add-external-repos + mono-5.10.0-external-repo-specs) + #$@prepare-mono-source-0)) + (patches + (search-patches "mono-5.10.0-later-mcs-changes.patch")))) + (native-inputs (modify-inputs (package-native-inputs mono-pre-5.10.0) + (replace "mono" mono-pre-5.10.0) + (append (default-python)))) + (arguments + (substitute-keyword-arguments (package-arguments mono-pre-5.10.0) + ((#:phases phases #~%standard-phases) + #~(modify-phases #$phases + ;; Build now relies on these being built before any mcs is built; + ;; have to use the input mcs. + (delete 'build-reference-assemblies) + (add-before 'build 'build-reference-assemblies + (lambda* (#:key make-flags #:allow-other-keys) + (let ((top (getcwd))) + (with-directory-excursion + "external/binary-reference-assemblies" + (substitute* (find-files "." "^Makefile$") + (("CSC_COMMON_ARGS := " all) + (string-append all "-delaysign+ ")) + (("IBM\\.Data\\.DB2_REFS := " all) + (string-append all "System.Xml ")) + (("Mono\\.Data\\.Sqlite_REFS := " all) + (string-append all "System.Xml ")) + (("System\\.Data\\.DataSetExtensions_REFS := " all) + (string-append all "System.Xml ")) + (("System\\.Data\\.OracleClient_REFS := " all) + (string-append all "System.Xml ")) + (("System\\.IdentityModel_REFS := " all) + (string-append all "System.Configuration ")) + (("System\\.Design_REFS := " all) + (string-append all "Accessibility ")) + (("System\\.Web\\.Extensions\\.Design_REFS := " all) + (string-append all "System.Windows.Forms System.Web ")) + (("System\\.ServiceModel\\.Routing_REFS := " all) + (string-append all "System.Xml ")) + (("System\\.Web\\.Abstractions_REFS := " all) + (string-append all "System ")) + (("System\\.Reactive\\.Windows\\.Forms_REFS := " all) + (string-append all "System ")) + (("System\\.Windows\\.Forms\\.DataVisualization_REFS := " all) + (string-append all "Accessibility ")) + (("Facades/System\\.ServiceModel\\.Primitives_REFS := " all) + (string-append all "System.Xml ")) + (("Facades/System\\.Dynamic\\.Runtime_REFS := " all) + (string-append all "System ")) + (("Facades/System\\.Xml\\.XDocument_REFS := " all) + (string-append all "System.Xml ")) + (("Facades/System\\.Runtime\\.Serialization.Xml_REFS := " all) + (string-append all "System.Xml ")) + (("Facades/System\\.Data\\.Common_REFS := " all) + (string-append all "System System.Xml "))) + (apply invoke "make" "CSC=mcs" make-flags))))))))))) diff --git a/gnu/packages/patches/mono-5.10.0-later-mcs-changes.patch b/gnu/packages/patches/mono-5.10.0-later-mcs-changes.patch new file mode 100644 index 0000000000..c4e211a8a3 --- /dev/null +++ b/gnu/packages/patches/mono-5.10.0-later-mcs-changes.patch @@ -0,0 +1,4601 @@ +The result of cherry-picking every commit (except ones that seemed to not +affect the compiler itself) from mono-5.10.0.179 to mono-6.12.0.206 that +touched ./mcs/mcs. + +Mono seems to consistently, almost as a rule, depend on C# features before +they implement them. This is extremely awkward for building using previous +versions, so hopefully this will allow us to jump straight to a high version. + +Includes the following commits, in order of most-recent to least-recent: + +b3911589b37 +6700dd220fe +2a7dfb28e07 +eea6f11a3e6 +3fc047c6f3a +ac6666f5b0b +927b27bb9d8 +4ab24d4c059 +aa836b46a23 +ee7dccfb320 +23510f26915 +d9f26547d88 +9dc1c885a0f +ef558ead89a +2cb7909b13c +0390ea2e78c +b4f6659bdc0 +e92d6070eaf +4c5b3fbd4f4 +e6507f2da8a +656a4b1120c +9bd2fa4cf33 +be2d1aeffe0 +454a76cfa4a +60c1ee454d4 +53f1ef506ea +d3487bfebb3 +92f6e5b1a81 + +diff --git a/.gitignore b/.gitignore +index c6ef19a849b..c37d4fce3f0 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -40,6 +40,7 @@ Ankh.NoLoad + *.gpState + .vscode/ + *.exp ++.vs/ + + # Tooling + _ReSharper*/ +diff --git a/mcs/class/Commons.Xml.Relaxng/Makefile b/mcs/class/Commons.Xml.Relaxng/Makefile +index 1febae4eb1e..f9b57fea265 100644 +--- a/mcs/class/Commons.Xml.Relaxng/Makefile ++++ b/mcs/class/Commons.Xml.Relaxng/Makefile +@@ -22,7 +22,7 @@ EXTRA_DISTFILES = \ + $(RESOURCE_FILES) + + Commons.Xml.Relaxng.Rnc/RncParser.cs: Commons.Xml.Relaxng.Rnc/RncParser.jay $(topdir)/jay/skeleton.cs +- $(topdir)/jay/jay -ctv < $(topdir)/jay/skeleton.cs $(CURDIR)/Commons.Xml.Relaxng.Rnc/RncParser.jay > Commons.Xml.Relaxng.Rnc/RncParser.cs ++ $(topdir)/jay/jay -ctv -o Commons.Xml.Relaxng.Rnc/RncParser.cs $< < $(topdir)/jay/skeleton.cs + + BUILT_SOURCES = Commons.Xml.Relaxng.Rnc/RncParser.cs + +diff --git a/mcs/class/Microsoft.Build/Makefile b/mcs/class/Microsoft.Build/Makefile +index 2dcbefdf7f9..1a711069b0b 100644 +--- a/mcs/class/Microsoft.Build/Makefile ++++ b/mcs/class/Microsoft.Build/Makefile +@@ -26,7 +26,7 @@ EXTRA_DISTFILES = \ + EXPR_PARSER = Microsoft.Build.Internal/ExpressionParser + + $(EXPR_PARSER).cs: $(EXPR_PARSER).jay $(topdir)/jay/skeleton.cs +- (cd Microsoft.Build.Internal; $(topdir)/../jay/jay -ctv < $(topdir)/../jay/skeleton.cs ExpressionParser.jay > ExpressionParser.cs) ++ (cd Microsoft.Build.Internal; $(topdir)/../jay/jay -ctv -o ExpressionParser.cs ExpressionParser.jay < $(topdir)/../jay/skeleton.cs ) + + BUILT_SOURCES = $(EXPR_PARSER).cs + +diff --git a/mcs/class/Mono.CSharp/Makefile b/mcs/class/Mono.CSharp/Makefile +index 7b1986b78e5..3615532853d 100644 +--- a/mcs/class/Mono.CSharp/Makefile ++++ b/mcs/class/Mono.CSharp/Makefile +@@ -24,7 +24,7 @@ LIB_MCS_FLAGS += $(REFERENCE_SOURCES_FLAGS) + BUILT_SOURCES = $(PROFILE)-parser.cs + + $(PROFILE)-parser.cs: $(topdir)/mcs/cs-parser.jay $(topdir)/jay/skeleton.cs +- $(topdir)/jay/jay -c < $(topdir)/jay/skeleton.cs $< > $(PROFILE)-jay-tmp.out && mv $(PROFILE)-jay-tmp.out $@ ++ $(topdir)/jay/jay -c -o $(PROFILE)-jay-tmp.out $< < $(topdir)/jay/skeleton.cs && mv $(PROFILE)-jay-tmp.out $@ + + include ../../build/library.make + +diff --git a/mcs/class/Mono.Xml.Ext/Makefile b/mcs/class/Mono.Xml.Ext/Makefile +index dc49f816fee..16498215a38 100644 +--- a/mcs/class/Mono.Xml.Ext/Makefile ++++ b/mcs/class/Mono.Xml.Ext/Makefile +@@ -29,13 +29,13 @@ Mono.Xml.XPath2/XQueryParser.jay: Mono.Xml.XPath2/ParserBase.jay $(SKELETON) + Mono.Xml.XPath2/XPath2Parser.cs: Mono.Xml.XPath2/XPath2Parser.jay + echo "#define XPATH2_PARSER" > $@ + echo "#if NET_2_0" >> $@ +- $(topdir)/jay/jay -ct < $(SKELETON) $(CURDIR)/$< >>$@ ++ $(topdir)/jay/jay -ct $(CURDIR)/$< < $(SKELETON) >>$@ + echo "#endif" >> $@ + + Mono.Xml.XPath2/XQueryParser.cs: Mono.Xml.XPath2/XQueryParser.jay $(SKELETON) + echo "#define XQUERY_PARSER" > $@ + echo "#if NET_2_0" >> $@ +- $(topdir)/jay/jay -ct < $(SKELETON) $(CURDIR)/$< >>$@ ++ $(topdir)/jay/jay -ct $(CURDIR)/$< < $(SKELETON) >>$@ + echo "#endif" >> $@ + + Mono.Xml.XPath2/XPath2Tokenizer.cs: Mono.Xml.XPath2/TokenizerBase.cs +diff --git a/mcs/class/corlib/System/RuntimeArgumentHandle.cs b/mcs/class/corlib/System/RuntimeArgumentHandle.cs +index 216c4ea3924..c10d3f174d1 100644 +--- a/mcs/class/corlib/System/RuntimeArgumentHandle.cs ++++ b/mcs/class/corlib/System/RuntimeArgumentHandle.cs +@@ -31,13 +31,9 @@ + // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + // + +-using System; +-using System.Runtime.InteropServices; +- + namespace System + { +- [ComVisible (true)] +- public struct RuntimeArgumentHandle ++ public ref struct RuntimeArgumentHandle + { + #pragma warning disable 649 + internal IntPtr args; +diff --git a/mcs/class/referencesource/mscorlib/system/typedreference.cs b/mcs/class/referencesource/mscorlib/system/typedreference.cs +index 80bef5ab852..a30541f4399 100644 +--- a/mcs/class/referencesource/mscorlib/system/typedreference.cs ++++ b/mcs/class/referencesource/mscorlib/system/typedreference.cs +@@ -19,7 +19,11 @@ namespace System { + [CLSCompliant(false)] + [System.Runtime.InteropServices.ComVisible(true)] + [System.Runtime.Versioning.NonVersionable] // This only applies to field layout +- public struct TypedReference ++ public ++#if MONO ++ ref ++#endif ++ struct TypedReference + { + #if MONO + #pragma warning disable 169 +diff --git a/mcs/errors/cs0151-4.cs b/mcs/errors/cs0151-4.cs +index 0e45b1a9049..c9e05589e4d 100644 +--- a/mcs/errors/cs0151-4.cs ++++ b/mcs/errors/cs0151-4.cs +@@ -1,5 +1,6 @@ + // CS0151: A switch expression of type `S1?' cannot be converted to an integral type, bool, char, string, enum or nullable type +-// Line: 24 ++// Line: 25 ++// Compiler options: -langversion:5 + + using System; + +diff --git a/mcs/errors/cs0273-2.cs b/mcs/errors/cs0273-2.cs +new file mode 100644 +index 00000000000..b0bdbef9e75 +--- /dev/null ++++ b/mcs/errors/cs0273-2.cs +@@ -0,0 +1,9 @@ ++// CS0273: The accessibility modifier of the `C.S2.set' accessor must be more restrictive than the modifier of the property or indexer `C.S2' ++// Line: 7 ++// Compiler options: -langversion:7.2 ++ ++ class C ++ { ++ private string S2 { get; private protected set; } ++ } ++ +diff --git a/mcs/errors/cs0280.cs b/mcs/errors/cs0280.cs +new file mode 100644 +index 00000000000..62be8e39585 +--- /dev/null ++++ b/mcs/errors/cs0280.cs +@@ -0,0 +1,22 @@ ++// CS0280: `C.Fixable.GetPinnableReference(int)' has the wrong signature to be used in extensible fixed statement ++// Line: 11 ++// Compiler options: -unsafe -langversion:latest -warnaserror ++ ++using System; ++ ++unsafe class C ++{ ++ public static void Main () ++ { ++ fixed (int* p = new Fixable ()) { ++ } ++ } ++ ++ struct Fixable ++ { ++ public ref int GetPinnableReference (int i = 1) ++ { ++ throw new NotImplementedException (); ++ } ++ } ++} +\ No newline at end of file +diff --git a/mcs/errors/cs0826-9.cs b/mcs/errors/cs0826-9.cs +deleted file mode 100644 +index 4e098969b8c..00000000000 +--- a/mcs/errors/cs0826-9.cs ++++ /dev/null +@@ -1,16 +0,0 @@ +-// CS0826: The type of an implicitly typed array cannot be inferred from the initializer. Try specifying array type explicitly +-// Line: 8 +- +-class C +-{ +- static void Main() +- { +- object o = 1; +- dynamic d = 1; +- +- var a = new[] { +- new { X = o }, +- new { X = d } +- }; +- } +-} +diff --git a/mcs/errors/cs1013-1.cs b/mcs/errors/cs1013-1.cs +new file mode 100644 +index 00000000000..01827df4995 +--- /dev/null ++++ b/mcs/errors/cs1013-1.cs +@@ -0,0 +1,8 @@ ++// CS1013: Invalid number ++// Line : 6 ++ ++class X ++{ ++ static int i = 0b; ++ static void Main () {} ++} +\ No newline at end of file +diff --git a/mcs/errors/cs1013-2.cs b/mcs/errors/cs1013-2.cs +new file mode 100644 +index 00000000000..c868cb2a769 +--- /dev/null ++++ b/mcs/errors/cs1013-2.cs +@@ -0,0 +1,7 @@ ++// CS1013: Invalid number ++// Line : 6 ++ ++class X ++{ ++ static int i = 0x0_; ++} +\ No newline at end of file +diff --git a/mcs/errors/cs1013-3.cs b/mcs/errors/cs1013-3.cs +new file mode 100644 +index 00000000000..3145b1ba596 +--- /dev/null ++++ b/mcs/errors/cs1013-3.cs +@@ -0,0 +1,7 @@ ++// CS1013: Invalid number ++// Line : 6 ++ ++class X ++{ ++ static int i = 1_; ++} +\ No newline at end of file +diff --git a/mcs/errors/cs1013-4.cs b/mcs/errors/cs1013-4.cs +new file mode 100644 +index 00000000000..3a5e744ff4f +--- /dev/null ++++ b/mcs/errors/cs1013-4.cs +@@ -0,0 +1,7 @@ ++// CS1013: Invalid number ++// Line : 6 ++ ++class X ++{ ++ static double i = 1_.2; ++} +\ No newline at end of file +diff --git a/mcs/errors/cs1013-5.cs b/mcs/errors/cs1013-5.cs +new file mode 100644 +index 00000000000..8082743c0b5 +--- /dev/null ++++ b/mcs/errors/cs1013-5.cs +@@ -0,0 +1,7 @@ ++// CS1013: Invalid number ++// Line : 6 ++ ++class X ++{ ++ static int i = 1_e1; ++} +\ No newline at end of file +diff --git a/mcs/errors/cs1013-6.cs b/mcs/errors/cs1013-6.cs +new file mode 100644 +index 00000000000..d2cea2c72dd +--- /dev/null ++++ b/mcs/errors/cs1013-6.cs +@@ -0,0 +1,7 @@ ++// CS1013: Invalid number ++// Line : 6 ++ ++class X ++{ ++ static float i = 1_f; ++} +\ No newline at end of file +diff --git a/mcs/errors/cs1013-7.cs b/mcs/errors/cs1013-7.cs +new file mode 100644 +index 00000000000..8030d6ed095 +--- /dev/null ++++ b/mcs/errors/cs1013-7.cs +@@ -0,0 +1,7 @@ ++// CS1013: Invalid number ++// Line : 6 ++ ++class X ++{ ++ static int i = 0x_1; ++} +\ No newline at end of file +diff --git a/mcs/errors/cs1013-8.cs b/mcs/errors/cs1013-8.cs +new file mode 100644 +index 00000000000..d26c7acacb7 +--- /dev/null ++++ b/mcs/errors/cs1013-8.cs +@@ -0,0 +1,7 @@ ++// CS1013: Invalid number ++// Line : 6 ++ ++class X ++{ ++ static int i = 0b_1; ++} +\ No newline at end of file +diff --git a/mcs/errors/cs1021-4.cs b/mcs/errors/cs1021-4.cs +new file mode 100644 +index 00000000000..75c2ff70360 +--- /dev/null ++++ b/mcs/errors/cs1021-4.cs +@@ -0,0 +1,8 @@ ++// CS1021: Integral constant is too large ++// Line: 6 ++ ++class X { ++ public static void Main() { ++ int h = 0b11111111111111111111111111111111111111111111111111111111111111111; ++ } ++} +diff --git a/mcs/errors/cs1061-18.cs b/mcs/errors/cs1061-18.cs +new file mode 100644 +index 00000000000..3ac82b7f2d3 +--- /dev/null ++++ b/mcs/errors/cs1061-18.cs +@@ -0,0 +1,10 @@ ++// CS1061: Type `int' does not contain a definition for `__0' and no extension method `__0' of type `int' could be found. Are you missing an assembly reference? ++// Line: 8 ++ ++static class C ++{ ++ static void Main () ++ { ++ int c = 0.__0; ++ } ++} +\ No newline at end of file +diff --git a/mcs/errors/cs1525-27.cs b/mcs/errors/cs1525-27.cs +index dc184931667..d4c1f326be2 100644 +--- a/mcs/errors/cs1525-27.cs ++++ b/mcs/errors/cs1525-27.cs +@@ -1,4 +1,4 @@ +-// CS1525: Unexpected symbol `fe', expecting `class', `delegate', `enum', `interface', `partial', or `struct' ++// CS1525: Unexpected symbol `fe', expecting `class', `delegate', `enum', `interface', `partial', `ref', or `struct' + // Line: 6 + + namespace X +diff --git a/mcs/errors/cs1525-43.cs b/mcs/errors/cs1525-43.cs +index d83d4d847fa..26f466a2528 100644 +--- a/mcs/errors/cs1525-43.cs ++++ b/mcs/errors/cs1525-43.cs +@@ -1,4 +1,4 @@ +-// CS1525: Unexpected symbol `)', expecting `(', `[', `out', `params', `ref', `this', or `type' ++// CS1525: Unexpected symbol `)' + // Line: 6 + + class TestClass +diff --git a/mcs/errors/cs1527-2.cs b/mcs/errors/cs1527-2.cs +index d38945f3c89..0256ee2b354 100644 +--- a/mcs/errors/cs1527-2.cs ++++ b/mcs/errors/cs1527-2.cs +@@ -1,4 +1,4 @@ +-// CS1527: Namespace elements cannot be explicitly declared as private, protected or protected internal ++// CS1527: Namespace elements cannot be explicitly declared as private, protected, protected internal, or private protected + // Line: 4 + + protected interface IFoo { +diff --git a/mcs/errors/cs1527-3.cs b/mcs/errors/cs1527-3.cs +index 763c75958ee..469d74cbb99 100644 +--- a/mcs/errors/cs1527-3.cs ++++ b/mcs/errors/cs1527-3.cs +@@ -1,4 +1,4 @@ +-// CS1527: Namespace elements cannot be explicitly declared as private, protected or protected internal ++// CS1527: Namespace elements cannot be explicitly declared as private, protected, protected internal, or private protected + // Line: 4 + + protected internal enum E { +diff --git a/mcs/errors/cs1527.cs b/mcs/errors/cs1527.cs +index 189cc472f4c..e847fd14e11 100644 +--- a/mcs/errors/cs1527.cs ++++ b/mcs/errors/cs1527.cs +@@ -1,4 +1,5 @@ +-// CS1527: Namespace elements cannot be explicitly declared as private, protected or protected internal +-// Line: ++// CS1527: Namespace elements cannot be explicitly declared as private, protected, protected internal, or private protected ++// Line: 4 ++ + private class X { + } +diff --git a/mcs/errors/cs1611-2.cs b/mcs/errors/cs1611-2.cs +new file mode 100644 +index 00000000000..882231378f0 +--- /dev/null ++++ b/mcs/errors/cs1611-2.cs +@@ -0,0 +1,8 @@ ++// CS1611: The params parameter cannot be declared as ref, out or in ++// Line: 6 ++// Compiler options: -langversion:latest ++ ++class Test ++{ ++ public static void Error (params in int args) {} ++} +\ No newline at end of file +diff --git a/mcs/errors/cs1611.cs b/mcs/errors/cs1611.cs +index 8df10fac0ce..469e083ec3c 100644 +--- a/mcs/errors/cs1611.cs ++++ b/mcs/errors/cs1611.cs +@@ -1,4 +1,4 @@ +-// CS1611: The params parameter cannot be declared as ref or out ++// CS1611: The params parameter cannot be declared as ref, out or in + // Line: 6 + + class Test +diff --git a/mcs/errors/cs1644-61.cs b/mcs/errors/cs1644-61.cs +new file mode 100644 +index 00000000000..d58ba64c7ec +--- /dev/null ++++ b/mcs/errors/cs1644-61.cs +@@ -0,0 +1,11 @@ ++// CS1644: Feature `digit separators' cannot be used because it is not part of the C# 6.0 language specification ++// Line: 9 ++// Compiler options: -langversion:6 ++ ++class X ++{ ++ int Test () ++ { ++ var i = 1_0; ++ } ++} +diff --git a/mcs/errors/cs1644-62.cs b/mcs/errors/cs1644-62.cs +new file mode 100644 +index 00000000000..5a29839610d +--- /dev/null ++++ b/mcs/errors/cs1644-62.cs +@@ -0,0 +1,10 @@ ++// CS1644: Feature `private protected' cannot be used because it is not part of the C# 6.0 language specification ++// Line: 7 ++// Compiler options: -langversion:6 ++ ++class C ++{ ++ private protected enum E ++ { ++ } ++} +\ No newline at end of file +diff --git a/mcs/errors/cs1644-63.cs b/mcs/errors/cs1644-63.cs +new file mode 100644 +index 00000000000..ce61d5ce046 +--- /dev/null ++++ b/mcs/errors/cs1644-63.cs +@@ -0,0 +1,22 @@ ++// CS1644: Feature `extensible fixed statement' cannot be used because it is not part of the C# 7.2 language specification ++// Line: 11 ++// Compiler options: -unsafe -langversion:7.2 ++ ++using System; ++ ++unsafe class C ++{ ++ public static void Main () ++ { ++ fixed (int* p = new Fixable ()) { ++ } ++ } ++ ++ struct Fixable ++ { ++ public ref int GetPinnableReference () ++ { ++ throw new NotImplementedException (); ++ } ++ } ++} +\ No newline at end of file +diff --git a/mcs/errors/cs1644-64.cs b/mcs/errors/cs1644-64.cs +new file mode 100644 +index 00000000000..88917a0a5d5 +--- /dev/null ++++ b/mcs/errors/cs1644-64.cs +@@ -0,0 +1,13 @@ ++// CS1644: Feature `expression body property accessor' cannot be used because it is not part of the C# 6.0 language specification ++// Line: 11 ++// Compiler options: -langversion:6 ++ ++using System; ++ ++class C ++{ ++ public int Integer ++ { ++ get => 0; ++ } ++} +\ No newline at end of file +diff --git a/mcs/errors/cs1644-65.cs b/mcs/errors/cs1644-65.cs +new file mode 100644 +index 00000000000..dea648b7846 +--- /dev/null ++++ b/mcs/errors/cs1644-65.cs +@@ -0,0 +1,13 @@ ++// CS1644: Feature `expression body property accessor' cannot be used because it is not part of the C# 6.0 language specification ++// Line: 11 ++// Compiler options: -langversion:6 ++ ++using System; ++ ++class C ++{ ++ public int this[int i] ++ { ++ get => i; ++ } ++} +\ No newline at end of file +diff --git a/mcs/errors/cs1644-66.cs b/mcs/errors/cs1644-66.cs +new file mode 100644 +index 00000000000..3f393b50d30 +--- /dev/null ++++ b/mcs/errors/cs1644-66.cs +@@ -0,0 +1,17 @@ ++// CS1644: Feature `expression body event accessor' cannot be used because it is not part of the C# 6.0 language specification ++// Line: 11 ++// Compiler options: -langversion:6 ++ ++using System; ++ ++class C ++{ ++ public event EventHandler Event ++ { ++ add => Ignore (); ++ } ++ ++ static void Ignore () ++ { ++ } ++} +\ No newline at end of file +diff --git a/mcs/errors/cs1763-2.cs b/mcs/errors/cs1763-2.cs +index 72f5370949a..7e4d091fc72 100644 +--- a/mcs/errors/cs1763-2.cs ++++ b/mcs/errors/cs1763-2.cs +@@ -1,4 +1,4 @@ +-// CS1763: Optional parameter `o' of type `object' can only be initialized with `null' ++// CS1763: Optional parameter `o' of type `object' can only be initialized with default value + // Line: 6 + + class C +diff --git a/mcs/errors/cs1763.cs b/mcs/errors/cs1763.cs +index d10a7bf2c20..03b5f28a19d 100644 +--- a/mcs/errors/cs1763.cs ++++ b/mcs/errors/cs1763.cs +@@ -1,4 +1,4 @@ +-// CS1763: Optional parameter `o' of type `object' can only be initialized with `null' ++// CS1763: Optional parameter `o' of type `object' can only be initialized with default value + // Line: 6 + + class C +diff --git a/mcs/errors/cs8326.cs b/mcs/errors/cs8326.cs +new file mode 100644 +index 00000000000..efd3a84fea7 +--- /dev/null ++++ b/mcs/errors/cs8326.cs +@@ -0,0 +1,13 @@ ++// CS8326: Both ref conditional operators must be ref values ++// Line: 11 ++ ++class Program ++{ ++ static int x, y; ++ ++ public static void Main () ++ { ++ bool b = false; ++ ref int targetBucket = ref b ? x : y; ++ } ++} +\ No newline at end of file +diff --git a/mcs/errors/cs8327.cs b/mcs/errors/cs8327.cs +new file mode 100644 +index 00000000000..8d0ccd86a70 +--- /dev/null ++++ b/mcs/errors/cs8327.cs +@@ -0,0 +1,14 @@ ++// CS8327: The ref conditional expression types `int' and `byte' have to match ++// Line: 12 ++ ++class Program ++{ ++ static int x; ++ static byte y; ++ ++ public static void Main () ++ { ++ bool b = false; ++ ref int targetBucket = ref b ? ref x : ref y; ++ } ++} +\ No newline at end of file +diff --git a/mcs/errors/cs0428-2.cs b/mcs/errors/cs8385-2.cs +similarity index 50% +rename from mcs/errors/cs0428-2.cs +rename to mcs/errors/cs8385-2.cs +index 5f468fd519a..cc7860faa62 100644 +--- a/mcs/errors/cs0428-2.cs ++++ b/mcs/errors/cs8385-2.cs +@@ -1,4 +1,4 @@ +-// CS0428: Cannot convert method group `Main' to non-delegate type `void*'. Consider using parentheses to invoke the method ++// CS8385: The given expression cannot be used in a fixed statement + // Line: 9 + // Compiler options: -unsafe + +diff --git a/mcs/errors/cs0213-2.cs b/mcs/errors/cs8385.cs +similarity index 54% +rename from mcs/errors/cs0213-2.cs +rename to mcs/errors/cs8385.cs +index ae72e4cd9aa..5fa9f794ccf 100644 +--- a/mcs/errors/cs0213-2.cs ++++ b/mcs/errors/cs8385.cs +@@ -1,4 +1,4 @@ +-// CS0213: You cannot use the fixed statement to take the address of an already fixed expression ++// CS8385: The given expression cannot be used in a fixed statement + // Line: 9 + // Compiler options: -unsafe + +diff --git a/mcs/errors/known-issues-net_4_x b/mcs/errors/known-issues-net_4_x +index c9ed9317350..54902e03e7b 100644 +--- a/mcs/errors/known-issues-net_4_x ++++ b/mcs/errors/known-issues-net_4_x +@@ -14,6 +14,9 @@ + # Parser problems + cs0080.cs + ++# Undocumented switch governing rules ++cs0151-4.cs NO ERROR ++ + # Operators + cs0457-2.cs + cs0457.cs +diff --git a/mcs/ilasm/Makefile b/mcs/ilasm/Makefile +index 090d1cc3231..4ca11545781 100644 +--- a/mcs/ilasm/Makefile ++++ b/mcs/ilasm/Makefile +@@ -13,7 +13,7 @@ EXTRA_DISTFILES = \ + $(wildcard tests/*.il) + + ILParser.cs: parser/ILParser.jay $(topdir)/jay/skeleton.cs +- $(topdir)/jay/jay -ct < $(topdir)/jay/skeleton.cs $(CURDIR)/$< >$@ ++ $(topdir)/jay/jay -ct -o $@ $(CURDIR)/$< < $(topdir)/jay/skeleton.cs + + include ../build/executable.make + +diff --git a/mcs/jay/defs.h b/mcs/jay/defs.h +index 2aade48dac2..3bd3c5859ce 100644 +--- a/mcs/jay/defs.h ++++ b/mcs/jay/defs.h +@@ -236,12 +236,14 @@ extern char *input_file_name; + extern char *prolog_file_name; + extern char *local_file_name; + extern char *verbose_file_name; ++extern char *output_file_name; + + extern FILE *action_file; + extern FILE *input_file; + extern FILE *prolog_file; + extern FILE *local_file; + extern FILE *verbose_file; ++extern FILE *output_file; + + extern int nitems; + extern int nrules; +diff --git a/mcs/jay/main.c b/mcs/jay/main.c +index fcac218b1df..7fb5e6c8ccb 100644 +--- a/mcs/jay/main.c ++++ b/mcs/jay/main.c +@@ -63,6 +63,7 @@ char *input_file_name = ""; + char *prolog_file_name; + char *local_file_name; + char *verbose_file_name; ++char *output_file_name = 0; + + FILE *action_file; /* a temp file, used to save actions associated */ + /* with rules until the parser is written */ +@@ -70,6 +71,7 @@ FILE *input_file; /* the input file */ + FILE *prolog_file; /* temp files, used to save text until all */ + FILE *local_file; /* symbols have been defined */ + FILE *verbose_file; /* y.output */ ++FILE *output_file; /* defaults to stdout */ + + int nitems; + int nrules; +@@ -106,6 +108,7 @@ int k; + if (action_file) { fclose(action_file); unlink(action_file_name); } + if (prolog_file) { fclose(prolog_file); unlink(prolog_file_name); } + if (local_file) { fclose(local_file); unlink(local_file_name); } ++ if (output_file && (output_file != stdout)) { fclose(output_file); if (k != 0) unlink(output_file_name); } + exit(k); + } + +@@ -137,7 +140,7 @@ set_signals() + + usage() + { +- fprintf(stderr, "usage: %s [-tvcp] [-b file_prefix] filename\n", myname); ++ fprintf(stderr, "usage: %s [-tvcp] [-b file_prefix] [-o output_filename] input_filename\n", myname); + exit(1); + } + +@@ -167,9 +170,9 @@ char *argv[]; + if (i + 1 < argc) usage(); + return; + +- case '-': +- ++i; +- goto no_more_options; ++ case '-': ++ ++i; ++ goto no_more_options; + + case 'b': + if (*++s) +@@ -180,13 +183,22 @@ char *argv[]; + usage(); + continue; + +- case 't': +- tflag = 1; +- break; ++ case 'o': ++ if (*++s) ++ output_file_name = s; ++ else if (++i < argc) ++ output_file_name = argv[i]; ++ else ++ usage(); ++ continue; ++ ++ case 't': ++ tflag = 1; ++ break; + + case 'p': +- print_skel_dir (); +- break; ++ print_skel_dir (); ++ break; + + case 'c': + csharp = 1; +@@ -217,12 +229,12 @@ char *argv[]; + vflag = 1; + break; + +- case 'p': +- print_skel_dir (); +- break; ++ case 'p': ++ print_skel_dir (); ++ break; + +- case 'c': +- csharp = 1; ++ case 'c': ++ csharp = 1; + line_format = "#line %d \"%s\"\n"; + default_line_format = "#line default\n"; + +@@ -355,6 +367,17 @@ open_files() + if (verbose_file == 0) + open_error(verbose_file_name); + } ++ ++ if (output_file == 0) ++ { ++ if (output_file_name != 0) { ++ output_file = fopen(output_file_name, "w"); ++ if (output_file == 0) ++ open_error(output_file_name); ++ } else { ++ output_file = stdout; ++ } ++ } + } + + +diff --git a/mcs/jay/output.c b/mcs/jay/output.c +index d1e2c14a1b2..ab9b2043be9 100644 +--- a/mcs/jay/output.c ++++ b/mcs/jay/output.c +@@ -73,7 +73,7 @@ output () { + fprintf(stderr, "jay: line %d is too long\n", lno), done(1); + switch (buf[0]) { + case '#': continue; +- case 't': if (!tflag) fputs("//t", stdout); ++ case 't': if (!tflag) fputs("//t", output_file); + case '.': break; + default: + cp = strtok(buf, " \t\r\n"); +@@ -93,7 +93,7 @@ output () { + fprintf(stderr, "jay: unknown call (%s) in line %d\n", cp, lno); + continue; + } +- fputs(buf+1, stdout), ++ outline; ++ fputs(buf+1, output_file), ++ outline; + } + free_parser(); + } +@@ -103,19 +103,19 @@ output_rule_data() + register int i; + register int j; + +- printf("/*\n All more than 3 lines long rules are wrapped into a method\n*/\n"); ++ fprintf(output_file, "/*\n All more than 3 lines long rules are wrapped into a method\n*/\n"); + + for (i = 0; i < nmethods; ++i) + { +- printf("%s", methods[i]); ++ fprintf(output_file, "%s", methods[i]); + FREE(methods[i]); +- printf("\n\n"); ++ fprintf(output_file, "\n\n"); + } + FREE(methods); + +- printf(default_line_format, ++outline + 1); ++ fprintf(output_file, default_line_format, ++outline + 1); + +- printf(" %s static %s short [] yyLhs = {%16d,", ++ fprintf(output_file, " %s static %s short [] yyLhs = {%16d,", + csharp ? "" : " protected", + csharp ? "readonly" : "final", + symbol_value[start_symbol]); +@@ -126,18 +126,18 @@ output_rule_data() + if (j >= 10) + { + ++outline; +- putchar('\n'); ++ putc('\n', output_file); + j = 1; + } + else + ++j; + +- printf("%5d,", symbol_value[rlhs[i]]); ++ fprintf(output_file, "%5d,", symbol_value[rlhs[i]]); + } + outline += 2; +- printf("\n };\n"); ++ fprintf(output_file, "\n };\n"); + +- printf(" %s static %s short [] yyLen = {%12d,", ++ fprintf(output_file, " %s static %s short [] yyLen = {%12d,", + csharp ? "" : "protected", + csharp ? "readonly" : "final", + 2); +@@ -148,16 +148,16 @@ output_rule_data() + if (j >= 10) + { + ++outline; +- putchar('\n'); ++ putc('\n', output_file); + j = 1; + } + else + j++; + +- printf("%5d,", rrhs[i + 1] - rrhs[i] - 1); ++ fprintf(output_file, "%5d,", rrhs[i + 1] - rrhs[i] - 1); + } + outline += 2; +- printf("\n };\n"); ++ fprintf(output_file, "\n };\n"); + } + + +@@ -165,7 +165,7 @@ output_yydefred() + { + register int i, j; + +- printf(" %s static %s short [] yyDefRed = {%13d,", ++ fprintf(output_file, " %s static %s short [] yyDefRed = {%13d,", + csharp ? "" : "protected", + csharp ? "readonly" : "final", + (defred[0] ? defred[0] - 2 : 0)); +@@ -178,15 +178,15 @@ output_yydefred() + else + { + ++outline; +- putchar('\n'); ++ putc('\n', output_file); + j = 1; + } + +- printf("%5d,", (defred[i] ? defred[i] - 2 : 0)); ++ fprintf(output_file, "%5d,", (defred[i] ? defred[i] - 2 : 0)); + } + + outline += 2; +- printf("\n };\n"); ++ fprintf(output_file, "\n };\n"); + } + + +@@ -309,7 +309,7 @@ goto_actions() + state_count = NEW2(nstates, short); + + k = default_goto(start_symbol + 1); +- printf(" protected static %s short [] yyDgoto = {%14d,", csharp ? "readonly" : "final", k); ++ fprintf(output_file, " protected static %s short [] yyDgoto = {%14d,", csharp ? "readonly" : "final", k); + save_column(start_symbol + 1, k); + + j = 10; +@@ -318,19 +318,19 @@ goto_actions() + if (j >= 10) + { + ++outline; +- putchar('\n'); ++ putc('\n', output_file); + j = 1; + } + else + ++j; + + k = default_goto(i); +- printf("%5d,", k); ++ fprintf(output_file, "%5d,", k); + save_column(i, k); + } + + outline += 2; +- printf("\n };\n"); ++ fprintf(output_file, "\n };\n"); + FREE(state_count); + } + +@@ -633,7 +633,7 @@ output_base() + { + register int i, j; + +- printf(" protected static %s short [] yySindex = {%13d,", csharp? "readonly":"final", base[0]); ++ fprintf(output_file, " protected static %s short [] yySindex = {%13d,", csharp? "readonly":"final", base[0]); + + j = 10; + for (i = 1; i < nstates; i++) +@@ -641,17 +641,17 @@ output_base() + if (j >= 10) + { + ++outline; +- putchar('\n'); ++ putc('\n', output_file); + j = 1; + } + else + ++j; + +- printf("%5d,", base[i]); ++ fprintf(output_file, "%5d,", base[i]); + } + + outline += 2; +- printf("\n };\n protected static %s short [] yyRindex = {%13d,", ++ fprintf(output_file, "\n };\n protected static %s short [] yyRindex = {%13d,", + csharp ? "readonly" : "final", + base[nstates]); + +@@ -661,17 +661,17 @@ output_base() + if (j >= 10) + { + ++outline; +- putchar('\n'); ++ putc('\n', output_file); + j = 1; + } + else + ++j; + +- printf("%5d,", base[i]); ++ fprintf(output_file, "%5d,", base[i]); + } + + outline += 2; +- printf("\n };\n protected static %s short [] yyGindex = {%13d,", ++ fprintf(output_file, "\n };\n protected static %s short [] yyGindex = {%13d,", + csharp ? "readonly" : "final", + base[2*nstates]); + +@@ -681,17 +681,17 @@ output_base() + if (j >= 10) + { + ++outline; +- putchar('\n'); ++ putc('\n', output_file); + j = 1; + } + else + ++j; + +- printf("%5d,", base[i]); ++ fprintf(output_file, "%5d,", base[i]); + } + + outline += 2; +- printf("\n };\n"); ++ fprintf(output_file, "\n };\n"); + FREE(base); + } + +@@ -702,7 +702,7 @@ output_table() + register int i; + register int j; + +- printf(" protected static %s short [] yyTable = {%14d,", csharp ? "readonly" : "final", table[0]); ++ fprintf(output_file, " protected static %s short [] yyTable = {%14d,", csharp ? "readonly" : "final", table[0]); + + j = 10; + for (i = 1; i <= high; i++) +@@ -710,17 +710,17 @@ output_table() + if (j >= 10) + { + ++outline; +- putchar('\n'); ++ putc('\n', output_file); + j = 1; + } + else + ++j; + +- printf("%5d,", table[i]); ++ fprintf(output_file, "%5d,", table[i]); + } + + outline += 2; +- printf("\n };\n"); ++ fprintf(output_file, "\n };\n"); + FREE(table); + } + +@@ -731,7 +731,7 @@ output_check() + register int i; + register int j; + +- printf(" protected static %s short [] yyCheck = {%14d,", ++ fprintf(output_file, " protected static %s short [] yyCheck = {%14d,", + csharp ? "readonly" : "final", + check[0]); + +@@ -741,17 +741,17 @@ output_check() + if (j >= 10) + { + ++outline; +- putchar('\n'); ++ putc('\n', output_file); + j = 1; + } + else + ++j; + +- printf("%5d,", check[i]); ++ fprintf(output_file, "%5d,", check[i]); + } + + outline += 2; +- printf("\n };\n"); ++ fprintf(output_file, "\n };\n"); + FREE(check); + } + +@@ -801,30 +801,30 @@ char *prefix; + if (is_C_identifier(s)) + { + if (prefix) +- printf(" %s ", prefix); ++ fprintf(output_file, " %s ", prefix); + c = *s; + if (c == '"') + { + while ((c = *++s) != '"') + { +- putchar(c); ++ putc(c, output_file); + } + } + else + { + do + { +- putchar(c); ++ putc(c, output_file); + } + while (c = *++s); + } + ++outline; +- printf(" = %d%s\n", symbol_value[i], csharp ? ";" : ";"); ++ fprintf(output_file, " = %d%s\n", symbol_value[i], csharp ? ";" : ";"); + } + } + + ++outline; +- printf(" %s yyErrorCode = %d%s\n", prefix ? prefix : "", symbol_value[1], csharp ? ";" : ";"); ++ fprintf(output_file, " %s yyErrorCode = %d%s\n", prefix ? prefix : "", symbol_value[1], csharp ? ";" : ";"); + } + + +@@ -842,14 +842,14 @@ char *name; + if ((c = getc(in)) != EOF) { + if (c == '\n') + ++outline; +- putchar(c); ++ putc(c, output_file); + while ((c = getc(in)) != EOF) + { + if (c == '\n') + ++outline; +- putchar(c); ++ putc(c, output_file); + } +- printf(default_line_format, ++outline + 1); ++ fprintf(output_file, default_line_format, ++outline + 1); + } + fclose(in); + } +@@ -862,67 +862,67 @@ output_debug() + char * prefix = tflag ? "" : "//t"; + + ++outline; +- printf(" protected %s int yyFinal = %d;\n", csharp ? "const" : "static final", final_state); ++ fprintf(output_file, " protected %s int yyFinal = %d;\n", csharp ? "const" : "static final", final_state); + + ++outline; +- printf ("%s // Put this array into a separate class so it is only initialized if debugging is actually used\n", prefix); +- printf ("%s // Use MarshalByRefObject to disable inlining\n", prefix); +- printf("%s class YYRules %s {\n", prefix, csharp ? ": MarshalByRefObject" : ""); +- printf("%s public static %s string [] yyRule = {\n", prefix, csharp ? "readonly" : "final"); ++ fprintf(output_file, "%s // Put this array into a separate class so it is only initialized if debugging is actually used\n", prefix); ++ fprintf(output_file, "%s // Use MarshalByRefObject to disable inlining\n", prefix); ++ fprintf(output_file, "%s class YYRules %s {\n", prefix, csharp ? ": MarshalByRefObject" : ""); ++ fprintf(output_file, "%s public static %s string [] yyRule = {\n", prefix, csharp ? "readonly" : "final"); + for (i = 2; i < nrules; ++i) + { +- printf("%s \"%s :", prefix, symbol_name[rlhs[i]]); ++ fprintf(output_file, "%s \"%s :", prefix, symbol_name[rlhs[i]]); + for (j = rrhs[i]; ritem[j] > 0; ++j) + { + s = symbol_name[ritem[j]]; + if (s[0] == '"') + { +- printf(" \\\""); ++ fprintf(output_file, " \\\""); + while (*++s != '"') + { + if (*s == '\\') + { + if (s[1] == '\\') +- printf("\\\\\\\\"); ++ fprintf(output_file, "\\\\\\\\"); + else +- printf("\\\\%c", s[1]); ++ fprintf(output_file, "\\\\%c", s[1]); + ++s; + } + else +- putchar(*s); ++ putc(*s, output_file); + } +- printf("\\\""); ++ fprintf(output_file, "\\\""); + } + else if (s[0] == '\'') + { + if (s[1] == '"') +- printf(" '\\\"'"); ++ fprintf(output_file, " '\\\"'"); + else if (s[1] == '\\') + { + if (s[2] == '\\') +- printf(" '\\\\\\\\"); ++ fprintf(output_file, " '\\\\\\\\"); + else +- printf(" '\\\\%c", s[2]); ++ fprintf(output_file, " '\\\\%c", s[2]); + s += 2; + while (*++s != '\'') +- putchar(*s); +- putchar('\''); ++ putc(*s, output_file); ++ putc('\'', output_file); + } + else +- printf(" '%c'", s[1]); ++ fprintf(output_file, " '%c'", s[1]); + } + else +- printf(" %s", s); ++ fprintf(output_file, " %s", s); + } + ++outline; +- printf("\",\n"); ++ fprintf(output_file, "\",\n"); + } + ++ outline; +- printf("%s };\n", prefix); +- printf ("%s public static string getRule (int index) {\n", prefix); +- printf ("%s return yyRule [index];\n", prefix); +- printf ("%s }\n", prefix); +- printf ("%s}\n", prefix); ++ fprintf(output_file, "%s };\n", prefix); ++ fprintf(output_file, "%s public static string getRule (int index) {\n", prefix); ++ fprintf(output_file, "%s return yyRule [index];\n", prefix); ++ fprintf(output_file, "%s }\n", prefix); ++ fprintf(output_file, "%s}\n", prefix); + + max = 0; + for (i = 2; i < ntokens; ++i) +@@ -931,7 +931,7 @@ output_debug() + + /* need yyNames for yyExpecting() */ + +- printf(" protected static %s string [] yyNames = {", csharp ? "readonly" : "final"); ++ fprintf(output_file, " protected static %s string [] yyNames = {", csharp ? "readonly" : "final"); + symnam = (char **) MALLOC((max+1)*sizeof(char *)); + if (symnam == 0) no_space(); + +@@ -943,7 +943,7 @@ output_debug() + symnam[symbol_value[i]] = symbol_name[i]; + symnam[0] = "end-of-file"; + +- j = 70; fputs(" ", stdout); ++ j = 70; fputs(" ", output_file); + for (i = 0; i <= max; ++i) + { + if (s = symnam[i]) +@@ -965,25 +965,25 @@ output_debug() + if (j > 70) + { + ++outline; +- printf("\n "); ++ fprintf(output_file, "\n "); + j = k; + } +- printf("\"\\\""); ++ fprintf(output_file, "\"\\\""); + s = symnam[i]; + while (*++s != '"') + { + if (*s == '\\') + { +- printf("\\\\"); ++ fprintf(output_file, "\\\\"); + if (*++s == '\\') +- printf("\\\\"); ++ fprintf(output_file, "\\\\"); + else +- putchar(*s); ++ putc(*s, output_file); + } + else +- putchar(*s); ++ putc(*s, output_file); + } +- printf("\\\"\","); ++ fprintf(output_file, "\\\"\","); + } + else if (s[0] == '\'') + { +@@ -993,10 +993,10 @@ output_debug() + if (j > 70) + { + ++outline; +- printf("\n "); ++ fprintf(output_file, "\n "); + j = 7; + } +- printf("\"'\\\"'\","); ++ fprintf(output_file, "\"'\\\"'\","); + } + else + { +@@ -1015,25 +1015,25 @@ output_debug() + if (j > 70) + { + ++outline; +- printf("\n "); ++ fprintf(output_file, "\n "); + j = k; + } +- printf("\"'"); ++ fprintf(output_file, "\"'"); + s = symnam[i]; + while (*++s != '\'') + { + if (*s == '\\') + { +- printf("\\\\"); ++ fprintf(output_file, "\\\\"); + if (*++s == '\\') +- printf("\\\\"); ++ fprintf(output_file, "\\\\"); + else +- putchar(*s); ++ putc(*s, output_file); + } + else +- putchar(*s); ++ putc(*s, output_file); + } +- printf("'\","); ++ fprintf(output_file, "'\","); + } + } + else +@@ -1043,12 +1043,12 @@ output_debug() + if (j > 70) + { + ++outline; +- printf("\n "); ++ fprintf(output_file, "\n "); + j = k; + } +- putchar('"'); +- do { putchar(*s); } while (*++s); +- printf("\","); ++ putc('"', output_file); ++ do { putc(*s, output_file); } while (*++s); ++ fprintf(output_file, "\","); + } + } + else +@@ -1057,14 +1057,14 @@ output_debug() + if (j > 70) + { + ++outline; +- printf("\n "); ++ fprintf(output_file, "\n "); + j = 5; + } +- printf("null,"); ++ fprintf(output_file, "null,"); + } + } + outline += 2; +- printf("\n };\n"); ++ fprintf(output_file, "\n };\n"); + FREE(symnam); + } + +@@ -1084,19 +1084,19 @@ output_trailing_text() + if ((c = getc(in)) == EOF) + return; + ++outline; +- printf(line_format, lineno, input_file_name); ++ fprintf(output_file, line_format, lineno, input_file_name); + if (c == '\n') + ++outline; +- putchar(c); ++ putc(c, output_file); + last = c; + } + else + { + ++outline; +- printf(line_format, lineno, input_file_name); +- do { putchar(c); } while ((c = *++cptr) != '\n'); ++ fprintf(output_file, line_format, lineno, input_file_name); ++ do { putc(c, output_file); } while ((c = *++cptr) != '\n'); + ++outline; +- putchar('\n'); ++ putc('\n', output_file); + last = '\n'; + } + +@@ -1104,16 +1104,16 @@ output_trailing_text() + { + if (c == '\n') + ++outline; +- putchar(c); ++ putc(c, output_file); + last = c; + } + + if (last != '\n') + { + ++outline; +- putchar('\n'); ++ putc('\n', output_file); + } +- printf(default_line_format, ++outline + 1); ++ fprintf(output_file, default_line_format, ++outline + 1); + } + + +@@ -1132,22 +1132,22 @@ output_semantic_actions() + last = c; + if (c == '\n') + ++outline; +- putchar(c); ++ putc(c, output_file); + while ((c = getc(action_file)) != EOF) + { + if (c == '\n') + ++outline; +- putchar(c); ++ putc(c, output_file); + last = c; + } + + if (last != '\n') + { + ++outline; +- putchar('\n'); ++ putc('\n', output_file); + } + +- printf(default_line_format, ++outline + 1); ++ fprintf(output_file, default_line_format, ++outline + 1); + } + + +diff --git a/mcs/mcs/Makefile b/mcs/mcs/Makefile +index dbd71a3d581..dbf040afdd6 100644 +--- a/mcs/mcs/Makefile ++++ b/mcs/mcs/Makefile +@@ -32,7 +32,7 @@ BUILT_SOURCES = cs-parser.cs + CLEAN_FILES += y.output + + %-parser.cs: %-parser.jay $(topdir)/jay/skeleton.cs +- $(topdir)/jay/jay $(JAY_FLAGS) < $(topdir)/jay/skeleton.cs $< > jay-tmp.out && mv jay-tmp.out $@ ++ $(topdir)/jay/jay $(JAY_FLAGS) -o jay-tmp.out $< < $(topdir)/jay/skeleton.cs && mv jay-tmp.out $@ + + KEEP_OUTPUT_FILE_COPY = yes + +diff --git a/mcs/mcs/argument.cs b/mcs/mcs/argument.cs +index 5b1003dbadf..4c75e41a9e5 100644 +--- a/mcs/mcs/argument.cs ++++ b/mcs/mcs/argument.cs +@@ -38,6 +38,8 @@ namespace Mono.CSharp + // Conditional instance expression inserted as the first argument + ExtensionTypeConditionalAccess = 5 | ConditionalAccessFlag, + ++ Readonly = 6, ++ + ConditionalAccessFlag = 1 << 7 + } + +diff --git a/mcs/mcs/assembly.cs b/mcs/mcs/assembly.cs +index aa4c54317a2..96e43e70d99 100644 +--- a/mcs/mcs/assembly.cs ++++ b/mcs/mcs/assembly.cs +@@ -554,7 +554,8 @@ namespace Mono.CSharp + if (prop != null) { + AttributeEncoder encoder = new AttributeEncoder (); + encoder.EncodeNamedPropertyArgument (prop, new BoolLiteral (Compiler.BuiltinTypes, true, Location.Null)); +- SetCustomAttribute (pa.Constructor, encoder.ToArray ()); ++ SetCustomAttribute (pa.Constructor, encoder.ToArray (out var references)); ++ module.AddAssemblyReferences (references); + } + } + } +diff --git a/mcs/mcs/attribute.cs b/mcs/mcs/attribute.cs +index 83d403118ad..faf2cfaa1d8 100644 +--- a/mcs/mcs/attribute.cs ++++ b/mcs/mcs/attribute.cs +@@ -1064,8 +1064,10 @@ namespace Mono.CSharp { + } + + byte[] cdata; ++ List references; + if (pos_args == null && named_values == null) { + cdata = AttributeEncoder.Empty; ++ references = null; + } else { + AttributeEncoder encoder = new AttributeEncoder (); + +@@ -1138,7 +1140,7 @@ namespace Mono.CSharp { + encoder.EncodeEmptyNamedArguments (); + } + +- cdata = encoder.ToArray (); ++ cdata = encoder.ToArray (out references); + } + + if (!IsConditionallyExcluded (ctor.DeclaringType)) { +@@ -1157,6 +1159,8 @@ namespace Mono.CSharp { + Error_AttributeEmitError (e.Message); + return; + } ++ ++ context.Module.AddAssemblyReferences (references); + } + + if (!usage_attr.AllowMultiple && allEmitted != null) { +@@ -1415,6 +1419,7 @@ namespace Mono.CSharp { + byte[] buffer; + int pos; + const ushort Version = 1; ++ List imports; + + static AttributeEncoder () + { +@@ -1594,7 +1599,15 @@ namespace Mono.CSharp { + public void EncodeTypeName (TypeSpec type) + { + var old_type = type.GetMetaInfo (); +- Encode (type.MemberDefinition.IsImported ? old_type.AssemblyQualifiedName : old_type.FullName); ++ if (type.MemberDefinition.IsImported) { ++ if (imports == null) ++ imports = new List (); ++ ++ imports.Add (old_type.Assembly); ++ Encode (old_type.AssemblyQualifiedName); ++ } else { ++ Encode (old_type.FullName); ++ } + } + + public void EncodeTypeName (TypeContainer type) +@@ -1675,8 +1688,10 @@ namespace Mono.CSharp { + Encode (value); + } + +- public byte[] ToArray () ++ public byte[] ToArray (out List assemblyReferences) + { ++ assemblyReferences = imports; ++ + byte[] buf = new byte[pos]; + Array.Copy (buffer, buf, pos); + return buf; +@@ -1990,7 +2005,8 @@ namespace Mono.CSharp { + encoder.Encode ((int) state); + encoder.EncodeEmptyNamedArguments (); + +- builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ()); ++ builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray (out var references)); ++ module.AddAssemblyReferences (references); + } + } + +@@ -2024,7 +2040,8 @@ namespace Mono.CSharp { + encoder.Encode ((int) modes); + encoder.EncodeEmptyNamedArguments (); + +- builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ()); ++ builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray (out var references)); ++ module.AddAssemblyReferences (references); + } + } + +@@ -2050,7 +2067,8 @@ namespace Mono.CSharp { + encoder.Encode ((uint) bits[0]); + encoder.EncodeEmptyNamedArguments (); + +- builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ()); ++ builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray (out var references)); ++ module.AddAssemblyReferences (references); + } + + public void EmitAttribute (FieldBuilder builder, decimal value, Location loc) +@@ -2068,7 +2086,8 @@ namespace Mono.CSharp { + encoder.Encode ((uint) bits[0]); + encoder.EncodeEmptyNamedArguments (); + +- builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ()); ++ builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray (out var references)); ++ module.AddAssemblyReferences (references); + } + } + +@@ -2092,7 +2111,8 @@ namespace Mono.CSharp { + encoder.EncodeTypeName (type); + encoder.EncodeEmptyNamedArguments (); + +- builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ()); ++ builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray (out var references)); ++ module.AddAssemblyReferences (references); + } + } + +diff --git a/mcs/mcs/class.cs b/mcs/mcs/class.cs +index 6b1adc297a3..dc61f6dc627 100644 +--- a/mcs/mcs/class.cs ++++ b/mcs/mcs/class.cs +@@ -2117,7 +2117,8 @@ namespace Mono.CSharp + encoder.Encode (GetAttributeDefaultMember ()); + encoder.EncodeEmptyNamedArguments (); + +- TypeBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ()); ++ TypeBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray (out var references)); ++ Module.AddAssemblyReferences (references); + } + + public override void VerifyMembers () +@@ -3962,7 +3963,10 @@ namespace Mono.CSharp + Report.Error (4013, Location, + "Local variables of type `{0}' cannot be used inside anonymous methods, lambda expressions or query expressions", + MemberType.GetSignatureForError ()); +- } else if (MemberType.IsByRefLike) { ++ } else if (MemberType.IsSpecialRuntimeType) { ++ Report.Error (610, Location, ++ "Field or property cannot be of type `{0}'", MemberType.GetSignatureForError ()); ++ } else { + if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0) + return; + +@@ -3975,9 +3979,6 @@ namespace Mono.CSharp + Report.Error (8345, Location, + "Field or auto-implemented property cannot be of type `{0}' unless it is an instance member of a ref struct", + MemberType.GetSignatureForError ()); +- } else { +- Report.Error (610, Location, +- "Field or property cannot be of type `{0}'", MemberType.GetSignatureForError ()); + } + } + } +diff --git a/mcs/mcs/convert.cs b/mcs/mcs/convert.cs +index ae153fc49e8..2c8d2a0204c 100644 +--- a/mcs/mcs/convert.cs ++++ b/mcs/mcs/convert.cs +@@ -1232,6 +1232,13 @@ namespace Mono.CSharp { + FindApplicableUserDefinedConversionOperators (rc, operators, source_type_expr, target_type, restr, ref candidates); + } + ++ if (source_type_expr == source && source_type.IsNullableType) { ++ operators = MemberCache.GetUserOperator (source_type.TypeArguments [0], Operator.OpType.Implicit, declared_only); ++ if (operators != null) { ++ FindApplicableUserDefinedConversionOperators (rc, operators, source_type_expr, target_type, restr, ref candidates); ++ } ++ } ++ + if (!implicitOnly) { + operators = MemberCache.GetUserOperator (source_type, Operator.OpType.Explicit, declared_only); + if (operators != null) { +diff --git a/mcs/mcs/cs-parser.jay b/mcs/mcs/cs-parser.jay +index 4d6fcb44c0d..4ca3bf74f3d 100644 +--- a/mcs/mcs/cs-parser.jay ++++ b/mcs/mcs/cs-parser.jay +@@ -34,13 +34,16 @@ namespace Mono.CSharp + Params = 1 << 4, + Arglist = 1 << 5, + DefaultValue = 1 << 6, ++ ReadOnly = 1 << 7, + +- All = Ref | Out | This | Params | Arglist | DefaultValue, ++ All = Ref | Out | This | Params | Arglist | DefaultValue | ReadOnly, + PrimaryConstructor = Ref | Out | Params | DefaultValue + } + + static readonly object ModifierNone = 0; +- ++ static readonly object RefStructToken = new object (); ++ static readonly object RefPartialStructToken = new object (); ++ + NamespaceContainer current_namespace; + TypeContainer current_container; + TypeDefinition current_type; +@@ -338,6 +341,7 @@ namespace Mono.CSharp + %token OPEN_BRACKET_EXPR + %token OPEN_PARENS_DECONSTRUCT + %token REF_STRUCT ++%token REF_PARTIAL + + // Make the parser go into eval mode parsing (statements and compilation units). + %token EVAL_STATEMENT_PARSER +@@ -648,8 +652,8 @@ namespace_or_type_declaration + TypeContainer ds = (TypeContainer)$1; + + if ((ds.ModFlags & (Modifiers.PRIVATE | Modifiers.PROTECTED)) != 0){ +- report.Error (1527, ds.Location, +- "Namespace elements cannot be explicitly declared as private, protected or protected internal"); ++ report.Error (1527, ds.Location, ++ "Namespace elements cannot be explicitly declared as private, protected, protected internal, or private protected"); + } + + // Here is a trick, for explicit attributes we don't know where they belong to until +@@ -1028,7 +1032,15 @@ struct_keyword + FeatureIsNotAvailable (GetLocation ($1), "ref structs"); + } + +- $$ = this; ++ $$ = RefStructToken; ++ } ++ | REF_PARTIAL STRUCT ++ { ++ if (lang_version < LanguageVersion.V_7_2) { ++ FeatureIsNotAvailable (GetLocation ($1), "ref structs"); ++ } ++ ++ $$ = RefPartialStructToken; + } + ; + +@@ -1043,8 +1055,13 @@ struct_declaration + if ((mods & Modifiers.READONLY) != 0 && lang_version < LanguageVersion.V_7_2) { + FeatureIsNotAvailable (GetLocation ($4), "readonly structs"); + } +- if ($4 != null) ++ if ($4 != null) { + mods |= Modifiers.REF; ++ if ($4 == RefPartialStructToken) { ++ mods |= Modifiers.PARTIAL; ++ $3 = $4; ++ } ++ } + + lexer.ConstraintsParsing = true; + valid_param_mod = ParameterModifierType.PrimaryConstructor; +@@ -1469,7 +1486,7 @@ method_header + OPEN_PARENS + { + lexer.parsing_generic_declaration = false; +- valid_param_mod = ParameterModifierType.All; ++ valid_param_mod = ParameterModifierType.All; + } + opt_formal_parameter_list CLOSE_PARENS + { +@@ -1569,7 +1586,7 @@ constructor_body + expression SEMICOLON + { + lexer.parsing_block = 0; +- current_block.AddStatement (new ContextualReturn ((Expression) $3)); ++ current_block.AddStatement (CreateExpressionBodiedStatement ((Expression) $3)); + var b = end_block (GetLocation ($4)); + b.IsCompilerGenerated = true; + $$ = b; +@@ -1590,7 +1607,7 @@ expression_block + lambda_arrow_expression SEMICOLON + { + lexer.parsing_block = 0; +- current_block.AddStatement (new ContextualReturn ((Expression) $3)); ++ current_block.AddStatement (CreateExpressionBodiedStatement ((Expression) $3)); + var b = end_block (GetLocation ($4)); + b.IsCompilerGenerated = true; + $$ = b; +@@ -1794,7 +1811,9 @@ parameter_modifiers + Parameter.Modifier mod = (Parameter.Modifier)$1 | p2; + if (((Parameter.Modifier)$1 & p2) == p2) { + Error_DuplicateParameterModifier (lexer.Location, p2); +- } else { ++ } else if ((mod & ~(Parameter.Modifier.This | Parameter.Modifier.ReadOnly)) == 0) { ++ // ok ++ } else { + switch (mod & ~Parameter.Modifier.This) { + case Parameter.Modifier.REF: + report.Error (1101, lexer.Location, "The parameter modifiers `this' and `ref' cannot be used altogether"); +@@ -1836,6 +1855,13 @@ parameter_modifier + + $$ = Parameter.Modifier.This; + } ++ | IN ++ { ++ if (lang_version < LanguageVersion.V_7_2) ++ FeatureIsNotAvailable (GetLocation ($1), "readonly references"); ++ ++ $$ = Parameter.Modifier.ReadOnly; ++ } + ; + + parameter_array +@@ -1871,7 +1897,7 @@ params_modifier + if ((mod & Parameter.Modifier.This) != 0) { + report.Error (1104, GetLocation ($1), "The parameter modifiers `this' and `params' cannot be used altogether"); + } else { +- report.Error (1611, GetLocation ($1), "The params parameter cannot be declared as ref or out"); ++ report.Error (1611, GetLocation ($1), "The params parameter cannot be declared as ref, out or in"); + } + } + | PARAMS params_modifier +@@ -2004,7 +2030,7 @@ indexer_declaration + : opt_attributes opt_modifiers + ref_member_type indexer_declaration_name OPEN_BRACKET + { +- valid_param_mod = ParameterModifierType.Params | ParameterModifierType.DefaultValue; ++ valid_param_mod = ParameterModifierType.Params | ParameterModifierType.DefaultValue | ParameterModifierType.ReadOnly; + } + opt_formal_parameter_list CLOSE_BRACKET + { +@@ -2181,6 +2207,11 @@ set_accessor_declaration + accessor_body + : block + | expression_block ++ { ++ if (lang_version < LanguageVersion.V_7) { ++ FeatureIsNotAvailable (GetLocation ($1), "expression body property accessor"); ++ } ++ } + | SEMICOLON + { + // TODO: lbag +@@ -2331,7 +2362,7 @@ operator_type + operator_declarator + : operator_type OPERATOR overloadable_operator OPEN_PARENS + { +- valid_param_mod = ParameterModifierType.DefaultValue; ++ valid_param_mod = ParameterModifierType.DefaultValue | ParameterModifierType.ReadOnly; + if ((Operator.OpType) $3 == Operator.OpType.Is) + valid_param_mod |= ParameterModifierType.Out; + } +@@ -2418,7 +2449,7 @@ overloadable_operator + conversion_operator_declarator + : IMPLICIT OPERATOR type OPEN_PARENS + { +- valid_param_mod = ParameterModifierType.DefaultValue; ++ valid_param_mod = ParameterModifierType.DefaultValue | ParameterModifierType.ReadOnly; + } + opt_formal_parameter_list CLOSE_PARENS + { +@@ -2441,7 +2472,7 @@ conversion_operator_declarator + } + | EXPLICIT OPERATOR type OPEN_PARENS + { +- valid_param_mod = ParameterModifierType.DefaultValue; ++ valid_param_mod = ParameterModifierType.DefaultValue | ParameterModifierType.ReadOnly; + } + opt_formal_parameter_list CLOSE_PARENS + { +@@ -2850,6 +2881,11 @@ event_accessor_block + } + | block + | expression_block ++ { ++ if (lang_version < LanguageVersion.V_7) { ++ FeatureIsNotAvailable (GetLocation ($1), "expression body event accessor"); ++ } ++ } + ; + + attributes_without_members +@@ -3014,7 +3050,7 @@ delegate_declaration + ref_member_type type_declaration_name + OPEN_PARENS + { +- valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out | ParameterModifierType.Params | ParameterModifierType.DefaultValue; ++ valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out | ParameterModifierType.Params | ParameterModifierType.DefaultValue | ParameterModifierType.ReadOnly; + } + opt_formal_parameter_list CLOSE_PARENS + { +@@ -3927,7 +3963,15 @@ non_simple_argument + { + $$ = new Argument (new Arglist (GetLocation ($1))); + lbag.AddLocation ($$, GetLocation ($2), GetLocation ($3)); +- } ++ } ++ | IN variable_reference ++ { ++ if (lang_version < LanguageVersion.V_7_2) ++ FeatureIsNotAvailable (GetLocation ($1), "readonly references"); ++ ++ $$ = new Argument ((Expression) $2, Argument.AType.Readonly); ++ lbag.AddLocation ($$, GetLocation ($1)); ++ } + ; + + out_variable_declaration +@@ -4408,7 +4452,7 @@ opt_anonymous_method_signature + anonymous_method_signature + : OPEN_PARENS + { +- valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out; ++ valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out | ParameterModifierType.ReadOnly; + } + opt_formal_parameter_list CLOSE_PARENS + { +@@ -5014,36 +5058,47 @@ null_coalescing_expression + } + ; + ++ ++conditional_oper_expr ++ : expression ++ | stackalloc_expression ++ ; ++ + conditional_expression + : null_coalescing_expression +- | null_coalescing_expression INTERR expression COLON expression ++ | null_coalescing_expression INTERR conditional_oper_expr COLON conditional_oper_expr + { + $$ = new Conditional (new BooleanExpression ((Expression) $1), (Expression) $3, (Expression) $5, GetLocation ($2)); + lbag.AddLocation ($$, GetLocation ($4)); + } +- | null_coalescing_expression INTERR expression COLON THROW prefixed_unary_expression ++ | null_coalescing_expression INTERR conditional_oper_expr COLON THROW prefixed_unary_expression + { + if (lang_version < LanguageVersion.V_7) +- FeatureIsNotAvailable (lexer.Location, "throw expression"); ++ FeatureIsNotAvailable (GetLocation ($5), "throw expression"); + + var expr = new ThrowExpression ((Expression) $6, GetLocation ($5)); + $$ = new Conditional (new BooleanExpression ((Expression) $1), (Expression) $3, expr, GetLocation ($2)); + lbag.AddLocation ($$, GetLocation ($4)); + } +- | null_coalescing_expression INTERR expression error ++ | null_coalescing_expression INTERR reference_expression COLON reference_expression ++ { ++ $$ = new Conditional (new BooleanExpression ((Expression) $1), (Expression) $3, (Expression) $5, GetLocation ($2)); ++ lbag.AddLocation ($$, GetLocation ($4)); ++ } ++ | null_coalescing_expression INTERR conditional_oper_expr error + { + Error_SyntaxError (yyToken); + + $$ = new Conditional (new BooleanExpression ((Expression) $1), (Expression) $3, null, GetLocation ($2)); + } +- | null_coalescing_expression INTERR expression COLON error ++ | null_coalescing_expression INTERR conditional_oper_expr COLON error + { + Error_SyntaxError (yyToken); + + $$ = new Conditional (new BooleanExpression ((Expression) $1), (Expression) $3, null, GetLocation ($2)); + lbag.AddLocation ($$, GetLocation ($4)); + } +- | null_coalescing_expression INTERR expression COLON CLOSE_BRACE ++ | null_coalescing_expression INTERR conditional_oper_expr COLON CLOSE_BRACE + { + Error_SyntaxError (Token.CLOSE_BRACE); + +@@ -5308,7 +5363,7 @@ lambda_expression + } + | OPEN_PARENS_LAMBDA + { +- valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out; ++ valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out | ParameterModifierType.ReadOnly; + } + opt_lambda_parameter_list CLOSE_PARENS ARROW + { +@@ -5322,7 +5377,7 @@ lambda_expression + } + | ASYNC OPEN_PARENS_LAMBDA + { +- valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out; ++ valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out | ParameterModifierType.ReadOnly; + } + opt_lambda_parameter_list CLOSE_PARENS ARROW + { +@@ -5522,10 +5577,17 @@ modifiers + if ((m1 & m2) != 0) { + report.Error (1004, lexer.Location - ModifiersExtensions.Name (m2).Length, + "Duplicate `{0}' modifier", ModifiersExtensions.Name (m2)); +- } else if ((m2 & Modifiers.AccessibilityMask) != 0 && (m1 & Modifiers.AccessibilityMask) != 0 && +- ((m2 | m1 & Modifiers.AccessibilityMask) != (Modifiers.PROTECTED | Modifiers.INTERNAL))) { +- report.Error (107, lexer.Location - ModifiersExtensions.Name (m2).Length, +- "More than one protection modifier specified"); ++ } else if ((m2 & Modifiers.AccessibilityMask) != 0 && (m1 & Modifiers.AccessibilityMask) != 0) { ++ var accessibility = (m2 | m1 & Modifiers.AccessibilityMask); ++ ++ if (accessibility == (Modifiers.PRIVATE | Modifiers.PROTECTED)) { ++ if (lang_version < LanguageVersion.V_7_2) { ++ FeatureIsNotAvailable (lexer.Location, "private protected"); ++ } ++ } else if (accessibility != (Modifiers.PROTECTED | Modifiers.INTERNAL)) { ++ report.Error (107, lexer.Location - ModifiersExtensions.Name (m2).Length, ++ "More than one protection modifier specified"); ++ } + } + + $$ = m1 | m2; +@@ -6223,11 +6285,28 @@ block_variable_initializer + | STACKALLOC simple_type + { + report.Error (1575, GetLocation ($1), "A stackalloc expression requires [] after type"); +- $$ = new StackAlloc ((Expression) $2, null, GetLocation ($1)); ++ $$ = new StackAlloc ((Expression) $2, null, GetLocation ($1)); + } + | reference_expression + ; + ++stackalloc_expression ++ : STACKALLOC simple_type OPEN_BRACKET_EXPR expression CLOSE_BRACKET ++ { ++ if (lang_version < LanguageVersion.V_7_2) { ++ FeatureIsNotAvailable (GetLocation ($1), "ref structs"); ++ } ++ ++ $$ = new SpanStackAlloc ((Expression) $2, (Expression) $4, GetLocation ($1)); ++ lbag.AddLocation ($$, GetLocation ($3), GetLocation ($5)); ++ } ++ | STACKALLOC simple_type ++ { ++ report.Error (1575, GetLocation ($1), "A stackalloc expression requires [] after type"); ++ $$ = new StackAlloc ((Expression) $2, null, GetLocation ($1)); ++ } ++ ; ++ + reference_expression + : REF expression + { +@@ -7699,7 +7778,7 @@ doc_cref + } + | doc_type_declaration_name DOT THIS OPEN_BRACKET + { +- valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out; ++ valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out | ParameterModifierType.ReadOnly; + } + opt_doc_parameters CLOSE_BRACKET + { +@@ -7743,7 +7822,7 @@ opt_doc_method_sig + : /* empty */ + | OPEN_PARENS + { +- valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out; ++ valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out | ParameterModifierType.ReadOnly; + } + opt_doc_parameters CLOSE_PARENS + { +@@ -7951,6 +8030,14 @@ static bool IsUnaryOperator (Operator.OpType op) + return false; + } + ++static Statement CreateExpressionBodiedStatement (Expression expr) ++{ ++ if (expr is ThrowExpression te) ++ return new StatementExpression (te); ++ ++ return new ContextualReturn (expr); ++} ++ + void syntax_error (Location l, string msg) + { + report.Error (1003, l, "Syntax error, " + msg); +@@ -8430,6 +8517,8 @@ static string GetTokenName (int token) + case Token.READONLY: + return "readonly"; + case Token.REF: ++ case Token.REF_STRUCT: ++ case Token.REF_PARTIAL: + return "ref"; + case Token.RETURN: + return "return"; +@@ -8444,7 +8533,6 @@ static string GetTokenName (int token) + case Token.STATIC: + return "static"; + case Token.STRUCT: +- case Token.REF_STRUCT: + return "struct"; + case Token.SWITCH: + return "switch"; +diff --git a/mcs/mcs/cs-tokenizer.cs b/mcs/mcs/cs-tokenizer.cs +index 37edb5c1224..db5ba1f1f1b 100644 +--- a/mcs/mcs/cs-tokenizer.cs ++++ b/mcs/mcs/cs-tokenizer.cs +@@ -825,8 +825,7 @@ namespace Mono.CSharp + next_token == Token.CLASS || + next_token == Token.STRUCT || + next_token == Token.INTERFACE || +- next_token == Token.VOID || +- next_token == Token.REF_STRUCT; ++ next_token == Token.VOID; + + PopPosition (); + +@@ -916,14 +915,20 @@ namespace Mono.CSharp + + break; + case Token.REF: +- if (peek_token () == Token.STRUCT) { ++ var pp = peek_token (); ++ switch (pp) { ++ case Token.STRUCT: + token (); + res = Token.REF_STRUCT; ++ break; ++ case Token.PARTIAL: ++ token (); ++ res = Token.REF_PARTIAL; ++ break; + } + break; + } + +- + return res; + } + +@@ -1212,6 +1217,7 @@ namespace Mono.CSharp + + case Token.REF: + case Token.OUT: ++ case Token.IN: + can_be_type = is_type = false; + continue; + +@@ -1406,6 +1412,8 @@ namespace Mono.CSharp + case Token.INTERPOLATED_STRING: + case Token.THROW: + case Token.DEFAULT_COLON: ++ case Token.REF: ++ case Token.STACKALLOC: + next_token = Token.INTERR; + break; + +@@ -1567,28 +1575,53 @@ namespace Mono.CSharp + { + int d; + bool seen_digits = false; +- +- if (c != -1){ ++ bool digit_separator = false; ++ int prev = c; ++ var loc = Location; ++ ++ if (prev != -1){ + if (number_pos == MaxNumberLength) + Error_NumericConstantTooLong (); +- number_builder [number_pos++] = (char) c; ++ number_builder [number_pos++] = (char) prev; + } +- ++ + // + // We use peek_char2, because decimal_digits needs to do a + // 2-character look-ahead (5.ToString for example). + // + while ((d = peek_char2 ()) != -1){ +- if (d >= '0' && d <= '9'){ ++ if (d >= '0' && d <= '9') { + if (number_pos == MaxNumberLength) + Error_NumericConstantTooLong (); +- number_builder [number_pos++] = (char) d; +- get_char (); ++ number_builder [number_pos++] = (char)d; ++ prev = get_char (); + seen_digits = true; +- } else +- break; ++ continue; ++ } else if (d == '_') { ++ if (!digit_separator) { ++ if (context.Settings.Version < LanguageVersion.V_7) ++ Report.FeatureIsNotAvailable (context, Location, "digit separators"); ++ ++ digit_separator = true; ++ } ++ ++ if (prev == '.') ++ break; ++ ++ if (prev == 'e' || prev == 'E') ++ Error_InvalidNumber (); ++ ++ prev = get_char(); ++ continue; ++ } ++ ++ break; + } + ++ if (prev == '_') { ++ Error_InvalidNumber (); ++ } ++ + return seen_digits; + } + +@@ -1716,9 +1749,8 @@ namespace Mono.CSharp + } catch (OverflowException) { + Error_NumericConstantTooLong (); + return new IntLiteral (context.BuiltinTypes, 0, loc); +- } +- catch (FormatException) { +- Report.Error (1013, Location, "Invalid number"); ++ } catch (FormatException) { ++ Error_InvalidNumber (); + return new IntLiteral (context.BuiltinTypes, 0, loc); + } + } +@@ -1757,14 +1789,41 @@ namespace Mono.CSharp + { + int d; + ulong ul; +- +- get_char (); ++ bool digit_separator = false; ++ int prev = get_char (); ++ + while ((d = peek_char ()) != -1){ + if (is_hex (d)){ + number_builder [number_pos++] = (char) d; + get_char (); +- } else +- break; ++ ++ prev = d; ++ continue; ++ } ++ ++ if (d == '_') { ++ if (prev == 'x' || prev == 'X') ++ Error_InvalidNumber (); ++ ++ get_char (); ++ ++ if (!digit_separator) { ++ if (context.Settings.Version < LanguageVersion.V_7) ++ Report.FeatureIsNotAvailable (context, Location, "digit separators"); ++ ++ digit_separator = true; ++ } ++ ++ prev = d; ++ continue; ++ } ++ ++ break; ++ } ++ ++ if (number_pos == 0 || prev == '_') { ++ Error_InvalidNumber (); ++ return new IntLiteral (context.BuiltinTypes, 0, loc); + } + + string s = new String (number_builder, 0, number_pos); +@@ -1779,13 +1838,65 @@ namespace Mono.CSharp + } catch (OverflowException){ + Error_NumericConstantTooLong (); + return new IntLiteral (context.BuiltinTypes, 0, loc); +- } +- catch (FormatException) { +- Report.Error (1013, Location, "Invalid number"); ++ } catch (FormatException) { ++ Error_InvalidNumber (); + return new IntLiteral (context.BuiltinTypes, 0, loc); + } + } + ++ ILiteralConstant handle_binary (Location loc) ++ { ++ int d; ++ ulong ul = 0; ++ bool digit_separator = false; ++ int digits = 0; ++ int prev = get_char (); ++ ++ while ((d = peek_char ()) != -1){ ++ ++ if (d == '0' || d == '1') { ++ ul = (ul << 1); ++ digits++; ++ if (d == '1') ++ ul |= 1; ++ get_char (); ++ if (digits > 64) { ++ Error_NumericConstantTooLong (); ++ return new IntLiteral (context.BuiltinTypes, 0, loc); ++ } ++ ++ prev = d; ++ continue; ++ } ++ ++ if (d == '_') { ++ if (prev == 'b' || prev == 'B') ++ Error_InvalidNumber (); ++ ++ get_char (); ++ ++ if (!digit_separator) { ++ if (context.Settings.Version < LanguageVersion.V_7) ++ Report.FeatureIsNotAvailable (context, Location, "digit separators"); ++ ++ digit_separator = true; ++ } ++ ++ prev = d; ++ continue; ++ } ++ ++ break; ++ } ++ ++ if (digits == 0 || prev == '_') { ++ Error_InvalidNumber (); ++ return new IntLiteral (context.BuiltinTypes, 0, loc); ++ } ++ ++ return integer_type_suffix (ul, peek_char (), loc); ++ } ++ + // + // Invoked if we know we have .digits or digits + // +@@ -1817,7 +1928,20 @@ namespace Mono.CSharp + + return Token.LITERAL; + } ++ ++ if (peek == 'b' || peek == 'B'){ ++ if (context.Settings.Version < LanguageVersion.V_7) ++ Report.FeatureIsNotAvailable (context, Location, "binary literals"); ++ ++ val = res = handle_binary (loc); ++#if FULL_AST ++ res.ParsedValue = reader.ReadChars (read_start, reader.Position - 1); ++#endif ++ ++ return Token.LITERAL; ++ } + } ++ + decimal_digits (c); + c = peek_char (); + } +@@ -1869,7 +1993,7 @@ namespace Mono.CSharp + Error_NumericConstantTooLong (); + number_builder [number_pos++] = '+'; + } +- ++ + decimal_digits (c); + c = peek_char (); + } +@@ -2944,6 +3068,11 @@ namespace Mono.CSharp + { + Report.Error (1021, Location, "Integral constant is too large"); + } ++ ++ void Error_InvalidNumber () ++ { ++ Report.Error (1013, Location, "Invalid number"); ++ } + + void Error_InvalidDirective () + { +diff --git a/mcs/mcs/ecore.cs b/mcs/mcs/ecore.cs +index 20ee9e73b19..d5926bf4d1f 100644 +--- a/mcs/mcs/ecore.cs ++++ b/mcs/mcs/ecore.cs +@@ -241,7 +241,7 @@ namespace Mono.CSharp { + + protected void CheckExpressionVariable (ResolveContext rc) + { +- if (rc.HasAny (ResolveContext.Options.BaseInitializer | ResolveContext.Options.FieldInitializerScope)) { ++ if (rc.HasAny (ResolveContext.Options.BaseInitializer | ResolveContext.Options.FieldInitializerScope) && rc.CurrentAnonymousMethod == null) { + rc.Report.Error (8200, loc, "Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers"); + } else if (rc.HasSet (ResolveContext.Options.QueryClauseScope)) { + rc.Report.Error (8201, loc, "Out variable and pattern variable declarations are not allowed within a query clause"); +diff --git a/mcs/mcs/expression.cs b/mcs/mcs/expression.cs +index 518ccc8ef43..87db14a0ce7 100644 +--- a/mcs/mcs/expression.cs ++++ b/mcs/mcs/expression.cs +@@ -920,7 +920,7 @@ namespace Mono.CSharp + + public override bool ContainsEmitWithAwait () + { +- throw new NotImplementedException (); ++ return false; + } + + public override Expression CreateExpressionTree (ResolveContext ec) +@@ -2051,7 +2051,11 @@ namespace Mono.CSharp + + if (d.BuiltinType == BuiltinTypeSpec.Type.Dynamic) + return this; +- ++ ++ // TODO: Requires custom optimized version with variable store ++ if (Variable != null) ++ return this; ++ + // + // Turn is check into simple null check for implicitly convertible reference types + // +@@ -2757,6 +2761,12 @@ namespace Mono.CSharp + } + } + ++ public override bool IsNull { ++ get { ++ return TypeSpec.IsReferenceType (type); ++ } ++ } ++ + public override bool ContainsEmitWithAwait () + { + return false; +@@ -5669,6 +5679,12 @@ namespace Mono.CSharp + ConvCast.Emit (ec, enum_conversion); + } + ++ public override void EmitPrepare (EmitContext ec) ++ { ++ Left.EmitPrepare (ec); ++ Right.EmitPrepare (ec); ++ } ++ + public override void EmitSideEffect (EmitContext ec) + { + if ((oper & Operator.LogicalMask) != 0 || +@@ -6385,7 +6401,7 @@ namespace Mono.CSharp + } + } + +- if (conv_false_expr != null) { ++ if (conv_false_expr != null && false_type != InternalType.ErrorType && true_type != InternalType.ErrorType) { + ec.Report.Error (172, true_expr.Location, + "Type of conditional expression cannot be determined as `{0}' and `{1}' convert implicitly to each other", + true_type.GetSignatureForError (), false_type.GetSignatureForError ()); +@@ -6398,7 +6414,7 @@ namespace Mono.CSharp + } else if ((conv = Convert.ImplicitConversion (ec, false_expr, true_type, loc)) != null) { + false_expr = conv; + } else { +- if (false_type != InternalType.ErrorType) { ++ if (false_type != InternalType.ErrorType && true_type != InternalType.ErrorType) { + ec.Report.Error (173, true_expr.Location, + "Type of conditional expression cannot be determined because there is no implicit conversion between `{0}' and `{1}'", + true_type.GetSignatureForError (), false_type.GetSignatureForError ()); +@@ -6427,6 +6443,30 @@ namespace Mono.CSharp + return this; + } + ++ public override Expression DoResolveLValue (ResolveContext rc, Expression right_side) ++ { ++ expr = expr.Resolve (rc); ++ true_expr = true_expr.Resolve (rc); ++ false_expr = false_expr.Resolve (rc); ++ ++ if (true_expr == null || false_expr == null || expr == null) ++ return null; ++ ++ if (!(true_expr is ReferenceExpression && false_expr is ReferenceExpression)) { ++ rc.Report.Error (8326, expr.Location, "Both ref conditional operators must be ref values"); ++ return null; ++ } ++ ++ if (!TypeSpecComparer.IsEqual (true_expr.Type, false_expr.Type)) { ++ rc.Report.Error (8327, true_expr.Location, "The ref conditional expression types `{0}' and `{1}' have to match", ++ true_expr.Type.GetSignatureForError (), false_expr.Type.GetSignatureForError ()); ++ } ++ ++ eclass = ExprClass.Value; ++ type = true_expr.Type; ++ return this; ++ } ++ + public override void Emit (EmitContext ec) + { + Label false_target = ec.DefineLabel (); +@@ -6774,7 +6814,7 @@ namespace Mono.CSharp + "Cannot use fixed variable `{0}' inside an anonymous method, lambda expression or query expression", + GetSignatureForError ()); + } else if (local_info.IsByRef || local_info.Type.IsByRefLike) { +- if (ec.CurrentAnonymousMethod is StateMachineInitializer) { ++ if (local_info.Type.IsSpecialRuntimeType || ec.CurrentAnonymousMethod is StateMachineInitializer) { + // It's reported later as 4012/4013 + } else { + ec.Report.Error (8175, loc, +@@ -11877,12 +11917,17 @@ namespace Mono.CSharp + if (!TypeManager.VerifyUnmanaged (ec.Module, otype, loc)) + return null; + +- type = PointerContainer.MakeType (ec.Module, otype); ++ ResolveExpressionType (ec, otype); + eclass = ExprClass.Value; + + return this; + } + ++ protected virtual void ResolveExpressionType (ResolveContext rc, TypeSpec elementType) ++ { ++ type = PointerContainer.MakeType (rc.Module, elementType); ++ } ++ + public override void Emit (EmitContext ec) + { + int size = BuiltinTypeSpec.GetSize (otype); +@@ -11931,14 +11976,36 @@ namespace Mono.CSharp + public bool ResolveSpanConversion (ResolveContext rc, TypeSpec spanType) + { + ctor = MemberCache.FindMember (spanType, MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (PointerContainer.MakeType (rc.Module, rc.Module.Compiler.BuiltinTypes.Void), rc.Module.Compiler.BuiltinTypes.Int)), BindingRestriction.DeclaredOnly) as MethodSpec; +- if (ctor == null) ++ if (ctor == null) { ++ this.type = InternalType.ErrorType; + return false; ++ } + + this.type = spanType; + return true; + } + } + ++ class SpanStackAlloc : StackAlloc ++ { ++ public SpanStackAlloc (Expression type, Expression count, Location l) ++ : base (type, count, l) ++ { ++ } ++ ++ protected override void ResolveExpressionType (ResolveContext rc, TypeSpec elementType) ++ { ++ var span = rc.Module.PredefinedTypes.SpanGeneric.Resolve (); ++ if (span == null) { ++ type = InternalType.ErrorType; ++ return; ++ } ++ ++ type = span.MakeGenericType (rc, new [] { elementType }); ++ ResolveSpanConversion (rc, type); ++ } ++ } ++ + // + // An object initializer expression + // +@@ -13085,6 +13152,9 @@ namespace Mono.CSharp + if (expr is IAssignMethod) + return true; + ++ if (expr is Conditional) ++ return true; ++ + var invocation = expr as Invocation; + if (invocation?.Type.Kind == MemberKind.ByRef) + return true; +@@ -13232,6 +13302,10 @@ namespace Mono.CSharp + this.loc = loc; + } + ++ protected override void CloneTo (CloneContext clonectx, Expression t) ++ { ++ } ++ + public override Expression CreateExpressionTree (ResolveContext ec) + { + throw new NotImplementedException (); +diff --git a/mcs/mcs/field.cs b/mcs/mcs/field.cs +index 86bb028defc..8c667328143 100644 +--- a/mcs/mcs/field.cs ++++ b/mcs/mcs/field.cs +@@ -542,7 +542,7 @@ namespace Mono.CSharp + } + ); + +- fixed_buffer_type.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ()); ++ fixed_buffer_type.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray (out _)); + #endif + // + // Don't emit FixedBufferAttribute attribute for private types +@@ -559,7 +559,8 @@ namespace Mono.CSharp + encoder.Encode (buffer_size); + encoder.EncodeEmptyNamedArguments (); + +- FieldBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ()); ++ FieldBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray (out var references)); ++ Module.AddAssemblyReferences (references); + } + } + +diff --git a/mcs/mcs/generic.cs b/mcs/mcs/generic.cs +index ec2965df63b..0c7032b2088 100644 +--- a/mcs/mcs/generic.cs ++++ b/mcs/mcs/generic.cs +@@ -3381,7 +3381,7 @@ namespace Mono.CSharp { + continue; + + var bound = candidates [ci]; +- if (bound.Type == best_candidate) ++ if (TypeSpecComparer.IsEqual (bound.Type, best_candidate)) + continue; + + int cii = 0; +diff --git a/mcs/mcs/modifiers.cs b/mcs/mcs/modifiers.cs +index 926ab5d1848..21dd52b3b14 100644 +--- a/mcs/mcs/modifiers.cs ++++ b/mcs/mcs/modifiers.cs +@@ -74,6 +74,8 @@ namespace Mono.CSharp + return "internal"; + case Modifiers.PRIVATE: + return "private"; ++ case Modifiers.PRIVATE | Modifiers.PROTECTED: ++ return "private protected"; + default: + throw new NotImplementedException (mod.ToString ()); + } +@@ -129,12 +131,16 @@ namespace Mono.CSharp + if ((modB & Modifiers.PUBLIC) != 0) { + flags = Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE; + } else if ((modB & Modifiers.PROTECTED) != 0) { +- if ((modB & Modifiers.INTERNAL) != 0) +- flags = Modifiers.PROTECTED | Modifiers.INTERNAL; +- +- flags |= Modifiers.PRIVATE; +- } else if ((modB & Modifiers.INTERNAL) != 0) ++ if ((modB & Modifiers.INTERNAL) != 0) { ++ flags = Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE; ++ } else { ++ modA &= ~Modifiers.PROTECTED; ++ flags = Modifiers.PRIVATE; ++ } ++ } else if ((modB & Modifiers.INTERNAL) != 0) { ++ modA &= ~Modifiers.PROTECTED; + flags = Modifiers.PRIVATE; ++ } + + return modB != modA && (modA & (~flags)) == 0; + } +@@ -151,6 +157,8 @@ namespace Mono.CSharp + } else { + if ((mod_flags & Modifiers.PUBLIC) != 0) + t = TypeAttributes.NestedPublic; ++ else if ((mod_flags & (Modifiers.PROTECTED | Modifiers.PRIVATE)) == (Modifiers.PROTECTED | Modifiers.PRIVATE)) ++ t = TypeAttributes.NestedFamANDAssem; + else if ((mod_flags & Modifiers.PRIVATE) != 0) + t = TypeAttributes.NestedPrivate; + else if ((mod_flags & (Modifiers.PROTECTED | Modifiers.INTERNAL)) == (Modifiers.PROTECTED | Modifiers.INTERNAL)) +@@ -173,18 +181,27 @@ namespace Mono.CSharp + { + FieldAttributes fa = 0; + +- if ((mod_flags & Modifiers.PUBLIC) != 0) ++ switch (mod_flags & Modifiers.AccessibilityMask) { ++ case Modifiers.PUBLIC: + fa |= FieldAttributes.Public; +- if ((mod_flags & Modifiers.PRIVATE) != 0) ++ break; ++ case Modifiers.PRIVATE: + fa |= FieldAttributes.Private; +- if ((mod_flags & Modifiers.PROTECTED) != 0) { +- if ((mod_flags & Modifiers.INTERNAL) != 0) +- fa |= FieldAttributes.FamORAssem; +- else +- fa |= FieldAttributes.Family; +- } else { +- if ((mod_flags & Modifiers.INTERNAL) != 0) +- fa |= FieldAttributes.Assembly; ++ break; ++ case Modifiers.PROTECTED | Modifiers.INTERNAL: ++ fa |= FieldAttributes.FamORAssem; ++ break; ++ case Modifiers.PROTECTED: ++ fa |= FieldAttributes.Family; ++ break; ++ case Modifiers.INTERNAL: ++ fa |= FieldAttributes.Assembly; ++ break; ++ case Modifiers.PRIVATE | Modifiers.PROTECTED: ++ fa |= FieldAttributes.FamANDAssem; ++ break; ++ default: ++ throw new NotImplementedException (mod_flags.ToString ()); + } + + if ((mod_flags & Modifiers.STATIC) != 0) +@@ -215,6 +232,9 @@ namespace Mono.CSharp + case Modifiers.INTERNAL: + ma |= MethodAttributes.Assembly; + break; ++ case Modifiers.PRIVATE | Modifiers.PROTECTED: ++ ma |= MethodAttributes.FamANDAssem; ++ break; + default: + throw new NotImplementedException (mod_flags.ToString ()); + } +diff --git a/mcs/mcs/module.cs b/mcs/mcs/module.cs +index 2293d825b36..4680433bb01 100644 +--- a/mcs/mcs/module.cs ++++ b/mcs/mcs/module.cs +@@ -480,6 +480,18 @@ namespace Mono.CSharp + attributes.AddAttribute (attr); + } + ++ public void AddAssemblyReferences (List names) ++ { ++ if (names == null) ++ return; ++ ++#if STATIC ++ foreach (var name in names) { ++ Builder.__GetAssemblyToken (name); ++ } ++#endif ++ } ++ + public override void AddTypeContainer (TypeContainer tc) + { + AddTypeContainerMember (tc); +diff --git a/mcs/mcs/parameter.cs b/mcs/mcs/parameter.cs +index cc10eee162b..95851478010 100644 +--- a/mcs/mcs/parameter.cs ++++ b/mcs/mcs/parameter.cs +@@ -221,12 +221,13 @@ namespace Mono.CSharp { + REF = 1 << 1, + OUT = 1 << 2, + This = 1 << 3, +- CallerMemberName = 1 << 4, +- CallerLineNumber = 1 << 5, +- CallerFilePath = 1 << 6, ++ ReadOnly = 1 << 4, ++ CallerMemberName = 1 << 5, ++ CallerLineNumber = 1 << 6, ++ CallerFilePath = 1 << 7, + + RefOutMask = REF | OUT, +- ModifierMask = PARAMS | REF | OUT | This, ++ ModifierMask = PARAMS | REF | OUT | This | ReadOnly, + CallerMask = CallerMemberName | CallerLineNumber | CallerFilePath + } + +@@ -1474,9 +1475,9 @@ namespace Mono.CSharp { + } + } + +- if (!expr.IsNull && TypeSpec.IsReferenceType (parameter_type) && parameter_type.BuiltinType != BuiltinTypeSpec.Type.String) { ++ if (!res.IsNull && TypeSpec.IsReferenceType (parameter_type) && parameter_type.BuiltinType != BuiltinTypeSpec.Type.String) { + rc.Report.Error (1763, Location, +- "Optional parameter `{0}' of type `{1}' can only be initialized with `null'", ++ "Optional parameter `{0}' of type `{1}' can only be initialized with default value", + p.Name, parameter_type.GetSignatureForError ()); + + return; +diff --git a/mcs/mcs/report.cs b/mcs/mcs/report.cs +index cc3d82b26e0..5d64c8e766e 100644 +--- a/mcs/mcs/report.cs ++++ b/mcs/mcs/report.cs +@@ -42,7 +42,7 @@ namespace Mono.CSharp { + public static readonly int[] AllWarnings = new int[] { + 28, 67, 78, + 105, 108, 109, 114, 162, 164, 168, 169, 183, 184, 197, +- 219, 251, 252, 253, 278, 282, ++ 219, 251, 252, 253, 278, 280, 282, + 402, 414, 419, 420, 429, 436, 437, 440, 458, 464, 465, 467, 469, 472, 473, + 612, 618, 626, 628, 642, 649, 652, 657, 658, 659, 660, 661, 665, 672, 675, 693, + 728, +@@ -107,6 +107,15 @@ namespace Mono.CSharp { + case LanguageVersion.V_7: + version = "7.0"; + break; ++ case LanguageVersion.V_7_1: ++ version = "7.1"; ++ break; ++ case LanguageVersion.V_7_2: ++ version = "7.2"; ++ break; ++ case LanguageVersion.V_7_3: ++ version = "7.3"; ++ break; + default: + throw new InternalErrorException ("Invalid feature version", compiler.Settings.Version); + } +diff --git a/mcs/mcs/settings.cs b/mcs/mcs/settings.cs +index 37664187c71..976c9b68128 100644 +--- a/mcs/mcs/settings.cs ++++ b/mcs/mcs/settings.cs +@@ -32,10 +32,11 @@ namespace Mono.CSharp { + V_7 = 7, + V_7_1 = 71, + V_7_2 = 72, ++ V_7_3 = 73, + Experimental = 100, + + Default = V_7, +- Latest = V_7_2 ++ Latest = V_7_3 + } + + public enum RuntimeVersion +@@ -1270,6 +1271,7 @@ namespace Mono.CSharp { + case "/highentropyva+": + case "/highentropyva-": + case "/link": ++ case "/sourcelink": + case "/moduleassemblyname": + case "/nowin32manifest": + case "/pdb": +diff --git a/mcs/mcs/statement.cs b/mcs/mcs/statement.cs +index 9c51128548f..c8b77c1adc1 100644 +--- a/mcs/mcs/statement.cs ++++ b/mcs/mcs/statement.cs +@@ -928,8 +928,7 @@ namespace Mono.CSharp { + public override Reachability MarkReachable (Reachability rc) + { + base.MarkReachable (rc); +- expr.MarkReachable (rc); +- return rc; ++ return expr.MarkReachable (rc); + } + + public override bool Resolve (BlockContext ec) +@@ -2419,6 +2418,7 @@ namespace Mono.CSharp { + IsLocked = 1 << 8, + SymbolFileHidden = 1 << 9, + ByRef = 1 << 10, ++ PointerByRef = 1 << 11, + + ReadonlyMask = 1 << 20 + } +@@ -2609,20 +2609,22 @@ namespace Mono.CSharp { + + if (IsByRef) { + builder = ec.DeclareLocal (ReferenceContainer.MakeType (ec.Module, Type), IsFixed); ++ } else if ((flags & Flags.PointerByRef) != 0) { ++ builder = ec.DeclareLocal (ReferenceContainer.MakeType (ec.Module, ((PointerContainer) Type).Element), IsFixed); + } else { + // + // All fixed variabled are pinned, a slot has to be alocated + // +- builder = ec.DeclareLocal(Type, IsFixed); ++ builder = ec.DeclareLocal (Type, IsFixed); + } + + if ((flags & Flags.SymbolFileHidden) == 0) + ec.DefineLocalVariable (name, builder); + } + +- public static LocalVariable CreateCompilerGenerated (TypeSpec type, Block block, Location loc, bool writeToSymbolFile = false) ++ public static LocalVariable CreateCompilerGenerated (TypeSpec type, Block block, Location loc, bool writeToSymbolFile = false, Flags additionalFlags = 0) + { +- LocalVariable li = new LocalVariable (block, GetCompilerGeneratedName (block), Flags.CompilerGenerated | Flags.Used, loc); ++ LocalVariable li = new LocalVariable (block, GetCompilerGeneratedName (block), Flags.CompilerGenerated | Flags.Used | additionalFlags, loc); + if (!writeToSymbolFile) + li.flags |= Flags.SymbolFileHidden; + +@@ -2725,6 +2727,11 @@ namespace Mono.CSharp { + flags |= Flags.Used; + } + ++ public void SetIsPointerByRef () ++ { ++ flags |= Flags.PointerByRef; ++ } ++ + public void SetHasAddressTaken () + { + flags |= (Flags.AddressTaken | Flags.Used); +@@ -6562,18 +6569,26 @@ namespace Mono.CSharp { + + // TODO: Should use Binary::Add + pinned_string.Emit (ec); +- ec.Emit (OpCodes.Conv_I); ++ ec.Emit (OpCodes.Conv_U); + + var m = ec.Module.PredefinedMembers.RuntimeHelpersOffsetToStringData.Resolve (loc); + if (m == null) + return; + ++ var null_value = ec.DefineLabel (); ++ vi.EmitAssign (ec); ++ vi.Emit (ec); ++ ec.Emit (OpCodes.Brfalse_S, null_value); ++ ++ vi.Emit (ec); + PropertyExpr pe = new PropertyExpr (m, pinned_string.Location); + //pe.InstanceExpression = pinned_string; + pe.Resolve (new ResolveContext (ec.MemberContext)).Emit (ec); + + ec.Emit (OpCodes.Add); + vi.EmitAssign (ec); ++ ++ ec.MarkLabel (null_value); + } + + public override void EmitExit (EmitContext ec) +@@ -6660,31 +6675,94 @@ namespace Mono.CSharp { + return new ExpressionEmitter (res, li); + } + +- bool already_fixed = true; +- + // + // Case 4: & object. + // + Unary u = res as Unary; + if (u != null) { ++ bool already_fixed = true; ++ + if (u.Oper == Unary.Operator.AddressOf) { + IVariableReference vr = u.Expr as IVariableReference; + if (vr == null || !vr.IsFixed) { + already_fixed = false; + } + } +- } else if (initializer is Cast) { ++ ++ if (already_fixed) { ++ bc.Report.Error (213, loc, "You cannot use the fixed statement to take the address of an already fixed expression"); ++ return null; ++ } ++ ++ res = Convert.ImplicitConversionRequired (bc, res, li.Type, loc); ++ return new ExpressionEmitter (res, li); ++ } ++ ++ if (initializer is Cast) { + bc.Report.Error (254, initializer.Location, "The right hand side of a fixed statement assignment may not be a cast expression"); + return null; + } + +- if (already_fixed) { +- bc.Report.Error (213, loc, "You cannot use the fixed statement to take the address of an already fixed expression"); ++ // ++ // Case 5: by-ref GetPinnableReference method on the rhs expression ++ // ++ var method = GetPinnableReference (bc, res); ++ if (method == null) { ++ bc.Report.Error (8385, initializer.Location, "The given expression cannot be used in a fixed statement"); ++ return null; ++ } ++ ++ var compiler = bc.Module.Compiler; ++ if (compiler.Settings.Version < LanguageVersion.V_7_3) { ++ bc.Report.FeatureIsNotAvailable (compiler, initializer.Location, "extensible fixed statement"); ++ } ++ ++ method.InstanceExpression = res; ++ res = new Invocation.Predefined (method, null).ResolveLValue (bc, EmptyExpression.OutAccess); ++ if (res == null) ++ return null; ++ ++ ReferenceContainer rType = (ReferenceContainer)method.BestCandidateReturnType; ++ PointerContainer lType = li.Type as PointerContainer; ++ if (rType.Element != lType?.Element) { ++ // CSC: Should be better error code ++ res.Error_ValueCannotBeConverted (bc, lType, false); ++ return null; + } + +- res = Convert.ImplicitConversionRequired (bc, res, li.Type, loc); ++ li.SetIsPointerByRef (); + return new ExpressionEmitter (res, li); + } ++ ++ MethodGroupExpr GetPinnableReference (BlockContext bc, Expression expr) ++ { ++ TypeSpec type = expr.Type; ++ var mexpr = Expression.MemberLookup (bc, false, type, ++ "GetPinnableReference", 0, Expression.MemberLookupRestrictions.ExactArity, loc); ++ ++ if (mexpr == null) ++ return null; ++ ++ var mg = mexpr as MethodGroupExpr; ++ if (mg == null) ++ return null; ++ ++ mg.InstanceExpression = expr; ++ ++ // TODO: handle extension methods ++ Arguments args = new Arguments (0); ++ mg = mg.OverloadResolve (bc, ref args, null, OverloadResolver.Restrictions.None); ++ ++ if (mg == null || mg.BestCandidate.IsStatic || !mg.BestCandidate.IsPublic || mg.BestCandidateReturnType.Kind != MemberKind.ByRef || !mg.BestCandidate.Parameters.IsEmpty) { ++ if (bc.Module.Compiler.Settings.Version > LanguageVersion.V_7_2) { ++ bc.Report.Warning (280, 2, expr.Location, "`{0}' has the wrong signature to be used in extensible fixed statement", mg.GetSignatureForError ()); ++ } ++ ++ return null; ++ } ++ ++ return mg; ++ } + } + + +diff --git a/mcs/mcs/tuples.cs b/mcs/mcs/tuples.cs +index 901efdc9541..0b56859615f 100644 +--- a/mcs/mcs/tuples.cs ++++ b/mcs/mcs/tuples.cs +@@ -267,6 +267,11 @@ namespace Mono.CSharp + this.Location = expr.Location; + } + ++ public TupleLiteralElement Clone (CloneContext clonectx) ++ { ++ return new TupleLiteralElement (Name, Expr.Clone (clonectx), Location); ++ } ++ + public string Name { get; private set; } + public Expression Expr { get; set; } + public Location Location { get; private set; } +@@ -288,6 +293,16 @@ namespace Mono.CSharp + } + } + ++ protected override void CloneTo (CloneContext clonectx, Expression t) ++ { ++ var clone = new List (elements.Count); ++ foreach (var te in elements) ++ clone.Add (te.Clone (clonectx)); ++ ++ TupleLiteral target = (TupleLiteral)t; ++ target.elements = clone; ++ } ++ + public static bool ContainsNoTypeElement (TypeSpec type) + { + var ta = type.TypeArguments; +@@ -432,6 +447,7 @@ namespace Mono.CSharp + { + Expression source; + List targetExprs; ++ List tempExprs; + List variables; + Expression instance; + +@@ -440,6 +456,8 @@ namespace Mono.CSharp + this.source = source; + this.targetExprs = targetExprs; + this.loc = loc; ++ ++ tempExprs = new List (); + } + + public TupleDeconstruct (List variables, Expression source, Location loc) +@@ -447,6 +465,8 @@ namespace Mono.CSharp + this.source = source; + this.variables = variables; + this.loc = loc; ++ ++ tempExprs = new List (); + } + + public override Expression CreateExpressionTree (ResolveContext ec) +@@ -492,6 +512,15 @@ namespace Mono.CSharp + instance = expr_variable.CreateReferenceExpression (rc, loc); + } + ++ var element_srcs = new List (); ++ var src_names = new List (); ++ for (int i = 0; i < target_count; ++i) { ++ var element_src = tupleLiteral == null ? new MemberAccess (instance, NamedTupleSpec.GetElementPropertyName (i)) : tupleLiteral.Elements [i].Expr; ++ element_srcs.Add (element_src); ++ if (element_src is VariableReference) ++ src_names.Add ((element_src as VariableReference)?.Name); ++ } ++ + for (int i = 0; i < target_count; ++i) { + var tle = src_type.TypeArguments [i]; + +@@ -522,8 +551,17 @@ namespace Mono.CSharp + variable.PrepareAssignmentAnalysis ((BlockContext)rc); + } + +- var element_src = tupleLiteral == null ? new MemberAccess (instance, NamedTupleSpec.GetElementPropertyName (i)) : tupleLiteral.Elements [i].Expr; +- targetExprs [i] = new SimpleAssign (targetExprs [i], element_src).Resolve (rc); ++ var element_target = (targetExprs [i] as SimpleName)?.LookupNameExpression (rc, MemberLookupRestrictions.None); ++ ++ if (element_target != null && src_names.Contains ((element_target as VariableReference)?.Name)) { ++ var tempType = element_target.Resolve (rc).Type; ++ ++ var temp = new LocalTemporary (tempType); ++ tempExprs.Add (new SimpleAssign (temp, element_srcs [i]).Resolve (rc)); ++ targetExprs [i] = new SimpleAssign (targetExprs [i], temp).Resolve (rc); ++ } else { ++ targetExprs [i] = new SimpleAssign (targetExprs [i], element_srcs [i]).Resolve (rc); ++ } + } + + eclass = ExprClass.Value; +@@ -557,9 +595,24 @@ namespace Mono.CSharp + if (instance != null) + ((ExpressionStatement)source).EmitStatement (ec); + +- foreach (ExpressionStatement expr in targetExprs) ++ foreach (ExpressionStatement expr in tempExprs) { ++ var temp = (expr as Assign)?.Target as LocalTemporary; ++ if (temp == null) ++ continue; ++ ++ temp.AddressOf (ec, AddressOp.LoadStore); ++ ec.Emit (OpCodes.Initobj, temp.Type); ++ expr.Emit (ec); ++ } ++ ++ foreach (ExpressionStatement expr in targetExprs) { + expr.Emit (ec); + ++ var temp = (expr as Assign)?.Source as LocalTemporary; ++ if (temp != null) ++ temp.Release (ec); ++ } ++ + var ctor = MemberCache.FindMember (type, MemberFilter.Constructor (null), BindingRestriction.DeclaredOnly | BindingRestriction.InstanceOnly) as MethodSpec; + ec.Emit (OpCodes.Newobj, ctor); + } +@@ -574,9 +627,24 @@ namespace Mono.CSharp + + if (instance != null) + ((ExpressionStatement) source).EmitStatement (ec); +- +- foreach (ExpressionStatement expr in targetExprs) ++ ++ foreach (ExpressionStatement expr in tempExprs) { ++ var temp = (expr as Assign)?.Target as LocalTemporary; ++ if (temp == null) ++ continue; ++ ++ temp.AddressOf (ec, AddressOp.LoadStore); ++ ec.Emit (OpCodes.Initobj, temp.Type); ++ expr.EmitStatement (ec); ++ } ++ ++ foreach (ExpressionStatement expr in targetExprs) { + expr.EmitStatement (ec); ++ ++ var temp = (expr as Assign)?.Source as LocalTemporary; ++ if (temp != null) ++ temp.Release (ec); ++ } + } + + public void Emit (EmitContext ec, bool leave_copy) +@@ -594,6 +662,7 @@ namespace Mono.CSharp + + public override void FlowAnalysis (FlowAnalysisContext fc) + { ++ source.FlowAnalysis (fc); + foreach (var expr in targetExprs) + expr.FlowAnalysis (fc); + } +diff --git a/mcs/nunit24/ClientUtilities/util/AssemblyInfo.cs b/mcs/nunit24/ClientUtilities/util/AssemblyInfo.cs +index 919ca07ace3..6489c1b2a58 100644 +--- a/mcs/nunit24/ClientUtilities/util/AssemblyInfo.cs ++++ b/mcs/nunit24/ClientUtilities/util/AssemblyInfo.cs +@@ -5,7 +5,3 @@ + // **************************************************************** + + using System.Reflection; +- +-[assembly: AssemblyDelaySign(false)] +-[assembly: AssemblyKeyFile("../../nunit.snk")] +-[assembly: AssemblyKeyName("")] +diff --git a/mcs/nunit24/ConsoleRunner/nunit-console/AssemblyInfo.cs b/mcs/nunit24/ConsoleRunner/nunit-console/AssemblyInfo.cs +index 919ca07ace3..6489c1b2a58 100644 +--- a/mcs/nunit24/ConsoleRunner/nunit-console/AssemblyInfo.cs ++++ b/mcs/nunit24/ConsoleRunner/nunit-console/AssemblyInfo.cs +@@ -5,7 +5,3 @@ + // **************************************************************** + + using System.Reflection; +- +-[assembly: AssemblyDelaySign(false)] +-[assembly: AssemblyKeyFile("../../nunit.snk")] +-[assembly: AssemblyKeyName("")] +diff --git a/mcs/nunit24/NUnitCore/core/AssemblyInfo.cs b/mcs/nunit24/NUnitCore/core/AssemblyInfo.cs +index 747032c7e63..2f66d80222c 100644 +--- a/mcs/nunit24/NUnitCore/core/AssemblyInfo.cs ++++ b/mcs/nunit24/NUnitCore/core/AssemblyInfo.cs +@@ -7,7 +7,3 @@ using System; + using System.Reflection; + + [assembly: CLSCompliant(true)] +- +-[assembly: AssemblyDelaySign(false)] +-[assembly: AssemblyKeyFile("../../nunit.snk")] +-[assembly: AssemblyKeyName("")] +diff --git a/mcs/nunit24/NUnitCore/interfaces/AssemblyInfo.cs b/mcs/nunit24/NUnitCore/interfaces/AssemblyInfo.cs +index fa86732b3d3..efeaecf1986 100644 +--- a/mcs/nunit24/NUnitCore/interfaces/AssemblyInfo.cs ++++ b/mcs/nunit24/NUnitCore/interfaces/AssemblyInfo.cs +@@ -8,7 +8,3 @@ using System; + using System.Reflection; + + [assembly: CLSCompliant(true)] +- +-[assembly: AssemblyDelaySign(false)] +-[assembly: AssemblyKeyFile("../../nunit.snk")] +-[assembly: AssemblyKeyName("")] +diff --git a/mcs/nunit24/NUnitExtensions/core/AssemblyInfo.cs b/mcs/nunit24/NUnitExtensions/core/AssemblyInfo.cs +index fa86732b3d3..efeaecf1986 100644 +--- a/mcs/nunit24/NUnitExtensions/core/AssemblyInfo.cs ++++ b/mcs/nunit24/NUnitExtensions/core/AssemblyInfo.cs +@@ -8,7 +8,3 @@ using System; + using System.Reflection; + + [assembly: CLSCompliant(true)] +- +-[assembly: AssemblyDelaySign(false)] +-[assembly: AssemblyKeyFile("../../nunit.snk")] +-[assembly: AssemblyKeyName("")] +diff --git a/mcs/nunit24/NUnitExtensions/framework/AssemblyInfo.cs b/mcs/nunit24/NUnitExtensions/framework/AssemblyInfo.cs +index a9553f691cd..2b4b5bfb340 100644 +--- a/mcs/nunit24/NUnitExtensions/framework/AssemblyInfo.cs ++++ b/mcs/nunit24/NUnitExtensions/framework/AssemblyInfo.cs +@@ -8,7 +8,3 @@ using System; + using System.Reflection; + + [assembly: CLSCompliant(true)] +- +-[assembly: AssemblyDelaySign(false)] +-[assembly: AssemblyKeyFile("../../nunit.snk")] +-[assembly: AssemblyKeyName("")] +diff --git a/mcs/nunit24/NUnitFramework/framework/AssemblyInfo.cs b/mcs/nunit24/NUnitFramework/framework/AssemblyInfo.cs +index fa86732b3d3..efeaecf1986 100644 +--- a/mcs/nunit24/NUnitFramework/framework/AssemblyInfo.cs ++++ b/mcs/nunit24/NUnitFramework/framework/AssemblyInfo.cs +@@ -8,7 +8,3 @@ using System; + using System.Reflection; + + [assembly: CLSCompliant(true)] +- +-[assembly: AssemblyDelaySign(false)] +-[assembly: AssemblyKeyFile("../../nunit.snk")] +-[assembly: AssemblyKeyName("")] +diff --git a/mcs/nunit24/NUnitMocks/mocks/AssemblyInfo.cs b/mcs/nunit24/NUnitMocks/mocks/AssemblyInfo.cs +index 599b04ce453..f87ae602810 100644 +--- a/mcs/nunit24/NUnitMocks/mocks/AssemblyInfo.cs ++++ b/mcs/nunit24/NUnitMocks/mocks/AssemblyInfo.cs +@@ -6,7 +6,3 @@ + + using System; + using System.Reflection; +- +-[assembly: AssemblyDelaySign(false)] +-[assembly: AssemblyKeyFile("../../nunit.snk")] +-[assembly: AssemblyKeyName("")] +diff --git a/mcs/tests/dtest-066.cs b/mcs/tests/dtest-066.cs +new file mode 100644 +index 00000000000..893fb40dffa +--- /dev/null ++++ b/mcs/tests/dtest-066.cs +@@ -0,0 +1,13 @@ ++class C ++{ ++ static void Main() ++ { ++ object o = 1; ++ dynamic d = 1; ++ ++ var a = new[] { ++ new { X = o }, ++ new { X = d } ++ }; ++ } ++} +diff --git a/mcs/tests/gtest-647.cs b/mcs/tests/gtest-647.cs +new file mode 100644 +index 00000000000..4aae641f85f +--- /dev/null ++++ b/mcs/tests/gtest-647.cs +@@ -0,0 +1,34 @@ ++using System; ++ ++public class Program ++{ ++ public static int Main () ++ { ++ int B = default (MyStruct?); ++ if (MyStruct.counter != 1) ++ return 1; ++ ++ switch (default (MyStruct?)) { ++ case 0: ++ break; ++ default: ++ return 2; ++ } ++ ++ if (MyStruct.counter != 2) ++ return 4; ++ ++ return 0; ++ } ++ ++ public struct MyStruct ++ { ++ public static int counter; ++ ++ public static implicit operator int (MyStruct? s) ++ { ++ ++counter; ++ return 0; ++ } ++ } ++} +\ No newline at end of file +diff --git a/mcs/tests/test-928.cs b/mcs/tests/test-928.cs +index 90180137957..290ee4d1fb3 100644 +--- a/mcs/tests/test-928.cs ++++ b/mcs/tests/test-928.cs +@@ -15,6 +15,24 @@ unsafe class Program + } + } + ++ public static bool StringNull (string s) ++ { ++ unsafe { ++ fixed (char *a = s) { ++ return a == null; ++ } ++ } ++ } ++ ++ public static bool ArrayNull (int[] a) ++ { ++ unsafe { ++ fixed (int *e = a) { ++ return e == null; ++ } ++ } ++ } ++ + public static int Main () + { + Test (); +@@ -24,6 +42,12 @@ unsafe class Program + if (lv.IsPinned) + return 1; + ++ if (!StringNull (null)) ++ return 1; ++ ++ if (!ArrayNull (null)) ++ return 2; ++ + return 0; + } + } +diff --git a/mcs/tests/test-948.cs b/mcs/tests/test-948.cs +index 34b3ab9a0c4..563e37dc7d5 100644 +--- a/mcs/tests/test-948.cs ++++ b/mcs/tests/test-948.cs +@@ -1,4 +1,4 @@ +-// Compiler options: -langversion:7.2 -unsafe ++// Compiler options: -langversion:7.2 /unsafe + + using System; + +@@ -7,10 +7,16 @@ class X + public static void Main () + { + Span stackSpan = stackalloc int[100]; ++ ++ bool b = false; ++ ++ var r1 = !b ? stackalloc char[1] : throw null; ++ var r2 = b ? throw null : stackalloc char[1]; ++ var r3 = b ? stackalloc char[1] : stackalloc char[2]; + } + ++ // Disables verifier + unsafe void Foo () + { +- + } +-} +\ No newline at end of file ++} +diff --git a/mcs/tests/test-950.cs b/mcs/tests/test-950.cs +new file mode 100644 +index 00000000000..fef764c85cc +--- /dev/null ++++ b/mcs/tests/test-950.cs +@@ -0,0 +1,12 @@ ++using System; ++ ++public class B ++{ ++ public static void Main () ++ { ++ int a = 1_0_3; ++ double b = 0__0e+1_1; ++ int c = 0b0__1_0; ++ int d = 0x0__F_0; ++ } ++} +\ No newline at end of file +diff --git a/mcs/tests/test-960.cs b/mcs/tests/test-960.cs +new file mode 100644 +index 00000000000..ac2a1ca7435 +--- /dev/null ++++ b/mcs/tests/test-960.cs +@@ -0,0 +1,20 @@ ++// Compiler options: -langversion:7.2 ++ ++public class B ++{ ++ private protected enum E ++ { ++ } ++ ++ public int Index { get; protected private set; } ++ ++ internal string S1 { get; private protected set; } ++ ++ protected string S2 { get; private protected set; } ++ ++ private protected int field; ++ ++ public static void Main () ++ { ++ } ++} +\ No newline at end of file +diff --git a/mcs/tests/test-961.cs b/mcs/tests/test-961.cs +new file mode 100644 +index 00000000000..efe19673875 +--- /dev/null ++++ b/mcs/tests/test-961.cs +@@ -0,0 +1,34 @@ ++// Compiler options: -langversion:latest ++ ++using System; ++ ++public static class B { ++ public static void Main () ++ { ++ int lo = 1; ++ Bar (in lo); ++ } ++ ++ public static void Bar (in int arg) ++ { ++ } ++ ++ static void Foo (this in int src) ++ { ++ D p = (in int a) => {}; ++ } ++ ++} ++ ++delegate void D (in int arg); ++ ++class M ++{ ++ int this[in int a] { set { } } ++ public static implicit operator string (in M m) => null; ++ public M (in int arg) { } ++ ++ public void Test2 (in int arg) ++ { ++ } ++} +\ No newline at end of file +diff --git a/mcs/tests/test-anon-123.cs b/mcs/tests/test-anon-123.cs +index 91c72b45afe..45aab27c0a5 100644 +--- a/mcs/tests/test-anon-123.cs ++++ b/mcs/tests/test-anon-123.cs +@@ -1,3 +1,4 @@ ++// Compiler options: -langversion:latest + // Cloning tests + + using System; +@@ -103,7 +104,11 @@ public class C : B + default: + break; + } +- }); ++ }); ++ ++ Test (() => { ++ char ch = default; ++ }); + + var c = new C (); + c.InstanceTests (); +diff --git a/mcs/tests/test-binaryliteral.cs b/mcs/tests/test-binaryliteral.cs +new file mode 100644 +index 00000000000..3d9cc89bcbd +--- /dev/null ++++ b/mcs/tests/test-binaryliteral.cs +@@ -0,0 +1,57 @@ ++ ++class Demo { ++ static int Main () ++ { ++ if (0b1 != 1) ++ return 1; ++ var hex1 = 0x123ul; ++ var bin1 = 0b100100011ul; ++ var bin11 = 0b100100011lu; ++ if (hex1 != bin1) ++ return 2; ++ if (hex1 != bin11) ++ return 3; ++ if (hex1.GetType () != bin1.GetType ()) ++ return 4; ++ if (hex1.GetType () != bin11.GetType ()) ++ return 5; ++ ++ var hex2 = 0x7FFFFFFF; ++ var bin2 = 0b1111111111111111111111111111111; ++ ++ if (hex2 != bin2) ++ return 6; ++ if (hex2.GetType () != bin2.GetType ()) ++ return 7; ++ ++ var hex3 = 0xFFFFFFFF; ++ var bin3 = 0b11111111111111111111111111111111; ++ if (hex3 != bin3) ++ return 8; ++ if (hex3.GetType () != bin3.GetType ()) ++ return 9; ++ ++ var hex4 = 0xFFFFFFFFu; ++ var bin4 = 0b11111111111111111111111111111111u; ++ if (hex4 != bin4) ++ return 10; ++ if (hex4.GetType () != bin4.GetType ()) ++ return 11; ++ ++ var hex5 = 0x7FFFFFFFFFFFFFFF; ++ var bin5 = 0b111111111111111111111111111111111111111111111111111111111111111; ++ if (hex5 != bin5) ++ return 12; ++ if (hex5.GetType () != bin5.GetType ()) ++ return 13; ++ ++ var hex6 = 0xFFFFFFFFFFFFFFFF; ++ var bin6 = 0b1111111111111111111111111111111111111111111111111111111111111111; ++ if (hex6 != bin6) ++ return 14; ++ if (hex6.GetType () != bin6.GetType ()) ++ return 15; ++ ++ return 0; ++ } ++} +\ No newline at end of file +diff --git a/mcs/tests/test-decl-expr-05.cs b/mcs/tests/test-decl-expr-05.cs +index 730fd4278ca..907cde0b8d7 100644 +--- a/mcs/tests/test-decl-expr-05.cs ++++ b/mcs/tests/test-decl-expr-05.cs +@@ -6,6 +6,11 @@ class X + { + arg = s.ToString (); + } ++ ++ while (true && Call (out string s2)) ++ { ++ arg = s2.ToString (); ++ } + } + + static bool Call (out string s) +diff --git a/mcs/tests/test-decl-expr-06.cs b/mcs/tests/test-decl-expr-06.cs +new file mode 100644 +index 00000000000..9734f2ec2a7 +--- /dev/null ++++ b/mcs/tests/test-decl-expr-06.cs +@@ -0,0 +1,17 @@ ++using System; ++ ++public class C ++{ ++ Func f = () => Foo (out int arg); ++ ++ static bool Foo (out int arg) ++ { ++ arg = 2; ++ return false; ++ } ++ ++ public static void Main () ++ { ++ new C (); ++ } ++} +\ No newline at end of file +diff --git a/mcs/tests/test-default-01.cs b/mcs/tests/test-default-01.cs +index 823e33c451b..28aff830cd9 100644 +--- a/mcs/tests/test-default-01.cs ++++ b/mcs/tests/test-default-01.cs +@@ -41,7 +41,11 @@ static class X + static System.Func M4 () + { + return () => default; +- } ++ } ++ ++ static void Foo (II a = default (II), II b = default, II c = (II) null) ++ { ++ } + } + /* + enum E +@@ -49,4 +53,10 @@ enum E + A = default, + B = default + 1 + } +-*/ +\ No newline at end of file ++*/ ++ ++ ++interface II ++{ ++ ++} +\ No newline at end of file +diff --git a/mcs/tests/test-fixed-01.cs b/mcs/tests/test-fixed-01.cs +new file mode 100644 +index 00000000000..4684b0c5a06 +--- /dev/null ++++ b/mcs/tests/test-fixed-01.cs +@@ -0,0 +1,20 @@ ++// Compiler options: -unsafe -langversion:latest ++ ++unsafe class C ++{ ++ public static void Main () ++ { ++ fixed (int* p = new Fixable ()) { ++ System.Console.WriteLine (*p); ++ System.Console.WriteLine (p [2]); ++ } ++ } ++ ++ struct Fixable ++ { ++ public ref int GetPinnableReference () ++ { ++ return ref (new int[] { 1, 2, 3 })[0]; ++ } ++ } ++} +\ No newline at end of file +diff --git a/mcs/tests/test-pattern-13.cs b/mcs/tests/test-pattern-13.cs +new file mode 100644 +index 00000000000..315c7a9e4be +--- /dev/null ++++ b/mcs/tests/test-pattern-13.cs +@@ -0,0 +1,19 @@ ++using System; ++ ++class C : B ++{ ++ ++} ++ ++public class B ++{ ++ public static void Main () ++ { ++ C c = new C (); ++ ++ if (c is B b) ++ { ++ Console.WriteLine (b == null); ++ } ++ } ++} +\ No newline at end of file +diff --git a/mcs/tests/test-ref-07.cs b/mcs/tests/test-ref-07.cs +index 4aa16579752..f17cfb443b5 100644 +--- a/mcs/tests/test-ref-07.cs ++++ b/mcs/tests/test-ref-07.cs +@@ -1,6 +1,6 @@ + // Compiler options: -langversion:latest + +-public readonly partial ref struct Test ++public readonly ref partial struct Test + { + public static void Main () + { +@@ -14,6 +14,11 @@ public readonly partial ref struct Test + } + } + ++ref partial struct Test ++{ ++ ++} ++ + ref struct Second + { + Test field; +diff --git a/mcs/tests/test-ref-11.cs b/mcs/tests/test-ref-11.cs +new file mode 100644 +index 00000000000..8d392a77d07 +--- /dev/null ++++ b/mcs/tests/test-ref-11.cs +@@ -0,0 +1,13 @@ ++class Program ++{ ++ static int x; ++ static int y; ++ ++ public static int Main () ++ { ++ bool b = false; ++ ref int targetBucket = ref b ? ref x : ref y; ++ ++ return 0; ++ } ++} +\ No newline at end of file +diff --git a/mcs/tests/test-ref-12.cs b/mcs/tests/test-ref-12.cs +new file mode 100644 +index 00000000000..786a4162f4f +--- /dev/null ++++ b/mcs/tests/test-ref-12.cs +@@ -0,0 +1,22 @@ ++// Compiler options: -unsafe ++ ++unsafe class X ++{ ++ public static void Main () ++ { ++ void* pointer = null; ++ Bar (ref Foo (ref *(byte*)pointer)); ++ } ++ ++ static int field; ++ ++ static ref int Foo (ref byte b) ++ { ++ return ref field; ++ } ++ ++ static void Bar (ref int i) ++ { ++ ++ } ++} +\ No newline at end of file +diff --git a/mcs/tests/test-tuple-02.cs b/mcs/tests/test-tuple-02.cs +index c0492759452..ab722642aeb 100644 +--- a/mcs/tests/test-tuple-02.cs ++++ b/mcs/tests/test-tuple-02.cs +@@ -26,6 +26,11 @@ class TupleConversions + (string v1, object v2) b = ("a", "b"); + + (int v1, long v2)? x = null; ++ ++ var array = new [] { ++ (name: "A", offset: 0), ++ (name: "B", size: 4) ++ }; + } + + static void Foo (T arg) +diff --git a/mcs/tests/test-tuple-08.cs b/mcs/tests/test-tuple-08.cs +new file mode 100644 +index 00000000000..fd3375b4df6 +--- /dev/null ++++ b/mcs/tests/test-tuple-08.cs +@@ -0,0 +1,24 @@ ++using System; ++using System.Collections.Generic; ++using System.Threading.Tasks; ++ ++class X ++{ ++ public static void Main () ++ { ++ var x = new X (); ++ x.Test ().Wait (); ++ } ++ ++ int a, b; ++ ++ async Task Test () ++ { ++ (a, b) = await Waiting (); ++ } ++ ++ Task<(int, int)> Waiting () ++ { ++ return Task.FromResult ((1, 3)); ++ } ++} +\ No newline at end of file +diff --git a/mcs/tests/test-tuple-10.cs b/mcs/tests/test-tuple-10.cs +new file mode 100644 +index 00000000000..82f4e01ec1f +--- /dev/null ++++ b/mcs/tests/test-tuple-10.cs +@@ -0,0 +1,9 @@ ++using System.Linq; ++ ++class Program { ++ public static int Main () ++ { ++ var l = (from f in (typeof (Program)).GetFields() select (name: f.Name, offset: 0)).ToList(); ++ return 0; ++ } ++} +\ No newline at end of file +diff --git a/mcs/tests/test-tuple-11.cs b/mcs/tests/test-tuple-11.cs +new file mode 100644 +index 00000000000..b2aeb24026c +--- /dev/null ++++ b/mcs/tests/test-tuple-11.cs +@@ -0,0 +1,20 @@ ++using System; ++ ++class Program ++{ ++ public static int Main () ++ { ++ int x = 1; ++ int y = 2; ++ ++ (x, y) = (y, x); ++ ++ if (x != 2) ++ return 1; ++ ++ if (y != 1) ++ return 2; ++ ++ return 0; ++ } ++} +diff --git a/mcs/tests/ver-il-net_4_x.xml b/mcs/tests/ver-il-net_4_x.xml +index 4dbc7042a8a..2bde8270338 100644 +--- a/mcs/tests/ver-il-net_4_x.xml ++++ b/mcs/tests/ver-il-net_4_x.xml +@@ -3168,6 +3168,33 @@ + + + ++ ++ ++ ++ 41 ++ ++ ++ 7 ++ ++ ++ ++ ++ 7 ++ ++ ++ 39 ++ ++ ++ 63 ++ ++ ++ 67 ++ ++ ++ 14 ++ ++ ++ + + + +@@ -11064,7 +11091,7 @@ + + + +- 72 ++ 60 + + + 62 +@@ -19508,7 +19535,7 @@ + + + +- 267 ++ 255 + + + 7 +@@ -19742,7 +19769,7 @@ + + + +- 116 ++ 121 + + + 7 +@@ -20147,6 +20174,21 @@ + + + ++ ++ ++ ++ 99 ++ ++ ++ 7 ++ ++ ++ ++ ++ 22 ++ ++ ++ + + + +@@ -47609,7 +47651,7 @@ + 7 + + +- 73 ++ 78 + + + +@@ -51468,10 +51510,10 @@ + + + +- 20 ++ 12 + + +- 70 ++ 62 + + + 7 +@@ -52148,7 +52190,7 @@ + 14 + + +- 29 ++ 34 + + + 10 +@@ -52359,10 +52401,10 @@ + + + +- 25 ++ 30 + + +- 105 ++ 141 + + + 29 +@@ -52370,6 +52412,12 @@ + + 7 + ++ ++ 32 ++ ++ ++ 45 ++ + + + +@@ -52814,7 +52862,7 @@ + + + +- 16 ++ 103 + + + 2 +@@ -52834,6 +52882,16 @@ + + + ++ ++ ++ ++ 23 ++ ++ ++ 7 ++ ++ ++ + + + +@@ -52858,6 +52916,80 @@ + + + ++ ++ ++ ++ 14 ++ ++ ++ 8 ++ ++ ++ 14 ++ ++ ++ 8 ++ ++ ++ 14 ++ ++ ++ 8 ++ ++ ++ 2 ++ ++ ++ 7 ++ ++ ++ ++ ++ ++ ++ 10 ++ ++ ++ 32 ++ ++ ++ 2 ++ ++ ++ ++ ++ 0 ++ ++ ++ 0 ++ ++ ++ 0 ++ ++ ++ 0 ++ ++ ++ ++ ++ 2 ++ ++ ++ 9 ++ ++ ++ 2 ++ ++ ++ 8 ++ ++ ++ ++ ++ 2 ++ ++ ++ + + + +@@ -54448,7 +54580,7 @@ + 19 + + +- 247 ++ 281 + + + 7 +@@ -54518,6 +54650,9 @@ + + 35 + ++ ++ 4 ++ + + + +@@ -67020,6 +67155,16 @@ + + + ++ ++ ++ ++ 503 ++ ++ ++ 7 ++ ++ ++ + + + +@@ -68641,7 +68786,7 @@ + + + +- 29 ++ 62 + + + 17 +@@ -68654,6 +68799,22 @@ + + + ++ ++ ++ ++ 13 ++ ++ ++ 8 ++ ++ ++ 15 ++ ++ ++ 42 ++ ++ ++ + + + +@@ -68674,6 +68835,9 @@ + + 9 + ++ ++ 2 ++ + + + +@@ -69158,6 +69322,21 @@ + + + ++ ++ ++ ++ 39 ++ ++ ++ 7 ++ ++ ++ ++ ++ 32 ++ ++ ++ + + + +@@ -72564,7 +72743,7 @@ + + + +- 184 ++ 206 + + + 14 +@@ -72750,6 +72929,21 @@ + + + ++ ++ ++ ++ 7 ++ ++ ++ ++ ++ 35 ++ ++ ++ 7 ++ ++ ++ + + + +@@ -73155,6 +73349,11 @@ + + + ++ ++ ++ 6 ++ ++ + + + 18 +@@ -73243,6 +73442,32 @@ + + + ++ ++ ++ ++ 34 ++ ++ ++ 7 ++ ++ ++ ++ ++ ++ ++ 16 ++ ++ ++ 14 ++ ++ ++ 2 ++ ++ ++ 7 ++ ++ ++ + + + +@@ -73482,7 +73707,7 @@ + 32 + + +- 10 ++ 2 + + + 10 +@@ -73491,16 +73716,16 @@ + 23 + + +- 3 ++ 2 + + +- 10 ++ 2 + + +- 3 ++ 2 + + +- 3 ++ 2 + + + 21 +@@ -73527,7 +73752,7 @@ + 7 + + +- 10 ++ 2 + + + 15 +@@ -73569,7 +73794,7 @@ + + + +- 314 ++ 368 + + + 2 +@@ -73761,6 +73986,29 @@ + + + ++ ++ ++ ++ 65 ++ ++ ++ 21 ++ ++ ++ 7 ++ ++ ++ ++ ++ ++ ++ 70 ++ ++ ++ 7 ++ ++ ++ + + + +@@ -73896,4 +74144,4 @@ + + + +- +\ No newline at end of file ++ +diff --git a/msvc/scripts/System.Web.pre b/msvc/scripts/System.Web.pre +index c071bf45bfd..8f8d262597f 100644 +--- a/msvc/scripts/System.Web.pre ++++ b/msvc/scripts/System.Web.pre +@@ -1 +1 @@ +-@MONO@ $(ProjectDir)\..\lib\net_4_x\culevel.exe -o $(ProjectDir)\System.Web\UplevelHelper.cs $(ProjectDir)\UplevelHelperDefinitions.xml ++@MONO@ $([MSBuild]::GetDirectoryNameOfFileAbove($(TargetDir), culevel.exe))\culevel.exe -o $(ProjectDir)\System.Web\UplevelHelper.cs $(ProjectDir)\UplevelHelperDefinitions.xml +diff --git a/msvc/scripts/csproj.tmpl b/msvc/scripts/csproj.tmpl +index 642c9537321..c18b51d334e 100644 +--- a/msvc/scripts/csproj.tmpl ++++ b/msvc/scripts/csproj.tmpl +@@ -17,6 +17,7 @@ + obj-@OUTPUTSUFFIX@ + false + @NOSTDLIB@ ++ @METADATAVERSION@ + @STARTUPOBJECT@ + @NOCONFIG@ + @ALLOWUNSAFE@ +diff --git a/msvc/scripts/genproj.cs b/msvc/scripts/genproj.cs +index 3987abb212b..1440800b2b3 100644 +--- a/msvc/scripts/genproj.cs ++++ b/msvc/scripts/genproj.cs +@@ -27,27 +27,43 @@ public enum Target { + + class SlnGenerator { + public static readonly string NewLine = "\r\n"; //Environment.NewLine; // "\n"; +- public SlnGenerator (string formatVersion = "2012") ++ public SlnGenerator (string slnVersion) + { +- switch (formatVersion) { +- case "2008": +- this.header = MakeHeader ("10.00", "2008"); +- break; +- default: +- this.header = MakeHeader ("12.00", "2012"); +- break; +- } ++ Console.WriteLine("Requested sln version is {0}", slnVersion); ++ this.header = MakeHeader ("12.00", "15", "15.0.0.0"); + } + +- const string project_start = "Project(\"{{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}}\") = \"{0}\", \"{1}\", \"{2}\""; // Note: No need to double up on {} around {2} ++ const string project_start = "Project(\"{0}\") = \"{1}\", \"{2}\", \"{3}\""; // Note: No need to double up on {} around {2} + const string project_end = "EndProject"; + ++ public List profiles = new List { ++ "net_4_x", ++ "monodroid", ++ "monotouch", ++ "monotouch_tv", ++ "monotouch_watch", ++ "orbis", ++ "unreal", ++ "wasm", ++ "winaot", ++ "xammac", ++ }; ++ ++ const string jay_vcxproj_guid = "{5D485D32-3B9F-4287-AB24-C8DA5B89F537}"; ++ const string jay_sln_guid = "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}"; ++ + public List libraries = new List (); + string header; + +- string MakeHeader (string formatVersion, string yearTag) ++ string MakeHeader (string formatVersion, string yearTag, string minimumVersion) + { +- return string.Format ("Microsoft Visual Studio Solution File, Format Version {0}" + NewLine + "# Visual Studio {1}", formatVersion, yearTag); ++ return string.Format ( ++ "Microsoft Visual Studio Solution File, Format Version {0}" + NewLine + ++ "# Visual Studio {1}" + NewLine + ++ "MinimumVisualStudioVersion = {2}", ++ formatVersion, yearTag, ++ minimumVersion ++ ); + } + + public void Add (MsbuildGenerator.VsCsproj vsproj) +@@ -59,6 +75,40 @@ class SlnGenerator { + } + } + ++ private void WriteProjectReference (StreamWriter sln, string prefixGuid, string library, string relativePath, string projectGuid, params string[] dependencyGuids) ++ { ++ sln.WriteLine (project_start, prefixGuid, library, relativePath, projectGuid); ++ ++ foreach (var guid in dependencyGuids) { ++ sln.WriteLine (" ProjectSection(ProjectDependencies) = postProject"); ++ sln.WriteLine (" {0} = {0}", guid); ++ sln.WriteLine (" EndProjectSection"); ++ } ++ ++ sln.WriteLine (project_end); ++ } ++ ++ private void WriteProjectReference (StreamWriter sln, string slnFullPath, MsbuildGenerator.VsCsproj proj) ++ { ++ var unixProjFile = proj.csProjFilename.Replace ("\\", "/"); ++ var fullProjPath = Path.GetFullPath (unixProjFile); ++ var relativePath = MsbuildGenerator.GetRelativePath (slnFullPath, fullProjPath); ++ var dependencyGuids = new string[0]; ++ if (proj.preBuildEvent.Contains ("jay")) ++ dependencyGuids = new [] { jay_vcxproj_guid }; ++ WriteProjectReference(sln, "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}", proj.library, relativePath, proj.projectGuid, dependencyGuids); ++ } ++ ++ private void WriteProjectConfigurationPlatforms (StreamWriter sln, string guid, string platformToBuild) ++ { ++ foreach (var profile in profiles) { ++ sln.WriteLine ("\t\t{0}.Debug|{1}.ActiveCfg = Debug|{2}", guid, profile, platformToBuild); ++ sln.WriteLine ("\t\t{0}.Debug|{1}.Build.0 = Debug|{2}", guid, profile, platformToBuild); ++ sln.WriteLine ("\t\t{0}.Release|{1}.ActiveCfg = Release|{2}", guid, profile, platformToBuild); ++ sln.WriteLine ("\t\t{0}.Release|{1}.Build.0 = Release|{2}", guid, profile, platformToBuild); ++ } ++ } ++ + public void Write (string filename) + { + var fullPath = Path.GetDirectoryName (filename) + "/"; +@@ -66,27 +116,32 @@ class SlnGenerator { + using (var sln = new StreamWriter (filename)) { + sln.WriteLine (); + sln.WriteLine (header); ++ ++ // Manually insert jay's vcxproj. We depend on jay.exe to perform build steps later. ++ WriteProjectReference (sln, jay_sln_guid, "jay", "mcs\\jay\\jay.vcxproj", jay_vcxproj_guid); ++ + foreach (var proj in libraries) { +- var unixProjFile = proj.csProjFilename.Replace ("\\", "/"); +- var fullProjPath = Path.GetFullPath (unixProjFile); +- sln.WriteLine (project_start, proj.library, MsbuildGenerator.GetRelativePath (fullPath, fullProjPath), proj.projectGuid); +- sln.WriteLine (project_end); ++ WriteProjectReference (sln, fullPath, proj); + } ++ + sln.WriteLine ("Global"); + + sln.WriteLine ("\tGlobalSection(SolutionConfigurationPlatforms) = preSolution"); +- sln.WriteLine ("\t\tDebug|Any CPU = Debug|Any CPU"); +- sln.WriteLine ("\t\tRelease|Any CPU = Release|Any CPU"); ++ foreach (var profile in profiles) { ++ sln.WriteLine ("\t\tDebug|{0} = Debug|{0}", profile); ++ sln.WriteLine ("\t\tRelease|{0} = Release|{0}", profile); ++ } + sln.WriteLine ("\tEndGlobalSection"); + + sln.WriteLine ("\tGlobalSection(ProjectConfigurationPlatforms) = postSolution"); ++ ++ // Manually insert jay's configurations because they are different ++ WriteProjectConfigurationPlatforms (sln, jay_vcxproj_guid, "Win32"); ++ + foreach (var proj in libraries) { +- var guid = proj.projectGuid; +- sln.WriteLine ("\t\t{0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU", guid); +- sln.WriteLine ("\t\t{0}.Debug|Any CPU.Build.0 = Debug|Any CPU", guid); +- sln.WriteLine ("\t\t{0}.Release|Any CPU.ActiveCfg = Release|Any CPU", guid); +- sln.WriteLine ("\t\t{0}.Release|Any CPU.Build.0 = Release|Any CPU", guid); ++ WriteProjectConfigurationPlatforms (sln, proj.projectGuid, "Any CPU"); + } ++ + sln.WriteLine ("\tEndGlobalSection"); + + sln.WriteLine ("\tGlobalSection(SolutionProperties) = preSolution"); +@@ -634,6 +689,7 @@ class MsbuildGenerator { + public List projReferences = new List (); + public string library; + public MsbuildGenerator MsbuildGenerator; ++ public string preBuildEvent, postBuildEvent; + } + + public VsCsproj Csproj; +@@ -682,7 +738,7 @@ class MsbuildGenerator { + fx_version = "4.0"; + profile = "net_4_0"; + } else if (response.Contains (profile_4_x)) { +- fx_version = "4.5"; ++ fx_version = "4.6.2"; + profile = "net_4_x"; + } + } +@@ -882,6 +938,26 @@ class MsbuildGenerator { + + bool basic_or_build = (library.Contains ("-basic") || library.Contains ("-build")); + ++ // If an EXE is built with nostdlib, it won't work unless run with mono.exe. This stops our build steps ++ // from working in visual studio (because we already replace @MONO@ with '' on Windows.) ++ ++ if (Target != Target.Library) ++ StdLib = true; ++ ++ // We have our target framework set to 4.5 in many places because broken scripts check for files with 4.5 ++ // in the path, even though we compile code that uses 4.6 features. So we need to manually fix that here. ++ ++ if (fx_version == "4.5") ++ fx_version = "4.6.2"; ++ ++ // The VS2017 signing system fails to sign using this key for some reason, so for now, ++ // just disable code signing for the nunit assemblies. It's not important. ++ // I'd rather fix this by updating the makefiles but it seems to be impossible to disable ++ // code signing in our make system... ++ ++ if (StrongNameKeyFile?.Contains("nunit.snk") ?? false) ++ StrongNameKeyFile = null; ++ + // + // Replace the template values + // +@@ -894,6 +970,9 @@ class MsbuildGenerator { + " {0}", + StrongNameKeyFile, StrongNameDelaySign ? " true" + NewLine : ""); + } ++ ++ string assemblyName = Path.GetFileNameWithoutExtension (output_name); ++ + Csproj.output = template. + Replace ("@OUTPUTTYPE@", Target == Target.Library ? "Library" : "Exe"). + Replace ("@SIGNATURE@", strongNameSection). +@@ -906,7 +985,7 @@ class MsbuildGenerator { + Replace ("@NOCONFIG@", "" + (!load_default_config).ToString () + ""). + Replace ("@ALLOWUNSAFE@", Unsafe ? "true" : ""). + Replace ("@FX_VERSION", fx_version). +- Replace ("@ASSEMBLYNAME@", Path.GetFileNameWithoutExtension (output_name)). ++ Replace ("@ASSEMBLYNAME@", assemblyName). + Replace ("@OUTPUTDIR@", build_output_dir). + Replace ("@OUTPUTSUFFIX@", Path.GetFileName (build_output_dir)). + Replace ("@DEFINECONSTANTS@", defines.ToString ()). +@@ -920,7 +999,11 @@ class MsbuildGenerator { + Replace ("@ADDITIONALLIBPATHS@", String.Empty). + Replace ("@RESOURCES@", resources.ToString ()). + Replace ("@OPTIMIZE@", Optimize ? "true" : "false"). +- Replace ("@SOURCES@", sources.ToString ()); ++ Replace ("@SOURCES@", sources.ToString ()). ++ Replace ("@METADATAVERSION@", assemblyName == "mscorlib" ? "Mono" : ""); ++ ++ Csproj.preBuildEvent = prebuild; ++ Csproj.postBuildEvent = postbuild; + + //Console.WriteLine ("Generated {0}", ofile.Replace ("\\", "/")); + using (var o = new StreamWriter (generatedProjFile)) { +@@ -939,15 +1022,13 @@ class MsbuildGenerator { + if (q != -1) + target = target + Load (library.Substring (0, q) + suffix); + +- if (target.IndexOf ("@MONO@") != -1){ +- target_unix = target.Replace ("@MONO@", "mono").Replace ("@CAT@", "cat"); +- target_windows = target.Replace ("@MONO@", "").Replace ("@CAT@", "type"); +- } else { +- target_unix = target.Replace ("jay.exe", "jay"); +- target_windows = target; +- } ++ target_unix = target.Replace ("@MONO@", "mono").Replace ("@CAT@", "cat"); ++ target_windows = target.Replace ("@MONO@", "").Replace ("@CAT@", "type"); ++ ++ target_unix = target_unix.Replace ("\\jay\\jay.exe", "\\jay\\jay\\jay"); ++ + target_unix = target_unix.Replace ("@COPY@", "cp"); +- target_windows = target_unix.Replace ("@COPY@", "copy"); ++ target_windows = target_windows.Replace ("@COPY@", "copy"); + + target_unix = target_unix.Replace ("\r", ""); + const string condition_unix = "Condition=\" '$(OS)' != 'Windows_NT' \""; -- 2.45.2