Migrating from monodoc/ecma334 to mcs/docs/ecma334...
authorJonathan Pryor <jpryor@novell.com>
Fri, 17 Oct 2008 15:01:25 +0000 (15:01 -0000)
committerJonathan Pryor <jpryor@novell.com>
Fri, 17 Oct 2008 15:01:25 +0000 (15:01 -0000)
svn path=/trunk/mcs/; revision=116235

465 files changed:
mcs/docs/ecma334/1.xml [new file with mode: 0644]
mcs/docs/ecma334/10.1.xml [new file with mode: 0644]
mcs/docs/ecma334/10.10.xml [new file with mode: 0644]
mcs/docs/ecma334/10.2.xml [new file with mode: 0644]
mcs/docs/ecma334/10.3.xml [new file with mode: 0644]
mcs/docs/ecma334/10.4.1.xml [new file with mode: 0644]
mcs/docs/ecma334/10.4.2.xml [new file with mode: 0644]
mcs/docs/ecma334/10.4.3.xml [new file with mode: 0644]
mcs/docs/ecma334/10.4.4.xml [new file with mode: 0644]
mcs/docs/ecma334/10.4.5.xml [new file with mode: 0644]
mcs/docs/ecma334/10.4.6.xml [new file with mode: 0644]
mcs/docs/ecma334/10.4.7.xml [new file with mode: 0644]
mcs/docs/ecma334/10.4.xml [new file with mode: 0644]
mcs/docs/ecma334/10.5.1.xml [new file with mode: 0644]
mcs/docs/ecma334/10.5.2.xml [new file with mode: 0644]
mcs/docs/ecma334/10.5.3.xml [new file with mode: 0644]
mcs/docs/ecma334/10.5.4.xml [new file with mode: 0644]
mcs/docs/ecma334/10.5.xml [new file with mode: 0644]
mcs/docs/ecma334/10.6.xml [new file with mode: 0644]
mcs/docs/ecma334/10.7.1.1.xml [new file with mode: 0644]
mcs/docs/ecma334/10.7.1.2.xml [new file with mode: 0644]
mcs/docs/ecma334/10.7.1.xml [new file with mode: 0644]
mcs/docs/ecma334/10.7.xml [new file with mode: 0644]
mcs/docs/ecma334/10.8.1.xml [new file with mode: 0644]
mcs/docs/ecma334/10.8.xml [new file with mode: 0644]
mcs/docs/ecma334/10.9.xml [new file with mode: 0644]
mcs/docs/ecma334/10.xml [new file with mode: 0644]
mcs/docs/ecma334/11.1.1.xml [new file with mode: 0644]
mcs/docs/ecma334/11.1.2.xml [new file with mode: 0644]
mcs/docs/ecma334/11.1.3.xml [new file with mode: 0644]
mcs/docs/ecma334/11.1.4.xml [new file with mode: 0644]
mcs/docs/ecma334/11.1.5.xml [new file with mode: 0644]
mcs/docs/ecma334/11.1.6.xml [new file with mode: 0644]
mcs/docs/ecma334/11.1.7.xml [new file with mode: 0644]
mcs/docs/ecma334/11.1.8.xml [new file with mode: 0644]
mcs/docs/ecma334/11.1.xml [new file with mode: 0644]
mcs/docs/ecma334/11.2.1.xml [new file with mode: 0644]
mcs/docs/ecma334/11.2.2.xml [new file with mode: 0644]
mcs/docs/ecma334/11.2.3.xml [new file with mode: 0644]
mcs/docs/ecma334/11.2.4.xml [new file with mode: 0644]
mcs/docs/ecma334/11.2.5.xml [new file with mode: 0644]
mcs/docs/ecma334/11.2.6.xml [new file with mode: 0644]
mcs/docs/ecma334/11.2.xml [new file with mode: 0644]
mcs/docs/ecma334/11.3.1.xml [new file with mode: 0644]
mcs/docs/ecma334/11.3.2.xml [new file with mode: 0644]
mcs/docs/ecma334/11.3.xml [new file with mode: 0644]
mcs/docs/ecma334/11.xml [new file with mode: 0644]
mcs/docs/ecma334/12.1.1.xml [new file with mode: 0644]
mcs/docs/ecma334/12.1.2.1.xml [new file with mode: 0644]
mcs/docs/ecma334/12.1.2.2.xml [new file with mode: 0644]
mcs/docs/ecma334/12.1.2.xml [new file with mode: 0644]
mcs/docs/ecma334/12.1.3.xml [new file with mode: 0644]
mcs/docs/ecma334/12.1.4.xml [new file with mode: 0644]
mcs/docs/ecma334/12.1.5.xml [new file with mode: 0644]
mcs/docs/ecma334/12.1.6.xml [new file with mode: 0644]
mcs/docs/ecma334/12.1.7.xml [new file with mode: 0644]
mcs/docs/ecma334/12.1.xml [new file with mode: 0644]
mcs/docs/ecma334/12.2.xml [new file with mode: 0644]
mcs/docs/ecma334/12.3.1.xml [new file with mode: 0644]
mcs/docs/ecma334/12.3.2.xml [new file with mode: 0644]
mcs/docs/ecma334/12.3.3.1.xml [new file with mode: 0644]
mcs/docs/ecma334/12.3.3.10.xml [new file with mode: 0644]
mcs/docs/ecma334/12.3.3.11.xml [new file with mode: 0644]
mcs/docs/ecma334/12.3.3.12.xml [new file with mode: 0644]
mcs/docs/ecma334/12.3.3.13.xml [new file with mode: 0644]
mcs/docs/ecma334/12.3.3.14.xml [new file with mode: 0644]
mcs/docs/ecma334/12.3.3.15.xml [new file with mode: 0644]
mcs/docs/ecma334/12.3.3.16.xml [new file with mode: 0644]
mcs/docs/ecma334/12.3.3.17.xml [new file with mode: 0644]
mcs/docs/ecma334/12.3.3.18.xml [new file with mode: 0644]
mcs/docs/ecma334/12.3.3.19.xml [new file with mode: 0644]
mcs/docs/ecma334/12.3.3.2.xml [new file with mode: 0644]
mcs/docs/ecma334/12.3.3.20.xml [new file with mode: 0644]
mcs/docs/ecma334/12.3.3.21.xml [new file with mode: 0644]
mcs/docs/ecma334/12.3.3.22.xml [new file with mode: 0644]
mcs/docs/ecma334/12.3.3.23.xml [new file with mode: 0644]
mcs/docs/ecma334/12.3.3.24.xml [new file with mode: 0644]
mcs/docs/ecma334/12.3.3.25.xml [new file with mode: 0644]
mcs/docs/ecma334/12.3.3.26.xml [new file with mode: 0644]
mcs/docs/ecma334/12.3.3.3.xml [new file with mode: 0644]
mcs/docs/ecma334/12.3.3.4.xml [new file with mode: 0644]
mcs/docs/ecma334/12.3.3.5.xml [new file with mode: 0644]
mcs/docs/ecma334/12.3.3.6.xml [new file with mode: 0644]
mcs/docs/ecma334/12.3.3.7.xml [new file with mode: 0644]
mcs/docs/ecma334/12.3.3.8.xml [new file with mode: 0644]
mcs/docs/ecma334/12.3.3.9.xml [new file with mode: 0644]
mcs/docs/ecma334/12.3.3.xml [new file with mode: 0644]
mcs/docs/ecma334/12.3.xml [new file with mode: 0644]
mcs/docs/ecma334/12.4.xml [new file with mode: 0644]
mcs/docs/ecma334/12.5.xml [new file with mode: 0644]
mcs/docs/ecma334/12.xml [new file with mode: 0644]
mcs/docs/ecma334/13.1.1.xml [new file with mode: 0644]
mcs/docs/ecma334/13.1.2.xml [new file with mode: 0644]
mcs/docs/ecma334/13.1.3.xml [new file with mode: 0644]
mcs/docs/ecma334/13.1.4.xml [new file with mode: 0644]
mcs/docs/ecma334/13.1.5.xml [new file with mode: 0644]
mcs/docs/ecma334/13.1.6.xml [new file with mode: 0644]
mcs/docs/ecma334/13.1.7.xml [new file with mode: 0644]
mcs/docs/ecma334/13.1.xml [new file with mode: 0644]
mcs/docs/ecma334/13.2.1.xml [new file with mode: 0644]
mcs/docs/ecma334/13.2.2.xml [new file with mode: 0644]
mcs/docs/ecma334/13.2.3.xml [new file with mode: 0644]
mcs/docs/ecma334/13.2.4.xml [new file with mode: 0644]
mcs/docs/ecma334/13.2.5.xml [new file with mode: 0644]
mcs/docs/ecma334/13.2.xml [new file with mode: 0644]
mcs/docs/ecma334/13.3.1.xml [new file with mode: 0644]
mcs/docs/ecma334/13.3.2.xml [new file with mode: 0644]
mcs/docs/ecma334/13.3.xml [new file with mode: 0644]
mcs/docs/ecma334/13.4.1.xml [new file with mode: 0644]
mcs/docs/ecma334/13.4.2.xml [new file with mode: 0644]
mcs/docs/ecma334/13.4.3.xml [new file with mode: 0644]
mcs/docs/ecma334/13.4.4.xml [new file with mode: 0644]
mcs/docs/ecma334/13.4.xml [new file with mode: 0644]
mcs/docs/ecma334/13.xml [new file with mode: 0644]
mcs/docs/ecma334/14.1.1.xml [new file with mode: 0644]
mcs/docs/ecma334/14.1.xml [new file with mode: 0644]
mcs/docs/ecma334/14.10.1.xml [new file with mode: 0644]
mcs/docs/ecma334/14.10.2.xml [new file with mode: 0644]
mcs/docs/ecma334/14.10.3.xml [new file with mode: 0644]
mcs/docs/ecma334/14.10.xml [new file with mode: 0644]
mcs/docs/ecma334/14.11.1.xml [new file with mode: 0644]
mcs/docs/ecma334/14.11.2.xml [new file with mode: 0644]
mcs/docs/ecma334/14.11.xml [new file with mode: 0644]
mcs/docs/ecma334/14.12.xml [new file with mode: 0644]
mcs/docs/ecma334/14.13.1.xml [new file with mode: 0644]
mcs/docs/ecma334/14.13.2.xml [new file with mode: 0644]
mcs/docs/ecma334/14.13.3.xml [new file with mode: 0644]
mcs/docs/ecma334/14.13.xml [new file with mode: 0644]
mcs/docs/ecma334/14.14.xml [new file with mode: 0644]
mcs/docs/ecma334/14.15.xml [new file with mode: 0644]
mcs/docs/ecma334/14.16.xml [new file with mode: 0644]
mcs/docs/ecma334/14.2.1.xml [new file with mode: 0644]
mcs/docs/ecma334/14.2.2.xml [new file with mode: 0644]
mcs/docs/ecma334/14.2.3.xml [new file with mode: 0644]
mcs/docs/ecma334/14.2.4.xml [new file with mode: 0644]
mcs/docs/ecma334/14.2.5.xml [new file with mode: 0644]
mcs/docs/ecma334/14.2.6.1.xml [new file with mode: 0644]
mcs/docs/ecma334/14.2.6.2.xml [new file with mode: 0644]
mcs/docs/ecma334/14.2.6.xml [new file with mode: 0644]
mcs/docs/ecma334/14.2.xml [new file with mode: 0644]
mcs/docs/ecma334/14.3.1.xml [new file with mode: 0644]
mcs/docs/ecma334/14.3.xml [new file with mode: 0644]
mcs/docs/ecma334/14.4.1.xml [new file with mode: 0644]
mcs/docs/ecma334/14.4.2.1.xml [new file with mode: 0644]
mcs/docs/ecma334/14.4.2.2.xml [new file with mode: 0644]
mcs/docs/ecma334/14.4.2.3.xml [new file with mode: 0644]
mcs/docs/ecma334/14.4.2.xml [new file with mode: 0644]
mcs/docs/ecma334/14.4.3.1.xml [new file with mode: 0644]
mcs/docs/ecma334/14.4.3.xml [new file with mode: 0644]
mcs/docs/ecma334/14.4.xml [new file with mode: 0644]
mcs/docs/ecma334/14.5.1.xml [new file with mode: 0644]
mcs/docs/ecma334/14.5.10.1.xml [new file with mode: 0644]
mcs/docs/ecma334/14.5.10.2.xml [new file with mode: 0644]
mcs/docs/ecma334/14.5.10.3.xml [new file with mode: 0644]
mcs/docs/ecma334/14.5.10.xml [new file with mode: 0644]
mcs/docs/ecma334/14.5.11.xml [new file with mode: 0644]
mcs/docs/ecma334/14.5.12.xml [new file with mode: 0644]
mcs/docs/ecma334/14.5.2.1.xml [new file with mode: 0644]
mcs/docs/ecma334/14.5.2.xml [new file with mode: 0644]
mcs/docs/ecma334/14.5.3.xml [new file with mode: 0644]
mcs/docs/ecma334/14.5.4.1.xml [new file with mode: 0644]
mcs/docs/ecma334/14.5.4.xml [new file with mode: 0644]
mcs/docs/ecma334/14.5.5.1.xml [new file with mode: 0644]
mcs/docs/ecma334/14.5.5.2.xml [new file with mode: 0644]
mcs/docs/ecma334/14.5.5.xml [new file with mode: 0644]
mcs/docs/ecma334/14.5.6.1.xml [new file with mode: 0644]
mcs/docs/ecma334/14.5.6.2.xml [new file with mode: 0644]
mcs/docs/ecma334/14.5.6.xml [new file with mode: 0644]
mcs/docs/ecma334/14.5.7.xml [new file with mode: 0644]
mcs/docs/ecma334/14.5.8.xml [new file with mode: 0644]
mcs/docs/ecma334/14.5.9.xml [new file with mode: 0644]
mcs/docs/ecma334/14.5.xml [new file with mode: 0644]
mcs/docs/ecma334/14.6.1.xml [new file with mode: 0644]
mcs/docs/ecma334/14.6.2.xml [new file with mode: 0644]
mcs/docs/ecma334/14.6.3.xml [new file with mode: 0644]
mcs/docs/ecma334/14.6.4.xml [new file with mode: 0644]
mcs/docs/ecma334/14.6.5.xml [new file with mode: 0644]
mcs/docs/ecma334/14.6.6.xml [new file with mode: 0644]
mcs/docs/ecma334/14.6.xml [new file with mode: 0644]
mcs/docs/ecma334/14.7.1.xml [new file with mode: 0644]
mcs/docs/ecma334/14.7.2.xml [new file with mode: 0644]
mcs/docs/ecma334/14.7.3.xml [new file with mode: 0644]
mcs/docs/ecma334/14.7.4.xml [new file with mode: 0644]
mcs/docs/ecma334/14.7.5.xml [new file with mode: 0644]
mcs/docs/ecma334/14.7.xml [new file with mode: 0644]
mcs/docs/ecma334/14.8.xml [new file with mode: 0644]
mcs/docs/ecma334/14.9.1.xml [new file with mode: 0644]
mcs/docs/ecma334/14.9.10.xml [new file with mode: 0644]
mcs/docs/ecma334/14.9.2.xml [new file with mode: 0644]
mcs/docs/ecma334/14.9.3.xml [new file with mode: 0644]
mcs/docs/ecma334/14.9.4.xml [new file with mode: 0644]
mcs/docs/ecma334/14.9.5.xml [new file with mode: 0644]
mcs/docs/ecma334/14.9.6.xml [new file with mode: 0644]
mcs/docs/ecma334/14.9.7.xml [new file with mode: 0644]
mcs/docs/ecma334/14.9.8.xml [new file with mode: 0644]
mcs/docs/ecma334/14.9.9.xml [new file with mode: 0644]
mcs/docs/ecma334/14.9.xml [new file with mode: 0644]
mcs/docs/ecma334/14.xml [new file with mode: 0644]
mcs/docs/ecma334/15.1.xml [new file with mode: 0644]
mcs/docs/ecma334/15.10.xml [new file with mode: 0644]
mcs/docs/ecma334/15.11.xml [new file with mode: 0644]
mcs/docs/ecma334/15.12.xml [new file with mode: 0644]
mcs/docs/ecma334/15.13.xml [new file with mode: 0644]
mcs/docs/ecma334/15.2.1.xml [new file with mode: 0644]
mcs/docs/ecma334/15.2.xml [new file with mode: 0644]
mcs/docs/ecma334/15.3.xml [new file with mode: 0644]
mcs/docs/ecma334/15.4.xml [new file with mode: 0644]
mcs/docs/ecma334/15.5.1.xml [new file with mode: 0644]
mcs/docs/ecma334/15.5.2.xml [new file with mode: 0644]
mcs/docs/ecma334/15.5.xml [new file with mode: 0644]
mcs/docs/ecma334/15.6.xml [new file with mode: 0644]
mcs/docs/ecma334/15.7.1.xml [new file with mode: 0644]
mcs/docs/ecma334/15.7.2.xml [new file with mode: 0644]
mcs/docs/ecma334/15.7.xml [new file with mode: 0644]
mcs/docs/ecma334/15.8.1.xml [new file with mode: 0644]
mcs/docs/ecma334/15.8.2.xml [new file with mode: 0644]
mcs/docs/ecma334/15.8.3.xml [new file with mode: 0644]
mcs/docs/ecma334/15.8.4.xml [new file with mode: 0644]
mcs/docs/ecma334/15.8.xml [new file with mode: 0644]
mcs/docs/ecma334/15.9.1.xml [new file with mode: 0644]
mcs/docs/ecma334/15.9.2.xml [new file with mode: 0644]
mcs/docs/ecma334/15.9.3.xml [new file with mode: 0644]
mcs/docs/ecma334/15.9.4.xml [new file with mode: 0644]
mcs/docs/ecma334/15.9.5.xml [new file with mode: 0644]
mcs/docs/ecma334/15.9.xml [new file with mode: 0644]
mcs/docs/ecma334/15.xml [new file with mode: 0644]
mcs/docs/ecma334/16.1.xml [new file with mode: 0644]
mcs/docs/ecma334/16.2.xml [new file with mode: 0644]
mcs/docs/ecma334/16.3.1.xml [new file with mode: 0644]
mcs/docs/ecma334/16.3.2.xml [new file with mode: 0644]
mcs/docs/ecma334/16.3.xml [new file with mode: 0644]
mcs/docs/ecma334/16.4.xml [new file with mode: 0644]
mcs/docs/ecma334/16.5.xml [new file with mode: 0644]
mcs/docs/ecma334/16.xml [new file with mode: 0644]
mcs/docs/ecma334/17.1.1.1.xml [new file with mode: 0644]
mcs/docs/ecma334/17.1.1.2.xml [new file with mode: 0644]
mcs/docs/ecma334/17.1.1.xml [new file with mode: 0644]
mcs/docs/ecma334/17.1.2.1.xml [new file with mode: 0644]
mcs/docs/ecma334/17.1.2.2.xml [new file with mode: 0644]
mcs/docs/ecma334/17.1.2.xml [new file with mode: 0644]
mcs/docs/ecma334/17.1.3.xml [new file with mode: 0644]
mcs/docs/ecma334/17.1.xml [new file with mode: 0644]
mcs/docs/ecma334/17.10.1.xml [new file with mode: 0644]
mcs/docs/ecma334/17.10.2.xml [new file with mode: 0644]
mcs/docs/ecma334/17.10.3.xml [new file with mode: 0644]
mcs/docs/ecma334/17.10.4.xml [new file with mode: 0644]
mcs/docs/ecma334/17.10.5.xml [new file with mode: 0644]
mcs/docs/ecma334/17.10.6.xml [new file with mode: 0644]
mcs/docs/ecma334/17.10.xml [new file with mode: 0644]
mcs/docs/ecma334/17.11.xml [new file with mode: 0644]
mcs/docs/ecma334/17.12.xml [new file with mode: 0644]
mcs/docs/ecma334/17.2.1.xml [new file with mode: 0644]
mcs/docs/ecma334/17.2.2.xml [new file with mode: 0644]
mcs/docs/ecma334/17.2.3.xml [new file with mode: 0644]
mcs/docs/ecma334/17.2.4.xml [new file with mode: 0644]
mcs/docs/ecma334/17.2.5.xml [new file with mode: 0644]
mcs/docs/ecma334/17.2.6.1.xml [new file with mode: 0644]
mcs/docs/ecma334/17.2.6.2.xml [new file with mode: 0644]
mcs/docs/ecma334/17.2.6.3.xml [new file with mode: 0644]
mcs/docs/ecma334/17.2.6.4.xml [new file with mode: 0644]
mcs/docs/ecma334/17.2.6.5.xml [new file with mode: 0644]
mcs/docs/ecma334/17.2.6.xml [new file with mode: 0644]
mcs/docs/ecma334/17.2.7.1.xml [new file with mode: 0644]
mcs/docs/ecma334/17.2.7.2.xml [new file with mode: 0644]
mcs/docs/ecma334/17.2.7.3.xml [new file with mode: 0644]
mcs/docs/ecma334/17.2.7.4.xml [new file with mode: 0644]
mcs/docs/ecma334/17.2.7.xml [new file with mode: 0644]
mcs/docs/ecma334/17.2.xml [new file with mode: 0644]
mcs/docs/ecma334/17.3.xml [new file with mode: 0644]
mcs/docs/ecma334/17.4.1.xml [new file with mode: 0644]
mcs/docs/ecma334/17.4.2.1.xml [new file with mode: 0644]
mcs/docs/ecma334/17.4.2.2.xml [new file with mode: 0644]
mcs/docs/ecma334/17.4.2.xml [new file with mode: 0644]
mcs/docs/ecma334/17.4.3.xml [new file with mode: 0644]
mcs/docs/ecma334/17.4.4.xml [new file with mode: 0644]
mcs/docs/ecma334/17.4.5.1.xml [new file with mode: 0644]
mcs/docs/ecma334/17.4.5.2.xml [new file with mode: 0644]
mcs/docs/ecma334/17.4.5.xml [new file with mode: 0644]
mcs/docs/ecma334/17.4.xml [new file with mode: 0644]
mcs/docs/ecma334/17.5.1.1.xml [new file with mode: 0644]
mcs/docs/ecma334/17.5.1.2.xml [new file with mode: 0644]
mcs/docs/ecma334/17.5.1.3.xml [new file with mode: 0644]
mcs/docs/ecma334/17.5.1.4.xml [new file with mode: 0644]
mcs/docs/ecma334/17.5.1.xml [new file with mode: 0644]
mcs/docs/ecma334/17.5.2.xml [new file with mode: 0644]
mcs/docs/ecma334/17.5.3.xml [new file with mode: 0644]
mcs/docs/ecma334/17.5.4.xml [new file with mode: 0644]
mcs/docs/ecma334/17.5.5.xml [new file with mode: 0644]
mcs/docs/ecma334/17.5.6.xml [new file with mode: 0644]
mcs/docs/ecma334/17.5.7.xml [new file with mode: 0644]
mcs/docs/ecma334/17.5.8.xml [new file with mode: 0644]
mcs/docs/ecma334/17.5.9.xml [new file with mode: 0644]
mcs/docs/ecma334/17.5.xml [new file with mode: 0644]
mcs/docs/ecma334/17.6.1.xml [new file with mode: 0644]
mcs/docs/ecma334/17.6.2.xml [new file with mode: 0644]
mcs/docs/ecma334/17.6.3.xml [new file with mode: 0644]
mcs/docs/ecma334/17.6.xml [new file with mode: 0644]
mcs/docs/ecma334/17.7.1.xml [new file with mode: 0644]
mcs/docs/ecma334/17.7.2.xml [new file with mode: 0644]
mcs/docs/ecma334/17.7.3.xml [new file with mode: 0644]
mcs/docs/ecma334/17.7.4.xml [new file with mode: 0644]
mcs/docs/ecma334/17.7.xml [new file with mode: 0644]
mcs/docs/ecma334/17.8.1.xml [new file with mode: 0644]
mcs/docs/ecma334/17.8.xml [new file with mode: 0644]
mcs/docs/ecma334/17.9.1.xml [new file with mode: 0644]
mcs/docs/ecma334/17.9.2.xml [new file with mode: 0644]
mcs/docs/ecma334/17.9.3.xml [new file with mode: 0644]
mcs/docs/ecma334/17.9.xml [new file with mode: 0644]
mcs/docs/ecma334/17.xml [new file with mode: 0644]
mcs/docs/ecma334/18.1.1.xml [new file with mode: 0644]
mcs/docs/ecma334/18.1.2.xml [new file with mode: 0644]
mcs/docs/ecma334/18.1.3.xml [new file with mode: 0644]
mcs/docs/ecma334/18.1.xml [new file with mode: 0644]
mcs/docs/ecma334/18.2.xml [new file with mode: 0644]
mcs/docs/ecma334/18.3.1.xml [new file with mode: 0644]
mcs/docs/ecma334/18.3.2.xml [new file with mode: 0644]
mcs/docs/ecma334/18.3.3.xml [new file with mode: 0644]
mcs/docs/ecma334/18.3.4.xml [new file with mode: 0644]
mcs/docs/ecma334/18.3.5.xml [new file with mode: 0644]
mcs/docs/ecma334/18.3.6.xml [new file with mode: 0644]
mcs/docs/ecma334/18.3.7.xml [new file with mode: 0644]
mcs/docs/ecma334/18.3.8.xml [new file with mode: 0644]
mcs/docs/ecma334/18.3.9.xml [new file with mode: 0644]
mcs/docs/ecma334/18.3.xml [new file with mode: 0644]
mcs/docs/ecma334/18.4.1.xml [new file with mode: 0644]
mcs/docs/ecma334/18.4.2.xml [new file with mode: 0644]
mcs/docs/ecma334/18.4.xml [new file with mode: 0644]
mcs/docs/ecma334/18.xml [new file with mode: 0644]
mcs/docs/ecma334/19.1.1.xml [new file with mode: 0644]
mcs/docs/ecma334/19.1.xml [new file with mode: 0644]
mcs/docs/ecma334/19.2.xml [new file with mode: 0644]
mcs/docs/ecma334/19.3.xml [new file with mode: 0644]
mcs/docs/ecma334/19.4.xml [new file with mode: 0644]
mcs/docs/ecma334/19.5.xml [new file with mode: 0644]
mcs/docs/ecma334/19.6.xml [new file with mode: 0644]
mcs/docs/ecma334/19.xml [new file with mode: 0644]
mcs/docs/ecma334/2.xml [new file with mode: 0644]
mcs/docs/ecma334/20.1.1.xml [new file with mode: 0644]
mcs/docs/ecma334/20.1.2.xml [new file with mode: 0644]
mcs/docs/ecma334/20.1.3.xml [new file with mode: 0644]
mcs/docs/ecma334/20.1.xml [new file with mode: 0644]
mcs/docs/ecma334/20.2.1.xml [new file with mode: 0644]
mcs/docs/ecma334/20.2.2.xml [new file with mode: 0644]
mcs/docs/ecma334/20.2.3.xml [new file with mode: 0644]
mcs/docs/ecma334/20.2.4.xml [new file with mode: 0644]
mcs/docs/ecma334/20.2.5.xml [new file with mode: 0644]
mcs/docs/ecma334/20.2.xml [new file with mode: 0644]
mcs/docs/ecma334/20.3.xml [new file with mode: 0644]
mcs/docs/ecma334/20.4.1.xml [new file with mode: 0644]
mcs/docs/ecma334/20.4.2.xml [new file with mode: 0644]
mcs/docs/ecma334/20.4.3.xml [new file with mode: 0644]
mcs/docs/ecma334/20.4.4.xml [new file with mode: 0644]
mcs/docs/ecma334/20.4.5.xml [new file with mode: 0644]
mcs/docs/ecma334/20.4.xml [new file with mode: 0644]
mcs/docs/ecma334/20.xml [new file with mode: 0644]
mcs/docs/ecma334/21.1.xml [new file with mode: 0644]
mcs/docs/ecma334/21.2.xml [new file with mode: 0644]
mcs/docs/ecma334/21.3.xml [new file with mode: 0644]
mcs/docs/ecma334/21.4.xml [new file with mode: 0644]
mcs/docs/ecma334/21.xml [new file with mode: 0644]
mcs/docs/ecma334/22.1.xml [new file with mode: 0644]
mcs/docs/ecma334/22.2.xml [new file with mode: 0644]
mcs/docs/ecma334/22.3.xml [new file with mode: 0644]
mcs/docs/ecma334/22.xml [new file with mode: 0644]
mcs/docs/ecma334/23.1.xml [new file with mode: 0644]
mcs/docs/ecma334/23.2.xml [new file with mode: 0644]
mcs/docs/ecma334/23.3.xml [new file with mode: 0644]
mcs/docs/ecma334/23.4.xml [new file with mode: 0644]
mcs/docs/ecma334/23.xml [new file with mode: 0644]
mcs/docs/ecma334/24.1.1.xml [new file with mode: 0644]
mcs/docs/ecma334/24.1.2.xml [new file with mode: 0644]
mcs/docs/ecma334/24.1.3.xml [new file with mode: 0644]
mcs/docs/ecma334/24.1.xml [new file with mode: 0644]
mcs/docs/ecma334/24.2.xml [new file with mode: 0644]
mcs/docs/ecma334/24.3.1.xml [new file with mode: 0644]
mcs/docs/ecma334/24.3.2.xml [new file with mode: 0644]
mcs/docs/ecma334/24.3.xml [new file with mode: 0644]
mcs/docs/ecma334/24.4.1.xml [new file with mode: 0644]
mcs/docs/ecma334/24.4.2.xml [new file with mode: 0644]
mcs/docs/ecma334/24.4.3.xml [new file with mode: 0644]
mcs/docs/ecma334/24.4.xml [new file with mode: 0644]
mcs/docs/ecma334/24.xml [new file with mode: 0644]
mcs/docs/ecma334/25.1.xml [new file with mode: 0644]
mcs/docs/ecma334/25.2.xml [new file with mode: 0644]
mcs/docs/ecma334/25.3.xml [new file with mode: 0644]
mcs/docs/ecma334/25.4.xml [new file with mode: 0644]
mcs/docs/ecma334/25.5.1.xml [new file with mode: 0644]
mcs/docs/ecma334/25.5.2.xml [new file with mode: 0644]
mcs/docs/ecma334/25.5.3.xml [new file with mode: 0644]
mcs/docs/ecma334/25.5.4.xml [new file with mode: 0644]
mcs/docs/ecma334/25.5.5.xml [new file with mode: 0644]
mcs/docs/ecma334/25.5.6.xml [new file with mode: 0644]
mcs/docs/ecma334/25.5.7.xml [new file with mode: 0644]
mcs/docs/ecma334/25.5.8.xml [new file with mode: 0644]
mcs/docs/ecma334/25.5.xml [new file with mode: 0644]
mcs/docs/ecma334/25.6.xml [new file with mode: 0644]
mcs/docs/ecma334/25.7.xml [new file with mode: 0644]
mcs/docs/ecma334/25.8.xml [new file with mode: 0644]
mcs/docs/ecma334/25.xml [new file with mode: 0644]
mcs/docs/ecma334/3.xml [new file with mode: 0644]
mcs/docs/ecma334/4.xml [new file with mode: 0644]
mcs/docs/ecma334/5.xml [new file with mode: 0644]
mcs/docs/ecma334/6.xml [new file with mode: 0644]
mcs/docs/ecma334/7.xml [new file with mode: 0644]
mcs/docs/ecma334/8.1.xml [new file with mode: 0644]
mcs/docs/ecma334/8.10.xml [new file with mode: 0644]
mcs/docs/ecma334/8.11.xml [new file with mode: 0644]
mcs/docs/ecma334/8.12.xml [new file with mode: 0644]
mcs/docs/ecma334/8.13.xml [new file with mode: 0644]
mcs/docs/ecma334/8.14.xml [new file with mode: 0644]
mcs/docs/ecma334/8.2.1.xml [new file with mode: 0644]
mcs/docs/ecma334/8.2.2.xml [new file with mode: 0644]
mcs/docs/ecma334/8.2.3.xml [new file with mode: 0644]
mcs/docs/ecma334/8.2.4.xml [new file with mode: 0644]
mcs/docs/ecma334/8.2.xml [new file with mode: 0644]
mcs/docs/ecma334/8.3.xml [new file with mode: 0644]
mcs/docs/ecma334/8.4.xml [new file with mode: 0644]
mcs/docs/ecma334/8.5.xml [new file with mode: 0644]
mcs/docs/ecma334/8.6.xml [new file with mode: 0644]
mcs/docs/ecma334/8.7.1.xml [new file with mode: 0644]
mcs/docs/ecma334/8.7.10.xml [new file with mode: 0644]
mcs/docs/ecma334/8.7.11.xml [new file with mode: 0644]
mcs/docs/ecma334/8.7.2.xml [new file with mode: 0644]
mcs/docs/ecma334/8.7.3.xml [new file with mode: 0644]
mcs/docs/ecma334/8.7.4.xml [new file with mode: 0644]
mcs/docs/ecma334/8.7.5.xml [new file with mode: 0644]
mcs/docs/ecma334/8.7.6.xml [new file with mode: 0644]
mcs/docs/ecma334/8.7.7.xml [new file with mode: 0644]
mcs/docs/ecma334/8.7.8.xml [new file with mode: 0644]
mcs/docs/ecma334/8.7.9.xml [new file with mode: 0644]
mcs/docs/ecma334/8.7.xml [new file with mode: 0644]
mcs/docs/ecma334/8.8.xml [new file with mode: 0644]
mcs/docs/ecma334/8.9.xml [new file with mode: 0644]
mcs/docs/ecma334/8.xml [new file with mode: 0644]
mcs/docs/ecma334/9.1.xml [new file with mode: 0644]
mcs/docs/ecma334/9.2.1.xml [new file with mode: 0644]
mcs/docs/ecma334/9.2.2.xml [new file with mode: 0644]
mcs/docs/ecma334/9.2.xml [new file with mode: 0644]
mcs/docs/ecma334/9.3.1.xml [new file with mode: 0644]
mcs/docs/ecma334/9.3.2.xml [new file with mode: 0644]
mcs/docs/ecma334/9.3.3.xml [new file with mode: 0644]
mcs/docs/ecma334/9.3.xml [new file with mode: 0644]
mcs/docs/ecma334/9.4.1.xml [new file with mode: 0644]
mcs/docs/ecma334/9.4.2.xml [new file with mode: 0644]
mcs/docs/ecma334/9.4.3.xml [new file with mode: 0644]
mcs/docs/ecma334/9.4.4.1.xml [new file with mode: 0644]
mcs/docs/ecma334/9.4.4.2.xml [new file with mode: 0644]
mcs/docs/ecma334/9.4.4.3.xml [new file with mode: 0644]
mcs/docs/ecma334/9.4.4.4.xml [new file with mode: 0644]
mcs/docs/ecma334/9.4.4.5.xml [new file with mode: 0644]
mcs/docs/ecma334/9.4.4.6.xml [new file with mode: 0644]
mcs/docs/ecma334/9.4.4.xml [new file with mode: 0644]
mcs/docs/ecma334/9.4.5.xml [new file with mode: 0644]
mcs/docs/ecma334/9.4.xml [new file with mode: 0644]
mcs/docs/ecma334/9.5.1.xml [new file with mode: 0644]
mcs/docs/ecma334/9.5.2.xml [new file with mode: 0644]
mcs/docs/ecma334/9.5.3.xml [new file with mode: 0644]
mcs/docs/ecma334/9.5.4.xml [new file with mode: 0644]
mcs/docs/ecma334/9.5.5.xml [new file with mode: 0644]
mcs/docs/ecma334/9.5.6.xml [new file with mode: 0644]
mcs/docs/ecma334/9.5.7.xml [new file with mode: 0644]
mcs/docs/ecma334/9.5.xml [new file with mode: 0644]
mcs/docs/ecma334/9.xml [new file with mode: 0644]
mcs/docs/ecma334/gentoc.pl [new file with mode: 0644]
mcs/docs/ecma334/toc.xml [new file with mode: 0644]

diff --git a/mcs/docs/ecma334/1.xml b/mcs/docs/ecma334/1.xml
new file mode 100644 (file)
index 0000000..62bfe39
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<clause number="1" title="Scope" informative="true">
+  <paragraph>This clause is informative. </paragraph>
+  <paragraph>This ECMA Standard specifies the form and establishes the interpretation of programs written in the C# programming language. It specifies <list><list_item> The representation of C# programs; </list_item><list_item> The syntax and constraints of the C# language; </list_item><list_item> The semantic rules for interpreting C# programs; </list_item><list_item> The restrictions and limits imposed by a conforming implementation of C#. </list_item></list></paragraph>
+  <paragraph>This ECMA Standard does not specify <list><list_item> The mechanism by which C# programs are transformed for use by a data-processing system; </list_item><list_item> The mechanism by which C# applications are invoked for use by a data-processing system; </list_item><list_item> The mechanism by which input data are transformed for use by a C# application; </list_item><list_item> The mechanism by which output data are transformed after being produced by a C# application; </list_item><list_item> The size or complexity of a program and its data that will exceed the capacity of any specific  data-processing system or the capacity of a particular processor; </list_item><list_item> All minimal requirements of a data-processing system that is capable of supporting a conforming implementation. </list_item></list></paragraph>
+  <paragraph>End of informative text. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/10.1.xml b/mcs/docs/ecma334/10.1.xml
new file mode 100644 (file)
index 0000000..59c62ed
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<clause number="10.1" title="Application startup">
+  <paragraph>Application startup occurs when the execution environment calls a designated method, which is referred to as the application's entry point. This entry point method is always named Main, and shall have one of the following signatures: <code_example><![CDATA[
+static void Main() {...}  
+static void Main(string[] args) {...}  
+static int Main() {...}  
+static int Main(string[] args) {...}  
+]]></code_example></paragraph>
+  <paragraph>As shown, the entry point may optionally return an <keyword>int</keyword> value. This return value is used in application termination (<hyperlink>10.2</hyperlink>). </paragraph>
+  <paragraph>The entry point may optionally have one formal parameter, and this formal parameter may have any name. If such a parameter is declared, it must obey the following constraints: <list><list_item> The implementation shall ensure that the value of this parameter is not null. </list_item><list_item> Let args be the name of the parameter. If the length of the array designated by args is greater than zero, the array members args[0] through args[args.Length-1], inclusive, must refer to strings, called application parameters, which are given implementation-defined values by the host environment prior to application startup. The intent is to supply to the application information determined prior to application startup from elsewhere in the hosted environment. If the host environment is not capable of supplying strings with letters in both uppercase and lowercase, the implementation shall ensure that the strings are received in lowercase. <note>[Note: On systems supporting a command line, application parameters correspond to what are generally known as command-line arguments. end note]</note> </list_item></list></paragraph>
+  <paragraph>Since C# supports method overloading, a class or struct may contain multiple definitions of some method, provided each has a different signature. However, within a single program, no class or struct shall contain more than one method called Main whose definition qualifies it to be used as an application entry point. Other overloaded versions of Main are permitted, however, provided they have more than one parameter, or their only parameter is other than type string[]. </paragraph>
+  <paragraph>An application can be made up of multiple classes or structs. It is possible for more than one of these classes or structs to contain a method called Main whose definition qualifies it to be used as an application entry point. In such cases, one of these Main methods must be chosen as the entry point so that application startup can occur. This choice of an entry point is beyond the scope of this specification-no mechanism for specifying or determining an entry point is provided. </paragraph>
+  <paragraph>In C#, every method must be defined as a member of a class or struct. Ordinarily, the declared accessibility (<hyperlink>10.5.1</hyperlink>) of a method is determined by the access modifiers (<hyperlink>17.2.3</hyperlink>) specified in its declaration, and similarly the declared accessibility of a type is determined by the access modifiers specified in its declaration. In order for a given method of a given type to be callable, both the type and the member must be accessible. However, the application entry point is a special case. Specifically, the execution environment can access the application's entry point regardless of its declared accessibility and regardless of the declared accessibility of its enclosing type declarations. </paragraph>
+  <paragraph>In all other respects, entry point methods behave like those that are not entry points. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/10.10.xml b/mcs/docs/ecma334/10.10.xml
new file mode 100644 (file)
index 0000000..6850dd8
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="10.10" title="Execution order">
+  <paragraph>Execution shall proceed such that the side effects of each executing thread are preserved at critical execution points. A side effect is defined as a read or write of a volatile field, a write to a non-volatile variable, a write to an external resource, and the throwing of an exception. The critical execution points at which the order of these side effects must be preserved are references to volatile fields (<hyperlink>17.4.3</hyperlink>), lock statements (<hyperlink>15.12</hyperlink>), and thread creation and termination. An implementation is free to change the order of execution of a C# program, subject to the following constraints: <list><list_item> Data dependence is preserved within a thread of execution. That is, the value of each variable is computed as if all statements in the thread were executed in original program order. </list_item><list_item> Initialization ordering rules are preserved (<hyperlink>17.4.4</hyperlink> and <hyperlink>17.4.5</hyperlink>). </list_item><list_item> The ordering of side effects is preserved with respect to volatile reads and writes (<hyperlink>17.4.3</hyperlink>). Additionally, an implementation need not evaluate part of an expression if it can deduce that that expression's value is not used and that no needed side effects are produced (including any caused by calling a method or accessing a volatile field). When program execution is interrupted by an asynchronous event (such as an exception thrown by another thread), it is not guaranteed that the observable side effects are visible in the original program order. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/10.2.xml b/mcs/docs/ecma334/10.2.xml
new file mode 100644 (file)
index 0000000..292f5af
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<clause number="10.2" title="Application termination">
+  <paragraph>Application termination returns control to the execution environment. </paragraph>
+  <paragraph>If the return type of the application's entry point method is <keyword>int</keyword>, the value returned serves as the application's termination status code. The purpose of this code is to allow communication of success or failure to the execution environment. </paragraph>
+  <paragraph>If the return type of the entry point method is <keyword>void</keyword>, reaching the right brace (<symbol>}</symbol>) which terminates that method, or executing a return statement that has no expression, results in a termination status code of 0. </paragraph>
+  <paragraph>Prior to an application's termination, destructors for all of its objects that have not yet been garbage collected are called, unless such cleanup has been suppressed (by a call to the library method GC.SuppressFinalize, for example). </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/10.3.xml b/mcs/docs/ecma334/10.3.xml
new file mode 100644 (file)
index 0000000..7f2c596
--- /dev/null
@@ -0,0 +1,61 @@
+<?xml version="1.0"?>
+<clause number="10.3" title="Declarations">
+  <paragraph>Declarations in a C# program define the constituent elements of the program. C# programs are organized using namespaces (<hyperlink>16</hyperlink>), which can contain type declarations and nested namespace declarations. Type declarations (<hyperlink>16.5</hyperlink>) are used to define classes (<hyperlink>17</hyperlink>), structs (<hyperlink>18</hyperlink>), interfaces (<hyperlink>20</hyperlink>), enums (<hyperlink>21</hyperlink>), and delegates (<hyperlink>22</hyperlink>). The kinds of members permitted in a type declaration depend on the form of the type declaration. For instance, class declarations can contain declarations for constants (<hyperlink>17.3</hyperlink>), fields (<hyperlink>17.4</hyperlink>), methods (<hyperlink>17.5</hyperlink>), properties (<hyperlink>17.6</hyperlink>), events (<hyperlink>17.7</hyperlink>), indexers (<hyperlink>17.8</hyperlink>), operators (<hyperlink>17.9</hyperlink>), instance constructors (<hyperlink>17.10</hyperlink>), destructors (<hyperlink>17.12</hyperlink>), static constructors (<hyperlink>17.11</hyperlink>), and nested types. </paragraph>
+  <paragraph>A declaration defines a name in the declaration space to which the declaration belongs. Except for overloaded members (<hyperlink>10.6</hyperlink>), it is a compile-time error to have two or more declarations that introduce members with the same name in a declaration space. However, no diagnostic is required if the declaration space is a namespace for the global declaration space and the conflicting declarations are in separate programs. It is never possible for a declaration space to contain different kinds of members with the same name. <example>[Example: For example, a declaration space can never contain a field and a method by the same name. end example]</example> </paragraph>
+  <paragraph>There are several different types of declaration spaces, as described in the following. <list><list_item> Within all source files of a program, <non_terminal where="16.4">namespace-member-declaration</non_terminal>s with no enclosing  <non_terminal where="16.2">namespace-declaration</non_terminal> are members of a single combined declaration space called the global declaration space. </list_item><list_item> Within all source files of a program, <non_terminal where="16.4">namespace-member-declaration</non_terminal>s within <non_terminal where="16.2">namespace-declaration</non_terminal>s that have the same fully qualified namespace name are members of a single combined declaration space. </list_item><list_item> Each class, struct, or interface declaration creates a new declaration space. Names are introduced into this declaration space through <non_terminal where="17.2">class-member-declaration</non_terminal>s, <non_terminal where="18.2">struct-member-declaration</non_terminal>s, or  <non_terminal where="20.2">interface-member-declaration</non_terminal>s. Except for overloaded instance constructor declarations and static constructor declarations, a class or struct member declaration cannot introduce a member by the same name as the class or struct. A class, struct, or interface permits the declaration of overloaded methods and indexers. Furthermore, a class or struct permits the declaration of overloaded instance constructors and operators. <example>[Example: For example, a class, struct, or interface may contain multiple method declarations with the same name, provided these method declarations differ in their signature (<hyperlink>10.6</hyperlink>). end example]</example> Note that base classes do not contribute to the declaration space of a class, and base interfaces do not contribute to the declaration space of an interface. Thus, a derived class or interface is allowed to declare a member with the same name as an inherited member. Such a member is said to hide the inherited member. </list_item><list_item> Each enumeration declaration creates a new declaration space. Names are introduced into this declaration space through <non_terminal where="21.3">enum-member-declaration</non_terminal>s. </list_item><list_item> Each block or <non_terminal where="15.7.2">switch-block</non_terminal> creates a different declaration space for local variables. Names are introduced into this declaration space through <non_terminal where="15.5.1">local-variable-declaration</non_terminal>s. If a block is the body of an instance constructor, method, or operator declaration, or a get or set accessor for an indexer declaration, the parameters declared in such a declaration are members of the block's local variable declaration space. The local variable declaration space of a block includes any nested blocks. Thus, within a nested block it is not possible to declare a local variable with the same name as a local variable in an enclosing block. </list_item><list_item> Each block or <non_terminal where="15.7.2">switch-block</non_terminal> creates a separate declaration space for labels. Names are introduced into this declaration space through <non_terminal where="15.4">labeled-statement</non_terminal>s, and the names are referenced through <non_terminal where="15.9.3">goto-statement</non_terminal>s. The label declaration space of a block includes any nested blocks. Thus, within a nested block it is not possible to declare a label with the same name as a label in an enclosing block. </list_item></list></paragraph>
+  <paragraph>The textual order in which names are declared is generally of no significance. In particular, textual order is not significant for the declaration and use of namespaces, constants, methods, properties, events, indexers, operators, instance constructors, destructors, static constructors, and types. Declaration order is significant in the following ways: <list><list_item> Declaration order for field declarations and local variable declarations determines the order in which their initializers (if any) are executed. </list_item><list_item> Local variables must be defined before they are used (<hyperlink>10.7</hyperlink>). </list_item><list_item> Declaration order for enum member declarations (<hyperlink>21.3</hyperlink>) is significant when <non_terminal where="14.15">constant-expression</non_terminal> values are omitted. </list_item></list></paragraph>
+  <paragraph>
+    <example>[Example: The declaration space of a namespace is &quot;open ended&quot;, and two namespace declarations with the same fully qualified name contribute to the same declaration space. For example <code_example><![CDATA[
+namespace Megacorp.Data  
+{  
+   class Customer  
+   {  
+      ...  
+   }  
+}  
+namespace Megacorp.Data  
+{  
+   class Order  
+   {  
+      ...  
+   }  
+}  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>The two namespace declarations above contribute to the same declaration space, in this case declaring two classes with the fully qualified names Megacorp.Data.Customer and Megacorp.Data.Order. Because the two declarations contribute to the same declaration space, it would have caused a compile-time error if each contained a declaration of a class with the same name. end example]</example>
+  </paragraph>
+  <paragraph>
+    <note>[Note: As specified above, the declaration space of a block includes any nested blocks. Thus, in the following example, the F and G methods result in a compile-time error because the name i is declared in the outer block and cannot be redeclared in the inner block. However, the H and I methods are valid since the two i's are declared in separate non-nested blocks. <code_example><![CDATA[
+class A  
+{  
+   void F() {  
+      int i = 0;  
+      if (true) {  
+         int i = 1;        
+      }  
+   }  
+   void G() {  
+      if (true) {  
+         int i = 0;  
+      }  
+      int i = 1;          
+   }  
+   void H() {  
+      if (true) {  
+         int i = 0;  
+      }  
+      if (true) {  
+         int i = 1;  
+      }  
+   }  
+   void I() {  
+      for (int i = 0; i < 10; i++)  
+      H();  
+      for (int i = 0; i < 10; i++)  
+      H();  
+   }  
+}  
+]]></code_example>end note]</note>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/10.4.1.xml b/mcs/docs/ecma334/10.4.1.xml
new file mode 100644 (file)
index 0000000..869664f
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="10.4.1" title="Namespace members">
+  <paragraph>Namespaces and types that have no enclosing namespace are members of the global namespace. This corresponds directly to the names declared in the global declaration space. </paragraph>
+  <paragraph>Namespaces and types declared within a namespace are members of that namespace. This corresponds directly to the names declared in the declaration space of the namespace. </paragraph>
+  <paragraph>Namespaces have no access restrictions. It is not possible to declare private, protected, or internal namespaces, and namespace names are always publicly accessible. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/10.4.2.xml b/mcs/docs/ecma334/10.4.2.xml
new file mode 100644 (file)
index 0000000..9ce3752
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="10.4.2" title="Struct members">
+  <paragraph>The members of a struct are the members declared in the struct and the members inherited from the struct's direct base class System.ValueType and the indirect base class object. </paragraph>
+  <paragraph>The members of a simple type correspond directly to the members of the struct type aliased by the simple type: <list><list_item> The members of <keyword>sbyte</keyword> are the members of the System.SByte struct. </list_item><list_item> The members of <keyword>byte</keyword> are the members of the System.Byte struct. </list_item><list_item> The members of <keyword>short</keyword> are the members of the System.Int16 struct. </list_item><list_item> The members of <keyword>ushort</keyword> are the members of the System.UInt16 struct. </list_item><list_item> The members of <keyword>int</keyword> are the members of the System.Int32 struct. </list_item><list_item> The members of <keyword>uint</keyword> are the members of the System.UInt32 struct. </list_item><list_item> The members of <keyword>long</keyword> are the members of the System.Int64 struct. </list_item><list_item> The members of <keyword>ulong</keyword> are the members of the System.UInt64 struct. </list_item><list_item> The members of <keyword>char</keyword> are the members of the System.Char struct. </list_item><list_item> The members of <keyword>float</keyword> are the members of the System.Single struct. </list_item><list_item> The members of <keyword>double</keyword> are the members of the System.Double struct. </list_item><list_item> The members of <keyword>decimal</keyword> are the members of the System.Decimal struct. </list_item><list_item> The members of <keyword>bool</keyword> are the members of the System.Boolean struct. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/10.4.3.xml b/mcs/docs/ecma334/10.4.3.xml
new file mode 100644 (file)
index 0000000..4655a3b
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="10.4.3" title="Enumeration members">
+  <paragraph>The members of an enumeration are the constants declared in the enumeration and the members inherited from class object. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/10.4.4.xml b/mcs/docs/ecma334/10.4.4.xml
new file mode 100644 (file)
index 0000000..02d8102
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="10.4.4" title="Class members">
+  <paragraph>The members of a class are the members declared in the class and the members inherited from the base class (except for class object which has no base class). The members inherited from the base class include the constants, fields, methods, properties, events, indexers, operators, and types of the base class, but not the instance constructors, destructors, and static constructors of the base class. Base class members are inherited without regard to their accessibility. </paragraph>
+  <paragraph>A class declaration may contain declarations of constants, fields, methods, properties, events, indexers, operators, instance constructors, destructors, static constructors, and types. </paragraph>
+  <paragraph>The members of object and string correspond directly to the members of the class types they alias: <list><list_item> The members of object are the members of the System.Object class. </list_item><list_item> The members of string are the members of the System.String class. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/10.4.5.xml b/mcs/docs/ecma334/10.4.5.xml
new file mode 100644 (file)
index 0000000..580c88c
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="10.4.5" title="Interface members">
+  <paragraph>The members of an interface are the members declared in the interface and in all base interfaces of the interface, and the members inherited from class object. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/10.4.6.xml b/mcs/docs/ecma334/10.4.6.xml
new file mode 100644 (file)
index 0000000..69dd4c3
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="10.4.6" title="Array members">
+  <paragraph>The members of an array are the members inherited from class System.Array. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/10.4.7.xml b/mcs/docs/ecma334/10.4.7.xml
new file mode 100644 (file)
index 0000000..60ccba5
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="10.4.7" title="Delegate members">
+  <paragraph>The members of a delegate are the members inherited from class System.Delegate. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/10.4.xml b/mcs/docs/ecma334/10.4.xml
new file mode 100644 (file)
index 0000000..484bc6c
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="10.4" title="Members">
+  <paragraph>Namespaces and types have members. <note>[Note: The members of an entity are generally available through the use of a qualified name that starts with a reference to the entity, followed by a &quot;.&quot; token, followed by the name of the member. end note]</note> </paragraph>
+  <paragraph>Members of a type are either declared in the type or inherited from the base class of the type. When a type inherits from a base class, all members of the base class, except instance constructors, destructors, and static constructors become members of the derived type. The declared accessibility of a base class member does not control whether the member is inherited-inheritance extends to any member that isn't an instance constructor, static constructor, or destructor. However, an inherited member may not be accessible in a derived type, either because of its declared accessibility (<hyperlink>10.5.1</hyperlink>) or because it is hidden by a declaration in the type itself (<hyperlink>10.7.1.2</hyperlink>). </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/10.5.1.xml b/mcs/docs/ecma334/10.5.1.xml
new file mode 100644 (file)
index 0000000..23aaf40
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="10.5.1" title="Declared accessibility">
+  <paragraph>The declared accessibility of a member can be one of the following: <list><list_item> Public, which is selected by including a public modifier in the member declaration. The intuitive meaning of public is &quot;access not limited&quot;. </list_item><list_item> Protected, which is selected by including a protected modifier in the member declaration. The intuitive meaning of protected is &quot;access limited to the containing class or types derived from the containing class&quot;. </list_item><list_item> Internal, which is selected by including an internal modifier in the member declaration. The intuitive meaning of internal is &quot;access limited to this program&quot;. </list_item><list_item> Protected internal, which is selected by including both a protected and an internal modifier in the member declaration. The intuitive meaning of protected internal is &quot;access limited to this program or types derived from the containing class&quot;. </list_item><list_item> Private, which is selected by including a private modifier in the member declaration. The intuitive meaning of private is &quot;access limited to the containing type&quot;. </list_item></list></paragraph>
+  <paragraph>Depending on the context in which a member declaration takes place, only certain types of declared accessibility are permitted. Furthermore, when a member declaration does not include any access modifiers, the context in which the declaration takes place determines the default declared accessibility. <list><list_item> Namespaces implicitly have public declared accessibility. No access modifiers are allowed on namespace declarations. </list_item><list_item> Types declared in compilation units or namespaces can have public or internal declared accessibility and default to internal declared accessibility. </list_item><list_item> Class members can have any of the five kinds of declared accessibility and default to private declared accessibility. <note>[Note: A type declared as a member of a class can have any of the five kinds of declared accessibility, whereas a type declared as a member of a namespace can have only public or internal declared accessibility. end note]) </note></list_item><list_item> Struct members can have public, internal, or private declared accessibility and default to private declared accessibility because structs are implicitly sealed. Struct members introduced in a struct (that is, not inherited by that struct) cannot have protected or protected internal declared accessibility. <note>[Note: A type declared as a member of a struct can have public, internal, or private declared accessibility, whereas a type declared as a member of a namespace can have only public or internal declared accessibility. end note]) </note></list_item><list_item> Interface members implicitly have public declared accessibility. No access modifiers are allowed on interface member declarations. </list_item><list_item> Enumeration members implicitly have public declared accessibility. No access modifiers are allowed on enumeration member declarations. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/10.5.2.xml b/mcs/docs/ecma334/10.5.2.xml
new file mode 100644 (file)
index 0000000..f8fabac
--- /dev/null
@@ -0,0 +1,62 @@
+<?xml version="1.0"?>
+<clause number="10.5.2" title="Accessibility domains">
+  <paragraph>The accessibility domain of a member consists of the (possibly disjoint) sections of program text in which access to the member is permitted. For purposes of defining the accessibility domain of a member, a member is said to be top-level if it is not declared within a type, and a member is said to be nested if it is declared within another type. Furthermore, the text of an assembly is defined as all source text contained in all source files of that assembly, and the source text of a type is defined as all source text contained between the opening and closing &quot;{&quot; and &quot;}&quot; tokens in the <non_terminal where="17.1.3">class-body</non_terminal>, <non_terminal where="18.1.3">struct-body</non_terminal>, <non_terminal where="20.1.3">interface-body</non_terminal>, or <non_terminal where="21.1">enum-body</non_terminal> of the type (including, possibly, types that are nested within the type). </paragraph>
+  <paragraph>The accessibility domain of a predefined type (such as object, <keyword>int</keyword>, or <keyword>double</keyword>) is unlimited. </paragraph>
+  <paragraph>The accessibility domain of a top-level type T that is declared in a program P is defined as follows: <list><list_item> If the declared accessibility of T is public, the accessibility domain of T is the program text of P and any program that references P. </list_item><list_item> If the declared accessibility of T is internal, the accessibility domain of T is the program text of P. </list_item></list></paragraph>
+  <paragraph>
+    <note>[Note: From these definitions it follows that the accessibility domain of a top-level type is always at least the program text of the program in which that type is declared. end note]</note>
+  </paragraph>
+  <paragraph>The accessibility domain of a nested member M declared in a type T within a program P, is defined as follows (noting that M itself may possibly be a type): <list><list_item> If the declared accessibility of M is public, the accessibility domain of M is the accessibility domain of T. </list_item><list_item> If the declared accessibility of M is protected internal, let D be the union of the program text of P and the program text of any type derived from T, which is declared outside P. The accessibility domain of M is the intersection of the accessibility domain of T with D. </list_item><list_item> If the declared accessibility of M is protected, let D be the union of the program text of T and the program text of any type derived from T. The accessibility domain of M is the intersection of the accessibility domain of T with D. </list_item><list_item> If the declared accessibility of M is internal, the accessibility domain of M is the intersection of the accessibility domain of T with the program text of P. </list_item><list_item> If the declared accessibility of M is private, the accessibility domain of M is the program text of T. </list_item></list></paragraph>
+  <paragraph>
+    <note>[Note: From these definitions it follows that the accessibility domain of a nested member is always at least the program text of the type in which the member is declared. Furthermore, it follows that the accessibility domain of a member is never more inclusive than the accessibility domain of the type in which the member is declared. end note]</note>
+  </paragraph>
+  <paragraph>
+    <note>[Note: In intuitive terms, when a type or member M is accessed, the following steps are evaluated to ensure that the access is permitted: <list><list_item> First, if M is declared within a type (as opposed to a compilation unit or a namespace), a compile-time error occurs if that type is not accessible. </list_item><list_item> Then, if M is public, the access is permitted. </list_item><list_item> Otherwise, if M is protected internal, the access is permitted if it occurs within the program in which M is declared, or if it occurs within a class derived from the class in which M is declared and takes place through the derived class type (<hyperlink>10.5.3</hyperlink>). </list_item><list_item> Otherwise, if M is protected, the access is permitted if it occurs within the class in which M is declared, or if it occurs within a class derived from the class in which M is declared and takes place through the derived class type (<hyperlink>10.5.3</hyperlink>). </list_item><list_item> Otherwise, if M is internal, the access is permitted if it occurs within the program in which M is declared. </list_item><list_item> Otherwise, if M is private, the access is permitted if it occurs within the type in which M is declared. </list_item><list_item> Otherwise, the type or member is inaccessible, and a compile-time error occurs. end note]</list_item></list></note>
+  </paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+public class A  
+{  
+   public static int X;  
+   internal static int Y;  
+   private static int Z;  
+}  
+internal class B  
+{  
+   public static int X;  
+   internal static int Y;  
+   private static int Z;  
+   public class C  
+   {  
+      public static int X;  
+      internal static int Y;  
+      private static int Z;  
+   }  
+   private class D  
+   {  
+      public static int X;  
+      internal static int Y;  
+      private static int Z;  
+   }  
+}  
+]]></code_example>the classes and members have the following accessibility domains: <list><list_item> The accessibility domain of A and A.X is unlimited. </list_item><list_item> The accessibility domain of A.Y, B, B.X, B.Y, B.C, B.C.X, and B.C.Y is the program text of the containing program. </list_item><list_item> The accessibility domain of A.Z is the program text of A. </list_item><list_item> The accessibility domain of B.Z and B.D is the program text of B, including the program text of B.C and B.D. </list_item><list_item> The accessibility domain of B.C.Z is the program text of B.C. </list_item><list_item> The accessibility domain of B.D.X, B.D.Y, and B.D.Z is the program text of B.D. </list_item></list></example>
+  </paragraph>
+  <paragraph>
+    <example>As the example illustrates, the accessibility domain of a member is never larger than that of a containing type. For example, even though all X members have public declared accessibility, all but A.X have accessibility domains that are constrained by a containing type. end example]</example>
+  </paragraph>
+  <paragraph>As described in <hyperlink>10.4</hyperlink>, all members of a base class, except for instance constructors, destructors, and static constructors are inherited by derived types. This includes even private members of a base class. However, the accessibility domain of a private member includes only the program text of the type in which the member is declared. <example>[Example: In the example <code_example><![CDATA[
+class A  
+{  
+   int x;  
+   static void F(B b) {  
+      b.x = 1;   // Ok  
+   }  
+}  
+class B: A  
+{  
+   static void F(B b) {  
+      b.x = 1;   // Error, x not accessible  
+   }  
+}  
+]]></code_example>the B class inherits the private member x from the A class. Because the member is private, it is only accessible within the <non_terminal where="17.1.3">class-body</non_terminal> of A. Thus, the access to b.x succeeds in the A.F method, but fails in the B.F method. end example]</example> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/10.5.3.xml b/mcs/docs/ecma334/10.5.3.xml
new file mode 100644 (file)
index 0000000..91065da
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<clause number="10.5.3" title="Protected access for instance members">
+  <paragraph>When a protected instance member is accessed outside the program text of the class in which it is declared, and when a protected internal instance member is accessed outside the program text of the program in which it is declared, the access is required to take place through an instance of the derived class type in which the access occurs. Let B be a base class that declares a protected instance member M, and let D be a class that derives from B. Within the <non_terminal where="17.1.3">class-body</non_terminal> of D, access to M can take one of the following forms: <list><list_item> An unqualified <non_terminal where="10.8">type-name</non_terminal> or <non_terminal where="14.5">primary-expression</non_terminal> of the form M. </list_item><list_item> A <non_terminal where="14.5">primary-expression</non_terminal> of the form E.M, provided the type of E is D or a class derived from D. </list_item><list_item> A <non_terminal where="14.5">primary-expression</non_terminal> of the form base.M. </list_item></list></paragraph>
+  <paragraph>In addition to these forms of access, a derived class can access a protected instance constructor of a base class in a <non_terminal where="17.10">constructor-initializer</non_terminal> (<hyperlink>17.10.1</hyperlink>). </paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+public class A  
+{  
+   protected int x;  
+   static void F(A a, B b) {  
+      a.x = 1;   // Ok  
+      b.x = 1;   // Ok  
+   }  
+}  
+public class B: A  
+{  
+   static void F(A a, B b) {  
+      a.x = 1;   // Error, must access through instance of B  
+      b.x = 1;   // Ok  
+   }  
+}  
+]]></code_example>within A, it is possible to access x through instances of both A and B, since in either case the access takes place through an instance of A or a class derived from A. However, within B, it is not possible to access x through an instance of A, since A does not derive from B. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/10.5.4.xml b/mcs/docs/ecma334/10.5.4.xml
new file mode 100644 (file)
index 0000000..353517f
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<clause number="10.5.4" title="Accessibility constraints">
+  <paragraph>Several constructs in the C# language require a type to be at least as accessible as a member or another type. A type T is said to be at least as accessible as a member or type M if the accessibility domain of T is a superset of the accessibility domain of M. In other words, T is at least as accessible as M if T is accessible in all contexts in which M is accessible. </paragraph>
+  <paragraph>The following accessibility constraints exist: <list><list_item> The direct base class of a class type must be at least as accessible as the class type itself. </list_item><list_item> The explicit base interfaces of an interface type must be at least as accessible as the interface type itself. </list_item><list_item> The return type and parameter types of a delegate type must be at least as accessible as the delegate type itself. </list_item><list_item> The type of a constant must be at least as accessible as the constant itself. </list_item><list_item> The type of a field must be at least as accessible as the field itself. </list_item><list_item> The return type and parameter types of a method must be at least as accessible as the method itself. </list_item><list_item> The type of a property must be at least as accessible as the property itself. </list_item><list_item> The type of an event must be at least as accessible as the event itself. </list_item><list_item> The type and parameter types of an indexer must be at least as accessible as the indexer itself. </list_item><list_item> The return type and parameter types of an operator must be at least as accessible as the operator itself. </list_item><list_item> The parameter types of an instance constructor must be at least as accessible as the instance constructor itself. </list_item></list></paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+class A {...}  
+public class B: A {...}  
+]]></code_example>the B class results in a compile-time error because A is not at least as accessible as B. end example]</example>
+  </paragraph>
+  <paragraph>
+    <example>[Example: Likewise, in the example <code_example><![CDATA[
+class A {...}  
+public class B  
+{  
+   A F() {...}  
+   internal A G() {...}  
+   public A H() {...}  
+}  
+]]></code_example>the H method in B results in a compile-time error because the return type A is not at least as accessible as the method. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/10.5.xml b/mcs/docs/ecma334/10.5.xml
new file mode 100644 (file)
index 0000000..ee42417
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="10.5" title="Member access">
+  <paragraph>Declarations of members allow control over member access. The accessibility of a member is established by the declared accessibility (<hyperlink>10.5.1</hyperlink>) of the member combined with the accessibility of the immediately containing type, if any. </paragraph>
+  <paragraph>When access to a particular member is allowed, the member is said to be accessible. Conversely, when access to a particular member is disallowed, the member is said to be inaccessible. Access to a member is permitted when the textual location in which the access takes place is included in the accessibility domain (<hyperlink>10.5.2</hyperlink>) of the member. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/10.6.xml b/mcs/docs/ecma334/10.6.xml
new file mode 100644 (file)
index 0000000..3dbd48e
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<clause number="10.6" title="Signatures and overloading">
+  <paragraph>Methods, instance constructors, indexers, and operators are characterized by their signatures: <list><list_item> The signature of a method consists of the name of the method and the type and kind (value, reference, or output) of each of its formal parameters, considered in the order left to right. The signature of a method specifically does not include the return type, nor does it include the params modifier that may be specified for the right-most parameter. </list_item><list_item> The signature of an instance constructor consists of the type and kind (value, reference, or output) of each of its formal parameters, considered in the order left to right. The signature of an instance constructor specifically does not include the params modifier that may be specified for the right-most parameter. </list_item><list_item> The signature of an indexer consists of the type of each of its formal parameters, considered in the order left to right. The signature of an indexer specifically does not include the element type. </list_item><list_item> The signature of an operator consists of the name of the operator and the type of each of its formal parameters, considered in the order left to right. The signature of an operator specifically does not include the result type. </list_item></list></paragraph>
+  <paragraph>Signatures are the enabling mechanism for overloading of members in classes, structs, and interfaces: <list><list_item> Overloading of methods permits a class, struct, or interface to declare multiple methods with the same name, provided their signatures are unique within that class, struct, or interface. </list_item><list_item> Overloading of instance constructors permits a class or struct to declare multiple instance constructors, provided their signatures are unique within that class or struct. </list_item><list_item> Overloading of indexers permits a class, struct, or interface to declare multiple indexers, provided their signatures are unique within that class, struct, or interface. </list_item><list_item> Overloading of operators permits a class or struct to declare multiple operators with the same name, provided their signatures are unique within that class or struct. </list_item></list></paragraph>
+  <paragraph>
+    <example>[Example: The following example shows a set of overloaded method declarations along with their signatures. <code_example><![CDATA[
+interface ITest  
+{  
+   void F();              // F()  
+   void F(int x);      // F(int)  
+   void F(ref int x);     // F(ref int)  
+   void F(out int x);     // F(out int)  
+   void F(int x, int y);      // F(int, int)  
+   int F(string s);      // F(string)  
+   int F(int x);            // F(int)        error   
+   void F(string[] a);     // F(string[])  
+   void F(params string[] a);   // F(string[])   error  
+}  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>Note that any ref and out parameter modifiers (<hyperlink>17.5.1</hyperlink>) are part of a signature. Thus, F(<keyword>int</keyword>), F(ref <keyword>int</keyword>), and F(out <keyword>int</keyword>) are all unique signatures. Also, note that the return type and the params modifier are not part of a signature, so it is not possible to overload solely based on return type or on the inclusion or exclusion of the params modifier. As such, the declarations of the methods F(<keyword>int</keyword>) and F(params string[]) identified above, result in a compile-time error. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/10.7.1.1.xml b/mcs/docs/ecma334/10.7.1.1.xml
new file mode 100644 (file)
index 0000000..783a9cb
--- /dev/null
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<clause number="10.7.1.1" title="Hiding through nesting">
+  <paragraph>Name hiding through nesting can occur as a result of nesting namespaces or types within namespaces, as a result of nesting types within classes or structs, and as a result of parameter and local variable declarations. </paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+class A  
+{  
+   int i = 0;  
+   void F() {  
+      int i = 1;  
+   }  
+   void G() {  
+      i = 1;  
+   }  
+}  
+]]></code_example>within the F method, the instance variable i is hidden by the local variable i, but within the G method, i still refers to the instance variable. end example]</example>
+  </paragraph>
+  <paragraph>When a name in an inner scope hides a name in an outer scope, it hides all overloaded occurrences of that name. <example>[Example: In the example <code_example><![CDATA[
+class Outer  
+{  
+   static void F(int i) {}  
+   static void F(string s) {}  
+   class Inner  
+   {  
+      void G() {  
+         F(1);    // Invokes Outer.Inner.F  
+         F("Hello");  // Error  
+      }  
+      static void F(long l) {}  
+   }  
+}  
+]]></code_example>the call F(1) invokes the F declared in Inner because all outer occurrences of F are hidden by the inner declaration. For the same reason, the call F(&quot;Hello&quot;) results in a compile-time error. end example]</example> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/10.7.1.2.xml b/mcs/docs/ecma334/10.7.1.2.xml
new file mode 100644 (file)
index 0000000..94b1e4f
--- /dev/null
@@ -0,0 +1,48 @@
+<?xml version="1.0"?>
+<clause number="10.7.1.2" title="Hiding through inheritance">
+  <paragraph>Name hiding through inheritance occurs when classes or structs redeclare names that were inherited from base classes. This type of name hiding takes one of the following forms: <list><list_item> A constant, field, property, event, or type introduced in a class or struct hides all base class members with the same name. </list_item><list_item> A method introduced in a class or struct hides all non-method base class members with the same name, and all base class methods with the same signature (method name and parameter count, modifiers, and types). </list_item><list_item> An indexer introduced in a class or struct hides all base class indexers with the same signature (parameter count and types). </list_item></list></paragraph>
+  <paragraph>The rules governing operator declarations (<hyperlink>17.9</hyperlink>) make it impossible for a derived class to declare an operator with the same signature as an operator in a base class. Thus, operators never hide one another. </paragraph>
+  <paragraph>Contrary to hiding a name from an outer scope, hiding an accessible name from an inherited scope causes a warning to be reported. <example>[Example: In the example <code_example><![CDATA[
+class Base  
+{  
+   public void F() {}  
+}  
+class Derived: Base  
+{  
+   public void F() {}    // Warning, hiding an inherited name  
+}  
+]]></code_example>the declaration of F in Derived causes a warning to be reported. Hiding an inherited name is specifically not an error, since that would preclude separate evolution of base classes. For example, the above situation might have come about because a later version of Base introduced an F method that wasn't present in an earlier version of the class. Had the above situation been an error, then any change made to a base class in a separately versioned class library could potentially cause derived classes to become invalid. end example]</example> </paragraph>
+  <paragraph>The warning caused by hiding an inherited name can be eliminated through use of the new modifier: <example>[Example: <code_example><![CDATA[
+class Base  
+{  
+   public void F() {}  
+}  
+class Derived: Base  
+{  
+   new public void F() {}  
+}  
+]]></code_example></example></paragraph>
+  <paragraph>
+    <example>The new modifier indicates that the F in Derived is &quot;new&quot;, and that it is indeed intended to hide the inherited member. end example]</example>
+  </paragraph>
+  <paragraph>A declaration of a new member hides an inherited member only within the scope of the new member. </paragraph>
+  <paragraph>
+    <example>[Example: <code_example><![CDATA[
+class Base  
+{  
+   public static void F() {}  
+}  
+class Derived: Base  
+{  
+   new private static void F() {}  // Hides Base.F in Derived only  
+}  
+class MoreDerived: Derived  
+{  
+   static void G() { F(); }      // Invokes Base.F  
+}  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>In the example above, the declaration of F in Derived hides the F that was inherited from Base, but since the new F in Derived has private access, its scope does not extend to MoreDerived. Thus, the call F() in MoreDerived.G is valid and will invoke Base.F. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/10.7.1.xml b/mcs/docs/ecma334/10.7.1.xml
new file mode 100644 (file)
index 0000000..2382b76
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="10.7.1" title="Name hiding">
+  <paragraph>The scope of an entity typically encompasses more program text than the declaration space of the entity. In particular, the scope of an entity may include declarations that introduce new declaration spaces containing entities of the same name. Such declarations cause the original entity to become hidden. Conversely, an entity is said to be visible when it is not hidden. </paragraph>
+  <paragraph>Name hiding occurs when scopes overlap through nesting and when scopes overlap through inheritance. The characteristics of the two types of hiding are described in the following sections. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/10.7.xml b/mcs/docs/ecma334/10.7.xml
new file mode 100644 (file)
index 0000000..cd237fa
--- /dev/null
@@ -0,0 +1,55 @@
+<?xml version="1.0"?>
+<clause number="10.7" title="Scopes">
+  <paragraph>The scope of a name is the region of program text within which it is possible to refer to the entity declared by the name without qualification of the name. Scopes can be nested, and an inner scope may redeclare the meaning of a name from an outer scope. <note>[Note: This does not, however, remove the restriction imposed by <hyperlink>10.3</hyperlink> that within a nested block it is not possible to declare a local variable with the same name as a local variable in an enclosing block. end note]</note> The name from the outer scope is then said to be hidden in the region of program text covered by the inner scope, and access to the outer name is only possible by qualifying the name. <list><list_item> The scope of a namespace member declared by a <non_terminal where="16.4">namespace-member-declaration</non_terminal> (<hyperlink>16.4</hyperlink>) with no enclosing <non_terminal where="16.2">namespace-declaration</non_terminal> is the entire program text. </list_item><list_item> The scope of a namespace member declared by a <non_terminal where="16.4">namespace-member-declaration</non_terminal> within a  <non_terminal where="16.2">namespace-declaration</non_terminal> whose fully qualified name is N, is the <non_terminal where="16.2">namespace-body</non_terminal> of every <non_terminal where="16.2">namespace-declaration</non_terminal> whose fully qualified name is N or starts with N, followed by a period. </list_item><list_item> The scope of a name defined or imported by a <non_terminal where="16.3">using-directive</non_terminal> (<hyperlink>16.3</hyperlink>) extends over the  <non_terminal where="16.4">namespace-member-declaration</non_terminal>s of the <non_terminal where="16.1">compilation-unit</non_terminal> or <non_terminal where="16.2">namespace-body</non_terminal> in which the <non_terminal where="16.3">using-directive</non_terminal> occurs. A <non_terminal where="16.3">using-directive</non_terminal> may make zero or more namespace or type names available within a particular  <non_terminal where="16.1">compilation-unit</non_terminal> or <non_terminal where="16.2">namespace-body</non_terminal>, but does not contribute any new members to the underlying declaration space. In other words, a <non_terminal where="16.3">using-directive</non_terminal> is not transitive, but, rather, affects only the <non_terminal where="16.1">compilation-unit</non_terminal> or  <non_terminal where="16.2">namespace-body</non_terminal> in which it occurs. </list_item><list_item> The scope of a member declared by a <non_terminal where="17.2">class-member-declaration</non_terminal> (<hyperlink>17.2</hyperlink>) is the <non_terminal where="17.1.3">class-body</non_terminal> in which the declaration occurs. In addition, the scope of a class member extends to the <non_terminal where="17.1.3">class-body</non_terminal> of those derived classes that are included in the accessibility domain (<hyperlink>10.5.2</hyperlink>) of the member. </list_item><list_item> The scope of a member declared by a <non_terminal where="18.2">struct-member-declaration</non_terminal> (<hyperlink>18.2</hyperlink>) is the <non_terminal where="18.1.3">struct-body</non_terminal> in which the declaration occurs. </list_item><list_item> The scope of a member declared by an <non_terminal where="21.3">enum-member-declaration</non_terminal> (<hyperlink>21.3</hyperlink>) is the <non_terminal where="21.1">enum-body</non_terminal> in which the declaration occurs. </list_item><list_item> The scope of a parameter declared in a <non_terminal where="17.5">method-declaration</non_terminal> (<hyperlink>17.5</hyperlink>) is the <non_terminal where="17.5">method-body</non_terminal> of that  <non_terminal where="17.5">method-declaration</non_terminal>. </list_item><list_item> The scope of a parameter declared in an <non_terminal where="17.8">indexer-declaration</non_terminal> (<hyperlink>17.8</hyperlink>) is the <non_terminal where="17.6.2">accessor-declarations</non_terminal> of that <non_terminal where="17.8">indexer-declaration</non_terminal>. </list_item><list_item> The scope of a parameter declared in an <non_terminal where="17.9">operator-declaration</non_terminal> (<hyperlink>17.9</hyperlink>) is the block of that  <non_terminal where="17.9">operator-declaration</non_terminal>. </list_item><list_item> The scope of a parameter declared in a <non_terminal where="17.10">constructor-declaration</non_terminal> (<hyperlink>17.10</hyperlink>) is the <non_terminal where="17.10">constructor-initializer</non_terminal> and block of that <non_terminal where="17.10">constructor-declaration</non_terminal>. </list_item><list_item> The scope of a label declared in a <non_terminal where="15.4">labeled-statement</non_terminal> (<hyperlink>15.4</hyperlink>) is the block in which the declaration occurs. </list_item><list_item> The scope of a local variable declared in a <non_terminal where="15.5.1">local-variable-declaration</non_terminal> (<hyperlink>15.5.1</hyperlink>) is the block in which the declaration occurs. </list_item><list_item> The scope of a local variable declared in a <non_terminal where="15.7.2">switch-block</non_terminal> of a switch statement (<hyperlink>15.7.2</hyperlink>) is the  <non_terminal where="15.7.2">switch-block</non_terminal>. </list_item><list_item> The scope of a local variable declared in a <non_terminal where="15.8.3">for-initializer</non_terminal> of a for statement (<hyperlink>15.8.3</hyperlink>) is the  <non_terminal where="15.8.3">for-initializer</non_terminal>, the <non_terminal where="15.8.3">for-condition</non_terminal>, the <non_terminal where="15.8.3">for-iterator</non_terminal>, and the contained statement of the for statement. </list_item><list_item> The scope of a local constant declared in a <non_terminal where="15.5.2">local-constant-declaration</non_terminal> (<hyperlink>15.5.2</hyperlink>) is the block in which the declaration occurs. It is a compile-time error to refer to a local constant in a textual position that precedes its <non_terminal where="17.3">constant-declarator</non_terminal>. </list_item></list></paragraph>
+  <paragraph>Within the scope of a namespace, class, struct, or enumeration member it is possible to refer to the member in a textual position that precedes the declaration of the member. <example>[Example: For example <code_example><![CDATA[
+class A  
+{  
+   void F() {  
+      i = 1;  
+   }  
+   int i = 0;  
+}  
+]]></code_example></example></paragraph>
+  <paragraph>
+    <example>Here, it is valid for F to refer to i before it is declared. end example]</example>
+  </paragraph>
+  <paragraph>Within the scope of a local variable, it is a compile-time error to refer to the local variable in a textual position that precedes the <non_terminal where="15.5.1">local-variable-declarator</non_terminal> of the local variable. <example>[Example: For example <code_example><![CDATA[
+class A  
+{  
+   int i = 0;  
+   void F() {  
+      i = 1;      // Error, use precedes declaration  
+      int i;  
+      i = 2;  
+   }  
+   void G() {  
+      int j = (j = 1);    // Valid  
+   }  
+   void H() {  
+      int a = 1, b = ++a;  // Valid  
+   }  
+}  
+]]></code_example></example></paragraph>
+  <paragraph>
+    <example>In the F method above, the first assignment to i specifically does not refer to the field declared in the outer scope. Rather, it refers to the local variable and it results in a compile-time error because it textually precedes the declaration of the variable. In the G method, the use of j in the initializer for the declaration of j is valid because the use does not precede the <non_terminal where="15.5.1">local-variable-declarator</non_terminal>. In the H method, a subsequent <non_terminal where="15.5.1">local-variable-declarator</non_terminal> correctly refers to a local variable declared in an earlier <non_terminal where="15.5.1">local-variable-declarator</non_terminal> within the same <non_terminal where="15.5.1">local-variable-declaration</non_terminal>. end example]</example>
+  </paragraph>
+  <paragraph>
+    <note>[Note: The scoping rules for local variables are designed to guarantee that the meaning of a name used in an expression context is always the same within a block. If the scope of a local variable were to extend only from its declaration to the end of the block, then in the example above, the first assignment would assign to the instance variable and the second assignment would assign to the local variable. In certain situations but not in the exampe above, this could lead to a compile-time error if the statements of the block were later to be rearranged.) </note>
+  </paragraph>
+  <paragraph>
+    <note>The meaning of a name within a block may differ based on the context in which the name is used. In the example <code_example><![CDATA[
+using System;  
+class A {}  
+class Test  
+{  
+   static void Main() {  
+      string A = "hello, world";  
+      string s = A;         // expression context  
+      Type t = typeof(A);       // type context  
+      Console.WriteLine(s);      // writes "hello, world"  
+      Console.WriteLine(t.ToString());  // writes "Type: A"  
+   }  
+}  
+]]></code_example>the name A is used in an expression context to refer to the local variable A and in a type context to refer to the class A. end note]</note>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/10.8.1.xml b/mcs/docs/ecma334/10.8.1.xml
new file mode 100644 (file)
index 0000000..cca5ce4
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<clause number="10.8.1" title="Fully qualified names">
+  <paragraph>Every namespace and type has a fully qualified name, which uniquely identifies the namespace or type amongst all others. The fully qualified name of a namespace or type N is determined as follows: <list><list_item> If N is a member of the global namespace, its fully qualified name is N. </list_item><list_item> Otherwise, its fully qualified name is S.N, where S is the fully qualified name of the namespace or type in which N is declared. </list_item></list></paragraph>
+  <paragraph>In other words, the fully qualified name of N is the complete hierarchical path of identifiers that lead to N, starting from the global namespace. Because every member of a namespace or type must have a unique name, it follows that the fully qualified name of a namespace or type is always unique. </paragraph>
+  <paragraph>
+    <example>[Example: The example below shows several namespace and type declarations along with their associated fully qualified names. <code_example><![CDATA[
+class A {}        // A  
+namespace X       // X  
+{  
+   class B        // X.B  
+   {  
+      class C {}   // X.B.C  
+   }  
+   namespace Y   // X.Y  
+   {  
+      class D {}   // X.Y.D  
+   }  
+}  
+namespace X.Y    // X.Y  
+{  
+   class E {}    // X.Y.E  
+}  
+]]></code_example>end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/10.8.xml b/mcs/docs/ecma334/10.8.xml
new file mode 100644 (file)
index 0000000..09da35d
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<clause number="10.8" title="Namespace and type names">
+  <paragraph>Several contexts in a C# program require a <non_terminal where="10.8">namespace-name</non_terminal> or a <non_terminal where="10.8">type-name</non_terminal> to be specified. Either form of name is written as one or more identifiers separated by &quot;.&quot; tokens. <grammar_production><name><non_terminal where="10.8">namespace-name</non_terminal></name> : <rhs><non_terminal where="10.8">namespace-or-type-name</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="10.8">type-name</non_terminal></name> : <rhs><non_terminal where="10.8">namespace-or-type-name</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="10.8">namespace-or-type-name</non_terminal></name> : <rhs><non_terminal where="9.4.2">identifier</non_terminal></rhs><rhs><non_terminal where="10.8">namespace-or-type-name</non_terminal><terminal>.</terminal><non_terminal where="9.4.2">identifier</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>A <non_terminal where="10.8">type-name</non_terminal> is a <non_terminal where="10.8">namespace-or-type-name</non_terminal> that refers to a type. Following resolution as described below, the <non_terminal where="10.8">namespace-or-type-name</non_terminal> of a <non_terminal where="10.8">type-name</non_terminal> must refer to a type, or otherwise a compile-time error occurs. </paragraph>
+  <paragraph>A <non_terminal where="10.8">namespace-name</non_terminal> is a <non_terminal where="10.8">namespace-or-type-name</non_terminal> that refers to a namespace. Following resolution as described below, the <non_terminal where="10.8">namespace-or-type-name</non_terminal> of a <non_terminal where="10.8">namespace-name</non_terminal> must refer to a namespace, or otherwise a compile-time error occurs. </paragraph>
+  <paragraph>The meaning of a <non_terminal where="10.8">namespace-or-type-name</non_terminal> is determined as follows: <list><list_item> If the <non_terminal where="10.8">namespace-or-type-name</non_terminal> consists of a single identifier: </list_item><list><list_item> If the <non_terminal where="10.8">namespace-or-type-name</non_terminal> appears within the body of a class or struct declaration, then starting with that class or struct declaration and continuing with each enclosing class or struct declaration (if any), if a member with the given name exists, is accessible, and denotes a type, then the  <non_terminal where="10.8">namespace-or-type-name</non_terminal> refers to that member. Non-type members (constants, fields, methods, properties, indexers, operators, instance constructors, destructors, and static constructors) are ignored when determining the meaning of a <non_terminal where="10.8">namespace-or-type-name</non_terminal>. </list_item><list_item> Otherwise, starting with the namespace in which the <non_terminal where="10.8">namespace-or-type-name</non_terminal> occurs, continuing with each enclosing namespace (if any), and ending with the global namespace, the following steps are evaluated until an entity is located: </list_item><list><list_item> If the namespace contains a namespace member with the given name, then the  <non_terminal where="10.8">namespace-or-type-name</non_terminal> refers to that member and, depending on the member, is classified as a namespace or a type. </list_item><list_item> Otherwise, if the namespace has a corresponding namespace declaration enclosing the location where the <non_terminal where="10.8">namespace-or-type-name</non_terminal> occurs, then: </list_item><list><list_item> If the namespace declaration contains a <non_terminal where="16.3.1">using-alias-directive</non_terminal> that associates the given name with an imported namespace or type, then the <non_terminal where="10.8">namespace-or-type-name</non_terminal> refers to that namespace or type. </list_item><list_item> Otherwise, if the namespaces imported by the <non_terminal where="16.3.2">using-namespace-directive</non_terminal>s of the namespace declaration contain exactly one type with the given name, then the <non_terminal where="10.8">namespace-or-type-name</non_terminal> refers to that type. </list_item><list_item> Otherwise, if the namespaces imported by the <non_terminal where="16.3.2">using-namespace-directive</non_terminal>s of the namespace declaration contain more than one type with the given name, then the  <non_terminal where="10.8">namespace-or-type-name</non_terminal> is ambiguous and an error occurs. </list_item></list></list><list_item> Otherwise, the <non_terminal where="10.8">namespace-or-type-name</non_terminal> is undefined and a compile-time error occurs. </list_item></list><list_item> Otherwise, the <non_terminal where="10.8">namespace-or-type-name</non_terminal> is of the form N.I, where N is a <non_terminal where="10.8">namespace-or-type-name</non_terminal> consisting of all identifiers but the rightmost one, and I is the rightmost identifier. N is first resolved as a <non_terminal where="10.8">namespace-or-type-name</non_terminal>. If the resolution of N is not successful, a compile-time error occurs. Otherwise, N.I is resolved as follows: </list_item><list><list_item> If N is a namespace and I is the name of an accessible member of that namespace, then N.I refers to that member and, depending on the member, is classified as a namespace or a type. </list_item><list_item> If N is a class or struct type and I is the name of an accessible type in N, then N.I refers to that type. </list_item><list_item> Otherwise, N.I is an invalid <non_terminal where="10.8">namespace-or-type-name</non_terminal>, and a compile-time error occurs. </list_item></list></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/10.9.xml b/mcs/docs/ecma334/10.9.xml
new file mode 100644 (file)
index 0000000..81c51b1
--- /dev/null
@@ -0,0 +1,103 @@
+<?xml version="1.0"?>
+<clause number="10.9" title="Automatic memory management">
+  <paragraph>C# employs automatic memory management, which frees developers from manually allocating and freeing the memory occupied by objects. Automatic memory management policies are implemented by a garbage collector. The memory management life cycle of an object is as follows: </paragraph>
+  <paragraph>1 When the object is created, memory is allocated for it, the constructor is run, and the object is considered live. </paragraph>
+  <paragraph>2 If the object, or any part of it, cannot be accessed by any possible continuation of execution, other than the running of destructors, the object is considered no longer in use, and it becomes eligible for destruction. <note>[Note: Implementations may choose to analyze code to determine which references to an object may be used in the future. For instance, if a local variable that is in scope is the only existing reference to an object, but that local variable is never referred to in any possible continuation of execution from the current execution point in the procedure, an implementation may (but is not required to) treat the object as no longer in use. end note]</note> </paragraph>
+  <paragraph>3 Once the object is eligible for destruction, at some unspecified later time the destructor (<hyperlink>17.12</hyperlink>) (if any) for the object is run. Unless overridden by explicit calls, the destructor for the object is run once only. </paragraph>
+  <paragraph>4 Once the destructor for an object is run, if that object, or any part of it, cannot be accessed by any possible continuation of execution, including the running of destructors, the object is considered inaccessible and the object becomes eligible for collection. </paragraph>
+  <paragraph>5 Finally, at some time after the object becomes eligible for collection, the garbage collector frees the memory associated with that object. </paragraph>
+  <paragraph>The garbage collector maintains information about object usage, and uses this information to make memory management decisions, such as where in memory to locate a newly created object, when to relocate an object, and when an object is no longer in use or inaccessible. </paragraph>
+  <paragraph>Like other languages that assume the existence of a garbage collector, C# is designed so that the garbage collector may implement a wide range of memory management policies. For instance, C# does not require that destructors be run or that objects be collected as soon as they are eligible, or that destructors be run in any particular order, or on any particular thread. </paragraph>
+  <paragraph>The behavior of the garbage collector can be controlled, to some degree, via static methods on the class System.GC. This class can be used to request a collection to occur, destructors to be run (or not run), and so forth. </paragraph>
+  <paragraph>
+    <example>[Example: Since the garbage collector is allowed wide latitude in deciding when to collect objects and run destructors, a conforming implementation may produce output that differs from that shown by the following code. The program <code_example><![CDATA[
+using System;  
+class A  
+{  
+   ~A() {  
+      Console.WriteLine("Destruct instance of A");  
+   }  
+}  
+class B  
+{  
+   object Ref;  
+   public B(object o) {  
+      Ref = o;  
+   }  
+   ~B() {  
+      Console.WriteLine("Destruct instance of B");  
+   }  
+}  
+class Test  
+{  
+   static void Main() {  
+      B b = new B(new A());  
+      b = null;  
+      GC.Collect();  
+      GC.WaitForPendingFinalizers();  
+   }  
+}  
+]]></code_example>creates an instance of class A and an instance of class B. These objects become eligible for garbage collection when the variable b is assigned the value null, since after this time it is impossible for any  user-written code to access them. The output could be either <code_example><![CDATA[
+Destruct instance of A  
+Destruct instance of B  
+]]></code_example>or <code_example><![CDATA[
+Destruct instance of B  
+Destruct instance of A  
+]]></code_example>because the language imposes no constraints on the order in which objects are garbage collected. </example>
+  </paragraph>
+  <paragraph>
+    <example>In subtle cases, the distinction between &quot;eligible for destruction&quot; and &quot;eligible for collection&quot; can be important. For example, <code_example><![CDATA[
+using System;  
+class A  
+{  
+   ~A() {  
+      Console.WriteLine("Destruct instance of A");  
+   }  
+   public void F() {  
+      Console.WriteLine("A.F");  
+      Test.RefA = this;  
+   }  
+}  
+class B  
+{  
+   public A Ref;  
+   ~B() {  
+      Console.WriteLine("Destruct instance of B");  
+      Ref.F();  
+   }  
+}  
+class Test  
+{  
+   public static A RefA;  
+   public static B RefB;  
+   static void Main() {  
+      RefB = new B();  
+      RefA = new A();  
+      RefB.Ref = RefA;  
+      RefB = null;  
+      RefA = null;  
+      // A and B now eligible for destruction  
+      GC.Collect();  
+      GC.WaitForPendingFinalizers();  
+      // B now eligible for collection, but A is not  
+      if (RefA != null)  
+      Console.WriteLine("RefA is not null");  
+   }  
+}  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>In the above program, if the garbage collector chooses to run the destructor of A before the destructor of B, then the output of this program might be: <code_example><![CDATA[
+Destruct instance of A  
+Destruct instance of B  
+A.F  
+RefA is not null  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>Note that although the instance of A was not in use and A's destructor was run, it is still possible for methods of A (in this case, F) to be called from another destructor. Also, note that running of a destructor may cause an object to become usable from the mainline program again. In this case, the running of B's destructor caused an instance of A that was previously not in use to become accessible from the live reference RefA. After the call to WaitForPendingFinalizers, the instance of B is eligible for collection, but the instance of A is not, because of the reference RefA. </example>
+  </paragraph>
+  <paragraph>
+    <example>To avoid confusion and unexpected behavior, it is generally a good idea for destructors to only perform cleanup on data stored in their object's own fields, and not to perform any actions on referenced objects or static fields. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/10.xml b/mcs/docs/ecma334/10.xml
new file mode 100644 (file)
index 0000000..f13731a
--- /dev/null
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<clause number="10" title="Basic concepts"/>
diff --git a/mcs/docs/ecma334/11.1.1.xml b/mcs/docs/ecma334/11.1.1.xml
new file mode 100644 (file)
index 0000000..95dca04
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<clause number="11.1.1" title="Default constructors">
+  <paragraph>All value types implicitly declare a public parameterless instance constructor called the default constructor. </paragraph>
+  <paragraph>The default constructor returns a zero-initialized instance known as the default value for the value type: <list><list_item> For all <non_terminal where="11.1">simple-type</non_terminal>s, the default value is the value produced by a bit pattern of all zeros: </list_item><list><list_item> For <keyword>sbyte</keyword>, <keyword>byte</keyword>, <keyword>short</keyword>, <keyword>ushort</keyword>, <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>long</keyword>, and <keyword>ulong</keyword>, the default value is 0. </list_item><list_item> For <keyword>char</keyword>, the default value is '\x0000'. </list_item><list_item> For <keyword>float</keyword>, the default value is 0.0f. </list_item><list_item> For <keyword>double</keyword>, the default value is 0.0d. </list_item><list_item> For <keyword>decimal</keyword>, the default value is 0.0m. </list_item><list_item> For <keyword>bool</keyword>, the default value is false. </list_item></list><list_item> For an <non_terminal where="11.1">enum-type</non_terminal> E, the default value is 0. </list_item><list_item> For a <non_terminal where="11.1">struct-type</non_terminal>, the default value is the value produced by setting all value type fields to their default value and all reference type fields to null. </list_item></list></paragraph>
+  <paragraph>Like any other instance constructor, the default constructor of a value type is invoked using the new operator. <note>[Note: For efficiency reasons, this requirement is not intended to actually have the implementation generate a constructor call. end note]</note> In the example below, variables i and j are both initialized to zero. <code_example><![CDATA[
+class A  
+{  
+   void F() {  
+      int i = 0;  
+      int j = new int();  
+   }  
+}  
+]]></code_example></paragraph>
+  <paragraph>Because every value type implicitly has a public parameterless instance constructor, it is not possible for a struct type to contain an explicit declaration of a parameterless constructor. A struct type is however permitted to declare parameterized instance constructors (<hyperlink>18.3.8</hyperlink>). </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/11.1.2.xml b/mcs/docs/ecma334/11.1.2.xml
new file mode 100644 (file)
index 0000000..47da427
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="11.1.2" title="Struct types">
+  <paragraph>A struct type is a value type that can declare constants, fields, methods, properties, indexers, operators, instance constructors, static constructors, and nested types. Struct types are described in <hyperlink>18</hyperlink>. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/11.1.3.xml b/mcs/docs/ecma334/11.1.3.xml
new file mode 100644 (file)
index 0000000..7def99d
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<clause number="11.1.3" title="Simple types">
+  <paragraph>C# provides a set of predefined struct types called the simple types. The simple types are identified through reserved words, but these reserved words are simply aliases for predefined struct types in the System namespace, as described in the table below. <table_line>Reserved word Aliased type </table_line>
+<table_line><keyword>sbyte</keyword> System.SByte </table_line>
+<table_line><keyword>byte</keyword> System.Byte </table_line>
+<table_line><keyword>short</keyword> System.Int16 </table_line>
+<table_line><keyword>ushort</keyword> System.UInt16 </table_line>
+<table_line><keyword>int</keyword> System.Int32 </table_line>
+<table_line><keyword>uint</keyword> System.UInt32 </table_line>
+<table_line><keyword>long</keyword> System.Int64 </table_line>
+<table_line><keyword>ulong</keyword> System.UInt64 </table_line>
+<table_line><keyword>char</keyword> System.Char </table_line>
+<table_line><keyword>float</keyword> System.Single </table_line>
+<table_line><keyword>double</keyword> System.Double </table_line>
+<table_line><keyword>bool</keyword> System.Boolean </table_line>
+<table_line><keyword>decimal</keyword> System.Decimal </table_line>
+</paragraph>
+  <paragraph>Because a simple type aliases a struct type, every simple type has members. <example>[Example: For example, <keyword>int</keyword> has the members declared in System.Int32 and the members inherited from System.Object, and the following statements are permitted: <code_example><![CDATA[
+int i = int.MaxValue;      // System.Int32.MaxValue constant  
+string s = i.ToString();    // System.Int32.ToString() instance method  
+string t = 123.ToString();   // System.Int32.ToString() instance method  
+]]></code_example>end example]</example> The simple types differ from other struct types in that they permit certain additional operations: <list><list_item> Most simple types permit values to be created by writing literals (<hyperlink>9.4.4</hyperlink>). <example>[Example: For example, 123 is a literal of type <keyword>int</keyword> and 'a' is a literal of type <keyword>char</keyword>. end example]</example> C# makes no provision for literals of struct types in general, and non-default values of other struct types are ultimately always created through instance constructors of those struct types. </list_item><list_item> When the operands of an expression are all simple type constants, the compiler evaluates the expression at compile-time. Such an expression is known as a <non_terminal where="14.15">constant-expression</non_terminal> (<hyperlink>14.15</hyperlink>). Expressions involving operators defined by other struct types are not considered to be constant expressions. </list_item><list_item> Through const declarations, it is possible to declare constants of the simple types (<hyperlink>17.3</hyperlink>). It is not possible to have constants of other struct types, but a similar effect is provided by static readonly fields. </list_item><list_item> Conversions involving simple types can participate in evaluation of conversion operators defined by other struct types, but a user-defined conversion operator can never participate in evaluation of another  user-defined operator (<hyperlink>13.4.2</hyperlink>). </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/11.1.4.xml b/mcs/docs/ecma334/11.1.4.xml
new file mode 100644 (file)
index 0000000..a350540
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<clause number="11.1.4" title="Integral types">
+  <paragraph>C# supports nine integral types: <keyword>sbyte</keyword>, <keyword>byte</keyword>, <keyword>short</keyword>, <keyword>ushort</keyword>, <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>long</keyword>, <keyword>ulong</keyword>, and <keyword>char</keyword>. The integral types have the following sizes and ranges of values: <list><list_item> The <keyword>sbyte</keyword> type represents signed 8-bit integers with values between -128 and 127. </list_item><list_item> The <keyword>byte</keyword> type represents unsigned 8-bit integers with values between 0 and 255. </list_item><list_item> The <keyword>short</keyword> type represents signed 16-bit integers with values between -32768 and 32767. </list_item><list_item> The <keyword>ushort</keyword> type represents unsigned 16-bit integers with values between 0 and 65535. </list_item><list_item> The <keyword>int</keyword> type represents signed 32-bit integers with values between -2147483648 and 2147483647. </list_item><list_item> The <keyword>uint</keyword> type represents unsigned 32-bit integers with values between 0 and 4294967295. </list_item><list_item> The <keyword>long</keyword> type represents signed 64-bit integers with values between -9223372036854775808 and 9223372036854775807. </list_item><list_item> The <keyword>ulong</keyword> type represents unsigned 64-bit integers with values between 0 and 18446744073709551615. </list_item><list_item> The <keyword>char</keyword> type represents unsigned 16-bit integers with values between 0 and 65535. The set of possible values for the <keyword>char</keyword> type corresponds to the Unicode character set. <note>[Note: Although <keyword>char</keyword> has the same representation as <keyword>ushort</keyword>, not all operations permitted on one type are permitted on the other. end note]</note> </list_item></list></paragraph>
+  <paragraph>The <non_terminal where="11.1">integral-type</non_terminal> unary and binary operators always operate with signed 32-bit precision, unsigned 32-bit precision, signed 64-bit precision, or unsigned 64-bit precision: <list><list_item> For the unary + and ~ operators, the operand is converted to type T, where T is the first of <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>long</keyword>, and <keyword>ulong</keyword> that can fully represent all possible values of the operand. The operation is then performed using the precision of type T, and the type of the result is T. </list_item><list_item> For the unary  -operator, the operand is converted to type T, where T is the first of <keyword>int</keyword> and <keyword>long</keyword> that can fully represent all possible values of the operand. The operation is then performed using the precision of type T, and the type of the result is T. The unary  -operator cannot be applied to operands of type <keyword>ulong</keyword>. </list_item><list_item> For the binary +, -, *, /, %, &amp;, ^, |, ==, !=, &gt;, &lt;, &gt;=, and &lt;= operators, the operands are converted to type T, where T is the first of <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>long</keyword>, and <keyword>ulong</keyword> that can fully represent all possible values of both operands. The operation is then performed using the precision of type T, and the type of the result is T (or <keyword>bool</keyword> for the relational operators). It is not permitted for one operand to be of type <keyword>long</keyword> and the other to be of type <keyword>ulong</keyword> with the binary operators. </list_item><list_item> For the binary &lt;&lt; and &gt;&gt; operators, the left operand is converted to type T, where T is the first of <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>long</keyword>, and <keyword>ulong</keyword> that can fully represent all possible values of the operand. The operation is then performed using the precision of type T, and the type of the result is T. </list_item></list></paragraph>
+  <paragraph>The <keyword>char</keyword> type is classified as an integral type, but it differs from the other integral types in two ways: <list><list_item> There are no implicit conversions from other types to the <keyword>char</keyword> type. In particular, even though the <keyword>sbyte</keyword>, <keyword>byte</keyword>, and <keyword>ushort</keyword> types have ranges of values that are fully representable using the <keyword>char</keyword> type, implicit conversions from <keyword>sbyte</keyword>, <keyword>byte</keyword>, or <keyword>ushort</keyword> to <keyword>char</keyword> do not exist. </list_item><list_item> Constants of the <keyword>char</keyword> type must be written as <non_terminal where="9.4.4.4">character-literal</non_terminal>s or as <non_terminal where="9.4.4.2">integer-literal</non_terminal>s in combination with a cast to type <keyword>char</keyword>. <example>[Example: For example, (<keyword>char</keyword>)10 is the same as '\x000A'. end example]</example> </list_item></list></paragraph>
+  <paragraph>The checked and unchecked operators and statements are used to control overflow checking for  <non_terminal where="11.1">integral-type</non_terminal> arithmetic operations and conversions (<hyperlink>14.5.12</hyperlink>). In a checked context, an overflow produces a compile-time error or causes an System.OverflowException to be thrown. In an unchecked context, overflows are ignored and any high-order bits that do not fit in the destination type are discarded. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/11.1.5.xml b/mcs/docs/ecma334/11.1.5.xml
new file mode 100644 (file)
index 0000000..82cb5e8
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<clause number="11.1.5" title="Floating point types">
+  <paragraph>C# supports two floating-point types: <keyword>float</keyword> and <keyword>double</keyword>. The <keyword>float</keyword> and <keyword>double</keyword> types are represented using the 32-bit single-precision and 64-bit double-precision IEEE 754 formats, which provide the following sets of values: <list><list_item> Positive zero and negative zero. In most situations, positive zero and negative zero behave identically as the simple value zero, but certain operations distinguish between the two (<hyperlink>14.7.2</hyperlink>). </list_item><list_item> Positive infinity and negative infinity. Infinities are produced by such operations as dividing a non-zero number by zero. <example>[Example: For example, 1.0 / 0.0 yields positive infinity, and -1.0 / 0.0 yields negative infinity. end example]</example> </list_item><list_item> The Not-a-Number value, often abbreviated NaN. NaNs are produced by invalid floating-point operations, such as dividing zero by zero. </list_item><list_item> The finite set of non-zero values of the form s <unicode>215</unicode> m <unicode>215</unicode> 2<super>e</super>, where s is 1 or <unicode>8722</unicode>1, and m and e are determined by the particular floating-point type: For <keyword>float</keyword>, 0 &lt; m &lt; 2<super>24</super> and <unicode>8722</unicode>149 <unicode>8804</unicode> e <unicode>8804</unicode> 104, and for <keyword>double</keyword>, 0 &lt; m &lt; 2<super>53</super> and <unicode>8722</unicode>1075 <unicode>8804</unicode> e <unicode>8804</unicode> 970. Denormalized floating-point numbers are considered valid non-zero values. </list_item></list></paragraph>
+  <paragraph>The <keyword>float</keyword> type can represent values ranging from approximately 1.5 <unicode>215</unicode> 10<super>-45</super> to 3.4 <unicode>215</unicode> 10<super>38</super> with a precision of 7 digits. </paragraph>
+  <paragraph>The <keyword>double</keyword> type can represent values ranging from approximately 5.0 <unicode>215</unicode> 10<super>-324</super> to 1.7 <unicode>215</unicode> 10<super>308</super> with a precision of 15-16 digits. </paragraph>
+  <paragraph>If one of the operands of a binary operator is of a floating-point type, then the other operand must be of an integral type or a floating-point type, and the operation is evaluated as follows: <list><list_item> If one of the operands is of an integral type, then that operand is converted to the floating-point type of the other operand. </list_item><list_item> Then, if either of the operands is of type <keyword>double</keyword>, the other operand is converted to <keyword>double</keyword>, the operation is performed using at least <keyword>double</keyword> range and precision, and the type of the result is <keyword>double</keyword> (or <keyword>bool</keyword> for the relational operators). </list_item><list_item> Otherwise, the operation is performed using at least <keyword>float</keyword> range and precision, and the type of the result is <keyword>float</keyword> (or <keyword>bool</keyword> for the relational operators). </list_item></list></paragraph>
+  <paragraph>The floating-point operators, including the assignment operators, never produce exceptions. Instead, in exceptional situations, floating-point operations produce zero, infinity, or NaN, as described below: <list><list_item> If the result of a floating-point operation is too small for the destination format, the result of the operation becomes positive zero or negative zero. </list_item><list_item> If the result of a floating-point operation is too large for the destination format, the result of the operation becomes positive infinity or negative infinity. </list_item><list_item> If a floating-point operation is invalid, the result of the operation becomes NaN. </list_item><list_item> If one or both operands of a floating-point operation is NaN, the result of the operation becomes NaN. </list_item></list></paragraph>
+  <paragraph>Floating-point operations may be performed with higher precision than the result type of the operation. <example>[Example: For example, some hardware architectures support an &quot;extended&quot; or &quot;long double&quot; floating-point type with greater range and precision than the <keyword>double</keyword> type, and implicitly perform all floating-point operations using this higher precision type. Only at excessive cost in performance can such hardware architectures be made to perform floating-point operations with less precision, and rather than require an implementation to forfeit both performance and precision, C# allows a higher precision type to be used for all floating-point operations. Other than delivering more precise results, this rarely has any measurable effects. However, in expressions of the form x * y / z, where the multiplication produces a result that is outside the <keyword>double</keyword> range, but the subsequent division brings the temporary result back into the <keyword>double</keyword> range, the fact that the expression is evaluated in a higher range format may cause a finite result to be produced instead of an infinity. end example]</example> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/11.1.6.xml b/mcs/docs/ecma334/11.1.6.xml
new file mode 100644 (file)
index 0000000..5b5265e
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<clause number="11.1.6" title="The decimal type">
+  <paragraph>The <keyword>decimal</keyword> type is a 128-bit data type suitable for financial and monetary calculations. The <keyword>decimal</keyword> type can represent values ranging from 1.0 <unicode>215</unicode> 10<super>-28</super> to approximately 7.9 <unicode>215</unicode> 10<super>28</super> with 28-29 significant digits. </paragraph>
+  <paragraph>The finite set of values of type <keyword>decimal</keyword> are of the form -1<super>s</super> <unicode>215</unicode> c <unicode>215</unicode> 10<super>-e</super>, where the sign s is 0 or 1, the coefficient c is given by 0 <unicode>8804</unicode> c &lt; 2<super>96</super>, and the scale e is such that 0 <unicode>8804</unicode> e <unicode>8804</unicode> 28. The <keyword>decimal</keyword> type does not support signed zeros, infinities, or NaN's. </paragraph>
+  <paragraph>A <keyword>decimal</keyword> is represented as a 96-bit integer scaled by a power of ten. For decimals with an absolute value less than 1.0m, the value is exact to the 28<super>th</super> <keyword>decimal</keyword> place, but no further. For decimals with an absolute value greater than or equal to 1.0m, the value is exact to 28 or 29 digits. Contrary to the <keyword>float</keyword> and <keyword>double</keyword> data types, <keyword>decimal</keyword> fractional numbers such as 0.1 can be represented exactly in the <keyword>decimal</keyword> representation. In the <keyword>float</keyword> and <keyword>double</keyword> representations, such numbers are often infinite fractions, making those representations more prone to round-off errors. </paragraph>
+  <paragraph>If one of the operands of a binary operator is of type <keyword>decimal</keyword>, then the other operand must be of an integral type or of type <keyword>decimal</keyword>. If an integral type operand is present, it is converted to <keyword>decimal</keyword> before the operation is performed. </paragraph>
+  <paragraph>The result of an operation on values of type <keyword>decimal</keyword> is that which would result from calculating an exact result (preserving scale, as defined for each operator) and then rounding to fit the representation. Results are rounded to the nearest representable value, and, when a result is equally close to two representable values, to the value that has an even number in the least significant digit position (this is known as &quot;banker's rounding&quot;). That is, results are exact to 28 or 29 digits, but to no more than 28 <keyword>decimal</keyword> places. A zero result always has a sign of 0 and a scale of 0. </paragraph>
+  <paragraph>If a <keyword>decimal</keyword> arithmetic operation produces a value that is too small for the <keyword>decimal</keyword> format after rounding, the result of the operation becomes zero. If a <keyword>decimal</keyword> arithmetic operation produces a result that is too large for the <keyword>decimal</keyword> format, a System.OverflowException is thrown. </paragraph>
+  <paragraph>The <keyword>decimal</keyword> type has greater precision but smaller range than the floating-point types. Thus, conversions from the floating-point types to <keyword>decimal</keyword> might produce overflow exceptions, and conversions from <keyword>decimal</keyword> to the floating-point types might cause loss of precision. For these reasons, no implicit conversions exist between the floating-point types and <keyword>decimal</keyword>, and without explicit casts, it is not possible to mix floating-point and <keyword>decimal</keyword> operands in the same expression. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/11.1.7.xml b/mcs/docs/ecma334/11.1.7.xml
new file mode 100644 (file)
index 0000000..2a08e4b
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<clause number="11.1.7" title="The bool type">
+  <paragraph>The <keyword>bool</keyword> type represents boolean logical quantities. The possible values of type <keyword>bool</keyword> are true and false. </paragraph>
+  <paragraph>No standard conversions exist between <keyword>bool</keyword> and other types. In particular, the <keyword>bool</keyword> type is distinct and separate from the integral types, and a <keyword>bool</keyword> value cannot be used in place of an integral value, and vice versa. </paragraph>
+  <paragraph>
+    <note>[Note: In the C and C++ languages, a zero integral or floating-point value, or a null pointer can be converted to the boolean value false, and a non-zero integral or floating-point value, or a non-null pointer can be converted to the boolean value true. In C#, such conversions are accomplished by explicitly comparing an integral or floating-point value to zero, or by explicitly comparing an object reference to null. end note]</note>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/11.1.8.xml b/mcs/docs/ecma334/11.1.8.xml
new file mode 100644 (file)
index 0000000..c74d7e3
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="11.1.8" title="Enumeration types">
+  <paragraph>An enumeration type is a distinct type with named constants. Every enumeration type has an underlying type, which must be <keyword>byte</keyword>, <keyword>sbyte</keyword>, <keyword>short</keyword>, <keyword>ushort</keyword>, <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>long</keyword> or <keyword>ulong</keyword>. Enumeration types are defined through enumeration declarations (<hyperlink>21.1</hyperlink>). </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/11.1.xml b/mcs/docs/ecma334/11.1.xml
new file mode 100644 (file)
index 0000000..ef9c378
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<clause number="11.1" title="Value types">
+  <paragraph>A value type is either a struct type or an enumeration type. C# provides a set of predefined struct types called the simple types. The simple types are identified through reserved words. <grammar_production><name><non_terminal where="11.1">value-type</non_terminal></name> : <rhs><non_terminal where="11.1">struct-type</non_terminal></rhs><rhs><non_terminal where="11.1">enum-type</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="11.1">struct-type</non_terminal></name> : <rhs><non_terminal where="10.8">type-name</non_terminal></rhs><rhs><non_terminal where="11.1">simple-type</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="11.1">simple-type</non_terminal></name> : <rhs><non_terminal where="11.1">numeric-type</non_terminal></rhs><rhs><keyword>bool</keyword></rhs></grammar_production><grammar_production><name><non_terminal where="11.1">numeric-type</non_terminal></name> : <rhs><non_terminal where="11.1">integral-type</non_terminal></rhs><rhs><non_terminal where="11.1">floating-point-type</non_terminal></rhs><rhs><keyword>decimal</keyword></rhs></grammar_production><grammar_production><name><non_terminal where="11.1">integral-type</non_terminal></name> : <rhs><keyword>sbyte</keyword></rhs><rhs><keyword>byte</keyword></rhs><rhs><keyword>short</keyword></rhs><rhs><keyword>ushort</keyword></rhs><rhs><keyword>int</keyword></rhs><rhs><keyword>uint</keyword></rhs><rhs><keyword>long</keyword></rhs><rhs><keyword>ulong</keyword></rhs><rhs><keyword>char</keyword></rhs></grammar_production><grammar_production><name><non_terminal where="11.1">floating-point-type</non_terminal></name> : <rhs><keyword>float</keyword></rhs><rhs><keyword>double</keyword></rhs></grammar_production><grammar_production><name><non_terminal where="11.1">enum-type</non_terminal></name> : <rhs><non_terminal where="10.8">type-name</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>All value types implicitly inherit from class object. It is not possible for any type to derive from a value type, and value types are thus implicitly sealed (<hyperlink>17.1.1.2</hyperlink>). </paragraph>
+  <paragraph>A variable of a value type always contains a value of that type. Unlike reference types, it is not possible for a value of a value type to be null, or to reference an object of a more derived type. </paragraph>
+  <paragraph>Assignment to a variable of a value type creates a copy of the value being assigned. This differs from assignment to a variable of a reference type, which copies the reference but not the object identified by the reference. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/11.2.1.xml b/mcs/docs/ecma334/11.2.1.xml
new file mode 100644 (file)
index 0000000..447e8ca
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="11.2.1" title="Class types">
+  <paragraph>A class type defines a data structure that contains data members (constants and fields), function members (methods, properties, events, indexers, operators, instance constructors, destructors, and static constructors), and nested types. Class types support inheritance, a mechanism whereby derived classes can extend and specialize base classes. Instances of class types are created using <non_terminal where="14.5.10.1">object-creation-expression</non_terminal>s (<hyperlink>14.5.10.1</hyperlink>). </paragraph>
+  <paragraph>Class types are described in <hyperlink>17</hyperlink>. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/11.2.2.xml b/mcs/docs/ecma334/11.2.2.xml
new file mode 100644 (file)
index 0000000..99fbb33
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="11.2.2" title="The object type">
+  <paragraph>The object class type is the ultimate base class of all other types. Every type in C# directly or indirectly derives from the object class type. </paragraph>
+  <paragraph>The keyword object is simply an alias for the predefined class System.Object. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/11.2.3.xml b/mcs/docs/ecma334/11.2.3.xml
new file mode 100644 (file)
index 0000000..1975182
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="11.2.3" title="The string type">
+  <paragraph>The string type is a sealed class type that inherits directly from object. Instances of the string class represent Unicode character strings. </paragraph>
+  <paragraph>Values of the string type can be written as string literals (<hyperlink>9.4.4</hyperlink>). </paragraph>
+  <paragraph>The keyword string is simply an alias for the predefined class System.String. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/11.2.4.xml b/mcs/docs/ecma334/11.2.4.xml
new file mode 100644 (file)
index 0000000..c662439
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="11.2.4" title="Interface types">
+  <paragraph>An interface defines a contract. A class or struct that implements an interface must adhere to its contract. An interface may inherit from multiple base interfaces, and a class or struct may implement multiple interfaces. </paragraph>
+  <paragraph>Interface types are described in <hyperlink>20</hyperlink>. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/11.2.5.xml b/mcs/docs/ecma334/11.2.5.xml
new file mode 100644 (file)
index 0000000..034fdbf
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="11.2.5" title="Array types">
+  <paragraph>An array is a data structure that contains zero or more variables which are accessed through computed indices. The variables contained in an array, also called the elements of the array, are all of the same type, and this type is called the element type of the array. </paragraph>
+  <paragraph>Array types are described in <hyperlink>19</hyperlink>. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/11.2.6.xml b/mcs/docs/ecma334/11.2.6.xml
new file mode 100644 (file)
index 0000000..df539b4
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<clause number="11.2.6" title="Delegate types">
+  <paragraph>A delegate is a data structure that refers to one or more methods, and for instance methods, it also refers to their corresponding object instances. </paragraph>
+  <paragraph>
+    <note>[Note: The closest equivalent of a delegate in C or C++ is a function pointer, but whereas a function pointer can only reference static functions, a delegate can reference both static and instance methods. In the latter case, the delegate stores not only a reference to the method's entry point, but also a reference to the object instance on which to invoke the method. end note]</note>
+  </paragraph>
+  <paragraph>Delegate types are described in <hyperlink>22</hyperlink>. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/11.2.xml b/mcs/docs/ecma334/11.2.xml
new file mode 100644 (file)
index 0000000..02833f1
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="11.2" title="Reference types">
+  <paragraph>A reference type is a class type, an interface type, an array type, or a delegate type. <grammar_production><name><non_terminal where="11.2">reference-type</non_terminal></name> : <rhs><non_terminal where="11.2">class-type</non_terminal></rhs><rhs><non_terminal where="11.2">interface-type</non_terminal></rhs><rhs><non_terminal where="19.1">array-type</non_terminal></rhs><rhs><non_terminal where="11.2">delegate-type</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="11.2">class-type</non_terminal></name> : <rhs><non_terminal where="10.8">type-name</non_terminal></rhs><rhs><keyword>object</keyword></rhs><rhs><keyword>string</keyword></rhs></grammar_production><grammar_production><name><non_terminal where="11.2">interface-type</non_terminal></name> : <rhs><non_terminal where="10.8">type-name</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="19.1">array-type</non_terminal></name> : <rhs><non_terminal where="19.1">non-array-type</non_terminal><non_terminal where="19.1">rank-specifiers</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="19.1">non-array-type</non_terminal></name> : <rhs><non_terminal where="11">type</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="19.1">rank-specifier</non_terminal>s</name> : <rhs><non_terminal where="19.1">rank-specifier</non_terminal></rhs><rhs><non_terminal where="19.1">rank-specifiers</non_terminal><non_terminal where="19.1">rank-specifier</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="19.1">rank-specifier</non_terminal></name> : <rhs><terminal>[</terminal><non_terminal where="19.1">dim-separators</non_terminal><opt/><terminal>]</terminal></rhs></grammar_production><grammar_production><name><non_terminal where="19.1">dim-separators</non_terminal></name> : <rhs><terminal>,</terminal></rhs><rhs><non_terminal where="19.1">dim-separators</non_terminal><terminal>,</terminal></rhs></grammar_production><grammar_production><name><non_terminal where="11.2">delegate-type</non_terminal></name> : <rhs><non_terminal where="10.8">type-name</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>A reference type value is a reference to an instance of the type, the latter known as an object. The special value null is compatible with all reference types and indicates the absence of an instance. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/11.3.1.xml b/mcs/docs/ecma334/11.3.1.xml
new file mode 100644 (file)
index 0000000..7162f56
--- /dev/null
@@ -0,0 +1,44 @@
+<?xml version="1.0"?>
+<clause number="11.3.1" title="Boxing conversions">
+  <paragraph>A boxing conversion permits any <non_terminal where="11.1">value-type</non_terminal> to be implicitly converted to the type object or to any <non_terminal where="11.2">interface-type</non_terminal> implemented by the <non_terminal where="11.1">value-type</non_terminal>. Boxing a value of a <non_terminal where="11.1">value-type</non_terminal> consists of allocating an object instance and copying the <non_terminal where="11.1">value-type</non_terminal> value into that instance. </paragraph>
+  <paragraph>The actual process of boxing a value of a <non_terminal where="11.1">value-type</non_terminal> is best explained by imagining the existence of a boxing class for that type. <example>[Example: For any <non_terminal where="11.1">value-type</non_terminal> T, the boxing class behaves as if it were declared as follows: <code_example><![CDATA[
+sealed class T_Box  
+{  
+   T value;  
+   public T_Box(T t) {  
+      value = t;  
+   }  
+}  
+]]></code_example></example></paragraph>
+  <paragraph>
+    <example>Boxing of a value v of type T now consists of executing the expression new T_Box(v), and returning the resulting instance as a value of type object. Thus, the statements <code_example><![CDATA[
+int i = 123;  
+object box = i;  
+]]></code_example>conceptually correspond to <code_example><![CDATA[
+int i = 123;  
+object box = new int_Box(i);  
+]]></code_example>end example]</example>
+  </paragraph>
+  <paragraph>Boxing classes like T_Box and int_Box above don't actually exist and the dynamic type of a boxed value isn't actually a class type. Instead, a boxed value of type T has the dynamic type T, and a dynamic type check using the is operator can simply reference type T. <example>[Example: For example, <code_example><![CDATA[
+int i = 123;  
+object box = i;  
+if (box is int) {  
+   Console.Write("Box contains an int");  
+}  
+]]></code_example>will output the string &quot;Box contains an int&quot; on the console. end example]</example> </paragraph>
+  <paragraph>A boxing conversion implies making a copy of the value being boxed. This is different from a conversion of a <non_terminal where="11.2">reference-type</non_terminal> to type object, in which the value continues to reference the same instance and simply is regarded as the less derived type object. <example>[Example: For example, given the declaration <code_example><![CDATA[
+struct Point  
+{  
+   public int x, y;  
+   public Point(int x, int y) {  
+      this.x = x;  
+      this.y = y;  
+   }  
+}  
+]]></code_example>the following statements <code_example><![CDATA[
+Point p = new Point(10, 10);  
+object box = p;  
+p.x = 20;  
+Console.Write(((Point)box).x);  
+]]></code_example>will output the value 10 on the console because the implicit boxing operation that occurs in the assignment of p to box causes the value of p to be copied. Had Point been declared a class instead, the value 20 would be output because p and box would reference the same instance. end example]</example> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/11.3.2.xml b/mcs/docs/ecma334/11.3.2.xml
new file mode 100644 (file)
index 0000000..9d9a300
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<clause number="11.3.2" title="Unboxing conversions">
+  <paragraph>An unboxing conversion permits an explicit conversion from type object to any <non_terminal where="11.1">value-type</non_terminal> or from any <non_terminal where="11.2">interface-type</non_terminal> to any <non_terminal where="11.1">value-type</non_terminal> that implements the <non_terminal where="11.2">interface-type</non_terminal>. An unboxing operation consists of first checking that the object instance is a boxed value of the given <non_terminal where="11.1">value-type</non_terminal>, and then copying the value out of the instance. </paragraph>
+  <paragraph>Referring to the imaginary boxing class described in the previous section, an unboxing conversion of an object box to a <non_terminal where="11.1">value-type</non_terminal> T consists of executing the expression ((T_Box)box).value. <example>[Example: Thus, the statements <code_example><![CDATA[
+object box = 123;  
+int i = (int)box;  
+]]></code_example>conceptually correspond to <code_example><![CDATA[
+object box = new int_Box(123);  
+int i = ((int_Box)box).value;  
+]]></code_example>end example]</example> </paragraph>
+  <paragraph>For an unboxing conversion to a given <non_terminal where="11.1">value-type</non_terminal> to succeed at run-time, the value of the source operand must be a reference to an object that was previously created by boxing a value of that <non_terminal where="11.1">value-type</non_terminal>. If the source operand is null or a reference to an incompatible object, a System.InvalidCastException is thrown. <table_line/>
+</paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/11.3.xml b/mcs/docs/ecma334/11.3.xml
new file mode 100644 (file)
index 0000000..27cfd93
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="11.3" title="Boxing and unboxing">
+  <paragraph>The concept of boxing and unboxing is central to C#'s type system. It provides a bridge between <non_terminal where="11.1">value-type</non_terminal>s and <non_terminal where="11.2">reference-type</non_terminal>s by permitting any value of a <non_terminal where="11.1">value-type</non_terminal> to be converted to and from type object. Boxing and unboxing enables a unified view of the type system wherein a value of any type can ultimately be treated as an object. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/11.xml b/mcs/docs/ecma334/11.xml
new file mode 100644 (file)
index 0000000..9903703
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<clause number="11" title="Types">
+  <paragraph>The types of the C# language are divided into two main categories: Value types and reference types. <grammar_production><name>type</name> : <rhs><non_terminal where="11.1">value-type</non_terminal></rhs><rhs><non_terminal where="11.2">reference-type</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>A third category of types, pointers, is available only in unsafe code. This is discussed further in <hyperlink>25.2</hyperlink>. </paragraph>
+  <paragraph>Value types differ from reference types in that variables of the value types directly contain their data, whereas variables of the reference types store references to their data, the latter being known as objects. With reference types, it is possible for two variables to reference the same object, and thus possible for operations on one variable to affect the object referenced by the other variable. With value types, the variables each have their own copy of the data, and it is not possible for operations on one to affect the other. </paragraph>
+  <paragraph>C#'s type system is unified such that a value of any type can be treated as an object. Every type in C# directly or indirectly derives from the object class type, and object is the ultimate base class of all types. Values of reference types are treated as objects simply by viewing the values as type object. Values of value types are treated as objects by performing boxing and unboxing operations (<hyperlink>11.3</hyperlink>). </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.1.1.xml b/mcs/docs/ecma334/12.1.1.xml
new file mode 100644 (file)
index 0000000..4d7cbcc
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="12.1.1" title="Static variables">
+  <paragraph>A field declared with the static modifier is called a static variable. A static variable comes into existence before execution of the static constructor (<hyperlink>17.11</hyperlink>) for its containing type, and ceases to exist when the associated application domain ceases to exist.. </paragraph>
+  <paragraph>The initial value of a static variable is the default value (<hyperlink>12.2</hyperlink>) of the variable's type. </paragraph>
+  <paragraph>For the purposes of definite assignment checking, a static variable is considered initially assigned. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.1.2.1.xml b/mcs/docs/ecma334/12.1.2.1.xml
new file mode 100644 (file)
index 0000000..71ccbbf
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="12.1.2.1" title="Instance variables in classes">
+  <paragraph>An instance variable of a class comes into existence when a new instance of that class is created, and ceases to exist when there are no references to that instance and the instance's destructor (if any) has executed. </paragraph>
+  <paragraph>The initial value of an instance variable of a class is the default value (<hyperlink>12.2</hyperlink>) of the variable's type. </paragraph>
+  <paragraph>For the purpose of definite assignment checking, an instance variable is considered initially assigned. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.1.2.2.xml b/mcs/docs/ecma334/12.1.2.2.xml
new file mode 100644 (file)
index 0000000..00c9d92
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="12.1.2.2" title="Instance variables in structs">
+  <paragraph>An instance variable of a struct has exactly the same lifetime as the struct variable to which it belongs. In other words, when a variable of a struct type comes into existence or ceases to exist, so too do the instance variables of the struct. </paragraph>
+  <paragraph>The initial assignment state of an instance variable of a struct is the same as that of the containing struct variable. In other words, when a struct variable is considered initially assigned, so too are its instance variables, and when a struct variable is considered initially unassigned, its instance variables are likewise unassigned. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.1.2.xml b/mcs/docs/ecma334/12.1.2.xml
new file mode 100644 (file)
index 0000000..c551826
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="12.1.2" title="Instance variables">
+  <paragraph>A field declared without the static modifier is called an instance variable. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.1.3.xml b/mcs/docs/ecma334/12.1.3.xml
new file mode 100644 (file)
index 0000000..e97200d
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="12.1.3" title="Array elements">
+  <paragraph>The elements of an array come into existence when an array instance is created, and cease to exist when there are no references to that array instance. </paragraph>
+  <paragraph>The initial value of each of the elements of an array is the default value (<hyperlink>12.2</hyperlink>) of the type of the array elements. </paragraph>
+  <paragraph>For the purpose of definite assignment checking, an array element is considered initially assigned. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.1.4.xml b/mcs/docs/ecma334/12.1.4.xml
new file mode 100644 (file)
index 0000000..ea3900d
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="12.1.4" title="Value parameters">
+  <paragraph>A parameter declared without a ref or out modifier is a value parameter. </paragraph>
+  <paragraph>A value parameter comes into existence upon invocation of the function member (method, instance constructor, accessor, or operator) to which the parameter belongs, and is initialized with the value of the argument given in the invocation. A value parameter ceases to exist upon return of the function member. </paragraph>
+  <paragraph>For the purpose of definite assignment checking, a value parameter is considered initially assigned. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.1.5.xml b/mcs/docs/ecma334/12.1.5.xml
new file mode 100644 (file)
index 0000000..bfc6605
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<clause number="12.1.5" title="Reference parameters">
+  <paragraph>A parameter declared with a ref modifier is a reference parameter. </paragraph>
+  <paragraph>A reference parameter does not create a new storage location. Instead, a reference parameter represents the same storage location as the variable given as the argument in the function member invocation. Thus, the value of a reference parameter is always the same as the underlying variable. </paragraph>
+  <paragraph>The following definite assignment rules apply to reference parameters. <note>[Note: The rules for output parameters are different, and are described in <hyperlink>12.1.6</hyperlink>. end note]</note> <list><list_item> A variable must be definitely assigned (<hyperlink>12.3</hyperlink>) before it can be passed as a reference parameter in a function member invocation. </list_item><list_item> Within a function member, a reference parameter is considered initially assigned. </list_item></list></paragraph>
+  <paragraph>Within an instance method or instance accessor of a struct type, the this keyword behaves exactly as a reference parameter of the struct type (<hyperlink>14.5.7</hyperlink>). </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.1.6.xml b/mcs/docs/ecma334/12.1.6.xml
new file mode 100644 (file)
index 0000000..1c0c875
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<clause number="12.1.6" title="Output parameters">
+  <paragraph>A parameter declared with an out modifier is an output parameter. </paragraph>
+  <paragraph>An output parameter does not create a new storage location. Instead, an output parameter represents the same storage location as the variable given as the argument in the function member invocation. Thus, the value of an output parameter is always the same as the underlying variable. </paragraph>
+  <paragraph>The following definite assignment rules apply to output parameters. <note>[Note: The rules for reference parameters are different, and are described in <hyperlink>12.1.5</hyperlink>. end note]</note> <list><list_item> A variable need not be definitely assigned before it can be passed as an output parameter in a function member invocation. </list_item><list_item> Following the normal completion of a function member invocation, each variable that was passed as an output parameter is considered assigned in that execution path. </list_item><list_item> Within a function member, an output parameter is considered initially unassigned. </list_item><list_item> Every output parameter of a function member must be definitely assigned (<hyperlink>12.3</hyperlink>) before the function member returns normally. </list_item></list></paragraph>
+  <paragraph>Within an instance constructor of a struct type, the this keyword behaves exactly as an output parameter of the struct type (<hyperlink>14.5.7</hyperlink>). </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.1.7.xml b/mcs/docs/ecma334/12.1.7.xml
new file mode 100644 (file)
index 0000000..9d31d7d
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<clause number="12.1.7" title="Local variables">
+  <paragraph>A local variable is declared by a <non_terminal where="15.5.1">local-variable-declaration</non_terminal>, which may occur in a block, a <non_terminal where="15.8.3">for-statement</non_terminal>, a <non_terminal where="15.7.2">switch-statement</non_terminal>, or a <non_terminal where="15.13">using-statement</non_terminal>. </paragraph>
+  <paragraph>The lifetime of a local variable is the portion of program execution during which storage is guaranteed to be reserved for it. This lifetime extends from entry into the block, <non_terminal where="15.8.3">for-statement</non_terminal>, <non_terminal where="15.7.2">switch-statement</non_terminal>, or  <non_terminal where="15.13">using-statement</non_terminal> with which it is associated, until execution of that block, <non_terminal where="15.8.3">for-statement</non_terminal>, <non_terminal where="15.7.2">switch-statement</non_terminal>, or  <non_terminal where="15.13">using-statement</non_terminal> ends in any way. (Entering an enclosed block or calling a method suspends, but does not end, execution of the current block, <non_terminal where="15.8.3">for-statement</non_terminal>, <non_terminal where="15.7.2">switch-statement</non_terminal>, or <non_terminal where="15.13">using-statement</non_terminal>.) If the parent block,  <non_terminal where="15.8.3">for-statement</non_terminal>, <non_terminal where="15.7.2">switch-statement</non_terminal>, or <non_terminal where="15.13">using-statement</non_terminal> is entered recursively, a new instance of the local variable is created each time, and its <non_terminal where="15.5.1">local-variable-initializer</non_terminal>, if any, is evaluated each time. </paragraph>
+  <paragraph>A local variable is not automatically initialized and thus has no default value. For the purpose of definite assignment checking, a local variable is considered initially unassigned. A <non_terminal where="15.5.1">local-variable-declaration</non_terminal> may include a <non_terminal where="15.5.1">local-variable-initializer</non_terminal>, in which case the variable is considered definitely assigned in its entire scope, except within the expression provided in the <non_terminal where="15.5.1">local-variable-initializer</non_terminal>. </paragraph>
+  <paragraph>Within the scope of a local variable, it is a compile-time error to refer to that local variable in a textual position that precedes its <non_terminal where="15.5.1">local-variable-declarator</non_terminal>. </paragraph>
+  <paragraph>
+    <note>[Note: The actual lifetime of a local variable is implementation-dependent. For example, a compiler might statically determine that a local variable in a block is only used for a small portion of that block. Using this analysis, the compiler could generate code that results in the variable's storage having a shorter lifetime than its containing block. </note>
+  </paragraph>
+  <paragraph>
+    <note>The storage referred to by a local reference variable is reclaimed independently of the lifetime of that local reference variable (<hyperlink>10.9</hyperlink>). end note]</note>
+  </paragraph>
+  <paragraph>A local variable is also declared by a <non_terminal where="15.8.4">foreach-statement</non_terminal> and by a <non_terminal where="15.10">specific-catch-clause</non_terminal> for a <non_terminal where="15.10">try-statement</non_terminal>. For a <non_terminal where="15.8.4">foreach-statement</non_terminal>, the local variable is an iteration variable (<hyperlink>15.8.4</hyperlink>). For a <non_terminal where="15.10">specific-catch-clause</non_terminal>, the local variable is an exception variable (<hyperlink>15.10</hyperlink>). A local variable declared by a <non_terminal where="15.8.4">foreach-statement</non_terminal> or  <non_terminal where="15.10">specific-catch-clause</non_terminal> is considered definitely assigned in its entire scope. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.1.xml b/mcs/docs/ecma334/12.1.xml
new file mode 100644 (file)
index 0000000..cd86379
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+<clause number="12.1" title="Variable categories">
+  <paragraph>C# defines seven categories of variables: static variables, instance variables, array elements, value parameters, reference parameters, output parameters, and local variables. The sections that follow describe each of these categories. </paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+class A  
+{  
+   public static int x;  
+   int y;  
+   void F(int[] v, int a, ref int b, out int c) {  
+      int i = 1;  
+      c = a + b++;  
+   }  
+}  
+]]></code_example>x is a static variable, y is an instance variable, v[0] is an array element, a is a value parameter, b is a reference parameter, c is an output parameter, and i is a local variable. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.2.xml b/mcs/docs/ecma334/12.2.xml
new file mode 100644 (file)
index 0000000..b7a2376
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<clause number="12.2" title="Default values">
+  <paragraph>The following categories of variables are automatically initialized to their default values: <list><list_item> Static variables. </list_item><list_item> Instance variables of class instances. </list_item><list_item> Array elements. </list_item></list></paragraph>
+  <paragraph>The default value of a variable depends on the type of the variable and is determined as follows: <list><list_item> For a variable of a <non_terminal where="11.1">value-type</non_terminal>, the default value is the same as the value computed by the value-type's default constructor (<hyperlink>11.1.1</hyperlink>). </list_item><list_item> For a variable of a <non_terminal where="11.2">reference-type</non_terminal>, the default value is null. </list_item></list></paragraph>
+  <paragraph>
+    <note>[Note: Initialization to default values is typically done by having the memory manager or garbage collector initialize memory to all-bits-zero before it is allocated for use. For this reason, it is convenient to use  all-bits-zero to represent the null reference. end note]</note>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.3.1.xml b/mcs/docs/ecma334/12.3.1.xml
new file mode 100644 (file)
index 0000000..2b17861
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="12.3.1" title="Initially assigned variables">
+  <paragraph>The following categories of variables are classified as initially assigned: <list><list_item> Static variables. </list_item><list_item> Instance variables of class instances. </list_item><list_item> Instance variables of initially assigned struct variables. </list_item><list_item> Array elements. </list_item><list_item> Value parameters. </list_item><list_item> Reference parameters. </list_item><list_item> Variables declared in a catch clause, a foreach statement, or a using statement. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.3.2.xml b/mcs/docs/ecma334/12.3.2.xml
new file mode 100644 (file)
index 0000000..09f7091
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="12.3.2" title="Initially unassigned variables">
+  <paragraph>The following categories of variables are classified as initially unassigned: <list><list_item> Instance variables of initially unassigned struct variables. </list_item><list_item> Output parameters, including the this variable of struct instance constructors. </list_item><list_item> Local variables, except those declared in a catch clause, a foreach statement, or a using statement. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.3.3.1.xml b/mcs/docs/ecma334/12.3.3.1.xml
new file mode 100644 (file)
index 0000000..7cf2292
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<clause number="12.3.3.1" title="General rules for statements">
+  <paragraph>
+    <list>
+      <list_item> v is not definitely assigned at the beginning of a function member body. </list_item>
+      <list_item> v is definitely assigned at the beginning of any unreachable statement. </list_item>
+      <list_item> The definite assignment state of v at the beginning of any other statement is determined by checking the definite assignment state of v on all control flow transfers that target the beginning of that statement. If (and only if) v is definitely assigned on all such control flow transfers, then v is definitely assigned at the beginning of the statement. The set of possible control flow transfers is determined in the same way as for checking statement reachability (<hyperlink>15.1</hyperlink>). </list_item>
+      <list_item> The definite assignment state of v at the end point of a block, checked, unchecked, if, while, do, for, foreach, lock, using, or switch statement is determined by checking the definite assignment state of v on all control flow transfers that target the end point of that statement. If v is definitely assigned on all such control flow transfers, then v is definitely assigned at the end point of the statement. Otherwise, v is not definitely assigned at the end point of the statement. The set of possible control flow transfers is determined in the same way as for checking statement reachability (<hyperlink>15.1</hyperlink>). </list_item>
+    </list>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.3.3.10.xml b/mcs/docs/ecma334/12.3.3.10.xml
new file mode 100644 (file)
index 0000000..5521e53
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="12.3.3.10" title="Break, continue, and goto statements">
+  <paragraph>The definite assignment state of v on the control flow transfer caused by a break, continue, or goto statement is the same as the definite assignment state of v at the beginning of the statement. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.3.3.11.xml b/mcs/docs/ecma334/12.3.3.11.xml
new file mode 100644 (file)
index 0000000..0264f48
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<clause number="12.3.3.11" title="Throw statements">
+  <paragraph>For a statement stmt of the form <code_example><![CDATA[
+throw expr ;  
+]]></code_example></paragraph>
+  <paragraph>The definite assignment state of v at the beginning of expr is the same as the definite assignment state of v at the beginning of stmt. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.3.3.12.xml b/mcs/docs/ecma334/12.3.3.12.xml
new file mode 100644 (file)
index 0000000..851f163
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="12.3.3.12" title="Return statements">
+  <paragraph>For a statement stmt of the form <code_example><![CDATA[
+return expr ;   
+]]></code_example><list><list_item> The definite assignment state of v at the beginning of expr is the same as the definite assignment state of v at the beginning of stmt. </list_item><list_item> If v is an output parameter, then it must be definitely assigned either: </list_item><list><list_item> after expr </list_item><list_item> or at the end of the finally block of a try-finally or try-catch-finally that encloses the return statement. </list_item></list></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.3.3.13.xml b/mcs/docs/ecma334/12.3.3.13.xml
new file mode 100644 (file)
index 0000000..64dc991
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<clause number="12.3.3.13" title="Try-catch statements">
+  <paragraph>For a statement stmt of the form: <code_example><![CDATA[
+try try-block   
+catch(...) catch-block-1  
+...  
+catch(...) catch-block-n  
+
+]]></code_example><list><list_item> The definite assignment state of v at the beginning of try-block is the same as the definite assignment state of v at the beginning of stmt. </list_item><list_item> The definite assignment state of v at the beginning of catch-block-i (for any i) is the same as the definite assignment state of v at the beginning of stmt. </list_item><list_item> The definite assignment state of v at the end-point of stmt is definitely assigned if (and only if) v is definitely assigned at the end-point of try-block and every catch-block-i (for every i from 1 to n). </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.3.3.14.xml b/mcs/docs/ecma334/12.3.3.14.xml
new file mode 100644 (file)
index 0000000..9fee617
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<clause number="12.3.3.14" title="Try-finally statements">
+  <paragraph>For a try statement stmt of the form: <code_example><![CDATA[
+try try-block finally finally-block  
+]]></code_example><list><list_item> The definite assignment state of v at the beginning of try-block is the same as the definite assignment state of v at the beginning of stmt. </list_item><list_item> The definite assignment state of v at the beginning of finally-block is the same as the definite assignment state of v at the beginning of stmt. </list_item><list_item> The definite assignment state of v at the end-point of stmt is definitely assigned if (and only if) either: </list_item><list><list_item> v is definitely assigned at the end-point of try-block </list_item><list_item> v is definitely assigned at the end-point of finally-block </list_item></list></list></paragraph>
+  <paragraph>If a control flow transfer (for example, a goto statement) is made that begins within try-block, and ends outside of try-block, then v is also considered definitely assigned on that control flow transfer if v is definitely assigned at the end-point of finally-block. (This is not an only if-if v is definitely assigned for another reason on this control flow transfer, then it is still considered definitely assigned.) </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.3.3.15.xml b/mcs/docs/ecma334/12.3.3.15.xml
new file mode 100644 (file)
index 0000000..1b71cde
--- /dev/null
@@ -0,0 +1,48 @@
+<?xml version="1.0"?>
+<clause number="12.3.3.15" title="Try-catch-finally statements">
+  <paragraph>Definite assignment analysis for a try-catch-finally statement of the form: <code_example><![CDATA[
+try try-block   
+catch(...) catch-block-1  
+...  
+catch(...) catch-block-n  
+finally finally-block  
+]]></code_example>is done as if the statement were a try-finally statement enclosing a try-catch statement: <code_example><![CDATA[
+try {  
+   try try-block   
+   catch(...) catch-block-1  
+   ...  
+   catch(...) catch-block-n  
+}  
+finally finally-block  
+]]></code_example></paragraph>
+  <paragraph>
+    <example>[Example: The following example demonstrates how the different blocks of a try statement (<hyperlink>15.10</hyperlink>) affect definite assignment. <code_example><![CDATA[
+class A  
+{  
+   static void F() {  
+      int i, j;  
+      try {  
+         goto LABEL:  
+         // neither i nor j definitely assigned  
+         i = 1;  
+         // i definitely assigned  
+      }  
+      catch {  
+         // neither i nor j definitely assigned  
+         i = 3;  
+         // i definitely assigned  
+      }  
+      finally {  
+         // neither i nor j definitely assigned  
+         j = 5;  
+         // j definitely assigned  
+      }  
+      // i and j definitely assigned  
+      LABEL:  
+      // j definitely assigned  
+      
+   }  
+}  
+]]></code_example>end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.3.3.16.xml b/mcs/docs/ecma334/12.3.3.16.xml
new file mode 100644 (file)
index 0000000..07db035
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="12.3.3.16" title="Foreach statements">
+  <paragraph>For a foreach statement stmt of the form: <code_example><![CDATA[
+foreach (type identifier in expr) embedded-statement  
+]]></code_example><list><list_item> The definite assignment state of v at the beginning of expr is the same as the state of v at the beginning of stmt. </list_item><list_item> The definite assignment state of v on the control flow transfer to <non_terminal where="15">embedded-statement</non_terminal> or to the end point of stmt is the same as the state of v at the end of expr. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.3.3.17.xml b/mcs/docs/ecma334/12.3.3.17.xml
new file mode 100644 (file)
index 0000000..84469f2
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="12.3.3.17" title="Using statements">
+  <paragraph>For a using statement stmt of the form: <code_example><![CDATA[
+using (resource-acquisition) embedded-statement  
+]]></code_example><list><list_item> The definite assignment state of v at the beginning of <non_terminal where="15.13">resource-acquisition</non_terminal> is the same as the state of v at the beginning of stmt. </list_item><list_item> The definite assignment state of v on the control flow transfer to <non_terminal where="15">embedded-statement</non_terminal> is the same as the state of v at the end of <non_terminal where="15.13">resource-acquisition</non_terminal>. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.3.3.18.xml b/mcs/docs/ecma334/12.3.3.18.xml
new file mode 100644 (file)
index 0000000..66bf7a6
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="12.3.3.18" title="Lock statements">
+  <paragraph>For a lock statement stmt of the form: <code_example><![CDATA[
+lock (expr) embedded-statement  
+]]></code_example><list><list_item> The definite assignment state of v at the beginning of expr is the same as the state of v at the beginning of stmt. </list_item><list_item> The definite assignment state of v on the control flow transfer to <non_terminal where="15">embedded-statement</non_terminal> is the same as the state of v at the end of expr. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.3.3.19.xml b/mcs/docs/ecma334/12.3.3.19.xml
new file mode 100644 (file)
index 0000000..1c5c5d8
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="12.3.3.19" title="General rules for simple expressions">
+  <paragraph>The following rule applies to these kinds of expressions: literals (<hyperlink>14.5.1</hyperlink>), simple names (<hyperlink>14.5.2</hyperlink>), member access expressions (<hyperlink>14.5.4</hyperlink>), non-indexed base access expressions (<hyperlink>14.5.8</hyperlink>), and typeof expressions (<hyperlink>14.5.11</hyperlink>). <list><list_item> The definite assignment state of v at the end of such an expression is the same as the definite assignment state of v at the beginning of the expression. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.3.3.2.xml b/mcs/docs/ecma334/12.3.3.2.xml
new file mode 100644 (file)
index 0000000..d48c6be
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="12.3.3.2" title="Block statements, checked, and unchecked statements">
+  <paragraph>The definite assignment state of v on the control transfer to the first statement of the statement list in the block (or to the end point of the block, if the statement list is empty) is the same as the definite assignment statement of v before the block, checked, or unchecked statement. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.3.3.20.xml b/mcs/docs/ecma334/12.3.3.20.xml
new file mode 100644 (file)
index 0000000..1f259dd
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="12.3.3.20" title="General rules for expressions with embedded expressions">
+  <paragraph>The following rules apply to these kinds of expressions: parenthesized expressions (<hyperlink>14.5.3</hyperlink>), element access expressions (<hyperlink>14.5.6</hyperlink>), base access expressions with indexing (<hyperlink>14.5.8</hyperlink>), increment and decrement expressions (<hyperlink>14.5.9</hyperlink>, <hyperlink>14.6.5</hyperlink>), cast expressions (<hyperlink>14.6.6</hyperlink>), unary +, -, ~, * expressions, binary +, -, *, /, %, &lt;&lt;, &gt;&gt;, &lt;, &lt;=, &gt;, &gt;=, ==, !=, is, as, &amp;, |, ^ expressions (<hyperlink>14.7</hyperlink>, <hyperlink>14.8</hyperlink>, <hyperlink>14.9</hyperlink>, <hyperlink>14.10</hyperlink>), compound assignment expressions (<hyperlink>14.13.2</hyperlink>), checked and unchecked expressions (<hyperlink>14.5.12</hyperlink>), array and delegate creation expressions (<hyperlink>14.5.10</hyperlink>). </paragraph>
+  <paragraph>Each of these expressions has one or more sub-expressions that are unconditionally evaluated in a fixed order. <example>[Example: For example, the binary % operator evaluates the left hand side of the operator, then the right hand side. An indexing operation evaluates the indexed expression, and then evaluates each of the index expressions, in order from left to right. end example]</example> For an expression expr, which has sub-expressions expr<sub>1</sub>, expr<sub>2</sub>, ..., expr<sub>n</sub>, evaluated in that order: <list><list_item> The definite assignment state of v at the beginning of expr<sub>1</sub> is the same as the definite assignment state at the beginning of expr. </list_item><list_item> The definite assignment state of v at the beginning of expr<sub>i</sub> (i greater than one) is the same as the definite assignment state at the end of expr<sub>i-1</sub>. </list_item><list_item> The definite assignment state of v at the end of expr is the same as the definite assignment state at the end of expr<sub>n</sub>. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.3.3.21.xml b/mcs/docs/ecma334/12.3.3.21.xml
new file mode 100644 (file)
index 0000000..61d12e3
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<clause number="12.3.3.21" title="Invocation expressions and object creation expressions">
+  <paragraph>For an invocation expression expr of the form: <code_example><![CDATA[
+primary-expression (arg1, arg2, ..., argn)  
+]]></code_example>or an object creation expression of the form: <code_example><![CDATA[
+new type (arg1, arg2, ..., argn)  
+]]></code_example><list><list_item> For an invocation expression, the definite assignment state of v before <non_terminal where="14.5">primary-expression</non_terminal> is the same as the state of v before expr. </list_item><list_item> For an invocation expression, the definite assignment state of v before arg<sub>1</sub> is the same as the state of v after <non_terminal where="14.5">primary-expression</non_terminal>. </list_item><list_item> For an object creation expression, the definite assignment state of v before arg<sub>1</sub> is the same as the state of v before expr. </list_item><list_item> For each argument arg<sub>i</sub>, the definite assignment state of v after arg<sub>i</sub> is determined by the normal expression rules, ignoring any ref or out modifiers. </list_item><list_item> For each argument arg<sub>i</sub> for any i greater than one, the definite assignment state of v before arg<sub>i</sub> is the same as the state of v after arg<sub>i-1</sub>. </list_item><list_item> If the variable v is passed as an out argument (i.e., an argument of the form &quot;out v&quot;) in any of the arguments, then the state of v after expr is definitely assigned. Otherwise; the state of v after expr is the same as the state of v after arg<sub>n</sub>. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.3.3.22.xml b/mcs/docs/ecma334/12.3.3.22.xml
new file mode 100644 (file)
index 0000000..b2dbd50
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="12.3.3.22" title="Simple assignment expressions">
+  <paragraph>For an expression expr of the form w = expr-rhs: <list><list_item> The definite assignment state of v before expr-rhs is the same as the definite assignment state of v before expr. </list_item><list_item> If w is the same variable as v, then the definite assignment state of v after expr is definitely assigned. </list_item></list></paragraph>
+  <paragraph>Otherwise, the definite assignment state of v after expr is the same as the definite assignment state of v after expr-rhs. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.3.3.23.xml b/mcs/docs/ecma334/12.3.3.23.xml
new file mode 100644 (file)
index 0000000..f783d1a
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<clause number="12.3.3.23" title="&amp;&amp; expressions">
+  <paragraph>For an expression expr of the form expr-first &amp;&amp; expr-second: <list><list_item> The definite assignment state of v before expr-first is the same as the definite assignment state of v before expr. </list_item><list_item> The definite assignment state of v before expr-second is definitely assigned if the state of v after expr-first is either definitely assigned or &quot;definitely assigned after true expression&quot;. Otherwise, it is not definitely assigned. </list_item><list_item> The definite assignment state of v after expr is determined by: </list_item><list><list_item> If the state of v after expr-first is definitely assigned, then the state of v after expr is definitely assigned. </list_item><list_item> Otherwise, if the state of v after expr-second is definitely assigned, and the state of v after expr-first is &quot;definitely assigned after false expression&quot;, then the state of v after expr is definitely assigned. </list_item><list_item> Otherwise, if the state of v after expr-second is definitely assigned or &quot;definitely assigned after true expression&quot;, then the state of v after expr is &quot;definitely assigned after true expression&quot;. </list_item><list_item> Otherwise, if the state of v after expr-first is &quot;definitely assigned after false expression&quot;, and the state of v after expr-second is &quot;definitely assigned after false expression&quot;, then the state of v after expr is &quot;definitely assigned after false expression&quot;. </list_item><list_item> Otherwise, the state of v after expr is not definitely assigned. </list_item></list></list></paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+class A  
+{  
+   static void F(int x, int y) {  
+      int i;  
+      if (x >= 0 && (i = y) >= 0) {  
+         // i definitely assigned  
+      }  
+      else {  
+         // i not definitely assigned  
+      }  
+      // i not definitely assigned  
+   }  
+}  
+]]></code_example>the variable i is considered definitely assigned in one of the embedded statements of an if statement but not in the other. In the if statement in method F, the variable i is definitely assigned in the first embedded statement because execution of the expression (i = y) always precedes execution of this embedded statement. In contrast, the variable i is not definitely assigned in the second embedded statement, since x &gt;= 0 might have tested false, resulting in the variable i's being unassigned. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.3.3.24.xml b/mcs/docs/ecma334/12.3.3.24.xml
new file mode 100644 (file)
index 0000000..06cc2de
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<clause number="12.3.3.24" title="|| expressions">
+  <paragraph>For an expression expr of the form expr-first || expr-second: <list><list_item> The definite assignment state of v before expr-first is the same as the definite assignment state of v before expr. </list_item><list_item> The definite assignment state of v before expr-second is definitely assigned if the state of v after expr-first is either definitely assigned or &quot;definitely assigned after false expression&quot;. Otherwise, it is not definitely assigned. </list_item><list_item> The definite assignment statement of v after expr is determined by: </list_item><list><list_item> If the state of v after expr-first is definitely assigned, then the state of v after expr is definitely assigned. </list_item><list_item> Otherwise, if the state of v after expr-second is definitely assigned, and the state of v after expr-first is &quot;definitely assigned after true expression&quot;, then the state of v after expr is definitely assigned. </list_item><list_item> Otherwise, if the state of v after expr-second is definitely assigned or &quot;definitely assigned after false expression&quot;, then the state of v after expr is &quot;definitely assigned after false expression&quot;. </list_item><list_item> Otherwise, if the state of v after expr-first is &quot;definitely assigned after true expression&quot;, and the state of v after expr-second is &quot;definitely assigned after true expression&quot;, then the state of v after expr is &quot;definitely assigned after true expression&quot;. </list_item><list_item> Otherwise, the state of v after expr is not definitely assigned. </list_item></list></list></paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+class A  
+{  
+   static void G(int x, int y) {  
+      int i;  
+      if (x >= 0 || (i = y) >= 0) {  
+         // i not definitely assigned  
+      }  
+      else {  
+         // i definitely assigned  
+      }  
+      // i not definitely assigned  
+   }  
+}  
+]]></code_example>the variable i is considered definitely assigned in one of the embedded statements of an if statement but not in the other. In the if statement in method G, the variable i is definitely assigned in the second embedded statement because execution of the expression (i = y) always precedes execution of this embedded statement. In contrast, the variable i is not definitely assigned in the first embedded statement, since x &gt;= 0 might have tested false, resulting in the variable i's being unassigned. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.3.3.25.xml b/mcs/docs/ecma334/12.3.3.25.xml
new file mode 100644 (file)
index 0000000..03e3156
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="12.3.3.25" title="! expressions">
+  <paragraph>For an expression expr of the form ! expr-operand: <list><list_item> The definite assignment state of v before expr-operand is the same as the definite assignment state of v before expr. </list_item><list_item> The definite assignment state of v after expr is determined by: </list_item><list><list_item> If the state of v after expr-operand is definitely assigned, then the state of v after expr is definitely assigned. </list_item><list_item> If the state of v after expr-operand is not definitely assigned, then the state of v after expr is not definitely assigned. </list_item><list_item> If the state of v after expr-operand is &quot;definitely assigned after false expression&quot;, then the state of v after expr is &quot;definitely assigned after true expression&quot;. </list_item><list_item> If the state of v after expr-operand is &quot;definitely assigned after true expression&quot;, then the state of v after expr is &quot;definitely assigned after false expression&quot;. </list_item></list></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.3.3.26.xml b/mcs/docs/ecma334/12.3.3.26.xml
new file mode 100644 (file)
index 0000000..eadeccb
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="12.3.3.26" title="?: expressions">
+  <paragraph>For an expression expr of the form expr-cond ? expr-true : expr-false: <list><list_item> The definite assignment state of v before expr-cond is the same as the state of v before expr. </list_item><list_item> The definite assignment state of v before expr-true is definitely assigned if and only if the state of v after expr-cond is definitely assigned or &quot;definitely assigned after true expression&quot;. </list_item><list_item> The definite assignment state of v before expr-false is definitely assigned if and only if the state of v after expr-cond is definitely assigned or &quot;definitely assigned after false expression&quot;. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.3.3.3.xml b/mcs/docs/ecma334/12.3.3.3.xml
new file mode 100644 (file)
index 0000000..a8557d6
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="12.3.3.3" title="Expression statements">
+  <paragraph>For an expression statement stmt that consists of the expression expr: <list><list_item> v has the same definite assignment state at the beginning of expr as at the beginning of stmt. </list_item><list_item> If v if definitely assigned at the end of expr, it is definitely assigned at the end point of stmt; otherwise; it is not definitely assigned at the end point of stmt. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.3.3.4.xml b/mcs/docs/ecma334/12.3.3.4.xml
new file mode 100644 (file)
index 0000000..cf8f28f
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<clause number="12.3.3.4" title="Declaration statements">
+  <paragraph>
+    <list>
+      <list_item> If stmt is a declaration statement without initializers, then v has the same definite assignment state at the end point of stmt as at the beginning of stmt. </list_item>
+      <list_item> If stmt is a declaration statement with initializers, then the definite assignment state for v is determined as if stmt were a statement list, with one assignment statement for each declaration with an initializer (in the order of declaration). </list_item>
+    </list>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.3.3.5.xml b/mcs/docs/ecma334/12.3.3.5.xml
new file mode 100644 (file)
index 0000000..60be2a7
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="12.3.3.5" title="If statements">
+  <paragraph>For an if statement stmt of the form: <code_example><![CDATA[
+if (expr) then-stmt else else-stmt  
+]]></code_example><list><list_item> v has the same definite assignment state at the beginning of expr as at the beginning of stmt. </list_item><list_item> If v is definitely assigned at the end of expr, then it is definitely assigned on the control flow transfer to then-stmt and to either else-stmt or to the end-point of stmt if there is no else clause. </list_item><list_item> If v has the state &quot;definitely assigned after true expression&quot; at the end of expr, then it is definitely assigned on the control flow transfer to then-stmt, and not definitely assigned on the control flow transfer to either else-stmt or to the end-point of stmt if there is no else clause. </list_item><list_item> If v has the state &quot;definitely assigned after false expression&quot; at the end of expr, then it is definitely assigned on the control flow transfer to else-stmt, and not definitely assigned on the control flow transfer to then-stmt. It is definitely assigned at the end-point of stmt if and only if it is definitely assigned at the end-point of then-stmt. </list_item><list_item> Otherwise, v is considered not definitely assigned on the control flow transfer to either the then-stmt or else-stmt, or to the end-point of stmt if there is no else clause. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.3.3.6.xml b/mcs/docs/ecma334/12.3.3.6.xml
new file mode 100644 (file)
index 0000000..6af003f
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="12.3.3.6" title="Switch statements">
+  <paragraph>In a switch statement stmt with controlling expression expr: <list><list_item> The definite assignment state of v at the beginning of expr is the same as the state of v at the beginning of stmt. </list_item><list_item> The definite assignment state of v on the control flow transfer to a reachable switch block statement list is the same as the definite assignment state of v at the end of expr. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.3.3.7.xml b/mcs/docs/ecma334/12.3.3.7.xml
new file mode 100644 (file)
index 0000000..f319283
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="12.3.3.7" title="While statements">
+  <paragraph>For a while statement stmt of the form: <code_example><![CDATA[
+while (expr) while-body  
+]]></code_example><list><list_item> v has the same definite assignment state at the beginning of expr as at the beginning of stmt. </list_item><list_item> If v is definitely assigned at the end of expr, then it is definitely assigned on the control flow transfer to while-body and to the end point of stmt. </list_item><list_item> If v has the state &quot;definitely assigned after true expression&quot; at the end of expr, then it is definitely assigned on the control flow transfer to while-body, but not definitely assigned at the end-point of stmt. </list_item><list_item> If v has the state &quot;definitely assigned after false expression&quot; at the end of expr, then it is definitely assigned on the control flow transfer to the end point of stmt. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.3.3.8.xml b/mcs/docs/ecma334/12.3.3.8.xml
new file mode 100644 (file)
index 0000000..eb512d7
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="12.3.3.8" title="Do statements">
+  <paragraph>For a do statement stmt of the form: <code_example><![CDATA[
+do do-body while (expr);   
+]]></code_example><list><list_item> v has the same definite assignment state on the control flow transfer from the beginning of stmt to do-body as at the beginning of stmt. </list_item><list_item> v has the same definite assignment state at the beginning of expr as at the end point of do-body. </list_item><list_item> If v is definitely assigned at the end of expr, then it is definitely assigned on the end point of stmt. </list_item><list_item> If v has the state &quot;definitely assigned after false expression&quot; at the end of expr, then it is definitely assigned on the control flow transfer to the end point of stmt. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.3.3.9.xml b/mcs/docs/ecma334/12.3.3.9.xml
new file mode 100644 (file)
index 0000000..47452cf
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<clause number="12.3.3.9" title="For statements">
+  <paragraph>Definite assignment checking for a for statement of the form: <code_example><![CDATA[
+for (for-initializer; for-condition; for-iterator) embedded-statement  
+]]></code_example>is done as if the statement were written: <code_example><![CDATA[
+{  
+   for-initializer;  
+   while (for-condition) {  
+      embedded-statement;  
+      for-iterator;  
+   }  
+}  
+]]></code_example></paragraph>
+  <paragraph>If the <non_terminal where="15.8.3">for-condition</non_terminal> is omitted from the for statement, then evaluation of definite assignment proceeds as if <non_terminal where="15.8.3">for-condition</non_terminal> were replaced with true in the above expansion. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.3.3.xml b/mcs/docs/ecma334/12.3.3.xml
new file mode 100644 (file)
index 0000000..f0789eb
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<clause number="12.3.3" title="Precise rules for determining definite assignment">
+  <paragraph>In order to determine that each used variable is definitely assigned, the compiler must use a process that is equivalent to the one described in this section. </paragraph>
+  <paragraph>The compiler processes the body of each function member that has one or more initially unassigned variables. For each initially unassigned variable v, the compiler determines a definite assignment state for v at each of the following points in the function member: <list><list_item> At the beginning of each statement </list_item><list_item> At the end point (<hyperlink>15.1</hyperlink>) of each statement </list_item><list_item> On each arc which transfers control to another statement or to the end point of a statement </list_item><list_item> At the beginning of each expression </list_item><list_item> At the end of each expression </list_item></list></paragraph>
+  <paragraph>The definite assignment state of v can be either: <list><list_item> Definitely assigned. This indicates that on all possible control flows to this point, v has been assigned a value. </list_item><list_item> Not definitely assigned. For the state of a variable at the end of an expression of type <keyword>bool</keyword>, the state of a variable that isn't definitely assigned may (but doesn't necessarily) fall into one of the following sub-states: </list_item><list><list_item> Definitely assigned after true expression. This state indicates that v is definitely assigned if the boolean expression evaluated as true, but is not necessarily assigned if the boolean expression evaluated as false. </list_item><list_item> Definitely assigned after false expression. This state indicates that v is definitely assigned if the boolean expression evaluated as false, but is not necessarily assigned if the boolean expression evaluated as true. </list_item></list></list></paragraph>
+  <paragraph>The following rules govern how the state of a variable v is determined at each location. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.3.xml b/mcs/docs/ecma334/12.3.xml
new file mode 100644 (file)
index 0000000..f25b791
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<clause number="12.3" title="Definite assignment">
+  <paragraph>At a given location in the executable code of a function member, a variable is said to be definitely assigned if the compiler can prove, by static flow analysis, that the variable has been automatically initialized or has been the target of at least one assignment. The rules of definite assignment are: <list><list_item> An initially assigned variable (<hyperlink>12.3.1</hyperlink>) is always considered definitely assigned. </list_item><list_item> An initially unassigned variable (<hyperlink>12.3.2</hyperlink>) is considered definitely assigned at a given location if all possible execution paths leading to that location contain at least one of the following: </list_item><list><list_item> A simple assignment (<hyperlink>14.13.1</hyperlink>) in which the variable is the left operand. </list_item><list_item> An invocation expression (<hyperlink>14.5.5</hyperlink>) or object creation expression (<hyperlink>14.5.10.1</hyperlink>) that passes the variable as an output parameter. </list_item><list_item> For a local variable, a local variable declaration (<hyperlink>15.5</hyperlink>) that includes a variable initializer. </list_item></list></list></paragraph>
+  <paragraph>The definite assignment states of instance variables of a <non_terminal where="11.1">struct-type</non_terminal> variable are tracked individually as well as collectively. In additional to the rules above, the following rules apply to <non_terminal where="11.1">struct-type</non_terminal> variables and their instance variables: <list><list_item> An instance variable is considered definitely assigned if its containing <non_terminal where="11.1">struct-type</non_terminal> variable is considered definitely assigned. </list_item><list_item> A <non_terminal where="11.1">struct-type</non_terminal> variable is considered definitely assigned if each of its instance variables is considered definitely assigned. </list_item></list></paragraph>
+  <paragraph>Definite assignment is a requirement in the following contexts: <list><list_item> A variable must be definitely assigned at each location where its value is obtained. <note>[Note: This ensures that undefined values never occur. end note]</note> The occurrence of a variable in an expression is considered to obtain the value of the variable, except when </list_item><list><list_item> the variable is the left operand of a simple assignment, </list_item><list_item> the variable is passed as an output parameter, or </list_item><list_item> the variable is a <non_terminal where="11.1">struct-type</non_terminal> variable and occurs as the left operand of a member access. </list_item></list><list_item> A variable must be definitely assigned at each location where it is passed as a reference parameter. </list_item></list></paragraph>
+  <paragraph>
+    <note>[Note: This ensures that the function member being invoked can consider the reference parameter initially assigned. end note]</note>
+    <list>
+      <list_item> All output parameters of a function member must be definitely assigned at each location where the function member returns (through a return statement or through execution reaching the end of the function member body). <note>[Note: This ensures that function members do not return undefined values in output parameters, thus enabling the compiler to consider a function member invocation that takes a variable as an output parameter equivalent to an assignment to the variable. end note]</note> </list_item>
+      <list_item> The this variable of a <non_terminal where="11.1">struct-type</non_terminal> instance constructor must be definitely assigned at each location where that instance constructor returns. </list_item>
+    </list>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.4.xml b/mcs/docs/ecma334/12.4.xml
new file mode 100644 (file)
index 0000000..6be1274
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<clause number="12.4" title="Variable references">
+  <paragraph>A <non_terminal where="12.4">variable-reference</non_terminal> is an expression that is classified as a variable. A <non_terminal where="12.4">variable-reference</non_terminal> denotes a storage location that can be accessed both to fetch the current value and to store a new value. <grammar_production><name><non_terminal where="12.4">variable-reference</non_terminal></name> : <rhs><non_terminal where="14.14">expression</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>
+    <note>[Note: In C and C++, a <non_terminal where="12.4">variable-reference</non_terminal> is known as an lvalue. end note]</note>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.5.xml b/mcs/docs/ecma334/12.5.xml
new file mode 100644 (file)
index 0000000..d7f8b55
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="12.5" title="Atomicity of variable references">
+  <paragraph>Reads and writes of the following data types shall be atomic: <keyword>bool</keyword>, <keyword>char</keyword>, <keyword>byte</keyword>, <keyword>sbyte</keyword>, <keyword>short</keyword>, <keyword>ushort</keyword>, <keyword>uint</keyword>, <keyword>int</keyword>, <keyword>float</keyword>, and reference types. In addition, reads and writes of enum types with an underlying type in the previous list shall also be atomic. Reads and writes of other types, including <keyword>long</keyword>, <keyword>ulong</keyword>, <keyword>double</keyword>, and <keyword>decimal</keyword>, as well as user-defined types, need not be atomic. Aside from the library functions designed for that purpose, there is no guarantee of atomic read-modify-write, such as in the case of increment or decrement. <table_line/>
+</paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/12.xml b/mcs/docs/ecma334/12.xml
new file mode 100644 (file)
index 0000000..a450ada
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="12" title="Variables">
+  <paragraph>Variables represent storage locations. Every variable has a type that determines what values can be stored in the variable. C# is a type-safe language, and the C# compiler guarantees that values stored in variables are always of the appropriate type. The value of a variable can be changed through assignment or through use of the ++ and  --operators. </paragraph>
+  <paragraph>A variable must be definitely assigned (<hyperlink>12.3</hyperlink>) before its value can be obtained. </paragraph>
+  <paragraph>As described in the following sections, variables are either initially assigned or initially unassigned. An initially assigned variable has a well-defined initial value and is always considered definitely assigned. An initially unassigned variable has no initial value. For an initially unassigned variable to be considered definitely assigned at a certain location, an assignment to the variable must occur in every possible execution path leading to that location. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/13.1.1.xml b/mcs/docs/ecma334/13.1.1.xml
new file mode 100644 (file)
index 0000000..200e7a1
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="13.1.1" title="Identity conversion">
+  <paragraph>An identity conversion converts from any type to the same type. This conversion exists only such that an entity that already has a required type can be said to be convertible to that type. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/13.1.2.xml b/mcs/docs/ecma334/13.1.2.xml
new file mode 100644 (file)
index 0000000..b7dbe21
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="13.1.2" title="Implicit numeric conversions">
+  <paragraph>The implicit numeric conversions are: <list><list_item> From <keyword>sbyte</keyword> to <keyword>short</keyword>, <keyword>int</keyword>, <keyword>long</keyword>, <keyword>float</keyword>, <keyword>double</keyword>, or <keyword>decimal</keyword>. </list_item><list_item> From <keyword>byte</keyword> to <keyword>short</keyword>, <keyword>ushort</keyword>, <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>long</keyword>, <keyword>ulong</keyword>, <keyword>float</keyword>, <keyword>double</keyword>, or <keyword>decimal</keyword>. </list_item><list_item> From <keyword>short</keyword> to <keyword>int</keyword>, <keyword>long</keyword>, <keyword>float</keyword>, <keyword>double</keyword>, or <keyword>decimal</keyword>. </list_item><list_item> From <keyword>ushort</keyword> to <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>long</keyword>, <keyword>ulong</keyword>, <keyword>float</keyword>, <keyword>double</keyword>, or <keyword>decimal</keyword>. </list_item><list_item> From <keyword>int</keyword> to <keyword>long</keyword>, <keyword>float</keyword>, <keyword>double</keyword>, or <keyword>decimal</keyword>. </list_item><list_item> From <keyword>uint</keyword> to <keyword>long</keyword>, <keyword>ulong</keyword>, <keyword>float</keyword>, <keyword>double</keyword>, or <keyword>decimal</keyword>. </list_item><list_item> From <keyword>long</keyword> to <keyword>float</keyword>, <keyword>double</keyword>, or <keyword>decimal</keyword>. </list_item><list_item> From <keyword>ulong</keyword> to <keyword>float</keyword>, <keyword>double</keyword>, or <keyword>decimal</keyword>. </list_item><list_item> From <keyword>char</keyword> to <keyword>ushort</keyword>, <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>long</keyword>, <keyword>ulong</keyword>, <keyword>float</keyword>, <keyword>double</keyword>, or <keyword>decimal</keyword>. </list_item><list_item> From <keyword>float</keyword> to <keyword>double</keyword>. </list_item></list></paragraph>
+  <paragraph>Conversions from <keyword>int</keyword>, <keyword>uint</keyword>, or <keyword>long</keyword> to <keyword>float</keyword> and from <keyword>long</keyword> to <keyword>double</keyword> may cause a loss of precision, but will never cause a loss of magnitude. The other implicit numeric conversions never lose any information. </paragraph>
+  <paragraph>There are no implicit conversions to the <keyword>char</keyword> type, so values of the other integral types do not automatically convert to the <keyword>char</keyword> type. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/13.1.3.xml b/mcs/docs/ecma334/13.1.3.xml
new file mode 100644 (file)
index 0000000..8788779
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="13.1.3" title="Implicit enumeration conversions">
+  <paragraph>An implicit enumeration conversion permits the <non_terminal where="9.4.4.2">decimal-integer-literal</non_terminal> 0 to be converted to any <non_terminal where="11.1">enum-type</non_terminal>. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/13.1.4.xml b/mcs/docs/ecma334/13.1.4.xml
new file mode 100644 (file)
index 0000000..2f2ade2
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="13.1.4" title="Implicit reference conversions">
+  <paragraph>The implicit reference conversions are: <list><list_item> From any <non_terminal where="11.2">reference-type</non_terminal> to object. </list_item><list_item> From any <non_terminal where="11.2">class-type</non_terminal> S to any <non_terminal where="11.2">class-type</non_terminal> T, provided S is derived from T. </list_item><list_item> From any <non_terminal where="11.2">class-type</non_terminal> S to any <non_terminal where="11.2">interface-type</non_terminal> T, provided S implements T. </list_item><list_item> From any <non_terminal where="11.2">interface-type</non_terminal> S to any <non_terminal where="11.2">interface-type</non_terminal> T, provided S is derived from T. </list_item><list_item> From an <non_terminal where="19.1">array-type</non_terminal> S with an element type SE to an <non_terminal where="19.1">array-type</non_terminal> T with an element type TE, provided all of the following are true: </list_item><list><list_item> S and T differ only in element type. In other words, S and T have the same number of dimensions. </list_item><list_item> Both SE and TE are <non_terminal where="11.2">reference-type</non_terminal>s. </list_item><list_item> An implicit reference conversion exists from SE to TE. </list_item></list><list_item> From any <non_terminal where="19.1">array-type</non_terminal> to System.Array. </list_item><list_item> From any <non_terminal where="11.2">delegate-type</non_terminal> to System.Delegate. </list_item><list_item> From any <non_terminal where="19.1">array-type</non_terminal> or <non_terminal where="11.2">delegate-type</non_terminal> to System.ICloneable. </list_item><list_item> From the null type to any <non_terminal where="11.2">reference-type</non_terminal>. </list_item></list></paragraph>
+  <paragraph>The implicit reference conversions are those conversions between <non_terminal where="11.2">reference-type</non_terminal>s that can be proven to always succeed, and therefore require no checks at run-time. </paragraph>
+  <paragraph>Reference conversions, implicit or explicit, never change the referential identity of the object being converted. <note>[Note: In other words, while a reference conversion may change the type of the reference, it never changes the type or value of the object being referred to. end note]</note> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/13.1.5.xml b/mcs/docs/ecma334/13.1.5.xml
new file mode 100644 (file)
index 0000000..dc2f6c8
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="13.1.5" title="Boxing conversions">
+  <paragraph>A boxing conversion permits any <non_terminal where="11.1">value-type</non_terminal> to be implicitly converted to the type object or to any <non_terminal where="11.2">interface-type</non_terminal> implemented by the <non_terminal where="11.1">value-type</non_terminal>. Boxing a value of a <non_terminal where="11.1">value-type</non_terminal> consists of allocating an object instance and copying the <non_terminal where="11.1">value-type</non_terminal> value into that instance. </paragraph>
+  <paragraph>Boxing conversions are described further in <hyperlink>11.3.1</hyperlink>. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/13.1.6.xml b/mcs/docs/ecma334/13.1.6.xml
new file mode 100644 (file)
index 0000000..7dd1b0d
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="13.1.6" title="Implicit constant expression conversions">
+  <paragraph>An implicit constant expression conversion permits the following conversions: <list><list_item> A <non_terminal where="14.15">constant-expression</non_terminal> (<hyperlink>14.15</hyperlink>) of type <keyword>int</keyword> can be converted to type <keyword>sbyte</keyword>, <keyword>byte</keyword>, <keyword>short</keyword>, <keyword>ushort</keyword>, <keyword>uint</keyword>, or <keyword>ulong</keyword>, provided the value of the <non_terminal where="14.15">constant-expression</non_terminal> is within the range of the destination type. </list_item><list_item> A <non_terminal where="14.15">constant-expression</non_terminal> of type <keyword>long</keyword> can be converted to type <keyword>ulong</keyword>, provided the value of the  <non_terminal where="14.15">constant-expression</non_terminal> is not negative. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/13.1.7.xml b/mcs/docs/ecma334/13.1.7.xml
new file mode 100644 (file)
index 0000000..99f1a99
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="13.1.7" title="User-defined implicit conversions">
+  <paragraph>A user-defined implicit conversion consists of an optional standard implicit conversion, followed by execution of a user-defined implicit conversion operator, followed by another optional standard implicit conversion. The exact rules for evaluating user-defined conversions are described in <hyperlink>13.4.3</hyperlink>. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/13.1.xml b/mcs/docs/ecma334/13.1.xml
new file mode 100644 (file)
index 0000000..c548b2d
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="13.1" title="Implicit conversions">
+  <paragraph>The following conversions are classified as implicit conversions: <list><list_item> Identity conversions </list_item><list_item> Implicit numeric conversions </list_item><list_item> Implicit enumeration conversions. </list_item><list_item> Implicit reference conversions </list_item><list_item> Boxing conversions </list_item><list_item> Implicit constant expression conversions </list_item><list_item> User-defined implicit conversions </list_item></list></paragraph>
+  <paragraph>Implicit conversions can occur in a variety of situations, including function member invocations (<hyperlink>14.4.3</hyperlink>), cast expressions (<hyperlink>14.6.6</hyperlink>), and assignments (<hyperlink>14.13</hyperlink>). </paragraph>
+  <paragraph>The pre-defined implicit conversions always succeed and never cause exceptions to be thrown. <note>[Note: Properly designed user-defined implicit conversions should exhibit these characteristics as well. end note]</note> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/13.2.1.xml b/mcs/docs/ecma334/13.2.1.xml
new file mode 100644 (file)
index 0000000..4bbed9c
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="13.2.1" title="Explicit numeric conversions">
+  <paragraph>The explicit numeric conversions are the conversions from a <non_terminal where="11.1">numeric-type</non_terminal> to another <non_terminal where="11.1">numeric-type</non_terminal> for which an implicit numeric conversion (<hyperlink>13.1.2</hyperlink>) does not already exist: <list><list_item> From <keyword>sbyte</keyword> to <keyword>byte</keyword>, <keyword>ushort</keyword>, <keyword>uint</keyword>, <keyword>ulong</keyword>, or <keyword>char</keyword>. </list_item><list_item> From <keyword>byte</keyword> to <keyword>sbyte</keyword> and <keyword>char</keyword>. </list_item><list_item> From <keyword>short</keyword> to <keyword>sbyte</keyword>, <keyword>byte</keyword>, <keyword>ushort</keyword>, <keyword>uint</keyword>, <keyword>ulong</keyword>, or <keyword>char</keyword>. </list_item><list_item> From <keyword>ushort</keyword> to <keyword>sbyte</keyword>, <keyword>byte</keyword>, <keyword>short</keyword>, or <keyword>char</keyword>. </list_item><list_item> From <keyword>int</keyword> to <keyword>sbyte</keyword>, <keyword>byte</keyword>, <keyword>short</keyword>, <keyword>ushort</keyword>, <keyword>uint</keyword>, <keyword>ulong</keyword>, or <keyword>char</keyword>. </list_item><list_item> From <keyword>uint</keyword> to <keyword>sbyte</keyword>, <keyword>byte</keyword>, <keyword>short</keyword>, <keyword>ushort</keyword>, <keyword>int</keyword>, or <keyword>char</keyword>. </list_item><list_item> From <keyword>long</keyword> to <keyword>sbyte</keyword>, <keyword>byte</keyword>, <keyword>short</keyword>, <keyword>ushort</keyword>, <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>ulong</keyword>, or <keyword>char</keyword>. </list_item><list_item> From <keyword>ulong</keyword> to <keyword>sbyte</keyword>, <keyword>byte</keyword>, <keyword>short</keyword>, <keyword>ushort</keyword>, <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>long</keyword>, or <keyword>char</keyword>. </list_item><list_item> From <keyword>char</keyword> to <keyword>sbyte</keyword>, <keyword>byte</keyword>, or <keyword>short</keyword>. </list_item><list_item> From <keyword>float</keyword> to <keyword>sbyte</keyword>, <keyword>byte</keyword>, <keyword>short</keyword>, <keyword>ushort</keyword>, <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>long</keyword>, <keyword>ulong</keyword>, <keyword>char</keyword>, or <keyword>decimal</keyword>. </list_item><list_item> From <keyword>double</keyword> to <keyword>sbyte</keyword>, <keyword>byte</keyword>, <keyword>short</keyword>, <keyword>ushort</keyword>, <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>long</keyword>, <keyword>ulong</keyword>, <keyword>char</keyword>, <keyword>float</keyword>, or <keyword>decimal</keyword>. </list_item><list_item> From <keyword>decimal</keyword> to <keyword>sbyte</keyword>, <keyword>byte</keyword>, <keyword>short</keyword>, <keyword>ushort</keyword>, <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>long</keyword>, <keyword>ulong</keyword>, <keyword>char</keyword>, <keyword>float</keyword>, or <keyword>double</keyword>. </list_item></list></paragraph>
+  <paragraph>Because the explicit conversions include all implicit and explicit numeric conversions, it is always possible to convert from any <non_terminal where="11.1">numeric-type</non_terminal> to any other <non_terminal where="11.1">numeric-type</non_terminal> using a cast expression (<hyperlink>14.6.6</hyperlink>). </paragraph>
+  <paragraph>The explicit numeric conversions possibly lose information or possibly cause exceptions to be thrown. An explicit numeric conversion is processed as follows: <list><list_item> For a conversion from an integral type to another integral type, the processing depends on the overflow checking context (<hyperlink>14.5.12</hyperlink>) in which the conversion takes place: </list_item><list><list_item> In a checked context, the conversion succeeds if the value of the source operand is within the range of the destination type, but throws a System.OverflowException if the value of the source operand is outside the range of the destination type. </list_item><list_item> In an unchecked context, the conversion always succeeds, and proceeds as follows: </list_item><list><list_item> If the source type is larger than the destination type, then the source value is truncated by discarding its &quot;extra&quot; most significant bits. The result is then treated as a value of the destination type. </list_item><list_item> If the source type is smaller than the destination type, then the source value is either  sign-extended or zero-extended so that it is the same size as the destination type. Sign-extension is used if the source type is signed; zero-extension is used if the source type is unsigned. The result is then treated as a value of the destination type. </list_item><list_item> If the source type is the same size as the destination type, then the source value is treated as a value of the destination type. </list_item></list></list><list_item> For a conversion from <keyword>decimal</keyword> to an integral type, the source value is rounded towards zero to the nearest integral value, and this integral value becomes the result of the conversion. If the resulting integral value is outside the range of the destination type, a System.OverflowException is thrown. </list_item><list_item> For a conversion from <keyword>float</keyword> or <keyword>double</keyword> to an integral type, the processing depends on the  overflow-checking context (<hyperlink>14.5.12</hyperlink>) in which the conversion takes place: </list_item><list><list_item> In a checked context, the conversion proceeds as follows: </list_item><list><list_item> The value is rounded towards zero to the nearest integral value. If this integral value is within the range of the destination type, then this value is the result of the conversion. </list_item><list_item> Otherwise, a System.OverflowException is thrown. </list_item></list><list_item> In an unchecked context, the conversion always succeeds, and proceeds as follows: </list_item><list><list_item> The value is rounded towards zero to the nearest integral value. If this integral value is within the range of the destination type, then this value is the result of the conversion. </list_item><list_item> Otherwise, the result of the conversion is an unspecified value of the destination type. </list_item></list></list><list_item> For a conversion from <keyword>double</keyword> to <keyword>float</keyword>, the <keyword>double</keyword> value is rounded to the nearest <keyword>float</keyword> value. If the <keyword>double</keyword> value is too small to represent as a <keyword>float</keyword>, the result becomes positive zero or negative zero. If the <keyword>double</keyword> value is too large to represent as a <keyword>float</keyword>, the result becomes positive infinity or negative infinity. If the <keyword>double</keyword> value is NaN, the result is also NaN. </list_item><list_item> For a conversion from <keyword>float</keyword> or <keyword>double</keyword> to <keyword>decimal</keyword>, the source value is converted to <keyword>decimal</keyword> representation and rounded to the nearest number after the 28th <keyword>decimal</keyword> place if required (<hyperlink>11.1.6</hyperlink>). If the source value is too small to represent as a <keyword>decimal</keyword>, the result becomes zero. If the source value is NaN, infinity, or too large to represent as a <keyword>decimal</keyword>, a System.OverflowException is thrown. </list_item><list_item> For a conversion from <keyword>decimal</keyword> to <keyword>float</keyword> or <keyword>double</keyword>, the <keyword>decimal</keyword> value is rounded to the nearest <keyword>double</keyword> or <keyword>float</keyword> value. While this conversion may lose precision, it never causes an exception to be thrown. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/13.2.2.xml b/mcs/docs/ecma334/13.2.2.xml
new file mode 100644 (file)
index 0000000..e37b770
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="13.2.2" title="Explicit enumeration conversions">
+  <paragraph>The explicit enumeration conversions are: <list><list_item> From <keyword>sbyte</keyword>, <keyword>byte</keyword>, <keyword>short</keyword>, <keyword>ushort</keyword>, <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>long</keyword>, <keyword>ulong</keyword>, <keyword>char</keyword>, <keyword>float</keyword>, <keyword>double</keyword>, or <keyword>decimal</keyword> to any <non_terminal where="11.1">enum-type</non_terminal>. </list_item><list_item> From any <non_terminal where="11.1">enum-type</non_terminal> to <keyword>sbyte</keyword>, <keyword>byte</keyword>, <keyword>short</keyword>, <keyword>ushort</keyword>, <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>long</keyword>, <keyword>ulong</keyword>, <keyword>char</keyword>, <keyword>float</keyword>, <keyword>double</keyword>, or <keyword>decimal</keyword>. </list_item><list_item> From any <non_terminal where="11.1">enum-type</non_terminal> to any other <non_terminal where="11.1">enum-type</non_terminal>. </list_item></list></paragraph>
+  <paragraph>An explicit enumeration conversion between two types is processed by treating any participating <non_terminal where="11.1">enum-type</non_terminal> as the underlying type of that <non_terminal where="11.1">enum-type</non_terminal>, and then performing an implicit or explicit numeric conversion between the resulting types. <example>[Example: For example, given an <non_terminal where="11.1">enum-type</non_terminal> E with and underlying type of <keyword>int</keyword>, a conversion from E to <keyword>byte</keyword> is processed as an explicit numeric conversion (<hyperlink>13.2.1</hyperlink>) from <keyword>int</keyword> to <keyword>byte</keyword>, and a conversion from <keyword>byte</keyword> to E is processed as an implicit numeric conversion (<hyperlink>13.1.2</hyperlink>) from <keyword>byte</keyword> to <keyword>int</keyword>. end example]</example> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/13.2.3.xml b/mcs/docs/ecma334/13.2.3.xml
new file mode 100644 (file)
index 0000000..2c6a297
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<clause number="13.2.3" title="Explicit reference conversions">
+  <paragraph>The explicit reference conversions are: <list><list_item> From object to any <non_terminal where="11.2">reference-type</non_terminal>. </list_item><list_item> From any <non_terminal where="11.2">class-type</non_terminal> S to any <non_terminal where="11.2">class-type</non_terminal> T, provided S is a base class of T. </list_item><list_item> From any <non_terminal where="11.2">class-type</non_terminal> S to any <non_terminal where="11.2">interface-type</non_terminal> T, provided S is not sealed and provided S does not implement T. </list_item><list_item> From any <non_terminal where="11.2">interface-type</non_terminal> S to any <non_terminal where="11.2">class-type</non_terminal> T, provided T is not sealed or provided T implements S. </list_item><list_item> From any <non_terminal where="11.2">interface-type</non_terminal> S to any <non_terminal where="11.2">interface-type</non_terminal> T, provided S is not derived from T. </list_item><list_item> From an <non_terminal where="19.1">array-type</non_terminal> S with an element type SE to an <non_terminal where="19.1">array-type</non_terminal> T with an element type TE, provided all of the following are true: </list_item><list><list_item> S and T differ only in element type. (In other words, S and T have the same number of dimensions.) </list_item><list_item> Both SE and TE are <non_terminal where="11.2">reference-type</non_terminal>s. </list_item><list_item> An explicit reference conversion exists from SE to TE. </list_item></list><list_item> From System.Array and the interfaces it implements, to any <non_terminal where="19.1">array-type</non_terminal>. </list_item><list_item> From System.Delegate and the interfaces it implements, to any <non_terminal where="11.2">delegate-type</non_terminal>. </list_item></list></paragraph>
+  <paragraph>The explicit reference conversions are those conversions between <non_terminal where="11.2">reference-type</non_terminal>s that require run-time checks to ensure they are correct. </paragraph>
+  <paragraph>For an explicit reference conversion to succeed at run-time, the value of the source operand must be null, or the actual type of the object referenced by the source operand must be a type that can be converted to the destination type by an implicit reference conversion (<hyperlink>13.1.4</hyperlink>). If an explicit reference conversion fails, a System.InvalidCastException is thrown. </paragraph>
+  <paragraph>Reference conversions, implicit or explicit, never change the referential identity of the object being converted. <note>[Note: In other words, while a reference conversion may change the type of the reference, it never changes the type or value of the object being referred to. end note]</note> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/13.2.4.xml b/mcs/docs/ecma334/13.2.4.xml
new file mode 100644 (file)
index 0000000..6bbcb86
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="13.2.4" title="Unboxing conversions">
+  <paragraph>An unboxing conversion permits an explicit conversion from type object to any <non_terminal where="11.1">value-type</non_terminal> or from any <non_terminal where="11.2">interface-type</non_terminal> to any <non_terminal where="11.1">value-type</non_terminal> that implements the <non_terminal where="11.2">interface-type</non_terminal>. An unboxing operation consists of first checking that the object instance is a boxed value of the given <non_terminal where="11.1">value-type</non_terminal>, and then copying the value out of the instance. </paragraph>
+  <paragraph>Unboxing conversions are described further in <hyperlink>11.3.2</hyperlink>. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/13.2.5.xml b/mcs/docs/ecma334/13.2.5.xml
new file mode 100644 (file)
index 0000000..b216c63
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="13.2.5" title="User-defined explicit conversions">
+  <paragraph>A user-defined explicit conversion consists of an optional standard explicit conversion, followed by execution of a user-defined implicit or explicit conversion operator, followed by another optional standard explicit conversion. The exact rules for evaluating user-defined conversions are described in <hyperlink>13.4.4</hyperlink>. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/13.2.xml b/mcs/docs/ecma334/13.2.xml
new file mode 100644 (file)
index 0000000..c22d93b
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<clause number="13.2" title="Explicit conversions">
+  <paragraph>The following conversions are classified as explicit conversions: <list><list_item> All implicit conversions. </list_item><list_item> Explicit numeric conversions. </list_item><list_item> Explicit enumeration conversions. </list_item><list_item> Explicit reference conversions. </list_item><list_item> Explicit interface conversions. </list_item><list_item> Unboxing conversions. </list_item><list_item> User-defined explicit conversions. </list_item></list></paragraph>
+  <paragraph>Explicit conversions can occur in cast expressions (<hyperlink>14.6.6</hyperlink>). </paragraph>
+  <paragraph>The set of explicit conversions includes all implicit conversions. <note>[Note: This means that redundant cast expressions are allowed. end note]</note> </paragraph>
+  <paragraph>The explicit conversions that are not implicit conversions are conversions that cannot be proven to always succeed, conversions that are known to possibly lose information, and conversions across domains of types sufficiently different to merit explicit notation. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/13.3.1.xml b/mcs/docs/ecma334/13.3.1.xml
new file mode 100644 (file)
index 0000000..3bd35f0
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="13.3.1" title="Standard implicit conversions">
+  <paragraph>The following implicit conversions are classified as standard implicit conversions: <list><list_item> Identity conversions (<hyperlink>13.1.1</hyperlink>) </list_item><list_item> Implicit numeric conversions (<hyperlink>13.1.2</hyperlink>) </list_item><list_item> Implicit reference conversions (<hyperlink>13.1.4</hyperlink>) </list_item><list_item> Boxing conversions (<hyperlink>13.1.5</hyperlink>) </list_item><list_item> Implicit constant expression conversions (<hyperlink>13.1.6</hyperlink>) </list_item></list></paragraph>
+  <paragraph>The standard implicit conversions specifically exclude user-defined implicit conversions. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/13.3.2.xml b/mcs/docs/ecma334/13.3.2.xml
new file mode 100644 (file)
index 0000000..5c5fafb
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="13.3.2" title="Standard explicit conversions">
+  <paragraph>The standard explicit conversions are all standard implicit conversions plus the subset of the explicit conversions for which an opposite standard implicit conversion exists. <note>[Note: In other words, if a standard implicit conversion exists from a type A to a type B, then a standard explicit conversion exists from type A to type B and from type B to type A. end note]</note> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/13.3.xml b/mcs/docs/ecma334/13.3.xml
new file mode 100644 (file)
index 0000000..dd1afec
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="13.3" title="Standard conversions">
+  <paragraph>The standard conversions are those pre-defined conversions that can occur as part of a user-defined conversion. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/13.4.1.xml b/mcs/docs/ecma334/13.4.1.xml
new file mode 100644 (file)
index 0000000..c15bb6c
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="13.4.1" title="Permitted user-defined conversions">
+  <paragraph>C# permits only certain user-defined conversions to be declared. In particular, it is not possible to redefine an already existing implicit or explicit conversion. A class or struct is permitted to declare a conversion from a source type S to a target type T only if all of the following are true: <list><list_item> S and T are different types. </list_item><list_item> Either S or T is the class or struct type in which the operator declaration takes place. </list_item><list_item> Neither S nor T is object or an <non_terminal where="11.2">interface-type</non_terminal>. </list_item><list_item> T is not a base class of S, and S is not a base class of T. </list_item></list></paragraph>
+  <paragraph>The restrictions that apply to user-defined conversions are discussed further in <hyperlink>17.9.3</hyperlink>. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/13.4.2.xml b/mcs/docs/ecma334/13.4.2.xml
new file mode 100644 (file)
index 0000000..0a0b0cc
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<clause number="13.4.2" title="Evaluation of user-defined conversions">
+  <paragraph>A user-defined conversion converts a value from its type, called the source type, to another type, called the target type. Evaluation of a user-defined conversion centers on finding the most specific user-defined conversion operator for the particular source and target types. This determination is broken into several steps: <list><list_item> Finding the set of classes and structs from which user-defined conversion operators will be considered. This set consists of the source type and its base classes and the target type and its base classes (with the implicit assumptions that only classes and structs can declare user-defined operators, and that non-class types have no base classes). </list_item><list_item> From that set of types, determining which user-defined conversion operators are applicable. For a conversion operator to be applicable, it must be possible to perform a standard conversion (<hyperlink>13.3</hyperlink>) from the source type to the operand type of the operator, and it must be possible to perform a standard conversion from the result type of the operator to the target type. </list_item><list_item> From the set of applicable user-defined operators, determining which operator is unambiguously the most specific. In general terms, the most specific operator is the operator whose operand type is &quot;closest&quot; to the source type and whose result type is &quot;closest&quot; to the target type. The exact rules for establishing the most specific user-defined conversion operator are defined in the following sections. </list_item></list></paragraph>
+  <paragraph>Once a most specific user-defined conversion operator has been identified, the actual execution of the  user-defined conversion involves up to three steps: <list><list_item> First, if required, performing a standard conversion from the source type to the operand type of the  user-defined conversion operator. </list_item><list_item> Next, invoking the user-defined conversion operator to perform the conversion. </list_item><list_item> Finally, if required, performing a standard conversion from the result type of the user-defined conversion operator to the target type. </list_item></list></paragraph>
+  <paragraph>Evaluation of a user-defined conversion never involves more than one user-defined conversion operator. In other words, a conversion from type S to type T will never first execute a user-defined conversion from S to X and then execute a user-defined conversion from X to T. </paragraph>
+  <paragraph>Exact definitions of evaluation of user-defined implicit or explicit conversions are given in the following sections. The definitions make use of the following terms: <list><list_item> If a standard implicit conversion (<hyperlink>13.3.1</hyperlink>) exists from a type A to a type B, and if neither A nor B are <non_terminal where="11.2">interface-type</non_terminal>s, then A is said to be encompassed by B, and B is said to encompass A. </list_item><list_item> The most encompassing type in a set of types is the one type that encompasses all other types in the set. If no single type encompasses all other types, then the set has no most encompassing type. In more intuitive terms, the most encompassing type is the &quot;largest&quot; type in the set-the one type to which each of the other types can be implicitly converted. </list_item><list_item> The most encompassed type in a set of types is the one type that is encompassed by all other types in the set. If no single type is encompassed by all other types, then the set has no most encompassed type. In more intuitive terms, the most encompassed type is the &quot;smallest&quot; type in the set-the one type that can be implicitly converted to each of the other types. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/13.4.3.xml b/mcs/docs/ecma334/13.4.3.xml
new file mode 100644 (file)
index 0000000..01a7ebb
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="13.4.3" title="User-defined implicit conversions">
+  <paragraph>A user-defined implicit conversion from type S to type T is processed as follows: <list><list_item> Find the set of types, D, from which user-defined conversion operators will be considered. This set consists of S (if S is a class or struct), the base classes of S (if S is a class), T (if T is a class or struct), and the base classes of T (if T is a class). </list_item><list_item> Find the set of applicable user-defined conversion operators, U. This set consists of the user-defined implicit conversion operators declared by the classes or structs in D that convert from a type encompassing S to a type encompassed by T. If U is empty, the conversion is undefined and a compile-time error occurs. </list_item><list_item> Find the most specific source type, SX, of the operators in U: </list_item><list><list_item> If any of the operators in U convert from S, then SX is S. </list_item><list_item> Otherwise, SX is the most encompassed type in the combined set of source types of the operators in U. If no most encompassed type can be found, then the conversion is ambiguous and a  compile-time error occurs. </list_item></list><list_item> Find the most specific target type, TX, of the operators in U: </list_item><list><list_item> If any of the operators in U convert to T, then TX is T. </list_item><list_item> Otherwise, TX is the most encompassing type in the combined set of target types of the operators in U. If no most encompassing type can be found, then the conversion is ambiguous and a  compile-time error occurs. </list_item></list><list_item> If U contains exactly one user-defined conversion operator that converts from SX to TX, then this is the most specific conversion operator. If no such operator exists, or if more than one such operator exists, then the conversion is ambiguous and a compile-time error occurs. Otherwise, the user-defined conversion is applied: </list_item><list><list_item> If S is not SX, then a standard implicit conversion from S to SX is performed. </list_item><list_item> The most specific user-defined conversion operator is invoked to convert from SX to TX. </list_item><list_item> If TX is not T, then a standard implicit conversion from TX to T is performed. </list_item></list></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/13.4.4.xml b/mcs/docs/ecma334/13.4.4.xml
new file mode 100644 (file)
index 0000000..cf7f5e5
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="13.4.4" title="User-defined explicit conversions">
+  <paragraph>A user-defined explicit conversion from type S to type T is processed as follows: <list><list_item> Find the set of types, D, from which user-defined conversion operators will be considered. This set consists of S (if S is a class or struct), the base classes of S (if S is a class), T (if T is a class or struct), and the base classes of T (if T is a class). </list_item><list_item> Find the set of applicable user-defined conversion operators, U. This set consists of the user-defined implicit or explicit conversion operators declared by the classes or structs in D that convert from a type encompassing or encompassed by S to a type encompassing or encompassed by T. If U is empty, the conversion is undefined and a compile-time error occurs. </list_item><list_item> Find the most specific source type, SX, of the operators in U: </list_item><list><list_item> If any of the operators in U convert from S, then SX is S. </list_item><list_item> Otherwise, if any of the operators in U convert from types that encompass S, then SX is the most encompassed type in the combined set of source types of those operators. If no most encompassed type can be found, then the conversion is ambiguous and a compile-time error occurs. </list_item><list_item> Otherwise, SX is the most encompassing type in the combined set of source types of the operators in U. If no most encompassing type can be found, then the conversion is ambiguous and a  compile-time error occurs. </list_item></list><list_item> Find the most specific target type, TX, of the operators in U: </list_item><list><list_item> If any of the operators in U convert to T, then TX is T. </list_item><list_item> Otherwise, if any of the operators in U convert to types that are encompassed by T, then TX is the most encompassing type in the combined set of target types of those operators. If no most encompassing type can be found, then the conversion is ambiguous and a compile-time error occurs. </list_item><list_item> Otherwise, TX is the most encompassed type in the combined set of target types of the operators in U. If no most encompassed type can be found, then the conversion is ambiguous and a compile-time error occurs. </list_item></list><list_item> If U contains exactly one user-defined conversion operator that converts from SX to TX, then this is the most specific conversion operator. If no such operator exists, or if more than one such operator exists, then the conversion is ambiguous and a compile-time error occurs. Otherwise, the user-defined conversion is applied: </list_item><list><list_item> If S is not SX, then a standard explicit conversion from S to SX is performed. </list_item><list_item> The most specific user-defined conversion operator is invoked to convert from SX to TX. </list_item><list_item> If TX is not T, then a standard explicit conversion from TX to T is performed. <table_line/>
+</list_item></list></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/13.4.xml b/mcs/docs/ecma334/13.4.xml
new file mode 100644 (file)
index 0000000..6690b28
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="13.4" title="User-defined conversions">
+  <paragraph>C# allows the pre-defined implicit and explicit conversions to be augmented by user-defined conversions. User-defined conversions are introduced by declaring conversion operators (<hyperlink>17.9.3</hyperlink>) in class and struct types. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/13.xml b/mcs/docs/ecma334/13.xml
new file mode 100644 (file)
index 0000000..4007980
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<clause number="13" title="Conversions">
+  <paragraph>A conversion enables an expression of one type to be treated as another type. Conversions can be implicit or explicit, and this determines whether an explicit cast is required. <example>[Example: For instance, the conversion from type <keyword>int</keyword> to type <keyword>long</keyword> is implicit, so expressions of type <keyword>int</keyword> can implicitly be treated as type <keyword>long</keyword>. The opposite conversion, from type <keyword>long</keyword> to type <keyword>int</keyword>, is explicit and so an explicit cast is required. <code_example><![CDATA[
+int a = 123;  
+long b = a;     // implicit conversion from int to long  
+int c = (int) b;  // explicit conversion from long to int  
+]]></code_example>end example]</example> Some conversions are defined by the language. Programs may also define their own conversions (<hyperlink>13.4</hyperlink>). </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.1.1.xml b/mcs/docs/ecma334/14.1.1.xml
new file mode 100644 (file)
index 0000000..dc906e1
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="14.1.1" title="Values of expressions">
+  <paragraph>Most of the constructs that involve an expression ultimately require the expression to denote a value. In such cases, if the actual expression denotes a namespace, a type, a method group, or nothing, a compile-time error occurs. However, if the expression denotes a property access, an indexer access, or a variable, the value of the property, indexer, or variable is implicitly substituted: <list><list_item> The value of a variable is simply the value currently stored in the storage location identified by the variable. A variable must be considered definitely assigned (<hyperlink>12.3</hyperlink>) before its value can be obtained, or otherwise a compile-time error occurs. </list_item><list_item> The value of a property access expression is obtained by invoking the get-accessor of the property. If the property has no get-accessor, a compile-time error occurs. Otherwise, a function member invocation (<hyperlink>14.4.3</hyperlink>) is performed, and the result of the invocation becomes the value of the property access expression. </list_item><list_item> The value of an indexer access expression is obtained by invoking the get-accessor of the indexer. If the indexer has no get-accessor, a compile-time error occurs. Otherwise, a function member invocation (<hyperlink>14.4.3</hyperlink>) is performed with the argument list associated with the indexer access expression, and the result of the invocation becomes the value of the indexer access expression. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.1.xml b/mcs/docs/ecma334/14.1.xml
new file mode 100644 (file)
index 0000000..bcbd4a4
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="14.1" title="Expression classifications">
+  <paragraph>An expression is classified as one of the following: <list><list_item> A value. Every value has an associated type. </list_item><list_item> A variable. Every variable has an associated type, namely the declared type of the variable. </list_item><list_item> A namespace. An expression with this classification can only appear as the left-hand side of a  <non_terminal where="14.5.4">member-access</non_terminal> (<hyperlink>14.5.4</hyperlink>). In any other context, an expression classified as a namespace causes a compile-time error. </list_item><list_item> A type. An expression with this classification can only appear as the left-hand side of a <non_terminal where="14.5.4">member-access</non_terminal> (<hyperlink>14.5.4</hyperlink>), or as an operand for the as operator (<hyperlink>14.9.10</hyperlink>), the is operator (<hyperlink>14.9.9</hyperlink>), or the typeof operator (<hyperlink>14.5.11</hyperlink>). In any other context, an expression classified as a type causes a compile-time error. </list_item><list_item> A method group, which is a set of overloaded methods resulting from a member lookup (<hyperlink>14.3</hyperlink>). A method group may have an associated instance expression. When an instance method is invoked, the result of evaluating the instance expression becomes the instance represented by this (<hyperlink>14.5.7</hyperlink>). A method group is only permitted in an <non_terminal where="14.5.5">invocation-expression</non_terminal> (<hyperlink>14.5.5</hyperlink>) or a <non_terminal where="14.5.10.3">delegate-creation-expression</non_terminal> (<hyperlink>14.5.10.3</hyperlink>). In any other context, an expression classified as a method group causes a compile-time error. </list_item><list_item> A property access. Every property access has an associated type, namely the type of the property. Furthermore, a property access may have an associated instance expression. When an accessor (the get or set block) of an instance property access is invoked, the result of evaluating the instance expression becomes the instance represented by this (<hyperlink>14.5.7</hyperlink>). </list_item><list_item> An event access. Every event access has an associated type, namely the type of the event. Furthermore, an event access may have an associated instance expression. An event access may appear as the left-hand operand of the += and -= operators (<hyperlink>14.13.3</hyperlink>). In any other context, an expression classified as an event access causes a compile-time error. </list_item><list_item> An indexer access. Every indexer access has an associated type, namely the element type of the indexer. Furthermore, an indexer access has an associated instance expression and an associated argument list. When an accessor (the get or set block) of an indexer access is invoked, the result of evaluating the instance expression becomes the instance represented by this (<hyperlink>14.5.7</hyperlink>), and the result of evaluating the argument list becomes the parameter list of the invocation. </list_item><list_item> Nothing. This occurs when the expression is an invocation of a method with a return type of <keyword>void</keyword>. An expression classified as nothing is only valid in the context of a <non_terminal where="15.6">statement-expression</non_terminal> (<hyperlink>15.6</hyperlink>). </list_item></list></paragraph>
+  <paragraph>The final result of an expression is never a namespace, type, method group, or event access. Rather, as noted above, these categories of expressions are intermediate constructs that are only permitted in certain contexts. </paragraph>
+  <paragraph>A property access or indexer access is always reclassified as a value by performing an invocation of the  get-accessor or the set-accessor. The particular accessor is determined by the context of the property or indexer access: If the access is the target of an assignment, the set-accessor is invoked to assign a new value (<hyperlink>14.13.1</hyperlink>). Otherwise, the get-accessor is invoked to obtain the current value (<hyperlink>14.1.1</hyperlink>). </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.10.1.xml b/mcs/docs/ecma334/14.10.1.xml
new file mode 100644 (file)
index 0000000..f39d5ec
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<clause number="14.10.1" title="Integer logical operators">
+  <paragraph>The predefined integer logical operators are: <code_example><![CDATA[
+int operator &(int x, int y);  
+uint operator &(uint x, uint y);  
+long operator &(long x, long y);  
+ulong operator &(ulong x, ulong y);  
+int operator |(int x, int y);  
+uint operator |(uint x, uint y);  
+long operator |(long x, long y);  
+ulong operator |(ulong x, ulong y);  
+int operator ^(int x, int y);  
+uint operator ^(uint x, uint y);  
+long operator ^(long x, long y);  
+ulong operator ^(ulong x, ulong y);  
+]]></code_example></paragraph>
+  <paragraph>The &amp; operator computes the bitwise logical AND of the two operands, the | operator computes the bitwise logical OR of the two operands, and the ^ operator computes the bitwise logical exclusive OR of the two operands. No overflows are possible from these operations. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.10.2.xml b/mcs/docs/ecma334/14.10.2.xml
new file mode 100644 (file)
index 0000000..569d692
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<clause number="14.10.2" title="Enumeration logical operators">
+  <paragraph>Every enumeration type E implicitly provides the following predefined logical operators: <code_example><![CDATA[
+E operator &(E x, E y);  
+E operator |(E x, E y);  
+E operator ^(E x, E y);  
+]]></code_example></paragraph>
+  <paragraph>The result of evaluating x op y, where x and y are expressions of an enumeration type E with an underlying type U, and op is one of the logical operators, is exactly the same as evaluating (E)((U)x op (U)y). In other words, the enumeration type logical operators simply perform the logical operation on the underlying type of the two operands. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.10.3.xml b/mcs/docs/ecma334/14.10.3.xml
new file mode 100644 (file)
index 0000000..944ac6f
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<clause number="14.10.3" title="Boolean logical operators">
+  <paragraph>The predefined boolean logical operators are: <code_example><![CDATA[
+bool operator &(bool x, bool y);  
+bool operator |(bool x, bool y);  
+bool operator ^(bool x, bool y);  
+]]></code_example></paragraph>
+  <paragraph>The result of x &amp; y is true if both x and y are true. Otherwise, the result is false. </paragraph>
+  <paragraph>The result of x | y is true if either x or y is true. Otherwise, the result is false. </paragraph>
+  <paragraph>The result of x ^ y is true if x is true and y is false, or x is false and y is true. Otherwise, the result is false. When the operands are of type <keyword>bool</keyword>, the ^ operator computes the same result as the != operator. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.10.xml b/mcs/docs/ecma334/14.10.xml
new file mode 100644 (file)
index 0000000..abf117d
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="14.10" title="Logical operators">
+  <paragraph>The &amp;, ^, and | operators are called the logical operators. <grammar_production><name><non_terminal where="14.10">and-expression</non_terminal></name> : <rhs><non_terminal where="14.9">equality-expression</non_terminal></rhs><rhs><non_terminal where="14.10">and-expression</non_terminal><terminal>&amp;</terminal><non_terminal where="14.9">equality-expression</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="14.10">exclusive-or-expression</non_terminal></name> : <rhs><non_terminal where="14.10">and-expression</non_terminal></rhs><rhs><non_terminal where="14.10">exclusive-or-expression</non_terminal><terminal>^</terminal><non_terminal where="14.10">and-expression</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="14.10">inclusive-or-expression</non_terminal></name> : <rhs><non_terminal where="14.10">exclusive-or-expression</non_terminal></rhs><rhs><non_terminal where="14.10">inclusive-or-expression</non_terminal><terminal>|</terminal><non_terminal where="14.10">exclusive-or-expression</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>For an operation of the form x op y, where op is one of the logical operators, overload resolution (<hyperlink>14.2.4</hyperlink>) is applied to select a specific operator implementation. The operands are converted to the parameter types of the selected operator, and the type of the result is the return type of the operator. </paragraph>
+  <paragraph>The predefined logical operators are described in the following sections. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.11.1.xml b/mcs/docs/ecma334/14.11.1.xml
new file mode 100644 (file)
index 0000000..011b32c
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="14.11.1" title="Boolean conditional logical operators">
+  <paragraph>When the operands of &amp;&amp; or || are of type <keyword>bool</keyword>, or when the operands are of types that do not define an applicable operator &amp; or operator |, but do define implicit conversions to <keyword>bool</keyword>, the operation is processed as follows: <list><list_item> The operation x &amp;&amp; y is evaluated as x ? y : false. In other words, x is first evaluated and converted to type <keyword>bool</keyword>. Then, if x is true, y is evaluated and converted to type <keyword>bool</keyword>, and this becomes the result of the operation. Otherwise, the result of the operation is false. </list_item><list_item> The operation x || y is evaluated as x ? true : y. In other words, x is first evaluated and converted to type <keyword>bool</keyword>. Then, if x is true, the result of the operation is true. Otherwise, y is evaluated and converted to type <keyword>bool</keyword>, and this becomes the result of the operation. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.11.2.xml b/mcs/docs/ecma334/14.11.2.xml
new file mode 100644 (file)
index 0000000..505a85d
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<clause number="14.11.2" title="User-defined conditional logical operators">
+  <paragraph>When the operands of &amp;&amp; or || are of types that declare an applicable user-defined operator &amp; or operator |, both of the following must be true, where T is the type in which the selected operator is declared: <list><list_item> The return type and the type of each parameter of the selected operator must be T. In other words, the operator must compute the logical AND or the logical OR of two operands of type T, and must return a result of type T. </list_item><list_item> T must contain declarations of operator true and operator false. </list_item></list></paragraph>
+  <paragraph>A compile-time error occurs if either of these requirements is not satisfied. Otherwise, the &amp;&amp; or || operation is evaluated by combining the user-defined operator true or operator false with the selected user-defined operator: <list><list_item> The operation x &amp;&amp; y is evaluated as T.false(x) ? x : T.&amp;(x, y), where T.false(x) is an invocation of the operator false declared in T, and T.&amp;(x, y) is an invocation of the selected operator &amp;. In other words, x is first evaluated and operator false is invoked on the result to determine if x is definitely false. Then, if x is definitely false, the result of the operation is the value previously computed for x. Otherwise, y is evaluated, and the selected operator &amp; is invoked on the value previously computed for x and the value computed for y to produce the result of the operation. </list_item><list_item> The operation x || y is evaluated as T.true(x) ? x : T.|(x, y), where T.true(x) is an invocation of the operator true declared in T, and T.|(x, y) is an invocation of the selected operator |. In other words, x is first evaluated and operator true is invoked on the result to determine if x is definitely true. Then, if x is definitely true, the result of the operation is the value previously computed for x. Otherwise, y is evaluated, and the selected operator | is invoked on the value previously computed for x and the value computed for y to produce the result of the operation. </list_item></list></paragraph>
+  <paragraph>In either of these operations, the expression given by x is only evaluated once, and the expression given by y is either not evaluated or evaluated exactly once. </paragraph>
+  <paragraph>For an example of a type that implements operator true and operator false, see <hyperlink>18.4.2</hyperlink>. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.11.xml b/mcs/docs/ecma334/14.11.xml
new file mode 100644 (file)
index 0000000..4c70ef8
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<clause number="14.11" title="Conditional logical operators">
+  <paragraph>The &amp;&amp; and || operators are called the conditional logical operators. They are also called the  &quot;short-circuiting&quot; logical operators. <grammar_production><name><non_terminal where="14.11">conditional-and-expression</non_terminal></name> : <rhs><non_terminal where="14.10">inclusive-or-expression</non_terminal></rhs><rhs><non_terminal where="14.11">conditional-and-expression</non_terminal><terminal>&amp;&amp;</terminal><non_terminal where="14.10">inclusive-or-expression</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="14.11">conditional-or-expression</non_terminal></name> : <rhs><non_terminal where="14.11">conditional-and-expression</non_terminal></rhs><rhs><non_terminal where="14.11">conditional-or-expression</non_terminal><terminal>||</terminal><non_terminal where="14.11">conditional-and-expression</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>The &amp;&amp; and || operators are conditional versions of the &amp; and | operators: <list><list_item> The operation x &amp;&amp; y corresponds to the operation x &amp; y, except that y is evaluated only if x is true. </list_item><list_item> The operation x || y corresponds to the operation x | y, except that y is evaluated only if x is false. </list_item></list></paragraph>
+  <paragraph>An operation of the form x &amp;&amp; y or x || y is processed by applying overload resolution (<hyperlink>14.2.4</hyperlink>) as if the operation was written x &amp; y or x | y. Then, <list><list_item> If overload resolution fails to find a single best operator, or if overload resolution selects one of the predefined integer logical operators, a compile-time error occurs. </list_item><list_item> Otherwise, if the selected operator is one of the predefined boolean logical operators (<hyperlink>14.10.2</hyperlink>), the operation is processed as described in <hyperlink>14.11.1</hyperlink>. </list_item><list_item> Otherwise, the selected operator is a user-defined operator, and the operation is processed as described in <hyperlink>14.11.2</hyperlink>. </list_item></list></paragraph>
+  <paragraph>It is not possible to directly overload the conditional logical operators. However, because the conditional logical operators are evaluated in terms of the regular logical operators, overloads of the regular logical operators are, with certain restrictions, also considered overloads of the conditional logical operators. This is described further in <hyperlink>14.11.2</hyperlink>. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.12.xml b/mcs/docs/ecma334/14.12.xml
new file mode 100644 (file)
index 0000000..0bac1c1
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<clause number="14.12" title="Conditional operator">
+  <paragraph>The ?: operator is called the conditional operator. It is at times also called the ternary operator. <grammar_production><name><non_terminal where="14.12">conditional-expression</non_terminal></name> : <rhs><non_terminal where="14.11">conditional-or-expression</non_terminal></rhs><rhs><non_terminal where="14.11">conditional-or-expression</non_terminal><terminal>?</terminal><non_terminal where="14.14">expression</non_terminal><terminal>:</terminal><non_terminal where="14.14">expression</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>A conditional expression of the form b ? x : y first evaluates the condition b. Then, if b is true, x is evaluated and becomes the result of the operation. Otherwise, y is evaluated and becomes the result of the operation. A conditional expression never evaluates both x and y. </paragraph>
+  <paragraph>The conditional operator is right-associative, meaning that operations are grouped from right to left. For example, an expression of the form a ? b : c ? d : e is evaluated as a ? b : (c ? d : e). </paragraph>
+  <paragraph>The first operand of the ?: operator must be an expression of a type that can be implicitly converted to <keyword>bool</keyword>, or an expression of a type that implements operator true. If neither of these requirements is satisfied, a compile-time error occurs. </paragraph>
+  <paragraph>The second and third operands of the ?: operator control the type of the conditional expression. Let X and Y be the types of the second and third operands. Then, <list><list_item> If X and Y are the same type, then this is the type of the conditional expression. </list_item><list_item> Otherwise, if an implicit conversion (<hyperlink>13.1</hyperlink>) exists from X to Y, but not from Y to X, then Y is the type of the conditional expression. </list_item><list_item> Otherwise, if an implicit conversion (<hyperlink>13.1</hyperlink>) exists from Y to X, but not from X to Y, then X is the type of the conditional expression. </list_item><list_item> Otherwise, no expression type can be determined, and a compile-time error occurs. </list_item></list></paragraph>
+  <paragraph>The run-time processing of a conditional expression of the form b ? x : y consists of the following steps: <list><list_item> First, b is evaluated, and the <keyword>bool</keyword> value of b is determined: </list_item><list><list_item> If an implicit conversion from the type of b to <keyword>bool</keyword> exists, then this implicit conversion is performed to produce a <keyword>bool</keyword> value. </list_item><list_item> Otherwise, the operator true defined by the type of b is invoked to produce a <keyword>bool</keyword> value. </list_item></list><list_item> If the <keyword>bool</keyword> value produced by the step above is true, then x is evaluated and converted to the type of the conditional expression, and this becomes the result of the conditional expression. </list_item><list_item> Otherwise, y is evaluated and converted to the type of the conditional expression, and this becomes the result of the conditional expression. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.13.1.xml b/mcs/docs/ecma334/14.13.1.xml
new file mode 100644 (file)
index 0000000..ff585c4
--- /dev/null
@@ -0,0 +1,66 @@
+<?xml version="1.0"?>
+<clause number="14.13.1" title="Simple assignment">
+  <paragraph>The = operator is called the simple assignment operator. In a simple assignment, the right operand must be an expression of a type that is implicitly convertible to the type of the left operand. The operation assigns the value of the right operand to the variable, property, or indexer element given by the left operand. </paragraph>
+  <paragraph>The result of a simple assignment expression is the value assigned to the left operand. The result has the same type as the left operand and is always classified as a value. </paragraph>
+  <paragraph>If the left operand is a property or indexer access, the property or indexer must have a set accessor. If this is not the case, a compile-time error occurs. </paragraph>
+  <paragraph>The run-time processing of a simple assignment of the form x = y consists of the following steps: <list><list_item> If x is classified as a variable: </list_item><list><list_item> x is evaluated to produce the variable. </list_item><list_item> y is evaluated and, if required, converted to the type of x through an implicit conversion (<hyperlink>13.1</hyperlink>). </list_item><list_item> If the variable given by x is an array element of a <non_terminal where="11.2">reference-type</non_terminal>, a run-time check is performed to ensure that the value computed for y is compatible with the array instance of which x is an element. The check succeeds if y is null, or if an implicit reference conversion (<hyperlink>13.1.4</hyperlink>) exists from the actual type of the instance referenced by y to the actual element type of the array instance containing x. Otherwise, a System.ArrayTypeMismatchException is thrown. </list_item><list_item> The value resulting from the evaluation and conversion of y is stored into the location given by the evaluation of x. </list_item></list><list_item> If x is classified as a property or indexer access: </list_item><list><list_item> The instance expression (if x is not static) and the argument list (if x is an indexer access) associated with x are evaluated, and the results are used in the subsequent set accessor invocation. </list_item><list_item> y is evaluated and, if required, converted to the type of x through an implicit conversion (<hyperlink>13.1</hyperlink>). </list_item><list_item> The set accessor of x is invoked with the value computed for y as its value argument. </list_item></list></list></paragraph>
+  <paragraph>
+    <note>[Note: The array covariance rules (<hyperlink>19.5</hyperlink>) permit a value of an array type A[] to be a reference to an instance of an array type B[], provided an implicit reference conversion exists from B to A. Because of these rules, assignment to an array element of a <non_terminal where="11.2">reference-type</non_terminal> requires a run-time check to ensure that the value being assigned is compatible with the array instance. In the example <code_example><![CDATA[
+string[] sa = new string[10];  
+object[] oa = sa;  
+oa[0] = null;      // Ok  
+oa[1] = "Hello";     // Ok  
+oa[2] = new ArrayList();  // ArrayTypeMismatchException  
+]]></code_example>the last assignment causes a System.ArrayTypeMismatchException to be thrown because an instance of ArrayList cannot be stored in an element of a string[]. end note]</note>
+  </paragraph>
+  <paragraph>When a property or indexer declared in a <non_terminal where="11.1">struct-type</non_terminal> is the target of an assignment, the instance expression associated with the property or indexer access must be classified as a variable. If the instance expression is classified as a value, a compile-time error occurs. <note>[Note: Because of <hyperlink>14.5.4</hyperlink>, the same rule also applies to fields. end note]</note> </paragraph>
+  <paragraph>
+    <example>[Example: Given the declarations: <code_example><![CDATA[
+struct Point  
+{  
+   int x, y;  
+   public Point(int x, int y) {  
+      this.x = x;  
+      this.y = y;  
+   }  
+   public int X {  
+      get { return x; }  
+      set { x = value; }  
+   }  
+   public int Y {  
+      get { return y; }  
+      set { y = value; }  
+   }  
+}  
+struct Rectangle  
+{  
+   Point a, b;  
+   public Rectangle(Point a, Point b) {  
+      this.a = a;  
+      this.b = b;  
+   }  
+   public Point A {  
+      get { return a; }  
+      set { a = value; }  
+   }  
+   public Point B {  
+      get { return b; }  
+      set { b = value; }  
+   }  
+}  
+]]></code_example>in the example <code_example><![CDATA[
+Point p = new Point();  
+p.X = 100;  
+p.Y = 100;  
+Rectangle r = new Rectangle();  
+r.A = new Point(10, 10);  
+r.B = p;  
+]]></code_example>the assignments to p.X, p.Y, r.A, and r.B are permitted because p and r are variables. However, in the example <code_example><![CDATA[
+Rectangle r = new Rectangle();  
+r.A.X = 10;  
+r.A.Y = 10;  
+r.B.X = 100;  
+r.B.Y = 100;  
+]]></code_example>the assignments are all invalid, since r.A and r.B are not variables. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.13.2.xml b/mcs/docs/ecma334/14.13.2.xml
new file mode 100644 (file)
index 0000000..42bf9b2
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<clause number="14.13.2" title="Compound assignment">
+  <paragraph>An operation of the form x op= y is processed by applying binary operator overload resolution (<hyperlink>14.2.4</hyperlink>) as if the operation was written x op y. Then, <list><list_item> If the return type of the selected operator is implicitly convertible to the type of x, the operation is evaluated as x = x op y, except that x is evaluated only once. </list_item><list_item> Otherwise, if the selected operator is a predefined operator, if the return type of the selected operator is explicitly convertible to the type of x, and if y is implicitly convertible to the type of x, then the operation is evaluated as x = (T)(x op y), where T is the type of x, except that x is evaluated only once. </list_item><list_item> Otherwise, the compound assignment is invalid, and a compile-time error occurs. </list_item></list></paragraph>
+  <paragraph>The term &quot;evaluated only once&quot; means that in the evaluation of x op y, the results of any constituent expressions of x are temporarily saved and then reused when performing the assignment to x. <example>[Example: For example, in the assignment A()[B()] += C(), where A is a method returning int[], and B and C are methods returning <keyword>int</keyword>, the methods are invoked only once, in the order A, B, C. end example]</example> </paragraph>
+  <paragraph>When the left operand of a compound assignment is a property access or indexer access, the property or indexer must have both a get accessor and a set accessor. If this is not the case, a compile-time error occurs. </paragraph>
+  <paragraph>The second rule above permits x op= y to be evaluated as x = (T)(x op y) in certain contexts. The rule exists such that the predefined operators can be used as compound operators when the left operand is of type <keyword>sbyte</keyword>, <keyword>byte</keyword>, <keyword>short</keyword>, <keyword>ushort</keyword>, or <keyword>char</keyword>. Even when both arguments are of one of those types, the predefined operators produce a result of type <keyword>int</keyword>, as described in <hyperlink>14.2.6.2</hyperlink>. Thus, without a cast it would not be possible to assign the result to the left operand. </paragraph>
+  <paragraph>The intuitive effect of the rule for predefined operators is simply that x op= y is permitted if both of x op y and x = y are permitted. <example>[Example: In the example <code_example><![CDATA[
+byte b = 0;  
+char ch = '\0';  
+int i = 0;  
+b += 1;        // Ok  
+b += 1000;      // Error, b = 1000 not permitted  
+b += i;        // Error, b = i not permitted  
+b += (byte)i;    // Ok  
+ch += 1;       // Error, ch = 1 not permitted  
+ch += (char)1;   // Ok  
+]]></code_example>the intuitive reason for each error is that a corresponding simple assignment would also have been an error. end example]</example> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.13.3.xml b/mcs/docs/ecma334/14.13.3.xml
new file mode 100644 (file)
index 0000000..a7d4536
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="14.13.3" title="Event assignment">
+  <paragraph>If the left operand of a += or -= operator is classified as an event access, then the expression is evaluated as follows: <list><list_item> The instance expression, if any, of the event access is evaluated. </list_item><list_item> The right operand of the += or -= operator is evaluated, and, if required, converted to the type of the left operand through an implicit conversion (<hyperlink>13.1</hyperlink>). </list_item><list_item> An event accessor of the event is invoked, with argument list consisting of the right operand, after evaluation and, if necessary, conversion. If the operator was +=, the add accessor is invoked; if the operator was -=, the remove accessor is invoked. </list_item></list></paragraph>
+  <paragraph>An event assignment expression does not yield a value. Thus, an event assignment expression is valid only in the context of a <non_terminal where="15.6">statement-expression</non_terminal> (<hyperlink>15.6</hyperlink>). </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.13.xml b/mcs/docs/ecma334/14.13.xml
new file mode 100644 (file)
index 0000000..95aa398
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<clause number="14.13" title="Assignment operators">
+  <paragraph>The assignment operators assign a new value to a variable, a property, event, or an indexer element. <grammar_production><name>assignment</name> : <rhs><non_terminal where="14.6">unary-expression</non_terminal><non_terminal where="14.13">assignment-operator</non_terminal><non_terminal where="14.14">expression</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="14.13">assignment-operator</non_terminal></name> : one of <rhs><terminal>=</terminal><terminal>+=</terminal><terminal>-=</terminal><terminal>*=</terminal><terminal>/=</terminal><terminal>%=</terminal><terminal>&amp;=</terminal><terminal>|=</terminal><terminal>^=</terminal><terminal>&lt;&lt;=</terminal><terminal>&gt;&gt;=</terminal></rhs></grammar_production></paragraph>
+  <paragraph>The left operand of an assignment must be an expression classified as a variable, a property access, an indexer access, or an event access. </paragraph>
+  <paragraph>The = operator is called the simple assignment operator. It assigns the value of the right operand to the variable, property, or indexer element given by the left operand. The left operand of the simple assignment operator may not be an event access (except as described in <hyperlink>17.7.1</hyperlink>). The simple assignment operator is described in <hyperlink>14.13.1</hyperlink>. </paragraph>
+  <paragraph>The operators formed by prefixing a binary operator with an = character are called the compound assignment operators. These operators perform the indicated operation on the two operands, and then assign the resulting value to the variable, property, or indexer element given by the left operand. The compound assignment operators are described in <hyperlink>14.13.2</hyperlink>. </paragraph>
+  <paragraph>The += and -= operators with an event access expression as the left operand are called the event assignment operators. No other assignment operator is valid with an event access as the left operand. The event assignment operators are described in <hyperlink>14.13.3</hyperlink>. </paragraph>
+  <paragraph>The assignment operators are right-associative, meaning that operations are grouped from right to left. For example, an expression of the form a = b = c is evaluated as a = (b = c). </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.14.xml b/mcs/docs/ecma334/14.14.xml
new file mode 100644 (file)
index 0000000..36d4eb0
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="14.14" title="Expression">
+  <paragraph>An expression is either a <non_terminal where="14.12">conditional-expression</non_terminal> or an assignment. <grammar_production><name>expression</name> : <rhs><non_terminal where="14.12">conditional-expression</non_terminal></rhs><rhs><non_terminal where="14.13">assignment</non_terminal></rhs></grammar_production></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.15.xml b/mcs/docs/ecma334/14.15.xml
new file mode 100644 (file)
index 0000000..156cd49
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<clause number="14.15" title="Constant expressions">
+  <paragraph>A <non_terminal where="14.15">constant-expression</non_terminal> is an expression that can be fully evaluated at compile-time. <grammar_production><name><non_terminal where="14.15">constant-expression</non_terminal></name> : <rhs><non_terminal where="14.14">expression</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>The type of a constant expression can be one of the following: <keyword>sbyte</keyword>, <keyword>byte</keyword>, <keyword>short</keyword>, <keyword>ushort</keyword>, <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>long</keyword>, <keyword>ulong</keyword>, <keyword>char</keyword>, <keyword>float</keyword>, <keyword>double</keyword>, <keyword>decimal</keyword>, <keyword>bool</keyword>, string, any enumeration type, or the null type. The following constructs are permitted in constant expressions: <list><list_item> Literals (including the null literal). </list_item><list_item> References to const members of class and struct types. </list_item><list_item> References to members of enumeration types. </list_item><list_item> Parenthesized sub-expressions, which are themselves constant expressions. </list_item><list_item> Cast expressions, provided the target type is one of the types listed above. </list_item><list_item> The predefined +, -, !, and ~ unary operators. </list_item><list_item> The predefined +, -, *, /, %, &lt;&lt;, &gt;&gt;, &amp;, |, ^, &amp;&amp;, ||, ==, !=, &lt;, &gt;, &lt;=, and &gt;= binary operators, provided each operand is of a type listed above. </list_item><list_item> The ?: conditional operator. </list_item></list></paragraph>
+  <paragraph>Whenever an expression is of one of the types listed above and contains only the constructs listed above, the expression is evaluated at compile-time. This is true even if the expression is a sub-expression of a larger expression that contains non-constant constructs. </paragraph>
+  <paragraph>The compile-time evaluation of constant expressions uses the same rules as run-time evaluation of  non-constant expressions, except that where run-time evaluation would have thrown an exception, compile-time evaluation causes a compile-time error to occur. </paragraph>
+  <paragraph>Unless a constant expression is explicitly placed in an unchecked context, overflows that occur in  <non_terminal where="11.1">integral-type</non_terminal> arithmetic operations and conversions during the compile-time evaluation of the expression always cause compile-time errors (<hyperlink>14.5.12</hyperlink>). </paragraph>
+  <paragraph>Constant expressions occur in the contexts listed below. In these contexts, a compile-time error occurs if an expression cannot be fully evaluated at compile-time. <list><list_item> Constant declarations (<hyperlink>17.3</hyperlink>). </list_item><list_item> Enumeration member declarations (<hyperlink>21.30</hyperlink>). </list_item><list_item> case labels of a switch statement (<hyperlink>15.7.2</hyperlink>). </list_item><list_item> goto case statements (<hyperlink>15.9.3</hyperlink>). </list_item><list_item> Dimension lengths in an array creation expression (<hyperlink>14.5.10.2</hyperlink>) that includes an initializer. </list_item><list_item> Attributes (<hyperlink>24</hyperlink>). </list_item></list></paragraph>
+  <paragraph>An implicit constant expression conversion (<hyperlink>13.1.6</hyperlink>) permits a constant expression of type <keyword>int</keyword> to be converted to <keyword>sbyte</keyword>, <keyword>byte</keyword>, <keyword>short</keyword>, <keyword>ushort</keyword>, <keyword>uint</keyword>, or <keyword>ulong</keyword>, provided the value of the constant expression is within the range of the destination type. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.16.xml b/mcs/docs/ecma334/14.16.xml
new file mode 100644 (file)
index 0000000..1587f79
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<clause number="14.16" title="Boolean expressions">
+  <paragraph>A <non_terminal where="15.7.1">boolean-expression</non_terminal> is an expression that yields a result of type <keyword>bool</keyword>. <grammar_production><name><non_terminal where="15.7.1">boolean-expression</non_terminal></name> : <rhs><non_terminal where="14.14">expression</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>The controlling conditional expression of an <non_terminal where="15.7.1">if-statement</non_terminal> (<hyperlink>15.7.1</hyperlink>), <non_terminal where="15.8.1">while-statement</non_terminal> (<hyperlink>15.8.1</hyperlink>), <non_terminal where="15.8.2">do-statement</non_terminal> (<hyperlink>15.8.2</hyperlink>), or <non_terminal where="15.8.3">for-statement</non_terminal> (<hyperlink>15.8.3</hyperlink>) is a <non_terminal where="15.7.1">boolean-expression</non_terminal>. The controlling conditional expression of the ?: operator (<hyperlink>14.12</hyperlink>) follows the same rules as a <non_terminal where="15.7.1">boolean-expression</non_terminal>, but for reasons of operator precedence is classified as a <non_terminal where="14.11">conditional-or-expression</non_terminal>. </paragraph>
+  <paragraph>A <non_terminal where="15.7.1">boolean-expression</non_terminal> is required to be of a type that can be implicitly converted to <keyword>bool</keyword> or of a type that implements operator true. <note>[Note: As required by <hyperlink>17.9.1</hyperlink>, any type that implements operator true must also implement operator false. end note]</note> If neither requirement is satisfied, a compile-time error occurs. </paragraph>
+  <paragraph>When a boolean expression is of a type that cannot be implicitly converted to <keyword>bool</keyword> but does implement operator true, then following evaluation of the expression, the operator true implementation provided by that type is invoked to produce a <keyword>bool</keyword> value. </paragraph>
+  <paragraph>
+    <note>[Note: The DBBool struct type in <hyperlink>18.4.2</hyperlink> provides an example of a type that implements operator true and operator false. end note]</note>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.2.1.xml b/mcs/docs/ecma334/14.2.1.xml
new file mode 100644 (file)
index 0000000..99c4818
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<clause number="14.2.1" title="Operator precedence and associativity">
+  <paragraph>When an expression contains multiple operators, the precedence of the operators controls the order in which the individual operators are evaluated. <note>[Note: For example, the expression x + y * z is evaluated as x + (y * z) because the * operator has higher precedence than the binary + operator. end note]</note> The precedence of an operator is established by the definition of its associated grammar production. <note>[Note: For example, an <non_terminal where="14.7">additive-expression</non_terminal> consists of a sequence of <non_terminal where="14.7">multiplicative-expression</non_terminal>s separated by + or  -operators, thus giving the + and  -operators lower precedence than the *, /, and % operators. end note]</note> </paragraph>
+  <paragraph>The following table summarizes all operators in order of precedence from highest to lowest: <table_line>Section Category Operators </table_line>
+<table_line>14.5 Primary x.y f(x) a[x] x++  x--new </table_line>
+<table_line>typeof checked unchecked </table_line>
+<table_line>14.6 Unary +  -! ~ ++x --x (T)x </table_line>
+<table_line>14.7 Multiplicative * / % </table_line>
+<table_line>14.7 Additive +  </table_line>
+<table_line>-14.8 Shift &lt;&lt; &gt;&gt; </table_line>
+<table_line>14.9 Relational and </table_line>
+<table_line>type-testing </table_line>
+<table_line>&lt; &gt; &lt;= &gt;= is as </table_line>
+<table_line>14.9 Equality == != </table_line>
+<table_line>14.10 Logical AND &amp; </table_line>
+<table_line>14.10 Logical XOR ^ </table_line>
+<table_line>14.10 Logical OR | </table_line>
+<table_line>14.11 Conditional AND &amp;&amp; </table_line>
+<table_line>14.11 Conditional OR || </table_line>
+<table_line>14.12 Conditional ?: </table_line>
+<table_line>14.13 Assignment = *= /= %= += -= &lt;&lt;= &gt;&gt;= &amp;= ^= |= </table_line>
+When an operand occurs between two operators with the same precedence, the associativity of the operators controls the order in which the operations are performed: <list><list_item> Except for the assignment operators, all binary operators are left-associative, meaning that operations are performed from left to right. <example>[Example: For example, x + y + z is evaluated as (x + y) + z. end example]</example> </list_item><list_item> The assignment operators and the conditional operator (?:) are right-associative, meaning that operations are performed from right to left. <example>[Example: For example, x = y = z is evaluated as x = (y = z). end example]</example> </list_item></list></paragraph>
+  <paragraph>Precedence and associativity can be controlled using parentheses. <example>[Example: For example, x + y * z first multiplies y by z and then adds the result to x, but (x + y) * z first adds x and y and then multiplies the result by z. end example]</example> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.2.2.xml b/mcs/docs/ecma334/14.2.2.xml
new file mode 100644 (file)
index 0000000..3b1ce18
--- /dev/null
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<clause number="14.2.2" title="Operator overloading">
+  <paragraph>All unary and binary operators have predefined implementations that are automatically available in any expression. In addition to the predefined implementations, user-defined implementations can be introduced by including operator declarations in classes and structs (<hyperlink>17.9</hyperlink>). User-defined operator implementations always take precedence over predefined operator implementations: Only when no applicable user-defined operator implementations exist will the predefined operator implementations be considered. </paragraph>
+  <paragraph>The overloadable unary operators are: <code_example><![CDATA[
++   -   !   ~   ++   --   true   false  
+]]></code_example></paragraph>
+  <paragraph>
+    <note>[Note: Although true and false are not used explicitly in expressions, they are considered operators because they are invoked in several expression contexts: boolean expressions (<hyperlink>14.16</hyperlink>) and expressions involving the conditional (<hyperlink>14.12</hyperlink>), and conditional logical operators (<hyperlink>14.11</hyperlink>). end note]</note>
+  </paragraph>
+  <paragraph>The overloadable binary operators are: <code_example><![CDATA[
++   -   *   /   %   &   |   ^   <<   >>   ==   !=   >   <   >=   <=  
+]]></code_example></paragraph>
+  <paragraph>Only the operators listed above can be overloaded. In particular, it is not possible to overload member access, method invocation, or the =, &amp;&amp;, ||, ?:, checked, unchecked, new, typeof, as, and is operators. </paragraph>
+  <paragraph>When a binary operator is overloaded, the corresponding assignment operator, if any, is also implicitly overloaded. For example, an overload of operator * is also an overload of operator *=. This is described further in <hyperlink>14.13</hyperlink>. Note that the assignment operator itself (=) cannot be overloaded. An assignment always performs a simple bit-wise copy of a value into a variable. </paragraph>
+  <paragraph>Cast operations, such as (T)x, are overloaded by providing user-defined conversions (<hyperlink>13.4</hyperlink>). </paragraph>
+  <paragraph>Element access, such as a[x], is not considered an overloadable operator. Instead, user-defined indexing is supported through indexers (<hyperlink>17.8</hyperlink>). </paragraph>
+  <paragraph>In expressions, operators are referenced using operator notation, and in declarations, operators are referenced using functional notation. The following table shows the relationship between operator and functional notations for unary and binary operators. In the first entry, op denotes any overloadable unary prefix operator. In the second entry, op denotes the unary postfix ++ and  --operators. In the third entry, op denotes any overloadable binary operator. <note>[Note: For an example of overloading the ++ and  --operators see <hyperlink>17.9.1</hyperlink>. end note]</note> <table_line>Operator notation Functional notation </table_line>
+<table_line>op x operator op(x) </table_line>
+<table_line>x op operator op(x) </table_line>
+<table_line>x opy operator op(x, y) </table_line>
+</paragraph>
+  <paragraph>User-defined operator declarations always require at least one of the parameters to be of the class or struct type that contains the operator declaration. <note>[Note: Thus, it is not possible for a user-defined operator to have the same signature as a predefined operator. end note]</note> </paragraph>
+  <paragraph>User-defined operator declarations cannot modify the syntax, precedence, or associativity of an operator. </paragraph>
+  <paragraph>
+    <example>[Example: For example, the / operator is always a binary operator, always has the precedence level specified in <hyperlink>14.2.1</hyperlink>, and is always left-associative. end example]</example>
+  </paragraph>
+  <paragraph>
+    <note>[Note: While it is possible for a user-defined operator to perform any computation it pleases, implementations that produce results other than those that are intuitively expected are strongly discouraged. </note>
+  </paragraph>
+  <paragraph>
+    <note>For example, an implementation of operator == should compare the two operands for equality and return an appropriate <keyword>bool</keyword> result. end note]</note>
+  </paragraph>
+  <paragraph>The descriptions of individual operators in <hyperlink>14.5</hyperlink> through <hyperlink>14.13</hyperlink> specify the predefined implementations of the operators and any additional rules that apply to each operator. The descriptions make use of the terms unary operator overload resolution, binary operator overload resolution, and numeric promotion, definitions of which are found in the following sections. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.2.3.xml b/mcs/docs/ecma334/14.2.3.xml
new file mode 100644 (file)
index 0000000..018ab97
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="14.2.3" title="Unary operator overload resolution">
+  <paragraph>An operation of the form op x or x op, where op is an overloadable unary operator, and x is an expression of type X, is processed as follows: <list><list_item> The set of candidate user-defined operators provided by X for the operation operator op(x) is determined using the rules of <hyperlink>14.2.5</hyperlink>. </list_item><list_item> If the set of candidate user-defined operators is not empty, then this becomes the set of candidate operators for the operation. Otherwise, the predefined unary operator op implementations become the set of candidate operators for the operation. The predefined implementations of a given operator are specified in the description of the operator (<hyperlink>14.5</hyperlink> and <hyperlink>14.6</hyperlink>). </list_item><list_item> The overload resolution rules of <hyperlink>14.4.2</hyperlink> are applied to the set of candidate operators to select the best operator with respect to the argument list (x), and this operator becomes the result of the overload resolution process. If overload resolution fails to select a single best operator, a compile-time error occurs. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.2.4.xml b/mcs/docs/ecma334/14.2.4.xml
new file mode 100644 (file)
index 0000000..dc428dd
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="14.2.4" title="Binary operator overload resolution">
+  <paragraph>An operation of the form x op y, where op is an overloadable binary operator, x is an expression of type X, and y is an expression of type Y, is processed as follows: <list><list_item> The set of candidate user-defined operators provided by X and Y for the operation operator op(x, y) is determined. The set consists of the union of the candidate operators provided by X and the candidate operators provided by Y, each determined using the rules of <hyperlink>14.2.5</hyperlink>. If X and Y are the same type, or if X and Y are derived from a common base type, then shared candidate operators only occur in the combined set once. </list_item><list_item> If the set of candidate user-defined operators is not empty, then this becomes the set of candidate operators for the operation. Otherwise, the predefined binary operator op implementations become the set of candidate operators for the operation. The predefined implementations of a given operator are specified in the description of the operator (<hyperlink>14.7</hyperlink> through <hyperlink>14.13</hyperlink>). </list_item><list_item> The overload resolution rules of <hyperlink>14.4.2</hyperlink> are applied to the set of candidate operators to select the best operator with respect to the argument list (x, y), and this operator becomes the result of the overload resolution process. If overload resolution fails to select a single best operator, a compile-time error occurs. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.2.5.xml b/mcs/docs/ecma334/14.2.5.xml
new file mode 100644 (file)
index 0000000..4e94a98
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="14.2.5" title="Candidate user-defined operators">
+  <paragraph>Given a type T and an operation operator op(A), where op is an overloadable operator and A is an argument list, the set of candidate user-defined operators provided by T for operator op(A) is determined as follows: <list><list_item> For all operator op declarations in T, if at least one operator is applicable (<hyperlink>14.4.2.1</hyperlink>) with respect to the argument list A, then the set of candidate operators consists of all applicable operator op declarations in T. </list_item><list_item> Otherwise, if T is object, the set of candidate operators is empty. </list_item><list_item> Otherwise, the set of candidate operators provided by T is the set of candidate operators provided by the direct base class of T. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.2.6.1.xml b/mcs/docs/ecma334/14.2.6.1.xml
new file mode 100644 (file)
index 0000000..2197fff
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="14.2.6.1" title="Unary numeric promotions" informative="true">
+  <paragraph>This clause is informative. </paragraph>
+  <paragraph>Unary numeric promotion occurs for the operands of the predefined +, -, and ~ unary operators. Unary numeric promotion simply consists of converting operands of type <keyword>sbyte</keyword>, <keyword>byte</keyword>, <keyword>short</keyword>, <keyword>ushort</keyword>, or <keyword>char</keyword> to type <keyword>int</keyword>. Additionally, for the unary  -operator, unary numeric promotion converts operands of type <keyword>uint</keyword> to type <keyword>long</keyword>. </paragraph>
+  <paragraph>End of informative text. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.2.6.2.xml b/mcs/docs/ecma334/14.2.6.2.xml
new file mode 100644 (file)
index 0000000..3bad6bd
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<clause number="14.2.6.2" title="Binary numeric promotions" informative="true">
+  <paragraph>This clause is informative. </paragraph>
+  <paragraph>Binary numeric promotion occurs for the operands of the predefined +, -, *, /, %, &amp;, |, ^, ==, !=, &gt;, &lt;, &gt;=, and &lt;= binary operators. Binary numeric promotion implicitly converts both operands to a common type which, in case of the non-relational operators, also becomes the result type of the operation. Binary numeric promotion consists of applying the following rules, in the order they appear here: <list><list_item> If either operand is of type <keyword>decimal</keyword>, the other operand is converted to type <keyword>decimal</keyword>, or a  compile-time error occurs if the other operand is of type <keyword>float</keyword> or <keyword>double</keyword>. </list_item><list_item> Otherwise, if either operand is of type <keyword>double</keyword>, the other operand is converted to type <keyword>double</keyword>. </list_item><list_item> Otherwise, if either operand is of type <keyword>float</keyword>, the other operand is converted to type <keyword>float</keyword>. </list_item><list_item> Otherwise, if either operand is of type <keyword>ulong</keyword>, the other operand is converted to type <keyword>ulong</keyword>, or a compile-time error occurs if the other operand is of type <keyword>sbyte</keyword>, <keyword>short</keyword>, <keyword>int</keyword>, or <keyword>long</keyword>. </list_item><list_item> Otherwise, if either operand is of type <keyword>long</keyword>, the other operand is converted to type <keyword>long</keyword>. </list_item><list_item> Otherwise, if either operand is of type <keyword>uint</keyword> and the other operand is of type <keyword>sbyte</keyword>, <keyword>short</keyword>, or <keyword>int</keyword>, both operands are converted to type <keyword>long</keyword>. </list_item><list_item> Otherwise, if either operand is of type <keyword>uint</keyword>, the other operand is converted to type <keyword>uint</keyword>. </list_item><list_item> Otherwise, both operands are converted to type <keyword>int</keyword>. </list_item></list></paragraph>
+  <paragraph>
+    <note>[Note: Note that the first rule disallows any operations that mix the <keyword>decimal</keyword> type with the <keyword>double</keyword> and <keyword>float</keyword> types. The rule follows from the fact that there are no implicit conversions between the <keyword>decimal</keyword> type and the <keyword>double</keyword> and <keyword>float</keyword> types. end note]</note>
+  </paragraph>
+  <paragraph>
+    <note>[Note: Also note that it is not possible for an operand to be of type <keyword>ulong</keyword> when the other operand is of a signed integral type. The reason is that no integral type exists that can represent the full range of <keyword>ulong</keyword> as well as the signed integral types. end note]</note>
+  </paragraph>
+  <paragraph>In both of the above cases, a cast expression can be used to explicitly convert one operand to a type that is compatible with the other operand. </paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+decimal AddPercent(decimal x, double percent) {  
+   return x * (1.0 + percent / 100.0);  
+}  
+]]></code_example>a compile-time error occurs because a <keyword>decimal</keyword> cannot be multiplied by a <keyword>double</keyword>. The error is resolved by explicitly converting the second operand to <keyword>decimal</keyword>, as follows: <code_example><![CDATA[
+decimal AddPercent(decimal x, double percent) {  
+   return x * (decimal)(1.0 + percent / 100.0);  
+}  
+]]></code_example>end example]</example>
+  </paragraph>
+  <paragraph>End of informative text. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.2.6.xml b/mcs/docs/ecma334/14.2.6.xml
new file mode 100644 (file)
index 0000000..b97ee77
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<clause number="14.2.6" title="Numeric promotions" informative="true">
+  <paragraph>This clause is informative. </paragraph>
+  <paragraph>Numeric promotion consists of automatically performing certain implicit conversions of the operands of the predefined unary and binary numeric operators. Numeric promotion is not a distinct mechanism, but rather an effect of applying overload resolution to the predefined operators. Numeric promotion specifically does not affect evaluation of user-defined operators, although user-defined operators can be implemented to exhibit similar effects. </paragraph>
+  <paragraph>As an example of numeric promotion, consider the predefined implementations of the binary * operator: <code_example><![CDATA[
+int operator *(int x, int y);  
+uint operator *(uint x, uint y);  
+long operator *(long x, long y);  
+ulong operator *(ulong x, ulong y);  
+float operator *(float x, float y);  
+double operator *(double x, double y);  
+decimal operator *(decimal x, decimal y);  
+]]></code_example></paragraph>
+  <paragraph>When overload resolution rules (<hyperlink>14.4.2</hyperlink>) are applied to this set of operators, the effect is to select the first of the operators for which implicit conversions exist from the operand types. <example>[Example: For example, for the operation b * s, where b is a <keyword>byte</keyword> and s is a <keyword>short</keyword>, overload resolution selects operator *(<keyword>int</keyword>, <keyword>int</keyword>) as the best operator. Thus, the effect is that b and s are converted to <keyword>int</keyword>, and the type of the result is <keyword>int</keyword>. Likewise, for the operation i * d, where i is an <keyword>int</keyword> and d is a <keyword>double</keyword>, overload resolution selects operator *(<keyword>double</keyword>, <keyword>double</keyword>) as the best operator. end example]</example> </paragraph>
+  <paragraph>End of informative text. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.2.xml b/mcs/docs/ecma334/14.2.xml
new file mode 100644 (file)
index 0000000..34fef50
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<clause number="14.2" title="Operators">
+  <paragraph>Expressions are constructed from operands and operators. The operators of an expression indicate which operations to apply to the operands. Examples of operators include +, -, *, /, and new. Examples of operands include literals, fields, local variables, and expressions. </paragraph>
+  <paragraph>There are three kinds of operators: <list><list_item> Unary operators. The unary operators take one operand and use either prefix notation (such as -x) or postfix notation (such as x++). </list_item><list_item> Binary operators. The binary operators take two operands and all use infix notation (such as x + y). </list_item><list_item> Ternary operator. Only one ternary operator, ?:, exists; it takes three operands and uses infix notation (c ? x : y). </list_item></list></paragraph>
+  <paragraph>The order of evaluation of operators in an expression is determined by the precedence and associativity of the operators (<hyperlink>14.2.1</hyperlink>). </paragraph>
+  <paragraph>The order in which operands in an expression are evaluated, is left to right. <example>[Example: For example, in F(i) + G(i++) * H(i), method F is called using the old value of i, then method G is called with the old value of i, and, finally, method H is called with the new value of i. This is separate from and unrelated to operator precedence. end example]</example> Certain operators can be overloaded. Operator overloading permits  user-defined operator implementations to be specified for operations where one or both of the operands are of a user-defined class or struct type (<hyperlink>14.2.2</hyperlink>). </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.3.1.xml b/mcs/docs/ecma334/14.3.1.xml
new file mode 100644 (file)
index 0000000..69c54ab
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="14.3.1" title="Base types">
+  <paragraph>For purposes of member lookup, a type T is considered to have the following base types: <list><list_item> If T is object, then T has no base type. </list_item><list_item> If T is a <non_terminal where="11.1">value-type</non_terminal>, the base type of T is the class type object. </list_item><list_item> If T is a <non_terminal where="11.2">class-type</non_terminal>, the base types of T are the base classes of T, including the class type object. </list_item><list_item> If T is an <non_terminal where="11.2">interface-type</non_terminal>, the base types of T are the base interfaces of T and the class type object. </list_item><list_item> If T is an <non_terminal where="19.1">array-type</non_terminal>, the base types of T are the class types System.Array and object. </list_item><list_item> If T is a <non_terminal where="11.2">delegate-type</non_terminal>, the base types of T are the class types System.Delegate and object. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.3.xml b/mcs/docs/ecma334/14.3.xml
new file mode 100644 (file)
index 0000000..b4301d8
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="14.3" title="Member lookup">
+  <paragraph>A member lookup is the process whereby the meaning of a name in the context of a type is determined. A member lookup may occur as part of evaluating a <non_terminal where="14.5.2">simple-name</non_terminal> (<hyperlink>14.5.2</hyperlink>) or a <non_terminal where="14.5.4">member-access</non_terminal> (<hyperlink>14.5.4</hyperlink>) in an expression. </paragraph>
+  <paragraph>A member lookup of a name N in a type T is processed as follows: <list><list_item> First, the set of all accessible (<hyperlink>10.5</hyperlink>) members named N declared in T and the base types (<hyperlink>14.3.1</hyperlink>) of T is constructed. Declarations that include an override modifier are excluded from the set. If no members named N exist and are accessible, then the lookup produces no match, and the following steps are not evaluated. </list_item><list_item> Next, members that are hidden by other members are removed from the set. For every member S.M in the set, where S is the type in which the member M is declared, the following rules are applied: </list_item><list><list_item> If M is a constant, field, property, event, type, or enumeration member, then all members declared in a base type of S are removed from the set. </list_item><list_item> If M is a method, then all non-method members declared in a base type of S are removed from the set, and all methods with the same signature as M declared in a base type of S are removed from the set. </list_item></list><list_item> Finally, having removed hidden members, the result of the lookup is determined: </list_item><list><list_item> If the set consists of a single non-method member, then this member is the result of the lookup. </list_item><list_item> Otherwise, if the set contains only methods, then this group of methods is the result of the lookup. </list_item><list_item> Otherwise, the lookup is ambiguous, and a compile-time error occurs (this situation can only occur for a member lookup in an interface that has multiple direct base interfaces). </list_item></list></list></paragraph>
+  <paragraph>For member lookups in types other than interfaces, and member lookups in interfaces that are strictly  single-inheritance (each interface in the inheritance chain has exactly zero or one direct base interface), the effect of the lookup rules is simply that derived members hide base members with the same name or signature. Such single-inheritance lookups are never ambiguous. The ambiguities that can possibly arise from member lookups in multiple-inheritance interfaces are described in <hyperlink>20.2.5</hyperlink>. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.4.1.xml b/mcs/docs/ecma334/14.4.1.xml
new file mode 100644 (file)
index 0000000..9cfe5bf
--- /dev/null
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<clause number="14.4.1" title="Argument lists">
+  <paragraph>Every function member invocation includes an argument list, which provides actual values or variable references for the parameters of the function member. The syntax for specifying the argument list of a function member invocation depends on the function member category: <list><list_item> For instance constructors, methods, and delegates, the arguments are specified as an <non_terminal where="14.4.1">argument-list</non_terminal>, as described below. </list_item><list_item> For properties, the argument list is empty when invoking the get accessor, and consists of the expression specified as the right operand of the assignment operator when invoking the set accessor. </list_item><list_item> For events, the argument list consists of the expression specified as the right operand of the += or -= operator. </list_item><list_item> For indexers, the argument list consists of the expressions specified between the square brackets in the indexer access. When invoking the set accessor, the argument list additionally includes the expression specified as the right operand of the assignment operator. </list_item><list_item> For user-defined operators, the argument list consists of the single operand of the unary operator or the two operands of the binary operator. </list_item></list></paragraph>
+  <paragraph>The arguments of properties (<hyperlink>17.6</hyperlink>), events (<hyperlink>17.7</hyperlink>), indexers (<hyperlink>17.8</hyperlink>), and user-defined operators (<hyperlink>17.9</hyperlink>) are always passed as value parameters (<hyperlink>17.5.1.1</hyperlink>). Reference and output parameters are not supported for these categories of function members. </paragraph>
+  <paragraph>The arguments of an instance constructor, method, or delegate invocation are specified as an argument-list: <grammar_production><name><non_terminal where="14.4.1">argument-list</non_terminal></name> : <rhs><non_terminal where="14.4.1">argument</non_terminal></rhs><rhs><non_terminal where="14.4.1">argument-list</non_terminal><terminal>,</terminal><non_terminal where="14.4.1">argument</non_terminal></rhs></grammar_production><grammar_production><name>argument</name> : <rhs><non_terminal where="14.14">expression</non_terminal></rhs><rhs><keyword>ref</keyword><non_terminal where="12.4">variable-reference</non_terminal></rhs><rhs><keyword>out</keyword><non_terminal where="12.4">variable-reference</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>An <non_terminal where="14.4.1">argument-list</non_terminal> consists of one or more arguments, separated by commas. Each argument can take one of the following forms: <list><list_item> An expression, indicating that the argument is passed as a value parameter (<hyperlink>17.5.1.1</hyperlink>). </list_item><list_item> The keyword ref followed by a <non_terminal where="12.4">variable-reference</non_terminal> (<hyperlink>12.3.3</hyperlink>), indicating that the argument is passed as a reference parameter (<hyperlink>17.5.1.2</hyperlink>). A variable must be definitely assigned (<hyperlink>12.3</hyperlink>) before it can be passed as a reference parameter. A volatile field (<hyperlink>17.4.3</hyperlink>) cannot be passed as a reference parameter. </list_item><list_item> The keyword out followed by a <non_terminal where="12.4">variable-reference</non_terminal> (<hyperlink>12.3.3</hyperlink>), indicating that the argument is passed as an output parameter (<hyperlink>17.5.1.3</hyperlink>). A variable is considered definitely assigned (<hyperlink>12.3</hyperlink>) following a function member invocation in which the variable is passed as an output parameter. A volatile field (<hyperlink>17.4.3</hyperlink>) cannot be passed as an output parameter. </list_item></list></paragraph>
+  <paragraph>During the run-time processing of a function member invocation (<hyperlink>14.4.3</hyperlink>), the expressions or variable references of an argument list are evaluated in order, from left to right, as follows: <list><list_item> For a value parameter, the argument expression is evaluated and an implicit conversion (<hyperlink>13.1</hyperlink>) to the corresponding parameter type is performed. The resulting value becomes the initial value of the value parameter in the function member invocation. </list_item><list_item> For a reference or output parameter, the variable reference is evaluated and the resulting storage location becomes the storage location represented by the parameter in the function member invocation. If the variable reference given as a reference or output parameter is an array element of a <non_terminal where="11.2">reference-type</non_terminal>, a run-time check is performed to ensure that the element type of the array is identical to the type of the parameter. If this check fails, a System.ArrayTypeMismatchException is thrown. </list_item></list></paragraph>
+  <paragraph>Methods, indexers, and instance constructors may declare their right-most parameter to be a parameter array (<hyperlink>17.5.1.4</hyperlink>). Such function members are invoked either in their normal form or in their expanded form depending on which is applicable (<hyperlink>14.4.2.1</hyperlink>): <list><list_item> When a function member with a parameter array is invoked in its normal form, the argument given for the parameter array must be a single expression of a type that is implicitly convertible (<hyperlink>13.1</hyperlink>) to the parameter array type. In this case, the parameter array acts precisely like a value parameter. </list_item><list_item> When a function member with a parameter array is invoked in its expanded form, the invocation must specify zero or more arguments for the parameter array, where each argument is an expression of a type that is implicitly convertible (<hyperlink>13.1</hyperlink>) to the element type of the parameter array. In this case, the invocation creates an instance of the parameter array type with a length corresponding to the number of arguments, initializes the elements of the array instance with the given argument values, and uses the newly created array instance as the actual argument. </list_item></list></paragraph>
+  <paragraph>The expressions of an argument list are always evaluated in the order they are written. <example>[Example: Thus, the example <code_example><![CDATA[
+class Test  
+{  
+   static void F(int x, int y, int z) {  
+      System.Console.WriteLine("x = {0}, y = {1}, z = {2}", x, y, z);  
+   }  
+   static void Main() {  
+      int i = 0;  
+      F(i++, i++, i++);  
+   }  
+}  
+]]></code_example>produces the output <code_example><![CDATA[
+x = 0, y = 1, z = 2  
+]]></code_example>end example]</example> </paragraph>
+  <paragraph>The array covariance rules (<hyperlink>19.5</hyperlink>) permit a value of an array type A[] to be a reference to an instance of an array type B[], provided an implicit reference conversion exists from B to A. Because of these rules, when an array element of a <non_terminal where="11.2">reference-type</non_terminal> is passed as a reference or output parameter, a run-time check is required to ensure that the actual element type of the array is identical to that of the parameter. <example>[Example: In the example <code_example><![CDATA[
+class Test  
+{  
+   static void F(ref object x) {...}  
+   static void Main() {  
+      object[] a = new object[10];  
+      object[] b = new string[10];  
+      F(ref a[0]);    // Ok  
+      F(ref b[1]);   // ArrayTypeMismatchException  
+   }  
+}  
+]]></code_example>the second invocation of F causes a System.ArrayTypeMismatchException to be thrown because the actual element type of b is string and not object. end example]</example> </paragraph>
+  <paragraph>When a function member with a parameter array is invoked in its expanded form, the invocation is processed exactly as if an array creation expression with an array initializer (<hyperlink>14.5.10.2</hyperlink>) was inserted around the expanded parameters. <example>[Example: For example, given the declaration <code_example><![CDATA[
+void F(int x, int y, params object[] args);  
+]]></code_example>the following invocations of the expanded form of the method <code_example><![CDATA[
+F(10, 20);  
+F(10, 20, 30, 40);  
+F(10, 20, 1, "hello", 3.0);  
+]]></code_example>correspond exactly to <code_example><![CDATA[
+F(10, 20, new object[] {});  
+F(10, 20, new object[] {30, 40});  
+F(10, 20, new object[] {1, "hello", 3.0});  
+]]></code_example>end example]</example> In particular, note that an empty array is created when there are zero arguments given for the parameter array. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.4.2.1.xml b/mcs/docs/ecma334/14.4.2.1.xml
new file mode 100644 (file)
index 0000000..1427565
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="14.4.2.1" title="Applicable function member">
+  <paragraph>A function member is said to be an applicable function member with respect to an argument list A when all of the following are true: <list><list_item> The number of arguments in A is identical to the number of parameters in the function member declaration. </list_item><list_item> For each argument in A, the parameter passing mode of the argument (i.e., value, ref, or out) is identical to the parameter passing mode of the corresponding parameter, and </list_item><list><list_item> for a value parameter or a parameter array, an implicit conversion (<hyperlink>13.1</hyperlink>) exists from the type of the argument to the type of the corresponding parameter, or </list_item><list_item> for a ref or out parameter, the type of the argument is identical to the type of the corresponding parameter. <note>[Note: After all, a ref or out parameter is an alias for the argument passed. end note]</note> </list_item></list></list></paragraph>
+  <paragraph>For a function member that includes a parameter array, if the function member is applicable by the above rules, it is said to be applicable in its normal form. If a function member that includes a parameter array is not applicable in its normal form, the function member may instead be applicable in its expanded form: <list><list_item> The expanded form is constructed by replacing the parameter array in the function member declaration with zero or more value parameters of the element type of the parameter array such that the number of arguments in the argument list A matches the total number of parameters. If A has fewer arguments than the number of fixed parameters in the function member declaration, the expanded form of the function member cannot be constructed and is thus not applicable. </list_item><list_item> If the class, struct, or interface in which the function member is declared already contains another applicable function member with the same signature as the expanded form, the expanded form is not applicable. </list_item><list_item> Otherwise, the expanded form is applicable if for each argument in A the parameter passing mode of the argument is identical to the parameter passing mode of the corresponding parameter, and </list_item><list><list_item> for a fixed value parameter or a value parameter created by the expansion, an implicit conversion (<hyperlink>13.1</hyperlink>) exists from the type of the argument to the type of the corresponding parameter, or </list_item><list_item> for a ref or out parameter, the type of the argument is identical to the type of the corresponding parameter. </list_item></list></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.4.2.2.xml b/mcs/docs/ecma334/14.4.2.2.xml
new file mode 100644 (file)
index 0000000..5ddeef6
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="14.4.2.2" title="Better function member">
+  <paragraph>Given an argument list A with a set of argument types A1, A2, ..., AN and two applicable function members MP and MQ with parameter types P1, P2, ..., PN and Q1, Q2, ..., QN, MP is defined to be a better function member than MQ if <list><list_item> for each argument, the implicit conversion from AX to PX is not worse than the implicit conversion from AX to QX, and </list_item><list_item> for at least one argument, the conversion from AX to PX is better than the conversion from AX to QX. </list_item></list></paragraph>
+  <paragraph>When performing this evaluation, if MP or MQ is applicable in its expanded form, then PX or QX refers to a parameter in the expanded form of the parameter list. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.4.2.3.xml b/mcs/docs/ecma334/14.4.2.3.xml
new file mode 100644 (file)
index 0000000..b00c6fb
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="14.4.2.3" title="Better conversion">
+  <paragraph>Given an implicit conversion C1 that converts from a type S to a type T1, and an implicit conversion C2 that converts from a type S to a type T2, the better conversion of the two conversions is determined as follows: <list><list_item> If T1 and T2 are the same type, neither conversion is better. </list_item><list_item> If S is T1, C1 is the better conversion. </list_item><list_item> If S is T2, C2 is the better conversion. </list_item><list_item> If an implicit conversion from T1 to T2 exists, and no implicit conversion from T2 to T1 exists, C1 is the better conversion. </list_item><list_item> If an implicit conversion from T2 to T1 exists, and no implicit conversion from T1 to T2 exists, C2 is the better conversion. </list_item><list_item> If T1 is <keyword>sbyte</keyword> and T2 is <keyword>byte</keyword>, <keyword>ushort</keyword>, <keyword>uint</keyword>, or <keyword>ulong</keyword>, C1 is the better conversion. </list_item><list_item> If T2 is <keyword>sbyte</keyword> and T1 is <keyword>byte</keyword>, <keyword>ushort</keyword>, <keyword>uint</keyword>, or <keyword>ulong</keyword>, C2 is the better conversion. </list_item><list_item> If T1 is <keyword>short</keyword> and T2 is <keyword>ushort</keyword>, <keyword>uint</keyword>, or <keyword>ulong</keyword>, C1 is the better conversion. </list_item><list_item> If T2 is <keyword>short</keyword> and T1 is <keyword>ushort</keyword>, <keyword>uint</keyword>, or <keyword>ulong</keyword>, C2 is the better conversion. </list_item><list_item> If T1 is <keyword>int</keyword> and T2 is <keyword>uint</keyword>, or <keyword>ulong</keyword>, C1 is the better conversion. </list_item><list_item> If T2 is <keyword>int</keyword> and T1 is <keyword>uint</keyword>, or <keyword>ulong</keyword>, C2 is the better conversion. </list_item><list_item> If T1 is <keyword>long</keyword> and T2 is <keyword>ulong</keyword>, C1 is the better conversion. </list_item><list_item> If T2 is <keyword>long</keyword> and T1 is <keyword>ulong</keyword>, C2 is the better conversion. </list_item><list_item> Otherwise, neither conversion is better. </list_item></list></paragraph>
+  <paragraph>If an implicit conversion C1 is defined by these rules to be a better conversion than an implicit conversion C2, then it is also the case that C2 is a worse conversion than C1. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.4.2.xml b/mcs/docs/ecma334/14.4.2.xml
new file mode 100644 (file)
index 0000000..0beb2bc
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="14.4.2" title="Overload resolution">
+  <paragraph>Overload resolution is a compile-time mechanism for selecting the best function member to invoke given an argument list and a set of candidate function members. Overload resolution selects the function member to invoke in the following distinct contexts within C#: <list><list_item> Invocation of a method named in an <non_terminal where="14.5.5">invocation-expression</non_terminal> (<hyperlink>14.5.5</hyperlink>). </list_item><list_item> Invocation of an instance constructor named in an <non_terminal where="14.5.10.1">object-creation-expression</non_terminal> (<hyperlink>14.5.10.1</hyperlink>). </list_item><list_item> Invocation of an indexer accessor through an <non_terminal where="14.5.6">element-access</non_terminal> (<hyperlink>14.5.6</hyperlink>). </list_item><list_item> Invocation of a predefined or user-defined operator referenced in an expression (<hyperlink>14.2.3</hyperlink> and <hyperlink>14.2.4</hyperlink>). </list_item></list></paragraph>
+  <paragraph>Each of these contexts defines the set of candidate function members and the list of arguments in its own unique way. However, once the candidate function members and the argument list have been identified, the selection of the best function member is the same in all cases: <list><list_item> First, the set of candidate function members is reduced to those function members that are applicable with respect to the given argument list (<hyperlink>14.4.2.1</hyperlink>). If this reduced set is empty, a compile-time error occurs. </list_item><list_item> Then, given the set of applicable candidate function members, the best function member in that set is located. If the set contains only one function member, then that function member is the best function member. Otherwise, the best function member is the one function member that is better than all other function members with respect to the given argument list, provided that each function member is compared to all other function members using the rules in <hyperlink>14.4.2.2</hyperlink>. If there is not exactly one function member that is better than all other function members, then the function member invocation is ambiguous and a  compile-time error occurs. </list_item></list></paragraph>
+  <paragraph>The following sections define the exact meanings of the terms applicable function member and better function member. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.4.3.1.xml b/mcs/docs/ecma334/14.4.3.1.xml
new file mode 100644 (file)
index 0000000..f4e4f7b
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="14.4.3.1" title="Invocations on boxed instances">
+  <paragraph>A function member implemented in a <non_terminal where="11.1">value-type</non_terminal> can be invoked through a boxed instance of that <non_terminal where="11.1">value-type</non_terminal> in the following situations: <list><list_item> When the function member is an override of a method inherited from type object and is invoked through an instance expression of type object. </list_item><list_item> When the function member is an implementation of an interface function member and is invoked through an instance expression of an <non_terminal where="11.2">interface-type</non_terminal>. </list_item><list_item> When the function member is invoked through a delegate. </list_item></list></paragraph>
+  <paragraph>In these situations, the boxed instance is considered to contain a variable of the <non_terminal where="11.1">value-type</non_terminal>, and this variable becomes the variable referenced by this within the function member invocation. <note>[Note: In particular, this means that when a function member is invoked on a boxed instance, it is possible for the function member to modify the value contained in the boxed instance. end note]</note> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.4.3.xml b/mcs/docs/ecma334/14.4.3.xml
new file mode 100644 (file)
index 0000000..369f950
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="14.4.3" title="Function member invocation">
+  <paragraph>This section describes the process that takes place at run-time to invoke a particular function member. It is assumed that a compile-time process has already determined the particular member to invoke, possibly by applying overload resolution to a set of candidate function members. </paragraph>
+  <paragraph>For purposes of describing the invocation process, function members are divided into two categories: <list><list_item> Static function members. These are static methods, instance constructors, static property accessors, and user-defined operators. Static function members are always non-virtual. </list_item><list_item> Instance function members. These are instance methods, instance property accessors, and indexer accessors. Instance function members are either non-virtual or virtual, and are always invoked on a particular instance. The instance is computed by an instance expression, and it becomes accessible within the function member as this (<hyperlink>14.5.7</hyperlink>). </list_item></list></paragraph>
+  <paragraph>The run-time processing of a function member invocation consists of the following steps, where M is the function member and, if M is an instance member, E is the instance expression: <list><list_item> If M is a static function member: </list_item><list><list_item> The argument list is evaluated as described in <hyperlink>14.4.1</hyperlink>. </list_item><list_item> M is invoked. </list_item></list><list_item> If M is an instance function member declared in a value-type: </list_item><list><list_item> E is evaluated. If this evaluation causes an exception, then no further steps are executed. </list_item><list_item> If E is not classified as a variable, then a temporary local variable of E's type is created and the value of E is assigned to that variable. E is then reclassified as a reference to that temporary local variable. The temporary variable is accessible as this within M, but not in any other way. Thus, only when E is a true variable is it possible for the caller to observe the changes that M makes to this. </list_item><list_item> The argument list is evaluated as described in <hyperlink>14.4.1</hyperlink>. </list_item><list_item> M is invoked. The variable referenced by E becomes the variable referenced by this. </list_item></list><list_item> If M is an instance function member declared in a reference-type: </list_item><list><list_item> E is evaluated. If this evaluation causes an exception, then no further steps are executed. </list_item><list_item> The argument list is evaluated as described in <hyperlink>14.4.1</hyperlink>. </list_item><list_item> If the type of E is a <non_terminal where="11.1">value-type</non_terminal>, a boxing conversion (<hyperlink>11.3.1</hyperlink>) is performed to convert E to type object, and E is considered to be of type object in the following steps. <note>[Note: In this case, M could only be a member of System.Object. end note]</note> </list_item><list_item> The value of E is checked to be valid. If the value of E is null, a System.NullReferenceException is thrown and no further steps are executed. </list_item><list_item> The function member implementation to invoke is determined: </list_item><list><list_item> If the compile-time type of E is an interface, the function member to invoke is the implementation of M provided by the run-time type of the instance referenced by E. This function member is determined by applying the interface mapping rules (<hyperlink>20.4.2</hyperlink>) to determine the implementation of M provided by the run-time type of the instance referenced by E. </list_item><list_item> Otherwise, if M is a virtual function member, the function member to invoke is the implementation of M provided by the run-time type of the instance referenced by E. This function member is determined by applying the rules for determining the most derived implementation (<hyperlink>17.5.3</hyperlink>) of M with respect to the run-time type of the instance referenced by E. </list_item><list_item> Otherwise, M is a non-virtual function member, and the function member to invoke is M itself. </list_item></list><list_item> The function member implementation determined in the step above is invoked. The object referenced by E becomes the object referenced by this. </list_item></list></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.4.xml b/mcs/docs/ecma334/14.4.xml
new file mode 100644 (file)
index 0000000..553b988
--- /dev/null
@@ -0,0 +1,93 @@
+<?xml version="1.0"?>
+<clause number="14.4" title="Function members">
+  <paragraph>Function members are members that contain executable statements. Function members are always members of types and cannot be members of namespaces. C# defines the following categories of function members: <list><list_item> Methods </list_item><list_item> Properties </list_item><list_item> Events </list_item><list_item> Indexers </list_item><list_item> User-defined operators </list_item><list_item> Instance constructors </list_item><list_item> Static constructors </list_item><list_item> Destructors </list_item></list></paragraph>
+  <paragraph>Except for static constructors and destructors (which cannot be invoked explicitly), the statements contained in function members are executed through function member invocations. The actual syntax for writing a function member invocation depends on the particular function member category. </paragraph>
+  <paragraph>The argument list (<hyperlink>14.4.1</hyperlink>) of a function member invocation provides actual values or variable references for the parameters of the function member. </paragraph>
+  <paragraph>Invocations of methods, indexers, operators, and instance constructors employ overload resolution to determine which of a candidate set of function members to invoke. This process is described in <hyperlink>14.4.2</hyperlink>. </paragraph>
+  <paragraph>Once a particular function member has been identified at compile-time, possibly through overload resolution, the actual run-time process of invoking the function member is described in <hyperlink>14.4.3</hyperlink>. </paragraph>
+  <paragraph>
+    <note>[Note: The following table summarizes the processing that takes place in constructs involving the six categories of function members that can be explicitly invoked. In the table, e, x, y, and value indicate expressions classified as variables or values, T indicates an expression classified as a type, F is the simple name of a method, and P is the simple name of a property. <table_line>Construct Example Description </table_line>
+<table_line>F(x, y) Overload resolution is applied to select the best method F in the </table_line>
+<table_line>containing class or struct. The method is invoked with the </table_line>
+<table_line>argument list (x, y). If the method is not static, the </table_line>
+<table_line>instance expression is this. </table_line>
+<table_line>Method </table_line>
+<table_line>invocation </table_line>
+<table_line>T.F(x, y) Overload resolution is applied to select the best method F in the </table_line>
+<table_line>class or struct T. A compile-time error occurs if the method is </table_line>
+<table_line>not static. The method is invoked with the argument list </table_line>
+<table_line>(x, y). </table_line>
+<table_line>Construct Example Description </table_line>
+<table_line>e.F(x, y) Overload resolution is applied to select the best method F in the </table_line>
+<table_line>class, struct, or interface given by the type of e. A compile-time </table_line>
+<table_line>error occurs if the method is static. The method is invoked </table_line>
+<table_line>with the instance expression e and the argument list (x, y). </table_line>
+<table_line>P The get accessor of the property P in the containing class or </table_line>
+<table_line>struct is invoked. A compile-time error occurs if P is writeonly. </table_line>
+<table_line>If P is not static, the instance expression is this. </table_line>
+<table_line>P = value The set accessor of the property P in the containing class or </table_line>
+<table_line>struct is invoked with the argument list (value). A compiletime </table_line>
+<table_line>error occurs if P is read-only. If P is not static, the </table_line>
+<table_line>instance expression is this. </table_line>
+<table_line>T.P The get accessor of the property P in the class or struct T is </table_line>
+<table_line>invoked. A compile-time error occurs if P is not static or if P </table_line>
+<table_line>is write-only. </table_line>
+<table_line>T.P = value The set accessor of the property P in the class or struct T is </table_line>
+<table_line>invoked with the argument list (value). A compile-time error </table_line>
+<table_line>occurs if P is not static or if P is read-only. </table_line>
+<table_line>e.P The get accessor of the property P in the class, struct, or </table_line>
+<table_line>interface given by the type of e is invoked with the instance </table_line>
+<table_line>expression e. A compile-time error occurs if P is static or if </table_line>
+<table_line>P is write-only. </table_line>
+<table_line>Property </table_line>
+<table_line>access </table_line>
+<table_line>e.P = value The set accessor of the property P in the class, struct, or </table_line>
+<table_line>interface given by the type of e is invoked with the instance </table_line>
+<table_line>expression e and the argument list (value). A compile-time </table_line>
+<table_line>error occurs if P is static or if P is read-only. </table_line>
+<table_line>E += value The add accessor of the event E in the containing class or struct </table_line>
+<table_line>is invoked. If E is not static, the instance expression is this. </table_line>
+<table_line>E -= value The remove accessor of the event E in the containing class or </table_line>
+<table_line>struct is invoked. If E is not static, the instance expression is </table_line>
+<table_line>this. </table_line>
+<table_line>T.E += value The add accessor of the event E in the class or struct T is </table_line>
+<table_line>invoked. A compile-time error occurs if E is not static. </table_line>
+<table_line>T.E -= value The remove accessor of the event E in the class or struct T is </table_line>
+<table_line>invoked. A compile-time error occurs if E is not static. </table_line>
+<table_line>e.E += value The add accessor of the event E in the class, struct, or interface </table_line>
+<table_line>given by the type of e is invoked with the instance expression </table_line>
+<table_line>e. A compile-time error occurs if E is static. </table_line>
+<table_line>Event access </table_line>
+<table_line>e.E -= value The remove accessor of the event E in the class, struct, or </table_line>
+<table_line>interface given by the type of e is invoked with the instance </table_line>
+<table_line>expression e. A compile-time error occurs if E is static. </table_line>
+<table_line>Indexer </table_line>
+<table_line>access </table_line>
+<table_line>e[x, y] Overload resolution is applied to select the best indexer in the </table_line>
+<table_line>class, struct, or interface given by the type of e. The get </table_line>
+<table_line>accessor of the indexer is invoked with the instance expression </table_line>
+<table_line>e and the argument list (x, y). A compile-time error occurs if </table_line>
+<table_line>the indexer is write-only. </table_line>
+<table_line>Construct Example Description </table_line>
+<table_line>e[x, y] = value Overload resolution is applied to select the best indexer in the </table_line>
+<table_line>class, struct, or interface given by the type of e. The set </table_line>
+<table_line>accessor of the indexer is invoked with the instance expression </table_line>
+<table_line>e and the argument list (x, y, value). A compile-time error </table_line>
+<table_line>occurs if the indexer is read-only. </table_line>
+<table_line>-x Overload resolution is applied to select the best unary operator </table_line>
+<table_line>in the class or struct given by the type of x. The selected </table_line>
+<table_line>operator is invoked with the argument list (x). </table_line>
+<table_line>Operator </table_line>
+<table_line>invocation </table_line>
+<table_line>x + y Overload resolution is applied to select the best binary operator </table_line>
+<table_line>in the classes or structs given by the types of x and y. The </table_line>
+<table_line>selected operator is invoked with the argument list (x, y). </table_line>
+<table_line>Instance </table_line>
+<table_line>constructor </table_line>
+<table_line>invocation </table_line>
+<table_line>new T(x, y) Overload resolution is applied to select the best instance </table_line>
+<table_line>constructor in the class or struct T. The instance constructor is </table_line>
+<table_line>invoked with the argument list (x, y). </table_line>
+end note]</note>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.5.1.xml b/mcs/docs/ecma334/14.5.1.xml
new file mode 100644 (file)
index 0000000..0666be1
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="14.5.1" title="Literals">
+  <paragraph>A <non_terminal where="14.5">primary-expression</non_terminal> that consists of a literal (<hyperlink>9.4.4</hyperlink>) is classified as a value. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.5.10.1.xml b/mcs/docs/ecma334/14.5.10.1.xml
new file mode 100644 (file)
index 0000000..595eca0
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<clause number="14.5.10.1" title="Object creation expressions">
+  <paragraph>An <non_terminal where="14.5.10.1">object-creation-expression</non_terminal> is used to create a new instance of a <non_terminal where="11.2">class-type</non_terminal> or a <non_terminal where="11.1">value-type</non_terminal>. <grammar_production><name><non_terminal where="14.5.10.1">object-creation-expression</non_terminal></name> : <rhs><keyword>new</keyword><non_terminal where="11">type</non_terminal><terminal>(</terminal><non_terminal where="14.4.1">argument-list</non_terminal><opt/><terminal>)</terminal></rhs></grammar_production></paragraph>
+  <paragraph>The type of an <non_terminal where="14.5.10.1">object-creation-expression</non_terminal> must be a <non_terminal where="11.2">class-type</non_terminal> or a <non_terminal where="11.1">value-type</non_terminal>. The type cannot be an abstract <non_terminal where="11.2">class-type</non_terminal>. </paragraph>
+  <paragraph>The optional <non_terminal where="14.4.1">argument-list</non_terminal> (<hyperlink>14.4.1</hyperlink>) is permitted only if the type is a <non_terminal where="11.2">class-type</non_terminal> or a <non_terminal where="11.1">struct-type</non_terminal>. </paragraph>
+  <paragraph>The compile-time processing of an <non_terminal where="14.5.10.1">object-creation-expression</non_terminal> of the form new T(A), where T is a <non_terminal where="11.2">class-type</non_terminal> or a <non_terminal where="11.1">value-type</non_terminal> and A is an optional <non_terminal where="14.4.1">argument-list</non_terminal>, consists of the following steps: <list><list_item> If T is a <non_terminal where="11.1">value-type</non_terminal> and A is not present: </list_item><list><list_item> The <non_terminal where="14.5.10.1">object-creation-expression</non_terminal> is a default constructor invocation. The result of the  <non_terminal where="14.5.10.1">object-creation-expression</non_terminal> is a value of type T, namely the default value for T as defined in <hyperlink>11.1.1</hyperlink>. </list_item></list><list_item> Otherwise, if T is a <non_terminal where="11.2">class-type</non_terminal> or a struct-type: </list_item><list><list_item> If T is an abstract <non_terminal where="11.2">class-type</non_terminal>, a compile-time error occurs. </list_item><list_item> The instance constructor to invoke is determined using the overload resolution rules of <hyperlink>14.4.2</hyperlink>. The set of candidate instance constructors consists of all accessible instance constructors declared in T. If the set of candidate instance constructors is empty, or if a single best instance constructor cannot be identified, a compile-time error occurs. </list_item><list_item> The result of the <non_terminal where="14.5.10.1">object-creation-expression</non_terminal> is a value of type T, namely the value produced by invoking the instance constructor determined in the step above. </list_item></list><list_item> Otherwise, the <non_terminal where="14.5.10.1">object-creation-expression</non_terminal> is invalid, and a compile-time error occurs. </list_item></list></paragraph>
+  <paragraph>The run-time processing of an <non_terminal where="14.5.10.1">object-creation-expression</non_terminal> of the form new T(A), where T is <non_terminal where="11.2">class-type</non_terminal> or a <non_terminal where="11.1">struct-type</non_terminal> and A is an optional <non_terminal where="14.4.1">argument-list</non_terminal>, consists of the following steps: <list><list_item> If T is a class-type: </list_item><list><list_item> A new instance of class T is allocated. If there is not enough memory available to allocate the new instance, a System.OutOfMemoryException is thrown and no further steps are executed. </list_item><list_item> All fields of the new instance are initialized to their default values (<hyperlink>12.2</hyperlink>). </list_item><list_item> The instance constructor is invoked according to the rules of function member invocation (<hyperlink>14.4.3</hyperlink>). A reference to the newly allocated instance is automatically passed to the instance constructor and the instance can be accessed from within that constructor as this. </list_item></list><list_item> If T is a struct-type: </list_item><list><list_item> An instance of type T is created by allocating a temporary local variable. Since an instance constructor of a <non_terminal where="11.1">struct-type</non_terminal> is required to definitely assign a value to each field of the instance being created, no initialization of the temporary variable is necessary. </list_item><list_item> The instance constructor is invoked according to the rules of function member invocation (<hyperlink>14.4.3</hyperlink>). A reference to the newly allocated instance is automatically passed to the instance constructor and the instance can be accessed from within that constructor as this. </list_item></list></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.5.10.2.xml b/mcs/docs/ecma334/14.5.10.2.xml
new file mode 100644 (file)
index 0000000..f34fa4d
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<clause number="14.5.10.2" title="Array creation expressions">
+  <paragraph>An <non_terminal where="14.5.10.2">array-creation-expression</non_terminal> is used to create a new instance of an <non_terminal where="19.1">array-type</non_terminal>. <grammar_production><name><non_terminal where="14.5.10.2">array-creation-expression</non_terminal></name> : <rhs><keyword>new</keyword><non_terminal where="19.1">non-array-type</non_terminal><terminal>[</terminal><non_terminal where="14.5.6">expression-list</non_terminal><terminal>]</terminal><non_terminal where="19.1">rank-specifiers</non_terminal><opt/><non_terminal where="19.6">array-initializer</non_terminal><opt/></rhs><rhs><keyword>new</keyword><non_terminal where="19.1">array-type</non_terminal><non_terminal where="19.6">array-initializer</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>An array creation expression of the first form allocates an array instance of the type that results from deleting each of the individual expressions from the expression list. For example, the array creation expression new int[10,20] produces an array instance of type int[,], and the array creation expression new int[10][,] produces an array of type int[][,]. Each expression in the expression list must be of type <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>long</keyword>, or <keyword>ulong</keyword>, or of a type that can be implicitly converted to one or more of these types. The value of each expression determines the length of the corresponding dimension in the newly allocated array instance. Since the length of an array dimension must be nonnegative, it is a compile-time error to have a constant expression with a negative value, in the expression list. </paragraph>
+  <paragraph>Except in an unsafe context (<hyperlink>25.1</hyperlink>), the layout of arrays is unspecified. </paragraph>
+  <paragraph>If an array creation expression of the first form includes an array initializer, each expression in the expression list must be a constant and the rank and dimension lengths specified by the expression list must match those of the array initializer. </paragraph>
+  <paragraph>In an array creation expression of the second form, the rank of the specified array type must match that of the array initializer. The individual dimension lengths are inferred from the number of elements in each of the corresponding nesting levels of the array initializer. Thus, the expression <code_example><![CDATA[
+new int[,] {{0, 1}, {2, 3}, {4, 5}}  
+]]></code_example>exactly corresponds to <code_example><![CDATA[
+new int[3, 2] {{0, 1}, {2, 3}, {4, 5}}  
+]]></code_example></paragraph>
+  <paragraph>Array initializers are described further in <hyperlink>19.6</hyperlink>. </paragraph>
+  <paragraph>The result of evaluating an array creation expression is classified as a value, namely a reference to the newly allocated array instance. The run-time processing of an array creation expression consists of the following steps: <list><list_item> The dimension length expressions of the <non_terminal where="14.5.6">expression-list</non_terminal> are evaluated in order, from left to right. Following evaluation of each expression, an implicit conversion (<hyperlink>13.1</hyperlink>) to one of the following types is performed: <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>long</keyword>, <keyword>ulong</keyword>. The first type in this list for which an implicit conversion exists is chosen. If evaluation of an expression or the subsequent implicit conversion causes an exception, then no further expressions are evaluated and no further steps are executed. </list_item><list_item> The computed values for the dimension lengths are validated, as follows: If one or more of the values are less than zero, a System.OverflowException is thrown and no further steps are executed. </list_item><list_item> An array instance with the given dimension lengths is allocated. If there is not enough memory available to allocate the new instance, a System.OutOfMemoryException is thrown and no further steps are executed. </list_item><list_item> All elements of the new array instance are initialized to their default values (<hyperlink>12.2</hyperlink>). </list_item><list_item> If the array creation expression contains an array initializer, then each expression in the array initializer is evaluated and assigned to its corresponding array element. The evaluations and assignments are performed in the order the expressions are written in the array initializer-in other words, elements are initialized in increasing index order, with the rightmost dimension increasing first. If evaluation of a given expression or the subsequent assignment to the corresponding array element causes an exception, then no further elements are initialized (and the remaining elements will thus have their default values). </list_item></list></paragraph>
+  <paragraph>An array creation expression permits instantiation of an array with elements of an array type, but the elements of such an array must be manually initialized. <example>[Example: For example, the statement <code_example><![CDATA[
+int[][] a = new int[100][];  
+]]></code_example>creates a single-dimensional array with 100 elements of type int[]. The initial value of each element is null. end example]</example> It is not possible for the same array creation expression to also instantiate the  sub-arrays, and the statement <code_example><![CDATA[
+int[][] a = new int[100][5];    // Error  
+]]></code_example>results in a compile-time error. Instantiation of the sub-arrays must instead be performed manually, as in <code_example><![CDATA[
+int[][] a = new int[100][];  
+for (int i = 0; i < 100; i++) a[i] = new int[5];  
+]]></code_example></paragraph>
+  <paragraph>When an array of arrays has a &quot;rectangular&quot; shape, that is when the sub-arrays are all of the same length, it is more efficient to use a multi-dimensional array. In the example above, instantiation of the array of arrays creates 101 objects-one outer array and 100 sub-arrays. In contrast, <code_example><![CDATA[
+int[,] = new int[100, 5];  
+]]></code_example>creates only a single object, a two-dimensional array, and accomplishes the allocation in a single statement. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.5.10.3.xml b/mcs/docs/ecma334/14.5.10.3.xml
new file mode 100644 (file)
index 0000000..7068bde
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<clause number="14.5.10.3" title="Delegate creation expressions">
+  <paragraph>A <non_terminal where="14.5.10.3">delegate-creation-expression</non_terminal> is used to create a new instance of a <non_terminal where="11.2">delegate-type</non_terminal>. <grammar_production><name><non_terminal where="14.5.10.3">delegate-creation-expression</non_terminal></name> : <rhs><keyword>new</keyword><non_terminal where="11.2">delegate-type</non_terminal><terminal>(</terminal><non_terminal where="14.14">expression</non_terminal><terminal>)</terminal></rhs></grammar_production></paragraph>
+  <paragraph>The argument of a delegate creation expression must be a method group (<hyperlink>14.1</hyperlink>) or a value of a  <non_terminal where="11.2">delegate-type</non_terminal>. If the argument is a method group, it identifies the method and, for an instance method, the object for which to create a delegate. If the argument is a value of a <non_terminal where="11.2">delegate-type</non_terminal>, it identifies a delegate instance of which to create a copy. </paragraph>
+  <paragraph>The compile-time processing of a <non_terminal where="14.5.10.3">delegate-creation-expression</non_terminal> of the form new D(E), where D is a <non_terminal where="11.2">delegate-type</non_terminal> and E is an expression, consists of the following steps: <list><list_item> If E is a method group: </list_item><list><list_item> The set of methods identified by E must include exactly one method that is compatible (<hyperlink>22.1</hyperlink>) with D, and this method becomes the one to which the newly created delegate refers. If no matching method exists, or if more than one matching method exists, a compile-time error occurs. If the selected method is an instance method, the instance expression associated with E determines the target object of the delegate. </list_item><list_item> As in a method invocation, the selected method must be compatible with the context of the method group: If the method is a static method, the method group must have resulted from a <non_terminal where="14.5.2">simple-name</non_terminal> or a <non_terminal where="14.5.4">member-access</non_terminal> through a type. If the method is an instance method, the method group must have resulted from a <non_terminal where="14.5.2">simple-name</non_terminal> or a <non_terminal where="14.5.4">member-access</non_terminal> through a variable or value. If the selected method does not match the context of the method group, a compile-time error occurs. </list_item><list_item> The result is a value of type D, namely a newly created delegate that refers to the selected method and target object. </list_item></list><list_item> Otherwise, if E is a value of a delegate-type: </list_item><list><list_item> D and E must be compatible (<hyperlink>22.1</hyperlink>); otherwise, a compile-time error occurs. </list_item><list_item> The result is a value of type D, namely a newly created delegate that refers to the same invocation list as E. </list_item></list><list_item> Otherwise, the delegate creation expression is invalid, and a compile-time error occurs. </list_item></list></paragraph>
+  <paragraph>The run-time processing of a <non_terminal where="14.5.10.3">delegate-creation-expression</non_terminal> of the form new D(E), where D is a <non_terminal where="11.2">delegate-type</non_terminal> and E is an expression, consists of the following steps: <list><list_item> If E is a method group: </list_item><list><list_item> If the method selected at compile-time is a static method, the target object of the delegate is null. Otherwise, the selected method is an instance method, and the target object of the delegate is determined from the instance expression associated with E: </list_item><list><list_item> The instance expression is evaluated. If this evaluation causes an exception, no further steps are executed. </list_item><list_item> If the instance expression is of a <non_terminal where="11.2">reference-type</non_terminal>, the value computed by the instance expression becomes the target object. If the target object is null, a System.NullReferenceException is thrown and no further steps are executed. </list_item><list_item> If the instance expression is of a <non_terminal where="11.1">value-type</non_terminal>, a boxing operation (<hyperlink>11.3.1</hyperlink>) is performed to convert the value to an object, and this object becomes the target object. </list_item></list><list_item> A new instance of the delegate type D is allocated. If there is not enough memory available to allocate the new instance, a System.OutOfMemoryException is thrown and no further steps are executed. </list_item><list_item> The new delegate instance is initialized with a reference to the method that was determined at compile-time and a reference to the target object computed above. </list_item></list><list_item> If E is a value of a delegate-type: </list_item><list><list_item> E is evaluated. If this evaluation causes an exception, no further steps are executed. </list_item><list_item> If the value of E is null, a System.NullReferenceException is thrown and no further steps are executed. </list_item><list_item> A new instance of the delegate type D is allocated. If there is not enough memory available to allocate the new instance, a System.OutOfMemoryException is thrown and no further steps are executed. </list_item><list_item> The new delegate instance is initialized with references to the same invocation list as the delegate instance given by E. </list_item></list></list></paragraph>
+  <paragraph>The method and object to which a delegate refers are determined when the delegate is instantiated and then remain constant for the entire lifetime of the delegate. In other words, it is not possible to change the target method or object of a delegate once it has been created. <note>[Note: Remember, when two delegates are combined or one is removed from another, a new delegate results; no existing delegate has its content changed. end note]</note> </paragraph>
+  <paragraph>It is not possible to create a delegate that refers to a property, indexer, user-defined operator, instance constructor, destructor, or static constructor. </paragraph>
+  <paragraph>
+    <example>[Example: As described above, when a delegate is created from a method group, the formal parameter list and return type of the delegate determine which of the overloaded methods to select. In the example <code_example><![CDATA[
+delegate double DoubleFunc(double x);  
+class A  
+{  
+   DoubleFunc f = new DoubleFunc(Square);  
+   static float Square(float x) {  
+      return x * x;  
+   }  
+   static double Square(double x) {  
+      return x * x;  
+   }  
+}  
+]]></code_example>the A.f field is initialized with a delegate that refers to the second Square method because that method exactly matches the formal parameter list and return type of DoubleFunc. Had the second Square method not been present, a compile-time error would have occurred. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.5.10.xml b/mcs/docs/ecma334/14.5.10.xml
new file mode 100644 (file)
index 0000000..5adb881
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="14.5.10" title="The new operator">
+  <paragraph>The new operator is used to create new instances of types. </paragraph>
+  <paragraph>There are three forms of new expressions: <list><list_item> Object creation expressions are used to create new instances of class types and value types. </list_item><list_item> Array creation expressions are used to create new instances of array types. </list_item><list_item> Delegate creation expressions are used to create new instances of delegate types. </list_item></list></paragraph>
+  <paragraph>The new operator implies creation of an instance of a type, but does not necessarily imply dynamic allocation of memory. In particular, instances of value types require no additional memory beyond the variables in which they reside, and no dynamic allocations occur when new is used to create instances of value types. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.5.11.xml b/mcs/docs/ecma334/14.5.11.xml
new file mode 100644 (file)
index 0000000..37b252e
--- /dev/null
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+<clause number="14.5.11" title="The typeof operator">
+  <paragraph>The typeof operator is used to obtain the System.Type object for a type. <grammar_production><name><non_terminal where="14.5.11">typeof-expression</non_terminal></name> : <rhs><keyword>typeof</keyword><terminal>(</terminal><non_terminal where="11">type</non_terminal><terminal>)</terminal></rhs><rhs><keyword>typeof</keyword><terminal>(</terminal><keyword>void</keyword><terminal>)</terminal></rhs></grammar_production></paragraph>
+  <paragraph>The first form of <non_terminal where="14.5.11">typeof-expression</non_terminal> consists of a typeof keyword followed by a parenthesized type. The result of an expression of this form is the System.Type object for the indicated type. There is only one System.Type object for any given type. <note>[Note: This means that for type T, typeof(T) == typeof(T) is always true. end note]</note> </paragraph>
+  <paragraph>The second form of <non_terminal where="14.5.11">typeof-expression</non_terminal> consists of a typeof keyword followed by a parenthesized <keyword>void</keyword> keyword. The result of an expression of this form is the System.Type object that represents the absence of a type. The type object returned by typeof(<keyword>void</keyword>) is distinct from the type object returned for any type. </paragraph>
+  <paragraph>
+    <note>[Note: This special type object is useful in class libraries that allow reflection onto methods in the language, where those methods wish to have a way to represent the return type of any method, including <keyword>void</keyword> methods, with an instance of System.Type. end note]</note>
+  </paragraph>
+  <paragraph>
+    <example>[Example: The example <code_example><![CDATA[
+using System;  
+class Test  
+{  
+   static void Main() {  
+      Type[] t = {  
+         typeof(int),  
+         typeof(System.Int32),  
+         typeof(string),  
+         typeof(double[]),  
+      typeof(void)   };  
+      for (int i = 0; i < t.Length; i++) {  
+         Console.WriteLine(t[i].FullName);  
+      }  
+   }  
+}  
+]]></code_example>produces the following output: <code_example><![CDATA[
+System.Int32  
+System.Int32  
+System.String  
+System.Double[]  
+System.Void  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>Note that <keyword>int</keyword> and System.Int32 are the same type. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.5.12.xml b/mcs/docs/ecma334/14.5.12.xml
new file mode 100644 (file)
index 0000000..6e164d0
--- /dev/null
@@ -0,0 +1,76 @@
+<?xml version="1.0"?>
+<clause number="14.5.12" title="The checked and unchecked operators">
+  <paragraph>The checked and unchecked operators are used to control the overflow checking context for <non_terminal where="11.1">integral-type</non_terminal> arithmetic operations and conversions. <grammar_production><name><non_terminal where="14.5.12">checked-expression</non_terminal></name> : <rhs><keyword>checked</keyword><terminal>(</terminal><non_terminal where="14.14">expression</non_terminal><terminal>)</terminal></rhs></grammar_production><grammar_production><name><non_terminal where="14.5.12">unchecked-expression</non_terminal></name> : <rhs><keyword>unchecked</keyword><terminal>(</terminal><non_terminal where="14.14">expression</non_terminal><terminal>)</terminal></rhs></grammar_production></paragraph>
+  <paragraph>The checked operator evaluates the contained expression in a checked context, and the unchecked operator evaluates the contained expression in an unchecked context. A <non_terminal where="14.5.12">checked-expression</non_terminal> or  <non_terminal where="14.5.12">unchecked-expression</non_terminal> corresponds exactly to a <non_terminal where="14.5.3">parenthesized-expression</non_terminal> (<hyperlink>14.5.3</hyperlink>), except that the contained expression is evaluated in the given overflow checking context. </paragraph>
+  <paragraph>The overflow checking context can also be controlled through the checked and unchecked statements (<hyperlink>15.11</hyperlink>). </paragraph>
+  <paragraph>The following operations are affected by the overflow checking context established by the checked and unchecked operators and statements: <list><list_item> The predefined ++ and  --unary operators (<hyperlink>14.5.9</hyperlink> and <hyperlink>14.6.5</hyperlink>), when the operand is of an integral type. </list_item><list_item> The predefined  -unary operator (<hyperlink>14.6.2</hyperlink>), when the operand is of an integral type. </list_item><list_item> The predefined +, -, *, and / binary operators (<hyperlink>14.7</hyperlink>), when both operands are of integral types. </list_item><list_item> Explicit numeric conversions (<hyperlink>13.2.1</hyperlink>) from one integral type to another integral type. </list_item></list></paragraph>
+  <paragraph>When one of the above operations produce a result that is too large to represent in the destination type, the context in which the operation is performed controls the resulting behavior: <list><list_item> In a checked context, if the operation is a constant expression (<hyperlink>14.15</hyperlink>), a compile-time error occurs. Otherwise, when the operation is performed at run-time, a System.OverflowException is thrown. </list_item><list_item> In an unchecked context, the result is truncated by discarding any high-order bits that do not fit in the destination type. </list_item></list></paragraph>
+  <paragraph>For non-constant expressions (expressions that are evaluated at run-time) that are not enclosed by any checked or unchecked operators or statements, the default overflow checking context is unchecked, unless external factors (such as compiler switches and execution environment configuration) call for checked evaluation. </paragraph>
+  <paragraph>For constant expressions (expressions that can be fully evaluated at compile-time), the default overflow checking context is always checked. Unless a constant expression is explicitly placed in an unchecked context, overflows that occur during the compile-time evaluation of the expression always cause  compile-time errors. </paragraph>
+  <paragraph>
+    <note>[Note: Developers may benefit if they exercise their code using checked mode (as well as unchecked mode). </note>
+  </paragraph>
+  <paragraph>
+    <note>It also seems reasonable that, unless otherwise requested, the default overflow checking context is set to checked when debugging is enabled. end note]</note>
+  </paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+class Test  
+{  
+   static readonly int x = 1000000;  
+   static readonly int y = 1000000;  
+   static int F() {  
+      return checked(x * y);    // Throws OverflowException  
+   }  
+   static int G() {  
+      return unchecked(x * y);  // Returns -727379968  
+   }  
+   static int H() {  
+      return x * y;      // Depends on default  
+   }  
+}  
+]]></code_example>no compile-time errors are reported since neither of the expressions can be evaluated at compile-time. At run-time, the F method throws a System.OverflowException, and the G method returns -727379968 (the lower 32 bits of the out-of-range result). The behavior of the H method depends on the default overflow checking context for the compilation, but it is either the same as F or the same as G. end example]</example>
+  </paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+class Test  
+{  
+   const int x = 1000000;  
+   const int y = 1000000;  
+   static int F() {  
+      return checked(x * y);    // Compile error, overflow  
+   }  
+   static int G() {  
+      return unchecked(x * y);  // Returns -727379968  
+   }  
+   static int H() {  
+      return x * y;      // Compile error, overflow  
+   }  
+}  
+]]></code_example>the overflows that occur when evaluating the constant expressions in F and H cause compile-time errors to be reported because the expressions are evaluated in a checked context. An overflow also occurs when evaluating the constant expression in G, but since the evaluation takes place in an unchecked context, the overflow is not reported. end example]</example>
+  </paragraph>
+  <paragraph>The checked and unchecked operators only affect the overflow checking context for those operations that are textually contained within the &quot;(&quot; and &quot;)&quot; tokens. The operators have no effect on function members that are invoked as a result of evaluating the contained expression. <example>[Example: In the example <code_example><![CDATA[
+class Test  
+{  
+   static int Multiply(int x, int y) {  
+      return x * y;  
+   }  
+   static int F() {  
+      return checked(Multiply(1000000, 1000000));  
+   }  
+}  
+]]></code_example>the use of checked in F does not affect the evaluation of x * y in Multiply, so x * y is evaluated in the default overflow checking context. end example]</example> </paragraph>
+  <paragraph>The unchecked operator is convenient when writing constants of the signed integral types in hexadecimal notation. <example>[Example: For example: <code_example><![CDATA[
+class Test  
+{  
+   public const int AllBits = unchecked((int)0xFFFFFFFF);  
+   public const int HighBit = unchecked((int)0x80000000);  
+}  
+]]></code_example></example></paragraph>
+  <paragraph>
+    <example>Both of the hexadecimal constants above are of type <keyword>uint</keyword>. Because the constants are outside the <keyword>int</keyword> range, without the unchecked operator, the casts to <keyword>int</keyword> would produce compile-time errors. end example]</example>
+  </paragraph>
+  <paragraph>
+    <note>[Note: The checked and unchecked operators and statements allow programmers to control certain aspects of some numeric calculations. However, the behavior of some numeric operators depends on their operands' data types. For example, multiplying two decimals always results in an exception on overflow even within an explicitly unchecked construct. Similarly, multiplying two floats never results in an exception on overflow even within an explicitly checked construct. In addition, other operators are never affected by the mode of checking, whether default or explicit. As a service to programmers, it is recommended that the compiler issue a warning when there is an arithmetic expression within an explicitly checked or unchecked context (by operator or statement) that cannot possibly be affected by the specified mode of checking. Since such a warning is not required, the compiler has flexibility in determining the circumstances that merit the issuance of such warnings. end note]</note>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.5.2.1.xml b/mcs/docs/ecma334/14.5.2.1.xml
new file mode 100644 (file)
index 0000000..299d55c
--- /dev/null
@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+<clause number="14.5.2.1" title="Invariant meaning in blocks">
+  <paragraph>For each occurrence of a given identifier as a <non_terminal where="14.5.2">simple-name</non_terminal> in an expression, every other occurrence of the same identifier as a <non_terminal where="14.5.2">simple-name</non_terminal> in an expression within the immediately enclosing block (<hyperlink>15.2</hyperlink>) or  <non_terminal where="15.7.2">switch-block</non_terminal> (<hyperlink>15.7.2</hyperlink>) must refer to the same entity. This rule ensures that the meaning of a name in the context of an expression is always the same within a block. </paragraph>
+  <paragraph>The example <code_example><![CDATA[
+class Test  
+{  
+   double x;  
+   void F(bool b) {  
+      x = 1.0;  
+      if (b) {  
+         int x = 1;  
+      }  
+   }  
+}  
+]]></code_example>results in a compile-time error because x refers to different entities within the outer block (the extent of which includes the nested block in the if statement). In contrast, the example <code_example><![CDATA[
+class Test  
+{  
+   double x;  
+   void F(bool b) {  
+      if (b) {  
+         x = 1.0;  
+      }  
+      else {  
+         int x = 1;  
+      }  
+   }  
+}  
+]]></code_example>is permitted because the name x is never used in the outer block. </paragraph>
+  <paragraph>Note that the rule of invariant meaning applies only to simple names. It is perfectly valid for the same identifier to have one meaning as a simple name and another meaning as right operand of a member access (<hyperlink>14.5.4</hyperlink>). <example>[Example: For example: <code_example><![CDATA[
+struct Point  
+{  
+   int x, y;  
+   public Point(int x, int y) {  
+      this.x = x;  
+      this.y = y;  
+   }  
+}  
+]]></code_example></example></paragraph>
+  <paragraph>
+    <example>The example above illustrates a common pattern of using the names of fields as parameter names in an instance constructor. In the example, the simple names x and y refer to the parameters, but that does not prevent the member access expressions this.x and this.y from accessing the fields. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.5.2.xml b/mcs/docs/ecma334/14.5.2.xml
new file mode 100644 (file)
index 0000000..7a2500a
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="14.5.2" title="Simple names">
+  <paragraph>A <non_terminal where="14.5.2">simple-name</non_terminal> consists of a single identifier. <grammar_production><name><non_terminal where="14.5.2">simple-name</non_terminal></name> : <rhs><non_terminal where="9.4.2">identifier</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>A <non_terminal where="14.5.2">simple-name</non_terminal> is evaluated and classified as follows: <list><list_item> If the <non_terminal where="14.5.2">simple-name</non_terminal> appears within a block and if the block's (or an enclosing block's) local variable declaration space (<hyperlink>10.3</hyperlink>) contains a local variable or parameter with the given name, then the <non_terminal where="14.5.2">simple-name</non_terminal> refers to that local variable or parameter and is classified as a variable. </list_item><list_item> Otherwise, for each type T, starting with the immediately enclosing class, struct, or enumeration declaration and continuing with each enclosing outer class or struct declaration (if any), if a member lookup of the <non_terminal where="14.5.2">simple-name</non_terminal> in T produces a match: </list_item><list><list_item> If T is the immediately enclosing class or struct type and the lookup identifies one or more methods, the result is a method group with an associated instance expression of this. </list_item><list_item> If T is the immediately enclosing class or struct type, if the lookup identifies an instance member, and if the reference occurs within the block of an instance constructor, an instance method, or an instance accessor, the result is the same as a member access (<hyperlink>14.5.4</hyperlink>) of the form this.E, where E is the <non_terminal where="14.5.2">simple-name</non_terminal>. </list_item><list_item> Otherwise, the result is the same as a member access (<hyperlink>14.5.4</hyperlink>) of the form T.E, where E is the <non_terminal where="14.5.2">simple-name</non_terminal>. In this case, it is a compile-time error for the <non_terminal where="14.5.2">simple-name</non_terminal> to refer to an instance member. </list_item></list><list_item> Otherwise, starting with the namespace in which the <non_terminal where="14.5.2">simple-name</non_terminal> occurs, continuing with each enclosing namespace (if any), and ending with the global namespace, the following steps are evaluated until an entity is located: </list_item><list><list_item> If the namespace contains a namespace member with the given name, then the <non_terminal where="14.5.2">simple-name</non_terminal> refers to that member and, depending on the member, is classified as a namespace or a type. </list_item><list_item> Otherwise, if the namespace has a corresponding namespace declaration enclosing the location where the <non_terminal where="14.5.2">simple-name</non_terminal> occurs, then: </list_item><list><list_item> If the namespace declaration contains a <non_terminal where="16.3.1">using-alias-directive</non_terminal> that associates the given name with an imported namespace or type, then the <non_terminal where="14.5.2">simple-name</non_terminal> refers to that namespace or type. </list_item><list_item> Otherwise, if the namespaces imported by the <non_terminal where="16.3.2">using-namespace-directive</non_terminal>s of the namespace declaration contain exactly one type with the given name, then the <non_terminal where="14.5.2">simple-name</non_terminal> refers to that type. </list_item><list_item> Otherwise, if the namespaces imported by the <non_terminal where="16.3.2">using-namespace-directive</non_terminal>s of the namespace declaration contain more than one type with the given name, then the <non_terminal where="14.5.2">simple-name</non_terminal> is ambiguous and a compile-time error occurs. </list_item></list></list><list_item> Otherwise, the name given by the <non_terminal where="14.5.2">simple-name</non_terminal> is undefined and a compile-time error occurs. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.5.3.xml b/mcs/docs/ecma334/14.5.3.xml
new file mode 100644 (file)
index 0000000..5b5d6b3
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="14.5.3" title="Parenthesized expressions">
+  <paragraph>A <non_terminal where="14.5.3">parenthesized-expression</non_terminal> consists of an expression enclosed in parentheses. <grammar_production><name><non_terminal where="14.5.3">parenthesized-expression</non_terminal></name> : <rhs><terminal>(</terminal><non_terminal where="14.14">expression</non_terminal><terminal>)</terminal></rhs></grammar_production></paragraph>
+  <paragraph>A <non_terminal where="14.5.3">parenthesized-expression</non_terminal> is evaluated by evaluating the expression within the parentheses. If the expression within the parentheses denotes a namespace, type, or method group, a compile-time error occurs. Otherwise, the result of the <non_terminal where="14.5.3">parenthesized-expression</non_terminal> is the result of the evaluation of the contained expression. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.5.4.1.xml b/mcs/docs/ecma334/14.5.4.1.xml
new file mode 100644 (file)
index 0000000..80d8471
--- /dev/null
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<clause number="14.5.4.1" title="Identical simple names and type names">
+  <paragraph>In a member access of the form E.I, if E is a single identifier, and if the meaning of E as a <non_terminal where="14.5.2">simple-name</non_terminal> (<hyperlink>14.5.2</hyperlink>) is a constant, field, property, local variable, or parameter with the same type as the meaning of E as a <non_terminal where="10.8">type-name</non_terminal> (<hyperlink>10.8</hyperlink>), then both possible meanings of E are permitted. The two possible meanings of E.I are never ambiguous, since I must necessarily be a member of the type E in both cases. In other words, the rule simply permits access to the static members of E where a compile-time error would otherwise have occurred. </paragraph>
+  <paragraph>
+    <example>[Example: For example: <code_example><![CDATA[
+struct Color  
+{  
+   public static readonly Color White = new Color(...);  
+   public static readonly Color Black = new Color(...);  
+   public Color Complement() {...}  
+}  
+class A  
+{  
+   public Color Color;          // Field Color of type Color  
+   void F() {  
+      Color = Color.Black;       // References Color.Black static member  
+      
+      Color = Color.Complement();  // Invokes Complement() on Color field  
+      
+   }  
+   static void G() {  
+      Color c = Color.White;    // References Color.White static member  
+      
+   }  
+}  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>Within the A class, those occurrences of the Color identifier that reference the Color type are underlined, and those that reference the Color field are not underlined. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.5.4.xml b/mcs/docs/ecma334/14.5.4.xml
new file mode 100644 (file)
index 0000000..b13576f
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="14.5.4" title="Member access">
+  <paragraph>A <non_terminal where="14.5.4">member-access</non_terminal> consists of a <non_terminal where="14.5">primary-expression</non_terminal> or a <non_terminal where="14.5.4">predefined-type</non_terminal>, followed by a &quot;.&quot; token, followed by an identifier. <grammar_production><name><non_terminal where="14.5.4">member-access</non_terminal></name> : <rhs><non_terminal where="14.5">primary-expression</non_terminal><terminal>.</terminal><non_terminal where="9.4.2">identifier</non_terminal></rhs><rhs><non_terminal where="14.5.4">predefined-type</non_terminal><terminal>.</terminal><non_terminal where="9.4.2">identifier</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="14.5.4">predefined-type</non_terminal></name> : one of <rhs><keyword>bool</keyword><keyword>byte</keyword><keyword>char</keyword><keyword>decimal</keyword><keyword>double</keyword><keyword>float</keyword><keyword>int</keyword><keyword>long</keyword></rhs><rhs><keyword>object</keyword><keyword>sbyte</keyword><keyword>short</keyword><keyword>string</keyword><keyword>uint</keyword><keyword>ulong</keyword><keyword>ushort</keyword></rhs></grammar_production></paragraph>
+  <paragraph>A <non_terminal where="14.5.4">member-access</non_terminal> of the form E.I, where E is a <non_terminal where="14.5">primary-expression</non_terminal> or a <non_terminal where="14.5.4">predefined-type</non_terminal> and I is an identifier, is evaluated and classified as follows: <list><list_item> If E is a namespace and I is the name of an accessible member of that namespace, then the result is that member and, depending on the member, is classified as a namespace or a type. </list_item><list_item> If E is a <non_terminal where="14.5.4">predefined-type</non_terminal> or a <non_terminal where="14.5">primary-expression</non_terminal> classified as a type, and a member lookup (<hyperlink>14.3</hyperlink>) of I in E produces a match, then E.I is evaluated and classified as follows: </list_item><list><list_item> If I identifies a type, then the result is that type. </list_item><list_item> If I identifies one or more methods, then the result is a method group with no associated instance expression. </list_item><list_item> If I identifies a static property, then the result is a property access with no associated instance expression. </list_item><list_item> If I identifies a static field: </list_item><list><list_item> If the field is readonly and the reference occurs outside the static constructor of the class or struct in which the field is declared, then the result is a value, namely the value of the static field I in E. </list_item><list_item> Otherwise, the result is a variable, namely the static field I in E. </list_item></list><list_item> If I identifies a static event: </list_item><list><list_item> If the reference occurs within the class or struct in which the event is declared, and the event was declared without <non_terminal where="17.7">event-accessor-declarations</non_terminal> (<hyperlink>17.7</hyperlink>), then E.I is processed exactly as if I was a static field. </list_item><list_item> Otherwise, the result is an event access with no associated instance expression. </list_item></list><list_item> If I identifies a constant, then the result is a value, namely the value of that constant. </list_item><list_item> If I identifies an enumeration member, then the result is a value, namely the value of that enumeration member. </list_item><list_item> Otherwise, E.I is an invalid member reference, and a compile-time error occurs. </list_item></list><list_item> If E is a property access, indexer access, variable, or value, the type of which is T, and a member lookup (<hyperlink>14.3</hyperlink>) of I in T produces a match, then E.I is evaluated and classified as follows: </list_item><list><list_item> First, if E is a property or indexer access, then the value of the property or indexer access is obtained (<hyperlink>14.1.1</hyperlink>) and E is reclassified as a value. </list_item><list_item> If I identifies one or more methods, then the result is a method group with an associated instance expression of E. </list_item><list_item> If I identifies an instance property, then the result is a property access with an associated instance expression of E. </list_item><list_item> If T is a <non_terminal where="11.2">class-type</non_terminal> and I identifies an instance field of that class-type: </list_item><list><list_item> If the value of E is null, then a System.NullReferenceException is thrown. </list_item><list_item> Otherwise, if the field is readonly and the reference occurs outside an instance constructor of the class in which the field is declared, then the result is a value, namely the value of the field I in the object referenced by E. </list_item><list_item> Otherwise, the result is a variable, namely the field I in the object referenced by E. </list_item></list><list_item> If T is a <non_terminal where="11.1">struct-type</non_terminal> and I identifies an instance field of that struct-type: </list_item><list><list_item> If E is a value, or if the field is readonly and the reference occurs outside an instance constructor of the struct in which the field is declared, then the result is a value, namely the value of the field I in the struct instance given by E. </list_item><list_item> Otherwise, the result is a variable, namely the field I in the struct instance given by E. </list_item></list><list_item> If I identifies an instance event: </list_item><list><list_item> If the reference occurs within the class or struct in which the event is declared, and the event was declared without <non_terminal where="17.7">event-accessor-declarations</non_terminal> (<hyperlink>17.7</hyperlink>), then E.I is processed exactly as if I was an instance field. </list_item><list_item> Otherwise, the result is an event access with an associated instance expression of E. </list_item></list></list><list_item> Otherwise, E.I is an invalid member reference, and a compile-time error occurs. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.5.5.1.xml b/mcs/docs/ecma334/14.5.5.1.xml
new file mode 100644 (file)
index 0000000..b6cb505
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<clause number="14.5.5.1" title="Method invocations">
+  <paragraph>For a method invocation, the <non_terminal where="14.5">primary-expression</non_terminal> of the <non_terminal where="14.5.5">invocation-expression</non_terminal> must be a method group. The method group identifies the one method to invoke or the set of overloaded methods from which to choose a specific method to invoke. In the latter case, determination of the specific method to invoke is based on the context provided by the types of the arguments in the <non_terminal where="14.4.1">argument-list</non_terminal>. </paragraph>
+  <paragraph>The compile-time processing of a method invocation of the form M(A), where M is a method group and A is an optional <non_terminal where="14.4.1">argument-list</non_terminal>, consists of the following steps: <list><list_item> The set of candidate methods for the method invocation is constructed. Starting with the set of methods associated with M, which were found by a previous member lookup (<hyperlink>14.3</hyperlink>), the set is reduced to those methods that are applicable with respect to the argument list A. The set reduction consists of applying the following rules to each method T.N in the set, where T is the type in which the method N is declared: </list_item><list><list_item> If N is not applicable with respect to A (<hyperlink>14.4.2.1</hyperlink>), then N is removed from the set. </list_item><list_item> If N is applicable with respect to A (<hyperlink>14.4.2.1</hyperlink>), then all methods declared in a base type of T are removed from the set. </list_item></list><list_item> If the resulting set of candidate methods is empty, then no applicable methods exist, and a compile-time error occurs. If the candidate methods are not all declared in the same type, the method invocation is ambiguous, and a compile-time error occurs (this latter situation can only occur for an invocation of a method in an interface that has multiple direct base interfaces, as described in <hyperlink>20.2.5</hyperlink>). </list_item><list_item> The best method of the set of candidate methods is identified using the overload resolution rules of <hyperlink>14.4.2</hyperlink>. If a single best method cannot be identified, the method invocation is ambiguous, and a  compile-time error occurs. </list_item><list_item> Given a best method, the invocation of the method is validated in the context of the method group: If the best method is a static method, the method group must have resulted from a <non_terminal where="14.5.2">simple-name</non_terminal> or a  <non_terminal where="14.5.4">member-access</non_terminal> through a type. If the best method is an instance method, the method group must have resulted from a <non_terminal where="14.5.2">simple-name</non_terminal>, a <non_terminal where="14.5.4">member-access</non_terminal> through a variable or value, or a <non_terminal where="14.5.8">base-access</non_terminal>. If neither of these requirements are true, a compile-time error occurs. </list_item></list></paragraph>
+  <paragraph>Once a method has been selected and validated at compile-time by the above steps, the actual run-time invocation is processed according to the rules of function member invocation described in <hyperlink>14.4.3</hyperlink>. </paragraph>
+  <paragraph>
+    <note>[Note: The intuitive effect of the resolution rules described above is as follows: To locate the particular method invoked by a method invocation, start with the type indicated by the method invocation and proceed up the inheritance chain until at least one applicable, accessible, non-override method declaration is found. </note>
+  </paragraph>
+  <paragraph>
+    <note>Then perform overload resolution on the set of applicable, accessible, non-override methods declared in that type and invoke the method thus selected. end note]</note>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.5.5.2.xml b/mcs/docs/ecma334/14.5.5.2.xml
new file mode 100644 (file)
index 0000000..d4f2a45
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="14.5.5.2" title="Delegate invocations">
+  <paragraph>For a delegate invocation, the <non_terminal where="14.5">primary-expression</non_terminal> of the <non_terminal where="14.5.5">invocation-expression</non_terminal> must be a value of a <non_terminal where="11.2">delegate-type</non_terminal>. Furthermore, considering the <non_terminal where="11.2">delegate-type</non_terminal> to be a function member with the same parameter list as the <non_terminal where="11.2">delegate-type</non_terminal>, the <non_terminal where="11.2">delegate-type</non_terminal> must be applicable (<hyperlink>14.4.2.1</hyperlink>) with respect to the <non_terminal where="14.4.1">argument-list</non_terminal> of the <non_terminal where="14.5.5">invocation-expression</non_terminal>. </paragraph>
+  <paragraph>The run-time processing of a delegate invocation of the form D(A), where D is a <non_terminal where="14.5">primary-expression</non_terminal> of a <non_terminal where="11.2">delegate-type</non_terminal> and A is an optional <non_terminal where="14.4.1">argument-list</non_terminal>, consists of the following steps: <list><list_item> D is evaluated. If this evaluation causes an exception, no further steps are executed. </list_item><list_item> The value of D is checked to be valid. If the value of D is null, a System.NullReferenceException is thrown and no further steps are executed. </list_item><list_item> Otherwise, D is a reference to a delegate instance. A function member invocation (<hyperlink>14.4.3</hyperlink>) is performed on the method referenced by the delegate. If the method is an instance method, the instance of the invocation becomes the instance referenced by the delegate. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.5.5.xml b/mcs/docs/ecma334/14.5.5.xml
new file mode 100644 (file)
index 0000000..7b027ec
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<clause number="14.5.5" title="Invocation expressions">
+  <paragraph>An <non_terminal where="14.5.5">invocation-expression</non_terminal> is used to invoke a method. <grammar_production><name><non_terminal where="14.5.5">invocation-expression</non_terminal></name> : <rhs><non_terminal where="14.5">primary-expression</non_terminal><terminal>(</terminal><non_terminal where="14.4.1">argument-list</non_terminal><opt/><terminal>)</terminal></rhs></grammar_production></paragraph>
+  <paragraph>The <non_terminal where="14.5">primary-expression</non_terminal> of an <non_terminal where="14.5.5">invocation-expression</non_terminal> must be a method group or a value of a <non_terminal where="11.2">delegate-type</non_terminal>. If the <non_terminal where="14.5">primary-expression</non_terminal> is a method group, the <non_terminal where="14.5.5">invocation-expression</non_terminal> is a method invocation (<hyperlink>14.5.5.1</hyperlink>). If the <non_terminal where="14.5">primary-expression</non_terminal> is a value of a <non_terminal where="11.2">delegate-type</non_terminal>, the <non_terminal where="14.5.5">invocation-expression</non_terminal> is a delegate invocation (<hyperlink>14.5.5.2</hyperlink>). If the <non_terminal where="14.5">primary-expression</non_terminal> is neither a method group nor a value of a <non_terminal where="11.2">delegate-type</non_terminal>, a  compile-time error occurs. </paragraph>
+  <paragraph>The optional <non_terminal where="14.4.1">argument-list</non_terminal> (<hyperlink>14.4.1</hyperlink>) provides values or variable references for the parameters of the method. </paragraph>
+  <paragraph>The result of evaluating an <non_terminal where="14.5.5">invocation-expression</non_terminal> is classified as follows: <list><list_item> If the <non_terminal where="14.5.5">invocation-expression</non_terminal> invokes a method or delegate that returns <keyword>void</keyword>, the result is nothing. An expression that is classified as nothing cannot be an operand of any operator, and is permitted only in the context of a <non_terminal where="15.6">statement-expression</non_terminal> (<hyperlink>15.6</hyperlink>). </list_item><list_item> Otherwise, the result is a value of the type returned by the method or delegate. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.5.6.1.xml b/mcs/docs/ecma334/14.5.6.1.xml
new file mode 100644 (file)
index 0000000..e4617f9
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="14.5.6.1" title="Array access">
+  <paragraph>For an array access, the <non_terminal where="14.5">primary-no-array-creation-expression</non_terminal> of the <non_terminal where="14.5.6">element-access</non_terminal> must be a value of an <non_terminal where="19.1">array-type</non_terminal>. The number of expressions in the <non_terminal where="14.5.6">expression-list</non_terminal> must be the same as the rank of the <non_terminal where="19.1">array-type</non_terminal>, and each expression must be of type <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>long</keyword>, <keyword>ulong</keyword>, or of a type that can be implicitly converted to one or more of these types. </paragraph>
+  <paragraph>The result of evaluating an array access is a variable of the element type of the array, namely the array element selected by the value(s) of the expression(s) in the <non_terminal where="14.5.6">expression-list</non_terminal>. </paragraph>
+  <paragraph>The run-time processing of an array access of the form P[A], where P is a  <non_terminal where="14.5">primary-no-array-creation-expression</non_terminal> of an <non_terminal where="19.1">array-type</non_terminal> and A is an <non_terminal where="14.5.6">expression-list</non_terminal>, consists of the following steps: <list><list_item> P is evaluated. If this evaluation causes an exception, no further steps are executed. </list_item><list_item> The index expressions of the <non_terminal where="14.5.6">expression-list</non_terminal> are evaluated in order, from left to right. Following evaluation of each index expression, an implicit conversion (<hyperlink>13.1</hyperlink>) to one of the following types is performed: <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>long</keyword>, <keyword>ulong</keyword>. The first type in this list for which an implicit conversion exists is chosen. For instance, if the index expression is of type <keyword>short</keyword> then an implicit conversion to <keyword>int</keyword> is performed, since implicit conversions from <keyword>short</keyword> to <keyword>int</keyword> and from <keyword>short</keyword> to <keyword>long</keyword> are possible. If evaluation of an index expression or the subsequent implicit conversion causes an exception, then no further index expressions are evaluated and no further steps are executed. </list_item><list_item> The value of P is checked to be valid. If the value of P is null, a System.NullReferenceException is thrown and no further steps are executed. </list_item><list_item> The value of each expression in the <non_terminal where="14.5.6">expression-list</non_terminal> is checked against the actual bounds of each dimension of the array instance referenced by P. If one or more values are out of range, a System.IndexOutOfRangeException is thrown and no further steps are executed. </list_item><list_item> The location of the array element given by the index expression(s) is computed, and this location becomes the result of the array access. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.5.6.2.xml b/mcs/docs/ecma334/14.5.6.2.xml
new file mode 100644 (file)
index 0000000..d094acd
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="14.5.6.2" title="Indexer access">
+  <paragraph>For an indexer access, the <non_terminal where="14.5">primary-no-array-creation-expression</non_terminal> of the element-accessmust be a variable or value of a class, struct, or interface type, and this type must implement one or more indexers that are applicable with respect to the <non_terminal where="14.5.6">expression-list</non_terminal> of the <non_terminal where="14.5.6">element-access</non_terminal>. </paragraph>
+  <paragraph>The compile-time processing of an indexer access of the form P[A], where P is a  <non_terminal where="14.5">primary-no-array-creation-expression</non_terminal> of a class, struct, or interface type T, and A is an <non_terminal where="14.5.6">expression-list</non_terminal>, consists of the following steps: <list><list_item> The set of indexers provided by T is constructed. The set consists of all indexers declared in T or a base type of T that are not override declarations and are accessible in the current context (<hyperlink>10.5</hyperlink>). </list_item><list_item> The set is reduced to those indexers that are applicable and not hidden by other indexers. The following rules are applied to each indexer S.I in the set, where S is the type in which the indexer I is declared: </list_item><list><list_item> If I is not applicable with respect to A (<hyperlink>14.4.2.1</hyperlink>), then I is removed from the set. </list_item><list_item> If I is applicable with respect to A (<hyperlink>14.4.2.1</hyperlink>), then all indexers declared in a base type of S are removed from the set. </list_item></list><list_item> If the resulting set of candidate indexers is empty, then no applicable indexers exist, and a compile-time error occurs. If the candidate indexers are not all declared in the same type, the indexer access is ambiguous, and a compile-time error occurs (this latter situation can only occur for an indexer access on an instance of an interface that has multiple direct base interfaces). </list_item><list_item> The best indexer of the set of candidate indexers is identified using the overload resolution rules of <hyperlink>14.4.2</hyperlink>. If a single best indexer cannot be identified, the indexer access is ambiguous, and a compile-time error occurs. </list_item><list_item> The index expressions of the <non_terminal where="14.5.6">expression-list</non_terminal> are evaluated in order, from left to right. The result of processing the indexer access is an expression classified as an indexer access. The indexer access expression references the indexer determined in the step above, and has an associated instance expression of P and an associated argument list of A. </list_item></list></paragraph>
+  <paragraph>Depending on the context in which it is used, an indexer access causes invocation of either the get-accessor or the set-accessor of the indexer. If the indexer access is the target of an assignment, the set-accessor is invoked to assign a new value (<hyperlink>14.13.1</hyperlink>). In all other cases, the get-accessor is invoked to obtain the current value (<hyperlink>14.1.1</hyperlink>). </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.5.6.xml b/mcs/docs/ecma334/14.5.6.xml
new file mode 100644 (file)
index 0000000..59c3993
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="14.5.6" title="Element access">
+  <paragraph>An <non_terminal where="14.5.6">element-access</non_terminal> consists of a <non_terminal where="14.5">primary-no-array-creation-expression</non_terminal>, followed by a &quot;[&quot; token, followed by an <non_terminal where="14.5.6">expression-list</non_terminal>, followed by a &quot;]&quot; token. The <non_terminal where="14.5.6">expression-list</non_terminal> consists of one or more expressions, separated by commas. <grammar_production><name><non_terminal where="14.5.6">element-access</non_terminal></name> : <rhs><non_terminal where="14.5">primary-no-array-creation-expression</non_terminal><terminal>[</terminal><non_terminal where="14.5.6">expression-list</non_terminal><terminal>]</terminal></rhs></grammar_production><grammar_production><name><non_terminal where="14.5.6">expression-list</non_terminal></name> : <rhs><non_terminal where="14.14">expression</non_terminal></rhs><rhs><non_terminal where="14.5.6">expression-list</non_terminal><terminal>,</terminal><non_terminal where="14.14">expression</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>If the <non_terminal where="14.5">primary-no-array-creation-expression</non_terminal> of an <non_terminal where="14.5.6">element-access</non_terminal> is a value of an <non_terminal where="19.1">array-type</non_terminal>, the  <non_terminal where="14.5.6">element-access</non_terminal> is an array access (<hyperlink>14.5.6.1</hyperlink>). Otherwise, the <non_terminal where="14.5">primary-no-array-creation-expression</non_terminal> must be a variable or value of a class, struct, or interface type that has one or more indexer members, in which case the <non_terminal where="14.5.6">element-access</non_terminal> is an indexer access (<hyperlink>14.5.6.2</hyperlink>). </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.5.7.xml b/mcs/docs/ecma334/14.5.7.xml
new file mode 100644 (file)
index 0000000..11d0483
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="14.5.7" title="This access">
+  <paragraph>A <non_terminal where="14.5.7">this-access</non_terminal> consists of the reserved word this. <grammar_production><name><non_terminal where="14.5.7">this-access</non_terminal></name> : <rhs><keyword>this</keyword></rhs></grammar_production></paragraph>
+  <paragraph>A <non_terminal where="14.5.7">this-access</non_terminal> is permitted only in the block of an instance constructor, an instance method, or an instance accessor. It has one of the following meanings: <list><list_item> When this is used in a <non_terminal where="14.5">primary-expression</non_terminal> within an instance constructor of a class, it is classified as a value. The type of the value is the class within which the usage occurs, and the value is a reference to the object being constructed. </list_item><list_item> When this is used in a <non_terminal where="14.5">primary-expression</non_terminal> within an instance method or instance accessor of a class, it is classified as a value. The type of the value is the class within which the usage occurs, and the value is a reference to the object for which the method or accessor was invoked. </list_item><list_item> When this is used in a <non_terminal where="14.5">primary-expression</non_terminal> within an instance constructor of a struct, it is classified as a variable. The type of the variable is the struct within which the usage occurs, and the variable represents the struct being constructed. The this variable of an instance constructor of a struct behaves exactly the same as an out parameter of the struct type-in particular, this means that the variable must be definitely assigned in every execution path of the instance constructor. </list_item><list_item> When this is used in a <non_terminal where="14.5">primary-expression</non_terminal> within an instance method or instance accessor of a struct, it is classified as a variable. The type of the variable is the struct within which the usage occurs, and the variable represents the struct for which the method or accessor was invoked. The this variable of an instance method of a struct behaves exactly the same as a ref parameter of the struct type. </list_item></list></paragraph>
+  <paragraph>Use of this in a <non_terminal where="14.5">primary-expression</non_terminal> in a context other than the ones listed above is a compile-time error. In particular, it is not possible to refer to this in a static method, a static property accessor, or in a  <non_terminal where="19.6">variable-initializer</non_terminal> of a field declaration. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.5.8.xml b/mcs/docs/ecma334/14.5.8.xml
new file mode 100644 (file)
index 0000000..5aa10ed
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<clause number="14.5.8" title="Base access">
+  <paragraph>A <non_terminal where="14.5.8">base-access</non_terminal> consists of the reserved word base followed by either a &quot;.&quot; token and an identifier or an <non_terminal where="14.5.6">expression-list</non_terminal> enclosed in square brackets: <grammar_production><name><non_terminal where="14.5.8">base-access</non_terminal></name> : <rhs><keyword>base</keyword><terminal>.</terminal><non_terminal where="9.4.2">identifier</non_terminal></rhs><rhs><keyword>base</keyword><terminal>[</terminal><non_terminal where="14.5.6">expression-list</non_terminal><terminal>]</terminal></rhs></grammar_production></paragraph>
+  <paragraph>A <non_terminal where="14.5.8">base-access</non_terminal> is used to access base class members that are hidden by similarly named members in the current class or struct. A <non_terminal where="14.5.8">base-access</non_terminal> is permitted only in the block of an instance constructor, an instance method, or an instance accessor. When base.I occurs in a class or struct, I must denote a member of the base class of that class or struct. Likewise, when base[E] occurs in a class, an applicable indexer must exist in the base class. </paragraph>
+  <paragraph>At compile-time, <non_terminal where="14.5.8">base-access</non_terminal> expressions of the form base.I and base[E] are evaluated exactly as if they were written ((B)this).I and ((B)this)[E], where B is the base class of the class or struct in which the construct occurs. Thus, base.I and base[E] correspond to this.I and this[E], except this is viewed as an instance of the base class. </paragraph>
+  <paragraph>When a <non_terminal where="14.5.8">base-access</non_terminal> references a virtual function member (a method, property, or indexer), the determination of which function member to invoke at run-time (<hyperlink>14.4.3</hyperlink>) is changed. The function member that is invoked is determined by finding the most derived implementation (<hyperlink>17.5.3</hyperlink>) of the function member with respect to B (instead of with respect to the run-time type of this, as would be usual in a non-base access). Thus, within an override of a virtual function member, a <non_terminal where="14.5.8">base-access</non_terminal> can be used to invoke the inherited implementation of the function member. If the function member referenced by a <non_terminal where="14.5.8">base-access</non_terminal> is abstract, a compile-time error occurs. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.5.9.xml b/mcs/docs/ecma334/14.5.9.xml
new file mode 100644 (file)
index 0000000..9d4e75e
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<clause number="14.5.9" title="Postfix increment and decrement operators">
+  <paragraph>
+    <grammar_production><name><non_terminal where="14.5.9">post-increment-expression</non_terminal></name> : <rhs><non_terminal where="14.5">primary-expression</non_terminal><terminal>++</terminal></rhs></grammar_production>
+    <grammar_production><name><non_terminal where="14.5.9">post-decrement-expression</non_terminal></name> : <rhs><non_terminal where="14.5">primary-expression</non_terminal><terminal>--</terminal></rhs></grammar_production>
+  </paragraph>
+  <paragraph>The operand of a postfix increment or decrement operation must be an expression classified as a variable, a property access, or an indexer access. The result of the operation is a value of the same type as the operand. </paragraph>
+  <paragraph>If the operand of a postfix increment or decrement operation is a property or indexer access, the property or indexer must have both a get and a set accessor. If this is not the case, a compile-time error occurs. </paragraph>
+  <paragraph>Unary operator overload resolution (<hyperlink>14.2.3</hyperlink>) is applied to select a specific operator implementation. Predefined ++ and  --operators exist for the following types: <keyword>sbyte</keyword>, <keyword>byte</keyword>, <keyword>short</keyword>, <keyword>ushort</keyword>, <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>long</keyword>, <keyword>ulong</keyword>, <keyword>char</keyword>, <keyword>float</keyword>, <keyword>double</keyword>, <keyword>decimal</keyword>, and any enum type. The predefined ++ operators return the value produced by adding 1 to the operand, and the predefined  --operators return the value produced by subtracting 1 from the operand. </paragraph>
+  <paragraph>The run-time processing of a postfix increment or decrement operation of the form x++ or  x--consists of the following steps: <list><list_item> If x is classified as a variable: </list_item><list><list_item> x is evaluated to produce the variable. </list_item><list_item> The value of x is saved. </list_item><list_item> The selected operator is invoked with the saved value of x as its argument. </list_item><list_item> The value returned by the operator is stored in the location given by the evaluation of x. </list_item><list_item> The saved value of x becomes the result of the operation. </list_item></list><list_item> If x is classified as a property or indexer access: </list_item><list><list_item> The instance expression (if x is not static) and the argument list (if x is an indexer access) associated with x are evaluated, and the results are used in the subsequent get and set accessor invocations. </list_item><list_item> The get accessor of x is invoked and the returned value is saved. </list_item><list_item> The selected operator is invoked with the saved value of x as its argument. </list_item><list_item> The set accessor of x is invoked with the value returned by the operator as its value argument. </list_item><list_item> The saved value of x becomes the result of the operation. </list_item></list></list></paragraph>
+  <paragraph>The ++ and  --operators also support prefix notation (<hyperlink>14.6.5</hyperlink>). The result of x++ or  x--is the value of x before the operation, whereas the result of ++x or --x is the value of x after the operation. In either case, x itself has the same value after the operation. </paragraph>
+  <paragraph>An operator ++ or operator  --implementation can be invoked using either postfix or prefix notation. It is not possible to have separate operator implementations for the two notations. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.5.xml b/mcs/docs/ecma334/14.5.xml
new file mode 100644 (file)
index 0000000..fdfcc9f
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<clause number="14.5" title="Primary expressions">
+  <paragraph>Primary expressions include the simplest forms of expressions. <grammar_production><name><non_terminal where="14.5">primary-expression</non_terminal></name> : <rhs><non_terminal where="14.5.10.2">array-creation-expression</non_terminal></rhs><rhs><non_terminal where="14.5">primary-no-array-creation-expression</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="14.5">primary-no-array-creation-expression</non_terminal></name> : <rhs><non_terminal where="9.4.4">literal</non_terminal></rhs><rhs><non_terminal where="14.5.2">simple-name</non_terminal></rhs><rhs><non_terminal where="14.5.3">parenthesized-expression</non_terminal></rhs><rhs><non_terminal where="14.5.4">member-access</non_terminal></rhs><rhs><non_terminal where="14.5.5">invocation-expression</non_terminal></rhs><rhs><non_terminal where="14.5.6">element-access</non_terminal></rhs><rhs><non_terminal where="14.5.7">this-access</non_terminal></rhs><rhs><non_terminal where="14.5.8">base-access</non_terminal></rhs><rhs><non_terminal where="14.5.9">post-increment-expression</non_terminal></rhs><rhs><non_terminal where="14.5.9">post-decrement-expression</non_terminal></rhs><rhs><non_terminal where="14.5.10.1">object-creation-expression</non_terminal></rhs><rhs><non_terminal where="14.5.10.3">delegate-creation-expression</non_terminal></rhs><rhs><non_terminal where="14.5.11">typeof-expression</non_terminal></rhs><rhs><non_terminal where="25.5.8">sizeof-expression</non_terminal></rhs><rhs><non_terminal where="14.5.12">checked-expression</non_terminal></rhs><rhs><non_terminal where="14.5.12">unchecked-expression</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>Primary expressions are divided between <non_terminal where="14.5.10.2">array-creation-expression</non_terminal>s and  <non_terminal where="14.5">primary-no-array-creation-expression</non_terminal>s. Treating <non_terminal where="14.5.10.2">array-creation-expression</non_terminal> in this way, rather than listing it along with the other simple expression forms, enables the grammar to disallow potentially confusing code such as <code_example><![CDATA[
+object o = new int[3][1];  
+]]></code_example>which would otherwise be interpreted as <code_example><![CDATA[
+object o = (new int[3])[1];  
+]]></code_example></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.6.1.xml b/mcs/docs/ecma334/14.6.1.xml
new file mode 100644 (file)
index 0000000..f652324
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<clause number="14.6.1" title="Unary plus operator">
+  <paragraph>For an operation of the form +x, unary operator overload resolution (<hyperlink>14.2.3</hyperlink>) is applied to select a specific operator implementation. The operand is converted to the parameter type of the selected operator, and the type of the result is the return type of the operator. The predefined unary plus operators are: <code_example><![CDATA[
+int operator +(int x);  
+uint operator +(uint x);  
+long operator +(long x);  
+ulong operator +(ulong x);  
+float operator +(float x);  
+double operator +(double x);  
+decimal operator +(decimal x);  
+]]></code_example></paragraph>
+  <paragraph>For each of these operators, the result is simply the value of the operand. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.6.2.xml b/mcs/docs/ecma334/14.6.2.xml
new file mode 100644 (file)
index 0000000..f8215b2
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<clause number="14.6.2" title="Unary minus operator">
+  <paragraph>For an operation of the form -x, unary operator overload resolution (<hyperlink>14.2.3</hyperlink>) is applied to select a specific operator implementation. The operand is converted to the parameter type of the selected operator, and the type of the result is the return type of the operator. The predefined negation operators are: <list><list_item> Integer negation: <code_example><![CDATA[
+int operator -(int x);  
+long operator -(long x);  
+]]></code_example></list_item></list></paragraph>
+  <paragraph>The result is computed by subtracting x from zero. In a checked context, if the value of x is the maximum negative <keyword>int</keyword> or <keyword>long</keyword>, a System.OverflowException is thrown. In an unchecked context, if the value of x is the maximum negative <keyword>int</keyword> or <keyword>long</keyword>, the result is that same value and the overflow is not reported. If the operand of the negation operator is of type <keyword>uint</keyword>, it is converted to type <keyword>long</keyword>, and the type of the result is <keyword>long</keyword>. An exception is the rule that permits the <keyword>int</keyword> value <unicode>8722</unicode>2147483648 (<unicode>8722</unicode>2<super>31</super>) to be written as a <keyword>decimal</keyword> integer literal (<hyperlink>9.4.4.2</hyperlink>). If the operand of the negation operator is of type <keyword>ulong</keyword>, a compile-time error occurs. An exception is the rule that permits the <keyword>long</keyword> value <unicode>8722</unicode>9223372036854775808 (<unicode>8722</unicode>2<super>63</super>) to be written as a <keyword>decimal</keyword> integer literal (<hyperlink>9.4.4.2</hyperlink>). <list><list_item> Floating-point negation: <code_example><![CDATA[
+float operator -(float x);  
+double operator -(double x);  
+]]></code_example></list_item></list></paragraph>
+  <paragraph>The result is the value of x with its sign inverted. If x is NaN, the result is also NaN. <list><list_item> Decimal negation: <code_example><![CDATA[
+decimal operator -(decimal x);  
+]]></code_example></list_item></list></paragraph>
+  <paragraph>The result is computed by subtracting x from zero. Decimal negation is equivalent to using the unary minus operator of type System.Decimal. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.6.3.xml b/mcs/docs/ecma334/14.6.3.xml
new file mode 100644 (file)
index 0000000..4cb91ff
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<clause number="14.6.3" title="Logical negation operator">
+  <paragraph>For an operation of the form !x, unary operator overload resolution (<hyperlink>14.2.3</hyperlink>) is applied to select a specific operator implementation. The operand is converted to the parameter type of the selected operator, and the type of the result is the return type of the operator. Only one predefined logical negation operator exists: <code_example><![CDATA[
+bool operator !(bool x);  
+]]></code_example></paragraph>
+  <paragraph>This operator computes the logical negation of the operand: If the operand is true, the result is false. If the operand is false, the result is true. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.6.4.xml b/mcs/docs/ecma334/14.6.4.xml
new file mode 100644 (file)
index 0000000..4d54eaa
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<clause number="14.6.4" title="Bitwise complement operator">
+  <paragraph>For an operation of the form ~x, unary operator overload resolution (<hyperlink>14.2.3</hyperlink>) is applied to select a specific operator implementation. The operand is converted to the parameter type of the selected operator, and the type of the result is the return type of the operator. The predefined bitwise complement operators are: <code_example><![CDATA[
+int operator ~(int x);  
+uint operator ~(uint x);  
+long operator ~(long x);  
+ulong operator ~(ulong x);  
+]]></code_example></paragraph>
+  <paragraph>For each of these operators, the result of the operation is the bitwise complement of x. </paragraph>
+  <paragraph>Every enumeration type E implicitly provides the following bitwise complement operator: <code_example><![CDATA[
+E operator ~(E x);  
+]]></code_example></paragraph>
+  <paragraph>The result of evaluating ~x, where x is an expression of an enumeration type E with an underlying type U, is exactly the same as evaluating (E)(~(U)x). </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.6.5.xml b/mcs/docs/ecma334/14.6.5.xml
new file mode 100644 (file)
index 0000000..22118bf
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<clause number="14.6.5" title="Prefix increment and decrement operators">
+  <paragraph>
+    <grammar_production><name><non_terminal where="14.6.5">pre-increment-expression</non_terminal></name> : <rhs><terminal>++</terminal><non_terminal where="14.6">unary-expression</non_terminal></rhs></grammar_production>
+    <grammar_production><name><non_terminal where="14.6.5">pre-decrement-expression</non_terminal></name> : <rhs><terminal>--</terminal><non_terminal where="14.6">unary-expression</non_terminal></rhs></grammar_production>
+  </paragraph>
+  <paragraph>The operand of a prefix increment or decrement operation must be an expression classified as a variable, a property access, or an indexer access. The result of the operation is a value of the same type as the operand. </paragraph>
+  <paragraph>If the operand of a prefix increment or decrement operation is a property or indexer access, the property or indexer must have both a get and a set accessor. If this is not the case, a compile-time error occurs. </paragraph>
+  <paragraph>Unary operator overload resolution (<hyperlink>14.2.3</hyperlink>) is applied to select a specific operator implementation. Predefined ++ and  --operators exist for the following types: <keyword>sbyte</keyword>, <keyword>byte</keyword>, <keyword>short</keyword>, <keyword>ushort</keyword>, <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>long</keyword>, <keyword>ulong</keyword>, <keyword>char</keyword>, <keyword>float</keyword>, <keyword>double</keyword>, <keyword>decimal</keyword>, and any enum type. The predefined ++ operators return the value produced by adding 1 to the operand, and the predefined  --operators return the value produced by subtracting 1 from the operand. </paragraph>
+  <paragraph>The run-time processing of a prefix increment or decrement operation of the form ++x or --x consists of the following steps: <list><list_item> If x is classified as a variable: </list_item><list><list_item> x is evaluated to produce the variable. </list_item><list_item> The selected operator is invoked with the value of x as its argument. </list_item><list_item> The value returned by the operator is stored in the location given by the evaluation of x. </list_item><list_item> The value returned by the operator becomes the result of the operation. </list_item></list><list_item> If x is classified as a property or indexer access: </list_item><list><list_item> The instance expression (if x is not static) and the argument list (if x is an indexer access) associated with x are evaluated, and the results are used in the subsequent get and set accessor invocations. </list_item><list_item> The get accessor of x is invoked. </list_item><list_item> The selected operator is invoked with the value returned by the get accessor as its argument. </list_item><list_item> The set accessor of x is invoked with the value returned by the operator as its value argument. </list_item><list_item> The value returned by the operator becomes the result of the operation. </list_item></list></list></paragraph>
+  <paragraph>The ++ and  --operators also support postfix notation (<hyperlink>14.5.9</hyperlink>). The result of x++ or  x--is the value of x before the operation, whereas the result of ++x or --x is the value of x after the operation. In either case, x itself has the same value after the operation. </paragraph>
+  <paragraph>An operator ++ or operator  --implementation can be invoked using either postfix or prefix notation. It is not possible to have separate operator implementations for the two notations. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.6.6.xml b/mcs/docs/ecma334/14.6.6.xml
new file mode 100644 (file)
index 0000000..08c4134
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<clause number="14.6.6" title="Cast expressions">
+  <paragraph>A <non_terminal where="14.6.6">cast-expression</non_terminal> is used to explicitly convert an expression to a given type. <grammar_production><name><non_terminal where="14.6.6">cast-expression</non_terminal></name> : <rhs><terminal>(</terminal><non_terminal where="11">type</non_terminal><terminal>)</terminal><non_terminal where="14.6">unary-expression</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>A <non_terminal where="14.6.6">cast-expression</non_terminal> of the form (T)E, where T is a type and E is a <non_terminal where="14.6">unary-expression</non_terminal>, performs an explicit conversion (<hyperlink>13.2</hyperlink>) of the value of E to type T. If no explicit conversion exists from the type of E to T, a compile-time error occurs. Otherwise, the result is the value produced by the explicit conversion. The result is always classified as a value, even if E denotes a variable. </paragraph>
+  <paragraph>The grammar for a <non_terminal where="14.6.6">cast-expression</non_terminal> leads to certain syntactic ambiguities. For example, the expression  (x)-y could either be interpreted as a <non_terminal where="14.6.6">cast-expression</non_terminal> (a cast of -y to type x) or as an <non_terminal where="14.7">additive-expression</non_terminal> combined with a <non_terminal where="14.5.3">parenthesized-expression</non_terminal> (which computes the value x  -y). </paragraph>
+  <paragraph>To resolve <non_terminal where="14.6.6">cast-expression</non_terminal> ambiguities, the following rule exists: A sequence of one or more tokens (<hyperlink>9.4</hyperlink>) enclosed in parentheses is considered the start of a <non_terminal where="14.6.6">cast-expression</non_terminal> only if at least one of the following are true: <list><list_item> The sequence of tokens is correct grammar for a type, but not for an expression. </list_item><list_item> The sequence of tokens is correct grammar for a type, and the token immediately following the closing parentheses is the token &quot;~&quot;, the token &quot;!&quot;, the token &quot;(&quot;, an identifier (<hyperlink>9.4.1</hyperlink>), a literal (<hyperlink>9.4.4</hyperlink>), or any keyword (<hyperlink>9.4.3</hyperlink>) except as and is. </list_item></list></paragraph>
+  <paragraph>
+    <note>[Note: The above rule means that only if the construct is unambiguously a <non_terminal where="14.6.6">cast-expression</non_terminal> is it considered a <non_terminal where="14.6.6">cast-expression</non_terminal>. end note]</note>
+  </paragraph>
+  <paragraph>The term &quot;correct grammar&quot; above means only that the sequence of tokens must conform to the particular grammatical production. It specifically does not consider the actual meaning of any constituent identifiers. For example, if x and y are identifiers, then x.y is correct grammar for a type, even if x.y doesn't actually denote a type. </paragraph>
+  <paragraph>
+    <note>[Note: From the disambiguation rule, it follows that, if x and y are identifiers, (x)y, (x)(y), and (x)(-y) are <non_terminal where="14.6.6">cast-expression</non_terminal>s, but (x)-y is not, even if x identifies a type. However, if x is a keyword that identifies a predefined type (such as <keyword>int</keyword>), then all four forms are <non_terminal where="14.6.6">cast-expression</non_terminal>s (because such a keyword could not possibly be an expression by itself). end note]</note>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.6.xml b/mcs/docs/ecma334/14.6.xml
new file mode 100644 (file)
index 0000000..f08a33f
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="14.6" title="Unary expressions">
+  <paragraph>
+    <grammar_production><name><non_terminal where="14.6">unary-expression</non_terminal></name> : <rhs><non_terminal where="14.5">primary-expression</non_terminal></rhs><rhs><terminal>+</terminal><non_terminal where="14.6">unary-expression</non_terminal></rhs><rhs><terminal>-</terminal><non_terminal where="14.6">unary-expression</non_terminal></rhs><rhs><terminal>!</terminal><non_terminal where="14.6">unary-expression</non_terminal></rhs><rhs><terminal>~</terminal><non_terminal where="14.6">unary-expression</non_terminal></rhs><rhs><terminal>*</terminal><non_terminal where="14.6">unary-expression</non_terminal></rhs><rhs><terminal>&amp;</terminal><non_terminal where="14.6">unary-expression</non_terminal></rhs><rhs><non_terminal where="14.6.5">pre-increment-expression</non_terminal></rhs><rhs><non_terminal where="14.6.5">pre-decrement-expression</non_terminal></rhs><rhs><non_terminal where="14.6.6">cast-expression</non_terminal></rhs></grammar_production>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.7.1.xml b/mcs/docs/ecma334/14.7.1.xml
new file mode 100644 (file)
index 0000000..0b40cb0
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<clause number="14.7.1" title="Multiplication operator">
+  <paragraph>For an operation of the form x * y, binary operator overload resolution (<hyperlink>14.2.4</hyperlink>) is applied to select a specific operator implementation. The operands are converted to the parameter types of the selected operator, and the type of the result is the return type of the operator. </paragraph>
+  <paragraph>The predefined multiplication operators are listed below. The operators all compute the product of x and y. <list><list_item> Integer multiplication: <code_example><![CDATA[
+int operator *(int x, int y);  
+uint operator *(uint x, uint y);  
+long operator *(long x, long y);  
+ulong operator *(ulong x, ulong y);  
+]]></code_example>In a checked context, if the product is outside the range of the result type, a System.OverflowException is thrown. In an unchecked context, overflows are not reported and any significant high-order bits outside the range of the result type are discarded. </list_item><list_item> Floating-point multiplication: <code_example><![CDATA[
+float operator *(float x, float y);  
+double operator *(double x, double y);  
+]]></code_example>The product is computed according to the rules of IEEE 754 arithmetic. The following table lists the results of all possible combinations of nonzero finite values, zeros, infinities, and NaN's. In the table, x and y are positive finite values. z is the result of x * y. If the result is too large for the destination type, z is infinity. If the result is too small for the destination type, z is zero. <table_line>+y <unicode>150</unicode>y +0 <unicode>150</unicode>0 +<infinity/> <unicode>150</unicode><infinity/> NaN </table_line>
+<table_line>+x +z <unicode>150</unicode>z +0 <unicode>150</unicode>0 +<infinity/> <unicode>150</unicode><infinity/> NaN </table_line>
+<table_line><unicode>150</unicode>x <unicode>150</unicode>z +z <unicode>150</unicode>0 +0 <unicode>150</unicode><infinity/> +<infinity/> NaN </table_line>
+<table_line>+0 +0 <unicode>150</unicode>0 +0 <unicode>150</unicode>0 NaN NaN NaN </table_line>
+<table_line><unicode>150</unicode>0 <unicode>150</unicode>0 +0 <unicode>150</unicode>0 +0 NaN NaN NaN </table_line>
+<table_line>+<infinity/> +<infinity/> <unicode>150</unicode><infinity/> NaN NaN +<infinity/> <unicode>150</unicode><infinity/> NaN </table_line>
+<table_line><unicode>150</unicode><infinity/><unicode>150</unicode><infinity/> +<infinity/> NaN NaN <unicode>150</unicode><infinity/> +<infinity/> NaN </table_line>
+<table_line>NaN NaN NaN NaN NaN NaN NaN NaN </table_line>
+</list_item><list_item> Decimal multiplication: <code_example><![CDATA[
+decimal operator *(decimal x, decimal y);  
+]]></code_example>If the resulting value is too large to represent in the <keyword>decimal</keyword> format, a System.OverflowException is thrown. If the result value is too small to represent in the <keyword>decimal</keyword> format, the result is zero. The scale of the result, before any rounding, is the sum of the scales of the two operands. Decimal multiplication is equivalent to using the multiplication operator of type System.Decimal. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.7.2.xml b/mcs/docs/ecma334/14.7.2.xml
new file mode 100644 (file)
index 0000000..8055d33
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<clause number="14.7.2" title="Division operator">
+  <paragraph>For an operation of the form x / y, binary operator overload resolution (<hyperlink>14.2.4</hyperlink>) is applied to select a specific operator implementation. The operands are converted to the parameter types of the selected operator, and the type of the result is the return type of the operator. </paragraph>
+  <paragraph>The predefined division operators are listed below. The operators all compute the quotient of x and y. <list><list_item> Integer division: <code_example><![CDATA[
+int operator /(int x, int y);  
+uint operator /(uint x, uint y);  
+long operator /(long x, long y);  
+ulong operator /(ulong x, ulong y);  
+]]></code_example>If the value of the right operand is zero, a System.DivideByZeroException is thrown. The division rounds the result towards zero, and the absolute value of the result is the largest possible integer that is less than the absolute value of the quotient of the two operands. The result is zero or positive when the two operands have the same sign and zero or negative when the two operands have opposite signs. If the left operand is the maximum negative <keyword>int</keyword> or <keyword>long</keyword> value and the right operand is -1, an overflow occurs. In a checked context, this causes a System.OverflowException to be thrown. In an unchecked context, the overflow is not reported and the result is instead the value of the left operand. </list_item><list_item> Floating-point division: <code_example><![CDATA[
+float operator /(float x, float y);  
+double operator /(double x, double y);  
+]]></code_example>The quotient is computed according to the rules of IEEE 754 arithmetic. The following table lists the results of all possible combinations of nonzero finite values, zeros, infinities, and NaN's. In the table, x and y are positive finite values. z is the result of x / y. If the result is too large for the destination type, z is infinity. If the result is too small for the destination type, z is zero. <table_line>+y <unicode>150</unicode>y +0 <unicode>150</unicode>0 +<infinity/> <unicode>150</unicode><infinity/> NaN </table_line>
+<table_line>+x +z <unicode>150</unicode>z +<infinity/> <unicode>150</unicode><infinity/> +0 <unicode>150</unicode>0 NaN </table_line>
+<table_line><unicode>150</unicode>x <unicode>150</unicode>z +z <unicode>150</unicode><infinity/> +<infinity/><unicode>150</unicode>0 +0 NaN </table_line>
+<table_line>+0 +0 <unicode>150</unicode>0 NaN NaN +0 <unicode>150</unicode>0 NaN </table_line>
+<table_line><unicode>150</unicode>0 <unicode>150</unicode>0 +0 NaN NaN <unicode>150</unicode>0 +0 NaN </table_line>
+<table_line>+<infinity/> +<infinity/> <unicode>150</unicode><infinity/> +<infinity/> <unicode>150</unicode><infinity/> NaN NaN NaN </table_line>
+<table_line><unicode>150</unicode><infinity/><unicode>150</unicode><infinity/> +<infinity/><unicode>150</unicode><infinity/> +<infinity/> NaN NaN NaN </table_line>
+<table_line>NaN NaN NaN NaN NaN NaN NaN NaN </table_line>
+</list_item><list_item> Decimal division: <code_example><![CDATA[
+decimal operator /(decimal x, decimal y);  
+]]></code_example>If the value of the right operand is zero, a System.DivideByZeroException is thrown. If the resulting value is too large to represent in the <keyword>decimal</keyword> format, a System.OverflowException is thrown. If the result value is too small to represent in the <keyword>decimal</keyword> format, the result is zero. The scale of the result, before any rounding, is the smallest scale that will preserve a result equal to the exact result. Decimal division is equivalent to using the division operator of type System.Decimal. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.7.3.xml b/mcs/docs/ecma334/14.7.3.xml
new file mode 100644 (file)
index 0000000..74ddb00
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<clause number="14.7.3" title="Remainder operator">
+  <paragraph>For an operation of the form x % y, binary operator overload resolution (<hyperlink>14.2.4</hyperlink>) is applied to select a specific operator implementation. The operands are converted to the parameter types of the selected operator, and the type of the result is the return type of the operator. </paragraph>
+  <paragraph>The predefined remainder operators are listed below. The operators all compute the remainder of the division between x and y. <list><list_item> Integer remainder: <code_example><![CDATA[
+int operator %(int x, int y);  
+uint operator %(uint x, uint y);  
+long operator %(long x, long y);  
+ulong operator %(ulong x, ulong y);  
+]]></code_example>The result of x % y is the value produced by x  -(x / y) * y. If y is zero, a System.DivideByZeroException is thrown. The remainder operator never causes an overflow. </list_item><list_item> Floating-point remainder: <code_example><![CDATA[
+float operator %(float x, float y);  
+double operator %(double x, double y);  
+]]></code_example>The following table lists the results of all possible combinations of nonzero finite values, zeros, infinities, and NaN's. In the table, x and y are positive finite values. z is the result of x % y and is computed as x  -n * y, where n is the largest possible integer that is less than or equal to x / y. This method of computing the remainder is analogous to that used for integer operands, but differs from the IEEE 754 definition (in which n is the integer closest to x / y). <table_line>+y <unicode>150</unicode>y +0 <unicode>150</unicode>0 +<infinity/> <unicode>150</unicode><infinity/> NaN </table_line>
+<table_line>+x +z +z NaN NaN x x NaN </table_line>
+<table_line><unicode>150</unicode>x <unicode>150</unicode>z <unicode>150</unicode>z NaN NaN <unicode>150</unicode>x <unicode>150</unicode>x NaN </table_line>
+<table_line>+0 +0 +0 NaN NaN +0 +0 NaN </table_line>
+<table_line><unicode>150</unicode>0 <unicode>150</unicode>0 <unicode>150</unicode>0 NaN NaN <unicode>150</unicode>0 <unicode>150</unicode>0 NaN </table_line>
+<table_line>+<infinity/> NaN NaN NaN NaN NaN NaN NaN </table_line>
+<table_line><unicode>150</unicode><infinity/> NaN NaN NaN NaN NaN NaN NaN </table_line>
+<table_line>NaN NaN NaN NaN NaN NaN NaN NaN </table_line>
+</list_item><list_item> Decimal remainder: <code_example><![CDATA[
+decimal operator %(decimal x, decimal y);  
+]]></code_example>If the value of the right operand is zero, a System.DivideByZeroException is thrown. If the resulting value is too large to represent in the <keyword>decimal</keyword> format, a System.OverflowException is thrown. If the result value is too small to represent in the <keyword>decimal</keyword> format, the result is zero. The scale of the result, before any rounding, is the same as the scale of y, and the sign of the result, if non-zero, is the same as that of x. Decimal remainder is equivalent to using the remainder operator of type System.Decimal. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.7.4.xml b/mcs/docs/ecma334/14.7.4.xml
new file mode 100644 (file)
index 0000000..15e9f56
--- /dev/null
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<clause number="14.7.4" title="Addition operator">
+  <paragraph>For an operation of the form x + y, binary operator overload resolution (<hyperlink>14.2.4</hyperlink>) is applied to select a specific operator implementation. The operands are converted to the parameter types of the selected operator, and the type of the result is the return type of the operator. </paragraph>
+  <paragraph>The predefined addition operators are listed below. For numeric and enumeration types, the predefined addition operators compute the sum of the two operands. When one or both operands are of type string, the predefined addition operators concatenate the string representation of the operands. <list><list_item> Integer addition: <code_example><![CDATA[
+int operator +(int x, int y);  
+uint operator +(uint x, uint y);  
+long operator +(long x, long y);  
+ulong operator +(ulong x, ulong y);  
+]]></code_example>In a checked context, if the sum is outside the range of the result type, a System.OverflowException is thrown. In an unchecked context, overflows are not reported and any significant high-order bits outside the range of the result type are discarded. </list_item><list_item> Floating-point addition: <code_example><![CDATA[
+float operator +(float x, float y);  
+double operator +(double x, double y);  
+]]></code_example>The sum is computed according to the rules of IEEE 754 arithmetic. The following table lists the results of all possible combinations of nonzero finite values, zeros, infinities, and NaN's. In the table, x and y are nonzero finite values, and z is the result of x + y. If x and y have the same magnitude but opposite signs, z is positive zero. If x + y is too large to represent in the destination type, z is an infinity with the same sign as x + y. If x + y is too small to represent in the destination type, z is a zero with the same sign as x + y. <table_line>y +0 <unicode>150</unicode>0 +<infinity/> <unicode>150</unicode><infinity/> NaN </table_line>
+<table_line>x z x x +<infinity/> <unicode>150</unicode><infinity/> NaN </table_line>
+<table_line>+0 y +0 +0 +<infinity/> <unicode>150</unicode><infinity/> NaN </table_line>
+<table_line><unicode>150</unicode>0 y +0 <unicode>150</unicode>0 +<infinity/><unicode>150</unicode><infinity/> NaN </table_line>
+<table_line>+<infinity/> +<infinity/> +<infinity/> +<infinity/> +<infinity/> NaN NaN </table_line>
+<table_line><unicode>150</unicode><infinity/><unicode>150</unicode><infinity/><unicode>150</unicode><infinity/><unicode>150</unicode><infinity/> NaN <unicode>150</unicode><infinity/> NaN </table_line>
+<table_line>NaN NaN NaN NaN NaN NaN NaN </table_line>
+</list_item><list_item> Decimal addition: <code_example><![CDATA[
+decimal operator +(decimal x, decimal y);  
+]]></code_example>If the resulting value is too large to represent in the <keyword>decimal</keyword> format, a System.OverflowException is thrown. The scale of the result, before any rounding, is the larger of the scales of the two operands. Decimal addition is equivalent to using the addition operator of type System.Decimal. </list_item><list_item> Enumeration addition. Every enumeration type implicitly provides the following predefined operators, where E is the enum type, and U is the underlying type of E: <code_example><![CDATA[
+E operator +(E x, U y);  
+E operator +(U x, E y);  
+]]></code_example>The operators are evaluated exactly as (E)((U)x + (U)y). </list_item><list_item> String concatenation: <code_example><![CDATA[
+string operator +(string x, string y);  
+string operator +(string x, object y);  
+string operator +(object x, string y);  
+]]></code_example>The binary + operator performs string concatenation when one or both operands are of type string. If an operand of string concatenation is null, an empty string is substituted. Otherwise, any non-string argument is converted to its string representation by invoking the virtual ToString method inherited from type object. If ToString returns null, an empty string is substituted. <example>[Example: <code_example><![CDATA[
+using System;  
+class Test  
+{  
+   static void Main() {  
+      string s = null;  
+      Console.WriteLine("s = >" + s + "<"); // displays s = ><  
+      int i = 1;  
+      Console.WriteLine("i = " + i);      // displays i = 1  
+      float f = 1.2300E+15F;  
+      Console.WriteLine("f = " + f);      // displays f = 1.23E+15  
+      decimal d = 2.900m;  
+      Console.WriteLine("d = " + d);      // displays d = 2.900  
+   }  
+}  
+]]></code_example>end example]</example> The result of the string concatenation operator is a string that consists of the characters of the left operand followed by the characters of the right operand. The string concatenation operator never returns a null value. A System.OutOfMemoryException may be thrown if there is not enough memory available to allocate the resulting string. </list_item><list_item> Delegate combination. Every delegate type implicitly provides the following predefined operator, where D is the delegate type: <code_example><![CDATA[
+D operator +(D x, D y);  
+]]></code_example>The binary + operator performs delegate combination when both operands are of some delegate type D. (If the operands have different delegate types, a compile-time error occurs.) If the first operand is null, the result of the operation is the value of the second operand (even if that is also null). Otherwise, if the second operand is null, then the result of the operation is the value of the first operand. Otherwise, the result of the operation is a new delegate instance that, when invoked, invokes the first operand and then invokes the second operand. <note>[Note: For examples of delegate combination, see <hyperlink>14.7.5</hyperlink> and <hyperlink>22.3</hyperlink>. Since System.Delegate is not a delegate type, operator + is not defined for it. end note]</note> </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.7.5.xml b/mcs/docs/ecma334/14.7.5.xml
new file mode 100644 (file)
index 0000000..c2278f1
--- /dev/null
@@ -0,0 +1,53 @@
+<?xml version="1.0"?>
+<clause number="14.7.5" title="Subtraction operator">
+  <paragraph>For an operation of the form x  -y, binary operator overload resolution (<hyperlink>14.2.4</hyperlink>) is applied to select a specific operator implementation. The operands are converted to the parameter types of the selected operator, and the type of the result is the return type of the operator. </paragraph>
+  <paragraph>The predefined subtraction operators are listed below. The operators all subtract y from x. <list><list_item> Integer subtraction: <code_example><![CDATA[
+int operator -(int x, int y);  
+uint operator -(uint x, uint y);  
+long operator -(long x, long y);  
+ulong operator -(ulong x, ulong y);  
+]]></code_example>In a checked context, if the difference is outside the range of the result type, a System.OverflowException is thrown. In an unchecked context, overflows are not reported and any significant high-order bits outside the range of the result type are discarded. </list_item><list_item> Floating-point subtraction: <code_example><![CDATA[
+float operator -(float x, float y);  
+double operator -(double x, double y);  
+]]></code_example>The difference is computed according to the rules of IEEE 754 arithmetic. The following table lists the results of all possible combinations of nonzero finite values, zeros, infinities, and NaNs. In the table, x and y are nonzero finite values, and z is the result of x  -y. If x and y are equal, z is positive zero. If x  -y is too large to represent in the destination type, z is an infinity with the same sign as x  -y. If x  -y is too small to represent in the destination type, z is a zero with the same sign as x  -y. <table_line>y +0 <unicode>150</unicode>0 +<infinity/> <unicode>150</unicode><infinity/> NaN </table_line>
+<table_line>x z x x <unicode>150</unicode><infinity/> +<infinity/> NaN </table_line>
+<table_line>+0 <unicode>150</unicode>y +0 +0 <unicode>150</unicode><infinity/> +<infinity/> NaN </table_line>
+<table_line><unicode>150</unicode>0 <unicode>150</unicode>y <unicode>150</unicode>0 +0 <unicode>150</unicode><infinity/> +<infinity/> NaN </table_line>
+<table_line>+<infinity/> +<infinity/> +<infinity/> +<infinity/> NaN +<infinity/> NaN </table_line>
+<table_line><unicode>150</unicode><infinity/><unicode>150</unicode><infinity/><unicode>150</unicode><infinity/><unicode>150</unicode><infinity/><unicode>150</unicode><infinity/> NaN NaN </table_line>
+<table_line>NaN NaN NaN NaN NaN NaN NaN </table_line>
+</list_item><list_item> Decimal subtraction: <code_example><![CDATA[
+decimal operator {UNICODE_150}(decimal x, decimal y);  
+]]></code_example>If the resulting value is too large to represent in the <keyword>decimal</keyword> format, a System.OverflowException is thrown. The scale of the result, before any rounding, is the larger of the scales of the two operands. Decimal subtraction is equivalent to using the subtraction operator of type System.Decimal. </list_item><list_item> Enumeration subtraction. Every enumeration type implicitly provides the following predefined operator, where E is the enum type, and U is the underlying type of E: <code_example><![CDATA[
+U operator -(E x, E y);  
+]]></code_example>This operator is evaluated exactly as (U)((U)x  -(U)y). In other words, the operator computes the difference between the ordinal values of x and y, and the type of the result is the underlying type of the enumeration. <code_example><![CDATA[
+E operator -(E x, U y);  
+]]></code_example>This operator is evaluated exactly as (E)((U)x  -y). In other words, the operator subtracts a value from the underlying type of the enumeration, yielding a value of the enumeration. </list_item><list_item> Delegate removal. Every delegate type implicitly provides the following predefined operator, where D is the delegate type: <code_example><![CDATA[
+D operator -(D x, D y);  
+]]></code_example>The binary  -operator performs delegate removal when both operands are of some delegate type D. (If the operands have different delegate types, a compile-time error occurs.) If the first operand is null, the result of the operation is null. Otherwise, if the second operand is null, then the result of the operation is the value of the first operand. Otherwise, both operands represent invocation lists (<hyperlink>22.1</hyperlink>) having one or more entries, and the result is a new invocation list consisting of the first operand's list with the second operand's entries removed from it, provided the second operand's list is a proper contiguous subset of the first's. (For determining subset equality, corresponding entries are compared as for the delegate equality operator (<hyperlink>14.9.8</hyperlink>).) Otherwise, the result is the value of the left operand. Neither of the operands' lists is changed in the process. If the second operand's list matches multiple subsets of contiguous entries in the first operand's list, the right-most matching subset of contiguous entries is removed. If removal results in an empty list, the result is null. <example>[Example: For example: <code_example><![CDATA[
+using System;  
+delegate void D(int x);  
+class Test  
+{  
+   public static void M1(int i) { /* ... */ }  
+   public static void M2(int i) { /* ... */ }  
+}  
+class Demo  
+{  
+   static void Main() {   
+      D cd1 = new D(Test.M1);  
+      D cd2 = new D(Test.M2);  
+      D cd3 = cd1 + cd2 + cd2 + cd1;  // M1 + M2 + M2 + M1  
+      cd3 -= cd1;        // => M1 + M2 + M2  
+      cd3 = cd1 + cd2 + cd2 + cd1;    // M1 + M2 + M2 + M1  
+      cd3 -= cd1 + cd2;      // => M2 + M1  
+      cd3 = cd1 + cd2 + cd2 + cd1;    // M1 + M2 + M2 + M1  
+      cd3 -= cd2 + cd2;      // => M1 + M1  
+      cd3 = cd1 + cd2 + cd2 + cd1;    // M1 + M2 + M2 + M1  
+      cd3 -= cd2 + cd1;      // => M1 + M2  
+      cd3 = cd1 + cd2 + cd2 + cd1;    // M1 + M2 + M2 + M1  
+      cd3 -= cd1 + cd1;      // => M1 + M2 + M2 + M1  
+   }  
+}  
+]]></code_example>end example]</example> </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.7.xml b/mcs/docs/ecma334/14.7.xml
new file mode 100644 (file)
index 0000000..ed961d6
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="14.7" title="Arithmetic operators">
+  <paragraph>The *, /, %, +, and  -operators are called the arithmetic operators. <grammar_production><name><non_terminal where="14.7">multiplicative-expression</non_terminal></name> : <rhs><non_terminal where="14.6">unary-expression</non_terminal></rhs><rhs><non_terminal where="14.7">multiplicative-expression</non_terminal><terminal>*</terminal><non_terminal where="14.6">unary-expression</non_terminal></rhs><rhs><non_terminal where="14.7">multiplicative-expression</non_terminal><terminal>/</terminal><non_terminal where="14.6">unary-expression</non_terminal></rhs><rhs><non_terminal where="14.7">multiplicative-expression</non_terminal><terminal>%</terminal><non_terminal where="14.6">unary-expression</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="14.7">additive-expression</non_terminal></name> : <rhs><non_terminal where="14.7">multiplicative-expression</non_terminal></rhs><rhs><non_terminal where="14.7">additive-expression</non_terminal><terminal>+</terminal><non_terminal where="14.7">multiplicative-expression</non_terminal></rhs><rhs><non_terminal where="14.7">additive-expression</non_terminal><terminal>-</terminal><non_terminal where="14.7">multiplicative-expression</non_terminal></rhs></grammar_production></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.8.xml b/mcs/docs/ecma334/14.8.xml
new file mode 100644 (file)
index 0000000..9e9315e
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<clause number="14.8" title="Shift operators">
+  <paragraph>The &lt;&lt; and &gt;&gt; operators are used to perform bit shifting operations. <grammar_production><name><non_terminal where="14.8">shift-expression</non_terminal></name> : <rhs><non_terminal where="14.7">additive-expression</non_terminal></rhs><rhs><non_terminal where="14.8">shift-expression</non_terminal><terminal>&lt;&lt;</terminal><non_terminal where="14.7">additive-expression</non_terminal></rhs><rhs><non_terminal where="14.8">shift-expression</non_terminal><terminal>&gt;&gt;</terminal><non_terminal where="14.7">additive-expression</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>For an operation of the form x &lt;&lt; count or x &gt;&gt; count, binary operator overload resolution (<hyperlink>14.2.4</hyperlink>) is applied to select a specific operator implementation. The operands are converted to the parameter types of the selected operator, and the type of the result is the return type of the operator. </paragraph>
+  <paragraph>When declaring an overloaded shift operator, the type of the first operand must always be the class or struct containing the operator declaration, and the type of the second operand must always be <keyword>int</keyword>. </paragraph>
+  <paragraph>The predefined shift operators are listed below. <list><list_item> Shift left: <code_example><![CDATA[
+int operator <<(int x, int count);  
+uint operator <<(uint x, int count);  
+long operator <<(long x, int count);  
+ulong operator <<(ulong x, int count);  
+]]></code_example>The &lt;&lt; operator shifts x left by a number of bits computed as described below. The high-order bits outside the range of the result type of x are discarded, the remaining bits are shifted left, and the low-order empty bit positions are set to zero. </list_item><list_item> Shift right: <code_example><![CDATA[
+int operator >>(int x, int count);  
+uint operator >>(uint x, int count);  
+long operator >>(long x, int count);  
+ulong operator >>(ulong x, int count);  
+]]></code_example>The &gt;&gt; operator shifts x right by a number of bits computed as described below. When x is of type <keyword>int</keyword> or <keyword>long</keyword>, the low-order bits of x are discarded, the remaining bits are shifted right, and the high-order empty bit positions are set to zero if x is non-negative and set to one if x is negative. When x is of type <keyword>uint</keyword> or <keyword>ulong</keyword>, the low-order bits of x are discarded, the remaining bits are shifted right, and the high-order empty bit positions are set to zero. </list_item></list></paragraph>
+  <paragraph>For the predefined operators, the number of bits to shift is computed as follows: <list><list_item> When the type of x is <keyword>int</keyword> or <keyword>uint</keyword>, the shift count is given by the low-order five bits of count. In other words, the shift count is computed from count &amp; 0x1F. </list_item><list_item> When the type of x is <keyword>long</keyword> or <keyword>ulong</keyword>, the shift count is given by the low-order six bits of count. In other words, the shift count is computed from count &amp; 0x3F. </list_item></list></paragraph>
+  <paragraph>If the resulting shift count is zero, the shift operators simply return the value of x. </paragraph>
+  <paragraph>Shift operations never cause overflows and produce the same results in checked and unchecked contexts. </paragraph>
+  <paragraph>When the left operand of the &gt;&gt; operator is of a signed integral type, the operator performs an arithmetic shift right wherein the value of the most significant bit (the sign bit) of the operand is propagated to the high-order empty bit positions. When the left operand of the &gt;&gt; operator is of an unsigned integral type, the operator performs a logical shift right wherein high-order empty bit positions are always set to zero. To perform the opposite operation of that inferred from the operand type, explicit casts can be used. For example, if x is a variable of type <keyword>int</keyword>, the operation unchecked((<keyword>int</keyword>)((<keyword>uint</keyword>)x &gt;&gt; y)) performs a logical shift right of x. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.9.1.xml b/mcs/docs/ecma334/14.9.1.xml
new file mode 100644 (file)
index 0000000..5b19888
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0"?>
+<clause number="14.9.1" title="Integer comparison operators">
+  <paragraph>The predefined integer comparison operators are: <code_example><![CDATA[
+bool operator ==(int x, int y);  
+bool operator ==(uint x, uint y);  
+bool operator ==(long x, long y);  
+bool operator ==(ulong x, ulong y);  
+bool operator !=(int x, int y);  
+bool operator !=(uint x, uint y);  
+bool operator !=(long x, long y);  
+bool operator !=(ulong x, ulong y);  
+bool operator <(int x, int y);  
+bool operator <(uint x, uint y);  
+bool operator <(long x, long y);  
+bool operator <(ulong x, ulong y);  
+bool operator >(int x, int y);  
+bool operator >(uint x, uint y);  
+bool operator >(long x, long y);  
+bool operator >(ulong x, ulong y);  
+bool operator <=(int x, int y);  
+bool operator <=(uint x, uint y);  
+bool operator <=(long x, long y);  
+bool operator <=(ulong x, ulong y);  
+bool operator >=(int x, int y);  
+bool operator >=(uint x, uint y);  
+bool operator >=(long x, long y);  
+bool operator >=(ulong x, ulong y);  
+]]></code_example></paragraph>
+  <paragraph>Each of these operators compares the numeric values of the two integer operands and returns a <keyword>bool</keyword> value that indicates whether the particular relation is true or false. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.9.10.xml b/mcs/docs/ecma334/14.9.10.xml
new file mode 100644 (file)
index 0000000..d385312
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="14.9.10" title="The as operator">
+  <paragraph>The as operator is used to explicitly convert a value to a given reference type using a reference conversion or a boxing conversion. Unlike a cast expression (<hyperlink>14.6.6</hyperlink>), the as operator never throws an exception. Instead, if the indicated conversion is not possible, the resulting value is null. </paragraph>
+  <paragraph>In an operation of the form e as T, e must be an expression and T must be a reference type. The type of the result is T, and the result is always classified as a value. The operation is evaluated as follows: <list><list_item> If the compile-time type of e is the same as T, the result is simply the value of e. </list_item><list_item> Otherwise, if an implicit reference conversion (<hyperlink>13.1.4</hyperlink>) or boxing conversion (<hyperlink>13.1.5</hyperlink>) exists from the compile-time type of e to T, this conversion is performed and becomes the result of the operation. </list_item><list_item> Otherwise, if an explicit reference conversion (<hyperlink>13.2.3</hyperlink>) exists from the compile-time type of e to T, a dynamic type check is performed: </list_item><list><list_item> If the value of e is null, the result is the value null with the compile-time type T. </list_item><list_item> Otherwise, let R be the run-time type of the instance referenced by e. If R and T are the same type, if R is a reference type and an implicit reference conversion from R to T exists, or if R is a value type and T is an interface type that is implemented by R, the result is the reference given by e with the compile-time type T. </list_item><list_item> Otherwise, the result is the value null with the compile-time type T. </list_item></list><list_item> Otherwise, the indicated conversion is never possible, and a compile-time error occurs. </list_item></list></paragraph>
+  <paragraph>Note that the as operator only performs reference conversions and boxing conversions. Other conversions, such as user defined conversions, are not possible with the as operator and should instead be performed using cast expressions. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.9.2.xml b/mcs/docs/ecma334/14.9.2.xml
new file mode 100644 (file)
index 0000000..37b84b8
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<clause number="14.9.2" title="Floating-point comparison operators">
+  <paragraph>The predefined floating-point comparison operators are: <code_example><![CDATA[
+bool operator ==(float x, float y);  
+bool operator ==(double x, double y);  
+bool operator !=(float x, float y);  
+bool operator !=(double x, double y);  
+bool operator <(float x, float y);  
+bool operator <(double x, double y);  
+bool operator >(float x, float y);  
+bool operator >(double x, double y);  
+bool operator <=(float x, float y);  
+bool operator <=(double x, double y);  
+bool operator >=(float x, float y);  
+bool operator >=(double x, double y);  
+]]></code_example></paragraph>
+  <paragraph>The operators compare the operands according to the rules of the IEEE 754 standard: <list><list_item> If either operand is NaN, the result is false for all operators except !=, for which the result is true. For any two operands, x != y always produces the same result as !(x == y). However, when one or both operands are NaN, the &lt;, &gt;, &lt;=, and &gt;= operators do not produce the same results as the logical negation of the opposite operator. <example>[Example: For example, if either of x and y is NaN, then x &lt; y is false, but !(x &gt;= y) is true. end example]</example> </list_item><list_item> When neither operand is NaN, the operators compare the values of the two floating-point operands with respect to the ordering <code_example><![CDATA[
+{UNICODE_150}{UNICODE_8734} < {UNICODE_150}max < {UNICODE_133} < {UNICODE_150}min < {UNICODE_150}0.0 == +0.0 < +min < {UNICODE_133} < +max < +{UNICODE_8734}  
+]]></code_example>where min and max are the smallest and largest positive finite values that can be represented in the given floating-point format. Notable effects of this ordering are: </list_item><list><list_item> Negative and positive zeros are considered equal. </list_item><list_item> A negative infinity is considered less than all other values, but equal to another negative infinity. </list_item><list_item> A positive infinity is considered greater than all other values, but equal to another positive infinity. </list_item></list></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.9.3.xml b/mcs/docs/ecma334/14.9.3.xml
new file mode 100644 (file)
index 0000000..aef4901
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<clause number="14.9.3" title="Decimal comparison operators">
+  <paragraph>The predefined <keyword>decimal</keyword> comparison operators are: <code_example><![CDATA[
+bool operator ==(decimal x, decimal y);  
+bool operator !=(decimal x, decimal y);  
+bool operator <(decimal x, decimal y);  
+bool operator >(decimal x, decimal y);  
+bool operator <=(decimal x, decimal y);  
+bool operator >=(decimal x, decimal y);  
+]]></code_example></paragraph>
+  <paragraph>Each of these operators compares the numeric values of the two <keyword>decimal</keyword> operands and returns a <keyword>bool</keyword> value that indicates whether the particular relation is true or false. Each <keyword>decimal</keyword> comparison is equivalent to using the corresponding relational or equality operator of type System.Decimal. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.9.4.xml b/mcs/docs/ecma334/14.9.4.xml
new file mode 100644 (file)
index 0000000..144a6c4
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<clause number="14.9.4" title="Boolean equality operators">
+  <paragraph>The predefined boolean equality operators are: <code_example><![CDATA[
+bool operator ==(bool x, bool y);  
+bool operator !=(bool x, bool y);  
+]]></code_example></paragraph>
+  <paragraph>The result of == is true if both x and y are true or if both x and y are false. Otherwise, the result is false. </paragraph>
+  <paragraph>The result of != is false if both x and y are true or if both x and y are false. Otherwise, the result is true. When the operands are of type <keyword>bool</keyword>, the != operator produces the same result as the ^ operator. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.9.5.xml b/mcs/docs/ecma334/14.9.5.xml
new file mode 100644 (file)
index 0000000..ad1d327
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<clause number="14.9.5" title="Enumeration comparison operators">
+  <paragraph>Every enumeration type implicitly provides the following predefined comparison operators: <code_example><![CDATA[
+bool operator ==(E x, E y);  
+bool operator !=(E x, E y);  
+bool operator <(E x, E y);  
+bool operator >(E x, E y);  
+bool operator <=(E x, E y);  
+bool operator >=(E x, E y);  
+]]></code_example></paragraph>
+  <paragraph>The result of evaluating x op y, where x and y are expressions of an enumeration type E with an underlying type U, and op is one of the comparison operators, is exactly the same as evaluating ((U)x) op ((U)y). In other words, the enumeration type comparison operators simply compare the underlying integral values of the two operands. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.9.6.xml b/mcs/docs/ecma334/14.9.6.xml
new file mode 100644 (file)
index 0000000..6df63d0
--- /dev/null
@@ -0,0 +1,44 @@
+<?xml version="1.0"?>
+<clause number="14.9.6" title="Reference type equality operators">
+  <paragraph>The predefined reference type equality operators are: <code_example><![CDATA[
+bool operator ==(object x, object y);  
+bool operator !=(object x, object y);  
+]]></code_example></paragraph>
+  <paragraph>The operators return the result of comparing the two references for equality or non-equality. </paragraph>
+  <paragraph>Since the predefined reference type equality operators accept operands of type object, they apply to all types that do not declare applicable operator == and operator != members. Conversely, any applicable user-defined equality operators effectively hide the predefined reference type equality operators. </paragraph>
+  <paragraph>The predefined reference type equality operators require the operands to be <non_terminal where="11.2">reference-type</non_terminal> values or the value null; furthermore, they require that a standard implicit conversion (<hyperlink>13.3.1</hyperlink>) exists from the type of either operand to the type of the other operand. Unless both of these conditions are true, a compile-time error occurs. <note>[Note: Notable implications of these rules are: <list><list_item> It is a compile-time error to use the predefined reference type equality operators to compare two references that are known to be different at compile-time. For example, if the compile-time types of the operands are two class types A and B, and if neither A nor B derives from the other, then it would be impossible for the two operands to reference the same object. Thus, the operation is considered a  compile-time error. </list_item><list_item> The predefined reference type equality operators do not permit value type operands to be compared. Therefore, unless a struct type declares its own equality operators, it is not possible to compare values of that struct type. </list_item><list_item> The predefined reference type equality operators never cause boxing operations to occur for their operands. It would be meaningless to perform such boxing operations, since references to the newly allocated boxed instances would necessarily differ from all other references. end note]</list_item></list></note> </paragraph>
+  <paragraph>For an operation of the form x == y or x != y, if any applicable operator == or operator != exists, the operator overload resolution (<hyperlink>14.2.4</hyperlink>) rules will select that operator instead of the predefined reference type equality operator. However, it is always possible to select the predefined reference type equality operator by explicitly casting one or both of the operands to type object. <example>[Example: The example <code_example><![CDATA[
+using System;  
+class Test  
+{  
+   static void Main() {  
+      string s = "Test";  
+      string t = string.Copy(s);  
+      Console.WriteLine(s == t);  
+      Console.WriteLine((object)s == t);  
+      Console.WriteLine(s == (object)t);  
+      Console.WriteLine((object)s == (object)t);  
+   }  
+}  
+]]></code_example>produces the output <code_example><![CDATA[
+True  
+False  
+False  
+False  
+]]></code_example></example></paragraph>
+  <paragraph>
+    <example>The s and t variables refer to two distinct string instances containing the same characters. The first comparison outputs True because the predefined string equality operator (<hyperlink>14.9.7</hyperlink>) is selected when both operands are of type string. The remaining comparisons all output False because the predefined reference type equality operator is selected when one or both of the operands are of type object. </example>
+  </paragraph>
+  <paragraph>
+    <example>Note that the above technique is not meaningful for value types. The example <code_example><![CDATA[
+class Test  
+{  
+   static void Main() {  
+      int i = 123;  
+      int j = 123;  
+      System.Console.WriteLine((object)i == (object)j);  
+   }  
+}  
+]]></code_example>outputs False because the casts create references to two separate instances of boxed <keyword>int</keyword> values. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.9.7.xml b/mcs/docs/ecma334/14.9.7.xml
new file mode 100644 (file)
index 0000000..6bfea34
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<clause number="14.9.7" title="String equality operators">
+  <paragraph>The predefined string equality operators are: : <code_example><![CDATA[
+bool operator ==(string x, string y);  
+bool operator !=(string x, string y);  
+]]></code_example></paragraph>
+  <paragraph>Two string values are considered equal when one of the following is true: <list><list_item> Both values are null. </list_item><list_item> Both values are non-null references to string instances that have identical lengths and identical characters in each character position. </list_item></list></paragraph>
+  <paragraph>The string equality operators compare string values rather than string references. When two separate string instances contain the exact same sequence of characters, the values of the strings are equal, but the references are different. <note>[Note: As described in <hyperlink>14.9.6</hyperlink>, the reference type equality operators can be used to compare string references instead of string values. end note]</note> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.9.8.xml b/mcs/docs/ecma334/14.9.8.xml
new file mode 100644 (file)
index 0000000..88bd71f
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<clause number="14.9.8" title="Delegate equality operators">
+  <paragraph>Every delegate type implicitly provides the following predefined comparison operators: : <code_example><![CDATA[
+bool operator ==(System.Delegate x, System.Delegate y);  
+bool operator !=(System.Delegate x, System.Delegate y);  
+]]></code_example></paragraph>
+  <paragraph>Two delegate instances are considered equal as follows: <list><list_item> If either of the delegate instances is null, they are equal if and only if both are null. </list_item><list_item> If either of the delegate instances has an invocation list (<hyperlink>22.1</hyperlink>) containing one entry, they are equal if and only if the other also has an invocation list containing one entry, and either: </list_item><list><list_item> Both refer to the same static method, or </list_item><list_item> Both refer to the same non-static method on the same target object. </list_item></list><list_item> If either of the delegate instances has an invocation list containing two or more entries, those instances are equal if and only if their invocation lists are the same length, and each entry in one's invocation list is equal to the corresponding entry, in order, in the other's invocation list. </list_item></list></paragraph>
+  <paragraph>Note that delegates of different types can be considered equal by the above definition, as <keyword>long</keyword> as they have the same return type and parameter types. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.9.9.xml b/mcs/docs/ecma334/14.9.9.xml
new file mode 100644 (file)
index 0000000..dc2505e
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="14.9.9" title="The is operator">
+  <paragraph>The is operator is used to dynamically check if the run-time type of an object is compatible with a given type. The result of the operation e is T, where e is an expression and T is a type, is a boolean value indicating whether e can successfully be converted to type T by a reference conversion, a boxing conversion, or an unboxing conversion. The operation is evaluated as follows: <list><list_item> If the compile-time type of e is the same as T, or if an implicit reference conversion (<hyperlink>13.1.4</hyperlink>) or boxing conversion (<hyperlink>13.1.5</hyperlink>) exists from the compile-time type of e to T: </list_item><list><list_item> If e is of a reference type, the result of the operation is equivalent to evaluating e != null. </list_item><list_item> If e is of a value type, the result of the operation is true. </list_item></list><list_item> Otherwise, if an explicit reference conversion (<hyperlink>13.2.3</hyperlink>) or unboxing conversion (<hyperlink>13.2.4</hyperlink>) exists from the compile-time type of e to T, a dynamic type check is performed: </list_item><list><list_item> If the value of e is null, the result is false. </list_item><list_item> Otherwise, let R be the run-time type of the instance referenced by e. If R and T are the same type, if R is a reference type and an implicit reference conversion from R to T exists, or if R is a value type and T is an interface type that is implemented by R, the result is true. </list_item><list_item> Otherwise, the result is false. </list_item></list><list_item> Otherwise, no reference or boxing conversion of e to type T is possible, and the result of the operation is false. </list_item></list></paragraph>
+  <paragraph>Note that the is operator only considers reference conversions, boxing conversions, and unboxing conversions. Other conversions, such as user defined conversions, are not considered by the is operator. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.9.xml b/mcs/docs/ecma334/14.9.xml
new file mode 100644 (file)
index 0000000..32f6e56
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<clause number="14.9" title="Relational and type-testing operators">
+  <paragraph>The ==, !=, &lt;, &gt;, &lt;=, &gt;=, is and as operators are called the relational and type-testing operators. <grammar_production><name><non_terminal where="14.9">relational-expression</non_terminal></name> : <rhs><non_terminal where="14.8">shift-expression</non_terminal></rhs><rhs><non_terminal where="14.9">relational-expression</non_terminal><terminal>&lt;</terminal><non_terminal where="14.8">shift-expression</non_terminal></rhs><rhs><non_terminal where="14.9">relational-expression</non_terminal><terminal>&gt;</terminal><non_terminal where="14.8">shift-expression</non_terminal></rhs><rhs><non_terminal where="14.9">relational-expression</non_terminal><terminal>&lt;=</terminal><non_terminal where="14.8">shift-expression</non_terminal></rhs><rhs><non_terminal where="14.9">relational-expression</non_terminal><terminal>&gt;=</terminal><non_terminal where="14.8">shift-expression</non_terminal></rhs><rhs><non_terminal where="14.9">relational-expression</non_terminal><keyword>is</keyword><non_terminal where="11">type</non_terminal></rhs><rhs><non_terminal where="14.9">relational-expression</non_terminal><keyword>as</keyword><non_terminal where="11">type</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="14.9">equality-expression</non_terminal></name> : <rhs><non_terminal where="14.9">relational-expression</non_terminal></rhs><rhs><non_terminal where="14.9">equality-expression</non_terminal><terminal>==</terminal><non_terminal where="14.9">relational-expression</non_terminal></rhs><rhs><non_terminal where="14.9">equality-expression</non_terminal><terminal>!=</terminal><non_terminal where="14.9">relational-expression</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>The is operator is described in <hyperlink>14.9.9</hyperlink> and the as operator is described in <hyperlink>14.9.10</hyperlink>. </paragraph>
+  <paragraph>The ==, !=, &lt;, &gt;, &lt;= and &gt;= operators are comparison operators. For an operation of the form x op y, where op is a comparison operator, overload resolution (<hyperlink>14.2.4</hyperlink>) is applied to select a specific operator implementation. The operands are converted to the parameter types of the selected operator, and the type of the result is the return type of the operator. </paragraph>
+  <paragraph>The predefined comparison operators are described in the following sections. All predefined comparison operators return a result of type <keyword>bool</keyword>, as described in the following table. <table_line>Operation Result </table_line>
+<table_line>x == y true if x is equal to y, false otherwise </table_line>
+<table_line>x != y true if x is not equal to y, false otherwise </table_line>
+<table_line>x &lt; y true if x is less than y, false otherwise </table_line>
+<table_line>x &gt; y true if x is greater than y, false otherwise </table_line>
+<table_line>x &lt;= y true if x is less than or equal to y, false otherwise </table_line>
+<table_line>x &gt;= y true if x is greater than or equal to y, false otherwise </table_line>
+</paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/14.xml b/mcs/docs/ecma334/14.xml
new file mode 100644 (file)
index 0000000..fbab95d
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="14" title="Expressions">
+  <paragraph>An expression is a sequence of operators and operands. This chapter defines the syntax, order of evaluation of operands and operators, and meaning of expressions. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/15.1.xml b/mcs/docs/ecma334/15.1.xml
new file mode 100644 (file)
index 0000000..7e4992d
--- /dev/null
@@ -0,0 +1,43 @@
+<?xml version="1.0"?>
+<clause number="15.1" title="End points and reachability">
+  <paragraph>Every statement has an end point. In intuitive terms, the end point of a statement is the location that immediately follows the statement. The execution rules for composite statements (statements that contain embedded statements) specify the action that is taken when control reaches the end point of an embedded statement. For example, when control reaches the end point of a statement in a block, control is transferred to the next statement in the block. </paragraph>
+  <paragraph>If a statement can possibly be reached by execution, the statement is said to be reachable. Conversely, if there is no possibility that a statement will be executed, the statement is said to be unreachable. </paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+void F() {  
+   Console.WriteLine("reachable");  
+   goto Label;  
+   Console.WriteLine("unreachable");  
+   Label:  
+   Console.WriteLine("reachable");  
+}  
+]]></code_example>the second invocation of Console.WriteLine is unreachable because there is no possibility that the statement will be executed. end example]</example>
+  </paragraph>
+  <paragraph>A warning is reported if the compiler determines that a statement is unreachable. It is specifically not an error for a statement to be unreachable. </paragraph>
+  <paragraph>
+    <note>[Note: To determine whether a particular statement or end point is reachable, the compiler performs flow analysis according to the reachability rules defined for each statement. The flow analysis takes into account the values of constant expressions (<hyperlink>14.15</hyperlink>) that control the behavior of statements, but the possible values of non-constant expressions are not considered. In other words, for purposes of control flow analysis, a  non-constant expression of a given type is considered to have any possible value of that type. </note>
+  </paragraph>
+  <paragraph>
+    <note>In the example <code_example><![CDATA[
+void F() {  
+   const int i = 1;  
+   if (i == 2) Console.WriteLine("unreachable");  
+}  
+]]></code_example>the boolean expression of the if statement is a constant expression because both operands of the == operator are constants. As the constant expression is evaluated at compile-time, producing the value false, the Console.WriteLine invocation is considered unreachable. However, if i is changed to be a local variable <code_example><![CDATA[
+void F() {  
+   int i = 1;  
+   if (i == 2) Console.WriteLine("reachable");  
+}  
+]]></code_example>the Console.WriteLine invocation is considered reachable, even though, in reality, it will never be executed. end note]</note>
+  </paragraph>
+  <paragraph>The block of a function member is always considered reachable. By successively evaluating the reachability rules of each statement in a block, the reachability of any given statement can be determined. </paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+void F(int x) {  
+   Console.WriteLine("start");  
+   if (x < 0) Console.WriteLine("negative");  
+}  
+]]></code_example>the reachability of the second Console.WriteLine is determined as follows: <list><list_item> The first Console.WriteLine expression statement is reachable because the block of the F method is reachable (<hyperlink>15.2</hyperlink>). </list_item><list_item> The end point of the first Console.WriteLine expression statement is reachable15.2 because that statement is reachable (<hyperlink>15.6</hyperlink> and <hyperlink>15.2</hyperlink>). </list_item><list_item> The if statement is reachable because the end point of the first Console.WriteLine expression statement is reachable (<hyperlink>15.6</hyperlink> and <hyperlink>15.2</hyperlink>). </list_item><list_item> The second Console.WriteLine expression statement is reachable because the boolean expression of the if statement does not have the constant value false. end example]</list_item></list></example>
+  </paragraph>
+  <paragraph>There are two situations in which it is a compile-time error for the end point of a statement to be reachable: <list><list_item> Because the switch statement does not permit a switch section to &quot;fall through&quot; to the next switch section, it is a compile-time error for the end point of the statement list of a switch section to be reachable. If this error occurs, it is typically an indication that a break statement is missing. </list_item><list_item> It is a compile-time error for the end point of the block of a function member that computes a value to be reachable. If this error occurs, it typically is an indication that a return statement is missing. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/15.10.xml b/mcs/docs/ecma334/15.10.xml
new file mode 100644 (file)
index 0000000..aeacf32
--- /dev/null
@@ -0,0 +1,62 @@
+<?xml version="1.0"?>
+<clause number="15.10" title="The try statement">
+  <paragraph>The try statement provides a mechanism for catching exceptions that occur during execution of a block. </paragraph>
+  <paragraph>Furthermore, the try statement provides the ability to specify a block of code that is always executed when control leaves the try statement. <grammar_production><name><non_terminal where="15.10">try-statement</non_terminal></name> : <rhs><keyword>try</keyword><non_terminal where="15.2">block</non_terminal><non_terminal where="15.10">catch-clauses</non_terminal></rhs><rhs><keyword>try</keyword><non_terminal where="15.2">block</non_terminal><non_terminal where="15.10">finally-clause</non_terminal></rhs><rhs><keyword>try</keyword><non_terminal where="15.2">block</non_terminal><non_terminal where="15.10">catch-clauses</non_terminal><non_terminal where="15.10">finally-clause</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="15.10">catch-clauses</non_terminal></name> : <rhs><non_terminal where="15.10">specific-catch-clauses</non_terminal><non_terminal where="15.10">general-catch-clause</non_terminal><opt/></rhs><rhs><non_terminal where="15.10">specific-catch-clauses</non_terminal><opt/><non_terminal where="15.10">general-catch-clause</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="15.10">specific-catch-clause</non_terminal>s</name> : <rhs><non_terminal where="15.10">specific-catch-clause</non_terminal></rhs><rhs><non_terminal where="15.10">specific-catch-clauses</non_terminal><non_terminal where="15.10">specific-catch-clause</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="15.10">specific-catch-clause</non_terminal></name> : <rhs><keyword>catch</keyword><terminal>(</terminal><non_terminal where="11.2">class-type</non_terminal><non_terminal where="9.4.2">identifier</non_terminal><opt/><terminal>)</terminal><non_terminal where="15.2">block</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="15.10">general-catch-clause</non_terminal></name> : <rhs><keyword>catch</keyword><non_terminal where="15.2">block</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="15.10">finally-clause</non_terminal></name> : <rhs><keyword>finally</keyword><non_terminal where="15.2">block</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>There are three possible forms of try statements: <list><list_item> A try block followed by one or more catch blocks. </list_item><list_item> A try block followed by a finally block. </list_item><list_item> A try block followed by one or more catch blocks followed by a finally block. </list_item></list></paragraph>
+  <paragraph>When a catch clause specifies a <non_terminal where="11.2">class-type</non_terminal>, the type must be System.Exception or a type that derives from System.Exception. </paragraph>
+  <paragraph>When a catch clause specifies both a <non_terminal where="11.2">class-type</non_terminal> and an identifier, an exception variable of the given name and type is declared. The exception variable corresponds to a local variable with a scope that extends over the catch block. During execution of the catch block, the exception variable represents the exception currently being handled. For purposes of definite assignment checking, the exception variable is considered definitely assigned in its entire scope. </paragraph>
+  <paragraph>Unless a catch clause includes an exception variable name, it is impossible to access the exception object in the catch block. </paragraph>
+  <paragraph>A catch clause that specifies neither an exception type nor an exception variable name is called a general catch clause. A try statement can only have one general catch clause, and if one is present it must be the last catch clause. </paragraph>
+  <paragraph>
+    <note>[Note: Some environments, especially those supporting multiple languages, may support exceptions that are not representable as an object derived from System.Exception, although such an exception could never be generated by C# code. In such an environment, a general catch clause might be used to catch such an exception. Thus, a general catch clause is semantically different from one that specifies the type System.Exception, in that the former may also catch exceptions from other languages. end note]</note>
+  </paragraph>
+  <paragraph>In order to locate a handler for an exception, catch clauses are examined in lexical order. A compile-time error occurs if a catch clause specifies a type that is the same as, or is derived from, a type that was specified in an earlier catch clause for the same try. <note>[Note: Without this restriction, it would be possible to write unreachable catch clauses. end note]</note> </paragraph>
+  <paragraph>Within a catch block, a throw statement (<hyperlink>15.9.5</hyperlink>) with no expression can be used to re-throw the exception that was caught by the catch block. Assignments to an exception variable do not alter the exception that is re-thrown. </paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+using System;  
+class Test  
+{  
+   static void F() {  
+      try {  
+         G();  
+      }  
+      catch (Exception e) {  
+         Console.WriteLine("Exception in F: " + e.Message);  
+         e = new Exception("F");  
+         throw;        // re-throw  
+      }  
+   }  
+   static void G() {  
+      throw new Exception("G");  
+   }  
+   static void Main() {  
+      try {  
+         F();  
+      }  
+      catch (Exception e) {  
+         Console.WriteLine("Exception in Main: " + e.Message);  
+      }  
+   }  
+}  
+]]></code_example>the method F catches an exception, writes some diagnostic information to the console, alters the exception variable, and re-throws the exception. The exception that is re-thrown is the original exception, so the output produced is: <code_example><![CDATA[
+Exception in F: G  
+Exception in Main: G  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>If the first catch block had thrown e instead of rethrowing the current exception, the output produced would be as follows: <code_example><![CDATA[
+Exception in F: G  
+Exception in Main: F  
+]]></code_example>end example]</example>
+  </paragraph>
+  <paragraph>It is a compile-time error for a break, continue, or goto statement to transfer control out of a finally block. When a break, continue, or goto statement occurs in a finally block, the target of the statement must be within the same finally block, or otherwise a compile-time error occurs. </paragraph>
+  <paragraph>It is a compile-time error for a return statement to occur in a finally block. </paragraph>
+  <paragraph>A try statement is executed as follows: <list><list_item> Control is transferred to the try block. </list_item><list_item> When and if control reaches the end point of the try block: </list_item><list><list_item> If the try statement has a finally block, the finally block is executed. </list_item><list_item> Control is transferred to the end point of the try statement. </list_item></list><list_item> If an exception is propagated to the try statement during execution of the try block: </list_item><list><list_item> The catch clauses, if any, are examined in order of appearance to locate a suitable handler for the exception. The first catch clause that specifies the exception type or a base type of the exception type is considered a match. A general catch clause is considered a match for any exception type. If a matching catch clause is located: </list_item><list><list_item> If the matching catch clause declares an exception variable, the exception object is assigned to the exception variable. </list_item><list_item> Control is transferred to the matching catch block. </list_item><list_item> When and if control reaches the end point of the catch block: </list_item><list><list_item> If the try statement has a finally block, the finally block is executed. </list_item><list_item> Control is transferred to the end point of the try statement. </list_item></list><list_item> If an exception is propagated to the try statement during execution of the catch block: </list_item><list><list_item> If the try statement has a finally block, the finally block is executed. </list_item><list_item> The exception is propagated to the next enclosing try statement. </list_item></list></list><list_item> If the try statement has no catch clauses or if no catch clause matches the exception: </list_item><list><list_item> If the try statement has a finally block, the finally block is executed. </list_item><list_item> The exception is propagated to the next enclosing try statement. </list_item></list></list></list></paragraph>
+  <paragraph>The statements of a finally block are always executed when control leaves a try statement. This is true whether the control transfer occurs as a result of normal execution, as a result of executing a break, continue, goto, or return statement, or as a result of propagating an exception out of the try statement. </paragraph>
+  <paragraph>If an exception is thrown during execution of a finally block, the exception is propagated to the next enclosing try statement. If another exception was in the process of being propagated, that exception is lost. The process of propagating an exception is discussed further in the description of the throw statement (<hyperlink>15.9.5</hyperlink>). </paragraph>
+  <paragraph>The try block of a try statement is reachable if the try statement is reachable. </paragraph>
+  <paragraph>A catch block of a try statement is reachable if the try statement is reachable. </paragraph>
+  <paragraph>The finally block of a try statement is reachable if the try statement is reachable. </paragraph>
+  <paragraph>The end point of a try statement is reachable if both of the following are true: <list><list_item> The end point of the try block is reachable or the end point of at least one catch block is reachable. </list_item><list_item> If a finally block is present, the end point of the finally block is reachable. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/15.11.xml b/mcs/docs/ecma334/15.11.xml
new file mode 100644 (file)
index 0000000..b686ce8
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="15.11" title="The checked and unchecked statements">
+  <paragraph>The checked and unchecked statements are used to control the overflow checking context for  <non_terminal where="11.1">integral-type</non_terminal> arithmetic operations and conversions. <grammar_production><name><non_terminal where="15.11">checked-statement</non_terminal></name> : <rhs><keyword>checked</keyword><non_terminal where="15.2">block</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="15.11">unchecked-statement</non_terminal></name> : <rhs><keyword>unchecked</keyword><non_terminal where="15.2">block</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>The checked statement causes all expressions in the block to be evaluated in a checked context, and the unchecked statement causes all expressions in the block to be evaluated in an unchecked context. </paragraph>
+  <paragraph>The checked and unchecked statements are precisely equivalent to the checked and unchecked operators (<hyperlink>14.5.12</hyperlink>), except that they operate on blocks instead of expressions. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/15.12.xml b/mcs/docs/ecma334/15.12.xml
new file mode 100644 (file)
index 0000000..475a6b4
--- /dev/null
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<clause number="15.12" title="The lock statement">
+  <paragraph>The lock statement obtains the mutual-exclusion lock for a given object, executes a statement, and then releases the lock. <grammar_production><name><non_terminal where="15.12">lock-statement</non_terminal></name> : <rhs><keyword>lock</keyword><terminal>(</terminal><non_terminal where="14.14">expression</non_terminal><terminal>)</terminal><non_terminal where="15">embedded-statement</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>The expression of a lock statement must denote a value of a <non_terminal where="11.2">reference-type</non_terminal>. No implicit boxing conversion (<hyperlink>13.1.5</hyperlink>) is ever performed for the expression of a lock statement, and thus it is a compile-time error for the expression to denote a value of a <non_terminal where="11.1">value-type</non_terminal>. </paragraph>
+  <paragraph>A lock statement of the form <code_example><![CDATA[
+lock (x) ...  
+]]></code_example>where x is an expression of a <non_terminal where="11.2">reference-type</non_terminal>, is precisely equivalent to <code_example><![CDATA[
+System.Threading.Monitor.Enter(x);  
+try {  
+   ...  
+}  
+finally {  
+   System.Threading.Monitor.Exit(x);  
+}  
+]]></code_example>except that x is only evaluated once. </paragraph>
+  <paragraph>
+    <example>[Example: The System.Type object of a class can conveniently be used as the mutual-exclusion lock for static methods of the class. For example: <code_example><![CDATA[
+class Cache  
+{  
+   public static void Add(object x) {  
+      lock (typeof(Cache)) {  
+         ...  
+      }  
+   }  
+   public static void Remove(object x) {  
+      lock (typeof(Cache)) {  
+         ...  
+      }  
+   }  
+}  
+]]></code_example>end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/15.13.xml b/mcs/docs/ecma334/15.13.xml
new file mode 100644 (file)
index 0000000..f6de429
--- /dev/null
@@ -0,0 +1,49 @@
+<?xml version="1.0"?>
+<clause number="15.13" title="The using statement">
+  <paragraph>The using statement obtains one or more resources, executes a statement, and then disposes of the resource. <grammar_production><name><non_terminal where="15.13">using-statement</non_terminal></name> : <rhs><keyword>using</keyword><terminal>(</terminal><non_terminal where="15.13">resource-acquisition</non_terminal><terminal>)</terminal><non_terminal where="15">embedded-statement</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="15.13">resource-acquisition</non_terminal></name> : <rhs><non_terminal where="15.5.1">local-variable-declaration</non_terminal></rhs><rhs><non_terminal where="14.14">expression</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>A resource is a class or struct that implements System.IDisposable, which includes a single parameterless method named Dispose. Code that is using a resource can call Dispose to indicate that the resource is no longer needed. If Dispose is not called, then automatic disposal eventually occurs as a consequence of garbage collection. </paragraph>
+  <paragraph>If the form of <non_terminal where="15.13">resource-acquisition</non_terminal> is <non_terminal where="15.5.1">local-variable-declaration</non_terminal> then the type of the  <non_terminal where="15.5.1">local-variable-declaration</non_terminal> must be System.IDisposable or a type that can be implicitly converted to System.IDisposable. If the form of <non_terminal where="15.13">resource-acquisition</non_terminal> is expression then this expression must be System.IDisposable or a type that can be implicitly converted to System.IDisposable. </paragraph>
+  <paragraph>Local variables declared in a <non_terminal where="15.13">resource-acquisition</non_terminal> are read-only, and must include an initializer. A  compile-time error occurs if the embedded statement attempts to modify these local variables (via assignment or the ++ and  --operators) or pass them as ref or out parameters. </paragraph>
+  <paragraph>A using statement is translated into three parts: acquisition, usage, and disposal. Usage of the resource is implicitly enclosed in a try statement that includes a finally clause. This finally clause disposes of the resource. If a null resource is acquired, then no call to Dispose is made, and no exception is thrown. </paragraph>
+  <paragraph>A using statement of the form <code_example><![CDATA[
+using (R r1 = new R()) {  
+   r1.F();  
+}  
+]]></code_example>is precisely equivalent to <code_example><![CDATA[
+R r1 = new R();  
+try {  
+   r1.F();  
+}  
+finally {  
+   if (r1 != null) ((IDisposable)r1).Dispose();  
+}  
+]]></code_example></paragraph>
+  <paragraph>A <non_terminal where="15.13">resource-acquisition</non_terminal> may acquire multiple resources of a given type. This is equivalent to nested using statements. A using statement of the form <code_example><![CDATA[
+using (R r1 = new R(), r2 = new R()) {  
+   r1.F();  
+   r2.F();  
+}  
+]]></code_example>is precisely equivalent to: <code_example><![CDATA[
+using (R r1 = new R())  
+using (R r2 = new R()) {  
+   r1.F();  
+   r2.F();  
+}  
+]]></code_example>which is, by expansion, precisely equivalent to: <code_example><![CDATA[
+R r1 = new R();  
+try {  
+   R r2 = new R();  
+   try {  
+      r1.F();  
+      r2.F();  
+   }  
+   finally {  
+      if (r2 != null) ((IDisposable)r2).Dispose();  
+   }  
+}  
+finally {  
+   if (r1 != null) ((IDisposable)r1).Dispose();  
+}  
+<table_line></table_line>
+]]></code_example></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/15.2.1.xml b/mcs/docs/ecma334/15.2.1.xml
new file mode 100644 (file)
index 0000000..5a87a58
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<clause number="15.2.1" title="Statement lists">
+  <paragraph>A statement list consists of one or more statements written in sequence. Statement lists occur in blocks (<hyperlink>15.2</hyperlink>) and in <non_terminal where="15.7.2">switch-block</non_terminal>s (<hyperlink>15.7.2</hyperlink>). <grammar_production><name><non_terminal where="15.2.1">statement-list</non_terminal></name> : <rhs><non_terminal where="15">statement</non_terminal></rhs><rhs><non_terminal where="15.2.1">statement-list</non_terminal><non_terminal where="15">statement</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>A statement list is executed by transferring control to the first statement. When and if control reaches the end point of a statement, control is transferred to the next statement. When and if control reaches the end point of the last statement, control is transferred to the end point of the statement list. </paragraph>
+  <paragraph>A statement in a statement list is reachable if at least one of the following is true: <list><list_item> The statement is the first statement and the statement list itself is reachable. </list_item><list_item> The end point of the preceding statement is reachable. </list_item><list_item> The statement is a labeled statement and the label is referenced by a reachable goto statement. </list_item></list></paragraph>
+  <paragraph>The end point of a statement list is reachable if the end point of the last statement in the list is reachable. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/15.2.xml b/mcs/docs/ecma334/15.2.xml
new file mode 100644 (file)
index 0000000..f2cf355
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<clause number="15.2" title="Blocks">
+  <paragraph>A block permits multiple statements to be written in contexts where a single statement is allowed. <grammar_production><name>block</name> : <rhs><terminal>{</terminal><non_terminal where="15.2.1">statement-list</non_terminal><opt/><terminal>}</terminal></rhs></grammar_production></paragraph>
+  <paragraph>A block consists of an optional <non_terminal where="15.2.1">statement-list</non_terminal> (<hyperlink>15.2.1</hyperlink>), enclosed in braces. If the statement list is omitted, the block is said to be empty. </paragraph>
+  <paragraph>A block may contain declaration statements (<hyperlink>15.5</hyperlink>). The scope of a local variable or constant declared in a block is the block. </paragraph>
+  <paragraph>Within a block, the meaning of a name used in an expression context must always be the same (<hyperlink>14.5.2.1</hyperlink>). </paragraph>
+  <paragraph>A block is executed as follows: <list><list_item> If the block is empty, control is transferred to the end point of the block. </list_item><list_item> If the block is not empty, control is transferred to the statement list. When and if control reaches the end point of the statement list, control is transferred to the end point of the block. </list_item></list></paragraph>
+  <paragraph>The statement list of a block is reachable if the block itself is reachable. </paragraph>
+  <paragraph>The end point of a block is reachable if the block is empty or if the end point of the statement list is reachable. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/15.3.xml b/mcs/docs/ecma334/15.3.xml
new file mode 100644 (file)
index 0000000..a74b4f7
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<clause number="15.3" title="The empty statement">
+  <paragraph>An <non_terminal where="15.3">empty-statement</non_terminal> does nothing. <grammar_production><name><non_terminal where="15.3">empty-statement</non_terminal></name> : <rhs><terminal>;</terminal></rhs></grammar_production></paragraph>
+  <paragraph>An empty statement is used when there are no operations to perform in a context where a statement is required. </paragraph>
+  <paragraph>Execution of an empty statement simply transfers control to the end point of the statement. Thus, the end point of an empty statement is reachable if the empty statement is reachable. </paragraph>
+  <paragraph>
+    <example>[Example: An empty statement can be used when writing a while statement with a null body: <code_example><![CDATA[
+bool ProcessMessage() {...}  
+void ProcessMessages() {  
+   while (ProcessMessage())  
+   ;  
+}  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>Also, an empty statement can be used to declare a label just before the closing &quot;}&quot; of a block: <code_example><![CDATA[
+void F() {  
+   ...  
+   if (done) goto exit;  
+   ...  
+   exit: ;  
+}  
+]]></code_example>end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/15.4.xml b/mcs/docs/ecma334/15.4.xml
new file mode 100644 (file)
index 0000000..edb6e9d
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<clause number="15.4" title="Labeled statements">
+  <paragraph>A <non_terminal where="15.4">labeled-statement</non_terminal> permits a statement to be prefixed by a label. Labeled statements are permitted in blocks, but are not permitted as embedded statements. <grammar_production><name><non_terminal where="15.4">labeled-statement</non_terminal></name> : <rhs><non_terminal where="9.4.2">identifier</non_terminal><terminal>:</terminal><non_terminal where="15">statement</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>A labeled statement declares a label with the name given by the identifier. The scope of a label is the whole block in which the label is declared, including any nested blocks. It is a compile-time error for two labels with the same name to have overlapping scopes. </paragraph>
+  <paragraph>A label can be referenced from goto statements (<hyperlink>15.9.3</hyperlink>) within the scope of the label. <note>[Note: This means that goto statements can transfer control within blocks and out of blocks, but never into blocks. end note]</note> </paragraph>
+  <paragraph>Labels have their own declaration space and do not interfere with other identifiers. <example>[Example: The example <code_example><![CDATA[
+int F(int x) {  
+   if (x >= 0) goto x;  
+   x = -x;  
+   x: return x;  
+}  
+]]></code_example>is valid and uses the name x as both a parameter and a label. end example]</example> </paragraph>
+  <paragraph>Execution of a labeled statement corresponds exactly to execution of the statement following the label. </paragraph>
+  <paragraph>In addition to the reachability provided by normal flow of control, a labeled statement is reachable if the label is referenced by a reachable goto statement. (Exception: If a goto statement is inside a try that includes a finally block, and the labeled statement is outside the try, and the end point of the finally block is unreachable, then the labeled statement is not reachable from that goto statement.) </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/15.5.1.xml b/mcs/docs/ecma334/15.5.1.xml
new file mode 100644 (file)
index 0000000..2a9dc00
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<clause number="15.5.1" title="Local variable declarations">
+  <paragraph>A <non_terminal where="15.5.1">local-variable-declaration</non_terminal> declares one or more local variables. <grammar_production><name><non_terminal where="15.5.1">local-variable-declaration</non_terminal></name> : <rhs><non_terminal where="11">type</non_terminal><non_terminal where="15.5.1">local-variable-declarators</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="15.5.1">local-variable-declarator</non_terminal>s</name> : <rhs><non_terminal where="15.5.1">local-variable-declarator</non_terminal></rhs><rhs><non_terminal where="15.5.1">local-variable-declarators</non_terminal><terminal>,</terminal><non_terminal where="15.5.1">local-variable-declarator</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="15.5.1">local-variable-declarator</non_terminal></name> : <rhs><non_terminal where="9.4.2">identifier</non_terminal></rhs><rhs><non_terminal where="9.4.2">identifier</non_terminal><terminal>=</terminal><non_terminal where="15.5.1">local-variable-initializer</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="15.5.1">local-variable-initializer</non_terminal></name> : <rhs><non_terminal where="14.14">expression</non_terminal></rhs><rhs><non_terminal where="19.6">array-initializer</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>The type of a <non_terminal where="15.5.1">local-variable-declaration</non_terminal> specifies the type of the variables introduced by the declaration. </paragraph>
+  <paragraph>The type is followed by a list of <non_terminal where="15.5.1">local-variable-declarator</non_terminal>s, each of which introduces a new variable. A <non_terminal where="15.5.1">local-variable-declarator</non_terminal> consists of an identifier that names the variable, optionally followed by an &quot;=&quot; token and a <non_terminal where="15.5.1">local-variable-initializer</non_terminal> that gives the initial value of the variable. </paragraph>
+  <paragraph>The value of a local variable is obtained in an expression using a <non_terminal where="14.5.2">simple-name</non_terminal> (<hyperlink>14.5.2</hyperlink>), and the value of a local variable is modified using an assignment (<hyperlink>14.13</hyperlink>). A local variable must be definitely assigned (<hyperlink>12.3</hyperlink>) at each location where its value is obtained. </paragraph>
+  <paragraph>The scope of a local variable declared in a <non_terminal where="15.5.1">local-variable-declaration</non_terminal> is the block in which the declaration occurs. It is an error to refer to a local variable in a textual position that precedes the  <non_terminal where="15.5.1">local-variable-declarator</non_terminal> of the local variable. Within the scope of a local variable, it is a compile-time error to declare another local variable or constant with the same name. </paragraph>
+  <paragraph>A local variable declaration that declares multiple variables is equivalent to multiple declarations of single variables with the same type. Furthermore, a variable initializer in a local variable declaration corresponds exactly to an assignment statement that is inserted immediately after the declaration. </paragraph>
+  <paragraph>
+    <example>[Example: The example <code_example><![CDATA[
+void F() {  
+   int x = 1, y, z = x * 2;  
+}  
+]]></code_example>corresponds exactly to <code_example><![CDATA[
+void F() {  
+   int x; x = 1;  
+   int y;  
+   int z; z = x * 2;  
+}  
+]]></code_example>end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/15.5.2.xml b/mcs/docs/ecma334/15.5.2.xml
new file mode 100644 (file)
index 0000000..fef7554
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<clause number="15.5.2" title="Local constant declarations">
+  <paragraph>A <non_terminal where="15.5.2">local-constant-declaration</non_terminal> declares one or more local constants. <grammar_production><name><non_terminal where="15.5.2">local-constant-declaration</non_terminal></name> : <rhs><keyword>const</keyword><non_terminal where="11">type</non_terminal><non_terminal where="17.3">constant-declarators</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.3">constant-declarator</non_terminal>s</name> : <rhs><non_terminal where="17.3">constant-declarator</non_terminal></rhs><rhs><non_terminal where="17.3">constant-declarators</non_terminal><terminal>,</terminal><non_terminal where="17.3">constant-declarator</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.3">constant-declarator</non_terminal></name> : <rhs><non_terminal where="9.4.2">identifier</non_terminal><terminal>=</terminal><non_terminal where="14.15">constant-expression</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>The type of a <non_terminal where="15.5.2">local-constant-declaration</non_terminal> specifies the type of the constants introduced by the declaration. The type is followed by a list of <non_terminal where="17.3">constant-declarator</non_terminal>s, each of which introduces a new constant. A  <non_terminal where="17.3">constant-declarator</non_terminal> consists of an identifier that names the constant, followed by an &quot;=&quot; token, followed by a <non_terminal where="14.15">constant-expression</non_terminal> (<hyperlink>14.15</hyperlink>) that gives the value of the constant. </paragraph>
+  <paragraph>The type and <non_terminal where="14.15">constant-expression</non_terminal> of a local constant declaration must follow the same rules as those of a constant member declaration (<hyperlink>17.3</hyperlink>). </paragraph>
+  <paragraph>The value of a local constant is obtained in an expression using a <non_terminal where="14.5.2">simple-name</non_terminal> (<hyperlink>14.5.2</hyperlink>). </paragraph>
+  <paragraph>The scope of a local constant is the block in which the declaration occurs. It is an error to refer to a local constant in a textual position that precedes its <non_terminal where="17.3">constant-declarator</non_terminal>. Within the scope of a local constant, it is a compile-time error to declare another local variable or constant with the same name. </paragraph>
+  <paragraph>A local constant declaration that declares multiple constants is equivalent to multiple declarations of single constants with the same type. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/15.5.xml b/mcs/docs/ecma334/15.5.xml
new file mode 100644 (file)
index 0000000..265f16a
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="15.5" title="Declaration statements">
+  <paragraph>A <non_terminal where="15.5">declaration-statement</non_terminal> declares a local variable or constant. Declaration statements are permitted in blocks, but are not permitted as embedded statements. <grammar_production><name><non_terminal where="15.5">declaration-statement</non_terminal></name> : <rhs><non_terminal where="15.5.1">local-variable-declaration</non_terminal><terminal>;</terminal></rhs><rhs><non_terminal where="15.5.2">local-constant-declaration</non_terminal><terminal>;</terminal></rhs></grammar_production></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/15.6.xml b/mcs/docs/ecma334/15.6.xml
new file mode 100644 (file)
index 0000000..45c00ae
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="15.6" title="Expression statements">
+  <paragraph>An <non_terminal where="15.6">expression-statement</non_terminal> evaluates a given expression. The value computed by the expression, if any, is discarded. <grammar_production><name><non_terminal where="15.6">expression-statement</non_terminal></name> : <rhs><non_terminal where="15.6">statement-expression</non_terminal><terminal>;</terminal></rhs></grammar_production><grammar_production><name><non_terminal where="15.6">statement-expression</non_terminal></name> : <rhs><non_terminal where="14.5.5">invocation-expression</non_terminal></rhs><rhs><non_terminal where="14.5.10.1">object-creation-expression</non_terminal></rhs><rhs><non_terminal where="14.13">assignment</non_terminal></rhs><rhs><non_terminal where="14.5.9">post-increment-expression</non_terminal></rhs><rhs><non_terminal where="14.5.9">post-decrement-expression</non_terminal></rhs><rhs><non_terminal where="14.6.5">pre-increment-expression</non_terminal></rhs><rhs><non_terminal where="14.6.5">pre-decrement-expression</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>Not all expressions are permitted as statements. <note>[Note: In particular, expressions such as x + y and x == 1, that merely compute a value (which will be discarded), are not permitted as statements. end note]</note> </paragraph>
+  <paragraph>Execution of an expression statement evaluates the contained expression and then transfers control to the end point of the expression statement. The end point of an <non_terminal where="15.6">expression-statement</non_terminal> is reachable if that <non_terminal where="15.6">expression-statement</non_terminal> is reachable. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/15.7.1.xml b/mcs/docs/ecma334/15.7.1.xml
new file mode 100644 (file)
index 0000000..00c342e
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<clause number="15.7.1" title="The if statement">
+  <paragraph>The if statement selects a statement for execution based on the value of a boolean expression. <grammar_production><name><non_terminal where="15.7.1">if-statement</non_terminal></name> : <rhs><keyword>if</keyword><terminal>(</terminal><non_terminal where="15.7.1">boolean-expression</non_terminal><terminal>)</terminal><non_terminal where="15">embedded-statement</non_terminal></rhs><rhs><keyword>if</keyword><terminal>(</terminal><non_terminal where="15.7.1">boolean-expression</non_terminal><terminal>)</terminal><non_terminal where="15">embedded-statement</non_terminal><keyword>else</keyword><non_terminal where="15">embedded-statement</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="15.7.1">boolean-expression</non_terminal></name> : <rhs><non_terminal where="14.14">expression</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>An else part is associated with the lexically nearest preceding if that is allowed by the syntax. <example>[Example: Thus, an if statement of the form <code_example><![CDATA[
+if (x) if (y) F(); else G();  
+]]></code_example>is equivalent to <code_example><![CDATA[
+if (x) {  
+   if (y) {  
+      F();  
+   }  
+   else {  
+      G();  
+   }  
+}  
+]]></code_example>end example]</example> </paragraph>
+  <paragraph>An if statement is executed as follows: <list><list_item> The <non_terminal where="15.7.1">boolean-expression</non_terminal> (<hyperlink>14.16</hyperlink>) is evaluated. </list_item><list_item> If the boolean expression yields true, control is transferred to the first embedded statement. When and if control reaches the end point of that statement, control is transferred to the end point of the if statement. </list_item><list_item> If the boolean expression yields false and if an else part is present, control is transferred to the second embedded statement. When and if control reaches the end point of that statement, control is transferred to the end point of the if statement. </list_item><list_item> If the boolean expression yields false and if an else part is not present, control is transferred to the end point of the if statement. </list_item></list></paragraph>
+  <paragraph>The first embedded statement of an if statement is reachable if the if statement is reachable and the boolean expression does not have the constant value false. </paragraph>
+  <paragraph>The second embedded statement of an if statement, if present, is reachable if the if statement is reachable and the boolean expression does not have the constant value true. </paragraph>
+  <paragraph>The end point of an if statement is reachable if the end point of at least one of its embedded statements is reachable. In addition, the end point of an if statement with no else part is reachable if the if statement is reachable and the boolean expression does not have the constant value true. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/15.7.2.xml b/mcs/docs/ecma334/15.7.2.xml
new file mode 100644 (file)
index 0000000..1bc1bf7
--- /dev/null
@@ -0,0 +1,112 @@
+<?xml version="1.0"?>
+<clause number="15.7.2" title="The switch statement">
+  <paragraph>The switch statement selects for execution a statement list having an associated switch label that corresponds to the value of the switch expression. <grammar_production><name><non_terminal where="15.7.2">switch-statement</non_terminal></name> : <rhs><keyword>switch</keyword><terminal>(</terminal><non_terminal where="14.14">expression</non_terminal><terminal>)</terminal><non_terminal where="15.7.2">switch-block</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="15.7.2">switch-block</non_terminal></name> : <rhs><terminal>{</terminal><non_terminal where="15.7.2">switch-sections</non_terminal><opt/><terminal>}</terminal></rhs></grammar_production><grammar_production><name><non_terminal where="15.7.2">switch-section</non_terminal>s</name> : <rhs><non_terminal where="15.7.2">switch-section</non_terminal></rhs><rhs><non_terminal where="15.7.2">switch-sections</non_terminal><non_terminal where="15.7.2">switch-section</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="15.7.2">switch-section</non_terminal></name> : <rhs><non_terminal where="15.7.2">switch-labels</non_terminal><non_terminal where="15.2.1">statement-list</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="15.7.2">switch-label</non_terminal>s</name> : <rhs><non_terminal where="15.7.2">switch-label</non_terminal></rhs><rhs><non_terminal where="15.7.2">switch-labels</non_terminal><non_terminal where="15.7.2">switch-label</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="15.7.2">switch-label</non_terminal></name> : <rhs><keyword>case</keyword><non_terminal where="14.15">constant-expression</non_terminal><terminal>:</terminal></rhs><rhs><keyword>default</keyword><terminal>:</terminal></rhs></grammar_production></paragraph>
+  <paragraph>A <non_terminal where="15.7.2">switch-statement</non_terminal> consists of the keyword switch, followed by a parenthesized expression (called the switch expression), followed by a <non_terminal where="15.7.2">switch-block</non_terminal>. The <non_terminal where="15.7.2">switch-block</non_terminal> consists of zero or more <non_terminal where="15.7.2">switch-section</non_terminal>s, enclosed in braces. Each <non_terminal where="15.7.2">switch-section</non_terminal> consists of one or more <non_terminal where="15.7.2">switch-label</non_terminal>s followed by a <non_terminal where="15.2.1">statement-list</non_terminal> (<hyperlink>15.2.1</hyperlink>). </paragraph>
+  <paragraph>The governing type of a switch statement is established by the switch expression. If the type of the switch expression is <keyword>sbyte</keyword>, <keyword>byte</keyword>, <keyword>short</keyword>, <keyword>ushort</keyword>, <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>long</keyword>, <keyword>ulong</keyword>, <keyword>char</keyword>, string, or an <non_terminal where="11.1">enum-type</non_terminal>, then that is the governing type of the switch statement. Otherwise, exactly one user-defined implicit conversion (<hyperlink>13.4</hyperlink>) must exist from the type of the switch expression to one of the following possible governing types: <keyword>sbyte</keyword>, <keyword>byte</keyword>, <keyword>short</keyword>, <keyword>ushort</keyword>, <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>long</keyword>, <keyword>ulong</keyword>, <keyword>char</keyword>, string. If no such implicit conversion exists, or if more than one such implicit conversion exists, a compile-time error occurs. </paragraph>
+  <paragraph>The constant expression of each case label must denote a value of a type that is implicitly convertible (<hyperlink>13.1</hyperlink>) to the governing type of the switch statement. A compile-time error occurs if two or more case labels in the same switch statement specify the same constant value. </paragraph>
+  <paragraph>There can be at most one default label in a switch statement. </paragraph>
+  <paragraph>A switch statement is executed as follows: <list><list_item> The switch expression is evaluated and converted to the governing type. </list_item><list_item> If one of the constants specified in a case label in the same switch statement is equal to the value of the switch expression, control is transferred to the statement list following the matched case label. </list_item><list_item> If none of the constants specified in case labels in the same switch statement is equal to the value of the switch expression, and if a default label is present, control is transferred to the statement list following the default label. </list_item><list_item> If none of the constants specified in case labels in the same switch statement is equal to the value of the switch expression, and if no default label is present, control is transferred to the end point of the switch statement. </list_item></list></paragraph>
+  <paragraph>If the end point of the statement list of a switch section is reachable, a compile-time error occurs. This is known as the &quot;no fall through&quot; rule. <example>[Example: The example <code_example><![CDATA[
+switch (i) {  
+   case 0:  
+   CaseZero();  
+   break;  
+   case 1:  
+   CaseOne();  
+   break;  
+   default:  
+   CaseOthers();  
+   break;  
+}  
+]]></code_example>is valid because no switch section has a reachable end point. Unlike C and C++, execution of a switch section is not permitted to &quot;fall through&quot; to the next switch section, and the example <code_example><![CDATA[
+switch (i) {  
+   case 0:  
+   CaseZero();  
+   case 1:  
+   CaseZeroOrOne();  
+   default:  
+   CaseAny();  
+}  
+]]></code_example>results in a compile-time error. When execution of a switch section is to be followed by execution of another switch section, an explicit goto case or goto default statement must be used: <code_example><![CDATA[
+switch (i) {  
+   case 0:  
+   CaseZero();  
+   goto case 1;  
+   case 1:  
+   CaseZeroOrOne();  
+   goto default;  
+   default:  
+   CaseAny();  
+   break;  
+}  
+]]></code_example>end example]</example> </paragraph>
+  <paragraph>Multiple labels are permitted in a <non_terminal where="15.7.2">switch-section</non_terminal>. <example>[Example: The example <code_example><![CDATA[
+switch (i) {  
+   case 0:  
+   CaseZero();  
+   break;  
+   case 1:  
+   CaseOne();  
+   break;  
+   case 2:  
+   default:  
+   CaseTwo();  
+   break;  
+}  
+]]></code_example>is valid. The example does not violate the &quot;no fall through&quot; rule because the labels case 2: and default: are part of the same <non_terminal where="15.7.2">switch-section</non_terminal>. end example]</example> </paragraph>
+  <paragraph>
+    <note>[Note: The &quot;no fall through&quot; rule prevents a common class of bugs that occur in C and C++ when break statements are accidentally omitted. In addition, because of this rule, the switch sections of a switch statement can be arbitrarily rearranged without affecting the behavior of the statement. For example, the sections of the switch statement above can be reversed without affecting the behavior of the statement: <code_example><![CDATA[
+switch (i) {  
+   default:  
+   CaseAny();  
+   break;  
+   case 1:  
+   CaseZeroOrOne();  
+   goto default;  
+   case 0:  
+   CaseZero();  
+   goto case 1;  
+}  
+]]></code_example>end note]</note>
+  </paragraph>
+  <paragraph>
+    <note>[Note: The statement list of a switch section typically ends in a break, goto case, or goto default statement, but any construct that renders the end point of the statement list unreachable is permitted. For example, a while statement controlled by the boolean expression true is known to never reach its end point. Likewise, a throw or return statement always transfers control elsewhere and never reaches its end point. Thus, the following example is valid: <code_example><![CDATA[
+switch (i) {  
+   case 0:  
+   while (true) F();  
+   case 1:  
+   throw new ArgumentException();  
+   case 2:  
+   return;  
+}  
+]]></code_example>end note]</note>
+  </paragraph>
+  <paragraph>
+    <example>[Example: The governing type of a switch statement may be the type string. For example: <code_example><![CDATA[
+void DoCommand(string command) {  
+   switch (command.ToLower()) {  
+      case "run":  
+      DoRun();  
+      break;  
+      case "save":  
+      DoSave();  
+      break;  
+      case "quit":  
+      DoQuit();  
+      break;  
+      default:  
+      InvalidCommand(command);  
+      break;  
+   }  
+}  
+]]></code_example>end example]</example>
+  </paragraph>
+  <paragraph>
+    <note>[Note: Like the string equality operators (<hyperlink>14.9.7</hyperlink>), the switch statement is case sensitive and will execute a given switch section only if the switch expression string exactly matches a case label constant. end note]</note>
+  </paragraph>
+  <paragraph>When the governing type of a switch statement is string, the value null is permitted as a case label constant. </paragraph>
+  <paragraph>The <non_terminal where="15.2.1">statement-list</non_terminal>s of a <non_terminal where="15.7.2">switch-block</non_terminal> may contain declaration statements (<hyperlink>15.5</hyperlink>). The scope of a local variable or constant declared in a switch block is the switch block. </paragraph>
+  <paragraph>Within a switch block, the meaning of a name used in an expression context must always be the same (<hyperlink>14.5.2.1</hyperlink>). </paragraph>
+  <paragraph>The statement list of a given switch section is reachable if the switch statement is reachable and at least one of the following is true: <list><list_item> The switch expression is a non-constant value. </list_item><list_item> The switch expression is a constant value that matches a case label in the switch section. </list_item><list_item> The switch expression is a constant value that doesn't match any case label, and the switch section contains the default label. </list_item><list_item> A switch label of the switch section is referenced by a reachable goto case or goto default statement. </list_item></list></paragraph>
+  <paragraph>The end point of a switch statement is reachable if at least one of the following is true: <list><list_item> The switch statement contains a reachable break statement that exits the switch statement. </list_item><list_item> The switch statement is reachable, the switch expression is a non-constant value, and no default label is present. </list_item><list_item> The switch statement is reachable, the switch expression is a constant value that doesn't match any case label, and no default label is present. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/15.7.xml b/mcs/docs/ecma334/15.7.xml
new file mode 100644 (file)
index 0000000..2669dd7
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="15.7" title="Selection statements">
+  <paragraph>Selection statements select one of a number of possible statements for execution based on the value of some expression. <grammar_production><name><non_terminal where="15.7">selection-statement</non_terminal></name> : <rhs><non_terminal where="15.7.1">if-statement</non_terminal></rhs><rhs><non_terminal where="15.7.2">switch-statement</non_terminal></rhs></grammar_production></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/15.8.1.xml b/mcs/docs/ecma334/15.8.1.xml
new file mode 100644 (file)
index 0000000..92dbd9b
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<clause number="15.8.1" title="The while statement">
+  <paragraph>The while statement conditionally executes an embedded statement zero or more times. <grammar_production><name><non_terminal where="15.8.1">while-statement</non_terminal></name> : <rhs><keyword>while</keyword><terminal>(</terminal><non_terminal where="15.7.1">boolean-expression</non_terminal><terminal>)</terminal><non_terminal where="15">embedded-statement</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>A while statement is executed as follows: <list><list_item> The <non_terminal where="15.7.1">boolean-expression</non_terminal> (<hyperlink>14.16</hyperlink>) is evaluated. </list_item><list_item> If the boolean expression yields true, control is transferred to the embedded statement. When and if control reaches the end point of the embedded statement (possibly from execution of a continue statement), control is transferred to the beginning of the while statement. </list_item><list_item> If the boolean expression yields false, control is transferred to the end point of the while statement. </list_item></list></paragraph>
+  <paragraph>Within the embedded statement of a while statement, a break statement (<hyperlink>15.9.1</hyperlink>) may be used to transfer control to the end point of the while statement (thus ending iteration of the embedded statement), and a continue statement (<hyperlink>15.9.2</hyperlink>) may be used to transfer control to the end point of the embedded statement (thus performing another iteration of the while statement). </paragraph>
+  <paragraph>The embedded statement of a while statement is reachable if the while statement is reachable and the boolean expression does not have the constant value false. </paragraph>
+  <paragraph>The end point of a while statement is reachable if at least one of the following is true: <list><list_item> The while statement contains a reachable break statement that exits the while statement. </list_item><list_item> The while statement is reachable and the boolean expression does not have the constant value true. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/15.8.2.xml b/mcs/docs/ecma334/15.8.2.xml
new file mode 100644 (file)
index 0000000..f2b765a
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<clause number="15.8.2" title="The do statement">
+  <paragraph>The do statement conditionally executes an embedded statement one or more times. <grammar_production><name><non_terminal where="15.8.2">do-statement</non_terminal></name> : <rhs><keyword>do</keyword><non_terminal where="15">embedded-statement</non_terminal><keyword>while</keyword><terminal>(</terminal><non_terminal where="15.7.1">boolean-expression</non_terminal><terminal>)</terminal><terminal>;</terminal></rhs></grammar_production></paragraph>
+  <paragraph>A do statement is executed as follows: <list><list_item> Control is transferred to the embedded statement. </list_item><list_item> When and if control reaches the end point of the embedded statement (possibly from execution of a continue statement), the <non_terminal where="15.7.1">boolean-expression</non_terminal> (<hyperlink>14.16</hyperlink>) is evaluated. If the boolean expression yields true, control is transferred to the beginning of the do statement. Otherwise, control is transferred to the end point of the do statement. </list_item></list></paragraph>
+  <paragraph>Within the embedded statement of a do statement, a break statement (<hyperlink>15.9.1</hyperlink>) may be used to transfer control to the end point of the do statement (thus ending iteration of the embedded statement), and a continue statement (<hyperlink>15.9.2</hyperlink>) may be used to transfer control to the end point of the embedded statement (thus performing another iteration of the do statement). </paragraph>
+  <paragraph>The embedded statement of a do statement is reachable if the do statement is reachable. </paragraph>
+  <paragraph>The end point of a do statement is reachable if at least one of the following is true: <list><list_item> The do statement contains a reachable break statement that exits the do statement. </list_item><list_item> The end point of the embedded statement is reachable and the boolean expression does not have the constant value true. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/15.8.3.xml b/mcs/docs/ecma334/15.8.3.xml
new file mode 100644 (file)
index 0000000..fe11369
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<clause number="15.8.3" title="The for statement">
+  <paragraph>The for statement evaluates a sequence of initialization expressions and then, while a condition is true, repeatedly executes an embedded statement and evaluates a sequence of iteration expressions. <grammar_production><name><non_terminal where="15.8.3">for-statement</non_terminal></name> : <rhs><keyword>for</keyword><terminal>(</terminal><non_terminal where="15.8.3">for-initializer</non_terminal><opt/><terminal>;</terminal><non_terminal where="15.8.3">for-condition</non_terminal><opt/><terminal>;</terminal><non_terminal where="15.8.3">for-iterator</non_terminal><opt/><terminal>)</terminal><non_terminal where="15">embedded-statement</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="15.8.3">for-initializer</non_terminal></name> : <rhs><non_terminal where="15.5.1">local-variable-declaration</non_terminal></rhs><rhs><non_terminal where="15.8.3">statement-expression-list</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="15.8.3">for-condition</non_terminal></name> : <rhs><non_terminal where="15.7.1">boolean-expression</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="15.8.3">for-iterator</non_terminal></name> : <rhs><non_terminal where="15.8.3">statement-expression-list</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="15.8.3">statement-expression-list</non_terminal></name> : <rhs><non_terminal where="15.6">statement-expression</non_terminal></rhs><rhs><non_terminal where="15.8.3">statement-expression-list</non_terminal><terminal>,</terminal><non_terminal where="15.6">statement-expression</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>The <non_terminal where="15.8.3">for-initializer</non_terminal>, if present, consists of either a <non_terminal where="15.5.1">local-variable-declaration</non_terminal> (<hyperlink>15.5.1</hyperlink>) or a list of  <non_terminal where="15.6">statement-expression</non_terminal>s (<hyperlink>15.6</hyperlink>) separated by commas. The scope of a local variable declared by a <non_terminal where="15.8.3">for-initializer</non_terminal> starts at the <non_terminal where="15.5.1">local-variable-declarator</non_terminal> for the variable and extends to the end of the embedded statement. The scope includes the <non_terminal where="15.8.3">for-condition</non_terminal> and the <non_terminal where="15.8.3">for-iterator</non_terminal>. </paragraph>
+  <paragraph>The <non_terminal where="15.8.3">for-condition</non_terminal>, if present, must be a <non_terminal where="15.7.1">boolean-expression</non_terminal> (<hyperlink>14.16</hyperlink>). </paragraph>
+  <paragraph>The <non_terminal where="15.8.3">for-iterator</non_terminal>, if present, consists of a list of <non_terminal where="15.6">statement-expression</non_terminal>s (<hyperlink>15.6</hyperlink>) separated by commas. </paragraph>
+  <paragraph>A for statement is executed as follows: <list><list_item> If a <non_terminal where="15.8.3">for-initializer</non_terminal> is present, the variable initializers or statement expressions are executed in the order they are written. This step is only performed once. </list_item><list_item> If a <non_terminal where="15.8.3">for-condition</non_terminal> is present, it is evaluated. </list_item><list_item> If the <non_terminal where="15.8.3">for-condition</non_terminal> is not present or if the evaluation yields true, control is transferred to the embedded statement. When and if control reaches the end point of the embedded statement (possibly from execution of a continue statement), the expressions of the <non_terminal where="15.8.3">for-iterator</non_terminal>, if any, are evaluated in sequence, and then another iteration is performed, starting with evaluation of the <non_terminal where="15.8.3">for-condition</non_terminal> in the step above. </list_item><list_item> If the <non_terminal where="15.8.3">for-condition</non_terminal> is present and the evaluation yields false, control is transferred to the end point of the for statement. </list_item></list></paragraph>
+  <paragraph>Within the embedded statement of a for statement, a break statement (<hyperlink>15.9.1</hyperlink>) may be used to transfer control to the end point of the for statement (thus ending iteration of the embedded statement), and a continue statement (<hyperlink>15.9.2</hyperlink>) may be used to transfer control to the end point of the embedded statement (thus executing another iteration of the for statement). </paragraph>
+  <paragraph>The embedded statement of a for statement is reachable if one of the following is true: <list><list_item> The for statement is reachable and no <non_terminal where="15.8.3">for-condition</non_terminal> is present. </list_item><list_item> The for statement is reachable and a <non_terminal where="15.8.3">for-condition</non_terminal> is present and does not have the constant value false. </list_item></list></paragraph>
+  <paragraph>The end point of a for statement is reachable if at least one of the following is true: <list><list_item> The for statement contains a reachable break statement that exits the for statement. </list_item><list_item> The for statement is reachable and a <non_terminal where="15.8.3">for-condition</non_terminal> is present and does not have the constant value true. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/15.8.4.xml b/mcs/docs/ecma334/15.8.4.xml
new file mode 100644 (file)
index 0000000..bfa009e
--- /dev/null
@@ -0,0 +1,67 @@
+<?xml version="1.0"?>
+<clause number="15.8.4" title="The foreach statement">
+  <paragraph>The foreach statement enumerates the elements of a collection, executing an embedded statement for each element of the collection. <grammar_production><name><non_terminal where="15.8.4">foreach-statement</non_terminal></name> : <rhs><keyword>foreach</keyword><terminal>(</terminal><non_terminal where="11">type</non_terminal><non_terminal where="9.4.2">identifier</non_terminal><keyword>in</keyword><non_terminal where="14.14">expression</non_terminal><terminal>)</terminal><non_terminal where="15">embedded-statement</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>The type and identifier of a foreach statement declare the iteration variable of the statement. The iteration variable corresponds to a read-only local variable with a scope that extends over the embedded statement. During execution of a foreach statement, the iteration variable represents the collection element for which an iteration is currently being performed. A compile-time error occurs if the embedded statement attempts to modify the iteration variable (via assignment or the ++ and  --operators) or pass the iteration variable as a ref or out parameter. </paragraph>
+  <paragraph>The type of the expression of a foreach statement must be a collection type (as defined below), and an explicit conversion (<hyperlink>13.2</hyperlink>) must exist from the element type of the collection to the type of the iteration variable. If expression has the value null, a System.NullReferenceException is thrown. </paragraph>
+  <paragraph>A type C is said to be a collection type if it implements the System.IEnumerable interface or implements the collection pattern by meeting all of the following criteria: <list><list_item> C contains a public instance method with the signature GetEnumerator(), that returns a <non_terminal where="11.1">struct-type</non_terminal>, <non_terminal where="11.2">class-type</non_terminal>, or <non_terminal where="11.2">interface-type</non_terminal>, which is called E in the following text. </list_item><list_item> E contains a public instance method with the signature MoveNext() and the return type <keyword>bool</keyword>. </list_item><list_item> E contains a public instance property named Current that permits reading the current value. The type of this property is said to be the element type of the collection type. </list_item></list></paragraph>
+  <paragraph>A type that implements IEnumerable is also a collection type, even if it doesn't satisfy the conditions above. (This is possible if it implements IEnumerable via private interface implementation.) </paragraph>
+  <paragraph>The System.Array type (<hyperlink>19.1.1</hyperlink>) is a collection type, and since all array types derive from System.Array, any array type expression is permitted in a foreach statement. The order in which foreach traverses the elements of an array is as follows: For single-dimensional arrays elements are traversed in increasing index order, starting with index 0 and ending with index Length  -1. For  multi-dimensional arrays, elements are traversed such that the indices of the rightmost dimension are increased first, then the next left dimension, and so on to the left. </paragraph>
+  <paragraph>A foreach statement of the form: <code_example><![CDATA[
+foreach (ElementType element in collection) statement  
+]]></code_example>corresponds to one of two possible expansions: <list><list_item> If the collection expression is of a type that implements the collection pattern (as defined above), the expansion of the foreach statement is: <code_example><![CDATA[
+Enumerator enumerator = (collection).GetEnumerator();  
+try {  
+   while (enumerator.MoveNext()) {  
+      ElementType element = (ElementType)enumerator.Current;  
+      statement;  
+   }  
+}  
+finally {  
+   IDisposable disposable = enumerator as System.IDisposable;  
+   if (disposable != null) disposable.Dispose();  
+}  
+]]></code_example></list_item></list></paragraph>
+  <paragraph>
+    <note>[Note: Significant optimizations of the above are often easily available. If the type E implements System.IDisposable, then the expression (enumerator as System.IDisposable) will always be non-null and the implementation can safely substitute a simple conversion for a possibly more expensive type test. Conversely, if the type E is sealed and does not implement System.IDisposable, then the expression (enumerator as System.IDisposable) will always evaluate to null. In this case, the implementation can safely optimize away the entire finally clause. end note]</note>
+    <list>
+      <list_item> Otherwise; the collection expression is of a type that implements System.IEnumerable, and the expansion of the foreach statement is: <code_example><![CDATA[
+IEnumerator enumerator =  
+((System.IEnumerable)(collection)).GetEnumerator();  
+try {  
+   while (enumerator.MoveNext()) {  
+      ElementType element = (ElementType)enumerator.Current;  
+      statement;  
+   }  
+}  
+finally {  
+   IDisposable disposable = enumerator as System.IDisposable;  
+   if (disposable != null) disposable.Dispose();  
+}  
+]]></code_example></list_item>
+    </list>
+  </paragraph>
+  <paragraph>In either expansion, the enumerator variable is a temporary variable that is inaccessible in, and invisible to, the embedded statement, and the element variable is read-only in the embedded statement. </paragraph>
+  <paragraph>
+    <example>[Example: The following example prints out each value in a two-dimensional array, in element order: <code_example><![CDATA[
+using System;  
+class Test  
+{  
+   static void Main() {  
+      double[,] values = {  
+         {1.2, 2.3, 3.4, 4.5},  
+         {5.6, 6.7, 7.8, 8.9}  
+      };  
+      
+      foreach (double elementValue in values)  
+      Console.Write("{0} ", elementValue);  
+      Console.WriteLine();  
+   }  
+}  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>The output produced is as follows: <code_example><![CDATA[
+1.2 2.3 3.4 4.5 5.6 6.7 7.8 8.9  
+]]></code_example>end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/15.8.xml b/mcs/docs/ecma334/15.8.xml
new file mode 100644 (file)
index 0000000..b000f1d
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="15.8" title="Iteration statements">
+  <paragraph>Iteration statements repeatedly execute an embedded statement. <grammar_production><name><non_terminal where="15.8">iteration-statement</non_terminal></name> : <rhs><non_terminal where="15.8.1">while-statement</non_terminal></rhs><rhs><non_terminal where="15.8.2">do-statement</non_terminal></rhs><rhs><non_terminal where="15.8.3">for-statement</non_terminal></rhs><rhs><non_terminal where="15.8.4">foreach-statement</non_terminal></rhs></grammar_production></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/15.9.1.xml b/mcs/docs/ecma334/15.9.1.xml
new file mode 100644 (file)
index 0000000..4da0324
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<clause number="15.9.1" title="The break statement">
+  <paragraph>The break statement exits the nearest enclosing switch, while, do, for, or foreach statement. <grammar_production><name><non_terminal where="15.9.1">break-statement</non_terminal></name> : <rhs><keyword>break</keyword><terminal>;</terminal></rhs></grammar_production></paragraph>
+  <paragraph>The target of a break statement is the end point of the nearest enclosing switch, while, do, for, or foreach statement. If a break statement is not enclosed by a switch, while, do, for, or foreach statement, a compile-time error occurs. </paragraph>
+  <paragraph>When multiple switch, while, do, for, or foreach statements are nested within each other, a break statement applies only to the innermost statement. To transfer control across multiple nesting levels, a goto statement (<hyperlink>15.9.3</hyperlink>) must be used. </paragraph>
+  <paragraph>A break statement cannot exit a finally block (<hyperlink>15.10</hyperlink>). When a break statement occurs within a finally block, the target of the break statement must be within the same finally block; otherwise a compile-time error occurs. </paragraph>
+  <paragraph>A break statement is executed as follows: <list><list_item> If the break statement exits one or more try blocks with associated finally blocks, control is initially transferred to the finally block of the innermost try statement. When and if control reaches the end point of a finally block, control is transferred to the finally block of the next enclosing try statement. This process is repeated until the finally blocks of all intervening try statements have been executed. </list_item><list_item> Control is transferred to the target of the break statement. </list_item></list></paragraph>
+  <paragraph>Because a break statement unconditionally transfers control elsewhere, the end point of a break statement is never reachable. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/15.9.2.xml b/mcs/docs/ecma334/15.9.2.xml
new file mode 100644 (file)
index 0000000..ad3af79
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<clause number="15.9.2" title="The continue statement">
+  <paragraph>The continue statement starts a new iteration of the nearest enclosing while, do, for, or foreach statement. <grammar_production><name><non_terminal where="15.9.2">continue-statement</non_terminal></name> : <rhs><keyword>continue</keyword><terminal>;</terminal></rhs></grammar_production></paragraph>
+  <paragraph>The target of a continue statement is the end point of the embedded statement of the nearest enclosing while, do, for, or foreach statement. If a continue statement is not enclosed by a while, do, for, or foreach statement, a compile-time error occurs. </paragraph>
+  <paragraph>When multiple while, do, for, or foreach statements are nested within each other, a continue statement applies only to the innermost statement. To transfer control across multiple nesting levels, a goto statement (<hyperlink>15.9.3</hyperlink>) must be used. </paragraph>
+  <paragraph>A continue statement cannot exit a finally block (<hyperlink>15.10</hyperlink>). When a continue statement occurs within a finally block, the target of the continue statement must be within the same finally block; otherwise a compile-time error occurs. </paragraph>
+  <paragraph>A continue statement is executed as follows: <list><list_item> If the continue statement exits one or more try blocks with associated finally blocks, control is initially transferred to the finally block of the innermost try statement. When and if control reaches the end point of a finally block, control is transferred to the finally block of the next enclosing try statement. This process is repeated until the finally blocks of all intervening try statements have been executed. </list_item><list_item> Control is transferred to the target of the continue statement. </list_item></list></paragraph>
+  <paragraph>Because a continue statement unconditionally transfers control elsewhere, the end point of a continue statement is never reachable. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/15.9.3.xml b/mcs/docs/ecma334/15.9.3.xml
new file mode 100644 (file)
index 0000000..1696313
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<clause number="15.9.3" title="The goto statement">
+  <paragraph>The goto statement transfers control to a statement that is marked by a label. <grammar_production><name><non_terminal where="15.9.3">goto-statement</non_terminal></name> : <rhs><keyword>goto</keyword><non_terminal where="9.4.2">identifier</non_terminal><terminal>;</terminal></rhs><rhs><keyword>goto</keyword><keyword>case</keyword><non_terminal where="14.15">constant-expression</non_terminal><terminal>;</terminal></rhs><rhs><keyword>goto</keyword><keyword>default</keyword><terminal>;</terminal></rhs></grammar_production></paragraph>
+  <paragraph>The target of a goto identifier statement is the labeled statement with the given label. If a label with the given name does not exist in the current function member, or if the goto statement is not within the scope of the label, a compile-time error occurs. <note>[Note: This rule permits the use of a goto statement to transfer control out of a nested scope, but not into a nested scope. In the example <code_example><![CDATA[
+using System;  
+class Test  
+{  
+   static void Main(string[] args) {  
+      string[,] table = {  
+         {"red", "blue", "green"},  
+         {"Monday", "Wednesday", "Friday"}  
+      };  
+      foreach (string str in args) {  
+         int row, colm;  
+         for (row = 0; row <= 1; ++row)  
+         for (colm = 0; colm <= 2; ++colm)  
+         if (str == table[row,colm])  
+         goto done;  
+         Console.WriteLine("{0} not found", str);  
+         continue;  
+         done:  
+         Console.WriteLine("Found {0} at [{1}][{2}]", str, row, colm);  
+      }  
+   }  
+}  
+]]></code_example>a goto statement is used to transfer control out of a nested scope. end note]</note> </paragraph>
+  <paragraph>The target of a goto case statement is the statement list in the immediately enclosing switch statement (<hyperlink>15.7.2</hyperlink>) which contains a case label with the given constant value. If the goto case statement is not enclosed by a switch statement, if the <non_terminal where="14.15">constant-expression</non_terminal> is not implicitly convertible (<hyperlink>13.1</hyperlink>) to the governing type of the nearest enclosing switch statement, or if the nearest enclosing switch statement does not contain a case label with the given constant value, a compile-time error occurs. </paragraph>
+  <paragraph>The target of a goto default statement is the statement list in the immediately enclosing switch statement (<hyperlink>15.7.2</hyperlink>), which contains a default label. If the goto default statement is not enclosed by a switch statement, or if the nearest enclosing switch statement does not contain a default label, a compile-time error occurs. </paragraph>
+  <paragraph>A goto statement cannot exit a finally block (<hyperlink>15.10</hyperlink>). When a goto statement occurs within a finally block, the target of the goto statement must be within the same finally block, or otherwise a compile-time error occurs. </paragraph>
+  <paragraph>A goto statement is executed as follows: <list><list_item> If the goto statement exits one or more try blocks with associated finally blocks, control is initially transferred to the finally block of the innermost try statement. When and if control reaches the end point of a finally block, control is transferred to the finally block of the next enclosing try statement. This process is repeated until the finally blocks of all intervening try statements have been executed. </list_item><list_item> Control is transferred to the target of the goto statement. </list_item></list></paragraph>
+  <paragraph>Because a goto statement unconditionally transfers control elsewhere, the end point of a goto statement is never reachable. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/15.9.4.xml b/mcs/docs/ecma334/15.9.4.xml
new file mode 100644 (file)
index 0000000..9c34711
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<clause number="15.9.4" title="The return statement">
+  <paragraph>The return statement returns control to the caller of the function member in which the return statement appears. <grammar_production><name><non_terminal where="15.9.4">return-statement</non_terminal></name> : <rhs><keyword>return</keyword><non_terminal where="14.14">expression</non_terminal><opt/><terminal>;</terminal></rhs></grammar_production></paragraph>
+  <paragraph>A return statement with no expression can be used only in a function member that does not compute a value; that is, a method with the return type <keyword>void</keyword>, the set accessor of a property or indexer, the add and remove accessors of an event, an instance constructor, static constructor, or a destructor. </paragraph>
+  <paragraph>A return statement with an expression can only be used in a function member that computes a value, that is, a method with a non-void return type, the get accessor of a property or indexer, or a user-defined operator. An implicit conversion (<hyperlink>13.1</hyperlink>) must exist from the type of the expression to the return type of the containing function member. </paragraph>
+  <paragraph>It is a compile-time error for a return statement to appear in a finally block (<hyperlink>15.10</hyperlink>). </paragraph>
+  <paragraph>A return statement is executed as follows: <list><list_item> If the return statement specifies an expression, the expression is evaluated and the resulting value is converted to the return type of the containing function member by an implicit conversion. The result of the conversion becomes the value returned to the caller. </list_item><list_item> If the return statement is enclosed by one or more try blocks with associated finally blocks, control is initially transferred to the finally block of the innermost try statement. When and if control reaches the end point of a finally block, control is transferred to the finally block of the next enclosing try statement. This process is repeated until the finally blocks of all enclosing try statements have been executed. </list_item><list_item> Control is returned to the caller of the containing function member. </list_item></list></paragraph>
+  <paragraph>Because a return statement unconditionally transfers control elsewhere, the end point of a return statement is never reachable. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/15.9.5.xml b/mcs/docs/ecma334/15.9.5.xml
new file mode 100644 (file)
index 0000000..d32d604
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<clause number="15.9.5" title="The throw statement">
+  <paragraph>The throw statement throws an exception. <grammar_production><name><non_terminal where="15.9.5">throw-statement</non_terminal></name> : <rhs><keyword>throw</keyword><non_terminal where="14.14">expression</non_terminal><opt/><terminal>;</terminal></rhs></grammar_production></paragraph>
+  <paragraph>A throw statement with an expression throws the value produced by evaluating the expression. The expression must denote a value of the class type System.Exception or of a class type that derives from System.Exception. If evaluation of the expression produces null, a System.NullReferenceException is thrown instead. </paragraph>
+  <paragraph>A throw statement with no expression can be used only in a catch block, in which case, that statement  re-throws the exception that is currently being handled by that catch block. </paragraph>
+  <paragraph>Because a throw statement unconditionally transfers control elsewhere, the end point of a throw statement is never reachable. </paragraph>
+  <paragraph>When an exception is thrown, control is transferred to the first catch clause in an enclosing try statement that can handle the exception. The process that takes place from the point of the exception being thrown to the point of transferring control to a suitable exception handler is known as exception propagation. Propagation of an exception consists of repeatedly evaluating the following steps until a catch clause that matches the exception is found. In this description, the throw point is initially the location at which the exception is thrown. <list><list_item> In the current function member, each try statement that encloses the throw point is examined. For each statement S, starting with the innermost try statement and ending with the outermost try statement, the following steps are evaluated: </list_item><list><list_item> If the try block of S encloses the throw point and if S has one or more catch clauses, the catch clauses are examined in order of appearance to locate a suitable handler for the exception. The first catch clause that specifies the exception type or a base type of the exception type is considered a match. A general catch (<hyperlink>15.10</hyperlink>) clause is considered a match for any exception type. If a matching catch clause is located, the exception propagation is completed by transferring control to the block of that catch clause. </list_item><list_item> Otherwise, if the try block or a catch block of S encloses the throw point and if S has a finally block, control is transferred to the finally block. If the finally block throws another exception, processing of the current exception is terminated. Otherwise, when control reaches the end point of the finally block, processing of the current exception is continued. </list_item></list><list_item> If an exception handler was not located in the current function member invocation, the function member invocation is terminated. The steps above are then repeated for the caller of the function member with a throw point corresponding to the statement from which the function member was invoked. </list_item><list_item> If the exception processing terminates all function member invocations in the current thread, indicating that the thread has no handler for the exception, then the thread is itself terminated. The impact of such termination is implementation-defined. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/15.9.xml b/mcs/docs/ecma334/15.9.xml
new file mode 100644 (file)
index 0000000..d46556d
--- /dev/null
@@ -0,0 +1,40 @@
+<?xml version="1.0"?>
+<clause number="15.9" title="Jump statements">
+  <paragraph>Jump statements unconditionally transfer control. <grammar_production><name><non_terminal where="15.9">jump-statement</non_terminal></name> : <rhs><non_terminal where="15.9.1">break-statement</non_terminal></rhs><rhs><non_terminal where="15.9.2">continue-statement</non_terminal></rhs><rhs><non_terminal where="15.9.3">goto-statement</non_terminal></rhs><rhs><non_terminal where="15.9.4">return-statement</non_terminal></rhs><rhs><non_terminal where="15.9.5">throw-statement</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>The location to which a jump statement transfers control is called the target of the jump statement. </paragraph>
+  <paragraph>When a jump statement occurs within a block, and the target of that jump statement is outside that block, the jump statement is said to exit the block. While a jump statement may transfer control out of a block, it can never transfer control into a block. </paragraph>
+  <paragraph>Execution of jump statements is complicated by the presence of intervening try statements. In the absence of such try statements, a jump statement unconditionally transfers control from the jump statement to its target. In the presence of such intervening try statements, execution is more complex. If the jump statement exits one or more try blocks with associated finally blocks, control is initially transferred to the finally block of the innermost try statement. When and if control reaches the end point of a finally block, control is transferred to the finally block of the next enclosing try statement. This process is repeated until the finally blocks of all intervening try statements have been executed. </paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+using System;  
+class Test  
+{  
+   static void Main() {  
+      while (true) {  
+         try {  
+            try {  
+               Console.WriteLine("Before break");  
+               break;  
+            }  
+            finally {  
+               Console.WriteLine("Innermost finally block");  
+            }  
+         }  
+         finally {  
+            Console.WriteLine("Outermost finally block");  
+         }  
+      }  
+      Console.WriteLine("After break");  
+   }  
+}  
+]]></code_example>the finally blocks associated with two try statements are executed before control is transferred to the target of the jump statement. </example>
+  </paragraph>
+  <paragraph>
+    <example>The output produced is as follows: <code_example><![CDATA[
+Before break  
+Innermost finally block  
+Outermost finally block  
+After break  
+]]></code_example>end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/15.xml b/mcs/docs/ecma334/15.xml
new file mode 100644 (file)
index 0000000..73c71df
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<clause number="15" title="Statements">
+  <paragraph>C# provides a variety of statements. <note>[Note: Most of these statements will be familiar to developers who have programmed in C and C++. end note]</note> <grammar_production><name>statement</name> : <rhs><non_terminal where="15.4">labeled-statement</non_terminal></rhs><rhs><non_terminal where="15.5">declaration-statement</non_terminal></rhs><rhs><non_terminal where="15">embedded-statement</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="15">embedded-statement</non_terminal></name> : <rhs><non_terminal where="15.2">block</non_terminal></rhs><rhs><non_terminal where="15.3">empty-statement</non_terminal></rhs><rhs><non_terminal where="15.6">expression-statement</non_terminal></rhs><rhs><non_terminal where="15.7">selection-statement</non_terminal></rhs><rhs><non_terminal where="15.8">iteration-statement</non_terminal></rhs><rhs><non_terminal where="15.9">jump-statement</non_terminal></rhs><rhs><non_terminal where="15.10">try-statement</non_terminal></rhs><rhs><non_terminal where="15.11">checked-statement</non_terminal></rhs><rhs><non_terminal where="15.11">unchecked-statement</non_terminal></rhs><rhs><non_terminal where="15.12">lock-statement</non_terminal></rhs><rhs><non_terminal where="15.13">using-statement</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>The <non_terminal where="15">embedded-statement</non_terminal> nonterminal is used for statements that appear within other statements. The use of <non_terminal where="15">embedded-statement</non_terminal> rather than statement excludes the use of declaration statements and labeled statements in these contexts. <example>[Example: The code <code_example><![CDATA[
+void F(bool b) {  
+   if (b)  
+   int i = 44;  
+}  
+]]></code_example>results in a compile-time error because an if statement requires an <non_terminal where="15">embedded-statement</non_terminal> rather than a statement for its if branch. If this code were permitted, then the variable i would be declared, but it could never be used. (Note, however, that by placing i's declaration in a block, the example is valid.) end example]</example> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/16.1.xml b/mcs/docs/ecma334/16.1.xml
new file mode 100644 (file)
index 0000000..72467f9
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<clause number="16.1" title="Compilation units">
+  <paragraph>A <non_terminal where="16.1">compilation-unit</non_terminal> defines the overall structure of a source file. A compilation unit consists of zero or more <non_terminal where="16.3">using-directive</non_terminal>s followed by zero or more <non_terminal where="24.2">global-attributes</non_terminal> followed by zero or more  <non_terminal where="16.4">namespace-member-declaration</non_terminal>s. <grammar_production><name><non_terminal where="16.1">compilation-unit</non_terminal></name> : <rhs><non_terminal where="16.3">using-directives</non_terminal><opt/><non_terminal where="24.2">global-attributes</non_terminal><opt/><non_terminal where="16.4">namespace-member-declarations</non_terminal><opt/></rhs></grammar_production></paragraph>
+  <paragraph>A C# program consists of one or more compilation units, each contained in a separate source file. When a C# program is compiled, all of the compilation units are processed together. Thus, compilation units can depend on each other, possibly in a circular fashion. </paragraph>
+  <paragraph>The <non_terminal where="16.3">using-directive</non_terminal>s of a compilation unit affect the <non_terminal where="24.2">global-attributes</non_terminal> and <non_terminal where="16.4">namespace-member-declaration</non_terminal>s of that compilation unit, but have no effect on other compilation units. </paragraph>
+  <paragraph>The <non_terminal where="24.2">global-attributes</non_terminal> (<hyperlink>24</hyperlink>) of a compilation unit permit the specification of attributes for the target assembly. Assemblies act as physical containers for types. </paragraph>
+  <paragraph>The <non_terminal where="16.4">namespace-member-declaration</non_terminal>s of each compilation unit of a program contribute members to a single declaration space called the global namespace. <example>[Example: For example: File A.cs: <code_example><![CDATA[
+class A {}  
+]]></code_example></example></paragraph>
+  <paragraph>
+    <example>File B.cs: <code_example><![CDATA[
+class B {}  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>The two compilation units contribute to the single global namespace, in this case declaring two classes with the fully qualified names A and B. Because the two compilation units contribute to the same declaration space, it would have been an error if each contained a declaration of a member with the same name. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/16.2.xml b/mcs/docs/ecma334/16.2.xml
new file mode 100644 (file)
index 0000000..ab379d3
--- /dev/null
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<clause number="16.2" title="Namespace declarations">
+  <paragraph>A <non_terminal where="16.2">namespace-declaration</non_terminal> consists of the keyword namespace, followed by a namespace name and body, optionally followed by a semicolon. <grammar_production><name><non_terminal where="16.2">namespace-declaration</non_terminal></name> : <rhs><keyword>namespace</keyword><non_terminal where="16.2">qualified-identifier</non_terminal><non_terminal where="16.2">namespace-body</non_terminal><terminal>;</terminal><opt/></rhs></grammar_production><grammar_production><name><non_terminal where="16.2">qualified-identifier</non_terminal></name> : <rhs><non_terminal where="9.4.2">identifier</non_terminal></rhs><rhs><non_terminal where="16.2">qualified-identifier</non_terminal><terminal>.</terminal><non_terminal where="9.4.2">identifier</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="16.2">namespace-body</non_terminal></name> : <rhs><terminal>{</terminal><non_terminal where="16.3">using-directives</non_terminal><opt/><non_terminal where="16.4">namespace-member-declarations</non_terminal><opt/><terminal>}</terminal></rhs></grammar_production></paragraph>
+  <paragraph>A <non_terminal where="16.2">namespace-declaration</non_terminal> may occur as a top-level declaration in a <non_terminal where="16.1">compilation-unit</non_terminal> or as a member declaration within another <non_terminal where="16.2">namespace-declaration</non_terminal>. When a <non_terminal where="16.2">namespace-declaration</non_terminal> occurs as a top-level declaration in a <non_terminal where="16.1">compilation-unit</non_terminal>, the namespace becomes a member of the global namespace. When a <non_terminal where="16.2">namespace-declaration</non_terminal> occurs within another <non_terminal where="16.2">namespace-declaration</non_terminal>, the inner namespace becomes a member of the outer namespace. In either case, the name of a namespace must be unique within the containing namespace. </paragraph>
+  <paragraph>Namespaces are implicitly public and the declaration of a namespace cannot include any access modifiers. </paragraph>
+  <paragraph>Within a <non_terminal where="16.2">namespace-body</non_terminal>, the optional <non_terminal where="16.3">using-directive</non_terminal>s import the names of other namespaces and types, allowing them to be referenced directly instead of through qualified names. The optional  <non_terminal where="16.4">namespace-member-declaration</non_terminal>s contribute members to the declaration space of the namespace. Note that all  <non_terminal where="16.3">using-directive</non_terminal>s must appear before any member declarations. </paragraph>
+  <paragraph>The <non_terminal where="16.2">qualified-identifier</non_terminal> of a <non_terminal where="16.2">namespace-declaration</non_terminal> may be a single identifier or a sequence of identifiers separated by &quot;.&quot; tokens. The latter form permits a program to define a nested namespace without lexically nesting several namespace declarations. <example>[Example: For example, <code_example><![CDATA[
+namespace N1.N2  
+{  
+   class A {}  
+   class B {}  
+}  
+]]></code_example>is semantically equivalent to <code_example><![CDATA[
+namespace N1  
+{  
+   namespace N2  
+   {  
+      class A {}  
+      class B {}  
+   }  
+}  
+]]></code_example>end example]</example> </paragraph>
+  <paragraph>Namespaces are open-ended, and two namespace declarations with the same fully qualified name contribute to the same declaration space (<hyperlink>10.3</hyperlink>). <example>[Example: In the example <code_example><![CDATA[
+namespace N1.N2  
+{  
+   class A {}  
+}  
+namespace N1.N2  
+{  
+   class B {}  
+}  
+]]></code_example>the two namespace declarations above contribute to the same declaration space, in this case declaring two classes with the fully qualified names N1.N2.A and N1.N2.B. Because the two declarations contribute to the same declaration space, it would have been an error if each contained a declaration of a member with the same name. end example]</example> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/16.3.1.xml b/mcs/docs/ecma334/16.3.1.xml
new file mode 100644 (file)
index 0000000..9d821ae
--- /dev/null
@@ -0,0 +1,96 @@
+<?xml version="1.0"?>
+<clause number="16.3.1" title="Using alias directives">
+  <paragraph>A <non_terminal where="16.3.1">using-alias-directive</non_terminal> introduces an identifier that serves as an alias for a namespace or type within the immediately enclosing compilation unit or namespace body. <grammar_production><name><non_terminal where="16.3.1">using-alias-directive</non_terminal></name> : <rhs><keyword>using</keyword><non_terminal where="9.4.2">identifier</non_terminal><terminal>=</terminal><non_terminal where="10.8">namespace-or-type-name</non_terminal><terminal>;</terminal></rhs></grammar_production></paragraph>
+  <paragraph>Within member declarations in a compilation unit or namespace body that contains a <non_terminal where="16.3.1">using-alias-directive</non_terminal>, the identifier introduced by the <non_terminal where="16.3.1">using-alias-directive</non_terminal> can be used to reference the given namespace or type. </paragraph>
+  <paragraph>
+    <example>[Example: For example: <code_example><![CDATA[
+namespace N1.N2  
+{  
+   class A {}  
+}  
+namespace N3  
+{  
+   using A = N1.N2.A;  
+   class B: A {}  
+}  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>Above, within member declarations in the N3 namespace, A is an alias for N1.N2.A, and thus class N3.B derives from class N1.N2.A. The same effect can be obtained by creating an alias R for N1.N2 and then referencing R.A: <code_example><![CDATA[
+namespace N3  
+{  
+   using R = N1.N2;  
+   class B: R.A {}  
+}  
+]]></code_example>end example]</example>
+  </paragraph>
+  <paragraph>The identifier of a <non_terminal where="16.3.1">using-alias-directive</non_terminal> must be unique within the declaration space of the compilation unit or namespace that immediately contains the <non_terminal where="16.3.1">using-alias-directive</non_terminal>. <example>[Example: For example: <code_example><![CDATA[
+namespace N3  
+{  
+   class A {}  
+}  
+namespace N3  
+{  
+   using A = N1.N2.A;    // Error, A already exists  
+}  
+]]></code_example></example></paragraph>
+  <paragraph><example>Above, N3 already contains a member A, so it is a compile-time error for a <non_terminal where="16.3.1">using-alias-directive</non_terminal> to use that identifier. end example]</example> Likewise, it is a compile-time error for two or more <non_terminal where="16.3.1">using-alias-directive</non_terminal>s in the same compilation unit or namespace body to declare aliases by the same name. </paragraph>
+  <paragraph>A <non_terminal where="16.3.1">using-alias-directive</non_terminal> makes an alias available within a particular compilation unit or namespace body, but it does not contribute any new members to the underlying declaration space. In other words, a  <non_terminal where="16.3.1">using-alias-directive</non_terminal> is not transitive, but, rather, affects only the compilation unit or namespace body in which it occurs. </paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+namespace N3  
+{  
+   using R = N1.N2;  
+}  
+namespace N3  
+{  
+   class B: R.A {}      // Error, R unknown  
+}  
+]]></code_example>the scope of the <non_terminal where="16.3.1">using-alias-directive</non_terminal> that introduces R only extends to member declarations in the namespace body in which it is contained, so R is unknown in the second namespace declaration. However, placing the <non_terminal where="16.3.1">using-alias-directive</non_terminal> in the containing compilation unit causes the alias to become available within both namespace declarations: <code_example><![CDATA[
+using R = N1.N2;  
+namespace N3  
+{  
+   class B: R.A {}  
+}  
+namespace N3  
+{  
+   class C: R.A {}  
+}  
+]]></code_example>end example]</example>
+  </paragraph>
+  <paragraph>Just like regular members, names introduced by <non_terminal where="16.3.1">using-alias-directive</non_terminal>s are hidden by similarly named members in nested scopes. <example>[Example: In the example <code_example><![CDATA[
+using R = N1.N2;  
+namespace N3  
+{  
+   class R {}  
+   class B: R.A {}    // Error, R has no member A  
+}  
+]]></code_example>the reference to R.A in the declaration of B causes a compile-time error because R refers to N3.R, not N1.N2. end example]</example> </paragraph>
+  <paragraph>The order in which <non_terminal where="16.3.1">using-alias-directive</non_terminal>s are written has no significance, and resolution of the  <non_terminal where="10.8">namespace-or-type-name</non_terminal> referenced by a <non_terminal where="16.3.1">using-alias-directive</non_terminal> is not affected by the <non_terminal where="16.3.1">using-alias-directive</non_terminal> itself or by other <non_terminal where="16.3">using-directive</non_terminal>s in the immediately containing compilation unit or namespace body. In other words, the <non_terminal where="10.8">namespace-or-type-name</non_terminal> of a <non_terminal where="16.3.1">using-alias-directive</non_terminal> is resolved as if the immediately containing compilation unit or namespace body had no <non_terminal where="16.3">using-directive</non_terminal>s. <example>[Example: In the example <code_example><![CDATA[
+namespace N1.N2 {}  
+namespace N3  
+{  
+   using R1 = N1;   // OK  
+   using R2 = N1.N2;   // OK  
+   using R3 = R1.N2;   // Error, R1 unknown  
+}  
+]]></code_example>the last <non_terminal where="16.3.1">using-alias-directive</non_terminal> results in a compile-time error because it is not affected by the first  <non_terminal where="16.3.1">using-alias-directive</non_terminal>. end example]</example> </paragraph>
+  <paragraph>A <non_terminal where="16.3.1">using-alias-directive</non_terminal> can create an alias for any namespace or type, including the namespace within which it appears and any namespace or type nested within that namespace. </paragraph>
+  <paragraph>Accessing a namespace or type through an alias yields exactly the same result as accessing that namespace or type through its declared name. <example>[Example: For example, given <code_example><![CDATA[
+namespace N1.N2  
+{  
+   class A {}  
+}  
+namespace N3  
+{  
+   using R1 = N1;  
+   using R2 = N1.N2;  
+   class B  
+   {  
+      N1.N2.A a;    // refers to N1.N2.A  
+      R1.N2.A b;    // refers to N1.N2.A  
+      R2.A c;     // refers to N1.N2.A  
+   }  
+}  
+]]></code_example>the names N1.N2.A, R1.N2.A, and R2.A are equivalent and all refer to the class whose fully qualified name is N1.N2.A. end example]</example> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/16.3.2.xml b/mcs/docs/ecma334/16.3.2.xml
new file mode 100644 (file)
index 0000000..49a9849
--- /dev/null
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<clause number="16.3.2" title="Using namespace directives">
+  <paragraph>A <non_terminal where="16.3.2">using-namespace-directive</non_terminal> imports the types contained in a namespace into the immediately enclosing compilation unit or namespace body, enabling the identifier of each type to be used without qualification. <grammar_production><name><non_terminal where="16.3.2">using-namespace-directive</non_terminal></name> : <rhs><keyword>using</keyword><non_terminal where="10.8">namespace-name</non_terminal><terminal>;</terminal></rhs></grammar_production></paragraph>
+  <paragraph>Within member declarations in a compilation unit or namespace body that contains a  <non_terminal where="16.3.2">using-namespace-directive</non_terminal>, the types contained in the given namespace can be referenced directly. <example>[Example: For example: <code_example><![CDATA[
+namespace N1.N2  
+{  
+   class A {}  
+}  
+namespace N3  
+{  
+   using N1.N2;  
+   class B: A {}  
+}  
+]]></code_example></example></paragraph>
+  <paragraph>
+    <example>Above, within member declarations in the N3 namespace, the type members of N1.N2 are directly available, and thus class N3.B derives from class N1.N2.A. end example]</example>
+  </paragraph>
+  <paragraph>A <non_terminal where="16.3.2">using-namespace-directive</non_terminal> imports the types contained in the given namespace, but specifically does not import nested namespaces. <example>[Example: In the example <code_example><![CDATA[
+namespace N1.N2  
+{  
+   class A {}  
+}  
+namespace N3  
+{  
+   using N1;  
+   class B: N2.A {}    // Error, N2 unknown  
+}  
+]]></code_example>the <non_terminal where="16.3.2">using-namespace-directive</non_terminal> imports the types contained in N1, but not the namespaces nested in N1. Thus, the reference to N2.A in the declaration of B results in a compile-time error because no members named N2 are in scope. end example]</example> </paragraph>
+  <paragraph>Unlike a <non_terminal where="16.3.1">using-alias-directive</non_terminal>, a <non_terminal where="16.3.2">using-namespace-directive</non_terminal> may import types whose identifiers are already defined within the enclosing compilation unit or namespace body. In effect, names imported by a  <non_terminal where="16.3.2">using-namespace-directive</non_terminal> are hidden by similarly named members in the enclosing compilation unit or namespace body. <example>[Example: For example: <code_example><![CDATA[
+namespace N1.N2  
+{  
+   class A {}  
+   class B {}  
+}  
+namespace N3  
+{  
+   using N1.N2;  
+   class A {}  
+}  
+]]></code_example></example></paragraph>
+  <paragraph>
+    <example>Here, within member declarations in the N3 namespace, A refers to N3.A rather than N1.N2.A. end example]</example>
+  </paragraph>
+  <paragraph>When more than one namespace imported by <non_terminal where="16.3.2">using-namespace-directive</non_terminal>s in the same compilation unit or namespace body contain types by the same name, references to that name are considered ambiguous. </paragraph>
+  <paragraph><example>[Example: In the example <code_example><![CDATA[
+namespace N1  
+{  
+   class A {}  
+}  
+namespace N2  
+{  
+   class A {}  
+}  
+namespace N3  
+{  
+   using N1;  
+   using N2;  
+   class B: A {}     // Error, A is ambiguous  
+}  
+]]></code_example>both N1 and N2 contain a member A, and because N3 imports both, referencing A in N3 is a compile-time error. end example]</example> In this situation, the conflict can be resolved either through qualification of references to A, or by introducing a <non_terminal where="16.3.1">using-alias-directive</non_terminal> that picks a particular A. <example>[Example: For example: <code_example><![CDATA[
+namespace N3  
+{  
+   using N1;  
+   using N2;  
+   using A = N1.A;  
+   class B: A {}     // A means N1.A  
+}  
+]]></code_example>end example]</example></paragraph>
+  <paragraph>Like a <non_terminal where="16.3.1">using-alias-directive</non_terminal>, a <non_terminal where="16.3.2">using-namespace-directive</non_terminal> does not contribute any new members to the underlying declaration space of the compilation unit or namespace, but, rather, affects only the compilation unit or namespace body in which it appears. </paragraph>
+  <paragraph>The <non_terminal where="10.8">namespace-name</non_terminal> referenced by a <non_terminal where="16.3.2">using-namespace-directive</non_terminal> is resolved in the same way as the <non_terminal where="10.8">namespace-or-type-name</non_terminal> referenced by a <non_terminal where="16.3.1">using-alias-directive</non_terminal>. Thus, <non_terminal where="16.3.2">using-namespace-directive</non_terminal>s in the same compilation unit or namespace body do not affect each other and can be written in any order. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/16.3.xml b/mcs/docs/ecma334/16.3.xml
new file mode 100644 (file)
index 0000000..e281584
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<clause number="16.3" title="Using directives">
+  <paragraph>Using-directives facilitate the use of namespaces and types defined in other namespaces. Using-directives impact the name resolution process of <non_terminal where="10.8">namespace-or-type-name</non_terminal>s (<hyperlink>10.8</hyperlink>) and <non_terminal where="14.5.2">simple-name</non_terminal>s (<hyperlink>14.5.2</hyperlink>), but unlike declarations, <non_terminal where="16.3">using-directive</non_terminal>s do not contribute new members to the underlying declaration spaces of the compilation units or namespaces within which they are used. <grammar_production><name><non_terminal where="16.3">using-directive</non_terminal>s</name> : <rhs><non_terminal where="16.3">using-directive</non_terminal></rhs><rhs><non_terminal where="16.3">using-directives</non_terminal><non_terminal where="16.3">using-directive</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="16.3">using-directive</non_terminal></name> : <rhs><non_terminal where="16.3.1">using-alias-directive</non_terminal></rhs><rhs><non_terminal where="16.3.2">using-namespace-directive</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>A <non_terminal where="16.3.1">using-alias-directive</non_terminal> (<hyperlink>16.3.1</hyperlink>) introduces an alias for a namespace or type. </paragraph>
+  <paragraph>A <non_terminal where="16.3.2">using-namespace-directive</non_terminal> (<hyperlink>16.3.2</hyperlink>) imports the type members of a namespace. </paragraph>
+  <paragraph>The scope of a <non_terminal where="16.3">using-directive</non_terminal> extends over the <non_terminal where="16.4">namespace-member-declaration</non_terminal>s of its immediately containing compilation unit or namespace body. The scope of a <non_terminal where="16.3">using-directive</non_terminal> specifically does not include its peer <non_terminal where="16.3">using-directive</non_terminal>s. Thus, peer <non_terminal where="16.3">using-directive</non_terminal>s do not affect each other, and the order in which they are written is insignificant. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/16.4.xml b/mcs/docs/ecma334/16.4.xml
new file mode 100644 (file)
index 0000000..7927f94
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="16.4" title="Namespace members">
+  <paragraph>A <non_terminal where="16.4">namespace-member-declaration</non_terminal> is either a <non_terminal where="16.2">namespace-declaration</non_terminal> (<hyperlink>16.2</hyperlink>) or a <non_terminal where="16.5">type-declaration</non_terminal> (<hyperlink>16.5</hyperlink>). <grammar_production><name><non_terminal where="16.4">namespace-member-declaration</non_terminal>s</name> : <rhs><non_terminal where="16.4">namespace-member-declaration</non_terminal></rhs><rhs><non_terminal where="16.4">namespace-member-declarations</non_terminal><non_terminal where="16.4">namespace-member-declaration</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="16.4">namespace-member-declaration</non_terminal></name> : <rhs><non_terminal where="16.2">namespace-declaration</non_terminal></rhs><rhs><non_terminal where="16.5">type-declaration</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>A compilation unit or a namespace body can contain <non_terminal where="16.4">namespace-member-declaration</non_terminal>s, and such declarations contribute new members to the underlying declaration space of the containing compilation unit or namespace body. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/16.5.xml b/mcs/docs/ecma334/16.5.xml
new file mode 100644 (file)
index 0000000..d939a63
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<clause number="16.5" title="Type declarations">
+  <paragraph>A <non_terminal where="16.5">type-declaration</non_terminal> is a <non_terminal where="17.1">class-declaration</non_terminal> (<hyperlink>17.1</hyperlink>), a <non_terminal where="18.1">struct-declaration</non_terminal> (<hyperlink>18.1</hyperlink>), an <non_terminal where="20.1">interface-declaration</non_terminal> (<hyperlink>20.1</hyperlink>), an <non_terminal where="21.1">enum-declaration</non_terminal> (<hyperlink>21.1</hyperlink>), or a <non_terminal where="22.1">delegate-declaration</non_terminal> (<hyperlink>22.1</hyperlink>). <grammar_production><name><non_terminal where="16.5">type-declaration</non_terminal></name> : <rhs><non_terminal where="17.1">class-declaration</non_terminal></rhs><rhs><non_terminal where="18.1">struct-declaration</non_terminal></rhs><rhs><non_terminal where="20.1">interface-declaration</non_terminal></rhs><rhs><non_terminal where="21.1">enum-declaration</non_terminal></rhs><rhs><non_terminal where="22.1">delegate-declaration</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>A <non_terminal where="16.5">type-declaration</non_terminal> can occur as a top-level declaration in a compilation unit or as a member declaration within a namespace, class, or struct. </paragraph>
+  <paragraph>When a type declaration for a type T occurs as a top-level declaration in a compilation unit, the fully qualified name of the newly declared type is simply T. When a type declaration for a type T occurs within a namespace, class, or struct, the fully qualified name of the newly declared type is N.T, where N is the fully qualified name of the containing namespace, class, or struct. </paragraph>
+  <paragraph>A type declared within a class or struct is called a nested type (<hyperlink>17.2.6</hyperlink>). </paragraph>
+  <paragraph>The permitted access modifiers and the default access for a type declaration depend on the context in which the declaration takes place (<hyperlink>10.5.1</hyperlink>): <list><list_item> Types declared in compilation units or namespaces can have public or internal access. The default is internal access. </list_item><list_item> Types declared in classes can have public, protected internal, protected, internal, or private access. The default is private access. </list_item><list_item> Types declared in structs can have public, internal, or private access. The default is private access. <table_line/>
+</list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/16.xml b/mcs/docs/ecma334/16.xml
new file mode 100644 (file)
index 0000000..68fd578
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="16" title="Namespaces">
+  <paragraph>C# programs are organized using namespaces. Namespaces are used both as an &quot;internal&quot; organization system for a program, and as an &quot;external&quot; organization system-a way of presenting program elements that are exposed to other programs. </paragraph>
+  <paragraph>Using-directives (<hyperlink>16.3</hyperlink>) are provided to facilitate the use of namespaces. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.1.1.1.xml b/mcs/docs/ecma334/17.1.1.1.xml
new file mode 100644 (file)
index 0000000..1cd44b2
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<clause number="17.1.1.1" title="Abstract classes">
+  <paragraph>The abstract modifier is used to indicate that a class is incomplete and that it is intended to be used only as a base class. An abstract class differs from a non-abstract class in the following ways: <list><list_item> An abstract class cannot be instantiated directly, and it is a compile-time error to use the new operator on an abstract class. While it is possible to have variables and values whose compile-time types are abstract, such variables and values will necessarily either be null or contain references to instances of non-abstract classes derived from the abstract types. </list_item><list_item> An abstract class is permitted (but not required) to contain abstract members. </list_item><list_item> An abstract class cannot be sealed. </list_item></list></paragraph>
+  <paragraph>When a non-abstract class is derived from an abstract class, the non-abstract class must include actual implementations of all inherited abstract members, thereby overriding those abstract members. <example>[Example: In the example <code_example><![CDATA[
+abstract class A  
+{  
+   public abstract void F();  
+}  
+abstract class B: A  
+{  
+   public void G() {}  
+}  
+class C: B  
+{  
+   public override void F() {  
+      // actual implementation of F  
+   }  
+}  
+]]></code_example>the abstract class A introduces an abstract method F. Class B introduces an additional method G, but since it doesn't provide an implementation of F, B must also be declared abstract. Class C overrides F and provides an actual implementation. Since there are no abstract members in C, C is permitted (but not required) to be non-abstract. end example]</example> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.1.1.2.xml b/mcs/docs/ecma334/17.1.1.2.xml
new file mode 100644 (file)
index 0000000..a63ac49
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<clause number="17.1.1.2" title="Sealed classes">
+  <paragraph>The sealed modifier is used to prevent derivation from a class. A compile-time error occurs if a sealed class is specified as the base class of another class. </paragraph>
+  <paragraph>A sealed class cannot also be an abstract class. </paragraph>
+  <paragraph>
+    <note>[Note: The sealed modifier is primarily used to prevent unintended derivation, but it also enables certain run-time optimizations. In particular, because a sealed class is known to never have any derived classes, it is possible to transform virtual function member invocations on sealed class instances into non-virtual invocations. end note]</note>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.1.1.xml b/mcs/docs/ecma334/17.1.1.xml
new file mode 100644 (file)
index 0000000..eddd40b
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<clause number="17.1.1" title="Class modifiers">
+  <paragraph>A <non_terminal where="17.1">class-declaration</non_terminal> may optionally include a sequence of class modifiers: <grammar_production><name><non_terminal where="17.1.1">class-modifier</non_terminal>s</name> : <rhs><non_terminal where="17.1.1">class-modifier</non_terminal></rhs><rhs><non_terminal where="17.1.1">class-modifiers</non_terminal><non_terminal where="17.1.1">class-modifier</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.1.1">class-modifier</non_terminal></name> : <rhs><keyword>new</keyword></rhs><rhs><keyword>public</keyword></rhs><rhs><keyword>protected</keyword></rhs><rhs><keyword>internal</keyword></rhs><rhs><keyword>private</keyword></rhs><rhs><keyword>abstract</keyword></rhs><rhs><keyword>sealed</keyword></rhs></grammar_production></paragraph>
+  <paragraph>It is a compile-time error for the same modifier to appear multiple times in a class declaration. </paragraph>
+  <paragraph>The new modifier is permitted on nested classes. It specifies that the class hides an inherited member by the same name, as described in <hyperlink>10.2.2</hyperlink>. It is a compile-time error for the new modifier to appear on a class declaration that is not a nested class declaration. </paragraph>
+  <paragraph>The public, protected, internal, and private modifiers control the accessibility of the class. Depending on the context in which the class declaration occurs, some of these modifiers may not be permitted (<hyperlink>10.5.1</hyperlink>). </paragraph>
+  <paragraph>The abstract and sealed modifiers are discussed in the following sections. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.1.2.1.xml b/mcs/docs/ecma334/17.1.2.1.xml
new file mode 100644 (file)
index 0000000..02e7bd6
--- /dev/null
@@ -0,0 +1,41 @@
+<?xml version="1.0"?>
+<clause number="17.1.2.1" title="Base classes">
+  <paragraph>When a <non_terminal where="11.2">class-type</non_terminal> is included in the <non_terminal where="17.1.2">class-base</non_terminal>, it specifies the direct base class of the class being declared. If a class declaration has no <non_terminal where="17.1.2">class-base</non_terminal>, or if the <non_terminal where="17.1.2">class-base</non_terminal> lists only interface types, the direct base class is assumed to be object. A class inherits members from its direct base class, as described in <hyperlink>17.2.1</hyperlink>. </paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+class A {}  
+class B: A {}  
+]]></code_example>class A is said to be the direct base class of B, and B is said to be derived from A. Since A does not explicitly specify a direct base class, its direct base class is implicitly object. end example]</example>
+  </paragraph>
+  <paragraph>The direct base class of a class type must be at least as accessible as the class type itself (<hyperlink>10.5.4</hyperlink>). For example, it is a compile-time error for a public class to derive from a private or internal class. </paragraph>
+  <paragraph>The direct base class of a class type must not be any of the following types: System.Array, System.Delegate, System.Enum, or System.ValueType. </paragraph>
+  <paragraph>The base classes of a class are the direct base class and its base classes. In other words, the set of base classes is the transitive closure of the direct base class relationship. <note>[Note: Referring to the example above, the base classes of B are A and object. end note]</note> </paragraph>
+  <paragraph>Except for class object, every class has exactly one direct base class. The object class has no direct base class and is the ultimate base class of all other classes. </paragraph>
+  <paragraph>When a class B derives from a class A, it is a compile-time error for A to depend on B. A class directly depends on its direct base class (if any) and directly depends on the class within which it is immediately nested (if any). Given this definition, the complete set of classes upon which a class depends is the transitive closure of the directly depends on relationship. </paragraph>
+  <paragraph>
+    <example>[Example: The example <code_example><![CDATA[
+class A: B {}  
+class B: C {}  
+class C: A {}  
+]]></code_example>is in error because the classes circularly depend on themselves. Likewise, the example <code_example><![CDATA[
+class A: B.C {}  
+class B: A  
+{  
+   public class C {}  
+}  
+]]></code_example>results in a compile-time error because A depends on B.C (its direct base class), which depends on B (its immediately enclosing class), which circularly depends on A. end example]</example>
+  </paragraph>
+  <paragraph>Note that a class does not depend on the classes that are nested within it. <example>[Example: In the example <code_example><![CDATA[
+class A  
+{  
+   class B: A {}  
+}  
+]]></code_example></example></paragraph>
+  <paragraph>
+    <example>B depends on A (because A is both its direct base class and its immediately enclosing class), but A does not depend on B (since B is neither a base class nor an enclosing class of A). Thus, the example is valid. end example]</example>
+  </paragraph>
+  <paragraph>It is not possible to derive from a sealed class. <example>[Example: In the example <code_example><![CDATA[
+sealed class A {}  
+class B: A {}      // Error, cannot derive from a sealed class  
+]]></code_example>class B results in a compile-time error because it attempts to derive from the sealed class A. end example]</example> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.1.2.2.xml b/mcs/docs/ecma334/17.1.2.2.xml
new file mode 100644 (file)
index 0000000..ff3c651
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="17.1.2.2" title="Interface implementations">
+  <paragraph>A <non_terminal where="17.1.2">class-base</non_terminal> specification may include a list of interface types, in which case the class is said to implement the given interface types. Interface implementations are discussed further in <hyperlink>20.4</hyperlink>. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.1.2.xml b/mcs/docs/ecma334/17.1.2.xml
new file mode 100644 (file)
index 0000000..44fac12
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="17.1.2" title="Class base specification">
+  <paragraph>A class declaration may include a <non_terminal where="17.1.2">class-base</non_terminal> specification, which defines the direct base class of the class and the interfaces (<hyperlink>20</hyperlink>) implemented by the class. <grammar_production><name><non_terminal where="17.1.2">class-base</non_terminal></name> : <rhs><terminal>:</terminal><non_terminal where="11.2">class-type</non_terminal></rhs><rhs><terminal>:</terminal><non_terminal where="17.1.2">interface-type-list</non_terminal></rhs><rhs><terminal>:</terminal><non_terminal where="11.2">class-type</non_terminal><terminal>,</terminal><non_terminal where="17.1.2">interface-type-list</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.1.2">interface-type-list</non_terminal></name> : <rhs><non_terminal where="11.2">interface-type</non_terminal></rhs><rhs><non_terminal where="17.1.2">interface-type-list</non_terminal><terminal>,</terminal><non_terminal where="11.2">interface-type</non_terminal></rhs></grammar_production></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.1.3.xml b/mcs/docs/ecma334/17.1.3.xml
new file mode 100644 (file)
index 0000000..48ed3b5
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="17.1.3" title="Class body">
+  <paragraph>The <non_terminal where="17.1.3">class-body</non_terminal> of a class defines the members of that class. <grammar_production><name><non_terminal where="17.1.3">class-body</non_terminal></name> : <rhs><terminal>{</terminal><non_terminal where="17.2">class-member-declarations</non_terminal><opt/><terminal>}</terminal></rhs></grammar_production></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.1.xml b/mcs/docs/ecma334/17.1.xml
new file mode 100644 (file)
index 0000000..53b3798
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="17.1" title="Class declarations">
+  <paragraph>A <non_terminal where="17.1">class-declaration</non_terminal> is a <non_terminal where="16.5">type-declaration</non_terminal> (<hyperlink>16.5</hyperlink>) that declares a new class. <grammar_production><name><non_terminal where="17.1">class-declaration</non_terminal></name> : <rhs><non_terminal where="24.2">attributes</non_terminal><opt/><non_terminal where="17.1.1">class-modifiers</non_terminal><opt/><keyword>class</keyword><non_terminal where="9.4.2">identifier</non_terminal><non_terminal where="17.1.2">class-base</non_terminal><opt/><non_terminal where="17.1.3">class-body</non_terminal><terminal>;</terminal><opt/></rhs></grammar_production></paragraph>
+  <paragraph>A <non_terminal where="17.1">class-declaration</non_terminal> consists of an optional set of attributes (<hyperlink>24</hyperlink>), followed by an optional set of  <non_terminal where="17.1.1">class-modifier</non_terminal>s (<hyperlink>17.1.1</hyperlink>), followed by the keyword class and an identifier that names the class, followed by an optional <non_terminal where="17.1.2">class-base</non_terminal> specification (<hyperlink>17.1.2</hyperlink>), followed by a <non_terminal where="17.1.3">class-body</non_terminal> (<hyperlink>17.1.3</hyperlink>), optionally followed by a semicolon. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.10.1.xml b/mcs/docs/ecma334/17.10.1.xml
new file mode 100644 (file)
index 0000000..dae01ac
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<clause number="17.10.1" title="Constructor initializers">
+  <paragraph>All instance constructors (except those for class object) implicitly include an invocation of another instance constructor immediately before the <non_terminal where="17.10">constructor-body</non_terminal>. The constructor to implicitly invoke is determined by the constructor-initializer: <list><list_item> An instance constructor initializer of the form base(argument-listopt) causes an instance constructor from the direct base class to be invoked. That constructor is selected using <non_terminal where="14.4.1">argument-list</non_terminal> and the overload resolution rules of <hyperlink>14.4.2</hyperlink>. The set of candidate instance constructors consists of all accessible instance constructors declared in the direct base class. If this set is empty, or if a single best instance constructor cannot be identified, a compile-time error occurs. </list_item><list_item> An instance constructor initializer of the form this(argument-listopt) causes an instance constructor from the class itself to be invoked. The constructor is selected using <non_terminal where="14.4.1">argument-list</non_terminal> and the overload resolution rules of <hyperlink>14.4.2</hyperlink>. The set of candidate instance constructors consists of all accessible instance constructors declared in the class itself. If that set is empty, or if a single best instance constructor cannot be identified, a compile-time error occurs. If an instance constructor declaration includes a constructor initializer that invokes the constructor itself, a compile-time error occurs. </list_item></list></paragraph>
+  <paragraph>If an instance constructor has no constructor initializer, a constructor initializer of the form base() is implicitly provided. <note>[Note: Thus, an instance constructor declaration of the form <code_example><![CDATA[
+C(...) {...}  
+]]></code_example>is exactly equivalent to <code_example><![CDATA[
+C(...): base() {...}  
+]]></code_example>end note]</note> </paragraph>
+  <paragraph>The scope of the parameters given by the <non_terminal where="17.5.1">formal-parameter-list</non_terminal> of an instance constructor declaration includes the constructor initializer of that declaration. Thus, a constructor initializer is permitted to access the parameters of the constructor. <example>[Example: For example: <code_example><![CDATA[
+class A  
+{  
+   public A(int x, int y) {}  
+}  
+class B: A  
+{  
+   public B(int x, int y): base(x + y, x - y) {}  
+}  
+]]></code_example>end example]</example> </paragraph>
+  <paragraph>An instance constructor initializer cannot access the instance being created. Therefore it is a compile-time error to reference this in an argument expression of the constructor initializer, as it is a compile-time error for an argument expression to reference any instance member through a <non_terminal where="14.5.2">simple-name</non_terminal>. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.10.2.xml b/mcs/docs/ecma334/17.10.2.xml
new file mode 100644 (file)
index 0000000..1719249
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="17.10.2" title="Instance variable initializers">
+  <paragraph>When an instance constructor has no constructor initializer, or it has a constructor initializer of the form base(...), that constructor implicitly performs the initializations specified by the <non_terminal where="19.6">variable-initializer</non_terminal>s of the instance fields declared in its class. This corresponds to a sequence of assignments that are executed immediately upon entry to the constructor and before the implicit invocation of the direct base class constructor. The variable initializers are executed in the textual order in which they appear in the class declaration. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.10.3.xml b/mcs/docs/ecma334/17.10.3.xml
new file mode 100644 (file)
index 0000000..13b86d5
--- /dev/null
@@ -0,0 +1,94 @@
+<?xml version="1.0"?>
+<clause number="17.10.3" title="Constructor execution">
+  <paragraph>Variable initializers are transformed into assignment statements, and these assignment statements are executed before the invocation of the base class instance constructor. This ordering ensures that all instance fields are initialized by their variable initializers before any statements that have access to that instance are executed. <example>[Example: For example: <code_example><![CDATA[
+using System;  
+class A  
+{  
+   public A() {  
+      PrintFields();  
+   }  
+   public virtual void PrintFields() {}  
+}  
+class B: A  
+{  
+   int x = 1;  
+   int y;  
+   public B() {  
+      y = -1;  
+   }  
+   public override void PrintFields() {  
+      Console.WriteLine("x = {0}, y = {1}", x, y);  
+   }  
+}  
+]]></code_example></example></paragraph>
+  <paragraph>
+    <example>When new B() is used to create an instance of B, the following output is produced: <code_example><![CDATA[
+x = 1, y = 0  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>The value of x is 1 because the variable initializer is executed before the base class instance constructor is invoked. However, the value of y is 0 (the default value of an <keyword>int</keyword>) because the assignment to y is not executed until after the base class constructor returns. </example>
+  </paragraph>
+  <paragraph>
+    <example>It is useful to think of instance variable initializers and constructor initializers as statements that are automatically inserted before the <non_terminal where="17.10">constructor-body</non_terminal>. The example <code_example><![CDATA[
+using System;  
+using System.Collections;  
+class A  
+{  
+   int x = 1, y = -1, count;  
+   public A() {  
+      count = 0;  
+   }  
+   public A(int n) {  
+      count = n;  
+   }  
+}  
+class B: A  
+{  
+   double sqrt2 = Math.Sqrt(2.0);  
+   ArrayList items = new ArrayList(100);  
+   int max;  
+   public B(): this(100) {  
+      items.Add("default");  
+   }  
+   public B(int n): base(n - 1) {  
+      max = n;  
+   }  
+}  
+]]></code_example>contains several variable initializers; it also contains constructor initializers of both forms (base and this). The example corresponds to the code shown below, where each comment indicates an automatically inserted statement (the syntax used for the automatically inserted constructor invocations isn't valid, but merely serves to illustrate the mechanism). <code_example><![CDATA[
+using System.Collections;  
+class A  
+{  
+   int x, y, count;  
+   public A() {  
+      x = 1;         // Variable initializer  
+      y = -1;         // Variable initializer  
+      object();        // Invoke object() constructor  
+      count = 0;  
+   }  
+   public A(int n) {  
+      x = 1;         // Variable initializer  
+      y = -1;         // Variable initializer  
+      object();        // Invoke object() constructor  
+      count = n;  
+   }  
+}  
+class B: A  
+{  
+   double sqrt2;  
+   ArrayList items;  
+   int max;  
+   public B(): this(100) {  
+      B(100);         // Invoke B(int) constructor  
+      items.Add("default");  
+   }  
+   public B(int n): base(n - 1) {  
+      sqrt2 = Math.Sqrt(2.0);   // Variable initializer  
+      items = new ArrayList(100);  // Variable initializer  
+      A(n - 1);        // Invoke A(int) constructor  
+      max = n;  
+   }  
+}  
+]]></code_example>end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.10.4.xml b/mcs/docs/ecma334/17.10.4.xml
new file mode 100644 (file)
index 0000000..77ea34f
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<clause number="17.10.4" title="Default constructors">
+  <paragraph>If a class contains no instance constructor declarations, a default instance constructor is automatically provided. That default constructor simply invokes the parameterless constructor of the direct base class. If the direct base class does not have an accessible parameterless instance constructor, a compile-time error occurs. If the class is abstract then the declared accessibility for the default constructor is protected. Otherwise, the declared accessibility for the default constructor is public. <note>[Note: Thus, the default constructor is always of the form <code_example><![CDATA[
+protected C(): base() {}  
+]]></code_example>or <code_example><![CDATA[
+public C(): base() {}  
+]]></code_example>where C is the name of the class. end note]</note> </paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+class Message  
+{  
+   object sender;  
+   string text;  
+}  
+]]></code_example>a default constructor is provided because the class contains no instance constructor declarations. Thus, the example is precisely equivalent to <code_example><![CDATA[
+class Message  
+{  
+   object sender;  
+   string text;  
+   public Message(): base() {}  
+}  
+]]></code_example>end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.10.5.xml b/mcs/docs/ecma334/17.10.5.xml
new file mode 100644 (file)
index 0000000..6d4f95a
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<clause number="17.10.5" title="Private constructors">
+  <paragraph>When a class declares only private instance constructors, it is not possible for other classes to derive from that class or to create instances of that class (an exception being classes nested within that class). <example>[Example: Private instance constructors are commonly used in classes that contain only static members. For example: <code_example><![CDATA[
+public class Trig  
+{  
+   private Trig() {}   // Prevent instantiation  
+   public const double PI = 3.14159265358979323846;  
+   public static double Sin(double x) {...}  
+   public static double Cos(double x) {...}  
+   public static double Tan(double x) {...}  
+}  
+]]></code_example></example></paragraph>
+  <paragraph><example>The Trig class groups related methods and constants, but is not intended to be instantiated. Therefore, it declares a single empty private instance constructor. end example]</example> At least one instance constructor must be declared to suppress the automatic generation of a default constructor. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.10.6.xml b/mcs/docs/ecma334/17.10.6.xml
new file mode 100644 (file)
index 0000000..76472a9
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<clause number="17.10.6" title="Optional instance constructor parameters">
+  <paragraph>
+    <note>[Note: The this(...) form of constructor initializer is commonly used in conjunction with overloading to implement optional instance constructor parameters. In the example <code_example><![CDATA[
+class Text  
+{  
+   public Text(): this(0, 0, null) {}  
+   public Text(int x, int y): this(x, y, null) {}  
+   public Text(int x, int y, string s) {  
+      // Actual constructor implementation  
+   }  
+}  
+]]></code_example>the first two instance constructors merely provide the default values for the missing arguments. Both use a this(...) constructor initializer to invoke the third instance constructor, which actually does the work of initializing the new instance. The effect is that of optional constructor parameters: <code_example><![CDATA[
+Text t1 = new Text();          // Same as Text(0, 0, null)  
+Text t2 = new Text(5, 10);       // Same as Text(5, 10, null)  
+Text t3 = new Text(5, 20, "Hello");  
+]]></code_example>end note]</note>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.10.xml b/mcs/docs/ecma334/17.10.xml
new file mode 100644 (file)
index 0000000..31f2892
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<clause number="17.10" title="Instance constructors">
+  <paragraph>An instance constructor is a member that implements the actions required to initialize an instance of a class. Instance constructors are declared using constructor-declarations: <grammar_production><name><non_terminal where="17.10">constructor-declaration</non_terminal></name> : <rhs><non_terminal where="24.2">attributes</non_terminal><opt/><non_terminal where="17.10">constructor-modifiers</non_terminal><opt/><non_terminal where="17.10">constructor-declarator</non_terminal><non_terminal where="17.10">constructor-body</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.10">constructor-modifier</non_terminal>s</name> : <rhs><non_terminal where="17.10">constructor-modifier</non_terminal></rhs><rhs><non_terminal where="17.10">constructor-modifiers</non_terminal><non_terminal where="17.10">constructor-modifier</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.10">constructor-modifier</non_terminal></name> : <rhs><keyword>public</keyword></rhs><rhs><keyword>protected</keyword></rhs><rhs><keyword>internal</keyword></rhs><rhs><keyword>private</keyword></rhs><rhs><keyword>extern</keyword></rhs></grammar_production><grammar_production><name><non_terminal where="17.10">constructor-declarator</non_terminal></name> : <rhs><non_terminal where="9.4.2">identifier</non_terminal><terminal>(</terminal><non_terminal where="17.5.1">formal-parameter-list</non_terminal><opt/><terminal>)</terminal><non_terminal where="17.10">constructor-initializer</non_terminal><opt/></rhs></grammar_production><grammar_production><name><non_terminal where="17.10">constructor-initializer</non_terminal></name> : <rhs><terminal>:</terminal><keyword>base</keyword><terminal>(</terminal><non_terminal where="14.4.1">argument-list</non_terminal><opt/><terminal>)</terminal></rhs><rhs><terminal>:</terminal><keyword>this</keyword><terminal>(</terminal><non_terminal where="14.4.1">argument-list</non_terminal><opt/><terminal>)</terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.10">constructor-body</non_terminal></name> : <rhs><non_terminal where="15.2">block</non_terminal></rhs><rhs><terminal>;</terminal></rhs></grammar_production></paragraph>
+  <paragraph>A <non_terminal where="17.10">constructor-declaration</non_terminal> may include a set of attributes (<hyperlink>24</hyperlink>), a valid combination of the four access modifiers (<hyperlink>17.2.3</hyperlink>), and an extern (<hyperlink>17.5.7</hyperlink>) modifier. A constructor declaration is not permitted to include the same modifier multiple times. </paragraph>
+  <paragraph>The identifier of a <non_terminal where="17.10">constructor-declarator</non_terminal> must name the class in which the instance constructor is declared. If any other name is specified, a compile-time error occurs. </paragraph>
+  <paragraph>The optional <non_terminal where="17.5.1">formal-parameter-list</non_terminal> of an instance constructor is subject to the same rules as the  <non_terminal where="17.5.1">formal-parameter-list</non_terminal> of a method (<hyperlink>17.5</hyperlink>). The formal parameter list defines the signature (<hyperlink>10.6</hyperlink>) of an instance constructor and governs the process whereby overload resolution (<hyperlink>14.4.2</hyperlink>) selects a particular instance constructor in an invocation. </paragraph>
+  <paragraph>Each of the types referenced in the <non_terminal where="17.5.1">formal-parameter-list</non_terminal> of an instance constructor must be at least as accessible as the constructor itself (<hyperlink>10.5.4</hyperlink>). </paragraph>
+  <paragraph>The optional <non_terminal where="17.10">constructor-initializer</non_terminal> specifies another instance constructor to invoke before executing the statements given in the <non_terminal where="17.10">constructor-body</non_terminal> of this instance constructor. This is described further in <hyperlink>17.10.1</hyperlink>. </paragraph>
+  <paragraph>When a constructor declaration includes an extern modifier, the constructor is said to be an external constructor. </paragraph>
+  <paragraph>Because an external constructor declaration provides no actual implementation, its <non_terminal where="17.10">constructor-body</non_terminal> consists of a semicolon. For all other constructors, the <non_terminal where="17.10">constructor-body</non_terminal> consists of a block, which specifies the statements to initialize a new instance of the class. This corresponds exactly to the block of an instance method with a <keyword>void</keyword> return type (<hyperlink>17.5.8</hyperlink>). </paragraph>
+  <paragraph>Instance constructors are not inherited. Thus, a class has no instance constructors other than those actually declared in the class. If a class contains no instance constructor declarations, a default instance constructor is automatically provided (<hyperlink>17.10.4</hyperlink>). </paragraph>
+  <paragraph>Instance constructors are invoked by <non_terminal where="14.5.10.1">object-creation-expression</non_terminal>s (<hyperlink>14.5.10.1</hyperlink>) and through  <non_terminal where="17.10">constructor-initializer</non_terminal>s. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.11.xml b/mcs/docs/ecma334/17.11.xml
new file mode 100644 (file)
index 0000000..21a9bec
--- /dev/null
@@ -0,0 +1,72 @@
+<?xml version="1.0"?>
+<clause number="17.11" title="Static constructors">
+  <paragraph>A static constructor is a member that implements the actions required to initialize a class. Static constructors are declared using static-constructor-declarations: <grammar_production><name><non_terminal where="17.11">static-constructor-declaration</non_terminal></name> : <rhs><non_terminal where="24.2">attributes</non_terminal><opt/><non_terminal where="17.11">static-constructor-modifiers</non_terminal><non_terminal where="9.4.2">identifier</non_terminal><terminal>(</terminal><terminal>)</terminal><non_terminal where="17.11">static-constructor-body</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.11">static-constructor-modifiers</non_terminal></name> : <rhs><keyword>extern</keyword><opt/><keyword>static</keyword></rhs><rhs><keyword>static</keyword><keyword>extern</keyword><opt/></rhs></grammar_production><grammar_production><name><non_terminal where="17.11">static-constructor-body</non_terminal></name> : <rhs><non_terminal where="15.2">block</non_terminal></rhs><rhs><terminal>;</terminal></rhs></grammar_production></paragraph>
+  <paragraph>A <non_terminal where="17.11">static-constructor-declaration</non_terminal> may include a set of attributes (<hyperlink>24</hyperlink>) and an extern modifier (<hyperlink>17.5.7</hyperlink>). </paragraph>
+  <paragraph>The identifier of a <non_terminal where="17.11">static-constructor-declaration</non_terminal> must name the class in which the static constructor is declared. If any other name is specified, a compile-time error occurs. </paragraph>
+  <paragraph>When a static constructor declaration includes an extern modifier, the static constructor is said to be an external static constructor. Because an external static constructor declaration provides no actual implementation, its <non_terminal where="17.11">static-constructor-body</non_terminal> consists of a semicolon. For all other static constructor declarations, the <non_terminal where="17.11">static-constructor-body</non_terminal> consists of a block, which specifies the statements to execute in order to initialize the class. This corresponds exactly to the <non_terminal where="17.5">method-body</non_terminal> of a static method with a <keyword>void</keyword> return type (<hyperlink>17.5.8</hyperlink>). </paragraph>
+  <paragraph>Static constructors are not inherited, and cannot be called directly. </paragraph>
+  <paragraph>The static constructor for a class executes at most once in a given application domain. The execution of a static constructor is triggered by the first of the following events to occur within an application domain: <list><list_item> An instance of the class is created. </list_item><list_item> Any of the static members of the class are referenced. </list_item></list></paragraph>
+  <paragraph>If a class contains the Main method (<hyperlink>10.1</hyperlink>) in which execution begins, the static constructor for that class executes before the Main method is called. If a class contains any static fields with initializers, those initializers are executed in textual order immediately prior to executing the static constructor. </paragraph>
+  <paragraph>
+    <example>[Example: The example <code_example><![CDATA[
+using System;  
+class Test  
+{  
+   static void Main() {  
+      A.F();  
+      B.F();  
+   }  
+}  
+class A  
+{  
+   static A() {  
+      Console.WriteLine("Init A");  
+   }  
+   public static void F() {  
+      Console.WriteLine("A.F");  
+   }  
+}  
+class B  
+{  
+   static B() {  
+      Console.WriteLine("Init B");  
+   }  
+   public static void F() {  
+      Console.WriteLine("B.F");  
+   }  
+}  
+]]></code_example>must produce the output: <code_example><![CDATA[
+Init A  
+A.F  
+Init B  
+B.F  
+]]></code_example>because the execution of A's static constructor is triggered by the call to A.F, and the execution of B's static constructor is triggered by the call to B.F. end example]</example>
+  </paragraph>
+  <paragraph>It is possible to construct circular dependencies that allow static fields with variable initializers to be observed in their default value state. </paragraph>
+  <paragraph>
+    <example>[Example: The example <code_example><![CDATA[
+using System;  
+class A  
+{  
+   public static int X;  
+   static A() { X = B.Y + 1;}  
+}  
+class B  
+{  
+   public static int Y = A.X + 1;  
+   static B() {}  
+   static void Main() {  
+      Console.WriteLine("X = {0}, Y = {1}", A.X, B.Y);  
+   }  
+}  
+]]></code_example>produces the output <code_example><![CDATA[
+X = 1, Y = 2  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>To execute the Main method, the system first runs the initializer for B.Y, prior to class B's static constructor. </example>
+  </paragraph>
+  <paragraph>
+    <example>Y's initializer causes A's static constructor to be run because the value of A.X is referenced. The static constructor of A in turn proceeds to compute the value of X, and in doing so fetches the default value of Y, which is zero. A.X is thus initialized to 1. The process of running A's static field initializers and static constructor then completes, returning to the calculation of the initial value of Y, the result of which becomes 2. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.12.xml b/mcs/docs/ecma334/17.12.xml
new file mode 100644 (file)
index 0000000..13c633a
--- /dev/null
@@ -0,0 +1,58 @@
+<?xml version="1.0"?>
+<clause number="17.12" title="Destructors">
+  <paragraph>A destructor is a member that implements the actions required to destruct an instance of a class. A destructor is declared using a destructor-declaration: <grammar_production><name><non_terminal where="17.12">destructor-declaration</non_terminal></name> : <rhs><non_terminal where="24.2">attributes</non_terminal><opt/><keyword>extern</keyword><opt/><terminal>~</terminal><non_terminal where="9.4.2">identifier</non_terminal><terminal>(</terminal><terminal>)</terminal><non_terminal where="17.12">destructor-body</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.12">destructor-body</non_terminal></name> : <rhs><non_terminal where="15.2">block</non_terminal></rhs><rhs><terminal>;</terminal></rhs></grammar_production></paragraph>
+  <paragraph>A <non_terminal where="17.12">destructor-declaration</non_terminal> may include a set of attributes (<hyperlink>24</hyperlink>). </paragraph>
+  <paragraph>The identifier of a destructor-declarator must name the class in which the destructor is declared. If any other name is specified, a compile-time error occurs. </paragraph>
+  <paragraph>When a destructor declaration includes an extern modifier, the destructor is said to be an external destructor. Because an external destructor declaration provides no actual implementation, its  <non_terminal where="17.12">destructor-body</non_terminal> consists of a semicolon. For all other destructors, the <non_terminal where="17.12">destructor-body</non_terminal> consists of a block, which specifies the statements to execute in order to destruct an instance of the class. A <non_terminal where="17.12">destructor-body</non_terminal> corresponds exactly to the <non_terminal where="17.5">method-body</non_terminal> of an instance method with a <keyword>void</keyword> return type (<hyperlink>17.5.8</hyperlink>). </paragraph>
+  <paragraph>Destructors are not inherited. Thus, a class has no destructors other than the one which may be declared in that class. </paragraph>
+  <paragraph>
+    <note>[Note: Since a destructor is required to have no parameters, it cannot be overloaded, so a class can have, at most, one destructor. end note]</note>
+  </paragraph>
+  <paragraph>Destructors are invoked automatically, and cannot be invoked explicitly. An instance becomes eligible for destruction when it is no longer possible for any code to use that instance. Execution of the destructor for the instance may occur at any time after the instance becomes eligible for destruction. When an instance is destructed, the destructors in that instance's inheritance chain are called, in order, from most derived to least derived <example>[Example: The output of the example <code_example><![CDATA[
+using System;  
+class A  
+{  
+   ~A() {  
+      Console.WriteLine("A's destructor");  
+   }  
+}  
+class B: A  
+{  
+   ~B() {  
+      Console.WriteLine("B's destructor");  
+   }  
+}  
+class Test  
+{  
+   static void Main() {  
+      B b = new B();  
+      b = null;  
+      GC.Collect();  
+      GC.WaitForPendingFinalizers();  
+   }  
+}  
+]]></code_example>is <code_example><![CDATA[
+B's destructor  
+A's destructor  
+]]></code_example>since destructors in an inheritance chain are called in order, from most derived to least derived. end example]</example> </paragraph>
+  <paragraph>Destructors may be implemented by overriding the virtual method Finalize on System.Object. In any event, C# programs are not permitted to override this method or call it (or overrides of it) directly. </paragraph>
+  <paragraph>
+    <example>[Example: For instance, the program <code_example><![CDATA[
+class A  
+{  
+   override protected void Finalize() {}  // error  
+   public void F() {  
+      this.Finalize();   // error  
+   }  
+}  
+]]></code_example>contains two errors. end example]</example>
+  </paragraph>
+  <paragraph>The compiler behaves as if this method, and overrides of it, does not exist at all. <example>[Example: Thus, this program: <code_example><![CDATA[
+class A  
+{  
+   void Finalize() {}   // permitted  
+}  
+]]></code_example>is valid and the method shown hides System.Object's Finalize method. end example]</example> </paragraph>
+  <paragraph>For a discussion of the behavior when an exception is thrown from a destructor, see <hyperlink>23.3</hyperlink>. <table_line/>
+</paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.2.1.xml b/mcs/docs/ecma334/17.2.1.xml
new file mode 100644 (file)
index 0000000..b01003b
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="17.2.1" title="Inheritance">
+  <paragraph>A class inherits the members of its direct base class. Inheritance means that a class implicitly contains all members of its direct base class, except for the instance constructors, destructors, and static constructors of the base class. Some important aspects of inheritance are: <list><list_item> Inheritance is transitive. If C is derived from B, and B is derived from A, then C inherits the members declared in B as well as the members declared in A. </list_item><list_item> A derived class extends its direct base class. A derived class can add new members to those it inherits, but it cannot remove the definition of an inherited member. </list_item><list_item> Instance constructors, destructors, and static constructors are not inherited, but all other members are, regardless of their declared accessibility (<hyperlink>10.5</hyperlink>). However, depending on their declared accessibility, inherited members might not be accessible in a derived class. </list_item><list_item> A derived class can hide (<hyperlink>10.7.1.2</hyperlink>) inherited members by declaring new members with the same name or signature. Note however that hiding an inherited member does not remove that member-it merely makes that member inaccessible in the derived class. </list_item><list_item> An instance of a class contains a set of all instance fields declared in the class and its base classes, and an implicit conversion (<hyperlink>13.1.4</hyperlink>) exists from a derived class type to any of its base class types. Thus, a reference to an instance of some derived class can be treated as a reference to an instance of any of its base classes. </list_item><list_item> A class can declare virtual methods, properties, and indexers, and derived classes can override the implementation of these function members. This enables classes to exhibit polymorphic behavior wherein the actions performed by a function member invocation varies depending on the run-time type of the instance through which that function member is invoked. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.2.2.xml b/mcs/docs/ecma334/17.2.2.xml
new file mode 100644 (file)
index 0000000..87e0aa7
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="17.2.2" title="The new modifier">
+  <paragraph>A <non_terminal where="17.2">class-member-declaration</non_terminal> is permitted to declare a member with the same name or signature as an inherited member. When this occurs, the derived class member is said to hide the base class member. Hiding an inherited member is not considered an error, but it does cause the compiler to issue a warning. To suppress the warning, the declaration of the derived class member can include a new modifier to indicate that the derived member is intended to hide the base member. This topic is discussed further in <hyperlink>10.7.1.2</hyperlink>. </paragraph>
+  <paragraph>If a new modifier is included in a declaration that doesn't hide an inherited member, a warning to that effect is issued. This warning is suppressed by removing the new modifier. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.2.3.xml b/mcs/docs/ecma334/17.2.3.xml
new file mode 100644 (file)
index 0000000..2191f58
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="17.2.3" title="Access modifiers">
+  <paragraph>A <non_terminal where="17.2">class-member-declaration</non_terminal> can have any one of the five possible kinds of declared accessibility (<hyperlink>10.5.1</hyperlink>): public, protected internal, protected, internal, or private. Except for the protected internal combination, it is a compile-time error to specify more than one access modifier. When a  <non_terminal where="17.2">class-member-declaration</non_terminal> does not include any access modifiers, private is assumed. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.2.4.xml b/mcs/docs/ecma334/17.2.4.xml
new file mode 100644 (file)
index 0000000..764eba3
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="17.2.4" title="Constituent types">
+  <paragraph>Types that are used in the declaration of a member are called the constituent types of that member. Possible constituent types are the type of a constant, field, property, event, or indexer, the return type of a method or operator, and the parameter types of a method, indexer, operator, or instance constructor. The constituent types of a member must be at least as accessible as that member itself (<hyperlink>10.5.4</hyperlink>). </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.2.5.xml b/mcs/docs/ecma334/17.2.5.xml
new file mode 100644 (file)
index 0000000..e518fbb
--- /dev/null
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<clause number="17.2.5" title="Static and instance members">
+  <paragraph>Members of a class are either static members or instance members. <note>[Note: Generally speaking, it is useful to think of static members as belonging to classes and instance members as belonging to objects (instances of classes). end note]</note> </paragraph>
+  <paragraph>When a field, method, property, event, operator, or constructor declaration includes a static modifier, it declares a static member. In addition, a constant or type declaration implicitly declares a static member. Static members have the following characteristics: <list><list_item> When a static member is referenced in a <non_terminal where="14.5.4">member-access</non_terminal> (<hyperlink>14.5.4</hyperlink>) of the form E.M, E must denote a type that has a member M. It is a compile-time error for E to denote an instance. </list_item><list_item> A static field identifies exactly one storage location. No matter how many instances of a class are created, there is only ever one copy of a static field. </list_item><list_item> A static function member (method, property, event, operator, or constructor) does not operate on a specific instance, and it is a compile-time error to refer to this in such a function member. </list_item></list></paragraph>
+  <paragraph>When a field, method, property, event, indexer, constructor, or destructor declaration does not include a static modifier, it declares an instance member. (An instance member is sometimes called a non-static member.) Instance members have the following characteristics: <list><list_item> When an instance member is referenced in a <non_terminal where="14.5.4">member-access</non_terminal> (<hyperlink>14.5.4</hyperlink>) of the form E.M, E must denote an instance of a type that has a member M. It is a compile-time error for E to denote a type. </list_item><list_item> Every instance of a class contains a separate set of all instance fields of the class. </list_item><list_item> An instance function member (method, property, indexer, instance constructor, or destructor) operates on a given instance of the class, and this instance can be accessed as this (<hyperlink>14.5.7</hyperlink>). </list_item></list></paragraph>
+  <paragraph>
+    <example>[Example: The following example illustrates the rules for accessing static and instance members: <code_example><![CDATA[
+class Test  
+{  
+   int x;  
+   static int y;  
+   void F() {  
+      x = 1;      // Ok, same as this.x = 1  
+      y = 1;      // Ok, same as Test.y = 1  
+   }  
+   static void G() {  
+      x = 1;      // Error, cannot access this.x  
+      y = 1;      // Ok, same as Test.y = 1  
+   }  
+   static void Main() {  
+      Test t = new Test();  
+      t.x = 1;     // Ok  
+      t.y = 1;     // Error, cannot access static member through  
+      instance  
+      Test.x = 1;   // Error, cannot access instance member through type  
+      Test.y = 1;   // Ok  
+   }  
+}  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>The F method shows that in an instance function member, a <non_terminal where="14.5.2">simple-name</non_terminal> (<hyperlink>14.5.2</hyperlink>) can be used to access both instance members and static members. The G method shows that in a static function member, it is a compile-time error to access an instance member through a <non_terminal where="14.5.2">simple-name</non_terminal>. The Main method shows that in a <non_terminal where="14.5.4">member-access</non_terminal> (<hyperlink>14.5.4</hyperlink>), instance members must be accessed through instances, and static members must be accessed through types. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.2.6.1.xml b/mcs/docs/ecma334/17.2.6.1.xml
new file mode 100644 (file)
index 0000000..93e3c71
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="17.2.6.1" title="Fully qualified name">
+  <paragraph>The fully qualified name (<hyperlink>10.8.1</hyperlink>) for a nested type is S.N where S is the fully qualified name of the type in which type N is declared. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.2.6.2.xml b/mcs/docs/ecma334/17.2.6.2.xml
new file mode 100644 (file)
index 0000000..e0b0d16
--- /dev/null
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<clause number="17.2.6.2" title="Declared accessibility">
+  <paragraph>Non-nested types can have public or internal declared accessibility and they have internal declared accessibility by default. Nested types can have these forms of declared accessibility too, plus one or more additional forms of declared accessibility, depending on whether the containing type is a class or struct: <list><list_item> A nested type that is declared in a class can have any of five forms of declared accessibility (public, protected internal, protected, internal, or private) and, like other class members, defaults to private declared accessibility. </list_item><list_item> A nested type that is declared in a struct can have any of three forms of declared accessibility (public, internal, or private) and, like other struct members, defaults to private declared accessibility. </list_item></list></paragraph>
+  <paragraph>
+    <example>[Example: The example <code_example><![CDATA[
+public class List  
+{  
+   // Private data structure  
+   private class Node  
+   {   
+      public object Data;  
+      public Node Next;  
+      public Node(object data, Node next) {  
+         this.Data = data;  
+         this.Next = next;  
+      }  
+   }  
+   private Node first = null;  
+   private Node last = null;  
+   // Public interface  
+   public void AddToFront(object o) {...}  
+   public void AddToBack(object o) {...}  
+   public object RemoveFromFront() {...}  
+   public object AddToFront() {...}  
+   public int Count { get {...} }  
+}  
+]]></code_example>declares a private nested class Node. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.2.6.3.xml b/mcs/docs/ecma334/17.2.6.3.xml
new file mode 100644 (file)
index 0000000..e29d71e
--- /dev/null
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+<clause number="17.2.6.3" title="Hiding">
+  <paragraph>A nested type may hide (<hyperlink>10.7.1.1</hyperlink>) a base member. The new modifier is permitted on nested type declarations so that hiding can be expressed explicitly. <example>[Example: The example <code_example><![CDATA[
+using System;  
+class Base   
+{  
+   public static void M() {  
+      Console.WriteLine("Base.M");  
+   }  
+}  
+class Derived: Base   
+{  
+   new public class M   
+   {  
+      public static void F() {  
+         Console.WriteLine("Derived.M.F");  
+      }  
+   }  
+}  
+class Test   
+{  
+   static void Main() {  
+      Derived.M.F();  
+   }  
+}  
+]]></code_example>shows a nested class M that hides the method M defined in Base. end example]</example> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.2.6.4.xml b/mcs/docs/ecma334/17.2.6.4.xml
new file mode 100644 (file)
index 0000000..4195f1b
--- /dev/null
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<clause number="17.2.6.4" title="this access">
+  <paragraph>A nested type and its containing type do not have a special relationship with regard to <non_terminal where="14.5.7">this-access</non_terminal> (<hyperlink>14.5.7</hyperlink>). Specifically, this within a nested type cannot be used to refer to instance members of the containing type. In cases where a nested type needs access to the instance members of its containing type, access can be provided by providing the this for the instance of the containing type as a constructor argument for the nested type. <example>[Example: The following example <code_example><![CDATA[
+using System;  
+class C   
+{  
+   int i = 123;  
+   public void F() {  
+      Nested n = new Nested(this);  
+      n.G();  
+   }  
+   public class Nested {  
+      C this_c;  
+      public Nested(C c) {  
+         this_c = c;  
+      }  
+      public void G() {  
+         Console.WriteLine(this_c.i);  
+      }  
+   }  
+}  
+class Test {  
+   static void Main() {  
+      C c = new C();  
+      c.F();  
+   }  
+}  
+]]></code_example>shows this technique. An instance of C creates an instance of Nested, and passes its own this to Nested's constructor in order to provide subsequent access to C's instance members. end example]</example> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.2.6.5.xml b/mcs/docs/ecma334/17.2.6.5.xml
new file mode 100644 (file)
index 0000000..c5a7733
--- /dev/null
@@ -0,0 +1,50 @@
+<?xml version="1.0"?>
+<clause number="17.2.6.5" title="Access to private and protected members of the containing type">
+  <paragraph>A nested type has access to all of the members that are accessible to its containing type, including members of the containing type that have private and protected declared accessibility. <example>[Example: The example <code_example><![CDATA[
+using System;  
+class C   
+{  
+   private static void F() {  
+      Console.WriteLine("C.F");  
+   }  
+   public class Nested   
+   {  
+      public static void G() {  
+         F();  
+      }  
+   }  
+}  
+class Test   
+{  
+   static void Main() {  
+      C.Nested.G();  
+   }  
+}  
+]]></code_example>shows a class C that contains a nested class Nested. Within Nested, themethod G calls the static method F defined in C, and F has private declared accessibility. end example]</example> </paragraph>
+  <paragraph>A nested type also may access protected members defined in a base type of its containing type. <example>[Example: In the example <code_example><![CDATA[
+using System;  
+class Base   
+{  
+   protected void F() {  
+      Console.WriteLine("Base.F");  
+   }  
+}  
+class Derived: Base   
+{  
+   public class Nested   
+   {  
+      public void G() {  
+         Derived d = new Derived();  
+         d.F();    // ok  
+      }  
+   }  
+}  
+class Test   
+{  
+   static void Main() {  
+      Derived.Nested n = new Derived.Nested();  
+      n.G();  
+   }  
+}  
+]]></code_example>the nested class Derived.Nested accesses the protected method F defined in Derived's base class, Base, by calling through an instance of Derived. end example]</example> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.2.6.xml b/mcs/docs/ecma334/17.2.6.xml
new file mode 100644 (file)
index 0000000..19df61d
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<clause number="17.2.6" title="Nested types">
+  <paragraph>A type declared within a class or struct is called a nested type. A type that is declared within a compilation unit or namespace is called a non-nested type. <example>[Example: In the following example: <code_example><![CDATA[
+using System;  
+class A  
+{  
+   class B  
+   {  
+      static void F() {  
+         Console.WriteLine("A.B.F");  
+      }  
+   }  
+}  
+]]></code_example>class B is a nested type because it is declared within class A, and class A is a non-nested type because it is declared within a compilation unit. end example]</example> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.2.7.1.xml b/mcs/docs/ecma334/17.2.7.1.xml
new file mode 100644 (file)
index 0000000..d360d34
--- /dev/null
@@ -0,0 +1,39 @@
+<?xml version="1.0"?>
+<clause number="17.2.7.1" title="Member Names Reserved for Properties">
+  <paragraph>For a property P (<hyperlink>17.6</hyperlink>) of type T, the following signatures are reserved: <code_example><![CDATA[
+T get_P();  
+void set_P(T value);  
+]]></code_example></paragraph>
+  <paragraph>Both signatures are reserved, even if the property is read-only or write-only. </paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+using System;  
+class A {  
+   public int P {  
+      get { return 123; }  
+   }  
+}  
+class B: A {  
+   new public int get_P() {  
+      return 456;  
+   }  
+   new public void set_P(int value) {  
+   }  
+}  
+class Test  
+{  
+   static void Main() {  
+      B b = new B();  
+      A a = b;  
+      Console.WriteLine(a.P);  
+      Console.WriteLine(b.P);  
+      Console.WriteLine(b.get_P());  
+   }  
+}  
+]]></code_example>a class A defines a read-only property P, thus reserving signatures for get_P and set_P methods. A class B derives from A and hides both of these reserved signatures. The example produces the output: <code_example><![CDATA[
+123  
+123  
+456  
+]]></code_example>end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.2.7.2.xml b/mcs/docs/ecma334/17.2.7.2.xml
new file mode 100644 (file)
index 0000000..8080128
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<clause number="17.2.7.2" title="Member Names Reserved for Events">
+  <paragraph>For an event E (<hyperlink>17.7</hyperlink>) of delegate type T, the following signatures are reserved: <code_example><![CDATA[
+void add_E(T handler);  
+void remove_E(T handler);  
+]]></code_example></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.2.7.3.xml b/mcs/docs/ecma334/17.2.7.3.xml
new file mode 100644 (file)
index 0000000..e9c9bc9
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<clause number="17.2.7.3" title="Member Names Reserved for Indexers">
+  <paragraph>For an indexer (<hyperlink>17.8</hyperlink>) of type T with parameter-list L, the following signatures are reserved: <code_example><![CDATA[
+T get_Item(L);  
+void set_Item(L, T value);  
+]]></code_example></paragraph>
+  <paragraph>Both signatures are reserved, even if the indexer is read-only or write-only. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.2.7.4.xml b/mcs/docs/ecma334/17.2.7.4.xml
new file mode 100644 (file)
index 0000000..317fc97
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="17.2.7.4" title="Member Names Reserved for Destructors">
+  <paragraph>For a class containing a destructor (<hyperlink>17.12</hyperlink>), the following signature is reserved: <code_example><![CDATA[
+void Finalize();  
+]]></code_example></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.2.7.xml b/mcs/docs/ecma334/17.2.7.xml
new file mode 100644 (file)
index 0000000..27edd75
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<clause number="17.2.7" title="Reserved member names">
+  <paragraph>To facilitate the underlying C# runtime implementation, for each source member declaration that is a property, event, or indexer, the implementation must reserve two method signatures based on the kind of the member declaration, its name, and its type (<hyperlink>17.2.7.1</hyperlink>, <hyperlink>17.2.7.2</hyperlink>, <hyperlink>17.2.7.3</hyperlink>). It is a compile-time error for a program to declare a member whose signature matches one of these reserved signatures, even if the underlying runtime implementation does not make use of these reservations. </paragraph>
+  <paragraph>The reserved names do not introduce declarations, thus they do not participate in member lookup. However, a declaration's associated reserved method signatures do participate in inheritance (<hyperlink>17.2.1</hyperlink>), and can be hidden with the new modifier (<hyperlink>17.2.2</hyperlink>). </paragraph>
+  <paragraph>
+    <note>[Note: The reservation of these names serves three purposes: </note>
+  </paragraph>
+  <paragraph>
+    <note>1 To allow the underlying implementation to use an ordinary identifier as a method name for get or set access to the C# language feature. </note>
+  </paragraph>
+  <paragraph>
+    <note>2 To allow other languages to interoperate using an ordinary identifier as a method name for get or set access to the C# language feature. </note>
+  </paragraph>
+  <paragraph>
+    <note>3 To help ensure that the source accepted by one conforming compiler is accepted by another, by making the specifics of reserved member names consistent across all C# implementations. end note]</note>
+  </paragraph>
+  <paragraph>The declaration of a destructor (<hyperlink>17.12</hyperlink>) also causes a signature to be reserved (<hyperlink>17.2.7.4</hyperlink>). </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.2.xml b/mcs/docs/ecma334/17.2.xml
new file mode 100644 (file)
index 0000000..4eef912
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<clause number="17.2" title="Class members">
+  <paragraph>The members of a class consist of the members introduced by its <non_terminal where="17.2">class-member-declaration</non_terminal>s and the members inherited from the direct base class. <grammar_production><name><non_terminal where="17.2">class-member-declaration</non_terminal>s</name> : <rhs><non_terminal where="17.2">class-member-declaration</non_terminal></rhs><rhs><non_terminal where="17.2">class-member-declarations</non_terminal><non_terminal where="17.2">class-member-declaration</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.2">class-member-declaration</non_terminal></name> : <rhs><non_terminal where="17.3">constant-declaration</non_terminal></rhs><rhs><non_terminal where="17.4">field-declaration</non_terminal></rhs><rhs><non_terminal where="17.5">method-declaration</non_terminal></rhs><rhs><non_terminal where="17.6">property-declaration</non_terminal></rhs><rhs><non_terminal where="17.7">event-declaration</non_terminal></rhs><rhs><non_terminal where="17.8">indexer-declaration</non_terminal></rhs><rhs><non_terminal where="17.9">operator-declaration</non_terminal></rhs><rhs><non_terminal where="17.10">constructor-declaration</non_terminal></rhs><rhs><non_terminal where="17.12">destructor-declaration</non_terminal></rhs><rhs><non_terminal where="17.11">static-constructor-declaration</non_terminal></rhs><rhs><non_terminal where="16.5">type-declaration</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>The members of a class are divided into the following categories: <list><list_item> Constants, which represent constant values associated with that class (<hyperlink>17.3</hyperlink>). </list_item><list_item> Fields, which are the variables of that class (<hyperlink>17.4</hyperlink>). </list_item><list_item> Methods, which implement the computations and actions that can be performed by that class (<hyperlink>17.5</hyperlink>). </list_item><list_item> Properties, which define named characteristics and the actions associated with reading and writing those characteristics (<hyperlink>17.6</hyperlink>). </list_item><list_item> Events, which define notifications that can be generated by that class (<hyperlink>17.7</hyperlink>). </list_item><list_item> Indexers, which permit instances of that class to be indexed in the same way as arrays (<hyperlink>17.8</hyperlink>). </list_item><list_item> Operators, which define the expression operators that can be applied to instances of that class (<hyperlink>17.9</hyperlink>). </list_item><list_item> Instance constructors, which implement the actions required to initialize instances of that class (<hyperlink>17.10</hyperlink>) </list_item><list_item> Destructors, which implement the actions to be performed before instances of that class are permanently discarded (<hyperlink>17.12</hyperlink>). </list_item><list_item> Static constructors, which implement the actions required to initialize that class itself (<hyperlink>17.11</hyperlink>). </list_item><list_item> Types, which represent the types that are local to that class (<hyperlink>16.5</hyperlink>). </list_item></list></paragraph>
+  <paragraph>Members that can contain executable code are collectively known as the function members of the class. The function members of a class are the methods, properties, events, indexers, operators, instance constructors, destructors, and static constructors of that class. </paragraph>
+  <paragraph>A <non_terminal where="17.1">class-declaration</non_terminal> creates a new declaration space (<hyperlink>10.3</hyperlink>), and the <non_terminal where="17.2">class-member-declaration</non_terminal>s immediately contained by the <non_terminal where="17.1">class-declaration</non_terminal> introduce new members into this declaration space. The following rules apply to class-member-declarations: <list><list_item> Instance constructors, destructors, and static constructors must have the same name as the immediately enclosing class. All other members must have names that differ from the name of the immediately enclosing class. </list_item><list_item> The name of a constant, field, property, event, or type must differ from the names of all other members declared in the same class. </list_item><list_item> The name of a method must differ from the names of all other non-methods declared in the same class. In addition, the signature (<hyperlink>10.6</hyperlink>) of a method must differ from the signatures of all other methods declared in the same class. </list_item><list_item> The signature of an instance constructor must differ from the signatures of all other instance constructors declared in the same class. </list_item><list_item> The signature of an indexer must differ from the signatures of all other indexers declared in the same class. </list_item><list_item> The signature of an operator must differ from the signatures of all other operators declared in the same class. </list_item></list></paragraph>
+  <paragraph>The inherited members of a class (<hyperlink>17.2.1</hyperlink>) are not part of the declaration space of a class. <note>[Note: Thus, a derived class is allowed to declare a member with the same name or signature as an inherited member (which in effect hides the inherited member). end note]</note> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.3.xml b/mcs/docs/ecma334/17.3.xml
new file mode 100644 (file)
index 0000000..52041f9
--- /dev/null
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+<clause number="17.3" title="Constants">
+  <paragraph>A constant is a class member that represents a constant value: a value that can be computed at compile-time. A <non_terminal where="17.3">constant-declaration</non_terminal> introduces one or more constants of a given type. <grammar_production><name><non_terminal where="17.3">constant-declaration</non_terminal></name> : <rhs><non_terminal where="24.2">attributes</non_terminal><opt/><non_terminal where="17.3">constant-modifiers</non_terminal><opt/><keyword>const</keyword><non_terminal where="11">type</non_terminal><non_terminal where="17.3">constant-declarators</non_terminal><terminal>;</terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.3">constant-modifier</non_terminal>s</name> : <rhs><non_terminal where="17.3">constant-modifier</non_terminal></rhs><rhs><non_terminal where="17.3">constant-modifiers</non_terminal><non_terminal where="17.3">constant-modifier</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.3">constant-modifier</non_terminal></name> : <rhs><keyword>new</keyword></rhs><rhs><keyword>public</keyword></rhs><rhs><keyword>protected</keyword></rhs><rhs><keyword>internal</keyword></rhs><rhs><keyword>private</keyword></rhs></grammar_production><grammar_production><name><non_terminal where="17.3">constant-declarator</non_terminal>s</name> : <rhs><non_terminal where="17.3">constant-declarator</non_terminal></rhs><rhs><non_terminal where="17.3">constant-declarators</non_terminal><terminal>,</terminal><non_terminal where="17.3">constant-declarator</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.3">constant-declarator</non_terminal></name> : <rhs><non_terminal where="9.4.2">identifier</non_terminal><terminal>=</terminal><non_terminal where="14.15">constant-expression</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>A <non_terminal where="17.3">constant-declaration</non_terminal> may include a set of attributes (<hyperlink>24</hyperlink>), a new modifier (<hyperlink>17.2.2</hyperlink>), and a valid combination of the four access modifiers (<hyperlink>17.2.3</hyperlink>). The attributes and modifiers apply to all of the members declared by the <non_terminal where="17.3">constant-declaration</non_terminal>. Even though constants are considered static members, a  <non_terminal where="17.3">constant-declaration</non_terminal> neither requires nor allows a static modifier. It is an error for the same modifier to appear multiple times in a constant declaration. </paragraph>
+  <paragraph>The type of a <non_terminal where="17.3">constant-declaration</non_terminal> specifies the type of the members introduced by the declaration. The type is followed by a list of <non_terminal where="17.3">constant-declarator</non_terminal>s, each of which introduces a new member. A <non_terminal where="17.3">constant-declarator</non_terminal> consists of an identifier that names themember, followed by an &quot;=&quot; token, followed by a  <non_terminal where="14.15">constant-expression</non_terminal> (<hyperlink>14.15</hyperlink>) that gives the value of the member. </paragraph>
+  <paragraph>The type specified in a constant declaration must be <keyword>sbyte</keyword>, <keyword>byte</keyword>, <keyword>short</keyword>, <keyword>ushort</keyword>, <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>long</keyword>, <keyword>ulong</keyword>, <keyword>char</keyword>, <keyword>float</keyword>, <keyword>double</keyword>, <keyword>decimal</keyword>, <keyword>bool</keyword>, string, an <non_terminal where="11.1">enum-type</non_terminal>, or a <non_terminal where="11.2">reference-type</non_terminal>. Each  <non_terminal where="14.15">constant-expression</non_terminal> must yield a value of the target type or of a type that can be converted to the target type by an implicit conversion (<hyperlink>13.1</hyperlink>). </paragraph>
+  <paragraph>The type of a constant must be at least as accessible as the constant itself (<hyperlink>10.5.4</hyperlink>). </paragraph>
+  <paragraph>The value of a constant is obtained in an expression using a <non_terminal where="14.5.2">simple-name</non_terminal> (<hyperlink>14.5.2</hyperlink>) or a <non_terminal where="14.5.4">member-access</non_terminal> (<hyperlink>14.5.4</hyperlink>). </paragraph>
+  <paragraph>A constant can itself participate in a <non_terminal where="14.15">constant-expression</non_terminal>. Thus, a constant may be used in any construct that requires a <non_terminal where="14.15">constant-expression</non_terminal>. <note>[Note: Examples of such constructs include case labels, goto case statements, enum member declarations, attributes, and other constant declarations. end note]</note> </paragraph>
+  <paragraph>
+    <note>[Note: As described in <hyperlink>14.15</hyperlink>, a <non_terminal where="14.15">constant-expression</non_terminal> is an expression that can be fully evaluated at  compile-time. Since the only way to create a non-null value of a <non_terminal where="11.2">reference-type</non_terminal> other than string is to apply the new operator, and since the new operator is not permitted in a <non_terminal where="14.15">constant-expression</non_terminal>, the only possible value for constants of <non_terminal where="11.2">reference-type</non_terminal>s other than string is null. end note]</note>
+  </paragraph>
+  <paragraph>When a symbolic name for a constant value is desired, but when the type of that value is not permitted in a constant declaration, or when the value cannot be computed at compile-time by a <non_terminal where="14.15">constant-expression</non_terminal>, a readonly field (<hyperlink>17.4.2</hyperlink>) may be used instead. <note>[Note: The versioning semantics of const and readonly differ (<hyperlink>17.4.2.2</hyperlink>). end note]</note> </paragraph>
+  <paragraph>A constant declaration that declares multiple constants is equivalent to multiple declarations of single constants with the same attributes, modifiers, and type. <example>[Example: For example <code_example><![CDATA[
+class A  
+{  
+   public const double X = 1.0, Y = 2.0, Z = 3.0;  
+}  
+]]></code_example>is equivalent to <code_example><![CDATA[
+class A  
+{  
+   public const double X = 1.0;  
+   public const double Y = 2.0;  
+   public const double Z = 3.0;  
+}  
+]]></code_example>end example]</example> </paragraph>
+  <paragraph>Constants are permitted to depend on other constants within the same program as <keyword>long</keyword> as the dependencies are not of a circular nature. The compiler automatically arranges to evaluate the constant declarations in the appropriate order. <example>[Example: In the example <code_example><![CDATA[
+class A  
+{  
+   public const int X = B.Z + 1;  
+   public const int Y = 10;  
+}  
+class B  
+{  
+   public const int Z = A.Y + 1;  
+}  
+]]></code_example>the compiler first evaluates A.Y, then evaluates B.Z, and finally evaluates A.X, producing the values 10, 11, and 12. end example]</example> Constant declarations may depend on constants from other programs, but such dependencies are only possible in one direction. <example>[Example: Referring to the example above, if A and B were declared in separate programs, it would be possible for A.X to depend on B.Z, but B.Z could then not simultaneously depend on A.Y. end example]</example> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.4.1.xml b/mcs/docs/ecma334/17.4.1.xml
new file mode 100644 (file)
index 0000000..952df03
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<clause number="17.4.1" title="Static and instance fields">
+  <paragraph>When a field declaration includes a static modifier, the fields introduced by the declaration are static fields. When no static modifier is present, the fields introduced by the declaration are instance fields. </paragraph>
+  <paragraph>Static fields and instance fields are two of the several kinds of variables (<hyperlink>12</hyperlink>) supported by C#, and at times they are referred to as static variables and instance variables, respectively. </paragraph>
+  <paragraph>A static field is not part of a specific instance; instead, it identifies exactly one storage location. No matter how many instances of a class are created, there is only ever one copy of a static field for the associated application domain. </paragraph>
+  <paragraph>An instance field belongs to an instance. Specifically, every instance of a class contains a separate set of all the instance fields of that class. </paragraph>
+  <paragraph>When a field is referenced in a <non_terminal where="14.5.4">member-access</non_terminal> (<hyperlink>14.5.4</hyperlink>) of the form E.M, if M is a static field, E must denote a type that has a field M, and if M is an instance field, E must denote an instance of a type that has a field M. </paragraph>
+  <paragraph>The differences between static and instance members are discussed further in <hyperlink>17.2.5</hyperlink>. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.4.2.1.xml b/mcs/docs/ecma334/17.4.2.1.xml
new file mode 100644 (file)
index 0000000..463c011
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<clause number="17.4.2.1" title="Using static readonly fields for constants">
+  <paragraph>A static readonly field is useful when a symbolic name for a constant value is desired, but when the type of the value is not permitted in a const declaration, or when the value cannot be computed at  compile-time. <example>[Example: In the example <code_example><![CDATA[
+public class Color  
+{  
+   public static readonly Color Black = new Color(0, 0, 0);  
+   public static readonly Color White = new Color(255, 255, 255);  
+   public static readonly Color Red = new Color(255, 0, 0);  
+   public static readonly Color Green = new Color(0, 255, 0);  
+   public static readonly Color Blue = new Color(0, 0, 255);  
+   private byte red, green, blue;  
+   public Color(byte r, byte g, byte b) {  
+      red = r;  
+      green = g;  
+      blue = b;  
+   }  
+}  
+]]></code_example>the Black, White, Red, Green, and Blue members cannot be declared as const members because their values cannot be computed at compile-time. However, declaring them static readonly instead has much the same effect. end example]</example> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.4.2.2.xml b/mcs/docs/ecma334/17.4.2.2.xml
new file mode 100644 (file)
index 0000000..d4acac3
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<clause number="17.4.2.2" title="Versioning of constants and static readonly fields">
+  <paragraph>Constants and readonly fields have different binary versioning semantics. When an expression references a constant, the value of the constant is obtained at compile-time, but when an expression references a readonly field, the value of the field is not obtained until run-time. <example>[Example: Consider an application that consists of two separate programs: <code_example><![CDATA[
+using System;  
+namespace Program1  
+{  
+   public class Utils  
+   {  
+      public static readonly int X = 1;  
+   }  
+}  
+namespace Program2  
+{  
+   class Test  
+   {  
+      static void Main() {  
+         Console.WriteLine(Program1.Utils.X);  
+      }  
+   }  
+}  
+]]></code_example></example></paragraph>
+  <paragraph>
+    <example>The Program1 and Program2 namespaces denote two programs that are compiled separately. Because Program1.Utils.X is declared as a static readonly field, the value output by the Console.WriteLine statement is not known at compile-time, but rather is obtained at run-time. Thus, if the value of X is changed and Program1 is recompiled, the Console.WriteLine statement will output the new value even if Program2 isn't recompiled. However, had X been a constant, the value of X would have been obtained at the time Program2 was compiled, and would remain unaffected by changes in Program1 until Program2 is recompiled. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.4.2.xml b/mcs/docs/ecma334/17.4.2.xml
new file mode 100644 (file)
index 0000000..1137422
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="17.4.2" title="Readonly fields">
+  <paragraph>When a <non_terminal where="17.4">field-declaration</non_terminal> includes a readonly modifier, the fields introduced by the declaration are readonly fields. Direct assignments to readonly fields can only occur as part of that declaration or in an instance constructor or static constructor in the same class. (A readonly field can be assigned to multiple times in these contexts.) Specifically, direct assignments to a readonly field are permitted only in the following contexts: <list><list_item> In the <non_terminal where="17.4">variable-declarator</non_terminal> that introduces the field (by including a <non_terminal where="19.6">variable-initializer</non_terminal> in the declaration). </list_item><list_item> For an instance field, in the instance constructors of the class that contains the field declaration; for a static field, in the static constructor of the class that contains the field declaration. These are also the only contexts in which it is valid to pass a readonly field as an out or ref parameter. </list_item></list></paragraph>
+  <paragraph>Attempting to assign to a readonly field or pass it as an out or ref parameter in any other context is a compile-time error. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.4.3.xml b/mcs/docs/ecma334/17.4.3.xml
new file mode 100644 (file)
index 0000000..60fa562
--- /dev/null
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+<clause number="17.4.3" title="Volatile fields">
+  <paragraph>When a <non_terminal where="17.4">field-declaration</non_terminal> includes a volatile modifier, the fields introduced by that declaration are volatile fields. For non-volatile fields, optimization techniques that reorder instructions can lead to unexpected and unpredictable results in multi-threaded programs that access fields without synchronization such as that provided by the <non_terminal where="15.12">lock-statement</non_terminal> (<hyperlink>15.12</hyperlink>). These optimizations can be performed by the compiler, by the runtime system, or by hardware. For volatile fields, such reordering optimizations are restricted: <list><list_item> A read of a volatile field is called a volatile read. A volatile read has &quot;acquire semantics&quot;; that is, it is guaranteed to occur prior to any references to memory that occur after it in the instruction sequence. </list_item><list_item> A write of a volatile field is called a volatile write. A volatile write has &quot;release semantics&quot;; that is, it is guaranteed to happen after any memory references prior to the write instruction in the instruction sequence. </list_item></list></paragraph>
+  <paragraph>These restrictions ensure that all threads will observe volatile writes performed by any other thread in the order in which they were performed. A conforming implementation is not required to provide a single total ordering of volatile writes as seen from all threads of execution. The type of a volatile field must be one of the following: <list><list_item> A <non_terminal where="11.2">reference-type</non_terminal>. </list_item><list_item> The type <keyword>byte</keyword>, <keyword>sbyte</keyword>, <keyword>short</keyword>, <keyword>ushort</keyword>, <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>char</keyword>, <keyword>float</keyword>, or <keyword>bool</keyword>. </list_item><list_item> An <non_terminal where="11.1">enum-type</non_terminal> having an enum base type of <keyword>byte</keyword>, <keyword>sbyte</keyword>, <keyword>short</keyword>, <keyword>ushort</keyword>, <keyword>int</keyword>, or <keyword>uint</keyword>. </list_item></list></paragraph>
+  <paragraph>
+    <example>[Example: The example <code_example><![CDATA[
+using System;  
+using System.Threading;  
+class Test  
+{  
+   public static int result;  
+   public static volatile bool finished;  
+   static void Thread2() {  
+      result = 143;  
+      finished = true;  
+   }  
+   static void Main() {  
+      finished = false;  
+      // Run Thread2() in a new thread  
+      new Thread(new ThreadStart(Thread2)).Start();  
+      // Wait for Thread2 to signal that it has a result by setting  
+      // finished to true.  
+      for (;;) {  
+         if (finished) {  
+            Console.WriteLine("result = {0}", result);  
+            return;  
+         }  
+      }  
+   }  
+}  
+]]></code_example>produces the output: <code_example><![CDATA[
+result = 143  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>In this example, the method Main starts a new thread that runs the method Thread2. This method stores a value into a non-volatile field called result, then stores true in the volatile field finished. The main thread waits for the field finished to be set to true, then reads the field result. Since result has been declared volatile, the main thread must read the value 143 from the field result. If the field finished had not been declared volatile, then it would be permissible for the store to result to be visible to the main thread after the store to finished, and hence for the main thread to read the value 0 from the field result. Declaring finished as a volatile field prevents any such inconsistency. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.4.4.xml b/mcs/docs/ecma334/17.4.4.xml
new file mode 100644 (file)
index 0000000..d6cc25f
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+<clause number="17.4.4" title="Field initialization">
+  <paragraph>The initial value of a field, whether it be a static field or an instance field, is the default value (<hyperlink>12.2</hyperlink>) of the field's type. It is not possible to observe the value of a field before this default initialization has occurred, and a field is thus never &quot;uninitialized&quot;. <example>[Example: The example <code_example><![CDATA[
+using System;  
+class Test  
+{  
+   static bool b;  
+   int i;  
+   static void Main() {  
+      Test t = new Test();  
+      Console.WriteLine("b = {0}, i = {1}", b, t.i);  
+   }  
+}  
+]]></code_example>produces the output <code_example><![CDATA[
+b = False, i = 0  
+]]></code_example>because b and i are both automatically initialized to default values. end example]</example> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.4.5.1.xml b/mcs/docs/ecma334/17.4.5.1.xml
new file mode 100644 (file)
index 0000000..f944791
--- /dev/null
@@ -0,0 +1,57 @@
+<?xml version="1.0"?>
+<clause number="17.4.5.1" title="Static field initialization">
+  <paragraph>The static field variable initializers of a class correspond to a sequence of assignments that are executed in the textual order in which they appear in the class declaration. If a static constructor (<hyperlink>17.11</hyperlink>) exists in the class, execution of the static field initializers occurs immediately prior to executing that static constructor. Otherwise, the static field initializers are executed at an implementation-dependent time prior to the first use of a static field of that class. <example>[Example: The example <code_example><![CDATA[
+using System;  
+class Test   
+{   
+   static void Main() {  
+      Console.WriteLine("{0} {1}", B.Y, A.X);  
+   }  
+   public static int f(string s) {  
+      Console.WriteLine(s);  
+      return 1;  
+   }  
+}  
+class A  
+{  
+   public static int X = Test.f("Init A");  
+}  
+class B  
+{  
+   public static int Y = Test.f("Init B");  
+}  
+]]></code_example>might produce either the output: <code_example><![CDATA[
+Init A  
+Init B  
+1 1  
+]]></code_example>or the output: <code_example><![CDATA[
+Init B  
+Init A  
+1 1  
+]]></code_example>because the execution of X's initializer and Y's initializer could occur in either order; they are only constrained to occur before the references to those fields. However, in the example: <code_example><![CDATA[
+using System;  
+class Test {  
+   static void Main() {  
+      Console.WriteLine("{0} {1}", B.Y, A.X);  
+   }  
+   public static int f(string s) {  
+      Console.WriteLine(s);  
+      return 1;  
+   }  
+}  
+class A  
+{  
+   static A() {}  
+   public static int X = Test.f("Init A");  
+}  
+class B  
+{  
+   static B() {}  
+   public static int Y = Test.f("Init B");  
+}  
+]]></code_example>the output must be: <code_example><![CDATA[
+Init B  
+Init A  
+1 1  
+]]></code_example>because the rules for when static constructors execute provide that B's static constructor (and hence B's static field initializers) must run before A's static constructor and field initializers. end example]</example> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.4.5.2.xml b/mcs/docs/ecma334/17.4.5.2.xml
new file mode 100644 (file)
index 0000000..8389f20
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<clause number="17.4.5.2" title="Instance field initialization">
+  <paragraph>The instance field variable initializers of a class correspond to a sequence of assignments that are executed immediately upon entry to any one of the instance constructors (<hyperlink>17.10.2</hyperlink>) of that class. The variable initializers are executed in the textual order in which they appear in the class declaration. The class instance creation and initialization process is described further in <hyperlink>17.10</hyperlink>. </paragraph>
+  <paragraph>A variable initializer for an instance field cannot reference the instance being created. Thus, it is a  compile-time error to reference this in a variable initializer, as it is a compile-time error for a variable initializer to reference any instance member through a <non_terminal where="14.5.2">simple-name</non_terminal>. <example>[Example: In the example <code_example><![CDATA[
+class A  
+{  
+   int x = 1;  
+   int y = x + 1;   // Error, reference to instance member of this  
+}  
+]]></code_example>the variable initializer for y results in a compile-time error because it references a member of the instance being created. end example]</example> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.4.5.xml b/mcs/docs/ecma334/17.4.5.xml
new file mode 100644 (file)
index 0000000..73552d9
--- /dev/null
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<clause number="17.4.5" title="Variable initializers">
+  <paragraph>Field declarations may include <non_terminal where="19.6">variable-initializer</non_terminal>s. For static fields, variable initializers correspond to assignment statements that are executed during class initialization. For instance fields, variable initializers correspond to assignment statements that are executed when an instance of the class is created. </paragraph>
+  <paragraph>
+    <example>[Example: The example <code_example><![CDATA[
+using System;  
+class Test  
+{  
+   static double x = Math.Sqrt(2.0);  
+   int i = 100;  
+   string s = "Hello";  
+   static void Main() {  
+      Test a = new Test();  
+      Console.WriteLine("x = {0}, i = {1}, s = {2}", x, a.i, a.s);  
+   }  
+}  
+]]></code_example>produces the output <code_example><![CDATA[
+x = 1.4142135623731, i = 100, s = Hello  
+]]></code_example>because an assignment to x occurs when static field initializers execute and assignments to i and s occur when the instance field initializers execute. end example]</example>
+  </paragraph>
+  <paragraph>The default value initialization described in <hyperlink>17.4.3</hyperlink> occurs for all fields, including fields that have variable initializers. Thus, when a class is initialized, all static fields in that class are first initialized to their default values, and then the static field initializers are executed in textual order. Likewise, when an instance of a class is created, all instance fields in that instance are first initialized to their default values, and then the instance field initializers are executed in textual order. </paragraph>
+  <paragraph>It is possible for static fields with variable initializers to be observed in their default value state. <example>[Example: However, this is strongly discouraged as a matter of style. The example <code_example><![CDATA[
+using System;  
+class Test  
+{  
+   static int a = b + 1;  
+   static int b = a + 1;  
+   static void Main() {  
+      Console.WriteLine("a = {0}, b = {1}", a, b);  
+   }  
+}  
+]]></code_example>exhibits this behavior. Despite the circular definitions of a and b, the program is valid. It results in the output <code_example><![CDATA[
+a = 1, b = 2  
+]]></code_example>because the static fields a and b are initialized to 0 (the default value for <keyword>int</keyword>) before their initializers are executed. When the initializer for a runs, the value of b is zero, and so a is initialized to 1. When the initializer for b runs, the value of a is already 1, and so b is initialized to 2. end example]</example> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.4.xml b/mcs/docs/ecma334/17.4.xml
new file mode 100644 (file)
index 0000000..557e989
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<clause number="17.4" title="Fields">
+  <paragraph>A field is a member that represents a variable associated with an object or class. A <non_terminal where="17.4">field-declaration</non_terminal> introduces one or more fields of a given type. <grammar_production><name><non_terminal where="17.4">field-declaration</non_terminal></name> : <rhs><non_terminal where="24.2">attributes</non_terminal><opt/><non_terminal where="17.4">field-modifiers</non_terminal><opt/><non_terminal where="11">type</non_terminal><non_terminal where="17.4">variable-declarators</non_terminal><terminal>;</terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.4">field-modifier</non_terminal>s</name> : <rhs><non_terminal where="17.4">field-modifier</non_terminal></rhs><rhs><non_terminal where="17.4">field-modifiers</non_terminal><non_terminal where="17.4">field-modifier</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.4">field-modifier</non_terminal></name> : <rhs><keyword>new</keyword></rhs><rhs><keyword>public</keyword></rhs><rhs><keyword>protected</keyword></rhs><rhs><keyword>internal</keyword></rhs><rhs><keyword>private</keyword></rhs><rhs><keyword>static</keyword></rhs><rhs><keyword>readonly</keyword></rhs><rhs><keyword>volatile</keyword></rhs></grammar_production><grammar_production><name><non_terminal where="17.4">variable-declarator</non_terminal>s</name> : <rhs><non_terminal where="17.4">variable-declarator</non_terminal></rhs><rhs><non_terminal where="17.4">variable-declarators</non_terminal><terminal>,</terminal><non_terminal where="17.4">variable-declarator</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.4">variable-declarator</non_terminal></name> : <rhs><non_terminal where="9.4.2">identifier</non_terminal></rhs><rhs><non_terminal where="9.4.2">identifier</non_terminal><terminal>=</terminal><non_terminal where="19.6">variable-initializer</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="19.6">variable-initializer</non_terminal></name> : <rhs><non_terminal where="14.14">expression</non_terminal></rhs><rhs><non_terminal where="19.6">array-initializer</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>A <non_terminal where="17.4">field-declaration</non_terminal> may include a set of attributes (<hyperlink>24</hyperlink>), a new modifier (<hyperlink>17.2.2</hyperlink>), a valid combination of the four access modifiers (<hyperlink>17.2.3</hyperlink>), and a static modifier (<hyperlink>17.4.1</hyperlink>). In addition, a <non_terminal where="17.4">field-declaration</non_terminal> may include a readonly modifier (<hyperlink>17.4.2</hyperlink>) or a volatile modifier (<hyperlink>17.4.3</hyperlink>), but not both The attributes and modifiers apply to all of the members declared by the <non_terminal where="17.4">field-declaration</non_terminal>. It is an error for the same modifier to appear multiple times in a field declaration. </paragraph>
+  <paragraph>The type of a <non_terminal where="17.4">field-declaration</non_terminal> specifies the type of the members introduced by the declaration. The type is followed by a list of <non_terminal where="17.4">variable-declarator</non_terminal>s, each of which introduces a new member. A <non_terminal where="17.4">variable-declarator</non_terminal> consists of an identifier that names that member, optionally followed by an &quot;=&quot; token and a  <non_terminal where="19.6">variable-initializer</non_terminal> (<hyperlink>17.4.5</hyperlink>) that gives the initial value of that member. </paragraph>
+  <paragraph>The type of a field must be at least as accessible as the field itself (<hyperlink>10.5.4</hyperlink>). </paragraph>
+  <paragraph>The value of a field is obtained in an expression using a <non_terminal where="14.5.2">simple-name</non_terminal> (<hyperlink>14.5.2</hyperlink>) or a <non_terminal where="14.5.4">member-access</non_terminal> (<hyperlink>14.5.4</hyperlink>). The value of a non-readonly field is modified using an assignment (<hyperlink>14.13</hyperlink>). The value of a  non-readonly field can be both obtained and modified using postfix increment and decrement operators (<hyperlink>14.5.9</hyperlink>) and prefix increment and decrement operators (<hyperlink>14.6.5</hyperlink>). </paragraph>
+  <paragraph>A field declaration that declares multiple fields is equivalent to multiple declarations of single fields with the same attributes, modifiers, and type. <example>[Example: For example <code_example><![CDATA[
+class A  
+{  
+   public static int X = 1, Y, Z = 100;  
+}  
+]]></code_example>is equivalent to <code_example><![CDATA[
+class A  
+{  
+   public static int X = 1;  
+   public static int Y;  
+   public static int Z = 100;  
+}  
+]]></code_example>end example]</example> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.5.1.1.xml b/mcs/docs/ecma334/17.5.1.1.xml
new file mode 100644 (file)
index 0000000..91f1c9f
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="17.5.1.1" title="Value parameters">
+  <paragraph>A parameter declared with no modifiers is a value parameter. A value parameter corresponds to a local variable that gets its initial value from the corresponding argument supplied in the method invocation. </paragraph>
+  <paragraph>When a formal parameter is a value parameter, the corresponding argument in a method invocation must be an expression of a type that is implicitly convertible (<hyperlink>13.1</hyperlink>) to the formal parameter type. </paragraph>
+  <paragraph>A method is permitted to assign new values to a value parameter. Such assignments only affect the local storage location represented by the value parameter-they have no effect on the actual argument given in the method invocation. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.5.1.2.xml b/mcs/docs/ecma334/17.5.1.2.xml
new file mode 100644 (file)
index 0000000..178ae21
--- /dev/null
@@ -0,0 +1,43 @@
+<?xml version="1.0"?>
+<clause number="17.5.1.2" title="Reference parameters">
+  <paragraph>A parameter declared with a ref modifier is a reference parameter. Unlike a value parameter, a reference parameter does not create a new storage location. Instead, a reference parameter represents the same storage location as the variable given as the argument in the method invocation. </paragraph>
+  <paragraph>When a formal parameter is a reference parameter, the corresponding argument in a method invocation must consist of the keyword ref followed by a <non_terminal where="12.4">variable-reference</non_terminal> (<hyperlink>12.3.3</hyperlink>) of the same type as the formal parameter. A variable must be definitely assigned before it can be passed as a reference parameter. </paragraph>
+  <paragraph>Within a method, a reference parameter is always considered definitely assigned. </paragraph>
+  <paragraph>
+    <example>[Example: The example <code_example><![CDATA[
+using System;  
+class Test  
+{  
+   static void Swap(ref int x, ref int y) {  
+      int temp = x;  
+      x = y;  
+      y = temp;  
+   }  
+   static void Main() {  
+      int i = 1, j = 2;  
+      Swap(ref i, ref j);  
+      Console.WriteLine("i = {0}, j = {1}", i, j);  
+   }  
+}  
+]]></code_example>produces the output <code_example><![CDATA[
+i = 2, j = 1  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>For the invocation of Swap in Main, x represents i and y represents j. Thus, the invocation has the effect of swapping the values of i and j. end example]</example>
+  </paragraph>
+  <paragraph>In a method that takes reference parameters, it is possible for multiple names to represent the same storage location. <example>[Example: In the example <code_example><![CDATA[
+class A  
+{  
+   string s;  
+   void F(ref string a, ref string b) {  
+      s = "One";  
+      a = "Two";  
+      b = "Three";  
+   }  
+   void G() {  
+      F(ref s, ref s);  
+   }  
+}  
+]]></code_example>the invocation of F in G passes a reference to s for both a and b. Thus, for that invocation, the names s, a, and b all refer to the same storage location, and the three assignments all modify the instance field s. end example]</example> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.5.1.3.xml b/mcs/docs/ecma334/17.5.1.3.xml
new file mode 100644 (file)
index 0000000..77bf225
--- /dev/null
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+<clause number="17.5.1.3" title="Output parameters">
+  <paragraph>A parameter declared with an out modifier is an output parameter. Similar to a reference parameter, an output parameter does not create a new storage location. Instead, an output parameter represents the same storage location as the variable given as the argument in the method invocation. </paragraph>
+  <paragraph>When a formal parameter is an output parameter, the corresponding argument in a method invocation must consist of the keyword out followed by a <non_terminal where="12.4">variable-reference</non_terminal> (<hyperlink>12.3.3</hyperlink>) of the same type as the formal parameter. A variable need not be definitely assigned before it can be passed as an output parameter, but following an invocation where a variable was passed as an output parameter, the variable is considered definitely assigned. </paragraph>
+  <paragraph>Within a method, just like a local variable, an output parameter is initially considered unassigned and must be definitely assigned before its value is used. </paragraph>
+  <paragraph>Every output parameter of a method must be definitely assigned before the method returns. </paragraph>
+  <paragraph>Output parameters are typically used in methods that produce multiple return values. <example>[Example: For example: <code_example><![CDATA[
+using System;  
+class Test  
+{  
+   static void SplitPath(string path, out string dir, out string name) {  
+      int i = path.Length;  
+      while (i > 0) {  
+         char ch = path[i - 1];  
+         if (ch == '\\' || ch == '/' || ch == ':') break;  
+         i--;  
+      }  
+      dir = path.Substring(0, i);  
+      name = path.Substring(i);  
+   }  
+   static void Main() {  
+      string dir, name;  
+      SplitPath("c:\\Windows\\System\\hello.txt", out dir, out name);  
+      Console.WriteLine(dir);  
+      Console.WriteLine(name);  
+   }  
+}  
+]]></code_example></example></paragraph>
+  <paragraph>
+    <example>The example produces the output: <code_example><![CDATA[
+c:\Windows\System\  
+hello.txt  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>Note that the dir and name variables can be unassigned before they are passed to SplitPath, and that they are considered definitely assigned following the call. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.5.1.4.xml b/mcs/docs/ecma334/17.5.1.4.xml
new file mode 100644 (file)
index 0000000..f4f1f78
--- /dev/null
@@ -0,0 +1,106 @@
+<?xml version="1.0"?>
+<clause number="17.5.1.4" title="Parameter arrays">
+  <paragraph>A parameter declared with a params modifier is a parameter array. If a formal parameter list includes a parameter array, it must be the last parameter in the list and it must be of a single-dimensional array type. </paragraph>
+  <paragraph><example>[Example: For example, the types string[] and string[][] can be used as the type of a parameter array, but the type string[,] can not. end example]</example> It is not possible to combine the params modifier with the modifiers ref and out. </paragraph>
+  <paragraph>A parameter array permits arguments to be specified in one of two ways in a method invocation: <list><list_item> The argument given for a parameter array can be a single expression of a type that is implicitly convertible (<hyperlink>13.1</hyperlink>) to the parameter array type. In this case, the parameter array acts precisely like a value parameter. </list_item><list_item> Alternatively, the invocation can specify zero or more arguments for the parameter array, where each argument is an expression of a type that is implicitly convertible (<hyperlink>13.1</hyperlink>) to the element type of the parameter array. In this case, the invocation creates an instance of the parameter array type with a length corresponding to the number of arguments, initializes the elements of the array instance with the given argument values, and uses the newly created array instance as the actual argument. </list_item></list></paragraph>
+  <paragraph>Except for allowing a variable number of arguments in an invocation, a parameter array is precisely equivalent to a value parameter (<hyperlink>17.5.1.1</hyperlink>) of the same type. </paragraph>
+  <paragraph>
+    <example>[Example: The example <code_example><![CDATA[
+using System;  
+class Test  
+{  
+   static void F(params int[] args) {  
+      Console.Write("Array contains {0} elements:", args.Length);  
+      foreach (int i in args)  
+      Console.Write(" {0}", i);  
+      Console.WriteLine();  
+   }  
+   static void Main() {  
+      int[] arr = {1, 2, 3};  
+      F(arr);  
+      F(10, 20, 30, 40);  
+      F();  
+   }  
+}  
+]]></code_example>produces the output <code_example><![CDATA[
+Array contains 3 elements: 1 2 3  
+Array contains 4 elements: 10 20 30 40  
+Array contains 0 elements:  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>The first invocation of F simply passes the array a as a value parameter. The second invocation of F automatically creates a four-element int[] with the given element values and passes that array instance as a value parameter. Likewise, the third invocation of F creates a zero-element int[] and passes that instance as a value parameter. The second and third invocations are precisely equivalent to writing: <code_example><![CDATA[
+F(new int[] {10, 20, 30, 40});  
+F(new int[] {});  
+]]></code_example>end example]</example>
+  </paragraph>
+  <paragraph>When performing overload resolution, a method with a parameter array may be applicable either in its normal form or in its expanded form (<hyperlink>14.4.2.1</hyperlink>). The expanded form of a method is available only if the normal form of the method is not applicable and only if a method with the same signature as the expanded form is not already declared in the same type. </paragraph>
+  <paragraph>
+    <example>[Example: The example <code_example><![CDATA[
+using System;  
+class Test  
+{  
+   static void F(params object[] a) {  
+      Console.WriteLine("F(object[])");  
+   }  
+   static void F() {  
+      Console.WriteLine("F()");  
+   }  
+   static void F(object a0, object a1) {  
+      Console.WriteLine("F(object,object)");  
+   }  
+   static void Main() {  
+      F();  
+      F(1);  
+      F(1, 2);  
+      F(1, 2, 3);  
+      F(1, 2, 3, 4);  
+   }  
+}  
+]]></code_example>produces the output <code_example><![CDATA[
+F();  
+F(object[]);  
+F(object,object);  
+F(object[]);  
+F(object[]);  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>In the example, two of the possible expanded forms of the method with a parameter array are already included in the class as regular methods. These expanded forms are therefore not considered when performing overload resolution, and the first and third method invocations thus select the regular methods. </example>
+  </paragraph>
+  <paragraph>
+    <example>When a class declares a method with a parameter array, it is not uncommon to also include some of the expanded forms as regular methods. By doing so it is possible to avoid the allocation of an array instance that occurs when an expanded form of a method with a parameter array is invoked. end example]</example>
+  </paragraph>
+  <paragraph>When the type of a parameter array is object[], a potential ambiguity arises between the normal form of the method and the expended form for a single object parameter. The reason for the ambiguity is that an object[] is itself implicitly convertible to type object. The ambiguity presents no problem, however, since it can be resolved by inserting a cast if needed. </paragraph>
+  <paragraph>
+    <example>[Example: The example <code_example><![CDATA[
+using System;  
+class Test  
+{  
+   static void F(params object[] args) {  
+      foreach (object o in args) {  
+         Console.Write(o.GetType().FullName);  
+         Console.Write(" ");  
+      }  
+      Console.WriteLine();  
+   }  
+   static void Main() {  
+      object[] a = {1, "Hello", 123.456};  
+      object o = a;  
+      F(a);  
+      F((object)a);  
+      F(o);  
+      F((object[])o);  
+   }  
+}  
+]]></code_example>produces the output <code_example><![CDATA[
+System.Int32 System.String System.Double  
+System.Object[]  
+System.Object[]  
+System.Int32 System.String System.Double  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>In the first and last invocations of F, the normal form of F is applicable because an implicit conversion exists from the argument type to the parameter type (both are of type object[]). Thus, overload resolution selects the normal form of F, and the argument is passed as a regular value parameter. In the second and third invocations, the normal form of F is not applicable because no implicit conversion exists from the argument type to the parameter type (type object cannot be implicitly converted to type object[]). However, the expanded form of F is applicable, so it is selected by overload resolution. As a result, a one-element object[] is created by the invocation, and the single element of the array is initialized with the given argument value (which itself is a reference to an object[]). end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.5.1.xml b/mcs/docs/ecma334/17.5.1.xml
new file mode 100644 (file)
index 0000000..5a3eecf
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<clause number="17.5.1" title="Method parameters">
+  <paragraph>The parameters of a method, if any, are declared by the method's <non_terminal where="17.5.1">formal-parameter-list</non_terminal>. <grammar_production><name><non_terminal where="17.5.1">formal-parameter-list</non_terminal></name> : <rhs><non_terminal where="17.5.1">fixed-parameters</non_terminal></rhs><rhs><non_terminal where="17.5.1">fixed-parameters</non_terminal><terminal>,</terminal><non_terminal where="17.5.1">parameter-array</non_terminal></rhs><rhs><non_terminal where="17.5.1">parameter-array</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.5.1">fixed-parameter</non_terminal>s</name> : <rhs><non_terminal where="17.5.1">fixed-parameter</non_terminal></rhs><rhs><non_terminal where="17.5.1">fixed-parameters</non_terminal><terminal>,</terminal><non_terminal where="17.5.1">fixed-parameter</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.5.1">fixed-parameter</non_terminal></name> : <rhs><non_terminal where="24.2">attributes</non_terminal><opt/><non_terminal where="17.5.1">parameter-modifier</non_terminal><opt/><non_terminal where="11">type</non_terminal><non_terminal where="9.4.2">identifier</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.5.1">parameter-modifier</non_terminal></name> : <rhs><keyword>ref</keyword></rhs><rhs><keyword>out</keyword></rhs></grammar_production><grammar_production><name><non_terminal where="17.5.1">parameter-array</non_terminal></name> : <rhs><non_terminal where="24.2">attributes</non_terminal><opt/><keyword>params</keyword><non_terminal where="19.1">array-type</non_terminal><non_terminal where="9.4.2">identifier</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>The formal parameter list consists of one or more comma-separated parameters of which only the last may be a <non_terminal where="17.5.1">parameter-array</non_terminal>. </paragraph>
+  <paragraph>A <non_terminal where="17.5.1">fixed-parameter</non_terminal> consists of an optional set of attributes (<hyperlink>24</hyperlink>), an optional ref or out modifier, a type, and an identifier. Each <non_terminal where="17.5.1">fixed-parameter</non_terminal> declares a parameter of the given type with the given name. </paragraph>
+  <paragraph>A <non_terminal where="17.5.1">parameter-array</non_terminal> consists of an optional set of attributes (<hyperlink>24</hyperlink>), a params modifier, an <non_terminal where="19.1">array-type</non_terminal>, and an identifier. A parameter array declares a single parameter of the given array type with the given name. The <non_terminal where="19.1">array-type</non_terminal> of a parameter array must be a single-dimensional array type (<hyperlink>19.1</hyperlink>). In a method invocation, a parameter array permits either a single argument of the given array type to be specified, or it permits zero or more arguments of the array element type to be specified. Parameter arrays are described further in <hyperlink>17.5.1.4</hyperlink>. </paragraph>
+  <paragraph>A method declaration creates a separate declaration space for parameters and local variables. Names are introduced into this declaration space by the formal parameter list of the method and by local variable declarations in the block of the method. All names in the declaration space of a method must be unique. Thus, it is a compile-time error for a parameter or local variable to have the same name as another parameter or local variable. </paragraph>
+  <paragraph>A method invocation (<hyperlink>14.5.5.1</hyperlink>) creates a copy, specific to that invocation, of the formal parameters and local variables of the method, and the argument list of the invocation assigns values or variable references to the newly created formal parameters. Within the block of a method, formal parameters can be referenced by their identifiers in <non_terminal where="14.5.2">simple-name</non_terminal> expressions (<hyperlink>14.5.2</hyperlink>). </paragraph>
+  <paragraph>There are four kinds of formal parameters: <list><list_item> Value parameters, which are declared without any modifiers. </list_item><list_item> Reference parameters, which are declared with the ref modifier. </list_item><list_item> Output parameters, which are declared with the out modifier. </list_item><list_item> Parameter arrays, which are declared with the params modifier. </list_item></list></paragraph>
+  <paragraph>
+    <note>[Note: As described in <hyperlink>10.6</hyperlink>, the ref and out modifiers are part of a method's signature, but the params modifier is not. end note]</note>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.5.2.xml b/mcs/docs/ecma334/17.5.2.xml
new file mode 100644 (file)
index 0000000..da6be70
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<clause number="17.5.2" title="Static and instance methods">
+  <paragraph>When a method declaration includes a static modifier, that method is said to be a static method. When no static modifier is present, the method is said to be an instance method. </paragraph>
+  <paragraph>A static method does not operate on a specific instance, and it is a compile-time error to refer to this in a static method. </paragraph>
+  <paragraph>An instance method operates on a given instance of a class, and that instance can be accessed as this (<hyperlink>14.5.7</hyperlink>). </paragraph>
+  <paragraph>When a method is referenced in a <non_terminal where="14.5.4">member-access</non_terminal> (<hyperlink>14.5.4</hyperlink>) of the form E.M, if M is a static method, E must denote a type that has a method M, and if M is an instance method, E must denote an instance of a type that has a method M. </paragraph>
+  <paragraph>The differences between static and instance members are discussed further in <hyperlink>17.2.5</hyperlink>. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.5.3.xml b/mcs/docs/ecma334/17.5.3.xml
new file mode 100644 (file)
index 0000000..33b61bb
--- /dev/null
@@ -0,0 +1,84 @@
+<?xml version="1.0"?>
+<clause number="17.5.3" title="Virtual methods">
+  <paragraph>When an instance method declaration includes a virtual modifier, that method is said to be a virtual method. When no virtual modifier is present, the method is said to be a non-virtual method. </paragraph>
+  <paragraph>The implementation of a non-virtual method is invariant: The implementation is the same whether the method is invoked on an instance of the class in which it is declared or an instance of a derived class. In contrast, the implementation of a virtual method can be superseded by derived classes. The process of superseding the implementation of an inherited virtual method is known as overriding that method (<hyperlink>17.5.4</hyperlink>). </paragraph>
+  <paragraph>In a virtual method invocation, the run-time type of the instance for which that invocation takes place determines the actual method implementation to invoke. In a non-virtual method invocation, the  compile-time type of the instance is the determining factor. In precise terms, when a method named N is invoked with an argument list A on an instance with a compile-time type C and a run-time type R (where R is either C or a class derived from C), the invocation is processed as follows: <list><list_item> First, overload resolution is applied to C, N, and A, to select a specific method M from the set of methods declared in and inherited by C. This is described in <hyperlink>14.5.5.1</hyperlink>. </list_item><list_item> Then, if M is a non-virtual method, M is invoked. </list_item><list_item> Otherwise, M is a virtual method, and the most derived implementation of M with respect to R is invoked. </list_item></list></paragraph>
+  <paragraph>For every virtual method declared in or inherited by a class, there exists a most derived implementation of the method with respect to that class. The most derived implementation of a virtual method M with respect to a class R is determined as follows: <list><list_item> If R contains the introducing virtual declaration of M, then this is the most derived implementation of M. </list_item><list_item> Otherwise, if R contains an override of M, then this is the most derived implementation of M. </list_item><list_item> Otherwise, the most derived implementation of M is the same as that of the direct base class of R. </list_item></list></paragraph>
+  <paragraph>
+    <example>[Example: The following example illustrates the differences between virtual and non-virtual methods: <code_example><![CDATA[
+using System;  
+class A  
+{  
+   public void F() { Console.WriteLine("A.F"); }  
+   public virtual void G() { Console.WriteLine("A.G"); }  
+}  
+class B: A  
+{  
+   new public void F() { Console.WriteLine("B.F"); }  
+   public override void G() { Console.WriteLine("B.G"); }  
+}  
+class Test  
+{  
+   static void Main() {  
+      B b = new B();  
+      A a = b;  
+      a.F();  
+      b.F();  
+      a.G();  
+      b.G();  
+   }  
+}  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>In the example, A introduces a non-virtual method F and a virtual method G. The class B introduces a new non-virtual method F, thus hiding the inherited F, and also overrides the inherited method G. The example produces the output: <code_example><![CDATA[
+A.F  
+B.F  
+B.G  
+B.G  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>Notice that the statement a.G() invokes B.G, not A.G. This is because the run-time type of the instance (which is B), not the compile-time type of the instance (which is A), determines the actual method implementation to invoke. end example]</example>
+  </paragraph>
+  <paragraph>Because methods are allowed to hide inherited methods, it is possible for a class to contain several virtual methods with the same signature. This does not present an ambiguity problem, since all but the most derived method are hidden. <example>[Example: In the example <code_example><![CDATA[
+using System;  
+class A  
+{  
+   public virtual void F() { Console.WriteLine("A.F"); }  
+}  
+class B: A  
+{  
+   public override void F() { Console.WriteLine("B.F"); }  
+}  
+class C: B  
+{  
+   new public virtual void F() { Console.WriteLine("C.F"); }  
+}  
+class D: C  
+{  
+   public override void F() { Console.WriteLine("D.F"); }  
+}  
+class Test  
+{  
+   static void Main() {  
+      D d = new D();  
+      A a = d;  
+      B b = d;  
+      C c = d;  
+      a.F();  
+      b.F();  
+      c.F();  
+      d.F();  
+   }  
+}  
+]]></code_example>the C and D classes contain two virtual methods with the same signature: The one introduced by A and the one introduced by C. The method introduced by C hides the method inherited from A. Thus, the override declaration in D overrides the method introduced by C, and it is not possible for D to override the method introduced by A. The example produces the output: <code_example><![CDATA[
+B.F  
+B.F  
+D.F  
+D.F  
+]]></code_example></example></paragraph>
+  <paragraph>
+    <example>Note that it is possible to invoke the hidden virtual method by accessing an instance of D through a less derived type in which the method is not hidden. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.5.4.xml b/mcs/docs/ecma334/17.5.4.xml
new file mode 100644 (file)
index 0000000..90d4eb7
--- /dev/null
@@ -0,0 +1,52 @@
+<?xml version="1.0"?>
+<clause number="17.5.4" title="Override methods">
+  <paragraph>When an instance method declaration includes an override modifier, the method is said to be an override method. An override method overrides an inherited virtual method with the same signature. Whereas a virtual method declaration introduces a new method, an override method declaration specializes an existing inherited virtual method by providing a new implementation of that method. </paragraph>
+  <paragraph>The method overridden by an override declaration is known as the overridden base method. For an override method M declared in a class C, the overridden base method is determined by examining each base class of C, starting with the direct base class of C and continuing with each successive direct base class, until an accessible method with the same signature as M is located. For the purposes of locating the overridden base method, a method is considered accessible if it is public, if it is protected, if it is protected internal, or if it is internal and declared in the same program as C. </paragraph>
+  <paragraph>A compile-time error occurs unless all of the following are true for an override declaration: <list><list_item> An overridden base method can be located as described above. </list_item><list_item> The overridden base method is a virtual, abstract, or override method. In other words, the overridden base method cannot be static or non-virtual. </list_item><list_item> The overridden base method is not a sealed method. </list_item><list_item> The override declaration and the overridden base method have the same declared accessibility. In other words, an override declaration cannot change the accessibility of the virtual method. </list_item></list></paragraph>
+  <paragraph>An override declaration can access the overridden base method using a <non_terminal where="14.5.8">base-access</non_terminal> (<hyperlink>14.5.8</hyperlink>). <example>[Example: In the example <code_example><![CDATA[
+class A  
+{  
+   int x;  
+   public virtual void PrintFields() {  
+      Console.WriteLine("x = {0}", x);  
+   }  
+}  
+class B: A  
+{  
+   int y;  
+   public override void PrintFields() {  
+      base.PrintFields();  
+      Console.WriteLine("y = {0}", y);  
+   }  
+}  
+]]></code_example>the base.PrintFields() invocation in B invokes the PrintFields method declared in A. A  <non_terminal where="14.5.8">base-access</non_terminal> disables the virtual invocation mechanism and simply treats the base method as a non-virtual method. </example></paragraph>
+  <paragraph>
+    <example>Had the invocation in B been written ((A)this).PrintFields(), it would recursively invoke the PrintFields method declared in B, not the one declared in A, since PrintFields is virtual and the  run-time type of ((A)this) is B. end example]</example>
+  </paragraph>
+  <paragraph>Only by including an override modifier can a method override another method. In all other cases, a method with the same signature as an inherited method simply hides the inherited method. <example>[Example: In the example <code_example><![CDATA[
+class A  
+{  
+   public virtual void F() {}  
+}  
+class B: A  
+{  
+   public virtual void F() {}   // Warning, hiding inherited F()  
+}  
+]]></code_example>the F method in B does not include an override modifier and therefore does not override the F method in A. Rather, the F method in B hides the method in A, and a warning is reported because the declaration does not include a new modifier. end example]</example> </paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+class A  
+{  
+   public virtual void F() {}  
+}  
+class B: A  
+{  
+   new private void F() {}     // Hides A.F within B  
+}  
+class C: B  
+{  
+   public override void F() {}  // Ok, overrides A.F  
+}  
+]]></code_example>the F method in B hides the virtual F method inherited from A. Since the new F in B has private access, its scope only includes the class body of B and does not extend to C. Therefore, the declaration of F in C is permitted to override the F inherited from A. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.5.5.xml b/mcs/docs/ecma334/17.5.5.xml
new file mode 100644 (file)
index 0000000..ba0351d
--- /dev/null
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<clause number="17.5.5" title="Sealed methods">
+  <paragraph>When an instance method declaration includes a sealed modifier, that method is said to be a sealed method. A sealed method overrides an inherited virtual method with the same signature. An override method can also be marked with the sealed modifier. Use of this modifier prevents a derived class from further overriding the method. </paragraph>
+  <paragraph>
+    <example>[Example: The example <code_example><![CDATA[
+using System;  
+class A  
+{  
+   public virtual void F() {  
+      Console.WriteLine("A.F");  
+   }  
+   public virtual void G() {  
+      Console.WriteLine("A.G");  
+   }  
+}  
+class B: A  
+{  
+   sealed override public void F() {  
+      Console.WriteLine("B.F");  
+   }   
+   override public void G() {  
+      Console.WriteLine("B.G");  
+   }   
+}  
+class C: B  
+{  
+   override public void G() {  
+      Console.WriteLine("C.G");  
+   }  
+}  
+]]></code_example>the class B provides two override methods: an F method that has the sealed modifier and a G method that does not. B's use of the sealed modifier prevents C from further overriding F. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.5.6.xml b/mcs/docs/ecma334/17.5.6.xml
new file mode 100644 (file)
index 0000000..d104fde
--- /dev/null
@@ -0,0 +1,57 @@
+<?xml version="1.0"?>
+<clause number="17.5.6" title="Abstract methods">
+  <paragraph>When an instance method declaration includes an abstract modifier, that method is said to be an abstract method. Although an abstract method is implicitly also a virtual method, it cannot have the modifier virtual. </paragraph>
+  <paragraph>An abstract method declaration introduces a new virtual method but does not provide an implementation of that method. Instead, non-abstract derived classes are required to provide their own implementation by overriding that method. Because an abstract method provides no actual implementation, the <non_terminal where="17.5">method-body</non_terminal> of an abstract method simply consists of a semicolon. </paragraph>
+  <paragraph>Abstract method declarations are only permitted in abstract classes (<hyperlink>17.1.1.1</hyperlink>). </paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+public abstract class Shape  
+{  
+   public abstract void Paint(Graphics g, Rectangle r);  
+}  
+public class Ellipse: Shape  
+{  
+   public override void Paint(Graphics g, Rectangle r) {  
+      g.DrawEllipse(r);  
+   }  
+}  
+public class Box: Shape  
+{  
+   public override void Paint(Graphics g, Rectangle r) {  
+      g.DrawRect(r);  
+   }  
+}  
+]]></code_example>the Shape class defines the abstract notion of a geometrical shape object that can paint itself. The Paint method is abstract because there is no meaningful default implementation. The Ellipse and Box classes are concrete Shape implementations. Because these classes are non-abstract, they are required to override the Paint method and provide an actual implementation. end example]</example>
+  </paragraph>
+  <paragraph>It is a compile-time error for a <non_terminal where="14.5.8">base-access</non_terminal> (<hyperlink>14.5.8</hyperlink>) to reference an abstract method. <example>[Example: In the example <code_example><![CDATA[
+abstract class A  
+{  
+   public abstract void F();  
+}  
+class B: A  
+{  
+   public override void F() {  
+      base.F();            // Error, base.F is abstract  
+   }  
+}  
+]]></code_example>a compile-time error is reported for the base.F() invocation because it references an abstract method. end example]</example> </paragraph>
+  <paragraph>An abstract method declaration is permitted to override a virtual method. This allows an abstract class to force re-implementation of the method in derived classes, and makes the original implementation of the method unavailable. <example>[Example: In the example <code_example><![CDATA[
+using System;  
+class A  
+{  
+   public virtual void F() {  
+      Console.WriteLine("A.F");  
+   }  
+}  
+abstract class B: A  
+{  
+   public abstract override void F();  
+}  
+class C: B  
+{  
+   public override void F() {  
+      Console.WriteLine("C.F");  
+   }  
+}  
+]]></code_example>class A declares a virtual method, class B overrides this method with an abstract method, and class C overrides that abstract method to provide its own implementation. end example]</example> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.5.7.xml b/mcs/docs/ecma334/17.5.7.xml
new file mode 100644 (file)
index 0000000..bee8b4b
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<clause number="17.5.7" title="External methods">
+  <paragraph>When a method declaration includes an extern modifier, the method is said to be an external method. External methods are implemented externally, typically using a language other than C#. Because an external method declaration provides no actual implementation, the <non_terminal where="17.5">method-body</non_terminal> of an external method simply consists of a semicolon. </paragraph>
+  <paragraph>The mechanism by which linkage to an external method is achieved, is implementation-defined. </paragraph>
+  <paragraph>
+    <example>[Example: The following example demonstrates the use of the extern modifier in combination with a DllImport attribute that specifies the name of the external library in which the method is implemented: <code_example><![CDATA[
+using System.Text;  
+using System.Security.Permissions;  
+using System.Runtime.InteropServices;  
+class Path  
+{  
+   [DllImport("kernel32", SetLastError=true)]  
+   static extern bool CreateDirectory(string name, SecurityAttribute sa);  
+   [DllImport("kernel32", SetLastError=true)]  
+   static extern bool RemoveDirectory(string name);  
+   [DllImport("kernel32", SetLastError=true)]  
+   static extern int GetCurrentDirectory(int bufSize, StringBuilder buf);  
+   [DllImport("kernel32", SetLastError=true)]  
+   static extern bool SetCurrentDirectory(string name);  
+}  
+]]></code_example>end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.5.8.xml b/mcs/docs/ecma334/17.5.8.xml
new file mode 100644 (file)
index 0000000..b4cd7f5
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<clause number="17.5.8" title="Method body">
+  <paragraph>The <non_terminal where="17.5">method-body</non_terminal> of a method declaration consists of either a block or a semicolon. </paragraph>
+  <paragraph>Abstract and external method declarations do not provide a method implementation, so their method bodies simply consist of a semicolon. For any other method, the method body is a block (<hyperlink>15.2</hyperlink>) that contains the statements to execute when that method is invoked. </paragraph>
+  <paragraph>When the return type of a method is <keyword>void</keyword>, return statements (<hyperlink>15.9.4</hyperlink>) in that method's body are not permitted to specify an expression. If execution of the method body of a <keyword>void</keyword> method completes normally (that is, control flows off the end of the method body), that method simply returns to its caller. </paragraph>
+  <paragraph>When the return type of a method is not <keyword>void</keyword>, each return statement in that method body must specify an expression of a type that is implicitly convertible to the return type. The endpoint of the method body of a value-returning method must not be reachable. In other words, in a value-returning method, control is not permitted to flow off the end of the method body. </paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+class A  
+{  
+   public int F() {}     // Error, return value required  
+   public int G() {  
+      return 1;  
+   }  
+   public int H(bool b) {  
+      if (b) {  
+         return 1;  
+      }  
+      else {  
+         return 0;  
+      }  
+   }  
+}  
+]]></code_example>the value-returning F method results in a compile-time error because control can flow off the end of the method body. The G and H methods are correct because all possible execution paths end in a return statement that specifies a return value. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.5.9.xml b/mcs/docs/ecma334/17.5.9.xml
new file mode 100644 (file)
index 0000000..106d970
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="17.5.9" title="Method overloading">
+  <paragraph>The method overload resolution rules are described in <hyperlink>14.4.2</hyperlink>. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.5.xml b/mcs/docs/ecma334/17.5.xml
new file mode 100644 (file)
index 0000000..7b6766e
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<clause number="17.5" title="Methods">
+  <paragraph>A method is a member that implements a computation or action that can be performed by an object or class. Methods are declared using method-declarations: <grammar_production><name><non_terminal where="17.5">method-declaration</non_terminal></name> : <rhs><non_terminal where="17.5">method-header</non_terminal><non_terminal where="17.5">method-body</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.5">method-header</non_terminal></name> : <rhs><non_terminal where="24.2">attributes</non_terminal><opt/><non_terminal where="17.5">method-modifiers</non_terminal><opt/><non_terminal where="17.5">return-type</non_terminal><non_terminal where="17.6">member-name</non_terminal><terminal>(</terminal><non_terminal where="17.5.1">formal-parameter-list</non_terminal><opt/><terminal>)</terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.5">method-modifier</non_terminal>s</name> : <rhs><non_terminal where="17.5">method-modifier</non_terminal></rhs><rhs><non_terminal where="17.5">method-modifiers</non_terminal><non_terminal where="17.5">method-modifier</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.5">method-modifier</non_terminal></name> : <rhs><keyword>new</keyword></rhs><rhs><keyword>public</keyword></rhs><rhs><keyword>protected</keyword></rhs><rhs><keyword>internal</keyword></rhs><rhs><keyword>private</keyword></rhs><rhs><keyword>static</keyword></rhs><rhs><keyword>virtual</keyword></rhs><rhs><keyword>sealed</keyword></rhs><rhs><keyword>override</keyword></rhs><rhs><keyword>abstract</keyword></rhs><rhs><keyword>extern</keyword></rhs></grammar_production><grammar_production><name><non_terminal where="17.5">return-type</non_terminal></name> : <rhs><non_terminal where="11">type</non_terminal></rhs><rhs><keyword>void</keyword></rhs></grammar_production><grammar_production><name><non_terminal where="17.6">member-name</non_terminal></name> : <rhs><non_terminal where="9.4.2">identifier</non_terminal></rhs><rhs><non_terminal where="11.2">interface-type</non_terminal><terminal>.</terminal><non_terminal where="9.4.2">identifier</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.5">method-body</non_terminal></name> : <rhs><non_terminal where="15.2">block</non_terminal></rhs><rhs><terminal>;</terminal></rhs></grammar_production></paragraph>
+  <paragraph>A <non_terminal where="17.5">method-declaration</non_terminal> may include a set of attributes (<hyperlink>24</hyperlink>) and a valid combination of the four access modifiers (<hyperlink>17.2.3</hyperlink>), the new (<hyperlink>17.2.2</hyperlink>), static (<hyperlink>17.5.2</hyperlink>), virtual (<hyperlink>17.5.3</hyperlink>), override (<hyperlink>17.5.4</hyperlink>), sealed (<hyperlink>17.5.5</hyperlink>), abstract (<hyperlink>17.5.6</hyperlink>), and extern (<hyperlink>17.5.7</hyperlink>) modifiers. </paragraph>
+  <paragraph>A declaration has a valid combination of modifiers if all of the following are true: <list><list_item> The declaration includes a valid combination of access modifiers (<hyperlink>17.2.3</hyperlink>). </list_item><list_item> The declaration does not include the same modifier multiple times. </list_item><list_item> The declaration includes at most one of the following modifiers: static, virtual, and override. </list_item><list_item> The declaration includes at most one of the following modifiers: new and override. </list_item><list_item> If the declaration includes the abstract modifier, then the declaration does not include any of the following modifiers: static, virtual, or extern. </list_item><list_item> If the declaration includes the private modifier, then the declaration does not include any of the following modifiers: virtual, override, or abstract. </list_item><list_item> If the declaration includes the sealed modifier, then the declaration also includes the override modifier. </list_item></list></paragraph>
+  <paragraph>The <non_terminal where="17.5">return-type</non_terminal> of a method declaration specifies the type of the value computed and returned by the method. The <non_terminal where="17.5">return-type</non_terminal> is <keyword>void</keyword> if the method does not return a value. </paragraph>
+  <paragraph>The <non_terminal where="17.6">member-name</non_terminal> specifies the name of the method. Unless the method is an explicit interface member implementation (<hyperlink>20.4.1</hyperlink>), the <non_terminal where="17.6">member-name</non_terminal> is simply an identifier. For an explicit interface member implementation, the <non_terminal where="17.6">member-name</non_terminal> consists of an <non_terminal where="11.2">interface-type</non_terminal> followed by a &quot;.&quot; and an identifier. </paragraph>
+  <paragraph>The optional <non_terminal where="17.5.1">formal-parameter-list</non_terminal> specifies the parameters of the method (<hyperlink>17.5.1</hyperlink>). </paragraph>
+  <paragraph>The <non_terminal where="17.5">return-type</non_terminal> and each of the types referenced in the <non_terminal where="17.5.1">formal-parameter-list</non_terminal> of a method must be at least as accessible as the method itself (<hyperlink>10.5.4</hyperlink>). </paragraph>
+  <paragraph>For abstract and extern methods, the <non_terminal where="17.5">method-body</non_terminal> consists simply of a semicolon. For all other methods, the <non_terminal where="17.5">method-body</non_terminal> consists of a block, which specifies the statements to execute when the method is invoked. </paragraph>
+  <paragraph>The name and the formal parameter list of a method define the signature (<hyperlink>10.6</hyperlink>) of the method. Specifically, the signature of a method consists of its name and the number, modifiers, and types of its formal parameters. The return type is not part of a method's signature, nor are the names of the formal parameters. </paragraph>
+  <paragraph>The name of a method must differ from the names of all other non-methods declared in the same class. In addition, the signature of a method must differ from the signatures of all other methods declared in the same class. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.6.1.xml b/mcs/docs/ecma334/17.6.1.xml
new file mode 100644 (file)
index 0000000..50ff08c
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<clause number="17.6.1" title="Static and instance properties">
+  <paragraph>When a property declaration includes a static modifier, the property is said to be a static property. When no static modifier is present, the property is said to be an instance property. </paragraph>
+  <paragraph>A static property is not associated with a specific instance, and it is a compile-time error to refer to this in the accessors of a static property. </paragraph>
+  <paragraph>An instance property is associated with a given instance of a class, and that instance can be accessed as this (<hyperlink>14.5.7</hyperlink>) in the accessors of that property. </paragraph>
+  <paragraph>When a property is referenced in a <non_terminal where="14.5.4">member-access</non_terminal> (<hyperlink>14.5.4</hyperlink>) of the form E.M, if M is a static property, E must denote a type that has a property M, and if M is an instance property, E must denote an instance having a property M. </paragraph>
+  <paragraph>The differences between static and instance members are discussed further in <hyperlink>17.2.5</hyperlink>. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.6.2.xml b/mcs/docs/ecma334/17.6.2.xml
new file mode 100644 (file)
index 0000000..15eef41
--- /dev/null
@@ -0,0 +1,180 @@
+<?xml version="1.0"?>
+<clause number="17.6.2" title="Accessors">
+  <paragraph>The <non_terminal where="17.6.2">accessor-declarations</non_terminal> of a property specify the executable statements associated with reading and writing that property. <grammar_production><name><non_terminal where="17.6.2">accessor-declarations</non_terminal></name> : <rhs><non_terminal where="17.6.2">get-accessor-declaration</non_terminal><non_terminal where="17.6.2">set-accessor-declaration</non_terminal><opt/></rhs><rhs><non_terminal where="17.6.2">set-accessor-declaration</non_terminal><non_terminal where="17.6.2">get-accessor-declaration</non_terminal><opt/></rhs></grammar_production><grammar_production><name><non_terminal where="17.6.2">get-accessor-declaration</non_terminal></name> : <rhs><non_terminal where="24.2">attributes</non_terminal><opt/><terminal>get</terminal><non_terminal where="17.6.2">accessor-body</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.6.2">set-accessor-declaration</non_terminal></name> : <rhs><non_terminal where="24.2">attributes</non_terminal><opt/><terminal>set</terminal><non_terminal where="17.6.2">accessor-body</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.6.2">accessor-body</non_terminal></name> : <rhs><non_terminal where="15.2">block</non_terminal></rhs><rhs><terminal>;</terminal></rhs></grammar_production></paragraph>
+  <paragraph>The accessor declarations consist of a <non_terminal where="17.6.2">get-accessor-declaration</non_terminal>, a <non_terminal where="17.6.2">set-accessor-declaration</non_terminal>, or both. Each accessor declaration consists of the token get or set followed by an <non_terminal where="17.6.2">accessor-body</non_terminal>. For abstract and extern properties, the <non_terminal where="17.6.2">accessor-body</non_terminal> for each accessor specified is simply a semicolon. For the accessors of any non-abstract, non-extern property, the <non_terminal where="17.6.2">accessor-body</non_terminal> is a block which specifies the statements to be executed when the corresponding accessor is invoked. </paragraph>
+  <paragraph>A get accessor corresponds to a parameterless method with a return value of the property type. Except as the target of an assignment, when a property is referenced in an expression, the get accessor of the property is invoked to compute the value of the property (<hyperlink>14.1.1</hyperlink>). The body of a get accessor must conform to the rules for value-returning methods described in <hyperlink>17.5.8</hyperlink>. In particular, all return statements in the body of a get accessor must specify an expression that is implicitly convertible to the property type. Furthermore, the endpoint of a get accessor must not be reachable. </paragraph>
+  <paragraph>A set accessor corresponds to a method with a single value parameter of the property type and a <keyword>void</keyword> return type. The implicit parameter of a set accessor is always named value. When a property is referenced as the target of an assignment (<hyperlink>14.13</hyperlink>), or as the operand of ++ or  (<hyperlink>14.5.9</hyperlink>, --14.6.5), the set accessor is invoked with an argument (whose value is that of the right-hand side of the assignment or the operand of the ++ or  --operator) that provides the new value (<hyperlink>14.13.1</hyperlink>). The body of a set accessor must conform to the rules for <keyword>void</keyword> methods described in <hyperlink>17.5.8</hyperlink>. In particular, return statements in the set accessor body are not permitted to specify an expression. Since a set accessor implicitly has a parameter named value, it is a compile-time error for a local variable declaration in a set accessor to have that name. </paragraph>
+  <paragraph>Based on the presence or absence of the get and set accessors, a property is classified as follows: <list><list_item> A property that includes both a get accessor and a set accessor is said to be a read-write property. </list_item><list_item> A property that has only a get accessor is said to be a read-only property. It is a compile-time error for a read-only property to be the target of an assignment. </list_item><list_item> A property that has only a set accessor is said to be a write-only property. Except as the target of an assignment, it is a compile-time error to reference a write-only property in an expression. <note>[Note: The  pre-and postfix ++ and  --operators cannot be applied to write-only properties, since these operators read the old value of their operand before they write the new one. end note]</note> </list_item></list></paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+public class Button: Control  
+{  
+   private string caption;  
+   public string Caption {  
+      get {  
+         return caption;  
+      }  
+      set {  
+         if (caption != value) {  
+            caption = value;  
+            Repaint();  
+         }  
+      }  
+   }  
+   public override void Paint(Graphics g, Rectangle r) {  
+      // Painting code goes here  
+   }  
+}  
+]]></code_example>the Button control declares a public Caption property. The get accessor of the Caption property returns the string stored in the private caption field. The set accessor checks if the new value is different from the current value, and if so, it stores the new value and repaints the control. Properties often follow the pattern shown above: The get accessor simply returns a value stored in a private field, and the set accessor modifies that private field and then performs any additional actions required to fully update the state of the object. </example>
+  </paragraph>
+  <paragraph>
+    <example>Given the Button class above, the following is an example of use of the Caption property: <code_example><![CDATA[
+Button okButton = new Button();  
+okButton.Caption = "OK";      // Invokes set accessor  
+string s = okButton.Caption;    // Invokes get accessor  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>Here, the set accessor is invoked by assigning a value to the property, and the get accessor is invoked by referencing the property in an expression. end example]</example>
+  </paragraph>
+  <paragraph>The get and set accessors of a property are not distinct members, and it is not possible to declare the accessors of a property separately. <note>[Note: As such, it is not possible for the two accessors of a read-write property to have different accessibility. end note]</note> <example>[Example: The example <code_example><![CDATA[
+class A  
+{  
+   private string name;  
+   public string Name {       // Error, duplicate member name  
+      get { return name; }  
+   }  
+   public string Name {       // Error, duplicate member name  
+      set { name = value; }  
+   }  
+}  
+]]></code_example>does not declare a single read-write property. Rather, it declares two properties with the same name, one read-only and one write-only. Since two members declared in the same class cannot have the same name, the example causes a compile-time error to occur. end example]</example> </paragraph>
+  <paragraph>When a derived class declares a property by the same name as an inherited property, the derived property hides the inherited property with respect to both reading and writing. <example>[Example: In the example <code_example><![CDATA[
+class A  
+{  
+   public int P {  
+      set {...}  
+   }  
+}  
+class B: A  
+{  
+   new public int P {  
+      get {...}  
+   }  
+}  
+]]></code_example>the P property in B hides the P property in A with respect to both reading and writing. Thus, in the statements <code_example><![CDATA[
+B b = new B();  
+b.P = 1;     // Error, B.P is read-only  
+((A)b).P = 1;  // Ok, reference to A.P  
+]]></code_example>the assignment to b.P causes a compile-time error to be reported, since the read-only P property in B hides the write-only P property in A. Note, however, that a cast can be used to access the hidden P property. end example]</example> </paragraph>
+  <paragraph>Unlike public fields, properties provide a separation between an object's internal state and its public interface. <example>[Example: Consider the example: <code_example><![CDATA[
+class Label  
+{  
+   private int x, y;  
+   private string caption;  
+   public Label(int x, int y, string caption) {  
+      this.x = x;  
+      this.y = y;  
+      this.caption = caption;  
+   }  
+   public int X {  
+      get { return x; }  
+   }  
+   public int Y {  
+      get { return y; }  
+   }  
+   public Point Location {  
+      get { return new Point(x, y); }  
+   }  
+   public string Caption {  
+      get { return caption; }  
+   }  
+}  
+]]></code_example></example></paragraph>
+  <paragraph>
+    <example>Here, the Label class uses two <keyword>int</keyword> fields, x and y, to store its location. The location is publicly exposed both as an X and a Y property and as a Location property of type Point. If, in a future version of Label, it becomes more convenient to store the location as a Point internally, the change can be made without affecting the public interface of the class: <code_example><![CDATA[
+class Label  
+{  
+   private Point location;  
+   private string caption;  
+   public Label(int x, int y, string caption) {  
+      this.location = new Point(x, y);  
+      this.caption = caption;  
+   }  
+   public int X {  
+      get { return location.x; }  
+   }  
+   public int Y {  
+      get { return location.y; }  
+   }  
+   public Point Location {  
+      get { return location; }  
+   }  
+   public string Caption {  
+      get { return caption; }  
+   }  
+}  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>Had x and y instead been public readonly fields, it would have been impossible to make such a change to the Label class. end example]</example>
+  </paragraph>
+  <paragraph>
+    <note>[Note: Exposing state through properties is not necessarily any less efficient than exposing fields directly. In particular, when a property is non-virtual and contains only a small amount of code, the execution environment may replace calls to accessors with the actual code of the accessors. This process is known as inlining, and it makes property access as efficient as field access, yet preserves the increased flexibility of properties. end note]</note>
+  </paragraph>
+  <paragraph>
+    <example>[Example: Since invoking a get accessor is conceptually equivalent to reading the value of a field, it is considered bad programming style for get accessors to have observable side-effects. In the example <code_example><![CDATA[
+class Counter  
+{  
+   private int next;  
+   public int Next {  
+      get { return next++; }  
+   }  
+}  
+]]></code_example>the value of the Next property depends on the number of times the property has previously been accessed. </example>
+  </paragraph>
+  <paragraph>
+    <example>Thus, accessing the property produces an observable side effect, and the property should be implemented as a method instead. end example]</example>
+  </paragraph>
+  <paragraph>
+    <note>[Note: The &quot;no side-effects&quot; convention for get accessors doesn't mean that get accessors should always be written to simply return values stored in fields. Indeed, get accessors often compute the value of a property by accessing multiple fields or invoking methods. However, a properly designed get accessor performs no actions that cause observable changes in the state of the object. end note]</note>
+  </paragraph>
+  <paragraph>Properties can be used to delay initialization of a resource until the moment it is first referenced. <example>[Example: For example: <code_example><![CDATA[
+using System.IO;  
+public class Console  
+{  
+   private static TextReader reader;  
+   private static TextWriter writer;  
+   private static TextWriter error;  
+   public static TextReader In {  
+      get {  
+         if (reader == null) {  
+            reader = new StreamReader(Console.OpenStandardInput());  
+         }  
+         return reader;  
+      }  
+   }  
+   public static TextWriter Out {  
+      get {  
+         if (writer == null) {  
+            writer = new StreamWriter(Console.OpenStandardOutput());  
+         }  
+         return writer;  
+      }  
+   }  
+   public static TextWriter Error {  
+      get {  
+         if (error == null) {  
+            error = new StreamWriter(Console.OpenStandardError());  
+         }  
+         return error;  
+      }  
+   }  
+}  
+]]></code_example></example></paragraph>
+  <paragraph>
+    <example>The Console class contains three properties, In, Out, and Error, that represent the standard input, output, and error devices, respectively. By exposing these members as properties, the Console class can delay their initialization until they are actually used. For example, upon first referencing the Out property, as in <code_example><![CDATA[
+Console.Out.WriteLine("hello, world");  
+]]></code_example>the underlying TextWriter for the output device is created. But if the application makes no reference to the In and Error properties, then no objects are created for those devices. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.6.3.xml b/mcs/docs/ecma334/17.6.3.xml
new file mode 100644 (file)
index 0000000..2976634
--- /dev/null
@@ -0,0 +1,53 @@
+<?xml version="1.0"?>
+<clause number="17.6.3" title="Virtual, sealed, override, and abstract accessors">
+  <paragraph>A virtual property declaration specifies that the accessors of the property are virtual. The virtual modifier applies to both accessors of a read-write property-it is not possible for only one accessor of a read-write property to be virtual. </paragraph>
+  <paragraph>An abstract property declaration specifies that the accessors of the property are virtual, but does not provide an actual implementation of the accessors. Instead, non-abstract derived classes are required to provide their own implementation for the accessors by overriding the property. Because an accessor for an abstract property declaration provides no actual implementation, its <non_terminal where="17.6.2">accessor-body</non_terminal> simply consists of a semicolon. </paragraph>
+  <paragraph>A property declaration that includes both the abstract and override modifiers specifies that the property is abstract and overrides a base property. The accessors of such a property are also abstract. </paragraph>
+  <paragraph>Abstract property declarations are only permitted in abstract classes (<hyperlink>17.1.1.1</hyperlink>). The accessors of an inherited virtual property can be overridden in a derived class by including a property declaration that specifies an override directive. This is known as an overriding property declaration. An overriding property declaration does not declare a new property. Instead, it simply specializes the implementations of the accessors of an existing virtual property. </paragraph>
+  <paragraph>An overriding property declaration must specify the exact same accessibility modifiers, type, and name as the inherited property. If the inherited property has only a single accessor (i.e., if the inherited property is read-only or write-only), the overriding property must include only that accessor. If the inherited property includes both accessors (i.e., if the inherited property is read-write), the overriding property can include either a single accessor or both accessors. </paragraph>
+  <paragraph>An overriding property declaration may include the sealed modifier. Use of this modifier prevents a derived class from further overriding the property. The accessors of a sealed property are also sealed. </paragraph>
+  <paragraph>Except for differences in declaration and invocation syntax, virtual, sealed, override, and abstract accessors behave exactly like virtual, sealed, override and abstract methods. Specifically, the rules described in <hyperlink>17.5.3</hyperlink>, <hyperlink>17.5.4</hyperlink>, <hyperlink>17.5.5</hyperlink>, and <hyperlink>17.5.6</hyperlink> apply as if accessors were methods of a corresponding form: <list><list_item> A get accessor corresponds to a parameterless method with a return value of the property type and the same modifiers as the containing property. </list_item><list_item> A set accessor corresponds to a method with a single value parameter of the property type, a <keyword>void</keyword> return type, and the same modifiers as the containing property. </list_item></list></paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+abstract class A  
+{  
+   int y;  
+   public virtual int X {  
+      get { return 0; }  
+   }  
+   public virtual int Y {  
+      get { return y; }  
+      set { y = value; }  
+   }  
+   public abstract int Z { get; set; }  
+}  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>X is a virtual read-only property, Y is a virtual read-write property, and Z is an abstract read-write property. </example>
+  </paragraph>
+  <paragraph>
+    <example>Because Z is abstract, the containing class A must also be declared abstract. </example>
+  </paragraph>
+  <paragraph>
+    <example>A class that derives from A is show below: <code_example><![CDATA[
+class B: A  
+{  
+   int z;  
+   public override int X {  
+      get { return base.X + 1; }  
+   }  
+   public override int Y {  
+      set { base.Y = value < 0? 0: value; }  
+   }  
+   public override int Z {  
+      get { return z; }  
+      set { z = value; }  
+   }  
+}  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>Here, the declarations of X, Y, and Z are overriding property declarations. Each property declaration exactly matches the accessibility modifiers, type, and name of the corresponding inherited property. The get accessor of X and the set accessor of Y use the base keyword to access the inherited accessors. The declaration of Z overrides both abstract accessors-thus, there are no outstanding abstract function members in B, and B is permitted to be a non-abstract class. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.6.xml b/mcs/docs/ecma334/17.6.xml
new file mode 100644 (file)
index 0000000..b72e425
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<clause number="17.6" title="Properties">
+  <paragraph>A property is a member that provides access to an attribute of an object or a class. Examples of properties include the length of a string, the size of a font, the caption of a window, the name of a customer, and so on. Properties are a natural extension of fields-both are named members with associated types, and the syntax for accessing fields and properties is the same. However, unlike fields, properties do not denote storage locations. Instead, properties have accessors that specify the statements to be executed when their values are read or written. Properties thus provide a mechanism for associating actions with the reading and writing of an object's attributes; furthermore, they permit such attributes to be computed. </paragraph>
+  <paragraph>Properties are declared using property-declarations: <grammar_production><name><non_terminal where="17.6">property-declaration</non_terminal></name> : <rhs><non_terminal where="24.2">attributes</non_terminal><opt/><non_terminal where="17.6">property-modifiers</non_terminal><opt/><non_terminal where="11">type</non_terminal><non_terminal where="17.6">member-name</non_terminal><terminal>{</terminal><non_terminal where="17.6.2">accessor-declarations</non_terminal><terminal>}</terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.6">property-modifier</non_terminal>s</name> : <rhs><non_terminal where="17.6">property-modifier</non_terminal></rhs><rhs><non_terminal where="17.6">property-modifiers</non_terminal><non_terminal where="17.6">property-modifier</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.6">property-modifier</non_terminal></name> : <rhs><keyword>new</keyword></rhs><rhs><keyword>public</keyword></rhs><rhs><keyword>protected</keyword></rhs><rhs><keyword>internal</keyword></rhs><rhs><keyword>private</keyword></rhs><rhs><keyword>static</keyword></rhs><rhs><keyword>virtual</keyword></rhs><rhs><keyword>sealed</keyword></rhs><rhs><keyword>override</keyword></rhs><rhs><keyword>abstract</keyword></rhs><rhs><keyword>extern</keyword></rhs></grammar_production><grammar_production><name><non_terminal where="17.6">member-name</non_terminal></name> : <rhs><non_terminal where="9.4.2">identifier</non_terminal></rhs><rhs><non_terminal where="11.2">interface-type</non_terminal><terminal>.</terminal><non_terminal where="9.4.2">identifier</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>A <non_terminal where="17.6">property-declaration</non_terminal> may include a set of attributes (<hyperlink>24</hyperlink>) and a valid combination of the four access modifiers (<hyperlink>17.2.3</hyperlink>), the new (<hyperlink>17.2.2</hyperlink>), static (<hyperlink>17.6.1</hyperlink>), virtual (<hyperlink>17.5.3</hyperlink>, <hyperlink>17.6.3</hyperlink>), override (<hyperlink>17.5.4</hyperlink>, <hyperlink>17.6.3</hyperlink>), sealed (<hyperlink>17.5.5</hyperlink>), abstract (<hyperlink>17.5.6</hyperlink>, <hyperlink>17.6.3</hyperlink>), and extern modifiers. </paragraph>
+  <paragraph>Property declarations are subject to the same rules as method declarations (<hyperlink>17.5</hyperlink>) with regard to valid combinations of modifiers. </paragraph>
+  <paragraph>The type of a property declaration specifies the type of the property introduced by the declaration, and the <non_terminal where="17.6">member-name</non_terminal> specifies the name of the property. Unless the property is an explicit interface member implementation, the <non_terminal where="17.6">member-name</non_terminal> is simply an identifier. For an explicit interface member implementation (<hyperlink>20.4.1</hyperlink>), the <non_terminal where="17.6">member-name</non_terminal> consists of an <non_terminal where="11.2">interface-type</non_terminal> followed by a &quot;.&quot; and an identifier. </paragraph>
+  <paragraph>The type of a property must be at least as accessible as the property itself (<hyperlink>10.5.4</hyperlink>). </paragraph>
+  <paragraph>The <non_terminal where="17.6.2">accessor-declarations</non_terminal>, which must be enclosed in &quot;{&quot; and &quot;}&quot; tokens, declare the accessors (<hyperlink>17.6.2</hyperlink>) of the property. The accessors specify the executable statements associated with reading and writing the property. </paragraph>
+  <paragraph>Even though the syntax for accessing a property is the same as that for a field, a property is not classified as a variable. Thus, it is not possible to pass a property as a ref or out argument. </paragraph>
+  <paragraph>When a property declaration includes an extern modifier, the property is said to be an external property. Because an external property declaration provides no actual implementation, each of its  <non_terminal where="17.6.2">accessor-declarations</non_terminal> consists of a semicolon. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.7.1.xml b/mcs/docs/ecma334/17.7.1.xml
new file mode 100644 (file)
index 0000000..1ccb896
--- /dev/null
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<clause number="17.7.1" title="Field-like events">
+  <paragraph>Within the program text of the class or struct that contains the declaration of an event, certain events can be used like fields. To be used in this way, an event must not be abstract or extern, and must not explicitly include <non_terminal where="17.7">event-accessor-declarations</non_terminal>. Such an event can be used in any context that permits a field. The field contains a delegate (<hyperlink>22</hyperlink>), which refers to the list of event handlers that have been added to the event. If no event handlers have been added, the field contains null. </paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+public delegate void EventHandler(object sender, EventArgs e);  
+public class Button: Control  
+{  
+   public event EventHandler Click;  
+   protected void OnClick(EventArgs e) {  
+      if (Click != null) Click(this, e);  
+   }  
+   public void Reset() {  
+      Click = null;  
+   }  
+}  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>Click is used as a field within the Button class. As the example demonstrates, the field can be examined, modified, and used in delegate invocation expressions. The OnClick method in the Button class &quot;raises&quot; the Click event. The notion of raising an event is precisely equivalent to invoking the delegate represented by the event-thus, there are no special language constructs for raising events. Note that the delegate invocation is preceded by a check that ensures the delegate is non-null. </example>
+  </paragraph>
+  <paragraph>
+    <example>Outside the declaration of the Button class, the Clickmember can only be used on the left-hand side of the += and -= operators, as in <code_example><![CDATA[
+b.Click += new EventHandler(...);  
+]]></code_example>which appends a delegate to the invocation list of the Click event, and <code_example><![CDATA[
+b.Click -= new EventHandler(...);  
+]]></code_example>which removes a delegate from the invocation list of the Click event. end example]</example>
+  </paragraph>
+  <paragraph>When compiling a field-like event, the compiler automatically creates storage to hold the delegate, and creates accessors for the event that add or remove event handlers to the delegate field. In order to be  thread-safe, the addition or removal operations are done while holding the lock (<hyperlink>15.12</hyperlink>) on the containing object for an instance event, or the type object (<hyperlink>14.5.11</hyperlink>) for a static event. </paragraph>
+  <paragraph>
+    <note>[Note: Thus, an instance event declaration of the form: <code_example><![CDATA[
+class X {  
+   public event D Ev;  
+}  
+]]></code_example>could be compiled to something equivalent to: <code_example><![CDATA[
+class X {  
+   private D __Ev;  // field to hold the delegate  
+   public event D Ev {  
+      add {  
+         lock(this) { __Ev = __Ev + value; }  
+      }  
+      remove {  
+         lock(this) { __Ev = __Ev - value; }  
+      }  
+   }  
+}  
+]]></code_example></note>
+  </paragraph>
+  <paragraph>
+    <note>Within the class X, references to Ev are compiled to reference the hidden field __Ev instead. The name &quot;__Ev&quot; is arbitrary; the hidden field could have any name or no name at all. </note>
+  </paragraph>
+  <paragraph>
+    <note>Similarly, a static event declaration of the form: <code_example><![CDATA[
+class X {  
+   public static event D Ev;  
+}  
+]]></code_example>could be compiled to something equivalent to: <code_example><![CDATA[
+class X {  
+   private static D __Ev;  // field to hold the delegate  
+   public static event D Ev {  
+      add {  
+         lock(typeof(X)) { __Ev = __Ev + value; }  
+      }  
+      remove {  
+         lock(typeof(X)) { __Ev = __Ev - value; }  
+      }  
+   }  
+}  
+]]></code_example>end note]</note>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.7.2.xml b/mcs/docs/ecma334/17.7.2.xml
new file mode 100644 (file)
index 0000000..2474cc3
--- /dev/null
@@ -0,0 +1,43 @@
+<?xml version="1.0"?>
+<clause number="17.7.2" title="Event accessors">
+  <paragraph>
+    <note>[Note: Event declarations typically omit <non_terminal where="17.7">event-accessor-declarations</non_terminal>, as in the Button example above. One situation for doing so involves the case in which the storage cost of one field per event is not acceptable. In such cases, a class can include <non_terminal where="17.7">event-accessor-declarations</non_terminal> and use a private mechanism for storing the list of event handlers. Similarly, in cases where the handling of an event requires access to external resources, event accessors may be used to manage these resources. end note]</note>
+  </paragraph>
+  <paragraph>The <non_terminal where="17.7">event-accessor-declarations</non_terminal> of an event specify the executable statements associated with adding and removing event handlers. </paragraph>
+  <paragraph>The accessor declarations consist of an <non_terminal where="17.7">add-accessor-declaration</non_terminal> and a <non_terminal where="17.7">remove-accessor-declaration</non_terminal>. Each accessor declaration consists of the token add or remove followed by a block. The block associated with an <non_terminal where="17.7">add-accessor-declaration</non_terminal> specifies the statements to execute when an event handler is added, and the block associated with a <non_terminal where="17.7">remove-accessor-declaration</non_terminal> specifies the statements to execute when an event handler is removed. </paragraph>
+  <paragraph>Each <non_terminal where="17.7">add-accessor-declaration</non_terminal> and <non_terminal where="17.7">remove-accessor-declaration</non_terminal> corresponds to a method with a single value parameter of the event type, and a <keyword>void</keyword> return type. The implicit parameter of an event accessor is named value. When an event is used in an event assignment, the appropriate event accessor is used. Specifically, if the assignment operator is += then the add accessor is used, and if the assignment operator is -= then the remove accessor is used. In either case, the right-hand operand of the assignment operator is used as the argument to the event accessor. The block of an <non_terminal where="17.7">add-accessor-declaration</non_terminal> or a  <non_terminal where="17.7">remove-accessor-declaration</non_terminal> must conform to the rules for <keyword>void</keyword> methods described in <hyperlink>17.5.8</hyperlink>. In particular, return statements in such a block are not permitted to specify an expression. </paragraph>
+  <paragraph>Since an event accessor implicitly has a parameter named value, it is a compile-time error for a local variable declared in an event accessor to have that name. </paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+class Control: Component  
+{  
+   // Unique keys for events  
+   static readonly object mouseDownEventKey = new object();  
+   static readonly object mouseUpEventKey = new object();  
+   // Return event handler associated with key  
+   protected Delegate GetEventHandler(object key) {...}  
+   // Add event handler associated with key  
+   protected void AddEventHandler(object key, Delegate handler) {...}  
+   // Remove event handler associated with key  
+   protected void RemoveEventHandler(object key, Delegate handler) {...}  
+   // MouseDown event  
+   public event MouseEventHandler MouseDown {  
+      add { AddEventHandler(mouseDownEventKey, value); }  
+      remove { RemoveEventHandler(mouseDownEventKey, value); }  
+   }  
+   // MouseUp event  
+   public event MouseEventHandler MouseUp {  
+      add { AddEventHandler(mouseUpEventKey, value); }  
+      remove { RemoveEventHandler(mouseUpEventKey, value); }  
+   }  
+   // Invoke the MouseUp event  
+   protected void OnMouseUp(MouseEventArgs args) {  
+      MouseEventHandler handler;   
+      handler = (MouseEventHandler)GetEventHandler(mouseUpEventKey);  
+      if (handler != null)  
+      handler(this, args);  
+   }  
+}  
+]]></code_example>the Control class implements an internal storage mechanism for events. The AddEventHandler method associates a delegate value with a key, the GetEventHandler method returns the delegate currently associated with a key, and the RemoveEventHandler method removes a delegate as an event handler for the specified event. Presumably, the underlying storage mechanism is designed such that there is no cost for associating a null delegate value with a key, and thus unhandled events consume no storage. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.7.3.xml b/mcs/docs/ecma334/17.7.3.xml
new file mode 100644 (file)
index 0000000..352bd1b
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<clause number="17.7.3" title="Static and instance events">
+  <paragraph>When an event declaration includes a static modifier, the event is said to be a static event. When no static modifier is present, the event is said to be an instance event. </paragraph>
+  <paragraph>A static event is not associated with a specific instance, and it is a compile-time error to refer to this in the accessors of a static event. </paragraph>
+  <paragraph>An instance event is associated with a given instance of a class, and this instance can be accessed as this (<hyperlink>14.5.7</hyperlink>) in the accessors of that event. </paragraph>
+  <paragraph>When an event is referenced in a <non_terminal where="14.5.4">member-access</non_terminal> (<hyperlink>14.5.4</hyperlink>) of the form E.M, if M is a static event, E must denote a type, and if M is an instance event, E must denote an instance. </paragraph>
+  <paragraph>The differences between static and instance members are discussed further in <hyperlink>17.2.5</hyperlink>. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.7.4.xml b/mcs/docs/ecma334/17.7.4.xml
new file mode 100644 (file)
index 0000000..7cb766a
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<clause number="17.7.4" title="Virtual, sealed, override, and abstract accessors">
+  <paragraph>A virtual event declaration specifies that the accessors of that event are virtual. The virtual modifier applies to both accessors of an event. </paragraph>
+  <paragraph>An abstract event declaration specifies that the accessors of the event are virtual, but does not provide an actual implementation of the accessors. Instead, non-abstract derived classes are required to provide their own implementation for the accessors by overriding the event. Because an accessor for an abstract event declaration provides no actual implementation, its <non_terminal where="17.6.2">accessor-body</non_terminal> simply consists of a semicolon. </paragraph>
+  <paragraph>An event declaration that includes both the abstract and override modifiers specifies that the event is abstract and overrides a base event. The accessors of such an event are also abstract. </paragraph>
+  <paragraph>Abstract event declarations are only permitted in abstract classes (<hyperlink>17.1.1.1</hyperlink>). </paragraph>
+  <paragraph>The accessors of an inherited virtual event can be overridden in a derived class by including an event declaration that specifies an override modifier. This is known as an overriding event declaration. An overriding event declaration does not declare a new event. Instead, it simply specializes the implementations of the accessors of an existing virtual event. </paragraph>
+  <paragraph>An overriding event declaration must specify the exact same accessibility modifiers, type, and name as the overridden event. </paragraph>
+  <paragraph>An overriding event declaration may include the sealed modifier. Use of this modifier prevents a derived class from further overriding the event. The accessors of a sealed event are also sealed. </paragraph>
+  <paragraph>It is a compile-time error for an overriding event declaration to include a new modifier. </paragraph>
+  <paragraph>Except for differences in declaration and invocation syntax, virtual, sealed, override, and abstract accessors behave exactly like virtual, sealed, override and abstract methods. Specifically, the rules described in <hyperlink>17.5.3</hyperlink>, <hyperlink>17.5.4</hyperlink>, <hyperlink>17.5.5</hyperlink>, and <hyperlink>17.5.6</hyperlink> apply as if accessors were methods of a corresponding form. Each accessor corresponds to a method with a single value parameter of the event type, a <keyword>void</keyword> return type, and the same modifiers as the containing event. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.7.xml b/mcs/docs/ecma334/17.7.xml
new file mode 100644 (file)
index 0000000..b4383e5
--- /dev/null
@@ -0,0 +1,44 @@
+<?xml version="1.0"?>
+<clause number="17.7" title="Events">
+  <paragraph>An event is a member that enables an object or class to provide notifications. Clients can attach executable code for events by supplying event handlers. </paragraph>
+  <paragraph>Events are declared using event-declarations: <grammar_production><name><non_terminal where="17.7">event-declaration</non_terminal></name> : <rhs><non_terminal where="24.2">attributes</non_terminal><opt/><non_terminal where="17.7">event-modifiers</non_terminal><opt/><keyword>event</keyword><non_terminal where="11">type</non_terminal><non_terminal where="17.4">variable-declarators</non_terminal><terminal>;</terminal></rhs><rhs><non_terminal where="24.2">attributes</non_terminal><opt/><non_terminal where="17.7">event-modifiers</non_terminal><opt/><keyword>event</keyword><non_terminal where="11">type</non_terminal><non_terminal where="17.6">member-name</non_terminal><terminal>{</terminal><non_terminal where="17.7">event-accessor-declarations</non_terminal><terminal>}</terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.7">event-modifier</non_terminal>s</name> : <rhs><non_terminal where="17.7">event-modifier</non_terminal></rhs><rhs><non_terminal where="17.7">event-modifiers</non_terminal><non_terminal where="17.7">event-modifier</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.7">event-modifier</non_terminal></name> : <rhs><keyword>new</keyword></rhs><rhs><keyword>public</keyword></rhs><rhs><keyword>protected</keyword></rhs><rhs><keyword>internal</keyword></rhs><rhs><keyword>private</keyword></rhs><rhs><keyword>static</keyword></rhs><rhs><keyword>virtual</keyword></rhs><rhs><keyword>sealed</keyword></rhs><rhs><keyword>override</keyword></rhs><rhs><keyword>abstract</keyword></rhs><rhs><keyword>extern</keyword></rhs></grammar_production><grammar_production><name><non_terminal where="17.7">event-accessor-declarations</non_terminal></name> : <rhs><non_terminal where="17.7">add-accessor-declaration</non_terminal><non_terminal where="17.7">remove-accessor-declaration</non_terminal></rhs><rhs><non_terminal where="17.7">remove-accessor-declaration</non_terminal><non_terminal where="17.7">add-accessor-declaration</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.7">add-accessor-declaration</non_terminal></name> : <rhs><non_terminal where="24.2">attributes</non_terminal><opt/><terminal>add</terminal><non_terminal where="15.2">block</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.7">remove-accessor-declaration</non_terminal></name> : <rhs><non_terminal where="24.2">attributes</non_terminal><opt/><terminal>remove</terminal><non_terminal where="15.2">block</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>An <non_terminal where="17.7">event-declaration</non_terminal> may include a set of attributes (<hyperlink>24</hyperlink>) and a valid combination of the four access modifiers (<hyperlink>17.2.3</hyperlink>), the new (<hyperlink>17.2.2</hyperlink>), static (<hyperlink>17.5.2</hyperlink>, <hyperlink>17.7.3</hyperlink>), virtual (<hyperlink>17.5.3</hyperlink>, <hyperlink>17.7.4</hyperlink>), override (<hyperlink>17.5.4</hyperlink>, <hyperlink>17.7.4</hyperlink>), sealed (<hyperlink>17.5.5</hyperlink>), abstract (<hyperlink>17.5.6</hyperlink>, <hyperlink>17.7.4</hyperlink>), and extern modifiers. </paragraph>
+  <paragraph>Event declarations are subject to the same rules as method declarations (<hyperlink>17.5</hyperlink>) with regard to valid combinations of modifiers. </paragraph>
+  <paragraph>The type of an event declaration must be a <non_terminal where="11.2">delegate-type</non_terminal> (<hyperlink>11.2</hyperlink>), and that <non_terminal where="11.2">delegate-type</non_terminal> must be at least as accessible as the event itself (<hyperlink>10.5.4</hyperlink>). </paragraph>
+  <paragraph>An event declaration may include <non_terminal where="17.7">event-accessor-declarations</non_terminal>. However, if it does not, for non-extern,  non-abstract events, the compiler shall supply them automatically (<hyperlink>17.7.1</hyperlink>); for extern events, the accessors are provided externally. </paragraph>
+  <paragraph>An event declaration that omits <non_terminal where="17.7">event-accessor-declarations</non_terminal> defines one or more events-one for each of the <non_terminal where="17.4">variable-declarator</non_terminal>s. The attributes and modifiers apply to all of the members declared by such an  <non_terminal where="17.7">event-declaration</non_terminal>. </paragraph>
+  <paragraph>It is a compile-time error for an <non_terminal where="17.7">event-declaration</non_terminal> to include both the abstract modifier and  brace-delimited <non_terminal where="17.7">event-accessor-declarations</non_terminal>. </paragraph>
+  <paragraph>When an event declaration includes an extern modifier, the event is said to be an external event. Because an external event declaration provides no actual implementation, it is an error for it to include both the extern modifier and <non_terminal where="17.7">event-accessor-declarations</non_terminal>. </paragraph>
+  <paragraph>An event can be used as the left-hand operand of the += and -= operators (<hyperlink>14.13.3</hyperlink>). These operators are used, respectively, to attach event handlers to, or to remove event handlers from an event, and the access modifiers of the event control the contexts in which such operations are permitted. </paragraph>
+  <paragraph>Since += and -= are the only operations that are permitted on an event outside the type that declares the event, external code can add and remove handlers for an event, but cannot in any other way obtain or modify the underlying list of event handlers. </paragraph>
+  <paragraph>In an operation of the form x += y or x -= y, when x is an event and the reference takes place outside the type that contains the declaration of x, the result of the operation has type <keyword>void</keyword> (as opposed to having the type of x, with the value of x after the assignment). This rule prohibits external code from indirectly examining the underlying delegate of an event. </paragraph>
+  <paragraph>
+    <example>[Example: The following example shows how event handlers are attached to instances of the Button class: <code_example><![CDATA[
+public delegate void EventHandler(object sender, EventArgs e);  
+public class Button: Control  
+{  
+   public event EventHandler Click;  
+}  
+public class LoginDialog: Form  
+{  
+   Button OkButton;  
+   Button CancelButton;  
+   public LoginDialog() {  
+      OkButton = new Button(...);  
+      OkButton.Click += new EventHandler(OkButtonClick);  
+      CancelButton = new Button(...);  
+      CancelButton.Click += new EventHandler(CancelButtonClick);  
+   }  
+   void OkButtonClick(object sender, EventArgs e) {  
+      // Handle OkButton.Click event  
+   }  
+   void CancelButtonClick(object sender, EventArgs e) {  
+      // Handle CancelButton.Click event  
+   }  
+}  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>Here, the LoginDialog instance constructor creates two Button instances and attaches event handlers to the Click events. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.8.1.xml b/mcs/docs/ecma334/17.8.1.xml
new file mode 100644 (file)
index 0000000..03e92e6
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="17.8.1" title="Indexer overloading">
+  <paragraph>The indexer overload resolution rules are described in <hyperlink>14.4.2</hyperlink>. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.8.xml b/mcs/docs/ecma334/17.8.xml
new file mode 100644 (file)
index 0000000..bf8f2bd
--- /dev/null
@@ -0,0 +1,119 @@
+<?xml version="1.0"?>
+<clause number="17.8" title="Indexers">
+  <paragraph>An indexer is a member that enables an object to be indexed in the same way as an array. Indexers are declared using indexer-declarations: <grammar_production><name><non_terminal where="17.8">indexer-declaration</non_terminal></name> : <rhs><non_terminal where="24.2">attributes</non_terminal><opt/><non_terminal where="17.8">indexer-modifiers</non_terminal><opt/><non_terminal where="17.8">indexer-declarator</non_terminal><terminal>{</terminal><non_terminal where="17.6.2">accessor-declarations</non_terminal><terminal>}</terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.8">indexer-modifier</non_terminal>s</name> : <rhs><non_terminal where="17.8">indexer-modifier</non_terminal></rhs><rhs><non_terminal where="17.8">indexer-modifiers</non_terminal><non_terminal where="17.8">indexer-modifier</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.8">indexer-modifier</non_terminal></name> : <rhs><keyword>new</keyword></rhs><rhs><keyword>public</keyword></rhs><rhs><keyword>protected</keyword></rhs><rhs><keyword>internal</keyword></rhs><rhs><keyword>private</keyword></rhs><rhs><keyword>virtual</keyword></rhs><rhs><keyword>sealed</keyword></rhs><rhs><keyword>override</keyword></rhs><rhs><keyword>abstract</keyword></rhs><rhs><keyword>extern</keyword></rhs></grammar_production><grammar_production><name><non_terminal where="17.8">indexer-declarator</non_terminal></name> : <rhs><non_terminal where="11">type</non_terminal><keyword>this</keyword><terminal>[</terminal><non_terminal where="17.5.1">formal-parameter-list</non_terminal><terminal>]</terminal></rhs><rhs><non_terminal where="11">type</non_terminal><non_terminal where="11.2">interface-type</non_terminal><terminal>.</terminal><keyword>this</keyword><terminal>[</terminal><non_terminal where="17.5.1">formal-parameter-list</non_terminal><terminal>]</terminal></rhs></grammar_production></paragraph>
+  <paragraph>An <non_terminal where="17.8">indexer-declaration</non_terminal> may include a set of attributes (<hyperlink>24</hyperlink>) and a valid combination of the four access modifiers (<hyperlink>17.2.3</hyperlink>), the new (<hyperlink>17.2.2</hyperlink>), virtual (<hyperlink>17.5.3</hyperlink>), override (<hyperlink>17.5.4</hyperlink>), sealed (<hyperlink>17.5.5</hyperlink>), abstract (<hyperlink>17.5.6</hyperlink>), and extern (<hyperlink>17.5.7</hyperlink>) modifiers. </paragraph>
+  <paragraph>Indexer declarations are subject to the same rules as method declarations (<hyperlink>17.5</hyperlink>) with regard to valid combinations of modifiers, with the one exception being that the static modifier is not permitted on an indexer declaration. </paragraph>
+  <paragraph>The modifiers virtual, override, and abstract are mutually exclusive except in one case. The abstract and override modifiers may be used together so that an abstract indexer can override a virtual one. </paragraph>
+  <paragraph>The type of an indexer declaration specifies the element type of the indexer introduced by the declaration. Unless the indexer is an explicit interface member implementation, the type is followed by the keyword this. For an explicit interface member implementation, the type is followed by an <non_terminal where="11.2">interface-type</non_terminal>, a &quot;.&quot;, and the keyword this. Unlike other members, indexers do not have user-defined names. </paragraph>
+  <paragraph>The <non_terminal where="17.5.1">formal-parameter-list</non_terminal> specifies the parameters of the indexer. The formal parameter list of an indexer corresponds to that of a method (<hyperlink>17.5.1</hyperlink>), except that at least one parameter must be specified, and that the ref and out parameter modifiers are not permitted. </paragraph>
+  <paragraph>The type of an indexer and each of the types referenced in the <non_terminal where="17.5.1">formal-parameter-list</non_terminal> must be at least as accessible as the indexer itself (<hyperlink>10.5.4</hyperlink>). </paragraph>
+  <paragraph>The <non_terminal where="17.6.2">accessor-declarations</non_terminal> (<hyperlink>17.6.2</hyperlink>), which must be enclosed in &quot;{&quot; and &quot;}&quot; tokens, declare the accessors of the indexer. The accessors specify the executable statements associated with reading and writing indexer elements. </paragraph>
+  <paragraph>Even though the syntax for accessing an indexer element is the same as that for an array element, an indexer element is not classified as a variable. Thus, it is not possible to pass an indexer element as a ref or out argument. </paragraph>
+  <paragraph>The <non_terminal where="17.5.1">formal-parameter-list</non_terminal> of an indexer defines the signature (<hyperlink>10.6</hyperlink>) of the indexer. Specifically, the signature of an indexer consists of the number and types of its formal parameters. The element type and names of the formal parameters are not part of an indexer's signature. </paragraph>
+  <paragraph>The signature of an indexer must differ from the signatures of all other indexers declared in the same class. </paragraph>
+  <paragraph>Indexers and properties are very similar in concept, but differ in the following ways: <list><list_item> A property is identified by its name, whereas an indexer is identified by its signature. </list_item><list_item> A property is accessed through a <non_terminal where="14.5.2">simple-name</non_terminal> (<hyperlink>14.5.2</hyperlink>) or a <non_terminal where="14.5.4">member-access</non_terminal> (<hyperlink>14.5.4</hyperlink>), whereas an indexer element is accessed through an <non_terminal where="14.5.6">element-access</non_terminal> (<hyperlink>14.5.6.2</hyperlink>). </list_item><list_item> A property can be a static member, whereas an indexer is always an instance member. </list_item><list_item> A get accessor of a property corresponds to a method with no parameters, whereas a get accessor of an indexer corresponds to a method with the same formal parameter list as the indexer. </list_item><list_item> A set accessor of a property corresponds to a method with a single parameter named value, whereas a set accessor of an indexer corresponds to a method with the same formal parameter list as the indexer, plus an additional parameter named value. </list_item><list_item> It is a compile-time error for an indexer accessor to declare a local variable with the same name as an indexer parameter. </list_item><list_item> In an overriding property declaration, the inherited property is accessed using the syntax base.P, where P is the property name. In an overriding indexer declaration, the inherited indexer is accessed using the syntax base[E], where E is a comma-separated list of expressions. </list_item></list></paragraph>
+  <paragraph>Aside from these differences, all rules defined in <hyperlink>17.6.2</hyperlink> and <hyperlink>17.6.3</hyperlink> apply to indexer accessors as well as to property accessors. </paragraph>
+  <paragraph>When an indexer declaration includes an extern modifier, the indexer is said to be an external indexer. Because an external indexer declaration provides no actual implementation, each of its  <non_terminal where="17.6.2">accessor-declarations</non_terminal> consists of a semicolon. </paragraph>
+  <paragraph>
+    <example>[Example: The example below declares a BitArray class that implements an indexer for accessing the individual bits in the bit array. <code_example><![CDATA[
+using System;  
+class BitArray  
+{  
+   int[] bits;  
+   int length;  
+   public BitArray(int length) {  
+      if (length < 0) throw new ArgumentException();  
+      bits = new int[((length - 1) >> 5) + 1];  
+      this.length = length;  
+   }  
+   public int Length {  
+      get { return length; }  
+   }  
+   public bool this[int index] {  
+      get {  
+         if (index < 0 || index >= length) {  
+            throw new IndexOutOfRangeException();  
+         }  
+         return (bits[index >> 5] & 1 << index) != 0;  
+      }  
+      set {  
+         if (index < 0 || index >= length) {  
+            throw new IndexOutOfRangeException();  
+         }  
+         if (value) {  
+            bits[index >> 5] |= 1 << index;  
+         }  
+         else {  
+            bits[index >> 5] &= ~(1 << index);  
+         }  
+      }  
+   }  
+}  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>An instance of the BitArray class consumes substantially less memory than a corresponding bool[] (since each value of the former occupies only one bit instead of the latter's one <keyword>byte</keyword>), but it permits the same operations as a bool[]. </example>
+  </paragraph>
+  <paragraph>
+    <example>The following CountPrimes class uses a BitArray and the classical &quot;sieve&quot; algorithm to compute the number of primes between 1 and a given maximum: <code_example><![CDATA[
+class CountPrimes  
+{  
+   static int Count(int max) {  
+      BitArray flags = new BitArray(max + 1);  
+      int count = 1;  
+      for (int i = 2; i <= max; i++) {  
+         if (!flags[i]) {  
+            for (int j = i * 2; j <= max; j += i) flags[j] = true;  
+            count++;  
+         }  
+      }  
+      return count;  
+   }  
+   static void Main(string[] args) {  
+      int max = int.Parse(args[0]);  
+      int count = Count(max);  
+      Console.WriteLine("Found {0} primes between 1 and {1}", count,  
+      max);  
+   }  
+}  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>Note that the syntax for accessing elements of the BitArray is precisely the same as for a bool[]. end example]</example>
+  </paragraph>
+  <paragraph>
+    <example>[Example: The following example shows a 26<unicode>215</unicode>10 grid class that has an indexer with two parameters. The first parameter is required to be an  upper-or lowercase letter in the range A-Z, and the second is required to be an integer in the range 0-9. <code_example><![CDATA[
+using System;  
+class Grid  
+{  
+   const int NumRows = 26;  
+   const int NumCols = 10;  
+   int[,] cells = new int[NumRows, NumCols];  
+   
+   public int this[char c, int colm]  
+   {  
+      get {  
+         c = Char.ToUpper(c);  
+         if (c < 'A' || c > 'Z') {  
+            throw new ArgumentException();  
+         }  
+         if (colm < 0 || colm >= NumCols) {  
+            throw new IndexOutOfRangeException();  
+         }  
+         return cells[c - 'A', colm];  
+      }  
+      set {  
+         c = Char.ToUpper(c);  
+         if (c < 'A' || c > 'Z') {  
+            throw new ArgumentException();  
+         }  
+         if (colm < 0 || colm >= NumCols) {  
+            throw new IndexOutOfRangeException();  
+         }  
+         cells[c - 'A', colm] = value;  
+      }  
+   }  
+}  
+]]></code_example>end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.9.1.xml b/mcs/docs/ecma334/17.9.1.xml
new file mode 100644 (file)
index 0000000..652cdc7
--- /dev/null
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+<clause number="17.9.1" title="Unary operators">
+  <paragraph>The following rules apply to unary operator declarations, where T denotes the class or struct type that contains the operator declaration: <list><list_item> A unary +, -, !, or ~ operator must take a single parameter of type T and can return any type. </list_item><list_item> A unary ++ or  --operator must take a single parameter of type T and must return type T. </list_item><list_item> A unary true or false operator must take a single parameter of type T and must return type <keyword>bool</keyword>. </list_item></list></paragraph>
+  <paragraph>The signature of a unary operator consists of the operator token (+, -, !, ~, ++, --, true, or false) and the type of the single formal parameter. The return type is not part of a unary operator's signature, nor is the name of the formal parameter. </paragraph>
+  <paragraph>The true and false unary operators require pair-wise declaration. A compile-time error occurs if a class declares one of these operators without also declaring the other. The true and false operators are described further in <hyperlink>14.16</hyperlink>. </paragraph>
+  <paragraph>
+    <example>[Example: The following example shows an implementation and subsequent usage of operator++ for an integer vector class: <code_example><![CDATA[
+public class IntVector  
+{  
+   public int Length { ... }    // read-only property  
+   public int this[int index] { ... } // read-write indexer  
+   public IntVector(int vectorLength) { ... }  
+   public static IntVector operator++(IntVector iv) {  
+      IntVector temp = new IntVector(iv.Length);  
+      for (int i = 0; i < iv.Length; ++i)  
+      temp[i] = iv[i] + 1;  
+      return temp;  
+   }  
+}  
+class Test  
+{  
+   static void Main() {  
+      IntVector iv1 = new IntVector(4);  // vector of 4x0  
+      IntVector iv2;  
+      
+      iv2 = iv1++;  // iv2 contains 4x0, iv1 contains 4x1  
+      iv2 = ++iv1;  // iv2 contains 4x2, iv1 contains 4x2  
+   }  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>Note how the operator method returns the value produced by adding 1 to the operand, just like the postfix increment and decrement operators(<hyperlink>14.5.9</hyperlink>), and the prefix increment and decrement operators (<hyperlink>14.6.5</hyperlink>). </example>
+  </paragraph>
+  <paragraph>
+    <example>Unlike in C++, this method need not, and, in fact, must not, modify the value of its operand directly. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.9.2.xml b/mcs/docs/ecma334/17.9.2.xml
new file mode 100644 (file)
index 0000000..b4173c3
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="17.9.2" title="Binary operators">
+  <paragraph>A binary operator must take two parameters, at least one of which must have the class or struct type in which the operator is declared. A binary operator can return any type. </paragraph>
+  <paragraph>The signature of a binary operator consists of the operator token (+, -, *, /, %, &amp;, |, ^, &lt;&lt;, &gt;&gt;, ==, !=, &gt;, &lt;, &gt;=, or &lt;=) and the types of the two formal parameters. The return type and the names of the formal parameters are not part of a binary operator's signature. </paragraph>
+  <paragraph>Certain binary operators require pair-wise declaration. For every declaration of either operator of a pair, there must be a matching declaration of the other operator of the pair. Two operator declarations match when they have the same return type and the same type for each parameter. The following operators require  pair-wise declaration: <list><list_item> operator == and operator != </list_item><list_item> operator &gt; and operator &lt; </list_item><list_item> operator &gt;= and operator &lt;= </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.9.3.xml b/mcs/docs/ecma334/17.9.3.xml
new file mode 100644 (file)
index 0000000..4874dc7
--- /dev/null
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<clause number="17.9.3" title="Conversion operators">
+  <paragraph>A conversion operator declaration introduces a user-defined conversion (<hyperlink>13.4</hyperlink>), which augments the  pre-defined implicit and explicit conversions. </paragraph>
+  <paragraph>A conversion operator declaration that includes the implicit keyword introduces a user-defined implicit conversion. Implicit conversions can occur in a variety of situations, including function member invocations, cast expressions, and assignments. This is described further in <hyperlink>13.1</hyperlink>. </paragraph>
+  <paragraph>A conversion operator declaration that includes the explicit keyword introduces a user-defined explicit conversion. Explicit conversions can occur in cast expressions, and are described further in <hyperlink>13.2</hyperlink>. </paragraph>
+  <paragraph>A conversion operator converts from a source type, indicated by the parameter type of the conversion operator, to a target type, indicated by the return type of the conversion operator. A class or struct is permitted to declare a conversion from a source type S to a target type T provided all of the following are true: <list><list_item> S and T are different types. </list_item><list_item> Either S or T is the class or struct type in which the operator declaration takes place. </list_item><list_item> Neither S nor T is object or an <non_terminal where="11.2">interface-type</non_terminal>. </list_item><list_item> T is not a base class of S, and S is not a base class of T. </list_item></list></paragraph>
+  <paragraph>From the second rule it follows that a conversion operator must convert either to or from the class or struct type in which the operator is declared. <example>[Example: For example, it is possible for a class or struct type C to define a conversion from C to <keyword>int</keyword> and from <keyword>int</keyword> to C, but not from <keyword>int</keyword> to <keyword>bool</keyword>. end example]</example> </paragraph>
+  <paragraph>It is not possible to redefine a pre-defined conversion. Thus, conversion operators are not allowed to convert from or to object because implicit and explicit conversions already exist between object and all other types. Likewise, neither the source nor the target types of a conversion can be a base type of the other, since a conversion would then already exist. </paragraph>
+  <paragraph>User-defined conversions are not allowed to convert from or to <non_terminal where="11.2">interface-type</non_terminal>s. In particular, this restriction ensures that no user-defined transformations occur when converting to an <non_terminal where="11.2">interface-type</non_terminal>, and that a conversion to an <non_terminal where="11.2">interface-type</non_terminal> succeeds only if the object being converted actually implements the specified <non_terminal where="11.2">interface-type</non_terminal>. </paragraph>
+  <paragraph>The signature of a conversion operator consists of the source type and the target type. (Note that this is the only form of member for which the return type participates in the signature.) The implicit or explicit classification of a conversion operator is not part of the operator's signature. Thus, a class or struct cannot declare both an implicit and an explicit conversion operator with the same source and target types. </paragraph>
+  <paragraph>
+    <note>[Note: In general, user-defined implicit conversions should be designed to never throw exceptions and never lose information. If a user-defined conversion can give rise to exceptions (for example, because the source argument is out of range) or loss of information (such as discarding high-order bits), then that conversion should be defined as an explicit conversion. end note]</note>
+  </paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+using System;  
+public struct Digit  
+{  
+   byte value;  
+   public Digit(byte value) {  
+      if (value < 0 || value > 9) throw new ArgumentException();  
+      this.value = value;  
+   }  
+   public static implicit operator byte(Digit d) {  
+      return d.value;  
+   }  
+   public static explicit operator Digit(byte b) {  
+      return new Digit(b);  
+   }  
+}  
+]]></code_example>the conversion from Digit to <keyword>byte</keyword> is implicit because it never throws exceptions or loses information, but the conversion from <keyword>byte</keyword> to Digit is explicit since Digit can only represent a subset of the possible values of a <keyword>byte</keyword>. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.9.xml b/mcs/docs/ecma334/17.9.xml
new file mode 100644 (file)
index 0000000..1dc3ce8
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<clause number="17.9" title="Operators">
+  <paragraph>An operator is a member that defines the meaning of an expression operator that can be applied to instances of the class. Operators are declared using operator-declarations: <grammar_production><name><non_terminal where="17.9">operator-declaration</non_terminal></name> : <rhs><non_terminal where="24.2">attributes</non_terminal><opt/><non_terminal where="17.9">operator-modifiers</non_terminal><non_terminal where="17.9">operator-declarator</non_terminal><non_terminal where="17.9">operator-body</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.9">operator-modifier</non_terminal>s</name> : <rhs><non_terminal where="17.9">operator-modifier</non_terminal></rhs><rhs><non_terminal where="17.9">operator-modifiers</non_terminal><non_terminal where="17.9">operator-modifier</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.9">operator-modifier</non_terminal></name> : <rhs><keyword>public</keyword></rhs><rhs><keyword>static</keyword></rhs><rhs><keyword>extern</keyword></rhs></grammar_production><grammar_production><name><non_terminal where="17.9">operator-declarator</non_terminal></name> : <rhs><non_terminal where="17.9">unary-operator-declarator</non_terminal></rhs><rhs><non_terminal where="17.9">binary-operator-declarator</non_terminal></rhs><rhs><non_terminal where="17.9">conversion-operator-declarator</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.9">unary-operator-declarator</non_terminal></name> : <rhs><non_terminal where="11">type</non_terminal><keyword>operator</keyword><non_terminal where="17.9">overloadable-unary-operator</non_terminal><terminal>(</terminal><non_terminal where="11">type</non_terminal><non_terminal where="9.4.2">identifier</non_terminal><terminal>)</terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.9">overloadable-unary-operator</non_terminal></name> : one of <rhs><terminal>+</terminal><terminal>-</terminal><terminal>!</terminal><terminal>~</terminal><terminal>++</terminal><terminal>--</terminal><keyword>true</keyword><keyword>false</keyword></rhs></grammar_production><grammar_production><name><non_terminal where="17.9">binary-operator-declarator</non_terminal></name> : <rhs><non_terminal where="11">type</non_terminal><keyword>operator</keyword><non_terminal where="17.9">overloadable-binary-operator</non_terminal><terminal>(</terminal><non_terminal where="11">type</non_terminal><non_terminal where="9.4.2">identifier</non_terminal><terminal>,</terminal><non_terminal where="11">type</non_terminal><non_terminal where="9.4.2">identifier</non_terminal><terminal>)</terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.9">overloadable-binary-operator</non_terminal></name> : one of <rhs><terminal>+</terminal><terminal>-</terminal><terminal>*</terminal><terminal>/</terminal><terminal>%</terminal><terminal>&amp;</terminal><terminal>|</terminal><terminal>^</terminal><terminal>&lt;&lt;</terminal><terminal>&gt;&gt;</terminal><terminal>==</terminal><terminal>!=</terminal><terminal>&gt;</terminal><terminal>&lt;</terminal><terminal>&gt;=</terminal><terminal>&lt;=</terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.9">conversion-operator-declarator</non_terminal></name> :  <rhs><keyword>implicit</keyword><keyword>operator</keyword><non_terminal where="11">type</non_terminal><terminal>(</terminal><non_terminal where="11">type</non_terminal><non_terminal where="9.4.2">identifier</non_terminal><terminal>)</terminal></rhs><rhs><keyword>explicit</keyword><keyword>operator</keyword><non_terminal where="11">type</non_terminal><terminal>(</terminal><non_terminal where="11">type</non_terminal><non_terminal where="9.4.2">identifier</non_terminal><terminal>)</terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.9">operator-body</non_terminal></name> : <rhs><non_terminal where="15.2">block</non_terminal></rhs><rhs><terminal>;</terminal></rhs></grammar_production></paragraph>
+  <paragraph>There are three categories of overloadable operators: Unary operators (<hyperlink>17.9.1</hyperlink>), binary operators (<hyperlink>17.9.2</hyperlink>), and conversion operators (<hyperlink>17.9.3</hyperlink>). </paragraph>
+  <paragraph>When an operator declaration includes an extern modifier, the operator is said to be an external operator. Because an external operator provides no actual implementation, its <non_terminal where="17.9">operator-body</non_terminal> consists of a semi-colon. For all other operators, the <non_terminal where="17.9">operator-body</non_terminal> consists of a block, which specifies the statements to execute when the operator is invoked. The block of an operator must conform to the rules for value-returning methods described in <hyperlink>17.5.8</hyperlink>. </paragraph>
+  <paragraph>The following rules apply to all operator declarations: <list><list_item> An operator declaration must include both a public and a static modifier. </list_item><list_item> The parameter(s) of an operator must be value parameters. It is a compile-time error for an operator declaration to specify ref or out parameters. </list_item><list_item> The signature of an operator (<hyperlink>17.9.1</hyperlink>, <hyperlink>17.9.2</hyperlink>, <hyperlink>17.9.3</hyperlink>) must differ from the signatures of all other operators declared in the same class. </list_item><list_item> All types referenced in an operator declaration must be at least as accessible as the operator itself (<hyperlink>10.5.4</hyperlink>). </list_item><list_item> It is an error for the same modifier to appear multiple times in an operator declaration. </list_item></list></paragraph>
+  <paragraph>Each operator category imposes additional restrictions, as described in the following sections. </paragraph>
+  <paragraph>Like other members, operators declared in a base class are inherited by derived classes. Because operator declarations always require the class or struct in which the operator is declared to participate in the signature of the operator, it is not possible for an operator declared in a derived class to hide an operator declared in a base class. Thus, the new modifier is never required, and therefore never permitted, in an operator declaration. </paragraph>
+  <paragraph>Additional information on unary and binary operators can be found in <hyperlink>14.2</hyperlink>. </paragraph>
+  <paragraph>Additional information on conversion operators can be found in <hyperlink>13.4</hyperlink>. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/17.xml b/mcs/docs/ecma334/17.xml
new file mode 100644 (file)
index 0000000..bb7467f
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="17" title="Classes">
+  <paragraph>A class is a data structure that may contain data members (constants and fields), function members (methods, properties, events, indexers, operators, instance constructors, destructors, and static constructors), and nested types. Class types support inheritance, a mechanism whereby a derived class can extend and specialize a base class. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/18.1.1.xml b/mcs/docs/ecma334/18.1.1.xml
new file mode 100644 (file)
index 0000000..ca8b1dc
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="18.1.1" title="Struct modifiers">
+  <paragraph>A <non_terminal where="18.1">struct-declaration</non_terminal> may optionally include a sequence of struct modifiers: <grammar_production><name><non_terminal where="18.1.1">struct-modifier</non_terminal>s</name> : <rhs><non_terminal where="18.1.1">struct-modifier</non_terminal></rhs><rhs><non_terminal where="18.1.1">struct-modifiers</non_terminal><non_terminal where="18.1.1">struct-modifier</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="18.1.1">struct-modifier</non_terminal></name> : <rhs><keyword>new</keyword></rhs><rhs><keyword>public</keyword></rhs><rhs><keyword>protected</keyword></rhs><rhs><keyword>internal</keyword></rhs><rhs><keyword>private</keyword></rhs></grammar_production></paragraph>
+  <paragraph>It is a compile-time error for the same modifier to appear multiple times in a struct declaration. </paragraph>
+  <paragraph>The modifiers of a struct declaration have the same meaning as those of a class declaration (<hyperlink>17.1.1</hyperlink>). </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/18.1.2.xml b/mcs/docs/ecma334/18.1.2.xml
new file mode 100644 (file)
index 0000000..8d7c24b
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="18.1.2" title="Struct interfaces">
+  <paragraph>A struct declaration may include a <non_terminal where="18.1.2">struct-interfaces</non_terminal> specification, in which case the struct is said to implement the given interface types. <grammar_production><name><non_terminal where="18.1.2">struct-interfaces</non_terminal></name> : <rhs><terminal>:</terminal><non_terminal where="17.1.2">interface-type-list</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>Interface implementations are discussed further in <hyperlink>20.4</hyperlink>. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/18.1.3.xml b/mcs/docs/ecma334/18.1.3.xml
new file mode 100644 (file)
index 0000000..ff39e1c
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="18.1.3" title="Struct body">
+  <paragraph>The <non_terminal where="18.1.3">struct-body</non_terminal> of a struct defines the members of the struct. <grammar_production><name><non_terminal where="18.1.3">struct-body</non_terminal></name> : <rhs><terminal>{</terminal><non_terminal where="18.2">struct-member-declarations</non_terminal><opt/><terminal>}</terminal></rhs></grammar_production></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/18.1.xml b/mcs/docs/ecma334/18.1.xml
new file mode 100644 (file)
index 0000000..c390748
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="18.1" title="Struct declarations">
+  <paragraph>A <non_terminal where="18.1">struct-declaration</non_terminal> is a <non_terminal where="16.5">type-declaration</non_terminal> (<hyperlink>16.5</hyperlink>) that declares a new struct: <grammar_production><name><non_terminal where="18.1">struct-declaration</non_terminal></name> : <rhs><non_terminal where="24.2">attributes</non_terminal><opt/><non_terminal where="18.1.1">struct-modifiers</non_terminal><opt/><keyword>struct</keyword><non_terminal where="9.4.2">identifier</non_terminal><non_terminal where="18.1.2">struct-interfaces</non_terminal><opt/><non_terminal where="18.1.3">struct-body</non_terminal><terminal>;</terminal><opt/></rhs></grammar_production></paragraph>
+  <paragraph>A <non_terminal where="18.1">struct-declaration</non_terminal> consists of an optional set of attributes (<hyperlink>24</hyperlink>), followed by an optional set of  <non_terminal where="18.1.1">struct-modifier</non_terminal>s (<hyperlink>18.1.1</hyperlink>), followed by the keyword struct and an identifier that names the struct, followed by an optional <non_terminal where="18.1.2">struct-interfaces</non_terminal> specification (<hyperlink>18.1.2</hyperlink>), followed by a <non_terminal where="18.1.3">struct-body</non_terminal> (<hyperlink>18.1.3</hyperlink>), optionally followed by a semicolon. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/18.2.xml b/mcs/docs/ecma334/18.2.xml
new file mode 100644 (file)
index 0000000..cc8e352
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="18.2" title="Struct members">
+  <paragraph>The members of a struct consist of the members introduced by its <non_terminal where="18.2">struct-member-declaration</non_terminal>s and the members inherited from the type System.ValueType. <grammar_production><name><non_terminal where="18.2">struct-member-declaration</non_terminal>s</name> : <rhs><non_terminal where="18.2">struct-member-declaration</non_terminal></rhs><rhs><non_terminal where="18.2">struct-member-declarations</non_terminal><non_terminal where="18.2">struct-member-declaration</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="18.2">struct-member-declaration</non_terminal></name> : <rhs><non_terminal where="17.3">constant-declaration</non_terminal></rhs><rhs><non_terminal where="17.4">field-declaration</non_terminal></rhs><rhs><non_terminal where="17.5">method-declaration</non_terminal></rhs><rhs><non_terminal where="17.6">property-declaration</non_terminal></rhs><rhs><non_terminal where="17.7">event-declaration</non_terminal></rhs><rhs><non_terminal where="17.8">indexer-declaration</non_terminal></rhs><rhs><non_terminal where="17.9">operator-declaration</non_terminal></rhs><rhs><non_terminal where="17.10">constructor-declaration</non_terminal></rhs><rhs><non_terminal where="17.11">static-constructor-declaration</non_terminal></rhs><rhs><non_terminal where="16.5">type-declaration</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>Except for the differences noted in <hyperlink>18.3</hyperlink>, the descriptions of class members provided in <hyperlink>17.2</hyperlink> through <hyperlink>17.11</hyperlink> apply to struct members as well. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/18.3.1.xml b/mcs/docs/ecma334/18.3.1.xml
new file mode 100644 (file)
index 0000000..3a74abc
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<clause number="18.3.1" title="Value semantics">
+  <paragraph>Structs are value types (<hyperlink>11.1</hyperlink>) and are said to have value semantics. Classes, on the other hand, are reference types (<hyperlink>11.2</hyperlink>) and are said to have reference semantics. </paragraph>
+  <paragraph>A variable of a struct type directly contains the data of the struct, whereas a variable of a class type contains a reference to the data, the latter known as an object. </paragraph>
+  <paragraph>With classes, it is possible for two variables to reference the same object, and thus possible for operations on one variable to affect the object referenced by the other variable. With structs, the variables each have their own copy of the data, and it is not possible for operations on one to affect the other. Furthermore, because structs are not reference types, it is not possible for values of a struct type to be null. </paragraph>
+  <paragraph>
+    <example>[Example: Given the declaration <code_example><![CDATA[
+struct Point  
+{  
+   public int x, y;  
+   public Point(int x, int y) {  
+      this.x = x;  
+      this.y = y;  
+   }  
+}  
+]]></code_example>the code fragment <code_example><![CDATA[
+Point a = new Point(10, 10);  
+Point b = a;  
+a.x = 100;  
+System.Console.WriteLine(b.x);  
+]]></code_example>outputs the value 10. The assignment of a to b creates a copy of the value, and b is thus unaffected by the assignment to a.x. Had Point instead been declared as a class, the output would be 100 because a and b would reference the same object. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/18.3.2.xml b/mcs/docs/ecma334/18.3.2.xml
new file mode 100644 (file)
index 0000000..574044d
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<clause number="18.3.2" title="Inheritance">
+  <paragraph>All struct types implicitly inherit from System.ValueType, which, in turn, inherits from class object. A struct declaration may specify a list of implemented interfaces, but it is not possible for a struct declaration to specify a base class. </paragraph>
+  <paragraph>Struct types are never abstract and are always implicitly sealed. The abstract and sealed modifiers are therefore not permitted in a struct declaration. </paragraph>
+  <paragraph>Since inheritance isn't supported for structs, the declared accessibility of a struct member cannot be protected or protected internal. </paragraph>
+  <paragraph>Function members in a struct cannot be abstract or virtual, and the override modifier is allowed only to override methods inherited from the type System.ValueType. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/18.3.3.xml b/mcs/docs/ecma334/18.3.3.xml
new file mode 100644 (file)
index 0000000..ae3d694
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="18.3.3" title="Assignment">
+  <paragraph>Assignment to a variable of a struct type creates a copy of the value being assigned. This differs from assignment to a variable of a class type, which copies the reference but not the object identified by the reference. </paragraph>
+  <paragraph>Similar to an assignment, when a struct is passed as a value parameter or returned as the result of a function member, a copy of the struct is created. A struct may be passed by reference to a function member using a ref or out parameter. </paragraph>
+  <paragraph>When a property or indexer of a struct is the target of an assignment, the instance expression associated with the property or indexer access must be classified as a variable. If the instance expression is classified as a value, a compile-time error occurs. This is described in further detail in <hyperlink>14.13.1</hyperlink>. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/18.3.4.xml b/mcs/docs/ecma334/18.3.4.xml
new file mode 100644 (file)
index 0000000..80263e5
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<clause number="18.3.4" title="Default values">
+  <paragraph>As described in <hyperlink>12.2</hyperlink>, several kinds of variables are automatically initialized to their default value when they are created. For variables of class types and other reference types, this default value is null. However, since structs are value types that cannot be null, the default value of a struct is the value produced by setting all value type fields to their default value and all reference type fields to null. </paragraph>
+  <paragraph>
+    <example>[Example: Referring to the Point struct declared above, the example <code_example><![CDATA[
+Point[] a = new Point[100];  
+]]></code_example>initializes each Point in the array to the value produced by setting the x and y fields to zero. end example]</example>
+  </paragraph>
+  <paragraph>The default value of a struct corresponds to the value returned by the default constructor of the struct (<hyperlink>11.1.1</hyperlink>). Unlike a class, a struct is not permitted to declare a parameterless instance constructor. Instead, every struct implicitly has a parameterless instance constructor, which always returns the value that results from setting all value type fields to their default value and all reference type fields to null. </paragraph>
+  <paragraph>
+    <note>[Note: Structs should be designed to consider the default initialization state a valid state. In the example <code_example><![CDATA[
+using System;  
+struct KeyValuePair  
+{  
+   string key;  
+   string value;  
+   public KeyValuePair(string key, string value) {  
+      if (key == null || value == null) throw new ArgumentException();  
+      this.key = key;  
+      this.value = value;  
+   }  
+}  
+]]></code_example>the user-defined instance constructor protects against null values only where it is explicitly called. In cases where a KeyValuePair variable is subject to default value initialization, the key and value fields will be null, and the struct must be prepared to handle this state. end note]</note>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/18.3.5.xml b/mcs/docs/ecma334/18.3.5.xml
new file mode 100644 (file)
index 0000000..17d6a5c
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="18.3.5" title="Boxing and unboxing">
+  <paragraph>A value of a class type can be converted to type object or to an interface type that is implemented by the class simply by treating the reference as another type at compile-time. Likewise, a value of type object or a value of an interface type can be converted back to a class type without changing the reference (but of course a run-time type check is required in this case). </paragraph>
+  <paragraph>Since structs are not reference types, these operations are implemented differently for struct types. When a value of a struct type is converted to type object or to an interface type that is implemented by the struct, a boxing operation takes place. Likewise, when a value of type object or a value of an interface type is converted back to a struct type, an unboxing operation takes place. A key difference from the same operations on class types is that boxing and unboxing copies the struct value either into or out of the boxed instance. <note>[Note: Thus, following a boxing or unboxing operation, changes made to the unboxed struct are not reflected in the boxed struct. end note]</note> </paragraph>
+  <paragraph>For further details on boxing and unboxing, see <hyperlink>11.3</hyperlink>. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/18.3.6.xml b/mcs/docs/ecma334/18.3.6.xml
new file mode 100644 (file)
index 0000000..dd26ab3
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="18.3.6" title="Meaning of this">
+  <paragraph>Within an instance constructor or instance function member of a class, this is classified as a value. Thus, while this can be used to refer to the instance for which the function member was invoked, it is not possible to assign to this in a function member of a class. </paragraph>
+  <paragraph>Within an instance constructor of a struct, this corresponds to an out parameter of the struct type, and within an instance function member of a struct, this corresponds to a ref parameter of the struct type. In both cases, this is classified as a variable, and it is possible to modify the entire struct for which the function member was invoked by assigning to this or by passing this as a ref or out parameter. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/18.3.7.xml b/mcs/docs/ecma334/18.3.7.xml
new file mode 100644 (file)
index 0000000..301b2ac
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<clause number="18.3.7" title="Field initializers">
+  <paragraph>As described in <hyperlink>18.3.4</hyperlink>, the default value of a struct consists of the value that results from setting all value type fields to their default value and all reference type fields to null. For this reason, a struct does not permit instance field declarations to include variable initializers. <example>[Example: As such, the following example results in one or more compile-time errors: <code_example><![CDATA[
+struct Point  
+{  
+   public int x = 1;  // Error, initializer not permitted  
+   public int y = 1;  // Error, initializer not permitted  
+}  
+]]></code_example>end example]</example> </paragraph>
+  <paragraph>This restriction applies only to instance fields. Static fields of a struct are permitted to include variable initializers. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/18.3.8.xml b/mcs/docs/ecma334/18.3.8.xml
new file mode 100644 (file)
index 0000000..6e358f2
--- /dev/null
@@ -0,0 +1,39 @@
+<?xml version="1.0"?>
+<clause number="18.3.8" title="Constructors">
+  <paragraph>Unlike a class, a struct is not permitted to declare a parameterless instance constructor. Instead, every struct implicitly has a parameterless instance constructor, which always returns the value that results from setting all value type fields to their default value and all reference type fields to null (<hyperlink>11.1.1</hyperlink>). A struct can declare instance constructors having parameters. <example>[Example: For example <code_example><![CDATA[
+struct Point  
+{  
+   int x, y;  
+   public Point(int x, int y) {  
+      this.x = x;  
+      this.y = y;  
+   }  
+}  
+]]></code_example></example></paragraph>
+  <paragraph>
+    <example>Given the above declaration, the statements <code_example><![CDATA[
+Point p1 = new Point();  
+Point p2 = new Point(0, 0);  
+]]></code_example>both create a Point with x and y initialized to zero. end example]</example>
+  </paragraph>
+  <paragraph>A struct instance constructor is not permitted to include a constructor initializer of the form base(...). </paragraph>
+  <paragraph>The this variable of a struct instance constructor corresponds to an out parameter of the struct type, and similar to an out parameter, this must be definitely assigned (<hyperlink>12.3</hyperlink>) at every location where the constructor returns. <example>[Example: Consider the instance constructor implementation below: <code_example><![CDATA[
+struct Point  
+{  
+   int x, y;  
+   public int X {  
+      set { x = value; }  
+   }  
+   public int Y {  
+      set { y = value; }  
+   }  
+   public Point(int x, int y) {  
+      X = x;    // error, this is not yet definitely assigned  
+      Y = y;    // error, this is not yet definitely assigned  
+   }  
+}  
+]]></code_example></example></paragraph>
+  <paragraph>
+    <example>No instance member function (including the set accessors for the properties X and Y) can be called until all fields of the struct being constructed have been definitely assigned. Note, however, that if Point were a class instead of a struct, the instance constructor implementation would be permitted. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/18.3.9.xml b/mcs/docs/ecma334/18.3.9.xml
new file mode 100644 (file)
index 0000000..578f489
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="18.3.9" title="Destructors">
+  <paragraph>A struct is not permitted to declare a destructor. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/18.3.xml b/mcs/docs/ecma334/18.3.xml
new file mode 100644 (file)
index 0000000..b5be69a
--- /dev/null
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<clause number="18.3" title="Class and struct differences"/>
diff --git a/mcs/docs/ecma334/18.4.1.xml b/mcs/docs/ecma334/18.4.1.xml
new file mode 100644 (file)
index 0000000..ebf9993
--- /dev/null
@@ -0,0 +1,77 @@
+<?xml version="1.0"?>
+<clause number="18.4.1" title="Database integer type" informative="true">
+  <paragraph>The DBInt struct below implements an integer type that can represent the complete set of values of the <keyword>int</keyword> type, plus an additional state that indicates an unknown value. A type with these characteristics is commonly used in databases. <code_example><![CDATA[
+using System;  
+public struct DBInt  
+{  
+   // The Null member represents an unknown DBInt value.  
+   public static readonly DBInt Null = new DBInt();  
+   // When the defined field is true, this DBInt represents a known value  
+   // which is stored in the value field. When the defined field is false,  
+   
+   // this DBInt represents an unknown value, and the value field is 0.  
+   int value;  
+   bool defined;  
+   // Private instance constructor. Creates a DBInt with a known value.  
+   DBInt(int value) {  
+      this.value = value;  
+      this.defined = true;  
+   }  
+   // The IsNull property is true if this DBInt represents an unknown value.  
+   
+   public bool IsNull { get { return !defined; } }  
+   // The Value property is the known value of this DBInt, or 0 if this  
+   // DBInt represents an unknown value.  
+   public int Value { get { return value; } }  
+   // Implicit conversion from int to DBInt.  
+   public static implicit operator DBInt(int x) {  
+      return new DBInt(x);  
+   }  
+   // Explicit conversion from DBInt to int. Throws an exception if the  
+   // given DBInt represents an unknown value.  
+   public static explicit operator int(DBInt x) {  
+      if (!x.defined) throw new InvalidOperationException();  
+      return x.value;  
+   }  
+   public static DBInt operator +(DBInt x) {  
+      return x;  
+   }  
+   public static DBInt operator -(DBInt x) {  
+      return x.defined? -x.value: Null;  
+   }  
+   public static DBInt operator +(DBInt x, DBInt y) {  
+      return x.defined && y.defined? x.value + y.value: Null;  
+   }  
+   public static DBInt operator -(DBInt x, DBInt y) {  
+      return x.defined && y.defined? x.value - y.value: Null;  
+   }  
+   public static DBInt operator *(DBInt x, DBInt y) {  
+      return x.defined && y.defined? x.value * y.value: Null;  
+   }  
+   public static DBInt operator /(DBInt x, DBInt y) {  
+      return x.defined && y.defined? x.value / y.value: Null;  
+   }  
+   public static DBInt operator %(DBInt x, DBInt y) {  
+      return x.defined && y.defined? x.value % y.value: Null;  
+   }  
+   public static DBBool operator ==(DBInt x, DBInt y) {  
+      return x.defined && y.defined? x.value == y.value: DBBool.Null;  
+   }  
+   public static DBBool operator !=(DBInt x, DBInt y) {  
+      return x.defined && y.defined? x.value != y.value: DBBool.Null;  
+   }  
+   public static DBBool operator >(DBInt x, DBInt y) {  
+      return x.defined && y.defined? x.value > y.value: DBBool.Null;  
+   }  
+   public static DBBool operator <(DBInt x, DBInt y) {  
+      return x.defined && y.defined? x.value < y.value: DBBool.Null;  
+   }  
+   public static DBBool operator >=(DBInt x, DBInt y) {  
+      return x.defined && y.defined? x.value >= y.value: DBBool.Null;  
+   }  
+   public static DBBool operator <=(DBInt x, DBInt y) {  
+      return x.defined && y.defined? x.value <= y.value: DBBool.Null;  
+   }  
+}  
+]]></code_example></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/18.4.2.xml b/mcs/docs/ecma334/18.4.2.xml
new file mode 100644 (file)
index 0000000..790e268
--- /dev/null
@@ -0,0 +1,81 @@
+<?xml version="1.0"?>
+<clause number="18.4.2" title="Database boolean type" informative="true">
+  <paragraph>The DBBool struct below implements a three-valued logical type. The possible values of this type are DBBool.True, DBBool.False, and DBBool.Null, where the Null member indicates an unknown value. Such three-valued logical types are commonly used in databases. <code_example><![CDATA[
+using System;  
+public struct DBBool  
+{  
+   // The three possible DBBool values.  
+   public static readonly DBBool Null = new DBBool(0);  
+   public static readonly DBBool False = new DBBool(-1);  
+   public static readonly DBBool True = new DBBool(1);  
+   // Private field that stores -1, 0, 1 for False, Null, True.  
+   sbyte value;  
+   // Private instance constructor. The value parameter must be -1, 0, or 1.  
+   
+   DBBool(int value) {  
+      this.value = (sbyte)value;  
+   }  
+   // Properties to examine the value of a DBBool. Return true if this  
+   // DBBool has the given value, false otherwise.  
+   public bool IsNull { get { return value == 0; } }  
+   public bool IsFalse { get { return value < 0; } }  
+   public bool IsTrue { get { return value > 0; } }  
+   // Implicit conversion from bool to DBBool. Maps true to DBBool.True  
+   
+   // and false to DBBool.False.  
+   public static implicit operator DBBool(bool x) {  
+      return x? True: False;  
+   }  
+   // Explicit conversion from DBBool to bool. Throws an exception if the  
+   // given DBBool is Null, otherwise returns true or false.  
+   public static explicit operator bool(DBBool x) {  
+      if (x.value == 0) throw new InvalidOperationException();  
+      return x.value > 0;  
+   }  
+   // Equality operator. Returns Null if either operand is Null,  
+   
+   // otherwise returns True or False.  
+   public static DBBool operator ==(DBBool x, DBBool y) {  
+      if (x.value == 0 || y.value == 0) return Null;  
+      return x.value == y.value? True: False;  
+   }  
+   // Inequality operator. Returns Null if either operand is Null,  
+   
+   // otherwise returns True or False.  
+   public static DBBool operator !=(DBBool x, DBBool y) {  
+      if (x.value == 0 || y.value == 0) return Null;  
+      return x.value != y.value? True: False;  
+   }  
+   // Logical negation operator. Returns True if the operand is False,  
+   
+   // Null if the operand is Null, or False if the operand is True.  
+   public static DBBool operator !(DBBool x) {  
+      return new DBBool(-x.value);  
+   }  
+   // Logical AND operator. Returns False if either operand is False,  
+   // otherwise Null if either operand is Null, otherwise True.  
+   public static DBBool operator &(DBBool x, DBBool y) {  
+      return new DBBool(x.value < y.value? x.value: y.value);  
+   }  
+   // Logical OR operator. Returns True if either operand is True,  
+   
+   // otherwise Null if either operand is Null, otherwise False.  
+   public static DBBool operator |(DBBool x, DBBool y) {  
+      return new DBBool(x.value > y.value? x.value: y.value);  
+   }  
+   // Definitely true operator. Returns true if the operand is True,  
+   
+   // false otherwise.  
+   public static bool operator true(DBBool x) {  
+      return x.value > 0;  
+   }  
+   // Definitely false operator. Returns true if the operand is False,  
+   
+   // false otherwise.  
+   public static bool operator false(DBBool x) {  
+      return x.value < 0;  
+   }  
+}  
+]]></code_example></paragraph>
+  <paragraph>End of informative text. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/18.4.xml b/mcs/docs/ecma334/18.4.xml
new file mode 100644 (file)
index 0000000..4ac8509
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="18.4" title="Struct examples" informative="true">
+  <paragraph>This whole clause is informative. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/18.xml b/mcs/docs/ecma334/18.xml
new file mode 100644 (file)
index 0000000..a11ecbb
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<clause number="18" title="Structs">
+  <paragraph>Structs are similar to classes in that they represent data structures that can contain data members and function members. However, unlike classes, structs are value types and do not require heap allocation. A variable of a struct type directly contains the data of the struct, whereas a variable of a class type contains a reference to the data, the latter known as an object. </paragraph>
+  <paragraph>
+    <note>[Note: Structs are particularly useful for small data structures that have value semantics. Complex numbers, points in a coordinate system, or key-value pairs in a dictionary are all good examples of structs. Key to these data structures is that they have few data members, that they do not require use of inheritance or referential identity, and that they can be conveniently implemented using value semantics where assignment copies the value instead of the reference. end note]</note>
+  </paragraph>
+  <paragraph>As described in <hyperlink>11.1.3</hyperlink>, the simple types provided by C#, such as <keyword>int</keyword>, <keyword>double</keyword>, and <keyword>bool</keyword>, are, in fact, all struct types. Just as these predefined types are structs, it is also possible to use structs and operator overloading to implement new &quot;primitive&quot; types in the C# language. Two examples of such types are given at the end of this chapter (<hyperlink>18.4</hyperlink>). </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/19.1.1.xml b/mcs/docs/ecma334/19.1.1.xml
new file mode 100644 (file)
index 0000000..1d9661c
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="19.1.1" title="The System.Array type">
+  <paragraph>The type System.Array is the abstract base type of all array types. An implicit reference conversion (<hyperlink>13.1.4</hyperlink>) exists from any array type to System.Array, and an explicit reference conversion (<hyperlink>13.2.3</hyperlink>) exists from System.Array to any array type. Note that System.Array is not itself an <non_terminal where="19.1">array-type</non_terminal>. Rather, it is a <non_terminal where="11.2">class-type</non_terminal> from which all <non_terminal where="19.1">array-type</non_terminal>s are derived. </paragraph>
+  <paragraph>At run-time, a value of type System.Array can be null or a reference to an instance of any array type. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/19.1.xml b/mcs/docs/ecma334/19.1.xml
new file mode 100644 (file)
index 0000000..70b8faf
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<clause number="19.1" title="Array types">
+  <paragraph>An array type is written as a <non_terminal where="19.1">non-array-type</non_terminal> followed by one or more rank-specifiers: <grammar_production><name><non_terminal where="19.1">array-type</non_terminal></name> : <rhs><non_terminal where="19.1">non-array-type</non_terminal><non_terminal where="19.1">rank-specifiers</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="19.1">non-array-type</non_terminal></name> : <rhs><non_terminal where="11">type</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="19.1">rank-specifier</non_terminal>s</name> : <rhs><non_terminal where="19.1">rank-specifier</non_terminal></rhs><rhs><non_terminal where="19.1">rank-specifiers</non_terminal><non_terminal where="19.1">rank-specifier</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="19.1">rank-specifier</non_terminal></name> : <rhs><terminal>[</terminal><non_terminal where="19.1">dim-separators</non_terminal><opt/><terminal>]</terminal></rhs></grammar_production><grammar_production><name><non_terminal where="19.1">dim-separators</non_terminal></name> : <rhs><terminal>,</terminal></rhs><rhs><non_terminal where="19.1">dim-separators</non_terminal><terminal>,</terminal></rhs></grammar_production></paragraph>
+  <paragraph>A <non_terminal where="19.1">non-array-type</non_terminal> is any type that is not itself an <non_terminal where="19.1">array-type</non_terminal>. </paragraph>
+  <paragraph>The rank of an array type is given by the leftmost <non_terminal where="19.1">rank-specifier</non_terminal> in the array-type: A <non_terminal where="19.1">rank-specifier</non_terminal> indicates that the array is an array with a rank of one plus the number of &quot;,&quot; tokens in the <non_terminal where="19.1">rank-specifier</non_terminal>. </paragraph>
+  <paragraph>The element type of an array type is the type that results from deleting the leftmost rank-specifier: <list><list_item> An array type of the form T[R] is an array with rank R and a non-array element type T. </list_item><list_item> An array type of the form T[R][R1]...[RN] is an array with rank R and an element type T[R1]...[RN]. </list_item></list></paragraph>
+  <paragraph>In effect, the <non_terminal where="19.1">rank-specifier</non_terminal>s are read from left to right before the final non-array element type. <example>[Example: The type int[][,,][,] is a single-dimensional array of three-dimensional arrays of two-dimensional arrays of <keyword>int</keyword>. end example]</example> </paragraph>
+  <paragraph>At run-time, a value of an array type can be null or a reference to an instance of that array type. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/19.2.xml b/mcs/docs/ecma334/19.2.xml
new file mode 100644 (file)
index 0000000..8f689d3
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<clause number="19.2" title="Array creation">
+  <paragraph>Array instances are created by <non_terminal where="14.5.10.2">array-creation-expression</non_terminal>s (<hyperlink>14.5.10.2</hyperlink>) or by field or local variable declarations that include an <non_terminal where="19.6">array-initializer</non_terminal> (<hyperlink>19.6</hyperlink>). </paragraph>
+  <paragraph>When an array instance is created, the rank and length of each dimension are established and then remain constant for the entire lifetime of the instance. In other words, it is not possible to change the rank of an existing array instance, nor is it possible to resize its dimensions. </paragraph>
+  <paragraph>An array instance is always of an array type. The System.Array type is an abstract type that cannot be instantiated. </paragraph>
+  <paragraph>Elements of arrays created by <non_terminal where="14.5.10.2">array-creation-expression</non_terminal>s are always initialized to their default value (<hyperlink>12.2</hyperlink>). </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/19.3.xml b/mcs/docs/ecma334/19.3.xml
new file mode 100644 (file)
index 0000000..236a750
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="19.3" title="Array element access">
+  <paragraph>Array elements are accessed using <non_terminal where="14.5.6">element-access</non_terminal> expressions (<hyperlink>14.5.6.1</hyperlink>) of the form A[I1, I2, ..., IN], where A is an expression of an array type and each IX is an expression of type <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>long</keyword>, <keyword>ulong</keyword>, or of a type that can be implicitly converted to one or more of these types. The result of an array element access is a variable, namely the array element selected by the indices. </paragraph>
+  <paragraph>The elements of an array can be enumerated using a foreach statement (<hyperlink>15.8.4</hyperlink>). </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/19.4.xml b/mcs/docs/ecma334/19.4.xml
new file mode 100644 (file)
index 0000000..8c6fc96
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="19.4" title="Array members">
+  <paragraph>Every array type inherits the members declared by the System.Array type. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/19.5.xml b/mcs/docs/ecma334/19.5.xml
new file mode 100644 (file)
index 0000000..697196d
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<clause number="19.5" title="Array covariance">
+  <paragraph>For any two <non_terminal where="11.2">reference-type</non_terminal>s A and B, if an implicit reference conversion (<hyperlink>13.1.4</hyperlink>) or explicit reference conversion (<hyperlink>13.2.3</hyperlink>) exists from A to B, then the same reference conversion also exists from the array type A[R] to the array type B[R], where R is any given <non_terminal where="19.1">rank-specifier</non_terminal> (but the same for both array types). This relationship is known as array covariance. Array covariance, in particular, means that a value of an array type A[R] may actually be a reference to an instance of an array type B[R], provided an implicit reference conversion exists from B to A. </paragraph>
+  <paragraph>Because of array covariance, assignments to elements of reference type arrays include a run-time check which ensures that the value being assigned to the array element is actually of a permitted type (<hyperlink>14.13.1</hyperlink>). </paragraph>
+  <paragraph>
+    <example>[Example: For example: <code_example><![CDATA[
+class Test  
+{  
+   static void Fill(object[] array, int index, int count, object value) {  
+      for (int i = index; i < index + count; i++) array[i] = value;  
+   }  
+   static void Main() {  
+      string[] strings = new string[100];  
+      Fill(strings, 0, 100, "Undefined");  
+      Fill(strings, 0, 10, null);  
+      Fill(strings, 90, 10, 0);  
+   }  
+}  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>The assignment to array[i] in the Fill method implicitly includes a run-time check, which ensures that the object referenced by value is either null or an instance of a type that is compatible with the actual element type of array. In Main, the first two invocations of Fill succeed, but the third invocation causes a System.ArrayTypeMismatchException to be thrown upon executing the first assignment to array[i]. The exception occurs because a boxed <keyword>int</keyword> cannot be stored in a string array. end example]</example>
+  </paragraph>
+  <paragraph>Array covariance specifically does not extend to arrays of <non_terminal where="11.1">value-type</non_terminal>s. For example, no conversion exists that permits an int[] to be treated as an object[]. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/19.6.xml b/mcs/docs/ecma334/19.6.xml
new file mode 100644 (file)
index 0000000..ae1e986
--- /dev/null
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<clause number="19.6" title="Array initializers">
+  <paragraph>Array initializers may be specified in field declarations (<hyperlink>17.4</hyperlink>), local variable declarations (<hyperlink>15.5.1</hyperlink>), and array creation expressions (<hyperlink>14.5.10.2</hyperlink>): <grammar_production><name><non_terminal where="19.6">array-initializer</non_terminal></name> : <rhs><terminal>{</terminal><non_terminal where="19.6">variable-initializer-list</non_terminal><opt/><terminal>}</terminal></rhs><rhs><terminal>{</terminal><non_terminal where="19.6">variable-initializer-list</non_terminal><terminal>,</terminal><terminal>}</terminal></rhs></grammar_production><grammar_production><name><non_terminal where="19.6">variable-initializer-list</non_terminal></name> : <rhs><non_terminal where="19.6">variable-initializer</non_terminal></rhs><rhs><non_terminal where="19.6">variable-initializer-list</non_terminal><terminal>,</terminal><non_terminal where="19.6">variable-initializer</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="19.6">variable-initializer</non_terminal></name> : <rhs><non_terminal where="14.14">expression</non_terminal></rhs><rhs><non_terminal where="19.6">array-initializer</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>An array initializer consists of a sequence of variable initializers, enclosed by &quot;{&quot;and &quot;}&quot; tokens and separated by &quot;,&quot; tokens. Each variable initializer is an expression or, in the case of a multi-dimensional array, a nested array initializer. </paragraph>
+  <paragraph>The context in which an array initializer is used determines the type of the array being initialized. In an array creation expression, the array type immediately precedes the initializer. In a field or variable declaration, the array type is the type of the field or variable being declared. When an array initializer is used in a field or variable declaration, <example>[Example: such as: <code_example><![CDATA[
+int[] a = {0, 2, 4, 6, 8};  
+]]></code_example>end example]</example> it is simply shorthand for an equivalent array creation expression: <example>[Example: <code_example><![CDATA[
+int[] a = new int[] {0, 2, 4, 6, 8};  
+]]></code_example>end example]</example> </paragraph>
+  <paragraph>For a single-dimensional array, the array initializer must consist of a sequence of expressions that are assignment compatible with the element type of the array. The expressions initialize array elements in increasing order, starting with the element at index zero. The number of expressions in the array initializer determines the length of the array instance being created. <example>[Example: For example, the array initializer above creates an int[] instance of length 5 and then initializes the instance with the following values: <code_example><![CDATA[
+a[0] = 0; a[1] = 2; a[2] = 4; a[3] = 6; a[4] = 8;  
+]]></code_example>end example]</example> </paragraph>
+  <paragraph>For a multi-dimensional array, the array initializer must have as many levels of nesting as there are dimensions in the array. The outermost nesting level corresponds to the leftmost dimension and the innermost nesting level corresponds to the rightmost dimension. The length of each dimension of the array is determined by the number of elements at the corresponding nesting level in the array initializer. For each nested array initializer, the number of elements must be the same as the other array initializers at the same level. <example>[Example: The example: <code_example><![CDATA[
+int[,] b = {{0, 1}, {2, 3}, {4, 5}, {6, 7}, {8, 9}};  
+]]></code_example>creates a two-dimensional array with a length of five for the leftmost dimension and a length of two for the rightmost dimension: <code_example><![CDATA[
+int[,] b = new int[5, 2];  
+]]></code_example>and then initializes the array instance with the following values: <code_example><![CDATA[
+b[0, 0] = 0; b[0, 1] = 1;  
+b[1, 0] = 2; b[1, 1] = 3;  
+b[2, 0] = 4; b[2, 1] = 5;  
+b[3, 0] = 6; b[3, 1] = 7;  
+b[4, 0] = 8; b[4, 1] = 9;  
+]]></code_example>end example]</example> </paragraph>
+  <paragraph>When an array creation expression includes both explicit dimension lengths and an array initializer, the lengths must be constant expressions and the number of elements at each nesting level must match the corresponding dimension length. <example>[Example: Here are some examples: <code_example><![CDATA[
+int i = 3;  
+int[] x = new int[3] {0, 1, 2};    // OK  
+int[] y = new int[i] {0, 1, 2};    // Error, i not a constant  
+int[] z = new int[3] {0, 1, 2, 3};  // Error, length/initializer mismatch  
+]]></code_example></example></paragraph>
+  <paragraph>
+    <example>Here, the initializer for y results in a compile-time error because the dimension length expression is not a constant, and the initializer for z results in a compile-time error because the length and the number of elements in the initializer do not agree. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/19.xml b/mcs/docs/ecma334/19.xml
new file mode 100644 (file)
index 0000000..9fd8c3a
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="19" title="Arrays">
+  <paragraph>An array is a data structure that contains a number of variables which are accessed through computed indices. The variables contained in an array, also called the elements of the array, are all of the same type, and this type is called the element type of the array. </paragraph>
+  <paragraph>An array has a rank which determines the number of indices associated with each array element. The rank of an array is also referred to as the dimensions of the array. An array with a rank of one is called a  single-dimensional array. An array with a rank greater than one is called a multi-dimensional array. Specific sized multi-dimensional arrays are often referred to as two-dimensional arrays, three-dimensional arrays, and so on. Each dimension of an array has an associated length which is an integral number greater than or equal to zero. The dimension lengths are not part of the type of the array, but rather are established when an instance of the array type is created at run-time. The length of a dimension determines the valid range of indices for that dimension: For a dimension of length N, indices can range from 0 to N  -1 inclusive. The total number of elements in an array is the product of the lengths of each dimension in the array. If one or more of the dimensions of an array have a length of zero, the array is said to be empty. </paragraph>
+  <paragraph>The element type of an array can be any type, including an array type. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/2.xml b/mcs/docs/ecma334/2.xml
new file mode 100644 (file)
index 0000000..5fe8cff
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+<clause number="2" title="Conformance">
+  <paragraph>Conformance is of interest to the following audiences: <list><list_item> Those designing, implementing, or maintaining C# implementations. </list_item><list_item> Governmental or commercial entities wishing to procure C# implementations. </list_item><list_item> Testing organizations wishing to provide a C# conformance test suite. </list_item><list_item> Programmers wishing to port code from one C# implementation to another. </list_item><list_item> Educators wishing to teach Standard C#. </list_item><list_item> Authors wanting to write about Standard C#. </list_item></list></paragraph>
+  <paragraph>As such, conformance is most important, and the bulk of this ECMA Standard is aimed at specifying the characteristics that make C# implementations and C# programs conforming ones. </paragraph>
+  <paragraph>The text in this ECMA Standard that specifies requirements is considered normative. All other text in this specification is informative; that is, for information purposes only. Unless stated otherwise, all text is normative. Normative text is further broken into required and conditional categories. Conditionally normative text specifies requirements for a feature such that if that feature is provided, its syntax and semantics must be exactly as specified. </paragraph>
+  <paragraph>If any requirement of this ECMA Standard is violated, the behavior is undefined. Undefined behavior is otherwise indicated in this ECMA Standard by the words ''undefined behavior'' or by the omission of any explicit definition of behavior. There is no difference in emphasis among these three; they all describe ''behavior that is undefined.'' </paragraph>
+  <paragraph>A strictly conforming program shall use only those features of the language specified in this ECMA Standard as being required. (This means that a strictly conforming program cannot use any conditionally normative feature.) It shall not produce output dependent on any unspecified, undefined, or  implementation-defined behavior. </paragraph>
+  <paragraph>A conforming implementation of C# must accept any strictly conforming program. </paragraph>
+  <paragraph>A conforming implementation of C# must provide and support all the types, values, objects, properties, methods, and program syntax and semantics described in this ECMA Standard. </paragraph>
+  <paragraph>A conforming implementation of C# shall interpret characters in conformance with the Unicode Standard, Version 3.0 or later, and ISO/IEC 10646-1. Conforming implementations must accept Unicode source files encoded with the UTF-8 encoding form. </paragraph>
+  <paragraph>A conforming implementation of C# shall not successfully translate source containing a <symbol>#error</symbol> preprocessing directive unless it is part of a group skipped by conditional compilation. </paragraph>
+  <paragraph>A conforming implementation of C# shall produce at least one diagnostic message if the source program violates any rule of syntax, or any negative requirement (defined as a &quot;shall&quot; or &quot;shall not&quot; or &quot;error&quot; or &quot;warning&quot; requirement), unless that requirement is marked with the words &quot;no diagnostic is required&quot;. </paragraph>
+  <paragraph>A conforming implementation of C# is permitted to provide additional types, values, objects, properties, and methods beyond those described in this ECMA Standard, provided they do not alter the behavior of any strictly conforming program. Conforming implementations are required to diagnose programs that use extensions that are ill formed according to this ECMA Standard. Having done so, however; they can compile and execute such programs. (The ability to have extensions implies that a conforming implementation reserves no identifiers other than those explicitly reserved in this ECMA Standard.) </paragraph>
+  <paragraph>A conforming implementation of C# shall be accompanied by a document that defines all  implementation-defined characteristics, and all extensions. </paragraph>
+  <paragraph>A conforming implementation of C# shall support the class library documented in <unicode>167</unicode>D. This library is included by reference in this ECMA Standard. </paragraph>
+  <paragraph>A conforming program is one that is acceptable to a conforming implementation. (Such a program may contain extensions or conditionally normative features.) </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/20.1.1.xml b/mcs/docs/ecma334/20.1.1.xml
new file mode 100644 (file)
index 0000000..2fd0a41
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<clause number="20.1.1" title="Interface modifiers">
+  <paragraph>An <non_terminal where="20.1">interface-declaration</non_terminal> may optionally include a sequence of interface modifiers: <grammar_production><name><non_terminal where="20.1.1">interface-modifier</non_terminal>s</name> : <rhs><non_terminal where="20.1.1">interface-modifier</non_terminal></rhs><rhs><non_terminal where="20.1.1">interface-modifiers</non_terminal><non_terminal where="20.1.1">interface-modifier</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="20.1.1">interface-modifier</non_terminal></name> : <rhs><keyword>new</keyword></rhs><rhs><keyword>public</keyword></rhs><rhs><keyword>protected</keyword></rhs><rhs><keyword>internal</keyword></rhs><rhs><keyword>private</keyword></rhs></grammar_production></paragraph>
+  <paragraph>It is a compile-time error for the same modifier to appear multiple times in an interface declaration. </paragraph>
+  <paragraph>The new modifier is only permitted on nested interfaces. It specifies that the interface hides an inherited member by the same name, as described in <hyperlink>17.2.2</hyperlink>. </paragraph>
+  <paragraph>The public, protected, internal, and private modifiers control the accessibility of the interface. Depending on the context in which the interface declaration occurs, only some of these modifiers may be permitted (<hyperlink>10.5.1</hyperlink>). </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/20.1.2.xml b/mcs/docs/ecma334/20.1.2.xml
new file mode 100644 (file)
index 0000000..ff2a62e
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<clause number="20.1.2" title="Base interfaces">
+  <paragraph>An interface can inherit from zero or more interfaces, which are called the explicit base interfaces of the interface. When an interface has one or more explicit base interfaces, then in the declaration of that interface, the interface identifier is followed by a colon and a comma-separated list of base interface identifiers. <grammar_production><name><non_terminal where="20.1.2">interface-base</non_terminal></name> : <rhs><terminal>:</terminal><non_terminal where="17.1.2">interface-type-list</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>The explicit base interfaces of an interface must be at least as accessible as the interface itself (<hyperlink>10.5.4</hyperlink>). </paragraph>
+  <paragraph>
+    <note>[Note: For example, it is a compile-time error to specify a private or internal interface in the  <non_terminal where="20.1.2">interface-base</non_terminal> of a public interface. end note]</note>
+  </paragraph>
+  <paragraph>It is a compile-time error for an interface to directly or indirectly inherit from itself. </paragraph>
+  <paragraph>The base interfaces of an interface are the explicit base interfaces and their base interfaces. In other words, the set of base interfaces is the complete transitive closure of the explicit base interfaces, their explicit base interfaces, and so on. An interface inherits all members of its base interfaces. <example>[Example: In the example <code_example><![CDATA[
+interface IControl  
+{  
+   void Paint();  
+}  
+interface ITextBox: IControl  
+{  
+   void SetText(string text);  
+}  
+interface IListBox: IControl  
+{  
+   void SetItems(string[] items);  
+}  
+interface IComboBox: ITextBox, IListBox {}  
+]]></code_example>the base interfaces of IComboBox are IControl, ITextBox, and IListBox. In other words, the IComboBox interface above inherits members SetText and SetItems as well as Paint. end example]</example> </paragraph>
+  <paragraph>A class or struct that implements an interface also implicitly implements all of the interface's base interfaces. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/20.1.3.xml b/mcs/docs/ecma334/20.1.3.xml
new file mode 100644 (file)
index 0000000..d6826d7
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="20.1.3" title="Interface body">
+  <paragraph>The <non_terminal where="20.1.3">interface-body</non_terminal> of an interface defines the members of the interface. <grammar_production><name><non_terminal where="20.1.3">interface-body</non_terminal></name> : <rhs><terminal>{</terminal><non_terminal where="20.2">interface-member-declarations</non_terminal><opt/><terminal>}</terminal></rhs></grammar_production></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/20.1.xml b/mcs/docs/ecma334/20.1.xml
new file mode 100644 (file)
index 0000000..70d471c
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="20.1" title="Interface declarations">
+  <paragraph>An <non_terminal where="20.1">interface-declaration</non_terminal> is a <non_terminal where="16.5">type-declaration</non_terminal> (<hyperlink>16.5</hyperlink>) that declares a new interface type. <grammar_production><name><non_terminal where="20.1">interface-declaration</non_terminal></name> : <rhs><non_terminal where="24.2">attributes</non_terminal><opt/><non_terminal where="20.1.1">interface-modifiers</non_terminal><opt/><keyword>interface</keyword><non_terminal where="9.4.2">identifier</non_terminal><non_terminal where="20.1.2">interface-base</non_terminal><opt/><non_terminal where="20.1.3">interface-body</non_terminal><terminal>;</terminal><opt/></rhs></grammar_production></paragraph>
+  <paragraph>An <non_terminal where="20.1">interface-declaration</non_terminal> consists of an optional set of attributes (<hyperlink>24</hyperlink>), followed by an optional set of <non_terminal where="20.1.1">interface-modifier</non_terminal>s (<hyperlink>20.1.1</hyperlink>), followed by the keyword interface and an identifier that names the interface, optionally followed by an optional <non_terminal where="20.1.2">interface-base</non_terminal> specification (<hyperlink>20.1.2</hyperlink>), followed by a  <non_terminal where="20.1.3">interface-body</non_terminal> (<hyperlink>20.1.3</hyperlink>), optionally followed by a semicolon. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/20.2.1.xml b/mcs/docs/ecma334/20.2.1.xml
new file mode 100644 (file)
index 0000000..6f8f1da
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="20.2.1" title="Interface methods">
+  <paragraph>Interface methods are declared using interface-method-declarations: <grammar_production><name><non_terminal where="20.2.1">interface-method-declaration</non_terminal></name> : <rhs><non_terminal where="24.2">attributes</non_terminal><opt/><keyword>new</keyword><opt/><non_terminal where="17.5">return-type</non_terminal><non_terminal where="9.4.2">identifier</non_terminal><terminal>(</terminal><non_terminal where="17.5.1">formal-parameter-list</non_terminal><opt/><terminal>)</terminal><terminal>;</terminal></rhs></grammar_production></paragraph>
+  <paragraph>The attributes, <non_terminal where="17.5">return-type</non_terminal>, identifier, and <non_terminal where="17.5.1">formal-parameter-list</non_terminal> of an interface method declaration have the same meaning as those of a method declaration in a class (<hyperlink>17.5</hyperlink>). An interface method declaration is not permitted to specify a method body, and the declaration therefore always ends with a semicolon. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/20.2.2.xml b/mcs/docs/ecma334/20.2.2.xml
new file mode 100644 (file)
index 0000000..61cbd0e
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="20.2.2" title="Interface properties">
+  <paragraph>Interface properties are declared using interface-property-declarations: <grammar_production><name><non_terminal where="20.2.2">interface-property-declaration</non_terminal></name> : <rhs><non_terminal where="24.2">attributes</non_terminal><opt/><keyword>new</keyword><opt/><non_terminal where="11">type</non_terminal><non_terminal where="9.4.2">identifier</non_terminal><terminal>{</terminal><non_terminal where="20.2.2">interface-accessors</non_terminal><terminal>}</terminal></rhs></grammar_production><grammar_production><name><non_terminal where="20.2.2">interface-accessors</non_terminal></name> : <rhs><non_terminal where="24.2">attributes</non_terminal><opt/><terminal>get</terminal><terminal>;</terminal></rhs><rhs><non_terminal where="24.2">attributes</non_terminal><opt/><terminal>set</terminal><terminal>;</terminal></rhs><rhs><non_terminal where="24.2">attributes</non_terminal><opt/><terminal>get</terminal><terminal>;</terminal><non_terminal where="24.2">attributes</non_terminal><opt/><terminal>set</terminal><terminal>;</terminal></rhs><rhs><non_terminal where="24.2">attributes</non_terminal><opt/><terminal>set</terminal><terminal>;</terminal><non_terminal where="24.2">attributes</non_terminal><opt/><terminal>get</terminal><terminal>;</terminal></rhs></grammar_production></paragraph>
+  <paragraph>The attributes, type, and identifier of an interface property declaration have the same meaning as those of a property declaration in a class (<hyperlink>17.6</hyperlink>). </paragraph>
+  <paragraph>The accessors of an interface property declaration correspond to the accessors of a class property declaration (<hyperlink>17.6.2</hyperlink>), except that the accessor body must always be a semicolon. Thus, the accessors simply indicate whether the property is read-write, read-only, or write-only. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/20.2.3.xml b/mcs/docs/ecma334/20.2.3.xml
new file mode 100644 (file)
index 0000000..3d3d708
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="20.2.3" title="Interface events">
+  <paragraph>Interface events are declared using interface-event-declarations: <grammar_production><name><non_terminal where="20.2.3">interface-event-declaration</non_terminal></name> : <rhs><non_terminal where="24.2">attributes</non_terminal><opt/><keyword>new</keyword><opt/><keyword>event</keyword><non_terminal where="11">type</non_terminal><non_terminal where="9.4.2">identifier</non_terminal><terminal>;</terminal></rhs></grammar_production></paragraph>
+  <paragraph>The attributes, type, and identifier of an interface event declaration have the same meaning as those of an event declaration in a class (<hyperlink>17.7</hyperlink>). </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/20.2.4.xml b/mcs/docs/ecma334/20.2.4.xml
new file mode 100644 (file)
index 0000000..8ec814a
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="20.2.4" title="Interface indexers">
+  <paragraph>Interface indexers are declared using interface-indexer-declarations: <grammar_production><name><non_terminal where="20.2.4">interface-indexer-declaration</non_terminal></name> : <rhs><non_terminal where="24.2">attributes</non_terminal><opt/><keyword>new</keyword><opt/><non_terminal where="11">type</non_terminal><keyword>this</keyword><terminal>[</terminal><non_terminal where="17.5.1">formal-parameter-list</non_terminal><terminal>]</terminal><terminal>{</terminal><non_terminal where="20.2.2">interface-accessors</non_terminal><terminal>}</terminal></rhs></grammar_production></paragraph>
+  <paragraph>The attributes, type, and <non_terminal where="17.5.1">formal-parameter-list</non_terminal> of an interface indexer declaration have the same meaning as those of an indexer declaration in a class (<hyperlink>17.8</hyperlink>). </paragraph>
+  <paragraph>The accessors of an interface indexer declaration correspond to the accessors of a class indexer declaration (<hyperlink>17.8</hyperlink>), except that the accessor body must always be a semicolon. Thus, the accessors simply indicate whether the indexer is read-write, read-only, or write-only. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/20.2.5.xml b/mcs/docs/ecma334/20.2.5.xml
new file mode 100644 (file)
index 0000000..57a29b3
--- /dev/null
@@ -0,0 +1,78 @@
+<?xml version="1.0"?>
+<clause number="20.2.5" title="Interface member access">
+  <paragraph>Interface members are accessed through member access (<hyperlink>14.5.4</hyperlink>) and indexer access (<hyperlink>14.5.6.2</hyperlink>) expressions of the form I.M and I[A], where I is an instance of an interface type, M is a method, property, or event of that interface type, and A is an indexer argument list. </paragraph>
+  <paragraph>For interfaces that are strictly single-inheritance (each interface in the inheritance chain has exactly zero or one direct base interface), the effects of the member lookup (<hyperlink>14.3</hyperlink>), method invocation (<hyperlink>14.5.5.1</hyperlink>), and indexer access (<hyperlink>14.5.6.2</hyperlink>) rules are exactly the same as for classes and structs: More derived members hide less derived members with the same name or signature. However, for multiple-inheritance interfaces, ambiguities can occur when two or more unrelated base interfaces declare members with the same name or signature. This section shows several examples of such situations. In all cases, explicit casts can be used to resolve the ambiguities. </paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+interface IList  
+{  
+   int Count { get; set; }  
+}  
+interface ICounter  
+{  
+   void Count(int i);  
+}  
+interface IListCounter: IList, ICounter {}  
+class C  
+{  
+   void Test(IListCounter x) {  
+      x.Count(1);      // Error  
+      x.Count = 1;          // Error  
+      ((IList)x).Count = 1;   // Ok, invokes IList.Count.set  
+      ((ICounter)x).Count(1);  // Ok, invokes ICounter.Count  
+   }  
+}  
+]]></code_example>the first two statements cause compile-time errors because the member lookup (<hyperlink>14.3</hyperlink>) of Count in IListCounter is ambiguous. As illustrated by the example, the ambiguity is resolved by casting x to the appropriate base interface type. Such casts have no run-time costs-they merely consist of viewing the instance as a less derived type at compile-time. end example]</example>
+  </paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+interface IInteger  
+{  
+   void Add(int i);  
+}  
+interface IDouble  
+{  
+   void Add(double d);  
+}  
+interface INumber: IInteger, IDouble {}  
+class C  
+{  
+   void Test(INumber n) {  
+      n.Add(1);      // Error, both Add methods are applicable  
+      n.Add(1.0);     // Ok, only IDouble.Add is applicable  
+      ((IInteger)n).Add(1);  // Ok, only IInteger.Add is a candidate  
+      ((IDouble)n).Add(1);   // Ok, only IDouble.Add is a candidate  
+   }  
+}  
+]]></code_example>the invocation n.Add(1) is ambiguous because a method invocation (<hyperlink>14.5.5.1</hyperlink>) requires all overloaded candidate methods to be declared in the same type. However, the invocation n.Add(1.0) is permitted because only IDouble.Add is applicable. When explicit casts are inserted, there is only one candidate method, and thus no ambiguity. end example]</example>
+  </paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+interface IBase  
+{  
+   void F(int i);  
+}  
+interface ILeft: IBase  
+{  
+   new void F(int i);  
+}  
+interface IRight: IBase  
+{  
+   void G();  
+}  
+interface IDerived: ILeft, IRight {}  
+class A  
+{  
+   void Test(IDerived d) {  
+      d.F(1);      // Invokes ILeft.F  
+      ((IBase)d).F(1);   // Invokes IBase.F  
+      ((ILeft)d).F(1);   // Invokes ILeft.F  
+      ((IRight)d).F(1);  // Invokes IBase.F  
+   }  
+}  
+]]></code_example>the IBase.F member is hidden by the ILeft.F member. The invocation d.F(1) thus selects ILeft.F, even though IBase.F appears to not be hidden in the access path that leads through IRight. </example>
+  </paragraph>
+  <paragraph>
+    <example>The intuitive rule for hiding in multiple-inheritance interfaces is simply this: If a member is hidden in any access path, it is hidden in all access paths. Because the access path from IDerived to ILeft to IBase hides IBase.F, the member is also hidden in the access path from IDerived to IRight to IBase. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/20.2.xml b/mcs/docs/ecma334/20.2.xml
new file mode 100644 (file)
index 0000000..403f7b7
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<clause number="20.2" title="Interface members">
+  <paragraph>The members of an interface are the members inherited from the base interfaces and the members declared by the interface itself. <grammar_production><name><non_terminal where="20.2">interface-member-declaration</non_terminal>s</name> : <rhs><non_terminal where="20.2">interface-member-declaration</non_terminal></rhs><rhs><non_terminal where="20.2">interface-member-declarations</non_terminal><non_terminal where="20.2">interface-member-declaration</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="20.2">interface-member-declaration</non_terminal></name> : <rhs><non_terminal where="20.2.1">interface-method-declaration</non_terminal></rhs><rhs><non_terminal where="20.2.2">interface-property-declaration</non_terminal></rhs><rhs><non_terminal where="20.2.3">interface-event-declaration</non_terminal></rhs><rhs><non_terminal where="20.2.4">interface-indexer-declaration</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>An interface declaration may declare zero or more members. The members of an interface must be methods, properties, events, or indexers. An interface cannot contain constants, fields, operators, instance constructors, destructors, or types, nor can an interface contain static members of any kind. </paragraph>
+  <paragraph>All interface members implicitly have public access. It is a compile-time error for interface member declarations to include any modifiers. In particular, interface members cannot be declared with the modifiers abstract, public, protected, internal, private, virtual, override, or static. </paragraph>
+  <paragraph>
+    <example>[Example: The example <code_example><![CDATA[
+public delegate void StringListEvent(IStringList sender);  
+public interface IStringList  
+{  
+   void Add(string s);  
+   int Count { get; }  
+   event StringListEvent Changed;  
+   string this[int index] { get; set; }  
+}  
+]]></code_example>declares an interface that contains one each of the possible kinds of members: A method, a property, an event, and an indexer. end example]</example>
+  </paragraph>
+  <paragraph>An <non_terminal where="20.1">interface-declaration</non_terminal> creates a new declaration space (<hyperlink>10.3</hyperlink>), and the <non_terminal where="20.2">interface-member-declaration</non_terminal>s immediately contained by the <non_terminal where="20.1">interface-declaration</non_terminal> introduce new members into this declaration space. The following rules apply to interface-member-declarations: <list><list_item> The name of a method must differ from the names of all properties and events declared in the same interface. In addition, the signature (<hyperlink>10.6</hyperlink>) of a method must differ from the signatures of all other methods declared in the same interface. </list_item><list_item> The name of a property or event must differ from the names of all other members declared in the same interface. </list_item><list_item> The signature of an indexer must differ from the signatures of all other indexers declared in the same interface. </list_item></list></paragraph>
+  <paragraph>The inherited members of an interface are specifically not part of the declaration space of the interface. Thus, an interface is allowed to declare a member with the same name or signature as an inherited member. When this occurs, the derived interface member is said to hide the base interface member. Hiding an inherited member is not considered an error, but it does cause the compiler to issue a warning. To suppress the warning, the declaration of the derived interface member must include a new modifier to indicate that the derived member is intended to hide the base member. This topic is discussed further in <hyperlink>10.7.1.2</hyperlink>. </paragraph>
+  <paragraph>If a new modifier is included in a declaration that doesn't hide an inherited member, a warning is issued to that effect. This warning is suppressed by removing the new modifier. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/20.3.xml b/mcs/docs/ecma334/20.3.xml
new file mode 100644 (file)
index 0000000..745794e
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<clause number="20.3" title="Fully qualified interface member names">
+  <paragraph>An interface member is sometimes referred to by its fully qualified name. The fully qualified name of an interface member consists of the name of the interface in which the member is declared, followed by a dot, followed by the name of the member. The fully qualified name of a member references the interface in which the member is declared. <example>[Example: For example, given the declarations <code_example><![CDATA[
+interface IControl  
+{  
+   void Paint();  
+}  
+interface ITextBox: IControl  
+{  
+   void SetText(string text);  
+}  
+]]></code_example>the fully qualified name of Paint is IControl.Paint and the fully qualified name of SetText is ITextBox.SetText. In the example above, it is not possible to refer to Paint as ITextBox.Paint. end example]</example> </paragraph>
+  <paragraph>When an interface is part of a namespace, the fully qualified name of an interface member includes the namespace name. <example>[Example: For example <code_example><![CDATA[
+namespace System  
+{  
+   public interface ICloneable  
+   {  
+      object Clone();  
+   }  
+}  
+]]></code_example></example></paragraph>
+  <paragraph>
+    <example>Here, the fully qualified name of the Clone method is System.ICloneable.Clone. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/20.4.1.xml b/mcs/docs/ecma334/20.4.1.xml
new file mode 100644 (file)
index 0000000..39ed663
--- /dev/null
@@ -0,0 +1,72 @@
+<?xml version="1.0"?>
+<clause number="20.4.1" title="Explicit interface member implementations">
+  <paragraph>For purposes of implementing interfaces, a class or struct may declare explicit interface member implementations. An explicit interface member implementation is a method, property, event, or indexer declaration that references a fully qualified interface member name. <example>[Example: For example <code_example><![CDATA[
+interface ICloneable  
+{  
+   object Clone();  
+}  
+interface IComparable  
+{  
+   int CompareTo(object other);  
+}  
+class ListEntry: ICloneable, IComparable  
+{  
+   object ICloneable.Clone() {...}  
+   int IComparable.CompareTo(object other) {...}  
+}  
+]]></code_example></example></paragraph>
+  <paragraph>
+    <example>Here, ICloneable.Clone and IComparable.CompareTo are explicit interface member implementations. end example]</example>
+  </paragraph>
+  <paragraph>
+    <example>[Example: In some cases, the name of an interface member may not be appropriate for the implementing class, in which case the interface member may be implemented using explicit interface member implementation. A class implementing a file abstraction, for example, would likely implement a Close member function that has the effect of releasing the file resource, and implement the Dispose method of the IDisposable interface using explicit interface member implementation: <code_example><![CDATA[
+interface IDisposable {  
+   void Dispose();  
+}  
+class MyFile: IDisposable {  
+   void IDisposable.Dispose() {  
+      Close();  
+   }  
+   public void Close() {  
+      // Do what's necessary to close the file  
+      System.GC.SuppressFinalize(this);  
+   }  
+}  
+]]></code_example>end example]</example>
+  </paragraph>
+  <paragraph>It is not possible to access an explicit interface member implementation through its fully qualified name in a method invocation, property access, or indexer access. An explicit interface member implementation can only be accessed through an interface instance, and is in that case referenced simply by its member name. </paragraph>
+  <paragraph>It is a compile-time error for an explicit interface member implementation to include access modifiers, and it is a compile-time error to include the modifiers abstract, virtual, override, or static. </paragraph>
+  <paragraph>Explicit interface member implementations have different accessibility characteristics than other members. Because explicit interface member implementations are never accessible through their fully qualified name in a method invocation or a property access, they are in a sense private. However, since they can be accessed through an interface instance, they are in a sense also public. </paragraph>
+  <paragraph>Explicit interface member implementations serve two primary purposes: <list><list_item> Because explicit interface member implementations are not accessible through class or struct instances, they allow interface implementations to be excluded from the public interface of a class or struct. This is particularly useful when a class or struct implements an internal interface that is of no interest to a consumer of that class or struct. </list_item><list_item> Explicit interface member implementations allow disambiguation of interface members with the same signature. Without explicit interface member implementations it would be impossible for a class or struct to have different implementations of interface members with the same signature and return type, as would it be impossible for a class or struct to have any implementation at all of interface members with the same signature but with different return types. </list_item></list></paragraph>
+  <paragraph>For an explicit interface member implementation to be valid, the class or struct must name an interface in its base class list that contains a member whose fully qualified name, type, and parameter types exactly match those of the explicit interface member implementation. <example>[Example: Thus, in the following class <code_example><![CDATA[
+class Shape: ICloneable  
+{  
+   object ICloneable.Clone() {...}  
+   int IComparable.CompareTo(object other) {...}  // invalid  
+}  
+]]></code_example>the declaration of IComparable.CompareTo results in a compile-time error because IComparable is not listed in the base class list of Shape and is not a base interface of ICloneable. Likewise, in the declarations <code_example><![CDATA[
+class Shape: ICloneable  
+{  
+   object ICloneable.Clone() {...}  
+}  
+class Ellipse: Shape  
+{  
+   object ICloneable.Clone() {...} // invalid  
+}  
+]]></code_example>the declaration of ICloneable.Clone in Ellipse results in a compile-time error because ICloneable is not explicitly listed in the base class list of Ellipse. end example]</example> </paragraph>
+  <paragraph>The fully qualified name of an interface member must reference the interface in which the member was declared. <example>[Example: Thus, in the declarations <code_example><![CDATA[
+interface IControl  
+{  
+   void Paint();  
+}  
+interface ITextBox: IControl  
+{  
+   void SetText(string text);  
+}  
+class TextBox: ITextBox  
+{  
+   void IControl.Paint() {...}  
+   void ITextBox.SetText(string text) {...}  
+}  
+]]></code_example>the explicit interface member implementation of Paint must be written as IControl.Paint. end example]</example> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/20.4.2.xml b/mcs/docs/ecma334/20.4.2.xml
new file mode 100644 (file)
index 0000000..63b7853
--- /dev/null
@@ -0,0 +1,105 @@
+<?xml version="1.0"?>
+<clause number="20.4.2" title="Interface mapping">
+  <paragraph>A class or struct must provide implementations of all members of the interfaces that are listed in the base class list of the class or struct. The process of locating implementations of interface members in an implementing class or struct is known as interface mapping. </paragraph>
+  <paragraph>Interface mapping for a class or struct C locates an implementation for each member of each interface specified in the base class list of C. The implementation of a particular interface member I.M, where I is the interface in which the member M is declared, is determined by examining each class or struct S, starting with C and repeating for each successive base class of C, until a match is located: <list><list_item> If S contains a declaration of an explicit interface member implementation that matches I and M, then this member is the implementation of I.M. </list_item><list_item> Otherwise, if S contains a declaration of a non-static public member that matches M, then this member is the implementation of I.M. </list_item></list></paragraph>
+  <paragraph>A compile-time error occurs if implementations cannot be located for all members of all interfaces specified in the base class list of C. Note that the members of an interface include those members that are inherited from base interfaces. </paragraph>
+  <paragraph>For purposes of interface mapping, a class member A matches an interface member B when: <list><list_item> A and B are methods, and the name, type, and formal parameter lists of A and B are identical. </list_item><list_item> A and B are properties, the name and type of A and B are identical, and A has the same accessors as B (A is permitted to have additional accessors if it is not an explicit interface member implementation). </list_item><list_item> A and B are events, and the name and type of A and B are identical. </list_item><list_item> A and B are indexers, the type and formal parameter lists of A and B are identical, and A has the same accessors as B (A is permitted to have additional accessors if it is not an explicit interface member implementation). </list_item></list></paragraph>
+  <paragraph>Notable implications of the interface-mapping algorithm are: <list><list_item> Explicit interface member implementations take precedence over other members in the same class or struct when determining the class or struct member that implements an interface member. </list_item><list_item> Neither non-public nor static members participate in interface mapping. </list_item></list></paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+interface ICloneable  
+{  
+   object Clone();  
+}  
+class C: ICloneable  
+{  
+   object ICloneable.Clone() {...}  
+   public object Clone() {...}  
+}  
+]]></code_example>the ICloneable.Clone member of C becomes the implementation of Clone in ICloneable because explicit interface member implementations take precedence over other members. end example]</example>
+  </paragraph>
+  <paragraph>If a class or struct implements two or more interfaces containing a member with the same name, type, and parameter types, it is possible to map each of those interface members onto a single class or struct member. </paragraph>
+  <paragraph>
+    <example>[Example: For example <code_example><![CDATA[
+interface IControl  
+{  
+   void Paint();  
+}  
+interface IForm  
+{  
+   void Paint();  
+}  
+class Page: IControl, IForm  
+{  
+   public void Paint() {...}  
+}  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>Here, the Paint methods of both IControl and IForm are mapped onto the Paint method in Page. It is of course also possible to have separate explicit interface member implementations for the two methods. end example]</example>
+  </paragraph>
+  <paragraph>If a class or struct implements an interface that contains hidden members, then some members must necessarily be implemented through explicit interface member implementations. <example>[Example: For example <code_example><![CDATA[
+interface IBase  
+{  
+   int P { get; }  
+}  
+interface IDerived: IBase  
+{  
+   new int P();  
+}  
+]]></code_example></example></paragraph>
+  <paragraph>
+    <example>An implementation of this interface would require at least one explicit interface member implementation, and would take one of the following forms <code_example><![CDATA[
+class C: IDerived  
+{  
+   int IBase.P { get {...} }  
+   int IDerived.P() {...}  
+}  
+class C: IDerived  
+{  
+   public int P { get {...} }  
+   int IDerived.P() {...}  
+}  
+class C: IDerived  
+{  
+   int IBase.P { get {...} }  
+   public int P() {...}  
+}  
+]]></code_example>end example]</example>
+  </paragraph>
+  <paragraph>When a class implements multiple interfaces that have the same base interface, there can be only one implementation of the base interface. <example>[Example: In the example <code_example><![CDATA[
+interface IControl  
+{  
+   void Paint();  
+}  
+interface ITextBox: IControl  
+{  
+   void SetText(string text);  
+}  
+interface IListBox: IControl  
+{  
+   void SetItems(string[] items);  
+}  
+class ComboBox: IControl, ITextBox, IListBox  
+{  
+   void IControl.Paint() {...}  
+   void ITextBox.SetText(string text) {...}  
+   void IListBox.SetItems(string[] items) {...}  
+}  
+]]></code_example>it is not possible to have separate implementations for the IControl named in the base class list, the IControl inherited by ITextBox, and the IControl inherited by IListBox. Indeed, there is no notion of a separate identity for these interfaces. Rather, the implementations of ITextBox and IListBox share the same implementation of IControl, and ComboBox is simply considered to implement three interfaces, IControl, ITextBox, and IListBox. end example]</example> </paragraph>
+  <paragraph>The members of a base class participate in interface mapping. <example>[Example: In the example <code_example><![CDATA[
+interface Interface1  
+{  
+   void F();  
+}  
+class Class1  
+{  
+   public void F() {}  
+   public void G() {}  
+}  
+class Class2: Class1, Interface1  
+{  
+   new public void G() {}  
+}  
+]]></code_example>the method F in Class1 is used in Class2's implementation of Interface1. end example]</example> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/20.4.3.xml b/mcs/docs/ecma334/20.4.3.xml
new file mode 100644 (file)
index 0000000..090219e
--- /dev/null
@@ -0,0 +1,68 @@
+<?xml version="1.0"?>
+<clause number="20.4.3" title="Interface implementation inheritance">
+  <paragraph>A class inherits all interface implementations provided by its base classes. </paragraph>
+  <paragraph>Without explicitly re-implementing an interface, a derived class cannot in any way alter the interface mappings it inherits from its base classes. <example>[Example: For example, in the declarations <code_example><![CDATA[
+interface IControl  
+{  
+   void Paint();  
+}  
+class Control: IControl  
+{  
+   public void Paint() {...}  
+}  
+class TextBox: Control  
+{  
+   new public void Paint() {...}  
+}  
+]]></code_example>the Paint method in TextBox hides the Paint method in Control, but it does not alter the mapping of Control.Paint onto IControl.Paint, and calls to Paint through class instances and interface instances will have the following effects <code_example><![CDATA[
+Control c = new Control();  
+TextBox t = new TextBox();  
+IControl ic = c;  
+IControl it = t;  
+c.Paint();    // invokes Control.Paint();  
+t.Paint();    // invokes TextBox.Paint();  
+ic.Paint();   // invokes Control.Paint();  
+it.Paint();   // invokes Control.Paint();  
+]]></code_example>end example]</example> </paragraph>
+  <paragraph>However, when an interface method is mapped onto a virtual method in a class, it is possible for derived classes to override the virtual method and alter the implementation of the interface. <example>[Example: For example, rewriting the declarations above to <code_example><![CDATA[
+interface IControl  
+{  
+   void Paint();  
+}  
+class Control: IControl  
+{  
+   public virtual void Paint() {...}  
+}  
+class TextBox: Control  
+{  
+   public override void Paint() {...}  
+}  
+]]></code_example>the following effects will now be observed <code_example><![CDATA[
+Control c = new Control();  
+TextBox t = new TextBox();  
+IControl ic = c;  
+IControl it = t;  
+c.Paint();    // invokes Control.Paint();  
+t.Paint();    // invokes TextBox.Paint();  
+ic.Paint();   // invokes Control.Paint();  
+it.Paint();   // invokes TextBox.Paint();  
+]]></code_example>end example]</example> </paragraph>
+  <paragraph>Since explicit interface member implementations cannot be declared virtual, it is not possible to override an explicit interface member implementation. However, it is perfectly valid for an explicit interface member implementation to call another method, and that other method can be declared virtual to allow derived classes to override it. <example>[Example: For example <code_example><![CDATA[
+interface IControl  
+{  
+   void Paint();  
+}  
+class Control: IControl  
+{  
+   void IControl.Paint() { PaintControl(); }  
+   protected virtual void PaintControl() {...}  
+}  
+class TextBox: Control  
+{  
+   protected override void PaintControl() {...}  
+}  
+]]></code_example></example></paragraph>
+  <paragraph>
+    <example>Here, classes derived from Control can specialize the implementation of IControl.Paint by overriding the PaintControl method. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/20.4.4.xml b/mcs/docs/ecma334/20.4.4.xml
new file mode 100644 (file)
index 0000000..dd2b653
--- /dev/null
@@ -0,0 +1,65 @@
+<?xml version="1.0"?>
+<clause number="20.4.4" title="Interface re-implementation">
+  <paragraph>A class that inherits an interface implementation is permitted to re-implement the interface by including it in the base class list. </paragraph>
+  <paragraph>A re-implementation of an interface follows exactly the same interface mapping rules as an initial implementation of an interface. Thus, the inherited interface mapping has no effect whatsoever on the interface mapping established for the re-implementation of the interface. <example>[Example: For example, in the declarations <code_example><![CDATA[
+interface IControl  
+{  
+   void Paint();  
+}  
+class Control: IControl  
+{  
+   void IControl.Paint() {...}  
+}  
+class MyControl: Control, IControl  
+{  
+   public void Paint() {}  
+}  
+]]></code_example>the fact that Control maps IControl.Paint onto Control.IControl.Paint doesn't affect the  re-implementation in MyControl, which maps IControl.Paint onto MyControl.Paint. end example]</example> </paragraph>
+  <paragraph>Inherited public member declarations and inherited explicit interface member declarations participate in the interface mapping process for re-implemented interfaces. <example>[Example: For example <code_example><![CDATA[
+interface IMethods  
+{  
+   void F();  
+   void G();  
+   void H();  
+   void I();  
+}  
+class Base: IMethods  
+{  
+   void IMethods.F() {}  
+   void IMethods.G() {}  
+   public void H() {}  
+   public void I() {}  
+}  
+class Derived: Base, IMethods  
+{  
+   public void F() {}  
+   void IMethods.H() {}  
+}  
+]]></code_example></example></paragraph>
+  <paragraph>
+    <example>Here, the implementation of IMethods in Derived maps the interface methods onto Derived.F, Base.IMethods.G, Derived.IMethods.H, and Base.I. end example]</example>
+  </paragraph>
+  <paragraph>When a class implements an interface, it implicitly also implements all of that interface's base interfaces. Likewise, a re-implementation of an interface is also implicitly a re-implementation of all of the interface's base interfaces. <example>[Example: For example <code_example><![CDATA[
+interface IBase  
+{  
+   void F();  
+}  
+interface IDerived: IBase  
+{  
+   void G();  
+}  
+class C: IDerived  
+{  
+   void IBase.F() {...}  
+   void IDerived.G() {...}  
+}  
+class D: C, IDerived  
+{  
+   public void F() {...}  
+   public void G() {...}  
+}  
+]]></code_example></example></paragraph>
+  <paragraph>
+    <example>Here, the re-implementation of IDerived also re-implements IBase, mapping IBase.F onto D.F. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/20.4.5.xml b/mcs/docs/ecma334/20.4.5.xml
new file mode 100644 (file)
index 0000000..f424609
--- /dev/null
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<clause number="20.4.5" title="Abstract classes and interfaces">
+  <paragraph>Like a non-abstract class, an abstract class must provide implementations of all members of the interfaces that are listed in the base class list of the class. However, an abstract class is permitted to map interface methods onto abstract methods. <example>[Example: For example <code_example><![CDATA[
+interface IMethods  
+{  
+   void F();  
+   void G();  
+}  
+abstract class C: IMethods  
+{  
+   public abstract void F();  
+   public abstract void G();  
+}  
+]]></code_example></example></paragraph>
+  <paragraph>
+    <example>Here, the implementation of IMethods maps F and G onto abstract methods, which must be overridden in non-abstract classes that derive from C. end example]</example>
+  </paragraph>
+  <paragraph>Note that explicit interface member implementations cannot be abstract, but explicit interface member implementations are of course permitted to call abstract methods. <example>[Example: For example <code_example><![CDATA[
+interface IMethods  
+{  
+   void F();  
+   void G();  
+}  
+abstract class C: IMethods  
+{  
+   void IMethods.F() { FF(); }  
+   void IMethods.G() { GG(); }  
+   protected abstract void FF();  
+   protected abstract void GG();  
+}  
+]]></code_example></example></paragraph>
+  <paragraph>
+    <example>Here, non-abstract classes that derive from C would be required to override FF and GG, thus providing the actual implementation of IMethods. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/20.4.xml b/mcs/docs/ecma334/20.4.xml
new file mode 100644 (file)
index 0000000..79d44ba
--- /dev/null
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<clause number="20.4" title="Interface implementations">
+  <paragraph>Interfaces may be implemented by classes and structs. To indicate that a class or struct implements an interface, the interface identifier is included in the base class list of the class or struct. <example>[Example: For example: <code_example><![CDATA[
+interface ICloneable  
+{  
+   object Clone();  
+}  
+interface IComparable  
+{  
+   int CompareTo(object other);  
+}  
+class ListEntry: ICloneable, IComparable  
+{  
+   public object Clone() {...}  
+   public int CompareTo(object other) {...}  
+}  
+]]></code_example>end example]</example> </paragraph>
+  <paragraph>A class or struct that implements an interface also implicitly implements all of the interface's base interfaces. This is true even if the class or struct doesn't explicitly list all base interfaces in the base class list. <example>[Example: For example: <code_example><![CDATA[
+interface IControl  
+{  
+   void Paint();  
+}  
+interface ITextBox: IControl  
+{  
+   void SetText(string text);  
+}  
+class TextBox: ITextBox  
+{  
+   public void Paint() {...}  
+   public void SetText(string text) {...}  
+}  
+]]></code_example></example></paragraph>
+  <paragraph>
+    <example>Here, class TextBox implements both IControl and ITextBox. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/20.xml b/mcs/docs/ecma334/20.xml
new file mode 100644 (file)
index 0000000..6651c79
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="20" title="Interfaces">
+  <paragraph>An interface defines a contract. A class or struct that implements an interface must adhere to its contract. An interface may inherit from multiple base interfaces, and a class or struct may implement multiple interfaces. </paragraph>
+  <paragraph>Interfaces can contain methods, properties, events, and indexers. The interface itself does not provide implementations for the members that it defines. The interface merely specifies the members that must be supplied by classes or interfaces that implement the interface. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/21.1.xml b/mcs/docs/ecma334/21.1.xml
new file mode 100644 (file)
index 0000000..d244038
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<clause number="21.1" title="Enum declarations">
+  <paragraph>An enum declaration declares a new enum type. An enum declaration begins with the keyword enum, and defines the name, accessibility, underlying type, and members of the enum. <grammar_production><name><non_terminal where="21.1">enum-declaration</non_terminal></name> : <rhs><non_terminal where="24.2">attributes</non_terminal><opt/><non_terminal where="21.2">enum-modifiers</non_terminal><opt/><keyword>enum</keyword><non_terminal where="9.4.2">identifier</non_terminal><non_terminal where="21.1">enum-base</non_terminal><opt/><non_terminal where="21.1">enum-body</non_terminal><terminal>;</terminal><opt/></rhs></grammar_production><grammar_production><name><non_terminal where="21.1">enum-base</non_terminal></name> : <rhs><terminal>:</terminal><non_terminal where="11.1">integral-type</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="21.1">enum-body</non_terminal></name> : <rhs><terminal>{</terminal><non_terminal where="21.3">enum-member-declarations</non_terminal><opt/><terminal>}</terminal></rhs><rhs><terminal>{</terminal><non_terminal where="21.3">enum-member-declarations</non_terminal><terminal>,</terminal><terminal>}</terminal></rhs></grammar_production></paragraph>
+  <paragraph>Each enum type has a corresponding integral type called the underlying type of the enum type. This underlying type must be able to represent all the enumerator values defined in the enumeration. An enum declaration may explicitly declare an underlying type of <keyword>byte</keyword>, <keyword>sbyte</keyword>, <keyword>short</keyword>, <keyword>ushort</keyword>, <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>long</keyword> or <keyword>ulong</keyword>. <note>[Note: <keyword>char</keyword> cannot be used as an underlying type. end note]</note> An enum declaration that does not explicitly declare an underlying type has an underlying type of <keyword>int</keyword>. </paragraph>
+  <paragraph>
+    <example>[Example: The example <code_example><![CDATA[
+enum Color: long  
+{  
+   Red,  
+   Green,  
+   Blue  
+}  
+]]></code_example>declares an enum with an underlying type of <keyword>long</keyword>. end example]</example>
+    <note>[Note: A developer might choose to use an underlying type of <keyword>long</keyword>, as in the example, to enable the use of values that are in the range of <keyword>long</keyword> but not in the range of <keyword>int</keyword>, or to preserve this option for the future. end note]</note>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/21.2.xml b/mcs/docs/ecma334/21.2.xml
new file mode 100644 (file)
index 0000000..8b457ea
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="21.2" title="Enum modifiers">
+  <paragraph>An <non_terminal where="21.1">enum-declaration</non_terminal> may optionally include a sequence of enum modifiers: <grammar_production><name><non_terminal where="21.2">enum-modifier</non_terminal>s</name> : <rhs><non_terminal where="21.2">enum-modifier</non_terminal></rhs><rhs><non_terminal where="21.2">enum-modifiers</non_terminal><non_terminal where="21.2">enum-modifier</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="21.2">enum-modifier</non_terminal></name> : <rhs><keyword>new</keyword></rhs><rhs><keyword>public</keyword></rhs><rhs><keyword>protected</keyword></rhs><rhs><keyword>internal</keyword></rhs><rhs><keyword>private</keyword></rhs></grammar_production>It is a compile-time error for the same modifier to appear multiple times in an enum declaration. </paragraph>
+  <paragraph>The modifiers of an enum declaration have the same meaning as those of a class declaration (<hyperlink>17.1.1</hyperlink>). Note, however, that the abstract and sealed modifiers are not permitted in an enum declaration. Enums cannot be abstract and do not permit derivation. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/21.3.xml b/mcs/docs/ecma334/21.3.xml
new file mode 100644 (file)
index 0000000..0f4ece3
--- /dev/null
@@ -0,0 +1,69 @@
+<?xml version="1.0"?>
+<clause number="21.3" title="Enum members">
+  <paragraph>The body of an enum type declaration defines zero or more enum members, which are the named constants of the enum type. No two enum members can have the same name. <grammar_production><name><non_terminal where="21.3">enum-member-declaration</non_terminal>s</name> : <rhs><non_terminal where="21.3">enum-member-declaration</non_terminal></rhs><rhs><non_terminal where="21.3">enum-member-declarations</non_terminal><terminal>,</terminal><non_terminal where="21.3">enum-member-declaration</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="21.3">enum-member-declaration</non_terminal></name> : <rhs><non_terminal where="24.2">attributes</non_terminal><opt/><non_terminal where="9.4.2">identifier</non_terminal></rhs><rhs><non_terminal where="24.2">attributes</non_terminal><opt/><non_terminal where="9.4.2">identifier</non_terminal><terminal>=</terminal><non_terminal where="14.15">constant-expression</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>Each enum member has an associated constant value. The type of this value is the underlying type for the containing enum. The constant value for each enum member must be in the range of the underlying type for the enum. <example>[Example: The example <code_example><![CDATA[
+enum Color: uint  
+{  
+   Red = -1,  
+   Green = -2,  
+   Blue = -3  
+}  
+]]></code_example>results in a compile-time error because the constant values -1, -2, and -3 are not in the range of the underlying integral type <keyword>uint</keyword>. end example]</example> </paragraph>
+  <paragraph>Multiple enum members may share the same associated value. <example>[Example: The example <code_example><![CDATA[
+enum Color   
+{  
+   Red,  
+   Green,  
+   Blue,  
+   
+   Max = Blue  
+}  
+]]></code_example>shows an enum that has two enum members-Blue and Max-that have the same associated value. end example]</example> </paragraph>
+  <paragraph>The associated value of an enum member is assigned either implicitly or explicitly. If the declaration of the enum member has a <non_terminal where="14.15">constant-expression</non_terminal> initializer, the value of that constant expression, implicitly converted to the underlying type of the enum, is the associated value of the enum member. If the declaration of the enum member has no initializer, its associated value is set implicitly, as follows: <list><list_item> If the enum member is the first enum member declared in the enum type, its associated value is zero. </list_item><list_item> Otherwise, the associated value of the enum member is obtained by increasing the associated value of the textually preceding enum member by one. This increased value must be within the range of values that can be represented by the underlying type. </list_item></list></paragraph>
+  <paragraph>
+    <example>[Example: The example <code_example><![CDATA[
+using System;  
+enum Color  
+{  
+   Red,  
+   Green = 10,  
+   Blue  
+}  
+class Test  
+{  
+   static void Main() {  
+      Console.WriteLine(StringFromColor(Color.Red));  
+      Console.WriteLine(StringFromColor(Color.Green));  
+      Console.WriteLine(StringFromColor(Color.Blue));  
+   }  
+   static string StringFromColor(Color c) {  
+      switch (c) {  
+         case Color.Red:   
+         return String.Format("Red = {0}", (int) c);  
+         case Color.Green:  
+         return String.Format("Green = {0}", (int) c);  
+         case Color.Blue:  
+         return String.Format("Blue = {0}", (int) c);  
+         default:  
+         return "Invalid color";  
+      }  
+   }  
+}  
+]]></code_example>prints out the enum member names and their associated values. The output is: <code_example><![CDATA[
+Red = 0  
+Green = 10  
+Blue = 11  
+]]></code_example>for the following reasons: <list><list_item> the enum member Red is automatically assigned the value zero (since it has no initializer and is the first enum member); </list_item><list_item> the enum member Green is explicitly given the value 10; </list_item><list_item> and the enum member Blue is automatically assigned the value one greater than the member that textually precedes it. end example]</list_item></list></example>
+  </paragraph>
+  <paragraph>The associated value of an enum member may not, directly or indirectly, use the value of its own associated enum member. Other than this circularity restriction, enum member initializers may freely refer to other enum member initializers, regardless of their textual position. Within an enum member initializer, values of other enum members are always treated as having the type of their underlying type, so that casts are not necessary when referring to other enum members. </paragraph>
+  <paragraph>
+    <example>[Example: The example <code_example><![CDATA[
+enum Circular  
+{  
+   A = B,  
+   B  
+}  
+]]></code_example>results in a compile-time error because the declarations of A and B are circular. A depends on B explicitly, and B depends on A implicitly. end example]</example>
+  </paragraph>
+  <paragraph>Enum members are named and scoped in a manner exactly analogous to fields within classes. The scope of an enum member is the body of its containing enum type. Within that scope, enum members can be referred to by their simple name. From all other code, the name of an enum member must be qualified with the name of its enum type. Enum members do not have any declared accessibility-an enum member is accessible if its containing enum type is accessible. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/21.4.xml b/mcs/docs/ecma334/21.4.xml
new file mode 100644 (file)
index 0000000..8b69275
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<clause number="21.4" title="Enum values and operations">
+  <paragraph>Each enum type defines a distinct type; an explicit enumeration conversion (<hyperlink>13.2.2</hyperlink>) is required to convert between an enum type and an integral type, or between two enum types. The set of values that an enum type can take on is not limited by its enum members. In particular, any value of the underlying type of an enum can be cast to the enum type, and is a distinct valid value of that enum type. </paragraph>
+  <paragraph>Enum members have the type of their containing enum type (except within other enum member initializers: see <hyperlink>21.3</hyperlink>). The value of an enum member declared in enum type E with associated value v is (E)v. </paragraph>
+  <paragraph>The following operators can be used on values of enum types: ==, !=, &lt;, &gt;, &lt;=, &gt;= (<hyperlink>14.9.5</hyperlink>), + (<hyperlink>14.7.4</hyperlink>),  (<hyperlink>14.7.5</hyperlink>), -^, &amp;, | (<hyperlink>14.10.2</hyperlink>), ~ (<hyperlink>14.6.4</hyperlink>), ++,  (<hyperlink>14.5.9</hyperlink> --and <hyperlink>14.6.5</hyperlink>), and sizeof (<hyperlink>25.5.4</hyperlink>). </paragraph>
+  <paragraph>Every enum type automatically derives from the class System.Enum. Thus, inherited methods and properties of this class can be used on values of an enum type. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/21.xml b/mcs/docs/ecma334/21.xml
new file mode 100644 (file)
index 0000000..fddc5ec
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<clause number="21" title="Enums">
+  <paragraph>An enum type is a distinct type that declares a set of named constants. <example>[Example: The example <code_example><![CDATA[
+enum Color  
+{  
+   Red,  
+   Green,  
+   Blue  
+}  
+]]></code_example>declares an enum type named Color with members Red, Green, and Blue. end example]</example> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/22.1.xml b/mcs/docs/ecma334/22.1.xml
new file mode 100644 (file)
index 0000000..8578707
--- /dev/null
@@ -0,0 +1,56 @@
+<?xml version="1.0"?>
+<clause number="22.1" title="Delegate declarations">
+  <paragraph>A <non_terminal where="22.1">delegate-declaration</non_terminal> is a <non_terminal where="16.5">type-declaration</non_terminal> (<hyperlink>16.5</hyperlink>) that declares a new delegate type. <grammar_production><name><non_terminal where="22.1">delegate-declaration</non_terminal></name> : <rhs><non_terminal where="24.2">attributes</non_terminal><opt/><non_terminal where="22.1">delegate-modifiers</non_terminal><opt/><keyword>delegate</keyword><non_terminal where="17.5">return-type</non_terminal><non_terminal where="9.4.2">identifier</non_terminal><terminal>(</terminal><non_terminal where="17.5.1">formal-parameter-list</non_terminal><opt/><terminal>)</terminal><terminal>;</terminal></rhs></grammar_production><grammar_production><name><non_terminal where="22.1">delegate-modifier</non_terminal>s</name> : <rhs><non_terminal where="22.1">delegate-modifier</non_terminal></rhs><rhs><non_terminal where="22.1">delegate-modifiers</non_terminal><non_terminal where="22.1">delegate-modifier</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="22.1">delegate-modifier</non_terminal></name> : <rhs><keyword>new</keyword></rhs><rhs><keyword>public</keyword></rhs><rhs><keyword>protected</keyword></rhs><rhs><keyword>internal</keyword></rhs><rhs><keyword>private</keyword></rhs></grammar_production>It is a compile-time error for the same modifier to appear multiple times in a delegate declaration. </paragraph>
+  <paragraph>The new modifier is only permitted on delegates declared within another type, in which case it specifies that such a delegate hides an inherited member by the same name, as described in <hyperlink>17.2.2</hyperlink>. </paragraph>
+  <paragraph>The public, protected, internal, and private modifiers control the accessibility of the delegate type. Depending on the context in which the delegate declaration occurs, some of these modifiers may not be permitted (<hyperlink>10.5.1</hyperlink>). </paragraph>
+  <paragraph>The delegate's type name is identifier. </paragraph>
+  <paragraph>The optional <non_terminal where="17.5.1">formal-parameter-list</non_terminal> specifies the parameters of the delegate, and <non_terminal where="17.5">return-type</non_terminal> indicates the return type of the delegate. A method and a delegate type are compatible if both of the following are true: <list><list_item> They have the same number or parameters, with the same types, in the same order, with the same parameter modifiers. </list_item><list_item> Their <non_terminal where="17.5">return-type</non_terminal>s are the same. </list_item></list></paragraph>
+  <paragraph>Delegate types in C# are name equivalent, not structurally equivalent. <note>[Note: However, instances of two distinct but structurally equivalent delegate types may compare as equal (<hyperlink>14.9.8</hyperlink>). end note]</note> Specifically, two different delegate types that have the same parameter lists and return type are considered different delegate types. <example>[Example: For example: <code_example><![CDATA[
+delegate int D1(int i, double d);  
+class A  
+{  
+   public static int M1(int a, double b) {...}  
+}  
+class B  
+{  
+   delegate int D2(int c, double d);  
+   public static int M1(int f, double g) {...}  
+   public static void M2(int k, double l) {...}  
+   public static int M3(int g) {...}  
+   public static void M4(int g) {...}  
+}  
+]]></code_example></example></paragraph>
+  <paragraph>
+    <example>The delegate types D1 and D2 are both compatible with the methods A.M1 and B.M1, since they have the same return type and parameter list; however, these delegate types are two different types, so they are not interchangeable. The delegate types D1 and D2 are incompatible with the methods B.M2, B.M3, and B.M4, since they have different return types or parameter lists. end example]</example>
+  </paragraph>
+  <paragraph>The only way to declare a delegate type is via a <non_terminal where="22.1">delegate-declaration</non_terminal>. A delegate type is a class type that is derived from System.Delegate. Delegate types are implicitly sealed, so it is not permissible to derive any type from a delegate type. It is also not permissible to derive a non-delegate class type from System.Delegate. Note that System.Delegate is not itself a delegate type; it is a class type from which all delegate types are derived. </paragraph>
+  <paragraph>C# provides special syntax for delegate instantiation and invocation. Except for instantiation, any operation that can be applied to a class or class instance can also be applied to a delegate class or instance, respectively. In particular, it is possible to access members of the System.Delegate type via the usual member access syntax. </paragraph>
+  <paragraph>The set of methods encapsulated by a delegate instance is called an invocation list. When a delegate instance is created (<hyperlink>22.2</hyperlink>) from a single method, it encapsulates that method, and its invocation list contains only one entry. However, when two non-null delegate instances are combined, their invocation lists are concatenated-in the order left operand then right operand-to form a new invocation list, which contains two or more entries. </paragraph>
+  <paragraph>Delegates are combined using the binary + (<hyperlink>14.7.4</hyperlink>) and += operators (<hyperlink>14.13.2</hyperlink>). A delegate can be removed from a combination of delegates, using the binary  (<hyperlink>14.7.5</hyperlink>) -and -= operators (<hyperlink>14.13.2</hyperlink>). Delegates can be compared for equality (<hyperlink>14.9.8</hyperlink>). </paragraph>
+  <paragraph>
+    <example>[Example: The following example shows the instantiation of a number of delegates, and their corresponding invocation lists: <code_example><![CDATA[
+delegate void D(int x);  
+class Test  
+{  
+   public static void M1(int i) {...}  
+   public static void M2(int i) {...}  
+}  
+class Demo  
+{  
+   static void Main() {   
+      D cd1 = new D(Test.M1); // M1  
+      D cd2 = new D(Test.M2); // m2  
+      D cd3 = cd1 + cd2;    // M1 + M2  
+      D cd4 = cd3 + cd1;     // M1 + M2 + M1  
+      D cd5 = cd4 + cd3;     // M1 + M2 + M1 + M1 + M2  
+   }  
+}  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>When cd1 and cd2 are instantiated, they each encapsulate one method. When cd3 is instantiated, it has an invocation list of two methods, M1 and M2, in that order. cd4's invocation list contains M1, M2, and M1, in that order. Finally, cd5's invocation list contains M1, M2, M1, M1, and M2, in that order. </example>
+  </paragraph>
+  <paragraph>
+    <example>For more examples of combining (as well as removing) delegates, see <hyperlink>22.3</hyperlink>. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/22.2.xml b/mcs/docs/ecma334/22.2.xml
new file mode 100644 (file)
index 0000000..1e763a9
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<clause number="22.2" title="Delegate instantiation">
+  <paragraph>An instance of a delegate is created by a <non_terminal where="14.5.10.3">delegate-creation-expression</non_terminal> (<hyperlink>14.5.10.3</hyperlink>). The newly created delegate instance then refers to either: <list><list_item> The static method referenced in the <non_terminal where="14.5.10.3">delegate-creation-expression</non_terminal>, or </list_item><list_item> The target object (which cannot be null) and instance method referenced in the  <non_terminal where="14.5.10.3">delegate-creation-expression</non_terminal>, or </list_item><list_item> Another delegate <example>[Example: For example: <code_example><![CDATA[
+delegate void D(int x);  
+class Test  
+{  
+   public static void M1(int i)  {...}  
+   public void M2(int i)    {...}  
+}  
+class Demo  
+{  
+   static void Main() {   
+      D cd1 = new D(Test.M1); // static method  
+      Test t = new Test();  
+      D cd2 = new D(t.M2);   // instance method  
+      D cd3 = new D(cd2);    // another delegate  
+   }  
+}  
+]]></code_example>end example]</example> </list_item></list></paragraph>
+  <paragraph>Once instantiated, delegate instances always refer to the same target object and method. <note>[Note: Remember, when two delegates are combined, or one is removed from another, a new delegate results with its own invocation list; the invocation lists of the delegates combined or removed remain unchanged. end note]</note> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/22.3.xml b/mcs/docs/ecma334/22.3.xml
new file mode 100644 (file)
index 0000000..67639cc
--- /dev/null
@@ -0,0 +1,82 @@
+<?xml version="1.0"?>
+<clause number="22.3" title="Delegate invocation">
+  <paragraph>C# provides special syntax for invoking a delegate. When a non-null delegate instance whose invocation list contains one entry, is invoked, it invokes the one method with the same arguments it was given, and returns the same value as the referred to method. (See <hyperlink>14.5.5.2</hyperlink> for detailed information on delegate invocation.) If an exception occurs during the invocation of such a delegate, and that exception is not caught within the method that was invoked, the search for an exception catch clause continues in the method that called the delegate, as if that method had directly called the method to which that delegate referred. </paragraph>
+  <paragraph>Invocation of a delegate instance whose invocation list contains multiple entries, proceeds by invoking each of the methods in the invocation list, synchronously, in order. Each method so called is passed the same set of arguments as was given to the delegate instance. If such a delegate invocation includes reference parameters (<hyperlink>17.5.1.2</hyperlink>), each method invocation will occur with a reference to the same variable; changes to that variable by one method in the invocation list will be visible to methods further down the invocation list. If the delegate invocation includes output parameters or a return value, their final value will come from the invocation of the last delegate in the list. If an exception occurs during processing of the invocation of such a delegate, and that exception is not caught within the method that was invoked, the search for an exception catch clause continues in the method that called the delegate, and any methods further down the invocation list are not invoked. </paragraph>
+  <paragraph>Attempting to invoke a delegate instance whose value is null results in an exception of type System.NullReferenceException. </paragraph>
+  <paragraph>
+    <example>[Example: The following example shows how to instantiate, combine, remove, and invoke delegates: <code_example><![CDATA[
+using System;  
+delegate void D(int x);  
+class Test  
+{  
+   public static void M1(int i) {  
+      Console.WriteLine("Test.M1: " + i);  
+   }  
+   public static void M2(int i) {  
+      Console.WriteLine("Test.M2: " + i);  
+   }  
+   public void M3(int i) {  
+      Console.WriteLine("Test.M3: " + i);  
+   }  
+}  
+class Demo  
+{  
+   static void Main() {   
+      D cd1 = new D(Test.M1);  
+      cd1(-1);  // call M1  
+      D cd2 = new D(Test.M2);  
+      cd2(-2);  // call M2  
+      D cd3 = cd1 + cd2;  
+      cd3(10);  // call M1 then M2  
+      
+      cd3 += cd1;  
+      cd3(20);  // call M1, M2, then M1  
+      Test t = new Test();  
+      D cd4 = new D(t.M3);  
+      cd3 += cd4;  
+      cd3(30);  // call M1, M2, M1, then M3  
+      cd3 -= cd1; // remove last M1  
+      cd3(40);  // call M1, M2, then M3  
+      cd3 -= cd4;  
+      cd3(50);  // call M1 then M2  
+      cd3 -= cd2;  
+      cd3(60);  // call M1  
+      cd3 -= cd2; // impossible removal is benign  
+      cd3(60);  // call M1  
+      cd3 -= cd1; // invocation list is empty  
+      //  cd3(70);  // System.NullReferenceException thrown  
+      cd3 -= cd1; // impossible removal is benign  
+   }  
+}  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>As shown in the statement cd3 += cd1;, a delegate can be present in an invocation list multiple times. In this case, it is simply invoked once per occurrence. In an invocation list such as this, when that delegate is removed, the last occurrence in the invocation list is the one actually removed. </example>
+  </paragraph>
+  <paragraph>
+    <example>Immediately prior to the execution of the final statement, cd3 -= cd1;, the delegate cd3 refers to an empty invocation list. Attempting to remove a delegate from an empty list (or to remove a non-existent delegate from a non-empty list) is not an error. </example>
+  </paragraph>
+  <paragraph>
+    <example>The output produced is: <code_example><![CDATA[
+Test.M1: -1  
+Test.M2: -2  
+Test.M1: 10  
+Test.M2: 10  
+Test.M1: 20  
+Test.M2: 20  
+Test.M1: 20  
+Test.M1: 30  
+Test.M2: 30  
+Test.M1: 30  
+Test.M3: 30  
+Test.M1: 40  
+Test.M2: 40  
+Test.M3: 40  
+Test.M1: 50  
+Test.M2: 50  
+Test.M1: 60  
+Test.M1: 60  
+]]></code_example>end example]</example>
+    <table_line/>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/22.xml b/mcs/docs/ecma334/22.xml
new file mode 100644 (file)
index 0000000..ed3effe
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<clause number="22" title="Delegates">
+  <paragraph>
+    <note>[Note: Delegates enable scenarios that other languages-such as C++, Pascal, and Modula-have addressed with function pointers. Unlike C++ function pointers, however, delegates are fully object oriented, and unlike C++ pointers to member functions, delegates encapsulate both an object instance and a method. end note]</note>
+  </paragraph>
+  <paragraph>A delegate declaration defines a class that is derived from the class System.Delegate. A delegate instance encapsulates one or more methods, each of which is referred to as a callable entity. For instance methods, a callable entity consists of an instance and a method on that instance. For static methods, a callable entity consists of just a method. Given a delegate instance and an appropriate set of arguments, one can invoke all of that delegate instance's methods with that set of arguments. </paragraph>
+  <paragraph>An interesting and useful property of a delegate instance is that it does not know or care about the classes of the methods it encapsulates; all that matters is that those methods be compatible (<hyperlink>22.1</hyperlink>) with the delegate's type. This makes delegates perfectly suited for &quot;anonymous&quot; invocation. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/23.1.xml b/mcs/docs/ecma334/23.1.xml
new file mode 100644 (file)
index 0000000..d2631c1
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="23.1" title="Causes of exceptions">
+  <paragraph>Exception can be thrown in two different ways. <list><list_item> A throw statement (<hyperlink>15.9.5</hyperlink>) throws an exception immediately and unconditionally. Control never reaches the statement immediately following the throw. </list_item><list_item> Certain exceptional conditions that arise during the processing of C# statements and expression cause an exception in certain circumstances when the operation cannot be completed normally. For example, an integer division operation (<hyperlink>14.7.2</hyperlink>) throws a System.DivideByZeroException if the denominator is zero. See <hyperlink>23.4</hyperlink> for a list of the various exceptions that can occur in this way. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/23.2.xml b/mcs/docs/ecma334/23.2.xml
new file mode 100644 (file)
index 0000000..c339717
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="23.2" title="The System.Exception class">
+  <paragraph>The System.Exception class is the base type of all exceptions. This class has a few notable properties that all exceptions share: <list><list_item> Message is a read-only property of type string that contains a human-readable description of the reason for the exception. </list_item><list_item> InnerException is a read-only property of type Exception. If its value is non-null, it refers to the exception that caused the current exception. (That is, the current exception was raised in a catch block handling the type InnerException.) Otherwise, its value is null, indicating that this exception was not caused by another exception. (The number of exception objects chained together in this manner can be arbitrary.) </list_item></list></paragraph>
+  <paragraph>The value of these properties can be specified in calls to the instance constructor for System.Exception. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/23.3.xml b/mcs/docs/ecma334/23.3.xml
new file mode 100644 (file)
index 0000000..1a92c5f
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<clause number="23.3" title="How exceptions are handled">
+  <paragraph>Exceptions are handled by a try statement (<hyperlink>15.10</hyperlink>). </paragraph>
+  <paragraph>When an exception occurs, the system searches for the nearest catch clause that can handle the exception, as determined by the run-time type of the exception. First, the current method is searched for a lexically enclosing try statement, and the associated catch clauses of the try statement are considered in order. If that fails, the method that called the current method is searched for a lexically enclosing try statement that encloses the point of the call to the current method. This search continues until a catch clause is found that can handle the current exception, by naming an exception class that is of the same class, or a base class, of the run-time type of the exception being thrown. A catch clause that doesn't name an exception class can handle any exception. </paragraph>
+  <paragraph>Once a matching catch clause is found, the system prepares to transfer control to the first statement of the catch clause. Before execution of the catch clause begins, the system first executes, in order any finally clauses that were associated with try statements more nested that than the one that caught the exception. </paragraph>
+  <paragraph>If no matching catch clause is found, one of two things occurs: <list><list_item> If the search for a matching catch clause reaches a static constructor (<hyperlink>17.11</hyperlink>) or static field initializer, then a System.TypeInitializationException is thrown at the point that triggered the invocation of the static constructor. The inner exception of the System.TypeInitializationException contains the exception that was originally thrown. </list_item><list_item> If the search for matching catch clauses reaches the code that initially started the thread, then execution of the thread is terminated. The impact of such termination is implementation-defined. </list_item></list></paragraph>
+  <paragraph>Exceptions that occur during destructor execution are worth special mention. If an exception occurs during destructor execution, and that exception is not caught, then the execution of that destructor is terminated and the destructor of the base class (if any) is called. If there is no base class (as in the case of the object type) or if there is no base class destructor, then the exception is discarded. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/23.4.xml b/mcs/docs/ecma334/23.4.xml
new file mode 100644 (file)
index 0000000..a40d7e7
--- /dev/null
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<clause number="23.4" title="Common Exception Classes">
+  <paragraph>The following exceptions are thrown by certain C# operations. <table_line>System.ArithmeticException A base class for exceptions that occur during </table_line>
+<table_line>arithmetic operations, such as </table_line>
+<table_line>System.DivideByZeroException and </table_line>
+<table_line>System.OverflowException. </table_line>
+<table_line>System.ArrayTypeMismatchException Thrown when a store into an array fails because the </table_line>
+<table_line>actual type of the stored element is incompatible </table_line>
+<table_line>with the actual type of the array. </table_line>
+<table_line>System.DivideByZeroException Thrown when an attempt to divide an integral </table_line>
+<table_line>value by zero occurs. </table_line>
+<table_line>System.IndexOutOfRangeException Thrown when an attempt to index an array via an </table_line>
+<table_line>index that is less than zero or outside the bounds of </table_line>
+<table_line>the array. </table_line>
+<table_line>System.InvalidCastException Thrown when an explicit conversion from a base </table_line>
+<table_line>type or interface to a derived type fails at run time. </table_line>
+<table_line>System.NullReferenceException Thrown when a null reference is used in a way </table_line>
+<table_line>that causes the referenced object to be required. </table_line>
+<table_line>System.OutOfMemoryException Thrown when an attempt to allocate memory (via </table_line>
+<table_line>new) fails. </table_line>
+<table_line>System.OverflowException Thrown when an arithmetic operation in a </table_line>
+<table_line>checked context overflows. </table_line>
+<table_line>System.StackOverflowException Thrown when the execution stack is exhausted by </table_line>
+<table_line>having too many pending method calls; typically </table_line>
+<table_line>indicative of very deep or unbounded recursion. </table_line>
+<table_line>System.TypeInitializationException Thrown when a static constructor throws an </table_line>
+<table_line>exception, and no catch clauses exists to catch it. </table_line>
+</paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/23.xml b/mcs/docs/ecma334/23.xml
new file mode 100644 (file)
index 0000000..7fffe9d
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="23" title="Exceptions">
+  <paragraph>Exceptions in C# provide a structured, uniform, and type-safe way of handling both system level and application-level error conditions. <note>[Note: The exception mechanism is C# is quite similar to that of C++, with a few important differences: <list><list_item> In C#, all exceptions must be represented by an instance of a class type derived from System.Exception. In C++, any value of any type can be used to represent an exception. </list_item><list_item> In C#, a finally block (<hyperlink>15.10</hyperlink>) can be used to write termination code that executes in both normal execution and exceptional conditions. Such code is difficult to write in C++ without duplicating code. </list_item><list_item> In C#, system-level exceptions such as overflow, divide-by-zero, and null dereferences have well defined exception classes and are on a par with application-level error conditions. end note]</list_item></list></note> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/24.1.1.xml b/mcs/docs/ecma334/24.1.1.xml
new file mode 100644 (file)
index 0000000..a4e607c
--- /dev/null
@@ -0,0 +1,43 @@
+<?xml version="1.0"?>
+<clause number="24.1.1" title="Attribute usage">
+  <paragraph>The attribute AttributeUsage (<hyperlink>24.4.1</hyperlink>) is used to describe how an attribute class can be used. </paragraph>
+  <paragraph>AttributeUsage has a positional parameter (<hyperlink>24.1.2</hyperlink>) that enables an attribute class to specify the kinds of declarations on which it can be used. <example>[Example: The example <code_example><![CDATA[
+using System;  
+[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)]  
+public class SimpleAttribute: Attribute  
+{}  
+]]></code_example>defines an attribute class named SimpleAttribute that can be placed on <non_terminal where="17.1">class-declaration</non_terminal>s and  <non_terminal where="20.1">interface-declaration</non_terminal>s only. The example <code_example><![CDATA[
+[Simple] class Class1 {...}  
+[Simple] interface Interface1 {...}  
+]]></code_example>shows several uses of the Simple attribute. Although this attribute is defined with the name SimpleAttribute, when this attribute is used, the Attribute suffix may be omitted, resulting in the <keyword>short</keyword> name Simple. Thus, the example above is semantically equivalent to the following <code_example><![CDATA[
+[SimpleAttribute] class Class1 {...}  
+[SimpleAttribute] interface Interface1 {...}  
+]]></code_example>end example]</example> </paragraph>
+  <paragraph>AttributeUsage has a named parameter (<hyperlink>24.1.2</hyperlink>), called AllowMultiple, which indicates whether the attribute can be specified more than once for a given entity. If AllowMultiple for an attribute class is true, then that class is a multi-use attribute class, and can be specified more than once on an entity. If AllowMultiple for an attribute class is false or it is unspecified, then that class is a single-use attribute class, and can be specified at most once on an entity. </paragraph>
+  <paragraph>
+    <example>[Example: The example <code_example><![CDATA[
+using System;  
+[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]  
+public class AuthorAttribute: Attribute {  
+   public AuthorAttribute(string name) {  
+      this.name = name;  
+   }  
+   public string Name { get { return name;} }  
+   private string name;  
+}  
+]]></code_example>defines a multi-use attribute class named AuthorAttribute. The example <code_example><![CDATA[
+[Author("Brian Kernighan"), Author("Dennis Ritchie")]   
+class Class1 {...}  
+]]></code_example>shows a class declaration with two uses of the Author attribute. end example]</example>
+  </paragraph>
+  <paragraph>AttributeUsage has another named parameter (<hyperlink>24.1.2</hyperlink>), called Inherited, which indicates whether the attribute, when specified on a base class, is also inherited by classes that derive from that base class. If Inherited for an attribute class is true, then that attribute is inherited. If Inherited for an attribute class is false or it is unspecified, then that attribute is not inherited. </paragraph>
+  <paragraph>An attribute class X not having an AttributeUsage attribute attached to it, as in <code_example><![CDATA[
+using System;  
+class X: Attribute { ... }  
+]]></code_example>is equivalent to the following: <code_example><![CDATA[
+using System;  
+[AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited =  
+true)]  
+class X: Attribute { ... }  
+]]></code_example></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/24.1.2.xml b/mcs/docs/ecma334/24.1.2.xml
new file mode 100644 (file)
index 0000000..9ea8c39
--- /dev/null
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<clause number="24.1.2" title="Positional and named parameters">
+  <paragraph>Attribute classes can have positional parameters and named parameters. Each public instance constructor for an attribute class defines a valid sequence of positional parameters for that attribute class. Each  non-static public read-write field and property for an attribute class defines a named parameter for the attribute class. </paragraph>
+  <paragraph>
+    <example>[Example: The example <code_example><![CDATA[
+using System;  
+[AttributeUsage(AttributeTargets.Class)]  
+public class HelpAttribute: Attribute  
+{  
+   public HelpAttribute(string url) {  // url is a positional parameter  
+      ...  
+   }  
+   public string Topic {  // Topic is a named parameter  
+      get {...}  
+      set {...}  
+   }  
+   public string Url { get {...} }  
+}  
+]]></code_example>defines an attribute class named HelpAttribute that has one positional parameter (string url) and one named parameter (string Topic). Although it is non-static and public, the property Url does not define a named parameter, since it is not read-write. </example>
+  </paragraph>
+  <paragraph>
+    <example>This attribute class might be used as follows: <code_example><![CDATA[
+[Help("http://www.mycompany.com/.../Class1.htm")]  
+class Class1 {  
+}  
+[Help("http://www.mycompany.com/.../Misc.htm", Topic ="Class2")]  
+class Class2 {  
+}  
+]]></code_example>end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/24.1.3.xml b/mcs/docs/ecma334/24.1.3.xml
new file mode 100644 (file)
index 0000000..dba0c8b
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="24.1.3" title="Attribute parameter types">
+  <paragraph>The types of positional and named parameters for an attribute class are limited to the attribute parameter types, which are: <list><list_item> One of the following types: <keyword>bool</keyword>, <keyword>byte</keyword>, <keyword>char</keyword>, <keyword>double</keyword>, <keyword>float</keyword>, <keyword>int</keyword>, <keyword>long</keyword>, <keyword>short</keyword>, string. </list_item><list_item> The type object. </list_item><list_item> The type System.Type. </list_item><list_item> An enum type, provided it has public accessibility and the types in which it is nested (if any) also have public accessibility. </list_item><list_item> Single-dimensional arrays of the above types. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/24.1.xml b/mcs/docs/ecma334/24.1.xml
new file mode 100644 (file)
index 0000000..bce9647
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="24.1" title="Attribute classes">
+  <paragraph>A class that derives from the abstract class System.Attribute, whether directly or indirectly, is an attribute class. The declaration of an attribute class defines a new kind of attribute that can be placed on a declaration. By convention, attribute classes are named with a suffix of Attribute. Uses of an attribute may either include or omit this suffix. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/24.2.xml b/mcs/docs/ecma334/24.2.xml
new file mode 100644 (file)
index 0000000..da3707e
--- /dev/null
@@ -0,0 +1,79 @@
+<?xml version="1.0"?>
+<clause number="24.2" title="Attribute specification">
+  <paragraph>Attribute specification is the application of a previously defined attribute to a declaration. An attribute is a piece of additional declarative information that is specified for a declaration. Attributes can be specified at global scope (to specify attributes on the containing assembly) and for <non_terminal where="16.5">type-declaration</non_terminal>s (<hyperlink>16.5</hyperlink>),  <non_terminal where="17.2">class-member-declaration</non_terminal>s (<hyperlink>17.2</hyperlink>), <non_terminal where="20.2">interface-member-declaration</non_terminal>s (<hyperlink>20.2</hyperlink>), <non_terminal where="21.3">enum-member-declaration</non_terminal>s (<hyperlink>21.1</hyperlink>), <non_terminal where="17.6.2">accessor-declarations</non_terminal> (<hyperlink>17.6.2</hyperlink>), <non_terminal where="17.7">event-accessor-declarations</non_terminal> (<hyperlink>17.7</hyperlink>), and <non_terminal where="17.5.1">formal-parameter-list</non_terminal>s (<hyperlink>17.5.1</hyperlink>). </paragraph>
+  <paragraph>Attributes are specified in attribute sections. An attribute section consists of a pair of square brackets, which surround a comma-separated list of one or more attributes. The order in which attributes are specified in such a list, and the order in which sections attached to the same program entity are arranged, is not significant. For instance, the attribute specifications [A][B], [B][A], [A, B], and [B, A] are equivalent. <grammar_production><name><non_terminal where="24.2">global-attributes</non_terminal></name> : <rhs><non_terminal where="24.2">global-attribute-sections</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="24.2">global-attribute-section</non_terminal>s</name> : <rhs><non_terminal where="24.2">global-attribute-section</non_terminal></rhs><rhs><non_terminal where="24.2">global-attribute-sections</non_terminal><non_terminal where="24.2">global-attribute-section</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="24.2">global-attribute-section</non_terminal></name> : <rhs><terminal>[</terminal><non_terminal where="24.2">global-attribute-target-specifier</non_terminal><non_terminal where="24.2">attribute-list</non_terminal><terminal>]</terminal></rhs><rhs><terminal>[</terminal><non_terminal where="24.2">global-attribute-target-specifier</non_terminal><non_terminal where="24.2">attribute-list</non_terminal><terminal>,]</terminal></rhs></grammar_production><grammar_production><name><non_terminal where="24.2">global-attribute-target-specifier</non_terminal></name> : <rhs><non_terminal where="24.2">global-attribute-target</non_terminal><terminal>:</terminal></rhs></grammar_production><grammar_production><name><non_terminal where="24.2">global-attribute-target</non_terminal></name> : <rhs><terminal>assembly  </terminal></rhs></grammar_production><grammar_production><name>attributes</name> : <rhs><non_terminal where="24.2">attribute-sections</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="24.2">attribute-section</non_terminal>s</name> : <rhs><non_terminal where="24.2">attribute-section</non_terminal></rhs><rhs><non_terminal where="24.2">attribute-sections</non_terminal><non_terminal where="24.2">attribute-section</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="24.2">attribute-section</non_terminal></name> : <rhs><terminal>[</terminal><non_terminal where="24.2">attribute-target-specifier</non_terminal><opt/><non_terminal where="24.2">attribute-list</non_terminal><terminal>]</terminal></rhs><rhs><terminal>[</terminal><non_terminal where="24.2">attribute-target-specifier</non_terminal><opt/><non_terminal where="24.2">attribute-list</non_terminal><terminal>,]</terminal></rhs></grammar_production><grammar_production><name><non_terminal where="24.2">attribute-target-specifier</non_terminal></name> : <rhs><non_terminal where="24.2">attribute-target</non_terminal><terminal>:</terminal></rhs></grammar_production><grammar_production><name><non_terminal where="24.2">attribute-target</non_terminal></name> : <rhs><terminal>field </terminal></rhs><rhs><terminal>event </terminal></rhs><rhs><terminal>method </terminal></rhs><rhs><terminal>param </terminal></rhs><rhs><terminal>property </terminal></rhs><rhs><terminal>return  </terminal></rhs><rhs><terminal>type  </terminal></rhs></grammar_production><grammar_production><name><non_terminal where="24.2">attribute-list</non_terminal></name> : <rhs><non_terminal where="24.2">attribute</non_terminal></rhs><rhs><non_terminal where="24.2">attribute-list</non_terminal><terminal>,</terminal><non_terminal where="24.2">attribute</non_terminal></rhs></grammar_production><grammar_production><name>attribute</name> : <rhs><non_terminal where="24.2">attribute-name</non_terminal><non_terminal where="24.2">attribute-arguments</non_terminal><opt/></rhs></grammar_production><grammar_production><name><non_terminal where="24.2">attribute-name</non_terminal></name> : <rhs><non_terminal where="10.8">type-name</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="24.2">attribute-arguments</non_terminal></name> : <rhs><terminal>(</terminal><non_terminal where="24.2">positional-argument-list</non_terminal><opt/><terminal>)</terminal></rhs><rhs><terminal>(</terminal><non_terminal where="24.2">positional-argument-list</non_terminal><terminal>,</terminal><non_terminal where="24.2">named-argument-list</non_terminal><terminal>)</terminal></rhs><rhs><terminal>(</terminal><non_terminal where="24.2">named-argument-list</non_terminal><terminal>)</terminal></rhs></grammar_production><grammar_production><name><non_terminal where="24.2">positional-argument-list</non_terminal></name> : <rhs><non_terminal where="24.2">positional-argument</non_terminal></rhs><rhs><non_terminal where="24.2">positional-argument-list</non_terminal><terminal>,</terminal><non_terminal where="24.2">positional-argument</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="24.2">positional-argument</non_terminal></name> : <rhs><non_terminal where="24.2">attribute-argument-expression</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="24.2">named-argument-list</non_terminal></name> : <rhs><non_terminal where="24.2">named-argument</non_terminal></rhs><rhs><non_terminal where="24.2">named-argument-list</non_terminal><terminal>,</terminal><non_terminal where="24.2">named-argument</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="24.2">named-argument</non_terminal></name> : <rhs><non_terminal where="9.4.2">identifier</non_terminal><terminal>=</terminal><non_terminal where="24.2">attribute-argument-expression</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="24.2">attribute-argument-expression</non_terminal></name> : <rhs><non_terminal where="14.14">expression</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>An attribute consists of an <non_terminal where="24.2">attribute-name</non_terminal> and an optional list of positional and named arguments. The positional arguments (if any) precede the named arguments. A positional argument consists of an  attribute-argument-expression; a named argument consists of a name, followed by an equal sign, followed by an <non_terminal where="24.2">attribute-argument-expression</non_terminal>, which, together, are constrained by the same rules as simple assignment.) The order of named arguments is not significant. </paragraph>
+  <paragraph>The <non_terminal where="24.2">attribute-name</non_terminal> identifies an attribute class. If the form of <non_terminal where="24.2">attribute-name</non_terminal> is <non_terminal where="10.8">type-name</non_terminal> then this name must refer to an attribute class. Otherwise, a compile-time error occurs. <example>[Example: The example <code_example><![CDATA[
+class Class1 {}  
+[Class1] class Class2 {}  // Error  
+]]></code_example>results in a compile-time error because it attempts to use Class1 as an attribute class when Class1 is not an attribute class. end example]</example> </paragraph>
+  <paragraph>Certain contexts permit the specification of an attribute on more than one target. A program can explicitly specify the target by including an <non_terminal where="24.2">attribute-target-specifier</non_terminal>. When an attribute is placed at the global level, a <non_terminal where="24.2">global-attribute-target-specifier</non_terminal> is required. In all other locations, a reasonable default is applied, but an <non_terminal where="24.2">attribute-target-specifier</non_terminal> can be used to affirm or override the default in certain ambiguous cases (or to just affirm the default in non-ambiguous cases). Thus, typically, <non_terminal where="24.2">attribute-target-specifier</non_terminal>s can be omitted except at the global level. The potentially ambiguous contexts are resolved as follows: <list><list_item> An attribute specified on a delegate declaration can apply either to the delegate being declared or to its return value. In the absence of an <non_terminal where="24.2">attribute-target-specifier</non_terminal>, the attribute applies to the delegate. The presence of the type <non_terminal where="24.2">attribute-target-specifier</non_terminal> indicates that the attribute applies to the delegate; the presence of the return <non_terminal where="24.2">attribute-target-specifier</non_terminal> indicates that the attribute applies to the return value. </list_item><list_item> An attribute specified on a method declaration can apply either to the method being declared or to its return value. In the absence of an <non_terminal where="24.2">attribute-target-specifier</non_terminal>, the attribute applies to the method. The presence of the method <non_terminal where="24.2">attribute-target-specifier</non_terminal> indicates that the attribute applies to the method; the presence of the return <non_terminal where="24.2">attribute-target-specifier</non_terminal> indicates that the attribute applies to the return value. </list_item><list_item> An attribute specified on an operator declaration can apply either to the operator being declared or to its return value of this declaration. In the absence of an <non_terminal where="24.2">attribute-target-specifier</non_terminal>, the attribute applies to the operator. The presence of the type <non_terminal where="24.2">attribute-target-specifier</non_terminal> indicates that the attribute applies to the operator; the presence of the return <non_terminal where="24.2">attribute-target-specifier</non_terminal> indicates that the attribute applies to the return value. </list_item><list_item> An attribute specified on an event declaration that omits event accessors can apply to the event being declared, to the associated field (if the event is not abstract), or to the associated add and remove methods. In the absence of an <non_terminal where="24.2">attribute-target-specifier</non_terminal>, the attribute applies to the event declaration. The presence of the event <non_terminal where="24.2">attribute-target-specifier</non_terminal> indicates that the attribute applies to the event; the presence of the field <non_terminal where="24.2">attribute-target-specifier</non_terminal> indicates that the attribute applies to the field; and the presence of the method <non_terminal where="24.2">attribute-target-specifier</non_terminal> indicates that the attribute applies to the methods. </list_item><list_item> An attribute specified on a get accessor declaration for a property or indexer declaration can apply either to the associated method or to its return value. In the absence of an <non_terminal where="24.2">attribute-target-specifier</non_terminal>, the attribute applies to the method. The presence of the method <non_terminal where="24.2">attribute-target-specifier</non_terminal> indicates that the attribute applies to the method; the presence of the return <non_terminal where="24.2">attribute-target-specifier</non_terminal> indicates that the attribute applies to the return value. </list_item><list_item> An attribute specified on a set accessor for a property or indexer declaration can apply either to the associated method or to its lone implicit parameter. In the absence of an <non_terminal where="24.2">attribute-target-specifier</non_terminal>, the attribute applies to the method. The presence of the method <non_terminal where="24.2">attribute-target-specifier</non_terminal> indicates that the attribute applies to the method; the presence of the param <non_terminal where="24.2">attribute-target-specifier</non_terminal> indicates that the attribute applies to the parameter. </list_item><list_item> An attribute specified on an add or remove accessor declaration for an event declaration can apply either to the associated method or to its lone parameter. In the absence of an <non_terminal where="24.2">attribute-target-specifier</non_terminal>, the attribute applies to the method. The presence of the method <non_terminal where="24.2">attribute-target-specifier</non_terminal> indicates that the attribute applies to the method; the presence of the param <non_terminal where="24.2">attribute-target-specifier</non_terminal> indicates that the attribute applies to the parameter. </list_item></list></paragraph>
+  <paragraph>An implementation may accept other attribute target specifiers, the purpose of which is  implementation-defined. However, an implementation that does not recognize such a target, shall issue a warning. </paragraph>
+  <paragraph>By convention, attribute classes are named with a suffix of Attribute. An <non_terminal where="24.2">attribute-name</non_terminal> of the form  <non_terminal where="10.8">type-name</non_terminal> may either include or omit this suffix. If an attribute class is found both with and without this suffix, an ambiguity is present, and a compile-time error shall be issued. If the <non_terminal where="24.2">attribute-name</non_terminal> is spelled using a verbatim identifier (<hyperlink>9.4.2</hyperlink>), then only an attribute without a suffix is matched, thus enabling such an ambiguity to be resolved. <example>[Example: The example <code_example><![CDATA[
+using System;  
+[AttributeUsage(AttributeTargets.All)]  
+public class X: Attribute  
+{}  
+[AttributeUsage(AttributeTargets.All)]  
+public class XAttribute: Attribute  
+{}  
+[X]      // error: ambiguity  
+class Class1 {}  
+[XAttribute]    // refers to XAttribute  
+class Class2 {}  
+[@X]          // refers to X  
+class Class3 {}  
+[@XAttribute]    // refers to XAttribute  
+class Class4 {}  
+]]></code_example>shows two attribute classes named X and XAttribute. The attribute [X] is ambiguous, since it could refer to either X or XAttribute. Using a verbatim identifier allows the exact intent to be specified in such rare cases. The attribute [XAttribute] is not ambiguous (although it would be if there was an attribute class named XAttributeAttribute!). If the declaration for class X is removed, then both attributes refer to the attribute class named XAttribute, as follows: <code_example><![CDATA[
+using System;  
+[AttributeUsage(AttributeTargets.All)]  
+public class XAttribute: Attribute  
+{}  
+[X]      // refers to XAttribute  
+class Class1 {}  
+[XAttribute]    // refers to XAttribute  
+class Class2 {}  
+[@X]      // error: no attribute named "X"  
+class Class3 {}  
+]]></code_example>end example]</example> </paragraph>
+  <paragraph>It is a compile-time error to use a single-use attribute class more than once on the same entity. <example>[Example: The example <code_example><![CDATA[
+using System;  
+[AttributeUsage(AttributeTargets.Class)]  
+public class HelpStringAttribute: Attribute  
+{  
+   string value;  
+   public HelpStringAttribute(string value) {  
+      this.value = value;  
+   }  
+   public string Value { get {...} }  
+}  
+[HelpString("Description of Class1")]  
+[HelpString("Another description of Class1")]  
+public class Class1 {}  
+]]></code_example>results in a compile-time error because it attempts to use HelpString, which is a single-use attribute class, more than once on the declaration of Class1. end example]</example> </paragraph>
+  <paragraph>An expression E is an <non_terminal where="24.2">attribute-argument-expression</non_terminal> if all of the following statements are true: <list><list_item> The type of E is an attribute parameter type (<hyperlink>24.1.3</hyperlink>). </list_item><list_item> At compile-time, the value of E can be resolved to one of the following: </list_item><list><list_item> A constant value. </list_item><list_item> A System.Type object. </list_item><list_item> A one-dimensional array of <non_terminal where="24.2">attribute-argument-expression</non_terminal>s. </list_item></list></list></paragraph>
+  <paragraph>
+    <example>[Example: For example: <code_example><![CDATA[
+using System;  
+[AttributeUsage(AttributeTargets.Class)]  
+public class MyAttribute: Attribute  
+{  
+   public int P1 {  
+      get {...}  
+      set {...}  
+   }  
+   public Type P2 {  
+      get {...}  
+      set {...}  
+   }  
+   public object P3 {  
+      get {...}  
+      set {...}  
+   }  
+}  
+[My(P1 = 1234, P3 = new int[]{1, 3, 5}, P2 = typeof(float))]  
+class MyClass {}  
+]]></code_example>end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/24.3.1.xml b/mcs/docs/ecma334/24.3.1.xml
new file mode 100644 (file)
index 0000000..b988684
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="24.3.1" title="Compilation of an attribute">
+  <paragraph>The compilation of an attribute with attribute class T, <non_terminal where="24.2">positional-argument-list</non_terminal> P and <non_terminal where="24.2">named-argument-list</non_terminal> N, consists of the following steps: <list><list_item> Follow the compile-time processing steps for compiling an <non_terminal where="14.5.10.1">object-creation-expression</non_terminal> of the form new T(P). These steps either result in a compile-time error, or determine an instance constructor on T that can be invoked at run-time. Call this instance constructor C. </list_item><list_item> If C does not have public accessibility, then a compile-time error occurs. </list_item><list_item> For each <non_terminal where="24.2">named-argument</non_terminal> Arg in N: </list_item><list><list_item> Let Name be the identifier of the <non_terminal where="24.2">named-argument</non_terminal> Arg. </list_item><list_item> Name must identify a non-static read-write public field or property on T. If T has no such field or property, then a compile-time error occurs. </list_item></list><list_item> Keep the following information for run-time instantiation of the attribute: the attribute class T, the instance constructor C on T, the <non_terminal where="24.2">positional-argument-list</non_terminal> P and the <non_terminal where="24.2">named-argument-list</non_terminal> N. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/24.3.2.xml b/mcs/docs/ecma334/24.3.2.xml
new file mode 100644 (file)
index 0000000..ffb0fe5
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="24.3.2" title="Run-time retrieval of an attribute instance">
+  <paragraph>Compilation of an attribute yields an attribute class T, an instance constructor C on T, a  <non_terminal where="24.2">positional-argument-list</non_terminal> P, and a <non_terminal where="24.2">named-argument-list</non_terminal> N. Given this information, an attribute instance can be retrieved at run-time using the following steps: <list><list_item> Follow the run-time processing steps for executing an <non_terminal where="14.5.10.1">object-creation-expression</non_terminal> of the form new T(P), using the instance constructor C as determined at compile-time. These steps either result in an exception, or produce an instance of T. Call this instance O. </list_item><list_item> For each <non_terminal where="24.2">named-argument</non_terminal> Arg in N, in order: </list_item><list><list_item> Let Name be the identifier of the <non_terminal where="24.2">named-argument</non_terminal> Arg. If Name does not identify a non-static public read-write field or property on O, then an exception is thrown. </list_item><list_item> Let Value be the result of evaluating the <non_terminal where="24.2">attribute-argument-expression</non_terminal> of Arg. </list_item><list_item> If Name identifies a field on O, then set this field to the value Value. </list_item><list_item> Otherwise, Name identifies a property on O. Set this property to the value Value. </list_item><list_item> The result is O, an instance of the attribute class T that has been initialized with the  <non_terminal where="24.2">positional-argument-list</non_terminal> P and the <non_terminal where="24.2">named-argument-list</non_terminal> N. </list_item></list></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/24.3.xml b/mcs/docs/ecma334/24.3.xml
new file mode 100644 (file)
index 0000000..fba29ea
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="24.3" title="Attribute instances">
+  <paragraph>An attribute instance is an instance that represents an attribute at run-time. An attribute is defined with an attribute class, positional arguments, and named arguments. An attribute instance is an instance of the attribute class that is initialized with the positional and named arguments. </paragraph>
+  <paragraph>Retrieval of an attribute instance involves both compile-time and run-time processing, as described in the following sections. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/24.4.1.xml b/mcs/docs/ecma334/24.4.1.xml
new file mode 100644 (file)
index 0000000..70ad069
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<clause number="24.4.1" title="The AttributeUsage attribute">
+  <paragraph>The attribute AttributeUsage is used to describe the manner in which the attribute class can be used. </paragraph>
+  <paragraph>A class that is decorated with the AttributeUsage attribute must derive from System.Attribute, either directly or indirectly. Otherwise, a compile-time error occurs. </paragraph>
+  <paragraph>
+    <note>[Note: For an example of using this attribute, see <hyperlink>24.1.1</hyperlink>. end note]</note>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/24.4.2.xml b/mcs/docs/ecma334/24.4.2.xml
new file mode 100644 (file)
index 0000000..1a3004a
--- /dev/null
@@ -0,0 +1,101 @@
+<?xml version="1.0"?>
+<clause number="24.4.2" title="The Conditional attribute">
+  <paragraph>The attribute Conditional enables the definition of conditional methods. The Conditional attribute indicates a condition by testing a conditional compilation symbol. Calls to a conditional method are either included or omitted depending on whether this symbol is defined at the point of the call. If the symbol is defined, the call is included; otherwise, the call is omitted. </paragraph>
+  <paragraph>A conditional method is subject to the following restrictions: <list><list_item> The conditional method must be a method in a <non_terminal where="17.1">class-declaration</non_terminal>. A compile-time error occurs if the Conditional attribute is specified on an interface method. </list_item><list_item> The conditional method must have a return type of <keyword>void</keyword>. </list_item><list_item> The conditional method must not be marked with the override modifier. A conditional method may be marked with the virtual modifier, however. Overrides of such a method are implicitly conditional, and must not be explicitly marked with a Conditional attribute. </list_item><list_item> The conditional method must not be an implementation of an interface method. Otherwise, a  compile-time error occurs. </list_item></list></paragraph>
+  <paragraph>In addition, a compile-time error occurs if a conditional method is used in a <non_terminal where="14.5.10.3">delegate-creation-expression</non_terminal>. </paragraph>
+  <paragraph>
+    <example>[Example: The example <code_example><![CDATA[
+#define DEBUG  
+using System;  
+using System.Diagnostics;  
+class Class1   
+{  
+   [Conditional("DEBUG")]  
+   public static void M() {  
+      Console.WriteLine("Executed Class1.M");  
+   }  
+}  
+class Class2  
+{  
+   public static void Test() {  
+      Class1.M();  
+   }  
+}  
+]]></code_example>declares Class1.M as a conditional method. Class2's Test method calls this method. Since the conditional compilation symbol DEBUG is defined, if Class2.Test is called, it will call M. If the symbol DEBUG had not been defined, then Class2.Test would not call Class1.M. end example]</example>
+  </paragraph>
+  <paragraph>It is important to note that the inclusion or exclusion of a call to a conditional method is controlled by the conditional compilation symbols at the point of the call. <example>[Example: In the example <code_example><![CDATA[
+// Begin class1.cs  
+using System;  
+using System.Diagnostics;  
+class Class1   
+{  
+   [Conditional("DEBUG")]  
+   public static void F() {  
+      Console.WriteLine("Executed Class1.F");  
+   }  
+}  
+// End class1.cs  
+
+// Begin class2.cs  
+#define DEBUG  
+class Class2  
+{  
+   public static void G() {  
+      Class1.F();    // F is called  
+   }  
+}  
+// End class2.cs  
+
+// Begin class3.cs  
+#undef DEBUG  
+class Class3  
+{  
+   public static void H() {  
+      Class1.F();    // F is not called  
+   }  
+}  
+// End class3.cs  
+]]></code_example>the classes Class2 and Class3 each contain calls to the conditional method Class1.F, which is conditional based on whether or not DEBUG is defined. Since this symbol is defined in the context of Class2 but not Class3, the call to F in Class2 is included, while the call to F in Class3 is omitted. end example]</example> </paragraph>
+  <paragraph>The use of conditional methods in an inheritance chain can be confusing. Calls made to a conditional method through base, of the form base.M, are subject to the normal conditional method call rules. </paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+// Begin class1.cs  
+using System;  
+using System.Diagnostics;  
+class Class1   
+{  
+   [Conditional("DEBUG")]  
+   public virtual void M() {  
+      Console.WriteLine("Class1.M executed");  
+   }  
+}  
+// End class1.cs  
+
+// Begin class2.cs  
+using System;  
+class Class2: Class1  
+{  
+   public override void M() {  
+      Console.WriteLine("Class2.M executed");  
+      base.M();       // base.M is not called!  
+   }  
+}  
+// End class2.cs  
+
+// Begin class3.cs  
+#define DEBUG  
+using System;  
+class Class3  
+{  
+   public static void Test() {  
+      Class2 c = new Class2();  
+      c.M();              // M is called  
+   }  
+}  
+// End class3.cs  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>Class2 includes a call to the M defined in its base class. This call is omitted because the base method is conditional based on the presence of the symbol DEBUG, which is undefined. Thus, the method writes to the console &quot;Class2.M executed&quot; only. Judicious use of <non_terminal where="9.5.3">pp-declaration</non_terminal>s can eliminate such problems. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/24.4.3.xml b/mcs/docs/ecma334/24.4.3.xml
new file mode 100644 (file)
index 0000000..311a646
--- /dev/null
@@ -0,0 +1,41 @@
+<?xml version="1.0"?>
+<clause number="24.4.3" title="The Obsolete attribute">
+  <paragraph>The attribute Obsolete is used to mark types and members of types that should no longer be used. <code_example><![CDATA[
+using System;  
+[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct |  
+AttributeTargets.Enum | AttributeTargets.Interface |  
+AttributeTargets.Delegate | AttributeTargets.Method |  
+AttributeTargets.Constructor | AttributeTargets.Property |  
+AttributeTargets.Field | AttributeTargets.Event)]  
+public class ObsoleteAttribute: Attribute  
+{  
+   public ObsoleteAttribute() {...}  
+   public ObsoleteAttribute(string message) {...}  
+   public ObsoleteAttribute(string message, bool error) {...}  
+   public string Message { get {...} }  
+   public bool IsError{ get {...} }  
+}  
+]]></code_example></paragraph>
+  <paragraph>If a program uses a type or member that is decorated with the Obsolete attribute, then the compiler shall issue a warning or error in order to alert the developer, so the offending code can be fixed. Specifically, the compiler shall issue a warning if no error parameter is provided, or if the error parameter is provided and has the value false. The compiler shall issue a compile-time error if the error parameter is specified and has the value true. </paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+[Obsolete("This class is obsolete; use class B instead")]  
+class A  
+{  
+   public void F() {}  
+}  
+class B  
+{  
+   public void F() {}  
+}  
+class Test  
+{  
+   static void Main() {  
+      A a = new A(); // warning  
+      a.F();  
+   }  
+}  
+]]></code_example>the class A is decorated with the Obsolete attribute. Each use of A in Main results in a warning that includes the specified message, &quot;This class is obsolete; use class B instead.&quot; end example]</example>
+    <table_line/>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/24.4.xml b/mcs/docs/ecma334/24.4.xml
new file mode 100644 (file)
index 0000000..7d50999
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="24.4" title="Reserved attributes">
+  <paragraph>A small number of attributes affect the language in some way. These attributes include: <list><list_item> System.AttributeUsageAttribute (<hyperlink>24.4.1</hyperlink>), which is used to describe the ways in which an attribute class can be used. </list_item><list_item> System.ConditionalAttribute (<hyperlink>24.4.2</hyperlink>), which is used to define conditional methods. </list_item><list_item> System.ObsoleteAttribute (<hyperlink>24.4.3</hyperlink>), which is used to mark a member as obsolete. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/24.xml b/mcs/docs/ecma334/24.xml
new file mode 100644 (file)
index 0000000..6db563e
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<clause number="24" title="Attributes">
+  <paragraph>
+    <note>[Note: Much of the C# language enables the programmer to specify declarative information about the entities defined in the program. For example, the accessibility of a method in a class is specified by decorating it with the <non_terminal where="17.5">method-modifier</non_terminal>s public, protected, internal, and private. end note]</note>
+  </paragraph>
+  <paragraph>C# enables programmers to invent new kinds of declarative information, called attributes. Programmers can then attach attributes to various program entities, and retrieve attribute information in a run-time environment. <note>[Note: For instance, a framework might define a HelpAttribute attribute that can be placed on certain program elements (such as classes and methods) to provide a mapping from those program elements to their documentation. end note]</note> </paragraph>
+  <paragraph>Attributes are defined through the declaration of attribute classes (<hyperlink>24.1</hyperlink>), which may have positional and named parameters (<hyperlink>24.1.2</hyperlink>). Attributes are attached to entities in a C# program using attribute specifications (<hyperlink>24.2</hyperlink>), and can be retrieved at run-time as attribute instances (<hyperlink>24.3</hyperlink>). </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/25.1.xml b/mcs/docs/ecma334/25.1.xml
new file mode 100644 (file)
index 0000000..8a82ed2
--- /dev/null
@@ -0,0 +1,56 @@
+<?xml version="1.0"?>
+<clause number="25.1" title="Unsafe contexts">
+  <paragraph>The unsafe features of C# are available only in unsafe contexts. An unsafe context is introduced by including an unsafe modifier in the declaration of a type or member, or by employing an unsafe-statement: <list><list_item> A declaration of a class, struct, interface, or delegate may include an unsafe modifier, in which case the entire textual extent of that type declaration (including the body of the class, struct, or interface) is considered an unsafe context. </list_item><list_item> A declaration of a field, method, property, event, indexer, operator, instance constructor, destructor, or static constructor may include an unsafe modifier, in which case, the entire textual extent of that member declaration is considered an unsafe context. </list_item><list_item> An <non_terminal where="25.1">unsafe-statement</non_terminal> enables the use of an unsafe context within a block. The entire textual extent of the associated block is considered an unsafe context. </list_item></list></paragraph>
+  <paragraph>The associated grammar extensions are shown below. For brevity, ellipses (...) are used to represent productions that appear in preceding chapters. <grammar_production><name><non_terminal where="17.1.1">class-modifier</non_terminal></name> : <rhs><terminal>...</terminal></rhs><rhs><keyword>unsafe</keyword></rhs></grammar_production><grammar_production><name><non_terminal where="18.1.1">struct-modifier</non_terminal></name> : <rhs><terminal>...</terminal></rhs><rhs><keyword>unsafe</keyword></rhs></grammar_production><grammar_production><name><non_terminal where="20.1.1">interface-modifier</non_terminal></name> : <rhs><terminal>...</terminal></rhs><rhs><keyword>unsafe</keyword></rhs></grammar_production><grammar_production><name><non_terminal where="22.1">delegate-modifier</non_terminal></name> : <rhs><terminal>...</terminal></rhs><rhs><keyword>unsafe</keyword></rhs></grammar_production><grammar_production><name><non_terminal where="17.4">field-modifier</non_terminal></name> : <rhs><terminal>...</terminal></rhs><rhs><keyword>unsafe</keyword></rhs></grammar_production><grammar_production><name><non_terminal where="17.5">method-modifier</non_terminal></name> : <rhs><terminal>...</terminal></rhs><rhs><keyword>unsafe</keyword></rhs></grammar_production><grammar_production><name><non_terminal where="17.6">property-modifier</non_terminal></name> : <rhs><terminal>...</terminal></rhs><rhs><keyword>unsafe</keyword></rhs></grammar_production><grammar_production><name><non_terminal where="17.7">event-modifier</non_terminal></name> : <rhs><terminal>...</terminal></rhs><rhs><keyword>unsafe</keyword></rhs></grammar_production><grammar_production><name><non_terminal where="17.8">indexer-modifier</non_terminal></name> : <rhs><terminal>...</terminal></rhs><rhs><keyword>unsafe</keyword></rhs></grammar_production><grammar_production><name><non_terminal where="17.9">operator-modifier</non_terminal></name> : <rhs><terminal>...</terminal></rhs><rhs><keyword>unsafe</keyword></rhs></grammar_production><grammar_production><name><non_terminal where="17.10">constructor-modifier</non_terminal></name> : <rhs><terminal>...</terminal></rhs><rhs><keyword>unsafe</keyword></rhs></grammar_production><grammar_production><name><non_terminal where="17.12">destructor-declaration</non_terminal></name> : <rhs><non_terminal where="24.2">attributes</non_terminal><opt/><keyword>extern</keyword><opt/><keyword>unsafe</keyword><opt/><terminal>~</terminal><non_terminal where="9.4.2">identifier</non_terminal><terminal>(</terminal><terminal>)</terminal><non_terminal where="17.12">destructor-body</non_terminal></rhs><rhs><non_terminal where="24.2">attributes</non_terminal><opt/><keyword>unsafe</keyword><opt/><keyword>extern</keyword><opt/><terminal>~</terminal><non_terminal where="9.4.2">identifier</non_terminal><terminal>(</terminal><terminal>)</terminal><non_terminal where="17.12">destructor-body</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="17.11">static-constructor-declaration</non_terminal></name> : <rhs><non_terminal where="24.2">attributes</non_terminal><opt/><keyword>extern</keyword><opt/><keyword>unsafe</keyword><opt/><keyword>static</keyword><non_terminal where="9.4.2">identifier</non_terminal><terminal>(</terminal><terminal>)</terminal><non_terminal where="17.11">static-constructor-body</non_terminal></rhs><rhs><non_terminal where="24.2">attributes</non_terminal><opt/><keyword>unsafe</keyword><opt/><keyword>extern</keyword><opt/><keyword>static</keyword><non_terminal where="9.4.2">identifier</non_terminal><terminal>(</terminal><terminal>)</terminal><non_terminal where="17.11">static-constructor-body</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="15">embedded-statement</non_terminal></name> : <rhs><terminal>...</terminal></rhs><rhs><non_terminal where="25.1">unsafe-statement</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="25.1">unsafe-statement</non_terminal></name> : <rhs><keyword>unsafe</keyword><non_terminal where="15.2">block</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+public unsafe struct Node  
+{  
+   public int Value;  
+   public Node* Left;  
+   public Node* Right;  
+}  
+]]></code_example>the unsafe modifier specified in the struct declaration causes the entire textual extent of the struct declaration to become an unsafe context. Thus, it is possible to declare the Left and Right fields to be of a pointer type. The example above could also be written <code_example><![CDATA[
+public struct Node  
+{  
+   public int Value;  
+   public unsafe Node* Left;  
+   public unsafe Node* Right;  
+}  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>Here, the unsafe modifiers in the field declarations cause those declarations to be considered unsafe contexts. end example]</example>
+  </paragraph>
+  <paragraph>Other than establishing an unsafe context, thus permitting the use of pointer types, the unsafe modifier has no effect on a type or a member. <example>[Example: In the example <code_example><![CDATA[
+public class A  
+{  
+   public unsafe virtual void F() {  
+      char* p;  
+      ...  
+   }  
+}  
+public class B: A  
+{  
+   public override void F() {  
+      base.F();  
+      ...  
+   }  
+}  
+]]></code_example>the unsafe modifier on the F method in A simply causes the textual extent of F to become an unsafe context in which the unsafe features of the language can be used. In the override of F in B, there is no need to re-specify the unsafe modifier-unless, of course, the F method in B itself needs access to unsafe features. </example></paragraph>
+  <paragraph>
+    <example>The situation is slightly different when a pointer type is part of the method's signature <code_example><![CDATA[
+public unsafe class A  
+{  
+   public virtual void F(char* p) {...}  
+}  
+public class B: A  
+{  
+   public unsafe override void F(char* p) {...}  
+}  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>Here, because F's signature includes a pointer type, it can only be written in an unsafe context. However, the unsafe context can be introduced by either making the entire class unsafe, as is the case in A, or by including an unsafe modifier in the method declaration, as is the case in B. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/25.2.xml b/mcs/docs/ecma334/25.2.xml
new file mode 100644 (file)
index 0000000..2a8e69f
--- /dev/null
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<clause number="25.2" title="Pointer types">
+  <paragraph>In an unsafe context, a type (<hyperlink>11</hyperlink>) may be a <non_terminal where="25.2">pointer-type</non_terminal> as well as a <non_terminal where="11.1">value-type</non_terminal> or a <non_terminal where="11.2">reference-type</non_terminal>. <grammar_production><name>type</name> : <rhs><non_terminal where="11.1">value-type</non_terminal></rhs><rhs><non_terminal where="11.2">reference-type</non_terminal></rhs></grammar_production><non_terminal where="25.2">pointer-type</non_terminal> A <non_terminal where="25.2">pointer-type</non_terminal> is written as an <non_terminal where="25.2">unmanaged-type</non_terminal> or the keyword <keyword>void</keyword>, followed by a * token: <grammar_production><name><non_terminal where="25.2">pointer-type</non_terminal></name> : <rhs><non_terminal where="25.2">unmanaged-type</non_terminal><terminal>*</terminal></rhs><rhs><keyword>void</keyword><terminal>*</terminal></rhs></grammar_production><grammar_production><name><non_terminal where="25.2">unmanaged-type</non_terminal></name> : <rhs><non_terminal where="11">type</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>The type specified before the * in a pointer type is called the referent type of the pointer type. It represents the type of the variable to which a value of the pointer type points. </paragraph>
+  <paragraph>Unlike references (values of reference types), pointers are not tracked by the garbage collector-the garbage collector has no knowledge of pointers and the data to which they point. For this reason a pointer is not permitted to point to a reference or to a struct that contains references, and the referent type of a pointer must be an <non_terminal where="25.2">unmanaged-type</non_terminal>. </paragraph>
+  <paragraph>An <non_terminal where="25.2">unmanaged-type</non_terminal> is any type that isn't a <non_terminal where="11.2">reference-type</non_terminal> and doesn't contain <non_terminal where="11.2">reference-type</non_terminal> fields at any level of nesting. In other words, an <non_terminal where="25.2">unmanaged-type</non_terminal> is one of the following: <list><list_item><keyword>sbyte</keyword>, <keyword>byte</keyword>, <keyword>short</keyword>, <keyword>ushort</keyword>, <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>long</keyword>, <keyword>ulong</keyword>, <keyword>char</keyword>, <keyword>float</keyword>, <keyword>double</keyword>, <keyword>decimal</keyword>, or <keyword>bool</keyword>. </list_item><list_item> Any <non_terminal where="11.1">enum-type</non_terminal>. </list_item><list_item> Any <non_terminal where="25.2">pointer-type</non_terminal>. </list_item><list_item> Any user-defined <non_terminal where="11.1">struct-type</non_terminal> that contains fields of <non_terminal where="25.2">unmanaged-type</non_terminal>s only. </list_item></list></paragraph>
+  <paragraph>The intuitive rule for mixing of pointers and references is that referents of references (objects) are permitted to contain pointers, but referents of pointers are not permitted to contain references. </paragraph>
+  <paragraph>
+    <example>[Example: Some examples of pointer types are given in the table below: <table_line>Example Description </table_line>
+<table_line>byte* Pointer to <keyword>byte</keyword> </table_line>
+<table_line>char* Pointer to <keyword>char</keyword> </table_line>
+<table_line>int** Pointer to pointer to <keyword>int</keyword> </table_line>
+<table_line>int*[] Single-dimensional array of pointers to <keyword>int</keyword> </table_line>
+<table_line>void* Pointer to unknown type </table_line>
+end example]</example>
+  </paragraph>
+  <paragraph>For a given implementation, all pointer types must have the same size and representation. </paragraph>
+  <paragraph>
+    <note>[Note: Unlike C and C++, when multiple pointers are declared in the same declaration, in C# the * is written along with the underlying type only, not as a prefix punctuator on each pointer name. For example: <code_example><![CDATA[
+int* pi, pj;  // NOT as int *pi, *pj;  
+]]></code_example>end note]</note>
+  </paragraph>
+  <paragraph>The value of a pointer having type T* represents the address of a variable of type T. The pointer indirection operator * (<hyperlink>25.5.1</hyperlink>) may be used to access this variable. For example, given a variable P of type int*, the expression *P denotes the <keyword>int</keyword> variable found at the address contained in P. </paragraph>
+  <paragraph>Like an object reference, a pointer may be null. Applying the indirection operator to a null pointer results in implementation-defined behavior. A pointer with value null is represented by all-bits-zero. </paragraph>
+  <paragraph>The void* type represents a pointer to an unknown type. Because the referent type is unknown, the indirection operator cannot be applied to a pointer of type void*, nor can any arithmetic be performed on such a pointer. However, a pointer of type void* can be cast to any other pointer type (and vice versa). </paragraph>
+  <paragraph>Pointer types are a separate category of types. Unlike reference types and value types, pointer types do not inherit from object and no conversions exist between pointer types and object. In particular, boxing and unboxing (<hyperlink>11.3</hyperlink>) are not supported for pointers. However, conversions are permitted between different pointer types and between pointer types and the integral types. This is described in <hyperlink>25.4</hyperlink>. </paragraph>
+  <paragraph>A <non_terminal where="25.2">pointer-type</non_terminal> may be used as the type of a volatile field (<hyperlink>17.4.3</hyperlink>). </paragraph>
+  <paragraph>
+    <note>[Note: Although pointers can be passed as ref or out parameters, doing so can cause undefined behavior, since the pointer may well be set to point to a local variable which no longer exists when the called method returns, or the fixed object to which it used to point, is no longer fixed. For example: <code_example><![CDATA[
+using System;  
+class Test  
+{  
+   static int value = 20;  
+   
+   unsafe static void F(out int* pi1, ref int* pi2) {  
+      int i = 10;  
+      pi1 = &i;  
+      
+      fixed (int* pj = &value) {  
+         // ...  
+         pi2 = pj;  
+      }  
+   }  
+   
+   static void Main() {  
+      int i = 10;  
+      unsafe {  
+         int* px1;  
+         int* px2 = &i;  
+         
+         F(out px1, ref px2);  
+         Console.WriteLine("*px1 = {0}, *px2 = {1}",  
+         *px1, *px2);  // undefined behavior  
+      }  
+   }  
+}  
+]]></code_example>end note]</note>
+  </paragraph>
+  <paragraph>A method can return a value of some type, and that type can be a pointer. <example>[Example: For example, when given a pointer to a contiguous sequence of ints, that sequence's element count, and some other <keyword>int</keyword> value, the following method returns the address of that value in that sequence, if a match occurs; otherwise it returns null: <code_example><![CDATA[
+unsafe static int* Find(int* pi, int size, int value) {  
+   for (int i = 0; i < size; ++i) {  
+      if (*pi == value) {  
+         return pi;  
+      }  
+      ++pi;  
+   }  
+   return null;  
+}  
+]]></code_example>end example]</example> </paragraph>
+  <paragraph>In an unsafe context, several constructs are available for operating on pointers: <list><list_item> The * operator may be used to perform pointer indirection (<hyperlink>25.5.1</hyperlink>). </list_item><list_item> The -&gt; operator may be used to access a member of a struct through a pointer (<hyperlink>25.5.2</hyperlink>). </list_item><list_item> The [] operator may be used to index a pointer (<hyperlink>25.5.3</hyperlink>). </list_item><list_item> The &amp; operator may be used to obtain the address of a variable (<hyperlink>25.5.4</hyperlink>). </list_item><list_item> The ++ and  --operators may be used to increment and decrement pointers (<hyperlink>25.5.5</hyperlink>). </list_item><list_item> The + and  -operators may be used to perform pointer arithmetic (<hyperlink>25.5.6</hyperlink>). </list_item><list_item> The ==, !=, &lt;, &gt;, &lt;=, and =&gt; operators may be used to compare pointers (<hyperlink>25.5.7</hyperlink>). </list_item><list_item> The stackalloc operator may be used to allocate memory from the call stack (<hyperlink>25.7</hyperlink>). </list_item><list_item> The fixed statement may be used to temporarily fix a variable so its address can be obtained (<hyperlink>25.6</hyperlink>). </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/25.3.xml b/mcs/docs/ecma334/25.3.xml
new file mode 100644 (file)
index 0000000..63ce523
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<clause number="25.3" title="Fixed and moveable variables">
+  <paragraph>The address-of operator (<hyperlink>25.5.4</hyperlink>) and the fixed statement (<hyperlink>25.6</hyperlink>) divide variables into two categories: Fixed variables and moveable variables. </paragraph>
+  <paragraph>Fixed variables reside in storage locations that are unaffected by operation of the garbage collector. </paragraph>
+  <paragraph>(Examples of fixed variables include local variables, value parameters, and variables created by dereferencing pointers.) On the other hand, moveable variables reside in storage locations that are subject to relocation or disposal by the garbage collector. (Examples of moveable variables include fields in objects and elements of arrays.) </paragraph>
+  <paragraph>The &amp; operator (<hyperlink>25.5.4</hyperlink>) permits the address of a fixed variable to be obtained without restrictions. However, because a moveable variable is subject to relocation or disposal by the garbage collector, the address of a moveable variable can only be obtained using a fixed statement (<hyperlink>25.6</hyperlink>), and that address remains valid only for the duration of that fixed statement. </paragraph>
+  <paragraph>In precise terms, a fixed variable is one of the following: <list><list_item> A variable resulting from a <non_terminal where="14.5.2">simple-name</non_terminal> (<hyperlink>14.5.2</hyperlink>) that refers to a local variable or a value parameter. </list_item><list_item> A variable resulting from a <non_terminal where="14.5.4">member-access</non_terminal> (<hyperlink>14.5.4</hyperlink>) of the form V.I, where V is a fixed variable of a <non_terminal where="11.1">struct-type</non_terminal>. </list_item><list_item> A variable resulting from a <non_terminal where="25.5.1">pointer-indirection-expression</non_terminal> (<hyperlink>25.5.1</hyperlink>) of the form *P, a  <non_terminal where="25.5.2">pointer-member-access</non_terminal> (<hyperlink>25.5.2</hyperlink>) of the form P-&gt;I, or a <non_terminal where="25.5.3">pointer-element-access</non_terminal> (<hyperlink>25.5.3</hyperlink>) of the form P[E]. </list_item></list></paragraph>
+  <paragraph>All other variables are classified as moveable variables. </paragraph>
+  <paragraph>Note that a static field is classified as a moveable variable. Also note that a ref or out parameter is classified as a moveable variable, even if the argument given for the parameter is a fixed variable. Finally, note that a variable produced by dereferencing a pointer is always classified as a fixed variable. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/25.4.xml b/mcs/docs/ecma334/25.4.xml
new file mode 100644 (file)
index 0000000..0b1c887
--- /dev/null
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+<clause number="25.4" title="Pointer conversions">
+  <paragraph>In an unsafe context, the set of available implicit conversions (<hyperlink>13.1</hyperlink>) is extended to include the following implicit pointer conversions: <list><list_item> From any <non_terminal where="25.2">pointer-type</non_terminal> to the type void*. </list_item><list_item> From the null type to any <non_terminal where="25.2">pointer-type</non_terminal>. </list_item></list></paragraph>
+  <paragraph>Additionally, in an unsafe context, the set of available explicit conversions (<hyperlink>13.2</hyperlink>) is extended to include the following explicit pointer conversions: <list><list_item> From any <non_terminal where="25.2">pointer-type</non_terminal> to any other <non_terminal where="25.2">pointer-type</non_terminal>. </list_item><list_item> From <keyword>sbyte</keyword>, <keyword>byte</keyword>, <keyword>short</keyword>, <keyword>ushort</keyword>, <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>long</keyword>, or <keyword>ulong</keyword> to any <non_terminal where="25.2">pointer-type</non_terminal>. </list_item><list_item> From any <non_terminal where="25.2">pointer-type</non_terminal> to <keyword>sbyte</keyword>, <keyword>byte</keyword>, <keyword>short</keyword>, <keyword>ushort</keyword>, <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>long</keyword>, or <keyword>ulong</keyword>. </list_item></list></paragraph>
+  <paragraph>Finally, in an unsafe context, the set of standard implicit conversions (<hyperlink>13.3.1</hyperlink>) includes the following pointer conversion: <list><list_item> From any <non_terminal where="25.2">pointer-type</non_terminal> to the type void*. </list_item></list></paragraph>
+  <paragraph>Conversions between two pointer types never change the actual pointer value. In other words, a conversion from one pointer type to another has no effect on the underlying address given by the pointer. </paragraph>
+  <paragraph>When one pointer type is converted to another, if the resulting pointer is not correctly aligned for the pointed-to type, the behavior is undefined if the result is dereferenced. In general, the concept &quot;correctly aligned&quot; is transitive: if a pointer to type A is correctly aligned for a pointer to type B, which, in turn, is correctly aligned for a pointer to type C, then a pointer to type A is correctly aligned for a pointer to type C. </paragraph>
+  <paragraph>
+    <example>[Example: Consider the following case in which a variable having one type is accessed via a pointer to a different type: <code_example><![CDATA[
+char c = 'A';  
+char* pc = &c;  
+void* pv = pc;  
+int* pi = (int*)pv;  
+int i = *pi;    // undefined  
+*pi = 123456;    // undefined  
+]]></code_example>end example]</example>
+  </paragraph>
+  <paragraph>When a pointer type is converted to a pointer to <keyword>byte</keyword>, the result points to the lowest addressed <keyword>byte</keyword> of the variable. Successive increments of the result, up to the size of the variable, yield pointers to the remaining bytes of that variable. <example>[Example: For example, the following method displays each of the eight bytes in a <keyword>double</keyword> as a hexadecimal value: <code_example><![CDATA[
+using System;  
+class Test  
+{  
+   static void Main() {  
+      double d = 123.456e23;  
+      unsafe {  
+         byte* pb = (byte*)&d;  
+         
+         for (int i = 0; i < sizeof(double); ++i)  
+         Console.Write(" {0,2:X}", (uint)(*pb++));  
+         Console.WriteLine();  
+      }  
+   }  
+}  
+]]></code_example></example></paragraph>
+  <paragraph>
+    <example>Of course, the output produced depends on endianness. end example]</example>
+  </paragraph>
+  <paragraph>Mappings between pointers and integers are implementation-defined. <note>[Note: However, on  32-and 64-bit CPU architectures with a linear address space, conversions of pointers to or from integral types typically behave exactly like conversions of <keyword>uint</keyword> or <keyword>ulong</keyword> values, respectively, to or from those integral types. end note]</note> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/25.5.1.xml b/mcs/docs/ecma334/25.5.1.xml
new file mode 100644 (file)
index 0000000..80ffe5f
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<clause number="25.5.1" title="Pointer indirection">
+  <paragraph>A <non_terminal where="25.5.1">pointer-indirection-expression</non_terminal> consists of an asterisk (*) followed by a <non_terminal where="14.6">unary-expression</non_terminal>. <grammar_production><name><non_terminal where="25.5.1">pointer-indirection-expression</non_terminal></name> : <rhs><terminal>*</terminal><non_terminal where="14.6">unary-expression</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>The unary * operator denotes pointer indirection and is used to obtain the variable to which a pointer points. </paragraph>
+  <paragraph>The result of evaluating *P, where P is an expression of a pointer type T*, is a variable of type T. It is a compile-time error to apply the unary * operator to an expression of type void* or to an expression that isn't of a pointer type. </paragraph>
+  <paragraph>The effect of applying the unary * operator to a null pointer is implementation-defined. In particular, there is no guarantee that this operation throws a System.NullReferenceException. </paragraph>
+  <paragraph>If an invalid value has been assigned to the pointer, the behavior of the unary * operator is undefined. <note>[Note: Among the invalid values for dereferencing a pointer by the unary * operator are an address inappropriately aligned for the type pointed to (see example in <hyperlink>25.4</hyperlink>), and the address of a variable after the end of its lifetime. end note]</note> </paragraph>
+  <paragraph>For purposes of definite assignment analysis, a variable produced by evaluating an expression of the form *P is considered initially assigned (<hyperlink>12.3.1</hyperlink>). </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/25.5.2.xml b/mcs/docs/ecma334/25.5.2.xml
new file mode 100644 (file)
index 0000000..2b7890d
--- /dev/null
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+<clause number="25.5.2" title="Pointer member access">
+  <paragraph>A <non_terminal where="25.5.2">pointer-member-access</non_terminal> consists of a <non_terminal where="14.5">primary-expression</non_terminal>, followed by a &quot;-&gt;&quot; token, followed by an identifier. <grammar_production><name><non_terminal where="25.5.2">pointer-member-access</non_terminal></name> : <rhs><non_terminal where="14.5">primary-expression</non_terminal><terminal>-&gt;</terminal><non_terminal where="9.4.2">identifier</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>In a pointer member access of the form P-&gt;I, P must be an expression of a pointer type other than void*, and I must denote an accessible member of the type to which P points. </paragraph>
+  <paragraph>A pointer member access of the form P-&gt;I is evaluated exactly as (*P).I. For a description of the pointer indirection operator (*), see <hyperlink>25.5.1</hyperlink>. For a description of the member access operator (.), see <hyperlink>14.5.4</hyperlink>. </paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+struct Point  
+{  
+   public int x;  
+   public int y;  
+   public override string ToString() {  
+      return "(" + x + "," + y + ")";  
+   }  
+}  
+using System;  
+class Test  
+{  
+   static void Main() {  
+      Point point;  
+      unsafe {  
+         Point* p = &point;  
+         p->x = 10;  
+         p->y = 20;  
+         Console.WriteLine(p->ToString());  
+      }  
+   }  
+}  
+]]></code_example>the -&gt; operator is used to access fields and invoke a method of a struct through a pointer. Because the operation P-&gt;I is precisely equivalent to (*P).I, the Main method could equally well have been written: <code_example><![CDATA[
+using System;  
+class Test  
+{  
+   static void Main() {  
+      Point point;  
+      unsafe {  
+         Point* p = &point;  
+         (*p).x = 10;  
+         (*p).y = 20;  
+         Console.WriteLine((*p).ToString());  
+      }  
+   }  
+}  
+]]></code_example>end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/25.5.3.xml b/mcs/docs/ecma334/25.5.3.xml
new file mode 100644 (file)
index 0000000..7cbd269
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0"?>
+<clause number="25.5.3" title="Pointer element access">
+  <paragraph>A <non_terminal where="25.5.3">pointer-element-access</non_terminal> consists of a <non_terminal where="14.5">primary-no-array-creation-expression</non_terminal> followed by an expression enclosed in &quot;[&quot; and &quot;]&quot;. <grammar_production><name><non_terminal where="25.5.3">pointer-element-access</non_terminal></name> : <rhs><non_terminal where="14.5">primary-no-array-creation-expression</non_terminal><terminal>[</terminal><non_terminal where="14.14">expression</non_terminal><terminal>]</terminal></rhs></grammar_production></paragraph>
+  <paragraph>In a pointer element access of the form P[E], P must be an expression of a pointer type other than void*, and E must be an expression of a type that can be implicitly converted to <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>long</keyword>, or <keyword>ulong</keyword>. </paragraph>
+  <paragraph>A pointer element access of the form P[E] is evaluated exactly as *(P + E). For a description of the pointer indirection operator (*), see <hyperlink>25.5.1</hyperlink>. For a description of the pointer addition operator (+), see <hyperlink>25.5.6</hyperlink>. </paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+class Test  
+{  
+   static void Main() {  
+      unsafe {  
+         char* p = stackalloc char[256];  
+         for (int i = 0; i < 256; i++) p[i] = (char)i;  
+      }  
+   }  
+}  
+]]></code_example>a pointer element access is used to initialize the character buffer in a for loop. Because the operation P[E] is precisely equivalent to *(P + E), the example could equally well have been written: <code_example><![CDATA[
+class Test  
+{  
+   static void Main() {  
+      unsafe {  
+         char* p = stackalloc char[256];  
+         for (int i = 0; i < 256; i++) *(p + i) = (char)i;  
+      }  
+   }  
+}  
+]]></code_example>end example]</example>
+  </paragraph>
+  <paragraph>The pointer element access operator does not check for out-of-bounds errors and the behavior when accessing an out-of-bounds element is undefined. <note>[Note: This is the same as C and C++. end note]</note> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/25.5.4.xml b/mcs/docs/ecma334/25.5.4.xml
new file mode 100644 (file)
index 0000000..faa0bd4
--- /dev/null
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<clause number="25.5.4" title="The address-of operator">
+  <paragraph>An <non_terminal where="25.5.4">addressof-expression</non_terminal> consists of an ampersand (&amp;) followed by a <non_terminal where="14.6">unary-expression</non_terminal>. <grammar_production><name><non_terminal where="25.5.4">addressof-expression</non_terminal></name> : <rhs><terminal>&amp;</terminal><non_terminal where="14.6">unary-expression</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>Given an expression E which is of a type T and is classified as a fixed variable (<hyperlink>25.3</hyperlink>), the construct &amp;E computes the address of the variable given by E. The type of the result is T* and is classified as a value. A compile-time error occurs if E is not classified as a variable, if E is classified as a volatile field (<hyperlink>17.4.3</hyperlink>), or if E denotes a moveable variable. In the last case, a fixed statement (<hyperlink>25.6</hyperlink>) can be used to temporarily &quot;fix&quot; the variable before obtaining its address. </paragraph>
+  <paragraph>The &amp; operator does not require its argument to be definitely assigned, but following an &amp; operation, the variable to which the operator is applied is considered definitely assigned in the execution path in which the operation occurs. It is the responsibility of the programmer to ensure that correct initialization of the variable actually does take place in this situation. </paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+using System;  
+class Test  
+{  
+   static void Main() {  
+      int i;  
+      unsafe {  
+         int* p = &i;  
+         *p = 123;  
+      }  
+      Console.WriteLine(i);  
+   }  
+}  
+]]></code_example>i is considered definitely assigned following the &amp;i operation used to initialize p. The assignment to *p in effect initializes i, but the inclusion of this initialization is the responsibility of the programmer, and no compile-time error would occur if the assignment was removed. end example]</example>
+  </paragraph>
+  <paragraph>
+    <note>[Note: The rules of definite assignment for the &amp; operator exist such that redundant initialization of local variables can be avoided. For example, many external APIs take a pointer to a structure which is filled in by the API. Calls to such APIs typically pass the address of a local struct variable, and without the rule, redundant initialization of the struct variable would be required. end note]</note>
+  </paragraph>
+  <paragraph>
+    <note>[Note: As stated in <hyperlink>14.5.4</hyperlink>, outside an instance constructor or static constructor for a struct or class that defines a readonly field, that field is considered a value, not a variable. As such, its address cannot be taken. </note>
+  </paragraph>
+  <paragraph>
+    <note>Similarly, the address of a constant cannot be taken. end note]</note>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/25.5.5.xml b/mcs/docs/ecma334/25.5.5.xml
new file mode 100644 (file)
index 0000000..5599b3c
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<clause number="25.5.5" title="Pointer increment and decrement">
+  <paragraph>In an unsafe context, the ++ and  --operators (<hyperlink>14.5.9</hyperlink> and <hyperlink>14.6.5</hyperlink>) can be applied to pointer variables of all types except void*. Thus, for every pointer type T*, the following operators are implicitly defined: <code_example><![CDATA[
+T* operator ++(T* x);  
+T* operator --(T* x);  
+]]></code_example></paragraph>
+  <paragraph>The operators produce the same results as x+1 and x-1, respectively (<hyperlink>25.5.6</hyperlink>). In other words, for a pointer variable of type T*, the ++ operator adds sizeof(T) to the address contained in the variable, and the  --operator subtracts sizeof(T) from the address contained in the variable. </paragraph>
+  <paragraph>If a pointer increment or decrement operation overflows the domain of the pointer type, the result is implementation-defined, but no exceptions are produced. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/25.5.6.xml b/mcs/docs/ecma334/25.5.6.xml
new file mode 100644 (file)
index 0000000..a86fcd1
--- /dev/null
@@ -0,0 +1,43 @@
+<?xml version="1.0"?>
+<clause number="25.5.6" title="Pointer arithmetic">
+  <paragraph>In an unsafe context, the + operator (<hyperlink>14.7.4</hyperlink>) and  -operator (<hyperlink>14.7.5</hyperlink>) can be applied to values of all pointer types except void*. Thus, for every pointer type T*, the following operators are implicitly defined: <code_example><![CDATA[
+T* operator +(T* x, int y);  
+T* operator +(T* x, uint y);  
+T* operator +(T* x, long y);  
+T* operator +(T* x, ulong y);  
+T* operator +(int x, T* y);  
+T* operator +(uint x, T* y);  
+T* operator +(long x, T* y);  
+T* operator +(ulong x, T* y);  
+T* operator -(T* x, int y);  
+T* operator -(T* x, uint y);  
+T* operator -(T* x, long y);  
+T* operator -(T* x, ulong y);  
+long operator -(T* x, T* y);  
+]]></code_example></paragraph>
+  <paragraph>Given an expression P of a pointer type T* and an expression N of type <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>long</keyword>, or <keyword>ulong</keyword>, the expressions P + N and N + P compute the pointer value of type T* that results from adding N * sizeof(T) to the address given by P. Likewise, the expression P  -N computes the pointer value of type T* that results from subtracting N * sizeof(T) from the address given by P. </paragraph>
+  <paragraph>Given two expressions, P and Q, of a pointer type T*, the expression P  -Q computes the difference between the addresses given by P and Q and then divides that difference by sizeof(T). The type of the result is always <keyword>long</keyword>. In effect, P  -Q is computed as ((<keyword>long</keyword>)(P)  -(<keyword>long</keyword>)(Q)) / sizeof(T). </paragraph>
+  <paragraph>
+    <example>[Example: For example: <code_example><![CDATA[
+using System;  
+class Test  
+{  
+   static void Main() {  
+      unsafe {  
+         int* values = stackalloc int[20];  
+         
+         int* p = &values[1];  
+         int* q = &values[15];  
+         
+         Console.WriteLine("p - q = {0}", p - q);  
+         Console.WriteLine("q - p = {0}", q - p);  
+      }  
+   }  
+}  
+]]></code_example>which produces the output: <code_example><![CDATA[
+p - q = -14  
+q - p = 14  
+]]></code_example>end example]</example>
+  </paragraph>
+  <paragraph>If a pointer arithmetic operation overflows the domain of the pointer type, the result is truncated in an implementation-defined fashion, but no exceptions are produced. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/25.5.7.xml b/mcs/docs/ecma334/25.5.7.xml
new file mode 100644 (file)
index 0000000..c6703e9
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<clause number="25.5.7" title="Pointer comparison">
+  <paragraph>In an unsafe context, the ==, !=, &lt;, &gt;, &lt;=, and =&gt; operators (<hyperlink>14.9</hyperlink>) can be applied to values of all pointer types. The pointer comparison operators are: <code_example><![CDATA[
+bool operator ==(void* x, void* y);  
+bool operator !=(void* x, void* y);  
+bool operator <(void* x, void* y);  
+bool operator >(void* x, void* y);  
+bool operator <=(void* x, void* y);  
+bool operator >=(void* x, void* y);  
+]]></code_example></paragraph>
+  <paragraph>Because an implicit conversion exists from any pointer type to the void* type, operands of any pointer type can be compared using these operators. The comparison operators compare the addresses given by the two operands as if they were unsigned integers. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/25.5.8.xml b/mcs/docs/ecma334/25.5.8.xml
new file mode 100644 (file)
index 0000000..242bda3
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<clause number="25.5.8" title="The sizeof operator">
+  <paragraph>The sizeof operator returns the number of bytes occupied by a variable of a given type. The type specified as an operand to sizeof must be an <non_terminal where="25.2">unmanaged-type</non_terminal> (<hyperlink>25.2</hyperlink>). <grammar_production><name><non_terminal where="25.5.8">sizeof-expression</non_terminal></name> : <rhs><keyword>sizeof</keyword><terminal>(</terminal><non_terminal where="25.2">unmanaged-type</non_terminal><terminal>)</terminal></rhs></grammar_production></paragraph>
+  <paragraph>The result of the sizeof operator is a value of type <keyword>int</keyword>. For certain predefined types, the sizeof operator yields a constant value as shown in the table below. <table_line>Expression Result </table_line>
+<table_line>sizeof(<keyword>sbyte</keyword>) 1 </table_line>
+<table_line>sizeof(<keyword>byte</keyword>) 1 </table_line>
+<table_line>sizeof(<keyword>short</keyword>) 2 </table_line>
+<table_line>sizeof(<keyword>ushort</keyword>) 2 </table_line>
+<table_line>sizeof(<keyword>int</keyword>) 4 </table_line>
+<table_line>sizeof(<keyword>uint</keyword>) 4 </table_line>
+<table_line>sizeof(<keyword>long</keyword>) 8 </table_line>
+<table_line>sizeof(<keyword>ulong</keyword>) 8 </table_line>
+<table_line>sizeof(<keyword>char</keyword>) 2 </table_line>
+<table_line>sizeof(<keyword>float</keyword>) 4 </table_line>
+<table_line>sizeof(<keyword>double</keyword>) 8 </table_line>
+<table_line>sizeof(<keyword>bool</keyword>) 1 </table_line>
+</paragraph>
+  <paragraph>For all other types, the result of the sizeof operator is implementation-defined and is classified as a value, not a constant. </paragraph>
+  <paragraph>The order in which members are packed into a struct is unspecified. </paragraph>
+  <paragraph>For alignment purposes, there may be unnamed padding at the beginning of a struct, within a struct, and at the end of the struct. The contents of the bits used as padding are indeterminate. </paragraph>
+  <paragraph>When applied to an operand that has struct type, the result is the total number of bytes in a variable of that type, including any padding. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/25.5.xml b/mcs/docs/ecma334/25.5.xml
new file mode 100644 (file)
index 0000000..d2cc0c5
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="25.5" title="Pointers in expressions">
+  <paragraph>In an unsafe context, an expression may yield a result of a pointer type, but outside an unsafe context it is a compile-time error for an expression to be of a pointer type. In precise terms, outside an unsafe context a compile-time error occurs if any <non_terminal where="14.5.2">simple-name</non_terminal> (<hyperlink>14.5.2</hyperlink>), <non_terminal where="14.5.4">member-access</non_terminal> (<hyperlink>14.5.4</hyperlink>), <non_terminal where="14.5.5">invocation-expression</non_terminal> (<hyperlink>14.5.5</hyperlink>), or <non_terminal where="14.5.6">element-access</non_terminal> (<hyperlink>14.5.6</hyperlink>) is of a pointer type. </paragraph>
+  <paragraph>In an unsafe context, the <non_terminal where="14.5">primary-no-array-creation-expression</non_terminal> (<hyperlink>14.5</hyperlink>) and <non_terminal where="14.6">unary-expression</non_terminal> (<hyperlink>14.6</hyperlink>) productions permit the following additional constructs: <grammar_production><name><non_terminal where="14.5">primary-no-array-creation-expression</non_terminal></name> : <rhs><terminal>...</terminal></rhs><rhs><non_terminal where="25.5.2">pointer-member-access</non_terminal></rhs><rhs><non_terminal where="25.5.3">pointer-element-access</non_terminal></rhs><rhs><non_terminal where="25.5.8">sizeof-expression</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="14.6">unary-expression</non_terminal></name> : <rhs><terminal>...</terminal></rhs><rhs><non_terminal where="25.5.1">pointer-indirection-expression</non_terminal></rhs><rhs><non_terminal where="25.5.4">addressof-expression</non_terminal></rhs><rhs>These constructs are described in the following sections. </rhs><rhs><terminal>[Note:</terminal><terminal>The</terminal><terminal>precedence</terminal><terminal>and</terminal><terminal>associativity</terminal><terminal>of</terminal><terminal>the</terminal><keyword>unsafe</keyword><terminal>operators</terminal><keyword>is</keyword><terminal>implied</terminal><terminal>by</terminal><terminal>the</terminal><terminal>grammar.</terminal><terminal>end</terminal><terminal>note]</terminal></rhs></grammar_production></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/25.6.xml b/mcs/docs/ecma334/25.6.xml
new file mode 100644 (file)
index 0000000..f710458
--- /dev/null
@@ -0,0 +1,103 @@
+<?xml version="1.0"?>
+<clause number="25.6" title="The fixed statement">
+  <paragraph>In an unsafe context, the <non_terminal where="15">embedded-statement</non_terminal> (<hyperlink>15</hyperlink>) production permits an additional construct, the fixed statement, which is used to &quot;fix&quot; a moveable variable such that its address remains constant for the duration of the statement. <grammar_production><name><non_terminal where="15">embedded-statement</non_terminal></name> : <rhs><terminal>...</terminal></rhs><rhs><non_terminal where="25.6">fixed-statement</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="25.6">fixed-statement</non_terminal></name> : <rhs><keyword>fixed</keyword><terminal>(</terminal><non_terminal where="25.2">pointer-type</non_terminal><non_terminal where="25.6">fixed-pointer-declarators</non_terminal><terminal>)</terminal><non_terminal where="15">embedded-statement</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="25.6">fixed-pointer-declarator</non_terminal>s</name> : <rhs><non_terminal where="25.6">fixed-pointer-declarator</non_terminal></rhs><rhs><non_terminal where="25.6">fixed-pointer-declarators</non_terminal><terminal>,</terminal><non_terminal where="25.6">fixed-pointer-declarator</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="25.6">fixed-pointer-declarator</non_terminal></name> : <rhs><non_terminal where="9.4.2">identifier</non_terminal><terminal>=</terminal><non_terminal where="25.6">fixed-pointer-initializer</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="25.6">fixed-pointer-initializer</non_terminal></name> : <rhs><terminal>&amp;</terminal><non_terminal where="12.4">variable-reference</non_terminal></rhs><rhs><non_terminal where="14.14">expression</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>Each <non_terminal where="25.6">fixed-pointer-declarator</non_terminal> declares a local variable of the given <non_terminal where="25.2">pointer-type</non_terminal> and initializes that local variable with the address computed by the corresponding <non_terminal where="25.6">fixed-pointer-initializer</non_terminal>. A local variable declared in a fixed statement is accessible in any <non_terminal where="25.6">fixed-pointer-initializer</non_terminal>s occurring to the right of that variable's declaration, and in the <non_terminal where="15">embedded-statement</non_terminal> of the fixed statement. A local variable declared by a fixed statement is considered read-only. A compile-time error occurs if the embedded statement attempts to modify this local variable (via assignment or the ++ and  --operators) or pass it as a ref or out parameter. </paragraph>
+  <paragraph>A <non_terminal where="25.6">fixed-pointer-initializer</non_terminal> can be one of the following: <list><list_item> The token &quot;&amp;&quot; followed by a <non_terminal where="12.4">variable-reference</non_terminal> (<hyperlink>12.3.3</hyperlink>) to a moveable variable (<hyperlink>25.3</hyperlink>) of an unmanaged type T, provided the type T* is implicitly convertible to the pointer type given in the fixed statement. In this case, the initializer computes the address of the given variable, and the variable is guaranteed to remain at a fixed address for the duration of the fixed statement. </list_item><list_item> An expression of an <non_terminal where="19.1">array-type</non_terminal> with elements of an unmanaged type T, provided the type T* is implicitly convertible to the pointer type given in the fixed statement. In this case, the initializer computes the address of the first element in the array, and the entire array is guaranteed to remain at a fixed address for the duration of the fixed statement. The behavior of the fixed statement is implementation-defined if the array expression is null or if the array has zero elements. </list_item><list_item> An expression of type string, provided the type char* is implicitly convertible to the pointer type given in the fixed statement. In this case, the initializer computes the address of the first character in the string, and the entire string is guaranteed to remain at a fixed address for the duration of the fixed statement. The behavior of the fixed statement is implementation-defined if the string expression is null. </list_item></list></paragraph>
+  <paragraph>For each address computed by a <non_terminal where="25.6">fixed-pointer-initializer</non_terminal> the fixed statement ensures that the variable referenced by the address is not subject to relocation or disposal by the garbage collector for the duration of the fixed statement. For example, if the address computed by a <non_terminal where="25.6">fixed-pointer-initializer</non_terminal> references a field of an object or an element of an array instance, the fixed statement guarantees that the containing object instance is not relocated or disposed of during the lifetime of the statement. </paragraph>
+  <paragraph>It is the programmer's responsibility to ensure that pointers created by fixed statements do not survive beyond execution of those statements. For example, when pointers created by fixed statements are passed to external APIs, it is the programmer's responsibility to ensure that the APIs retain no memory of these pointers. </paragraph>
+  <paragraph>Fixed objects may cause fragmentation of the heap (because they can't be moved). For that reason, objects should be fixed only when absolutely necessary and then only for the shortest amount of time possible. <example>[Example: The example <code_example><![CDATA[
+class Test  
+{  
+   static int x;  
+   int y;  
+   unsafe static void F(int* p) {  
+      *p = 1;  
+   }  
+   static void Main() {  
+      Test t = new Test();  
+      int[] a = new int[10];  
+      unsafe {  
+         fixed (int* p = &x) F(p);  
+         fixed (int* p = &t.y) F(p);  
+         fixed (int* p = &a[0]) F(p);  
+         fixed (int* p = a) F(p);  
+      }  
+   }  
+}  
+]]></code_example>demonstrates several uses of the fixed statement. The first statement fixes and obtains the address of a static field, the second statement fixes and obtains the address of an instance field, and the third statement fixes and obtains the address of an array element. In each case it would have been an error to use the regular &amp; operator since the variables are all classified as moveable variables. </example></paragraph>
+  <paragraph>
+    <example>The third and fourth fixed statements in the example above produce identical results. In general, for an array instance a, specifying &amp;a[0] in a fixed statement is the same as simply specifying a. </example>
+  </paragraph>
+  <paragraph>
+    <example>Here's another example of the fixed statement, this time using string: <code_example><![CDATA[
+class Test  
+{  
+   static string name = "xx";  
+   
+   unsafe static void F(char* p) {  
+      for (int i = 0; p[i] != '\0'; ++i)  
+      Console.WriteLine(p[i]);  
+   }  
+   
+   static void Main() {  
+      unsafe {  
+         fixed (char* p = name) F(p);  
+         fixed (char* p = "xx") F(p);  
+      }  
+   }  
+}  
+]]></code_example>end example]</example>
+  </paragraph>
+  <paragraph>In an unsafe context array elements of single-dimensional arrays are stored in increasing index order, starting with index 0 and ending with index Length  -1. For multi-dimensional arrays, array elements are stored such that the indices of the rightmost dimension are increased first, then the next left dimension, and so on to the left. </paragraph>
+  <paragraph>Within a fixed statement that obtains a pointer p to an array instance a, the pointer values ranging from p to p + a.Length  -1 represent addresses of the elements in the array. Likewise, the variables ranging from p[0] to p[a.Length  -1] represent the actual array elements. Given the way in which arrays are stored , we can treat an array of any dimension as though it were linear. <example>[Example: For example. <code_example><![CDATA[
+using System;  
+class Test  
+{  
+   static void Main() {  
+      int[,,] a = new int[2,3,4];  
+      unsafe {  
+         fixed (int* p = a) {  
+            for (int i = 0; i < a.Length; ++i)  // treat as linear  
+            p[i] = i;  
+         }  
+      }  
+      
+      for (int i = 0; i < 2; ++i)  
+      for (int j = 0; j < 3; ++j) {  
+         for (int k = 0; k < 4; ++k)  
+         Console.Write("[{0},{1},{2}] = {3,2} ", i, j, k,  
+         a[i,j,k]);  
+         Console.WriteLine();  
+      }  
+   }  
+}  
+]]></code_example>which produces the output: <code_example><![CDATA[
+[0,0,0] =  0 [0,0,1] =  1 [0,0,2] =  2 [0,0,3] =  3  
+[0,1,0] =  4 [0,1,1] =  5 [0,1,2] =  6 [0,1,3] =  7  
+[0,2,0] =  8 [0,2,1] =  9 [0,2,2] = 10 [0,2,3] = 11  
+[1,0,0] = 12 [1,0,1] = 13 [1,0,2] = 14 [1,0,3] = 15  
+[1,1,0] = 16 [1,1,1] = 17 [1,1,2] = 18 [1,1,3] = 19  
+[1,2,0] = 20 [1,2,1] = 21 [1,2,2] = 22 [1,2,3] = 23  
+]]></code_example>end example]</example> </paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+class Test  
+{  
+   unsafe static void Fill(int* p, int count, int value) {  
+      for (; count != 0; count--) *p++ = value;  
+   }  
+   static void Main() {  
+      int[] a = new int[100];  
+      unsafe {  
+         fixed (int* p = a) Fill(p, 100, -1);  
+      }  
+   }  
+}  
+]]></code_example>a fixed statement is used to fix an array so its address can be passed to a method that takes a pointer. end example]</example>
+  </paragraph>
+  <paragraph>A char* value produced by fixing a string instance always points to a null-terminated string. Within a fixed statement that obtains a pointer p to a string instance s, the pointer values ranging from p to p + s.Length  -1 represent addresses of the characters in the string, and the pointer value p + s.Length always points to a null character (the character with value '\0'). </paragraph>
+  <paragraph>Modifying objects of managed type through fixed pointers can result in undefined behavior. <note>[Note: For example, because strings are immutable, it is the programmer's responsibility to ensure that the characters referenced by a pointer to a fixed string are not modified. end note]</note> </paragraph>
+  <paragraph>
+    <note>[Note: The automatic null-termination of strings is particularly convenient when calling external APIs that expect &quot;C-style&quot; strings. Note, however, that a string instance is permitted to contain null characters. If such null characters are present, the string will appear truncated when treated as a null-terminated char*. end note]</note>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/25.7.xml b/mcs/docs/ecma334/25.7.xml
new file mode 100644 (file)
index 0000000..317c198
--- /dev/null
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<clause number="25.7" title="Stack allocation">
+  <paragraph>In an unsafe context, a local variable declaration (<hyperlink>15.5.1</hyperlink>) may include a stack allocation initializer, which allocates memory from the call stack. <grammar_production><name><non_terminal where="15.5.1">local-variable-initializer</non_terminal></name> : <rhs><non_terminal where="14.14">expression</non_terminal></rhs><rhs><non_terminal where="19.6">array-initializer</non_terminal></rhs></grammar_production><non_terminal where="25.7">stackalloc-initializer</non_terminal> <grammar_production><name><non_terminal where="25.7">stackalloc-initializer</non_terminal></name> : <rhs><keyword>stackalloc</keyword><non_terminal where="25.2">unmanaged-type</non_terminal><terminal>[</terminal><non_terminal where="14.14">expression</non_terminal><terminal>]</terminal></rhs></grammar_production></paragraph>
+  <paragraph>The <non_terminal where="25.2">unmanaged-type</non_terminal> indicates the type of the items that will be stored in the newly allocated location, and the expression indicates the number of these items. Taken together, these specify the required allocation size. Since the size of a stack allocation cannot be negative, it is a compile-time error to specify the number of items as a <non_terminal where="14.15">constant-expression</non_terminal> that evaluates to a negative value. </paragraph>
+  <paragraph>A stack allocation initializer of the form stackalloc T[E] requires T to be an unmanaged type (<hyperlink>25.2</hyperlink>) and E to be an expression of type <keyword>int</keyword>. The construct allocates E * sizeof(T) bytes from the call stack and returns a pointer, of type T*, to the newly allocated block. If E is a negative value, then the behavior is undefined. If E is zero, then no allocation is made, and the pointer returned is implementation-defined. If there is not enough memory available to allocate a block of the given size, a System.StackOverflowException is thrown. </paragraph>
+  <paragraph>The content of the newly allocated memory is undefined. </paragraph>
+  <paragraph>Stack allocation initializers are not permitted in catch or finally blocks (<hyperlink>15.10</hyperlink>). </paragraph>
+  <paragraph><note>[Note: There is no way to explicitly free memory allocated using stackalloc. end note]</note> All  stack-allocated memory blocks created during the execution of a function member are automatically discarded when that function member returns. <note>[Note: This corresponds to the alloca function, an extension commonly found C and C++ implementations. end note]</note></paragraph>
+  <paragraph>
+    <example>[Example: In the example <code_example><![CDATA[
+using System;  
+class Test  
+{  
+   static string IntToString(int value) {  
+      int n = value >= 0 ? value : -value;  
+      unsafe {  
+         char* buffer = stackalloc char[16];  
+         char* p = buffer + 16;  
+         do {  
+            *--p = (char)(n % 10 + '0');  
+            n /= 10;  
+         } while (n != 0);  
+         if (value < 0) *--p = '-';  
+         return new string(p, 0, (int)(buffer + 16 - p));  
+      }  
+   }  
+   static void Main() {  
+      Console.WriteLine(IntToString(12345));  
+      Console.WriteLine(IntToString(-999));  
+   }  
+}  
+]]></code_example>a stackalloc initializer is used in the IntToString method to allocate a buffer of 16 characters on the stack. The buffer is automatically discarded when the method returns. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/25.8.xml b/mcs/docs/ecma334/25.8.xml
new file mode 100644 (file)
index 0000000..5fb0cc7
--- /dev/null
@@ -0,0 +1,89 @@
+<?xml version="1.0"?>
+<clause number="25.8" title="Dynamic memory allocation">
+  <paragraph>Except for the stackalloc operator, C# provides no predefined constructs for managing non-garbage collected memory. Such services are typically provided by supporting class libraries or imported directly from the underlying operating system. <example>[Example: For example, the Memory class below illustrates how the heap functions of an underlying operating system might be accessed from C#: <code_example><![CDATA[
+using System;  
+using System.Runtime.InteropServices;  
+public unsafe class Memory  
+{  
+   // Handle for the process heap. This handle is used in all calls to  
+   the  
+   // HeapXXX APIs in the methods below.  
+   static int ph = GetProcessHeap();  
+   // Private instance constructor to prevent instantiation.  
+   private Memory() {}  
+   // Allocates a memory block of the given size. The allocated memory is  
+   // automatically initialized to zero.  
+   public static void* Alloc(int size) {  
+      void* result = HeapAlloc(ph, HEAP_ZERO_MEMORY, size);  
+      if (result == null) throw new OutOfMemoryException();  
+      return result;  
+   }  
+   // Copies count bytes from src to dst. The source and destination  
+   // blocks are permitted to overlap.  
+   public static void Copy(void* src, void* dst, int count) {  
+      byte* ps = (byte*)src;  
+      byte* pd = (byte*)dst;  
+      if (ps > pd) {  
+         for (; count != 0; count--) *pd++ = *ps++;  
+      }  
+      else if (ps < pd) {  
+         for (ps += count, pd += count; count != 0; count--) *--pd = *--  
+         ps;  
+      }  
+   }  
+   // Frees a memory block.  
+   public static void Free(void* block) {  
+      if (!HeapFree(ph, 0, block)) throw new InvalidOperationException();  
+   }  
+   // Re-allocates a memory block. If the reallocation request is for a  
+   // larger size, the additional region of memory is automatically  
+   // initialized to zero.  
+   public static void* ReAlloc(void* block, int size) {  
+      void* result = HeapReAlloc(ph, HEAP_ZERO_MEMORY, block, size);  
+      if (result == null) throw new OutOfMemoryException();  
+      return result;  
+   }  
+   // Returns the size of a memory block.  
+   public static int SizeOf(void* block) {  
+      int result = HeapSize(ph, 0, block);  
+      if (result == -1) throw new InvalidOperationException();  
+      return result;  
+   }  
+   // Heap API flags  
+   const int HEAP_ZERO_MEMORY = 0x00000008;  
+   // Heap API functions  
+   [DllImport("kernel32")]  
+   static extern int GetProcessHeap();  
+   [DllImport("kernel32")]  
+   static extern void* HeapAlloc(int hHeap, int flags, int size);  
+   [DllImport("kernel32")]  
+   static extern bool HeapFree(int hHeap, int flags, void* block);  
+   [DllImport("kernel32")]  
+   static extern void* HeapReAlloc(int hHeap, int flags,  
+   void* block, int size);  
+   [DllImport("kernel32")]  
+   static extern int HeapSize(int hHeap, int flags, void* block);  
+}  
+]]></code_example></example></paragraph>
+  <paragraph>
+    <example>An example that uses the Memory class is given below: <code_example><![CDATA[
+class Test  
+{  
+   static void Main() {  
+      unsafe {  
+         byte* buffer = (byte*)Memory.Alloc(256);  
+         for (int i = 0; i < 256; i++) buffer[i] = (byte)i;  
+         byte[] array = new byte[256];  
+         fixed (byte* p = array) Memory.Copy(buffer, p, 256);   
+         Memory.Free(buffer);  
+         for (int i = 0; i < 256; i++) Console.WriteLine(array[i]);  
+      }  
+   }  
+}  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>The example allocates 256 bytes of memory through Memory.Alloc and initializes the memory block with values increasing from 0 to 255. It then allocates a 256-element <keyword>byte</keyword> array and uses Memory.Copy to copy the contents of the memory block into the <keyword>byte</keyword> array. Finally, the memory block is freed using Memory.Free and the contents of the <keyword>byte</keyword> array are output on the console. end example]</example>
+  </paragraph>
+  <paragraph>End of conditionally normative text. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/25.xml b/mcs/docs/ecma334/25.xml
new file mode 100644 (file)
index 0000000..a93a58d
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+<clause number="25" title="Unsafe code">
+  <paragraph>An implementation that does not support unsafe code is required to diagnose any usage of the keyword unsafe. </paragraph>
+  <paragraph>This remainder of this clause is conditionally normative. </paragraph>
+  <paragraph>
+    <note>[Note: The core C# language, as defined in the preceding chapters, differs notably from C and C++ in its omission of pointers as a data type. Instead, C# provides references and the ability to create objects that are managed by a garbage collector. This design, coupled with other features, makes C# a much safer language than C or C++. In the core C# language it is simply not possible to have an uninitialized variable, a &quot;dangling&quot; pointer, or an expression that indexes an array beyond its bounds. Whole categories of bugs that routinely plague C and C++ programs are thus eliminated. </note>
+  </paragraph>
+  <paragraph>
+    <note>While practically every pointer type construct in C or C++ has a reference type counterpart in C#, nonetheless, there are situations where access to pointer types becomes a necessity. For example, interfacing with the underlying operating system, accessing a memory-mapped device, or implementing a time-critical algorithm may not be possible or practical without access to pointers. To address this need, C# provides the ability to write unsafe code. </note>
+  </paragraph>
+  <paragraph>
+    <note>In unsafe code it is possible to declare and operate on pointers, to perform conversions between pointers and integral types, to take the address of variables, and so forth. In a sense, writing unsafe code is much like writing C code within a C# program. </note>
+  </paragraph>
+  <paragraph>
+    <note>Unsafe code is in fact a &quot;safe&quot; feature from the perspective of both developers and users. Unsafe code must be clearly marked with the modifier unsafe, so developers can't possibly use unsafe features accidentally, and the execution engine works to ensure that unsafe code cannot be executed in an untrusted environment. end note]</note>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/3.xml b/mcs/docs/ecma334/3.xml
new file mode 100644 (file)
index 0000000..2a853a5
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<clause number="3" title="References" informative="true">
+  <paragraph>The following references are informative. </paragraph>
+  <paragraph>ISO/IEC 9899:1999, Programming languages  -C. </paragraph>
+  <paragraph>ISO/IEC 14882:1998, Programming languages  -C++. </paragraph>
+  <paragraph>ANSI X3.274-1996, Programming Language REXX. (This document is useful in understanding  floating-point <keyword>decimal</keyword> arithmetic rules.) </paragraph>
+  <paragraph>End of informative references. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/4.xml b/mcs/docs/ecma334/4.xml
new file mode 100644 (file)
index 0000000..537a1d9
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<clause number="4" title="Definitions">
+  <paragraph>For the purposes of this ECMA Standard, the following definitions apply. Other terms are defined where they appear in italic type or on the left side of a syntax rule. Terms explicitly defined in this ECMA Standard are not to be presumed to refer implicitly to similar terms defined elsewhere. Terms not defined in this ECMA Standard are to be interpreted according to ISO/IEC 2382.1. Mathematical symbols not defined in this ECMA Standard are to be interpreted according to ISO 31.11. </paragraph>
+  <paragraph><term_definition>Application</term_definition>  -refers to an assembly that has an entry point (<hyperlink>10.1</hyperlink>). When an application is run, a new application domain is created. Several different instantiations of an application may exist on the same machine at the same time, and each has its own application domain. </paragraph>
+  <paragraph><term_definition>Application domain</term_definition>  -an entity that enables application isolation by acting as a container for application state. An application domain acts as a container and boundary for the types defined in the application and the class libraries it uses. Types loaded into one application domain are distinct from the same type loaded into another application domain, and instances of objects are not directly shared between application domains. For instance, each application domain has its own copy of static variables for these types, and a static constructor for a type is run at most once per application domain. Implementations are free to provide implementation-specific policy or mechanisms for the creation and destruction of application domains. </paragraph>
+  <paragraph><term_definition>Argument</term_definition>  -an expression in the comma-separated list bounded by the parentheses in a method or instance constructor call expression. It is also known as an actual argument. </paragraph>
+  <paragraph><term_definition>Assembly</term_definition>  -refers to one or more files that are output by the compiler as a result of program compilation. An assembly is a configured set of loadable code modules and other resources that together implement a unit of functionality. An assembly may contain types, the executable code used to implement these types, and references to other assemblies. The physical representation of an assembly is not defined by this specification. Essentially, an assembly is the output of the compiler. </paragraph>
+  <paragraph><term_definition>Behavior</term_definition>  -external appearance or action. </paragraph>
+  <paragraph><term_definition>Behavior, implementation-defined</term_definition>  -unspecified behavior where each implementation documents how the choice is made. </paragraph>
+  <paragraph><term_definition>Behavior, undefined</term_definition>  -behavior, upon use of a nonportable or erroneous construct or of erroneous data, for which this ECMA Standard imposes no requirements. [Possible handling of undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message)]. </paragraph>
+  <paragraph><term_definition>Behavior, unspecified</term_definition>  -behavior where this ECMA Standard provides two or more possibilities and imposes no further requirements on which is chosen in any instance. </paragraph>
+  <paragraph><term_definition>Class library</term_definition>  -refers to an assembly that can be used by other assemblies. Use of a class library does not cause the creation of a new application domain. Instead, a class library is loaded into the application domain that uses it. For instance, when an application uses a class library, that class library is loaded into the application domain for that application. If an application uses a class library A that itself uses a class library B, then both A and B are loaded into the application domain for the application. </paragraph>
+  <paragraph><term_definition>Diagnostic message</term_definition>  -a message belonging to an implementation-defined subset of the implementation's output messages. </paragraph>
+  <paragraph><term_definition>Error, compile-time</term_definition>  -an error reported during program translation. </paragraph>
+  <paragraph><term_definition>Exception</term_definition>  -an error condition that is outside the ordinary expected behavior. </paragraph>
+  <paragraph><term_definition>Implementation</term_definition>  -particular set of software (running in a particular translation environment under particular control options) that performs translation of programs for, and supports execution of methods in, a particular execution environment. </paragraph>
+  <paragraph><term_definition>Namespace</term_definition>  -a logical organizational system that provides a way of presenting program elements that are exposed to other programs. </paragraph>
+  <paragraph><term_definition>Parameter</term_definition>  -a variable declared as part of a method, instance constructor, or indexer definition, which acquires a value on entry to that method. It is also known as formal parameter. </paragraph>
+  <paragraph><term_definition>Program</term_definition>  -refers to one or more source files that are presented to the compiler. Essentially, a program is the input to the compiler. </paragraph>
+  <paragraph><term_definition>Program, valid</term_definition>  -a C# program constructed according to the syntax rules and diagnosable semantic rules. </paragraph>
+  <paragraph><term_definition>Program instantiation</term_definition>  -the execution of an application. </paragraph>
+  <paragraph><term_definition>Recommended practice</term_definition>  -specification that is strongly recommended as being aligned with the intent of the standard, but that may be impractical for some implementations. </paragraph>
+  <paragraph><term_definition>Source file</term_definition>  -an ordered sequence of Unicode characters. Source files typically have a one-to-one correspondence with files in a file system, but this correspondence is not required. </paragraph>
+  <paragraph><term_definition>Unsafe code</term_definition>  -code that is permitted to perform such lower-level operations as declaring and operating on pointers, performing conversions between pointers and integral types, and taking the address of variables. Such operations provide functionality such as permitting interfacing with the underlying operating system, accessing a memory-mapped device, or implementing a time-critical algorithm. </paragraph>
+  <paragraph><term_definition>Warning, compile-time</term_definition>  -an informational message reported during program translation, that is intended to identify a potentially questionable usage of a program element. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/5.xml b/mcs/docs/ecma334/5.xml
new file mode 100644 (file)
index 0000000..71b5e20
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<clause number="5" title="Notational conventions">
+  <paragraph>Lexical and syntactic grammars for C# are interspersed throughout this specification. The lexical grammar defines how characters can be combined to form tokens (<hyperlink>9.4</hyperlink>), the minimal lexical elements of the language. The syntactic grammar defines how tokens can be combined to make valid C# programs. </paragraph>
+  <paragraph>Grammar productions include both non-terminal and terminal symbols. In grammar productions,  non-terminal symbols are shown in italic type, and terminal symbols are shown in a fixed-width font. Each non-terminal is defined by a set of productions. The first line of a set of productions is the name of the  non-terminal, followed by a colon. Each successive indented line contains the right-hand side for a production that has the non-terminal symbol as the left-hand side. For example: <grammar_production><name><non_terminal where="17.1.1">class-modifier</non_terminal></name> : <rhs><keyword>new</keyword></rhs><rhs><keyword>public</keyword></rhs><rhs><keyword>protected</keyword></rhs><rhs><keyword>internal</keyword></rhs><rhs><keyword>private</keyword></rhs><rhs><keyword>abstract</keyword></rhs><rhs><keyword>sealed</keyword></rhs></grammar_production>defines the <non_terminal where="17.1.1">class-modifier</non_terminal> non-terminal as having seven productions. </paragraph>
+  <paragraph>Alternatives are normally listed on separate lines, as shown above, though in cases where there are many alternatives, the phrase &quot;one of&quot; precedes a list of the options. This is simply shorthand for listing each of the alternatives on a separate line. For example: <grammar_production><name><non_terminal where="9.4.4.2">decimal-digit</non_terminal></name> : one of <rhs><terminal>0</terminal><terminal>1</terminal><terminal>2</terminal><terminal>3</terminal><terminal>4</terminal><terminal>5</terminal><terminal>6</terminal><terminal>7</terminal><terminal>8</terminal><terminal>9</terminal></rhs></grammar_production>is equivalent to: <grammar_production><name><non_terminal where="9.4.4.2">decimal-digit</non_terminal></name> : <rhs><terminal>0</terminal></rhs><rhs><terminal>1</terminal></rhs><rhs><terminal>2</terminal></rhs><rhs><terminal>3</terminal></rhs><rhs><terminal>4</terminal></rhs><rhs><terminal>5</terminal></rhs><rhs><terminal>6</terminal></rhs><rhs><terminal>7</terminal></rhs><rhs><terminal>8</terminal></rhs><rhs><terminal>9</terminal></rhs></grammar_production></paragraph>
+  <paragraph>A subscripted suffix &quot;opt&quot;, as in identifier<opt/>, is used as shorthand to indicate an optional symbol. The example: <grammar_production><name><non_terminal where="15.8.3">for-statement</non_terminal></name> : <rhs><keyword>for</keyword><terminal>(</terminal><non_terminal where="15.8.3">for-initializer</non_terminal><opt/><terminal>;</terminal><non_terminal where="15.8.3">for-condition</non_terminal><opt/><terminal>;</terminal><non_terminal where="15.8.3">for-iterator</non_terminal><opt/><terminal>)</terminal><non_terminal where="15">embedded-statement</non_terminal></rhs></grammar_production>is equivalent to: <grammar_production><name><non_terminal where="15.8.3">for-statement</non_terminal></name> : <rhs><keyword>for</keyword><terminal>(</terminal><terminal>;</terminal><terminal>;</terminal><terminal>)</terminal><non_terminal where="15">embedded-statement</non_terminal></rhs><rhs><keyword>for</keyword><terminal>(</terminal><non_terminal where="15.8.3">for-initializer</non_terminal><terminal>;</terminal><terminal>;</terminal><terminal>)</terminal><non_terminal where="15">embedded-statement</non_terminal></rhs><rhs><keyword>for</keyword><terminal>(</terminal><terminal>;</terminal><non_terminal where="15.8.3">for-condition</non_terminal><terminal>;</terminal><terminal>)</terminal><non_terminal where="15">embedded-statement</non_terminal></rhs><rhs><keyword>for</keyword><terminal>(</terminal><terminal>;</terminal><terminal>;</terminal><non_terminal where="15.8.3">for-iterator</non_terminal><terminal>)</terminal><non_terminal where="15">embedded-statement</non_terminal></rhs><rhs><keyword>for</keyword><terminal>(</terminal><non_terminal where="15.8.3">for-initializer</non_terminal><terminal>;</terminal><non_terminal where="15.8.3">for-condition</non_terminal><terminal>;</terminal><terminal>)</terminal><non_terminal where="15">embedded-statement</non_terminal></rhs><rhs><keyword>for</keyword><terminal>(</terminal><terminal>;</terminal><non_terminal where="15.8.3">for-condition</non_terminal><terminal>;</terminal><non_terminal where="15.8.3">for-iterator</non_terminal><terminal>)</terminal><non_terminal where="15">embedded-statement</non_terminal></rhs><rhs><keyword>for</keyword><terminal>(</terminal><non_terminal where="15.8.3">for-initializer</non_terminal><terminal>;</terminal><terminal>;</terminal><non_terminal where="15.8.3">for-iterator</non_terminal><terminal>)</terminal><non_terminal where="15">embedded-statement</non_terminal></rhs><rhs><keyword>for</keyword><terminal>(</terminal><non_terminal where="15.8.3">for-initializer</non_terminal><terminal>;</terminal><non_terminal where="15.8.3">for-condition</non_terminal><terminal>;</terminal><non_terminal where="15.8.3">for-iterator</non_terminal><terminal>)</terminal><non_terminal where="15">embedded-statement</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>All terminal characters are to be understood as the appropriate Unicode character from the ASCII range, as opposed to any similar-looking characters from other Unicode ranges. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/6.xml b/mcs/docs/ecma334/6.xml
new file mode 100644 (file)
index 0000000..1c5123d
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<clause number="6" title="Acronyms and abbreviations" informative="true">
+  <paragraph>This clause is informative. </paragraph>
+  <paragraph>The following acronyms and abbreviations are used throughout this ECMA Standard. </paragraph>
+  <paragraph>BCL  -Base Class Library, which provides types to represent the built-in data types of the CLI, simple file access, custom attributes, security attributes, string manipulation, formatting, streams, and collections. </paragraph>
+  <paragraph>CLI  -Common Language Infrastructure </paragraph>
+  <paragraph>CLS  -Common Language Specification </paragraph>
+  <paragraph>IEC  -the International Electrotechnical Commission </paragraph>
+  <paragraph>IEEE  -the Institute of Electrical and Electronics Engineers </paragraph>
+  <paragraph>ISO  -the International Organization for Standardization </paragraph>
+  <paragraph>The name C# is pronounced &quot;C Sharp&quot;. </paragraph>
+  <paragraph>The name C# is written as the LATIN CAPITAL LETTER C (U+0043) followed by the NUMBER SIGN # (U+000D). </paragraph>
+  <paragraph>End of informative text. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/7.xml b/mcs/docs/ecma334/7.xml
new file mode 100644 (file)
index 0000000..65274de
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<clause number="7" title="General description" informative="true">
+  <paragraph>This clause is informative. </paragraph>
+  <paragraph>This ECMA Standard is intended to be used by implementers, academics, and application programmers. As such, it contains a considerable amount of explanatory material that, strictly speaking, is not necessary in a formal language specification. </paragraph>
+  <paragraph>This standard is divided into the following subdivisions: </paragraph>
+  <paragraph>1 Front matter (clauses 1-7); </paragraph>
+  <paragraph>2 Language overview (clause 8); </paragraph>
+  <paragraph>3 The language syntax, constraints, and semantics (clauses 9-25); </paragraph>
+  <paragraph>4 Annexes </paragraph>
+  <paragraph>Examples are provided to illustrate possible forms of the constructions described. References are used to refer to related clauses. Notes are provided to give advice or guidance to implementers or programmers. Annexes provide additional information and summarize the information contained in this ECMA Standard. </paragraph>
+  <paragraph>Clauses 2-5, 9-24, the beginning of 25, and the beginning of D form a normative part of this standard; all of clause 25 with the exception of the beginning is conditionally normative; and Brief history, clauses 1, 6-8, annexes A, B, C, and most of D, notes, examples, and the index are informative. </paragraph>
+  <paragraph>Except for whole clauses or annexes that are identified as being informative, informative text that is contained within normative text is indicated in two ways: </paragraph>
+  <paragraph>1 <example>[Example: The following example... code fragment, possibly with some narrative...end example]</example> </paragraph>
+  <paragraph>2 <note>[Note: narrative... end note]</note> </paragraph>
+  <paragraph>End of informative text. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/8.1.xml b/mcs/docs/ecma334/8.1.xml
new file mode 100644 (file)
index 0000000..03dc67a
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<clause number="8.1" title="Getting started" informative="true">
+  <paragraph>The canonical &quot;hello, world&quot; program can be written as follows: <code_example><![CDATA[
+using System;  
+class Hello  
+{  
+   static void Main() {  
+      Console.WriteLine("hello, world");  
+   }  
+}  
+]]></code_example></paragraph>
+  <paragraph>The source code for a C# program is typically stored in one or more text files with a file extension of .cs, as in hello.cs. Using a command-line compiler, such a program can be compiled with a command line like <code_example><![CDATA[
+csc hello.cs  
+]]></code_example>which produces an application named hello.exe. The output produced by this application when it is run is: <code_example><![CDATA[
+hello, world  
+]]></code_example></paragraph>
+  <paragraph>Close examination of this program is illuminating: <list><list_item> The using System; directive references a namespace called System that is provided by the Common Language Infrastructure (CLI) class library. This namespace contains the Console class referred to in the Main method. Namespaces provide a hierarchical means of organizing the elements of one or more programs. A <non_terminal where="16.3">using-directive</non_terminal> enables unqualified use of the types that are members of the namespace. The &quot;hello, world&quot; program uses Console.WriteLine as shorthand for System.Console.WriteLine. </list_item><list_item> The Main method is a member of the class Hello. It has the static modifier, and so it is a method on the class Hello rather than on instances of this class. </list_item><list_item> The entry point for an application-the method that is called to begin execution-is always a static method named Main. </list_item><list_item> The &quot;hello, world&quot; output is produced using a class library. This standard does not include a class library. Instead, it references the class library provided by CLI. </list_item></list></paragraph>
+  <paragraph>For C and C++ developers, it is interesting to note a few things that do not appear in the &quot;hello, world&quot; program. <list><list_item> The program does not use a global method for Main. Methods and variables are not supported at the global level; such elements are always contained within type declarations (e.g., class and struct declarations). </list_item><list_item> The program does not use either &quot;::&quot; or &quot;-&gt;&quot; operators. The &quot;::&quot; is not an operator at all, and the &quot;-&gt;&quot; operator is used in only a small fraction of programs (which involve unsafe code). The separator &quot;.&quot; is used in compound names such as Console.WriteLine. </list_item><list_item> The program does not contain forward declarations. Forward declarations are never needed, as declaration order is not significant. </list_item><list_item> The program does not use #include to import program text. Dependencies among programs are handled symbolically rather than textually. This approach eliminates barriers between applications written using multiple languages. For example, the Console class need not be written in C#. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/8.10.xml b/mcs/docs/ecma334/8.10.xml
new file mode 100644 (file)
index 0000000..4e7c303
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<clause number="8.10" title="Delegates" informative="true">
+  <paragraph>Delegates enable scenarios that some other languages have addressed with function pointers. However, unlike function pointers, delegates are object-oriented and type-safe. </paragraph>
+  <paragraph>A delegate declaration defines a class that is derived from the class System.Delegate. A delegate instance encapsulates one or more methods, each of which is referred to as a callable entity. For instance methods, a callable entity consists of an instance and a method on that instance. For static methods, a callable entity consists of just a method. Given a delegate instance and an appropriate set of arguments, one can invoke all of that delegate instance's methods with that set of arguments. </paragraph>
+  <paragraph>An interesting and useful property of a delegate instance is that it does not know or care about the classes of the methods it encapsulates; all that matters is that those methods be compatible (<hyperlink>22.1</hyperlink>) with the delegate's type. This makes delegates perfectly suited for &quot;anonymous&quot; invocation. This is a powerful capability. </paragraph>
+  <paragraph>There are three steps in defining and using delegates: declaration, instantiation, and invocation. Delegates are declared using delegate declaration syntax. The example <code_example><![CDATA[
+delegate void SimpleDelegate();  
+]]></code_example>declares a delegate named SimpleDelegate that takes no arguments and returns no result. </paragraph>
+  <paragraph>The example <code_example><![CDATA[
+class Test  
+{  
+   static void F() {  
+      System.Console.WriteLine("Test.F");  
+   }  
+   static void Main() {  
+      SimpleDelegate d = new SimpleDelegate(F);  
+      d();  
+   }  
+}  
+]]></code_example>creates a SimpleDelegate instance and then immediately calls it. </paragraph>
+  <paragraph>There is not much point in instantiating a delegate for a method and then immediately calling that method via the delegate, as it would be simpler to call the method directly. Delegates really show their usefulness when their anonymity is used. The example <code_example><![CDATA[
+void MultiCall(SimpleDelegate d, int count) {  
+   for (int i = 0; i < count; i++) {  
+      d();  
+   }  
+}  
+]]></code_example>shows a MultiCall method that repeatedly calls a SimpleDelegate. The MultiCall method doesn't know or care about the type of the target method for the SimpleDelegate, what accessibility that method has, or whether or not that method is static. All that matters is that the target method is compatible (<hyperlink>22.1</hyperlink>) with SimpleDelegate. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/8.11.xml b/mcs/docs/ecma334/8.11.xml
new file mode 100644 (file)
index 0000000..b05d002
--- /dev/null
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<clause number="8.11" title="Enums" informative="true">
+  <paragraph>An enum type declaration defines a type name for a related group of symbolic constants. Enums are used for &quot;multiple choice&quot; scenarios, in which a runtime decision is made from a fixed number of choices that are known at compile-time. </paragraph>
+  <paragraph>The example <code_example><![CDATA[
+enum Color   
+{  
+   Red,  
+   Blue,  
+   Green  
+}  
+class Shape  
+{  
+   public void Fill(Color color) {  
+      switch(color) {  
+         case Color.Red:  
+         ...  
+         break;  
+         case Color.Blue:  
+         ...  
+         break;  
+         case Color.Green:  
+         ...  
+         break;  
+         default:  
+         break;  
+      }  
+   }  
+}  
+]]></code_example>shows a Color enum and a method that uses this enum. The signature of the Fill method makes it clear that the shape can be filled with one of the given colors. </paragraph>
+  <paragraph>The use of enums is superior to the use of integer constants-as is common in languages without  enums-because the use of enums makes the code more readable and self-documenting. The self-documenting nature of the code also makes it possible for the development tool to assist with code writing and other &quot;designer&quot; activities. For example, the use of Color rather than <keyword>int</keyword> for a parameter type enables smart code editors to suggest Color values. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/8.12.xml b/mcs/docs/ecma334/8.12.xml
new file mode 100644 (file)
index 0000000..3b68268
--- /dev/null
@@ -0,0 +1,48 @@
+<?xml version="1.0"?>
+<clause number="8.12" title="Namespaces and assemblies" informative="true">
+  <paragraph>The programs presented so far have stood on their own except for dependence on a few system-provided classes such as System.Console. It is far more common, however, for real-world applications to consist of several different pieces, each compiled separately. For example, a corporate application might depend on several different components, including some developed internally and some purchased from independent software vendors. </paragraph>
+  <paragraph>Namespaces and assemblies enable this component-based system. Namespaces provide a logical organizational system. Namespaces are used both as an &quot;internal&quot; organization system for a program, and as an &quot;external&quot; organization system-a way of presenting program elements that are exposed to other programs. </paragraph>
+  <paragraph>Assemblies are used for physical packaging and deployment. An assembly may contain types, the executable code used to implement these types, and references to other assemblies. </paragraph>
+  <paragraph>To demonstrate the use of namespaces and assemblies, this section revisits the &quot;hello, world&quot; program presented earlier, and splits it into two pieces: a class library that provides messages and a console application that displays them. </paragraph>
+  <paragraph>The class library will contain a single class named HelloMessage. The example <code_example><![CDATA[
+// HelloLibrary.cs  
+namespace CSharp.Introduction  
+{  
+   public class HelloMessage  
+   {  
+      public string Message {  
+         get {  
+            return "hello, world";  
+         }  
+      }  
+   }  
+}  
+]]></code_example>shows the HelloMessage class in a namespace named CSharp.Introduction. The HelloMessage class provides a read-only property named Message. Namespaces can nest, and the declaration <code_example><![CDATA[
+namespace CSharp.Introduction  
+{...}  
+]]></code_example>is shorthand for two levels of namespace nesting: <code_example><![CDATA[
+namespace CSharp  
+{  
+   namespace Introduction  
+   {...}  
+}   
+]]></code_example></paragraph>
+  <paragraph>The next step in the componentization of &quot;hello, world&quot; is to write a console application that uses the HelloMessage class. The fully qualified name for the  class-CSharp.Introduction.HelloMessage-could be used, but this name is quite long and unwieldy. An easier way is to use a using namespace directive, which makes it possible to use all of the types in a namespace without qualification. The example <code_example><![CDATA[
+// HelloApp.cs  
+using CSharp.Introduction;  
+class HelloApp  
+{  
+   static void Main() {  
+      HelloMessage m = new HelloMessage();  
+      System.Console.WriteLine(m.Message);  
+   }  
+}  
+]]></code_example>shows a using namespace directive that refers to the CSharp.Introduction namespace. The occurrences of HelloMessage are shorthand for CSharp.Introduction.HelloMessage. </paragraph>
+  <paragraph>C# also enables the definition and use of aliases. A using alias directive defines an alias for a type. Such aliases can be useful in situation in which name collisions occur between two class libraries, or when a small number of types from a much larger namespace are being used. The example <code_example><![CDATA[
+using MessageSource = CSharp.Introduction.HelloMessage;  
+]]></code_example>shows a using alias directive that defines MessageSource as an alias for the HelloMessage class. </paragraph>
+  <paragraph>The code we have written can be compiled into a class library containing the class HelloMessage and an application containing the class HelloApp. The details of this compilation step might differ based on the compiler or tool being used. A command-line compiler might enable compilation of a class library and an application that uses that library with the following command-line invocations: <code_example><![CDATA[
+csc /target:library HelloLibrary.cs   
+csc /reference:HelloLibrary.dll HelloApp.cs  
+]]></code_example>which produce a class library named HelloLibrary.dll and an application named HelloApp.exe. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/8.13.xml b/mcs/docs/ecma334/8.13.xml
new file mode 100644 (file)
index 0000000..24979be
--- /dev/null
@@ -0,0 +1,86 @@
+<?xml version="1.0"?>
+<clause number="8.13" title="Versioning" informative="true">
+  <paragraph>Versioning is the process of evolving a component over time in a compatible manner. A new version of a component is source compatible with a previous version if code that depends on the previous version can, when recompiled, work with the new version. In contrast, a new version of a component is binary compatible if an application that depended on the old version can, without recompilation, work with the new version. </paragraph>
+  <paragraph>Most languages do not support binary compatibility at all, and many do little to facilitate source compatibility. In fact, some languages contain flaws that make it impossible, in general, to evolve a class over time without breaking at least some client code. </paragraph>
+  <paragraph>As an example, consider the situation of a base class author who ships a class named Base. In the first version, Base contains no method F. A component named Derived derives from Base, and introduces an F. This Derived class, along with the class Base on which it depends, is released to customers, who deploy to numerous clients and servers. <code_example><![CDATA[
+// Author A  
+namespace A   
+{  
+   public class Base   // version 1  
+   {  
+   }  
+}  
+// Author B  
+namespace B  
+{  
+   class Derived: A.Base  
+   {  
+      public virtual void F() {  
+         System.Console.WriteLine("Derived.F");   
+      }  
+   }  
+}  
+]]></code_example></paragraph>
+  <paragraph>So far, so good, but now the versioning trouble begins. The author of Base produces a new version, giving it its own method F. <code_example><![CDATA[
+// Author A  
+namespace A   
+{  
+   public class Base   // version 2  
+   {  
+      public virtual void F() {    // added in version 2  
+         System.Console.WriteLine("Base.F");   
+      }  
+   }  
+}  
+]]></code_example></paragraph>
+  <paragraph>This new version of Base should be both source and binary compatible with the initial version. (If it weren't possible to simply add a method then a base class could never evolve.) Unfortunately, the new F in Base makes the meaning of Derived's F unclear. Did Derived mean to override Base's F? This seems unlikely, since when Derived was compiled, Base did not even have an F! Further, if Derived's F does override Base's F, then it must adhere to the contract specified by Base-a contract that was unspecified when Derived was written. In some cases, this is impossible. For example, Base's F might require that overrides of it always call the base. Derived's F could not possibly adhere to such a contract. </paragraph>
+  <paragraph>C# addresses this versioning problem by requiring developers to state their intent clearly. In the original code example, the code was clear, since Base did not even have an F. Clearly, Derived's F is intended as a new method rather than an override of a base method, since no base method named F exists. </paragraph>
+  <paragraph>If Base adds an F and ships a new version, then the intent of a binary version of Derived is still  clear-Derived's F is semantically unrelated, and should not be treated as an override. </paragraph>
+  <paragraph>However, when Derived is recompiled, the meaning is unclear-the author of Derived may intend its F to override Base's F, or to hide it. Since the intent is unclear, the compiler produces a warning, and by default makes Derived's F hide Base's F. This course of action duplicates the semantics for the case in which Derived is not recompiled. The warning that is generated alerts Derived's author to the presence of the F method in Base. </paragraph>
+  <paragraph>If Derived's F is semantically unrelated to Base's F, then Derived's author can express this intent-and, in effect, turn off the warning-by using the new keyword in the declaration of F. <code_example><![CDATA[
+// Author A  
+namespace A   
+{  
+   public class Base   // version 2  
+   {  
+      public virtual void F() { // added in version 2  
+         System.Console.WriteLine("Base.F");   
+      }  
+   }  
+}  
+// Author B  
+namespace B  
+{  
+   class Derived: A.Base  // version 2a: new  
+   {  
+      new public virtual void F() {  
+         System.Console.WriteLine("Derived.F");   
+      }  
+   }  
+}  
+]]></code_example></paragraph>
+  <paragraph>On the other hand, Derived's author might investigate further, and decide that Derived's F should override Base's F. This intent can be specified by using the override keyword, as shown below. <code_example><![CDATA[
+// Author A  
+namespace A   
+{  
+   public class Base     // version 2  
+   {  
+      public virtual void F() { // added in version 2  
+         System.Console.WriteLine("Base.F");   
+      }  
+   }  
+}  
+// Author B  
+namespace B  
+{  
+   class Derived: A.Base  // version 2b: override  
+   {  
+      public override void F() {  
+         base.F();  
+         System.Console.WriteLine("Derived.F");   
+      }  
+   }  
+}  
+]]></code_example></paragraph>
+  <paragraph>The author of Derived has one other option, and that is to change the name of F, thus completely avoiding the name collision. Although this change would break source and binary compatibility for Derived, the importance of this compatibility varies depending on the scenario. If Derived is not exposed to other programs, then changing the name of F is likely a good idea, as it would improve the readability of the program-there would no longer be any confusion about the meaning of F. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/8.14.xml b/mcs/docs/ecma334/8.14.xml
new file mode 100644 (file)
index 0000000..8b7ab52
--- /dev/null
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+<clause number="8.14" title="Attributes" informative="true">
+  <paragraph>C# is an imperative language, but like all imperative languages it does have some declarative elements. For example, the accessibility of a method in a class is specified by declaring it public, protected, internal, protected internal, or private. C# generalizes this capability, so that programmers can invent new kinds of declarative information, attach this declarative information to various program entities, and retrieve this declarative information at run-time. Programs specify this additional declarative information by defining and using attributes (<hyperlink>24</hyperlink>). </paragraph>
+  <paragraph>For instance, a framework might define a HelpAttribute attribute that can be placed on program elements such as classes and methods, enabling developers to provide a mapping from program elements to documentation for them. The example <code_example><![CDATA[
+using System;  
+[AttributeUsage(AttributeTargets.All)]  
+public class HelpAttribute: Attribute  
+{  
+   public HelpAttribute(string url) {  
+      this.url = url;  
+   }  
+   public string Topic = null;  
+   private string url;  
+   public string Url {   
+      get { return url; }  
+   }  
+}  
+]]></code_example>defines an attribute class named HelpAttribute, or Help for short, that has one positional parameter (string url) and one named parameter (string Topic). Positional parameters are defined by the formal parameters for public instance constructors of the attribute class, and named parameters are defined by public non-static read-write fields and properties of the attribute class. </paragraph>
+  <paragraph>The example <code_example><![CDATA[
+[Help("http://www.mycompany.com/.../Class1.htm")]  
+public class Class1   
+{  
+   [Help("http://www.mycompany.com/.../Class1.htm", Topic = "F")]  
+   public void F() {}  
+}  
+]]></code_example>shows several uses of the attribute Help. </paragraph>
+  <paragraph>Attribute information for a given program element can be retrieved at run-time by using reflection support. The example <code_example><![CDATA[
+using System;  
+class Test  
+{  
+   static void Main() {  
+      Type type = typeof(Class1);  
+      object[] arr = type.GetCustomAttributes(typeof(HelpAttribute),  
+      true);  
+      if (arr.Length == 0)  
+      Console.WriteLine("Class1 has no Help attribute.");  
+      else {  
+         HelpAttribute ha = (HelpAttribute) arr[0];  
+         Console.WriteLine("Url = {0}, Topic = {1}", ha.Url, ha.Topic);  
+      }  
+   }  
+}  
+]]></code_example>checks to see if Class1 has a Help attribute, and writes out the associated Topic and Url values if the attribute is present. </paragraph>
+  <paragraph>End of informative text. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/8.2.1.xml b/mcs/docs/ecma334/8.2.1.xml
new file mode 100644 (file)
index 0000000..136c077
--- /dev/null
@@ -0,0 +1,58 @@
+<?xml version="1.0"?>
+<clause number="8.2.1" title="Predefined types" informative="true">
+  <paragraph>C# provides a set of predefined types, most of which will be familiar to C and C++ developers. </paragraph>
+  <paragraph>The predefined reference types are object and string. The type object is the ultimate base type of all other types. The type string is used to represent Unicode string values. Values of type string are immutable. </paragraph>
+  <paragraph>The predefined value types include signed and unsigned integral types, floating-point types, and the types <keyword>bool</keyword>, <keyword>char</keyword>, and <keyword>decimal</keyword>. The signed integral types are <keyword>sbyte</keyword>, <keyword>short</keyword>, <keyword>int</keyword>, and long; the unsigned integral types are <keyword>byte</keyword>, <keyword>ushort</keyword>, <keyword>uint</keyword>, and ulong; and the floating-point types are <keyword>float</keyword> and <keyword>double</keyword>. </paragraph>
+  <paragraph>The <keyword>bool</keyword> type is used to represent boolean values: values that are either true or false. The inclusion of <keyword>bool</keyword> makes it easier to write self-documenting code, and also helps eliminate the all-too-common C++ coding error in which a developer mistakenly uses &quot;=&quot; when &quot;==&quot; should have been used. In C#, the example <code_example><![CDATA[
+int i = ...;  
+F(i);  
+if (i = 0)  // Bug: the test should be (i == 0)  
+G();  
+]]></code_example>results in a compile-time error because the expression i = 0 is of type <keyword>int</keyword>, and if statements require an expression of type <keyword>bool</keyword>. </paragraph>
+  <paragraph>The <keyword>char</keyword> type is used to represent Unicode characters. A variable of type <keyword>char</keyword> represents a single 16-bit Unicode character. </paragraph>
+  <paragraph>The <keyword>decimal</keyword> type is appropriate for calculations in which rounding errors caused by floating point representations are unacceptable. Common examples include financial calculations such as tax computations and currency conversions. The <keyword>decimal</keyword> type provides 28 significant digits. </paragraph>
+  <paragraph>The table below lists the predefined types, and shows how to write literal values for each of them. <table_line>Type Description Example </table_line>
+<table_line>object The ultimate base type of all other types object o = null; </table_line>
+<table_line>string String type; a string is a sequence of Unicode </table_line>
+<table_line>characters </table_line>
+<table_line>string s = &quot;hello&quot;; </table_line>
+<table_line><keyword>sbyte</keyword> 8-bit signed integral type <keyword>sbyte</keyword> val = 12; </table_line>
+<table_line><keyword>short</keyword> 16-bit signed integral type <keyword>short</keyword> val = 12; </table_line>
+<table_line><keyword>int</keyword> 32-bit signed integral type <keyword>int</keyword> val = 12; </table_line>
+<table_line><keyword>long</keyword> 64-bit signed integral type <keyword>long</keyword> val1 = 12; </table_line>
+<table_line><keyword>long</keyword> val2 = 34L; </table_line>
+<table_line><keyword>byte</keyword> 8-bit unsigned integral type <keyword>byte</keyword> val1 = 12; </table_line>
+<table_line><keyword>ushort</keyword> 16-bit unsigned integral type <keyword>ushort</keyword> val1 = 12; </table_line>
+<table_line><keyword>uint</keyword> 32-bit unsigned integral type <keyword>uint</keyword> val1 = 12; </table_line>
+<table_line><keyword>uint</keyword> val2 = 34U; </table_line>
+<table_line><keyword>ulong</keyword> 64-bit unsigned integral type <keyword>ulong</keyword> val1 = 12; </table_line>
+<table_line><keyword>ulong</keyword> val2 = 34U; </table_line>
+<table_line><keyword>ulong</keyword> val3 = 56L; </table_line>
+<table_line><keyword>ulong</keyword> val4 = 78UL; </table_line>
+<table_line><keyword>float</keyword> Single-precision floating point type <keyword>float</keyword> val = 1.23F; </table_line>
+<table_line><keyword>double</keyword> Double-precision floating point type <keyword>double</keyword> val1 = 1.23; </table_line>
+<table_line><keyword>double</keyword> val2 = 4.56D; </table_line>
+<table_line><keyword>bool</keyword> Boolean type; a <keyword>bool</keyword> value is either true or false <keyword>bool</keyword> val1 = true; </table_line>
+<table_line><keyword>bool</keyword> val2 = false; </table_line>
+<table_line><keyword>char</keyword> Character type; a <keyword>char</keyword> value is a Unicode character <keyword>char</keyword> val = 'h'; </table_line>
+<table_line><keyword>decimal</keyword> Precise <keyword>decimal</keyword> type with 28 significant digits <keyword>decimal</keyword> val = 1.23M; </table_line>
+</paragraph>
+  <paragraph>Each of the predefined types is shorthand for a system-provided type. For example, the keyword <keyword>int</keyword> refers to the struct System.Int32. As a matter of style, use of the keyword is favored over use of the complete system type name. </paragraph>
+  <paragraph>Predefined value types such as <keyword>int</keyword> are treated specially in a few ways but are for the most part treated exactly like other structs. Operator overloading enables developers to define new struct types that behave much like the predefined value types. For instance, a Digit struct can support the same mathematical operations as the predefined integral types, and can define conversions between Digit and predefined types. </paragraph>
+  <paragraph>The predefined types employ operator overloading themselves. For example, the comparison operators == and != have different semantics for different predefined types: <list><list_item> Two expressions of type <keyword>int</keyword> are considered equal if they represent the same integer value. </list_item><list_item> Two expressions of type object are considered equal if both refer to the same object, or if both are null. </list_item><list_item> Two expressions of type string are considered equal if the string instances have identical lengths and identical characters in each character position, or if both are null. </list_item></list></paragraph>
+  <paragraph>The example <code_example><![CDATA[
+using System;  
+class Test  
+{  
+   static void Main() {  
+      string s = "Test";  
+      string t = string.Copy(s);  
+      Console.WriteLine(s == t);  
+      Console.WriteLine((object)s == (object)t);  
+   }  
+}  
+]]></code_example>produces the output <code_example><![CDATA[
+True  
+False  
+]]></code_example>because the first comparison compares two expressions of type string, and the second comparison compares two expressions of type object. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/8.2.2.xml b/mcs/docs/ecma334/8.2.2.xml
new file mode 100644 (file)
index 0000000..707bc55
--- /dev/null
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+<clause number="8.2.2" title="Conversions" informative="true">
+  <paragraph>The predefined types also have predefined conversions. For instance, conversions exist between the predefined types <keyword>int</keyword> and <keyword>long</keyword>. C# differentiates between two kinds of conversions: implicit conversions and explicit conversions. Implicit conversions are supplied for conversions that can safely be performed without careful scrutiny. For instance, the conversion from <keyword>int</keyword> to <keyword>long</keyword> is an implicit conversion. This conversion always succeeds, and never results in a loss of information. The following example <code_example><![CDATA[
+using System;  
+class Test  
+{  
+   static void Main() {  
+      int intValue = 123;  
+      long longValue = intValue;  
+      Console.WriteLine("{0}, {1}", intValue, longValue);  
+   }  
+}  
+]]></code_example>implicitly converts an <keyword>int</keyword> to a <keyword>long</keyword>. </paragraph>
+  <paragraph>In contrast, explicit conversions are performed with a cast expression. The example <code_example><![CDATA[
+using System;  
+class Test  
+{  
+   static void Main() {  
+      long longValue = Int64.MaxValue;  
+      int intValue = (int) longValue;  
+      Console.WriteLine("(int) {0} = {1}", longValue, intValue);  
+   }  
+}  
+]]></code_example>uses an explicit conversion to convert a <keyword>long</keyword> to an <keyword>int</keyword>. The output is: <code_example><![CDATA[
+(int) 9223372036854775807 = -1  
+]]></code_example>because an overflow occurs. Cast expressions permit the use of both implicit and explicit conversions. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/8.2.3.xml b/mcs/docs/ecma334/8.2.3.xml
new file mode 100644 (file)
index 0000000..053c861
--- /dev/null
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<clause number="8.2.3" title="Array types" informative="true">
+  <paragraph>Arrays may be single-dimensional or multi-dimensional. Both &quot;rectangular&quot; and &quot;jagged&quot; arrays are supported. </paragraph>
+  <paragraph>Single-dimensional arrays are the most common type. The example <code_example><![CDATA[
+using System;  
+class Test  
+{  
+   static void Main() {  
+      int[] arr = new int[5];  
+      for (int i = 0; i < arr.Length; i++)  
+      arr[i] = i * i;  
+      for (int i = 0; i < arr.Length; i++)  
+      Console.WriteLine("arr[{0}] = {1}", i, arr[i]);  
+   }  
+}  
+]]></code_example>creates a single-dimensional array of <keyword>int</keyword> values, initializes the array elements, and then prints each of them out. The output produced is: <code_example><![CDATA[
+arr[0] = 0  
+arr[1] = 1  
+arr[2] = 4  
+arr[3] = 9  
+arr[4] = 16  
+]]></code_example></paragraph>
+  <paragraph>The type int[] used in the previous example is an array type. Array types are written using a  <non_terminal where="19.1">non-array-type</non_terminal> followed by one or more rank specifiers. The example <code_example><![CDATA[
+class Test  
+{  
+   static void Main() {  
+      int[] a1;    // single-dimensional array of int  
+      int[,] a2;    // 2-dimensional array of int  
+      int[,,] a3;   // 3-dimensional array of int  
+      int[][] j2;     // "jagged" array: array of (array of int)  
+      int[][][] j3;    // array of (array of (array of int))  
+   }  
+}  
+]]></code_example>shows a variety of local variable declarations that use array types with <keyword>int</keyword> as the element type. </paragraph>
+  <paragraph>Array types are reference types, and so the declaration of an array variable merely sets aside space for the reference to the array. Array instances are actually created via array initializers and array creation expressions. The example <code_example><![CDATA[
+class Test  
+{  
+   static void Main() {  
+      int[] a1 = new int[] {1, 2, 3};  
+      int[,] a2 = new int[,] {{1, 2, 3}, {4, 5, 6}};  
+      int[,,] a3 = new int[10, 20, 30];  
+      int[][] j2 = new int[3][];  
+      j2[0] = new int[] {1, 2, 3};  
+      j2[1] = new int[] {1, 2, 3, 4, 5, 6};  
+      j2[2] = new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9};  
+   }  
+}  
+]]></code_example>shows a variety of array creation expressions. The variables a1, a2 and a3 denote rectangular arrays, and the variable j2 denotes a jagged array. It should be no surprise that these terms are based on the shapes of the arrays. Rectangular arrays always have a rectangular shape. Given the length of each dimension of the array, its rectangular shape is clear. For example, the lengths of a3's three dimensions are 10, 20, and 30, respectively, and it is easy to see that this array contains 10*20*30 elements. </paragraph>
+  <paragraph>In contrast, the variable j2 denotes a &quot;jagged&quot; array, or an &quot;array of arrays&quot;. Specifically, j2 denotes an array of an array of <keyword>int</keyword>, or a single-dimensional array of type int[]. Each of these int[] variables can be initialized individually, and this allows the array to take on a jagged shape. The example gives each of the int[] arrays a different length. Specifically, the length of j2[0] is 3, the length of j2[1] is 6, and the length of j2[2] is 9. </paragraph>
+  <paragraph>
+    <note>[Note: In C++, an array declared as <keyword>int</keyword> x[3][5][7] would be considered a three dimensional rectangular array, while in C#, the declaration int[][][] declares a jagged array type. end note]</note>
+  </paragraph>
+  <paragraph>The element type and shape of an array-including whether it is jagged or rectangular, and the number of dimensions it has-are part of its type. On the other hand, the size of the array-as represented by the length of each of its dimensions-is not part of an array's type. This split is made clear in the language syntax, as the length of each dimension is specified in the array creation expression rather than in the array type. For instance the declaration <code_example><![CDATA[
+int[,,] a3 = new int[10, 20, 30];  
+]]></code_example>has an array type of int[,,] and an array creation expression of new int[10, 20, 30]. </paragraph>
+  <paragraph>For local variable and field declarations, a shorthand form is permitted so that it is not necessary to re-state the array type. For instance, the example <code_example><![CDATA[
+int[] a1 = new int[] {1, 2, 3};  
+]]></code_example>can be shortened to <code_example><![CDATA[
+int[] a1 = {1, 2, 3};  
+]]></code_example>without any change in program semantics. </paragraph>
+  <paragraph>The context in which an array initializer such as {1, 2, 3} is used determines the type of the array being initialized. The example <code_example><![CDATA[
+class Test  
+{  
+   static void Main() {  
+      short[] a = {1, 2, 3};  
+      int[] b = {1, 2, 3};  
+      long[] c = {1, 2, 3};  
+   }  
+}  
+]]></code_example>shows that the same array initializer syntax can be used for several different array types. Because context is required to determine the type of an array initializer, it is not possible to use an array initializer in an expression context without explicitly stating the type of the array. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/8.2.4.xml b/mcs/docs/ecma334/8.2.4.xml
new file mode 100644 (file)
index 0000000..cdfd4e6
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0"?>
+<clause number="8.2.4" title="Type system unification" informative="true">
+  <paragraph>C# provides a &quot;unified type system&quot;. All types-including value types-derive from the type object. It is possible to call object methods on any value, even values of &quot;primitive&quot; types such as <keyword>int</keyword>. The example <code_example><![CDATA[
+using System;  
+class Test  
+{  
+   static void Main() {  
+      Console.WriteLine(3.ToString());  
+   }  
+}  
+]]></code_example>calls the object-defined ToString method on an integer literal, resulting in the output &quot;3&quot;. </paragraph>
+  <paragraph>The example <code_example><![CDATA[
+class Test  
+{  
+   static void Main() {  
+      int i = 123;  
+      object o = i;   // boxing  
+      int j = (int) o;  // unboxing  
+   }  
+}  
+]]></code_example>is more interesting. An <keyword>int</keyword> value can be converted to object and back again to <keyword>int</keyword>. This example shows both boxing and unboxing. When a variable of a value type needs to be converted to a reference type, an object box is allocated to hold the value, and the value is copied into the box. Unboxing is just the opposite. When an object box is cast back to its original value type, the value is copied out of the box and into the appropriate storage location. </paragraph>
+  <paragraph>This type system unification provides value types with the benefits of object-ness without introducing unnecessary overhead. For programs that don't need <keyword>int</keyword> values to act like objects, <keyword>int</keyword> values are simply 32-bit values. For programs that need <keyword>int</keyword> values to behave like objects, this capability is available on demand. This ability to treat value types as objects bridges the gap between value types and reference types that exists in most languages. For example, a Stack class can provide Push and Pop methods that take and return object values. <code_example><![CDATA[
+public class Stack  
+{  
+   public object Pop() {...}  
+   public void Push(object o) {...}  
+}  
+]]></code_example></paragraph>
+  <paragraph>Because C# has a unified type system, the Stack class can be used with elements of any type, including value types like <keyword>int</keyword>. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/8.2.xml b/mcs/docs/ecma334/8.2.xml
new file mode 100644 (file)
index 0000000..a352a13
--- /dev/null
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<clause number="8.2" title="Types" informative="true">
+  <paragraph>C# supports two kinds of types: value types and reference types. Value types include simple types (e.g., <keyword>char</keyword>, <keyword>int</keyword>, and <keyword>float</keyword>), enum types, and struct types. Reference types include class types, interface types, delegate types, and array types. </paragraph>
+  <paragraph>Value types differ from reference types in that variables of the value types directly contain their data, whereas variables of the reference types store references to objects. With reference types, it is possible for two variables to reference the same object, and thus possible for operations on one variable to affect the object referenced by the other variable. With value types, the variables each have their own copy of the data, and it is not possible for operations on one to affect the other. </paragraph>
+  <paragraph>The example <code_example><![CDATA[
+using System;  
+class Class1  
+{  
+   public int Value = 0;  
+}  
+class Test  
+{  
+   static void Main() {  
+      int val1 = 0;  
+      int val2 = val1;  
+      val2 = 123;  
+      Class1 ref1 = new Class1();  
+      Class1 ref2 = ref1;  
+      ref2.Value = 123;  
+      Console.WriteLine("Values: {0}, {1}", val1, val2);  
+      Console.WriteLine("Refs: {0}, {1}", ref1.Value, ref2.Value);  
+   }  
+}  
+]]></code_example>shows this difference. The output produced is <code_example><![CDATA[
+Values: 0, 123  
+Refs: 123, 123  
+]]></code_example></paragraph>
+  <paragraph>The assignment to the local variable val1 does not impact the local variable val2 because both local variables are of a value type (the type <keyword>int</keyword>) and each local variable of a value type has its own storage. In contrast, the assignment ref2.Value = 123; affects the object that both ref1 and ref2 reference. </paragraph>
+  <paragraph>The lines <code_example><![CDATA[
+Console.WriteLine("Values: {0}, {1}", val1, val2);  
+Console.WriteLine("Refs: {0}, {1}", ref1.Value, ref2.Value);  
+]]></code_example>deserve further comment, as they demonstrate some of the string formatting behavior of Console.WriteLine, which, in fact, takes a variable number of arguments. The first argument is a string, which may contain numbered placeholders like {0} and {1}. Each placeholder refers to a trailing argument with {0} referring to the second argument, {1} referring to the third argument, and so on. Before the output is sent to the console, each placeholder is replaced with the formatted value of its corresponding argument. </paragraph>
+  <paragraph>Developers can define new value types through enum and struct declarations, and can define new reference types via class, interface, and delegate declarations. The example <code_example><![CDATA[
+using System;  
+public enum Color  
+{  
+   Red, Blue, Green  
+}  
+public struct Point   
+{   
+   public int x, y;   
+}  
+public interface IBase  
+{  
+   void F();  
+}  
+public interface IDerived: IBase  
+{  
+   void G();  
+}  
+public class A  
+{  
+   protected virtual void H() {  
+      Console.WriteLine("A.H");  
+   }  
+}  
+public class B: A, IDerived   
+{  
+   public void F() {  
+      Console.WriteLine("B.F, implementation of IDerived.F");  
+   }  
+   public void G() {  
+      Console.WriteLine("B.G, implementation of IDerived.G");  
+   }  
+   override protected void H() {  
+      Console.WriteLine("B.H, override of A.H");  
+   }  
+}  
+public delegate void EmptyDelegate();  
+]]></code_example>shows an example of each kind of type declaration. Later sections describe type declarations in detail. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/8.3.xml b/mcs/docs/ecma334/8.3.xml
new file mode 100644 (file)
index 0000000..200ce68
--- /dev/null
@@ -0,0 +1,140 @@
+<?xml version="1.0"?>
+<clause number="8.3" title="Variables and parameters" informative="true">
+  <paragraph>Variables represent storage locations. Every variable has a type that determines what values can be stored in the variable. Local variables are variables that are declared in methods, properties, or indexers. A local variable is defined by specifying a type name and a declarator that specifies the variable name and an optional initial value, as in: <code_example><![CDATA[
+int a;  
+int b = 1;  
+]]></code_example>but it is also possible for a local variable declaration to include multiple declarators. The declarations of a and b can be rewritten as: <code_example><![CDATA[
+int a, b = 1;  
+]]></code_example></paragraph>
+  <paragraph>A variable must be assigned before its value can be obtained. The example <code_example><![CDATA[
+class Test  
+{  
+   static void Main() {  
+      int a;  
+      int b = 1;  
+      int c = a + b; // error, a not yet assigned  
+      ...  
+   }  
+}  
+]]></code_example>results in a compile-time error because it attempts to use the variable a before it is assigned a value. The rules governing definite assignment are defined in <hyperlink>12.3</hyperlink>. </paragraph>
+  <paragraph>A field (<hyperlink>17.4</hyperlink>) is a variable that is associated with a class or struct, or an instance of a class or struct. A field declared with the static modifier defines a static variable, and a field declared without this modifier defines an instance variable. A static field is associated with a type, whereas an instance variable is associated with an instance. The example <code_example><![CDATA[
+using Personnel.Data;  
+class Employee  
+{  
+   private static DataSet ds;  
+   public string Name;  
+   public decimal Salary;  
+   ...  
+}  
+]]></code_example>shows an Employee class that has a private static variable and two public instance variables. </paragraph>
+  <paragraph>Formal parameter declarations also define variables. There are four kinds of parameters: value parameters, reference parameters, output parameters, and parameter arrays. </paragraph>
+  <paragraph>A value parameter is used for &quot;in&quot; parameter passing, in which the value of an argument is passed into a method, and modifications of the parameter do not impact the original argument. A value parameter refers to its own variable, one that is distinct from the corresponding argument. This variable is initialized by copying the value of the corresponding argument. The example <code_example><![CDATA[
+using System;  
+class Test {  
+   static void F(int p) {  
+      Console.WriteLine("p = {0}", p);  
+      p++;  
+   }  
+   static void Main() {  
+      int a = 1;  
+      Console.WriteLine("pre:  a = {0}", a);  
+      F(a);  
+      Console.WriteLine("post: a = {0}", a);  
+   }  
+}  
+]]></code_example>shows a method F that has a value parameter named p. The example produces the output: <code_example><![CDATA[
+pre:  a = 1  
+p = 1  
+post: a = 1  
+]]></code_example>even though the value parameter p is modified. </paragraph>
+  <paragraph>A reference parameter is used for &quot;by reference&quot; parameter passing, in which the parameter acts as an alias for a caller-provided argument. A reference parameter does not itself define a variable, but rather refers to the variable of the corresponding argument. Modifications of a reference parameter impact the corresponding argument. A reference parameter is declared with a ref modifier. The example <code_example><![CDATA[
+using System;  
+class Test {  
+   static void Swap(ref int a, ref int b) {  
+      int t = a;  
+      a = b;  
+      b = t;  
+   }  
+   static void Main() {  
+      int x = 1;  
+      int y = 2;  
+      
+      Console.WriteLine("pre:  x = {0}, y = {1}", x, y);  
+      Swap(ref x, ref y);  
+      Console.WriteLine("post: x = {0}, y = {1}", x, y);  
+   }  
+}  
+]]></code_example>shows a Swap method that has two reference parameters. The output produced is: <code_example><![CDATA[
+pre:  x = 1, y = 2  
+post: x = 2, y = 1  
+]]></code_example></paragraph>
+  <paragraph>The ref keyword must be used in both the declaration of the formal parameter and in uses of it. The use of ref at the call site calls special attention to the parameter, so that a developer reading the code will understand that the value of the argument could change as a result of the call. </paragraph>
+  <paragraph>An output parameter is similar to a reference parameter, except that the initial value of the caller-provided argument is unimportant. An output parameter is declared with an out modifier. The example <code_example><![CDATA[
+using System;  
+class Test {  
+   static void Divide(int a, int b, out int result, out int remainder) {  
+      result = a / b;  
+      remainder = a % b;  
+   }  
+   static void Main() {  
+      for (int i = 1; i < 10; i++)  
+      for (int j = 1; j < 10; j++) {  
+         int ans, r;  
+         Divide(i, j, out ans, out r);  
+         Console.WriteLine("{0} / {1} = {2}r{3}", i, j, ans, r);  
+      }  
+   }  
+}  
+]]></code_example>shows a Divide method that includes two output parameters-one for the result of the division and another for the remainder. </paragraph>
+  <paragraph>For value, reference, and output parameters, there is a one-to-one correspondence between caller-provided arguments and the parameters used to represent them. A parameter array enables a many-to-one relationship: many arguments can be represented by a single parameter array. In other words, parameter arrays enable variable length argument lists. </paragraph>
+  <paragraph>A parameter array is declared with a params modifier. There can be only one parameter array for a given method, and it must always be the last parameter specified. The type of a parameter array is always a single dimensional array type. A caller can either pass a single argument of this array type, or any number of arguments of the element type of this array type. For instance, the example <code_example><![CDATA[
+using System;  
+class Test  
+{  
+   static void F(params int[] args) {  
+      Console.WriteLine("# of arguments: {0}", args.Length);  
+      for (int i = 0; i < args.Length; i++)  
+      Console.WriteLine("\targs[{0}] = {1}", i, args[i]);  
+   }  
+   static void Main() {  
+      F();  
+      F(1);  
+      F(1, 2);  
+      F(1, 2, 3);  
+      F(new int[] {1, 2, 3, 4});  
+   }  
+}  
+]]></code_example>shows a method F that takes a variable number of <keyword>int</keyword> arguments, and several invocations of this method. The output is: <code_example><![CDATA[
+# of arguments: 0  
+# of arguments: 1  
+args[0] = 1  
+# of arguments: 2  
+args[0] = 1  
+args[1] = 2  
+# of arguments: 3  
+args[0] = 1  
+args[1] = 2  
+args[2] = 3  
+# of arguments: 4  
+args[0] = 1  
+args[1] = 2  
+args[2] = 3  
+args[3] = 4  
+]]></code_example></paragraph>
+  <paragraph>Most of the examples presented in this introduction use the WriteLine method of the Console class. The argument substitution behavior of this method, as exhibited in the example <code_example><![CDATA[
+int a = 1, b = 2;  
+Console.WriteLine("a = {0}, b = {1}", a, b);  
+]]></code_example>is accomplished using a parameter array. The WriteLine method provides several overloaded methods for the common cases in which a small number of arguments are passed, and one method that uses a parameter array. <code_example><![CDATA[
+namespace System  
+{  
+   public class Console  
+   {  
+      public static void WriteLine(string s) {...}  
+      public static void WriteLine(string s, object a) {...}  
+      public static void WriteLine(string s, object a, object b) {...}  
+      ...  
+      public static void WriteLine(string s, params object[] args) {...}  
+   }  
+}  
+]]></code_example></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/8.4.xml b/mcs/docs/ecma334/8.4.xml
new file mode 100644 (file)
index 0000000..87ee2fa
--- /dev/null
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<clause number="8.4" title="Automatic memory management" informative="true">
+  <paragraph>Manual memory management requires developers to manage the allocation and de-allocation of blocks of memory. Manual memory management can be both time-consuming and difficult. In C#, automatic memory management is provided so that developers are freed from this burdensome task. In the vast majority of cases, automatic memory management increases code quality and enhances developer productivity without negatively impacting either expressiveness or performance. </paragraph>
+  <paragraph>The example <code_example><![CDATA[
+using System;  
+public class Stack  
+{  
+   private Node first = null;  
+   public bool Empty {  
+      get {  
+         return (first == null);  
+      }  
+   }  
+   public object Pop() {  
+      if (first == null)   
+      throw new Exception("Can't Pop from an empty Stack.");  
+      else {  
+         object temp = first.Value;  
+         first = first.Next;  
+         return temp;  
+      }  
+   }  
+   public void Push(object o) {  
+      first = new Node(o, first);  
+   }  
+   class Node  
+   {  
+      public Node Next;  
+      public object Value;  
+      public Node(object value): this(value, null) {}  
+      public Node(object value, Node next) {  
+         Next = next;  
+         Value = value;  
+      }  
+   }  
+}  
+]]></code_example>shows a Stack class implemented as a linked list of Node instances. Node instances are created in the Push method and are garbage collected when no longer needed. A Node instance becomes eligible for garbage collection when it is no longer possible for any code to access it. For instance, when an item is removed from the Stack, the associated Node instance becomes eligible for garbage collection. </paragraph>
+  <paragraph>The example <code_example><![CDATA[
+class Test  
+{  
+   static void Main() {  
+      Stack s = new Stack();  
+      for (int i = 0; i < 10; i++)  
+      s.Push(i);  
+      s = null;  
+   }  
+}  
+]]></code_example>shows code that uses the Stack class. A Stack is created and initialized with 10 elements, and then assigned the value null. Once the variable s is assigned null, the Stack and the associated 10 Node instances become eligible for garbage collection. The garbage collector is permitted to clean up immediately, but is not required to do so. </paragraph>
+  <paragraph>The garbage collector underlying C# may work by moving objects around in memory, but this motion is invisible to most C# developers. For developers who are generally content with automatic memory management but sometimes need fine-grained control or that extra bit of performance, C# provides the ability to write &quot;unsafe&quot; code. Such code can deal directly with pointer types and object addresses, however, C# requires the programmer to fix objects to temporarily prevent the garbage collector from moving them. </paragraph>
+  <paragraph>This &quot;unsafe&quot; code feature is in fact a &quot;safe&quot; feature from the perspective of both developers and users. Unsafe code must be clearly marked in the code with the modifier unsafe, so developers can't possibly use unsafe language features accidentally, and the compiler and the execution engine work together to ensure that unsafe code cannot masquerade as safe code. These restrictions limit the use of unsafe code to situations in which the code is trusted. </paragraph>
+  <paragraph>The example <code_example><![CDATA[
+using System;  
+class Test  
+{  
+   static void WriteLocations(byte[] arr) {  
+      unsafe {  
+         fixed (byte* pArray = arr) {  
+            byte* pElem = pArray;  
+            for (int i = 0; i < arr.Length; i++) {  
+               byte value = *pElem;  
+               Console.WriteLine("arr[{0}] at 0x{1:X} is {2}",  
+               i, (uint)pElem, value);  
+               pElem++;  
+            }  
+         }  
+      }  
+   }  
+   static void Main() {  
+      byte[] arr = new byte[] {1, 2, 3, 4, 5};  
+      WriteLocations(arr);  
+   }  
+}  
+]]></code_example>shows an unsafe block in a method named WriteLocations that fixes an array instance and uses pointer manipulation to iterate over the elements. The index, value, and location of each array element are written to the console. One possible example of output is: <code_example><![CDATA[
+arr[0] at 0x8E0360 is 1  
+arr[1] at 0x8E0361 is 2  
+arr[2] at 0x8E0362 is 3  
+arr[3] at 0x8E0363 is 4  
+arr[4] at 0x8E0364 is 5  
+]]></code_example>but, of course, the exact memory locations may be different in different executions of the application. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/8.5.xml b/mcs/docs/ecma334/8.5.xml
new file mode 100644 (file)
index 0000000..c9fdf73
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<clause number="8.5" title="Expressions" informative="true">
+  <paragraph>C# includes unary operators, binary operators, and one ternary operator. The following table summarizes the operators, listing them in order of precedence from highest to lowest: <table_line>Section Category Operators </table_line>
+<table_line>14.5 Primary x.y f(x) a[x] x++  x--new </table_line>
+<table_line>typeof checked unchecked </table_line>
+<table_line>0 Unary +  -! ~ ++x --x (T)x </table_line>
+<table_line>14.7 Multiplicative * / % </table_line>
+<table_line>14.7 Additive +  </table_line>
+<table_line>-0 Shift &lt;&lt; &gt;&gt; </table_line>
+<table_line>14.9 Relational and </table_line>
+<table_line>type-testing </table_line>
+<table_line>&lt; &gt; &lt;= &gt;= is as </table_line>
+<table_line>14.9 Equality == != </table_line>
+<table_line>14.10 Logical AND &amp; </table_line>
+<table_line>14.10 Logical XOR ^ </table_line>
+<table_line>14.10 Logical OR | </table_line>
+<table_line>14.11 Conditional AND &amp;&amp; </table_line>
+<table_line>14.11 Conditional OR || </table_line>
+<table_line>14.12 Conditional ?: </table_line>
+<table_line>14.13 Assignment = *= /= %= += -= &lt;&lt;= &gt;&gt;= &amp;= ^= |= </table_line>
+When an expression contains multiple operators, the precedence of the operators controls the order in which the individual operators are evaluated. For example, the expression x + y * z is evaluated as x + (y * z) because the * operator has higher precedence than the + operator. </paragraph>
+  <paragraph>When an operand occurs between two operators with the same precedence, the associativity of the operators controls the order in which the operations are performed: <list><list_item> Except for the assignment operators, all binary operators are left-associative, meaning that operations are performed from left to right. For example, x + y + z is evaluated as (x + y) + z. </list_item><list_item> The assignment operators and the conditional operator (?:) are right-associative, meaning that operations are performed from right to left. For example, x = y = z is evaluated as x = (y = z). </list_item></list></paragraph>
+  <paragraph>Precedence and associativity can be controlled using parentheses. For example, x + y * z first multiplies y by z and then adds the result to x, but (x + y) * z first adds x and y and then multiplies the result by z. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/8.6.xml b/mcs/docs/ecma334/8.6.xml
new file mode 100644 (file)
index 0000000..c9c1cda
--- /dev/null
@@ -0,0 +1,145 @@
+<?xml version="1.0"?>
+<clause number="8.6" title="Statements" informative="true">
+  <paragraph>C# borrows most of its statements directly from C and C++, though there are some noteworthy additions and modifications. The table below lists the kinds of statements that can be used, and provides an example for each. <table_line>Statement Example </table_line>
+<table_line>Statement lists and block </table_line>
+<table_line>statements </table_line>
+<table_line>static <keyword>void</keyword> Main() <symbol>{</symbol> </table_line>
+<table_line>F(); </table_line>
+<table_line>G(); </table_line>
+<table_line><symbol>{</symbol></table_line>
+<table_line>H(); </table_line>
+<table_line>I(); </table_line>
+<table_line><symbol>}</symbol></table_line>
+<table_line><symbol>}</symbol></table_line>
+<table_line>Labeled statements and goto </table_line>
+<table_line>statements </table_line>
+<table_line>static <keyword>void</keyword> Main(string[] args) <symbol>{</symbol> </table_line>
+<table_line>if (args.Length == 0) </table_line>
+<table_line>goto done; </table_line>
+<table_line>Console.WriteLine(args.Length); </table_line>
+<table_line/>
+<table_line>done: </table_line>
+<table_line>Console.WriteLine(&quot;Done&quot;); </table_line>
+<table_line><symbol>}</symbol></table_line>
+<table_line>Local constant declarations static <keyword>void</keyword> Main() <symbol>{</symbol> </table_line>
+<table_line>const <keyword>float</keyword> pi = 3.14f; </table_line>
+<table_line>const <keyword>int</keyword> r = 123; </table_line>
+<table_line>Console.WriteLine(pi * r * r); </table_line>
+<table_line><symbol>}</symbol></table_line>
+<table_line>Local variable declarations static <keyword>void</keyword> Main() <symbol>{</symbol> </table_line>
+<table_line><keyword>int</keyword> a; </table_line>
+<table_line><keyword>int</keyword> b = 2, c = 3; </table_line>
+<table_line>a = 1; </table_line>
+<table_line>Console.WriteLine(a + b + c); </table_line>
+<table_line><symbol>}</symbol></table_line>
+<table_line>Expression statements static <keyword>int</keyword> F(<keyword>int</keyword> a, <keyword>int</keyword> b) <symbol>{</symbol> </table_line>
+<table_line>return a + b; </table_line>
+<table_line><symbol>}</symbol></table_line>
+<table_line>static <keyword>void</keyword> Main() <symbol>{</symbol> </table_line>
+<table_line>F(1, 2); // Expression statement </table_line>
+<table_line><symbol>}</symbol></table_line>
+<table_line>if statements static <keyword>void</keyword> Main(string[] args) <symbol>{</symbol> </table_line>
+<table_line>if (args.Length == 0) </table_line>
+<table_line>Console.WriteLine(&quot;No args&quot;); </table_line>
+<table_line>else </table_line>
+<table_line>Console.WriteLine(&quot;Args&quot;); </table_line>
+<table_line><symbol>}</symbol></table_line>
+<table_line>switch statements static <keyword>void</keyword> Main(string[] args) <symbol>{</symbol> </table_line>
+<table_line>switch (args.Length) <symbol>{</symbol> </table_line>
+<table_line>case 0: </table_line>
+<table_line>Console.WriteLine(&quot;No args&quot;); </table_line>
+<table_line>break; </table_line>
+<table_line>case 1: </table_line>
+<table_line>Console.WriteLine(&quot;One arg &quot;); </table_line>
+<table_line>break; </table_line>
+<table_line>default: </table_line>
+<table_line><keyword>int</keyword> n = args.Length; </table_line>
+<table_line>Console.WriteLine(&quot;{0} args&quot;, n); </table_line>
+<table_line>break; </table_line>
+<table_line><symbol>}</symbol></table_line>
+<table_line><symbol>}</symbol></table_line>
+<table_line>while statements static <keyword>void</keyword> Main(string[] args) <symbol>{</symbol> </table_line>
+<table_line><keyword>int</keyword> i = 0; </table_line>
+<table_line>while (i &lt; args.Length) <symbol>{</symbol> </table_line>
+<table_line>Console.WriteLine(args[i]); </table_line>
+<table_line>i++; </table_line>
+<table_line><symbol>}</symbol></table_line>
+<table_line><symbol>}</symbol></table_line>
+<table_line>do statements static <keyword>void</keyword> Main() <symbol>{</symbol> </table_line>
+<table_line>string s; </table_line>
+<table_line>do <symbol>{</symbol> s = Console.ReadLine(); <symbol>}</symbol> </table_line>
+<table_line>while (s != &quot;Exit&quot;); </table_line>
+<table_line><symbol>}</symbol></table_line>
+<table_line>for statements static <keyword>void</keyword> Main(string[] args) <symbol>{</symbol> </table_line>
+<table_line>for (<keyword>int</keyword> i = 0; i &lt; args.Length; i++) </table_line>
+<table_line>Console.WriteLine(args[i]); </table_line>
+<table_line><symbol>}</symbol></table_line>
+<table_line>foreach statements static <keyword>void</keyword> Main(string[] args) <symbol>{</symbol> </table_line>
+<table_line>foreach (string s in args) </table_line>
+<table_line>Console.WriteLine(s); </table_line>
+<table_line><symbol>}</symbol></table_line>
+<table_line>break statements static <keyword>void</keyword> Main(string[] args) <symbol>{</symbol> </table_line>
+<table_line><keyword>int</keyword> i = 0; </table_line>
+<table_line>while (true) <symbol>{</symbol> </table_line>
+<table_line>if (i == args.Length) </table_line>
+<table_line>break; </table_line>
+<table_line>Console.WriteLine(args[i++]); </table_line>
+<table_line><symbol>}</symbol></table_line>
+<table_line><symbol>}</symbol></table_line>
+<table_line>continue statements static <keyword>void</keyword> Main(string[] args) <symbol>{</symbol> </table_line>
+<table_line><keyword>int</keyword> i = 0; </table_line>
+<table_line>while (true) <symbol>{</symbol> </table_line>
+<table_line>Console.WriteLine(args[i++]); </table_line>
+<table_line>if (i &lt; args.Length) </table_line>
+<table_line>continue; </table_line>
+<table_line>break; </table_line>
+<table_line><symbol>}</symbol></table_line>
+<table_line><symbol>}</symbol></table_line>
+<table_line>return statements static <keyword>int</keyword> F(<keyword>int</keyword> a, <keyword>int</keyword> b) <symbol>{</symbol> </table_line>
+<table_line>return a + b; </table_line>
+<table_line><symbol>}</symbol></table_line>
+<table_line>static <keyword>void</keyword> Main() <symbol>{</symbol> </table_line>
+<table_line>Console.WriteLine(F(1, 2)); </table_line>
+<table_line>return; </table_line>
+<table_line><symbol>}</symbol></table_line>
+<table_line>throw statements and try </table_line>
+<table_line>statements </table_line>
+<table_line>static <keyword>int</keyword> F(<keyword>int</keyword> a, <keyword>int</keyword> b) <symbol>{</symbol> </table_line>
+<table_line>if (b == 0) </table_line>
+<table_line>throw new Exception(&quot;Divide by zero&quot;); </table_line>
+<table_line>return a / b; </table_line>
+<table_line><symbol>}</symbol></table_line>
+<table_line>static <keyword>void</keyword> Main() <symbol>{</symbol> </table_line>
+<table_line>try <symbol>{</symbol> </table_line>
+<table_line>Console.WriteLine(F(5, 0)); </table_line>
+<table_line><symbol>}</symbol></table_line>
+<table_line>catch(Exception e) <symbol>{</symbol> </table_line>
+<table_line>Console.WriteLine(&quot;Error&quot;); </table_line>
+<table_line><symbol>}</symbol></table_line>
+<table_line><symbol>}</symbol></table_line>
+<table_line>checked and unchecked </table_line>
+<table_line>statements </table_line>
+<table_line>static <keyword>void</keyword> Main() <symbol>{</symbol> </table_line>
+<table_line><keyword>int</keyword> x = Int32.MaxValue; </table_line>
+<table_line>Console.WriteLine(x + 1); // Overflow </table_line>
+<table_line>checked <symbol>{</symbol> </table_line>
+<table_line>Console.WriteLine(x + 1); // Exception </table_line>
+<table_line><symbol>}</symbol></table_line>
+<table_line>unchecked <symbol>{</symbol> </table_line>
+<table_line>Console.WriteLine(x + 1); // Overflow </table_line>
+<table_line><symbol>}</symbol></table_line>
+<table_line><symbol>}</symbol></table_line>
+<table_line/>
+<table_line>lock statements static <keyword>void</keyword> Main() <symbol>{</symbol> </table_line>
+<table_line>A a = ...; </table_line>
+<table_line>lock(a) <symbol>{</symbol> </table_line>
+<table_line>a.P = a.P + 1; </table_line>
+<table_line><symbol>}</symbol></table_line>
+<table_line><symbol>}</symbol></table_line>
+<table_line>using statements static <keyword>void</keyword> Main() <symbol>{</symbol> </table_line>
+<table_line>using (Resource r = new Resource()) <symbol>{</symbol> </table_line>
+<table_line>r.F(); </table_line>
+<table_line><symbol>}</symbol></table_line>
+<table_line><symbol>}</symbol></table_line>
+</paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/8.7.1.xml b/mcs/docs/ecma334/8.7.1.xml
new file mode 100644 (file)
index 0000000..8fed2f1
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<clause number="8.7.1" title="Constants" informative="true">
+  <paragraph>A constant is a class member that represents a constant value: a value that can be computed at compile-time. Constants are permitted to depend on other constants within the same program, as long as there are no circular dependencies. The rules governing constant expressions are defined in <hyperlink>14.15</hyperlink>. The example <code_example><![CDATA[
+class Constants  
+{  
+   public const int A = 1;  
+   public const int B = A + 1;  
+}  
+]]></code_example>shows a class named Constants that has two public constants. </paragraph>
+  <paragraph>Even though constants are considered static members, a constant declaration neither requires nor allows the modifier static. Constants can be accessed through the class, as in <code_example><![CDATA[
+using System;  
+class Test  
+{  
+   static void Main() {  
+      Console.WriteLine("{0}, {1}", Constants.A, Constants.B);  
+   }  
+}  
+]]></code_example>which prints out the values of Constants.A and Constants.B, respectively. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/8.7.10.xml b/mcs/docs/ecma334/8.7.10.xml
new file mode 100644 (file)
index 0000000..15ce99e
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+<clause number="8.7.10" title="Static constructors" informative="true">
+  <paragraph>A static constructor is a member that implements the actions required to initialize a class. Static constructors cannot have parameters, they cannot have accessibility modifiers, and they cannot be called explicitly. The static constructor for a class is called automatically. </paragraph>
+  <paragraph>The example <code_example><![CDATA[
+using Personnel.Data;  
+class Employee  
+{  
+   private static DataSet ds;  
+   static Employee() {  
+      ds = new DataSet(...);  
+   }  
+   public string Name;  
+   public decimal Salary;  
+   ...  
+}  
+]]></code_example>shows an Employee class with a static constructor that initializes a static field. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/8.7.11.xml b/mcs/docs/ecma334/8.7.11.xml
new file mode 100644 (file)
index 0000000..2bae35b
--- /dev/null
@@ -0,0 +1,70 @@
+<?xml version="1.0"?>
+<clause number="8.7.11" title="Inheritance" informative="true">
+  <paragraph>Classes support single inheritance, and the type object is the ultimate base class for all classes. </paragraph>
+  <paragraph>The classes shown in earlier examples all implicitly derive from object. The example <code_example><![CDATA[
+using System;  
+class A  
+{  
+   public void F() { Console.WriteLine("A.F"); }  
+}  
+]]></code_example>shows a class A that implicitly derives from object. The example <code_example><![CDATA[
+class B: A  
+{  
+   public void G() { Console.WriteLine("B.G"); }  
+}  
+class Test  
+{  
+   static void Main() {  
+      B b = new B();  
+      b.F();    // Inherited from A  
+      b.G();      // Introduced in B  
+      
+      A a = b;     // Treat a B as an A  
+      a.F();  
+   }  
+}  
+]]></code_example>shows a class B that derives from A. The class B inherits A's F method, and introduces a G method of its own. </paragraph>
+  <paragraph>Methods, properties, and indexers can be virtual, which means that their implementation can be overridden in derived classes. The example <code_example><![CDATA[
+using System;  
+class A  
+{  
+   public virtual void F() { Console.WriteLine("A.F"); }  
+}  
+class B: A  
+{  
+   public override void F() {   
+      base.F();  
+      Console.WriteLine("B.F");   
+   }  
+}  
+class Test  
+{  
+   static void Main() {  
+      B b = new B();  
+      b.F();  
+      A a = b;   
+      a.F();  
+   }  
+}   
+]]></code_example>shows a class A with a virtual method F, and a class B that overrides F. The overriding method in B contains a call, base.F(), which calls the overridden method in A. </paragraph>
+  <paragraph>A class can indicate that it is incomplete, and is intended only as a base class for other classes, by including the modifier abstract. Such a class is called an abstract class. An abstract class can specify abstract members-members that a non-abstract derived class must implement. The example <code_example><![CDATA[
+using System;  
+abstract class A  
+{  
+   public abstract void F();  
+}  
+class B: A  
+{  
+   public override void F() { Console.WriteLine("B.F"); }  
+}  
+class Test  
+{  
+   static void Main() {  
+      B b = new B();  
+      b.F();  
+      A a = b;  
+      a.F();  
+   }  
+}  
+]]></code_example>introduces an abstract method F in the abstract class A. The non-abstract class B provides an implementation for this method. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/8.7.2.xml b/mcs/docs/ecma334/8.7.2.xml
new file mode 100644 (file)
index 0000000..c25fbfc
--- /dev/null
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<clause number="8.7.2" title="Fields" informative="true">
+  <paragraph>A field is a member that represents a variable associated with an object or class. The example <code_example><![CDATA[
+class Color  
+{  
+   internal ushort redPart;  
+   internal ushort bluePart;  
+   internal ushort greenPart;  
+   public Color(ushort red, ushort blue, ushort green) {  
+      redPart = red;  
+      bluePart = blue;  
+      greenPart = green;  
+   }  
+   public static Color Red = new Color(0xFF, 0, 0);  
+   public static Color Blue = new Color(0, 0xFF, 0);  
+   public static Color Green = new Color(0, 0, 0xFF);  
+   public static Color White = new Color(0xFF, 0xFF, 0xFF);  
+}  
+]]></code_example>shows a Color class that has internal instance fields named redPart, bluePart, and greenPart, and static fields named Red, Blue, Green, and White The use of static fields in this manner is not ideal. The fields are initialized at some point before they are used, but after this initialization there is nothing to stop a client from changing them. Such a modification could cause unpredictable errors in other programs that use Color and assume that the values do not change. Readonly fields can be used to prevent such problems. Assignments to a readonly field can only occur as part of the declaration, or in an instance constructor or static constructor in the same class. A static readonly field can be assigned in a static constructor, and a non-static readonly field can be assigned in an instance constructor. Thus, the Color class can be enhanced by adding the modifier readonly to the static fields: <code_example><![CDATA[
+class Color  
+{  
+   internal ushort redPart;  
+   internal ushort bluePart;  
+   internal ushort greenPart;  
+   public Color(ushort red, ushort blue, ushort green) {  
+      redPart = red;  
+      bluePart = blue;  
+      greenPart = green;  
+   }  
+   public static readonly Color Red = new Color(0xFF, 0, 0);  
+   public static readonly Color Blue = new Color(0, 0xFF, 0);  
+   public static readonly Color Green = new Color(0, 0, 0xFF);  
+   public static readonly Color White = new Color(0xFF, 0xFF, 0xFF);  
+}  
+]]></code_example></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/8.7.3.xml b/mcs/docs/ecma334/8.7.3.xml
new file mode 100644 (file)
index 0000000..f07db6a
--- /dev/null
@@ -0,0 +1,68 @@
+<?xml version="1.0"?>
+<clause number="8.7.3" title="Methods" informative="true">
+  <paragraph>A method is a member that implements a computation or action that can be performed by an object or class. Methods have a (possibly empty) list of formal parameters, a return value (unless the method's <non_terminal where="17.5">return-type</non_terminal> is <keyword>void</keyword>), and are either static or non-static. Static methods are accessed through the class. Non-static methods, which are also called instance methods, are accessed through instances of the class. The example <code_example><![CDATA[
+using System;  
+public class Stack  
+{  
+   public static Stack Clone(Stack s) {...}  
+   public static Stack Flip(Stack s) {...}  
+   public object Pop() {...}  
+   public void Push(object o) {...}  
+   public override string ToString() {...}  
+   ...  
+}  
+class Test  
+{  
+   static void Main() {  
+      Stack s = new Stack();  
+      for (int i = 1; i < 10; i++)  
+      s.Push(i);  
+      Stack flipped = Stack.Flip(s);  
+      Stack cloned = Stack.Clone(s);  
+      Console.WriteLine("Original stack: " + s.ToString());  
+      Console.WriteLine("Flipped stack: " + flipped.ToString());  
+      Console.WriteLine("Cloned stack: " + cloned.ToString());  
+   }  
+}  
+]]></code_example>shows a Stack that has several static methods (Clone and Flip) and several instance methods (Pop, Push, and ToString). </paragraph>
+  <paragraph>Methods can be overloaded, which means that multiple methods may have the same name so long as they have unique signatures. The signature of a method consists of the name of the method and the number, modifiers, and types of its formal parameters. The signature of a method does not include the return type. The example <code_example><![CDATA[
+using System;  
+class Test  
+{  
+   static void F() {  
+      Console.WriteLine("F()");  
+   }  
+   static void F(object o) {  
+      Console.WriteLine("F(object)");  
+   }  
+   static void F(int value) {  
+      Console.WriteLine("F(int)");  
+   }  
+   static void F(ref int value) {  
+      Console.WriteLine("F(ref int)");  
+   }  
+   static void F(int a, int b) {  
+      Console.WriteLine("F(int, int)");  
+   }  
+   static void F(int[] values) {  
+      Console.WriteLine("F(int[])");  
+   }  
+   static void Main() {  
+      F();  
+      F(1);  
+      int i = 10;  
+      F(ref i);  
+      F((object)1);  
+      F(1, 2);  
+      F(new int[] {1, 2, 3});  
+   }  
+}  
+]]></code_example>shows a class with a number of methods called F. The output produced is <code_example><![CDATA[
+F()  
+F(int)  
+F(ref int)  
+F(object)  
+F(int, int)  
+F(int[])  
+]]></code_example></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/8.7.4.xml b/mcs/docs/ecma334/8.7.4.xml
new file mode 100644 (file)
index 0000000..0a200a0
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<clause number="8.7.4" title="Properties" informative="true">
+  <paragraph>A property is a member that provides access to a characteristic of an object or a class. Examples of properties include the length of a string, the size of a font, the caption of a window, the name of a customer, and so on. Properties are a natural extension of fields. Both are named members with associated types, and the syntax for accessing fields and properties is the same. However, unlike fields, properties do not denote storage locations. Instead, properties have accessors that specify the statements to be executed when their values are read or written. </paragraph>
+  <paragraph>Properties are defined with property declarations. The first part of a property declaration looks quite similar to a field declaration. The second part includes a get accessor and/or a set accessor. In the example below, the Button class defines a Caption property. <code_example><![CDATA[
+public class Button   
+{  
+   private string caption;  
+   public string Caption {  
+      get {  
+         return caption;  
+      }  
+      set {  
+         caption = value;  
+         Repaint();  
+      }  
+   }  
+}  
+]]></code_example></paragraph>
+  <paragraph>Properties that can be both read and written, such as Caption, include both get and set accessors. The get accessor is called when the property's value is read; the set accessor is called when the property's value is written. In a set accessor, the new value for the property is made available via an implicit parameter named value. </paragraph>
+  <paragraph>The declaration of properties is relatively straightforward, but the real value of properties is seen when they are used. For example, the Caption property can be read and written in the same way that fields can be read and written: <code_example><![CDATA[
+Button b = new Button();  
+b.Caption = "ABC";    // set; causes repaint  
+string s = b.Caption;  // get  
+b.Caption += "DEF";    // get & set; causes repaint  
+]]></code_example></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/8.7.5.xml b/mcs/docs/ecma334/8.7.5.xml
new file mode 100644 (file)
index 0000000..428076b
--- /dev/null
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<clause number="8.7.5" title="Events" informative="true">
+  <paragraph>An event is a member that enables an object or class to provide notifications. A class defines an event by providing an event declaration (which resembles a field declaration, though with an added event keyword) and an optional set of event accessors. The type of this declaration must be a delegate type. </paragraph>
+  <paragraph>An instance of a delegate type encapsulates one or more callable entities. For instance methods, a callable entity consists of an instance and a method on that instance. For static methods, a callable entity consists of just a method. Given a delegate instance and an appropriate set of arguments, one can invoke all of that delegate instance's methods with that set of arguments. </paragraph>
+  <paragraph>In the example <code_example><![CDATA[
+public delegate void EventHandler(object sender, System.EventArgs e);  
+public class Button   
+{  
+   public event EventHandler Click;  
+   public void Reset() {  
+      Click = null;  
+   }  
+}  
+]]></code_example>the Button class defines a Click event of type EventHandler. Inside the Button class, the Click member is exactly like a private field of type EventHandler. However, outside the Button class, the Click member can only be used on the left-hand side of the += and -= operators. The += operator adds a handler for the event, and the -= operator removes a handler for the event. The example <code_example><![CDATA[
+using System;  
+public class Form1   
+{  
+   public Form1() {  
+      // Add Button1_Click as an event handler for Button1's Click event  
+      Button1.Click += new EventHandler(Button1_Click);  
+   }  
+   Button Button1 = new Button();  
+   void Button1_Click(object sender, EventArgs e) {  
+      Console.WriteLine("Button1 was clicked!");  
+   }  
+   public void Disconnect() {  
+      Button1.Click -= new EventHandler(Button1_Click);  
+   }  
+}  
+]]></code_example>shows a Form1 class that adds Button1_Click as an event handler for Button1's Click event. In the Disconnect method, that event handler is removed. </paragraph>
+  <paragraph>For a simple event declaration such as <code_example><![CDATA[
+public event EventHandler Click;  
+]]></code_example>the compiler automatically provides the implementation underlying the += and -= operators. </paragraph>
+  <paragraph>An implementer who wants more control can get it by explicitly providing add and remove accessors. For example, the Button class could be rewritten as follows: <code_example><![CDATA[
+public class Button   
+{  
+   private EventHandler handler;  
+   public event EventHandler Click {  
+      add { handler += value; }  
+      
+      remove { handler -= value; }  
+   }  
+}  
+]]></code_example></paragraph>
+  <paragraph>This change has no effect on client code, but allows the Button class more implementation flexibility. For example, the event handler for Click need not be represented by a field. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/8.7.6.xml b/mcs/docs/ecma334/8.7.6.xml
new file mode 100644 (file)
index 0000000..8b06297
--- /dev/null
@@ -0,0 +1,58 @@
+<?xml version="1.0"?>
+<clause number="8.7.6" title="Operators" informative="true">
+  <paragraph>An operator is a member that defines the meaning of an expression operator that can be applied to instances of the class. There are three kinds of operators that can be defined: unary operators, binary operators, and conversion operators. </paragraph>
+  <paragraph>The following example defines a Digit type that represents <keyword>decimal</keyword> digits-integral values between 0 and 9. <code_example><![CDATA[
+using System;  
+public struct Digit  
+{  
+   byte value;  
+   public Digit(byte value) {  
+      if (value < 0 || value > 9) throw new ArgumentException();  
+      this.value = value;  
+   }  
+   public Digit(int value): this((byte) value) {}  
+   public static implicit operator byte(Digit d) {  
+      return d.value;  
+   }  
+   public static explicit operator Digit(byte b) {  
+      return new Digit(b);  
+   }  
+   public static Digit operator+(Digit a, Digit b) {  
+      return new Digit(a.value + b.value);  
+   }  
+   public static Digit operator-(Digit a, Digit b) {  
+      return new Digit(a.value - b.value);  
+   }  
+   public static bool operator==(Digit a, Digit b) {  
+      return a.value == b.value;  
+   }  
+   public static bool operator!=(Digit a, Digit b) {  
+      return a.value != b.value;  
+   }  
+   public override bool Equals(object value) {  
+      if (value == null) return false;  
+      if (GetType() == value.GetType()) return this == (Digit)value;  
+   return false;  }  
+   public override int GetHashCode() {  
+      return value.GetHashCode();  
+   }  
+   public override string ToString() {  
+      return value.ToString();  
+   }  
+}  
+class Test  
+{  
+   static void Main() {  
+      Digit a = (Digit) 5;  
+      Digit b = (Digit) 3;  
+      Digit plus = a + b;  
+      Digit minus = a - b;  
+      bool equals = (a == b);  
+      Console.WriteLine("{0} + {1} = {2}", a, b, plus);  
+      Console.WriteLine("{0} - {1} = {2}", a, b, minus);  
+      Console.WriteLine("{0} == {1} = {2}", a, b, equals);  
+   }  
+}  
+]]></code_example></paragraph>
+  <paragraph>The Digit type defines the following operators: <list><list_item> An implicit conversion operator from Digit to <keyword>byte</keyword>. </list_item><list_item> An explicit conversion operator from <keyword>byte</keyword> to Digit. </list_item><list_item> An addition operator that adds two Digit values and returns a Digit value. </list_item><list_item> A subtraction operator that subtracts one Digit value from another, and returns a Digit value. </list_item><list_item> The equality (==) and inequality (!=) operators, which compare two Digit values. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/8.7.7.xml b/mcs/docs/ecma334/8.7.7.xml
new file mode 100644 (file)
index 0000000..d3f1949
--- /dev/null
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<clause number="8.7.7" title="Indexers" informative="true">
+  <paragraph>An indexer is a member that enables an object to be indexed in the same way as an array. Whereas properties enable field-like access, indexers enable array-like access. </paragraph>
+  <paragraph>As an example, consider the Stack class presented earlier. The designer of this class might want to expose array-like access so that it is possible to inspect or alter the items on the stack without performing unnecessary Push and Pop operations. That is, class Stack is implemented as a linked list, but it also provides the convenience of array access. </paragraph>
+  <paragraph>Indexer declarations are similar to property declarations, with the main differences being that indexers are nameless (the &quot;name&quot; used in the declaration is this, since this is being indexed) and that indexers include indexing parameters. The indexing parameters are provided between square brackets. The example <code_example><![CDATA[
+using System;  
+public class Stack  
+{  
+   private Node GetNode(int index) {  
+      Node temp = first;   
+      while (index > 0) {  
+         temp = temp.Next;  
+         index--;  
+      }  
+      return temp;  
+   }  
+   public object this[int index] {  
+      get {  
+         if (!ValidIndex(index))  
+         throw new Exception("Index out of range.");  
+         else  
+         return GetNode(index).Value;  
+      }  
+      set {  
+         if (!ValidIndex(index))  
+         throw new Exception("Index out of range.");  
+         else  
+         GetNode(index).Value = value;  
+      }  
+   }  
+   ...  
+}  
+class Test  
+{  
+   static void Main() {  
+      Stack s = new Stack();  
+      s.Push(1);  
+      s.Push(2);  
+      s.Push(3);  
+      s[0] = 33;  // Changes the top item from 3 to 33  
+      s[1] = 22;  // Changes the middle item from 2 to 22  
+      s[2] = 11;  // Changes the bottom item from 1 to 11  
+   }  
+}  
+]]></code_example>shows an indexer for the Stack class. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/8.7.8.xml b/mcs/docs/ecma334/8.7.8.xml
new file mode 100644 (file)
index 0000000..b5a8817
--- /dev/null
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+<clause number="8.7.8" title="Instance constructors" informative="true">
+  <paragraph>An instance constructor is a member that implements the actions required to initialize an instance of a class. </paragraph>
+  <paragraph>The example <code_example><![CDATA[
+using System;  
+class Point  
+{  
+   public double x, y;  
+   public Point() {  
+      this.x = 0;  
+      this.y = 0;  
+   }  
+   public Point(double x, double y) {  
+      this.x = x;  
+      this.y = y;  
+   }  
+   public static double Distance(Point a, Point b) {  
+      double xdiff = a.x - b.x;  
+      double ydiff = a.y - b.y;  
+      return Math.Sqrt(xdiff * xdiff + ydiff * ydiff);  
+   }  
+   public override string ToString() {  
+      return string.Format("({0}, {1})", x, y);  
+   }  
+}  
+class Test  
+{  
+   static void Main() {  
+      Point a = new Point();  
+      Point b = new Point(3, 4);  
+      double d = Point.Distance(a, b);  
+      Console.WriteLine("Distance from {0} to {1} is {2}", a, b, d);  
+   }  
+}  
+]]></code_example>shows a Point class that provides two public instance constructors, one of which takes no arguments, while the other takes two <keyword>double</keyword> arguments. </paragraph>
+  <paragraph>If no instance constructor is supplied for a class, then an empty one with no parameters is automatically provided. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/8.7.9.xml b/mcs/docs/ecma334/8.7.9.xml
new file mode 100644 (file)
index 0000000..0d62edc
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<clause number="8.7.9" title="Destructors" informative="true">
+  <paragraph>A destructor is a member that implements the actions required to destruct an instance of a class. Destructors cannot have parameters, they cannot have accessibility modifiers, and they cannot be called explicitly. The destructor for an instance is called automatically during garbage collection. </paragraph>
+  <paragraph>The example <code_example><![CDATA[
+using System;  
+class Point  
+{  
+   public double x, y;  
+   public Point(double x, double y) {  
+      this.x = x;  
+      this.y = y;  
+   }  
+   ~Point() {  
+      Console.WriteLine("Destructed {0}", this);  
+   }  
+   public override string ToString() {  
+      return string.Format("({0}, {1})", x, y);  
+   }  
+}  
+]]></code_example>shows a Point class with a destructor. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/8.7.xml b/mcs/docs/ecma334/8.7.xml
new file mode 100644 (file)
index 0000000..bed06dc
--- /dev/null
@@ -0,0 +1,87 @@
+<?xml version="1.0"?>
+<clause number="8.7" title="Classes" informative="true">
+  <paragraph>Class declarations define new reference types. A class can inherit from another class, and can implement interfaces. </paragraph>
+  <paragraph>Class members can include constants, fields, methods, properties, events, indexers, operators, instance constructors, destructors, static constructors, and nested type declarations. Each member has an associated accessibility (<hyperlink>10.5</hyperlink>), which controls the regions of program text that are able to access the member. There are five possible forms of accessibility. These are summarized in the table below. <table_line>Form Intuitive meaning </table_line>
+<table_line>public Access not limited </table_line>
+<table_line>protected Access limited to the containing class or types derived from the containing class </table_line>
+<table_line>internal Access limited to this program </table_line>
+<table_line>protected </table_line>
+<table_line>internal </table_line>
+<table_line>Access limited to this program or types derived from the containing class </table_line>
+<table_line>private Access limited to the containing type </table_line>
+</paragraph>
+  <paragraph>The example <code_example><![CDATA[
+using System;  
+class MyClass  
+{  
+   public MyClass() {  
+      Console.WriteLine("Instance constructor");  
+   }  
+   public MyClass(int value) {  
+      MyField = value;  
+      Console.WriteLine("Instance constructor");  
+   }  
+   ~MyClass() {  
+      Console.WriteLine("Destructor");  
+   }  
+   public const int MyConst = 12;  
+   public int MyField = 34;  
+   public void MyMethod(){  
+      Console.WriteLine("MyClass.MyMethod");  
+   }  
+   public int MyProperty {  
+      get {  
+         return MyField;  
+      }  
+      set {  
+         MyField = value;  
+      }  
+   }  
+   public int this[int index] {  
+      get {  
+         return 0;  
+      }  
+      set {  
+         Console.WriteLine("this[{0}] = {1}", index, value);  
+      }  
+   }  
+   public event EventHandler MyEvent;  
+   public static MyClass operator+(MyClass a, MyClass b) {  
+      return new MyClass(a.MyField + b.MyField);  
+   }  
+   internal class MyNestedClass  
+   {}  
+}  
+]]></code_example>shows a class that contains each kind of member. The example <code_example><![CDATA[
+class Test  
+{  
+   static void Main() {  
+      // Instance constructor usage  
+      MyClass a = new MyClass();  
+      MyClass b = new MyClass(123);  
+      // Constant usage  
+      Console.WriteLine("MyConst = {0}", MyClass.MyConst);  
+      // Field usage  
+      a.MyField++;  
+      Console.WriteLine("a.MyField = {0}", a.MyField);  
+      // Method usage  
+      a.MyMethod();  
+      // Property usage  
+      a.MyProperty++;  
+      Console.WriteLine("a.MyProperty = {0}", a.MyProperty);  
+      // Indexer usage  
+      a[3] = a[1] = a[2];  
+      Console.WriteLine("a[3] = {0}", a[3]);  
+      // Event usage  
+      a.MyEvent += new EventHandler(MyHandler);  
+      // Overloaded operator usage  
+      MyClass c = a + b;  
+   }  
+   static void MyHandler(object sender, EventArgs e) {  
+      Console.WriteLine("Test.MyHandler");  
+   }  
+   internal class MyNestedClass  
+   {}  
+}  
+]]></code_example>shows uses of these members. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/8.8.xml b/mcs/docs/ecma334/8.8.xml
new file mode 100644 (file)
index 0000000..8f61f57
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<clause number="8.8" title="Structs" informative="true">
+  <paragraph>The list of similarities between classes and structs is long-structs can implement interfaces, and can have the same kinds of members as classes. Structs differ from classes in several important ways, however: structs are value types rather than reference types, and inheritance is not supported for structs. Struct values are stored &quot;on the stack&quot; or &quot;in-line&quot;. Careful programmers can sometimes enhance performance through judicious use of structs. </paragraph>
+  <paragraph>For example, the use of a struct rather than a class for a Point can make a large difference in the number of memory allocations performed at run time. The program below creates and initializes an array of 100 points. With Point implemented as a class, 101 separate objects are instantiated-one for the array and one each for the 100 elements. <code_example><![CDATA[
+class Point  
+{  
+   public int x, y;  
+   public Point(int x, int y) {  
+      this.x = x;  
+      this.y = y;  
+   }  
+}  
+class Test  
+{  
+   static void Main() {  
+      Point[] points = new Point[100];  
+      for (int i = 0; i < 100; i++)  
+      points[i] = new Point(i, i*i);  
+   }  
+}  
+]]></code_example></paragraph>
+  <paragraph>If Point is instead implemented as a struct, as in <code_example><![CDATA[
+struct Point  
+{  
+   public int x, y;  
+   public Point(int x, int y) {  
+      this.x = x;  
+      this.y = y;  
+   }  
+}  
+]]></code_example>only one object is instantiated-the one for the array. The Point instances are allocated in-line within the array. This optimization can be misused. Using structs instead of classes can also make an application run slower or take up more memory, as passing a struct instance by value causes a copy of that struct to be created. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/8.9.xml b/mcs/docs/ecma334/8.9.xml
new file mode 100644 (file)
index 0000000..08234cb
--- /dev/null
@@ -0,0 +1,58 @@
+<?xml version="1.0"?>
+<clause number="8.9" title="Interfaces" informative="true">
+  <paragraph>An interface defines a contract. A class or struct that implements an interface must adhere to its contract. Interfaces can contain methods, properties, events, and indexers as members. </paragraph>
+  <paragraph>The example <code_example><![CDATA[
+interface IExample  
+{  
+   string this[int index] { get; set; }  
+   event EventHandler E;  
+   void F(int value);  
+   string P { get; set; }  
+}  
+public delegate void EventHandler(object sender, EventArgs e);  
+]]></code_example>shows an interface that contains an indexer, an event E, a method F, and a property P. </paragraph>
+  <paragraph>Interfaces may employ multiple inheritance. In the example <code_example><![CDATA[
+interface IControl  
+{  
+   void Paint();  
+}  
+interface ITextBox: IControl  
+{  
+   void SetText(string text);  
+}  
+interface IListBox: IControl  
+{  
+   void SetItems(string[] items);  
+}  
+interface IComboBox: ITextBox, IListBox {}  
+]]></code_example>the interface IComboBox inherits from both ITextBox and IListBox. </paragraph>
+  <paragraph>Classes and structs can implement multiple interfaces. In the example <code_example><![CDATA[
+interface IDataBound  
+{  
+   void Bind(Binder b);  
+}  
+public class EditBox: Control, IControl, IDataBound  
+{  
+   public void Paint() {...}  
+   public void Bind(Binder b) {...}  
+}   
+]]></code_example>the class EditBox derives from the class Control and implements both IControl and IDataBound. </paragraph>
+  <paragraph>In the previous example, the Paint method from the IControl interface and the Bind method from IDataBound interface are implemented using public members on the EditBox class. C# provides an alternative way of implementing these methods that allows the implementing class to avoid having these members be public. Interface members can be implemented using a qualified name. For example, the EditBox class could instead be implemented by providing IControl.Paint and IDataBound.Bind methods. <code_example><![CDATA[
+public class EditBox: IControl, IDataBound  
+{  
+   void IControl.Paint() {...}  
+   void IDataBound.Bind(Binder b) {...}  
+}  
+]]></code_example></paragraph>
+  <paragraph>Interface members implemented in this way are called explicit interface members because each member explicitly designates the interface member being implemented. Explicit interface members can only be called via the interface. For example, the EditBox's implementation of the Paint method can be called only by casting to the IControl interface. <code_example><![CDATA[
+class Test  
+{  
+   static void Main() {  
+      EditBox editbox = new EditBox();  
+      editbox.Paint();  // error: no such method  
+      IControl control = editbox;  
+      control.Paint();  // calls EditBox's Paint implementation  
+   }  
+}  
+]]></code_example></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/8.xml b/mcs/docs/ecma334/8.xml
new file mode 100644 (file)
index 0000000..e3dae49
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="8" title="Language Overview" informative="true">
+    <paragraph>This clause is informative. </paragraph>
+    <paragraph>C# (pronounced &quot;C Sharp&quot;) is a simple, modern, object oriented, and type-safe programming language. It will immediately be familiar to C and C++ programmers. C# combines the high productivity of Rapid Application Development (RAD) languages and the raw power of C++. </paragraph>
+    <paragraph>The rest of this chapter describes the essential features of the language. While later chapters describe rules and exceptions in a detail-oriented and sometimes mathematical manner, this chapter strives for clarity and brevity at the expense of completeness. The intent is to provide the reader with an introduction to the language that will facilitate the writing of early programs and the reading of later chapters. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/9.1.xml b/mcs/docs/ecma334/9.1.xml
new file mode 100644 (file)
index 0000000..df5789a
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<clause number="9.1" title="Programs">
+  <paragraph>A C# program consists of one or more source files, known formally as compilation units (<hyperlink>16.1</hyperlink>). A source file is an ordered sequence of Unicode characters. Source files typically have a one-to-one correspondence with files in a file system, but this correspondence is not required. </paragraph>
+  <paragraph>Conceptually speaking, a program is compiled using three steps: </paragraph>
+  <paragraph>1 Transformation, which converts a file from a particular character repertoire and encoding scheme into a sequence of Unicode characters. </paragraph>
+  <paragraph>2 Lexical analysis, which translates a stream of Unicode input characters into a stream of tokens. </paragraph>
+  <paragraph>3 Syntactic analysis, which translates the stream of tokens into executable code. </paragraph>
+  <paragraph>Conforming implementations must accept Unicode source files encoded with the UTF-8 encoding form (as defined by the Unicode standard), and transform them into a sequence of Unicode characters. Implementations may choose to accept and transform additional character encoding schemes (such as  UTF-16, UTF-32, or non-Unicode character mappings). </paragraph>
+  <paragraph>
+    <note>[Note: It is beyond the scope of this standard to define how a file using a character representation other than Unicode might be transformed into a sequence of Unicode characters. During such transformation, however, it is recommended that the usual line-separating character (or sequence) in the other character set be translated to the two-character sequence consisting of the Unicode carriage-return character followed by Unicode line-feed character. For the most part this transformation will have no visible effects; however, it will affect the interpretation of verbatim string literal tokens (<hyperlink>9.4.4.5</hyperlink>). The purpose of this recommendation is to allow a verbatim string literal to produce the same character sequence when its source file is moved between systems that support differing non-Unicode character sets, in particular, those using differing character sequences for line-separation. end note]</note>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/9.2.1.xml b/mcs/docs/ecma334/9.2.1.xml
new file mode 100644 (file)
index 0000000..8121c58
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="9.2.1" title="Lexical grammar">
+  <paragraph>The lexical grammar of C# is presented in <hyperlink>9.3</hyperlink>, <hyperlink>9.4</hyperlink>, and <hyperlink>9.5</hyperlink>. The terminal symbols of the lexical grammar are the characters of the Unicode character set, and the lexical grammar specifies how characters are combined to form tokens (<hyperlink>9.4</hyperlink>), white space (<hyperlink>9.3.3</hyperlink>), comments (<hyperlink>9.3.2</hyperlink>), and pre-processing directives (<hyperlink>9.5</hyperlink>). </paragraph>
+  <paragraph>Every source file in a C# program must conform to the input production of the lexical grammar (<hyperlink>9.3</hyperlink>). </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/9.2.2.xml b/mcs/docs/ecma334/9.2.2.xml
new file mode 100644 (file)
index 0000000..e6a3c7a
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="9.2.2" title="Syntactic grammar">
+  <paragraph>The syntactic grammar of C# is presented in the chapters and appendices that follow this chapter. The terminal symbols of the syntactic grammar are the tokens defined by the lexical grammar, and the syntactic grammar specifies how tokens are combined to form C# programs. </paragraph>
+  <paragraph>Every source file in a C# program must conform to the <non_terminal where="16.1">compilation-unit</non_terminal> production (<hyperlink>16.1</hyperlink>) of the syntactic grammar. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/9.2.xml b/mcs/docs/ecma334/9.2.xml
new file mode 100644 (file)
index 0000000..0a7e144
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="9.2" title="Grammars">
+  <paragraph>This specification presents the syntax of the C# programming language using two grammars. The lexical grammar (<hyperlink>9.2.1</hyperlink>) defines how Unicode characters are combined to form line terminators, white space, comments, tokens, and pre-processing directives. The syntactic grammar (<hyperlink>9.2.2</hyperlink>) defines how the tokens resulting from the lexical grammar are combined to form C# programs. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/9.3.1.xml b/mcs/docs/ecma334/9.3.1.xml
new file mode 100644 (file)
index 0000000..187d2de
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="9.3.1" title="Line terminators">
+  <paragraph>Line terminators divide the characters of a C# source file into lines. <grammar_production><name><non_terminal where="9.3.1">new-line</non_terminal></name> :: <rhs>Carriage return character (U+000D) </rhs><rhs>Line feed character (U+000A) </rhs><rhs>Carriage return character (U+000D) followed by line feed character (U+000A) </rhs><rhs>Line separator character (U+2028) </rhs><rhs>Paragraph separator character (U+2029) </rhs></grammar_production></paragraph>
+  <paragraph>For compatibility with source code editing tools that add end-of-file markers, and to enable a source file to be viewed as a sequence of properly terminated lines, the following transformations are applied, in order, to every source file in a C# program: <list><list_item> If the last character of the source file is a Control-Z character (U+001A), this character is deleted. </list_item><list_item> A carriage-return character (U+000D) is added to the end of the source file if that source file is  non-empty and if the last character of the source file is not a carriage return (U+000D), a line feed (U+000A), a line separator (U+2028), or a paragraph separator (U+2029). </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/9.3.2.xml b/mcs/docs/ecma334/9.3.2.xml
new file mode 100644 (file)
index 0000000..4f21825
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<clause number="9.3.2" title="Comments">
+  <paragraph>Two forms of comments are supported: delimited comments and single-line comments. </paragraph>
+  <paragraph>A delimited comment begins with the characters /* and ends with the characters */. Delimited comments can occupy a portion of a line, a single line, or multiple lines. <example>[Example: The example <code_example><![CDATA[
+/* Hello, world program  
+This program writes "hello, world" to the console  
+*/  
+class Hello  
+{  
+   static void Main() {  
+      System.Console.WriteLine("hello, world");  
+   }  
+}  
+]]></code_example>includes a delimited comment. end example]</example> </paragraph>
+  <paragraph>A single-line comment begins with the characters // and extends to the end of the line. <example>[Example: The example <code_example><![CDATA[
+// Hello, world program  
+//   This program writes "hello, world" to the console  
+//  
+class Hello // any name will do for this class  
+{  
+   static void Main() { // this method must be named "Main"  
+      System.Console.WriteLine("hello, world");  
+   }  
+}  
+]]></code_example>shows several single-line comments. end example]</example> <grammar_production><name>comment</name> :: <rhs><non_terminal where="9.3.2">single-line-comment</non_terminal></rhs><rhs><non_terminal where="9.3.2">delimited-comment</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.3.2">single-line-comment</non_terminal></name> :: <rhs><terminal>//</terminal><non_terminal where="9.3.2">input-characters</non_terminal><opt/></rhs></grammar_production><grammar_production><name><non_terminal where="9.3.2">input-character</non_terminal>s</name> :: <rhs><non_terminal where="9.3.2">input-character</non_terminal></rhs><rhs><non_terminal where="9.3.2">input-characters</non_terminal><non_terminal where="9.3.2">input-character</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.3.2">input-character</non_terminal></name> :: <rhs>Any Unicode character except a <non_terminal where="9.3.2">new-line-character</non_terminal> </rhs></grammar_production><grammar_production><name><non_terminal where="9.3.2">new-line-character</non_terminal></name> :: <rhs>Carriage return character (U+000D) </rhs><rhs>Line feed character (U+000A) </rhs><rhs>Line separator character (U+2028) </rhs><rhs>Paragraph separator character (U+2029) </rhs></grammar_production><grammar_production><name><non_terminal where="9.3.2">delimited-comment</non_terminal></name> :: <rhs><terminal>/*</terminal><non_terminal where="9.3.2">delimited-comment-characters</non_terminal><opt/><terminal>*/</terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.3.2">delimited-comment-character</non_terminal>s</name> :: <rhs><non_terminal where="9.3.2">delimited-comment-character</non_terminal></rhs><rhs><non_terminal where="9.3.2">delimited-comment-characters</non_terminal><non_terminal where="9.3.2">delimited-comment-character</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.3.2">delimited-comment-character</non_terminal></name> :: <rhs><non_terminal where="9.3.2">not-asterisk</non_terminal></rhs><rhs><terminal>*</terminal><non_terminal where="9.3.2">not-slash</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.3.2">not-asterisk</non_terminal></name> :: <rhs>Any Unicode character except * </rhs></grammar_production><grammar_production><name><non_terminal where="9.3.2">not-slash</non_terminal></name> :: <rhs>Any Unicode character except / </rhs></grammar_production></paragraph>
+  <paragraph>Comments do not nest. The character sequences /* and */ have no special meaning within a single-line comment, and the character sequences // and /* have no special meaning within a delimited comment. </paragraph>
+  <paragraph>Comments are not processed within character and string literals. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/9.3.3.xml b/mcs/docs/ecma334/9.3.3.xml
new file mode 100644 (file)
index 0000000..1d42c9d
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="9.3.3" title="White space">
+  <paragraph>White space is defined as any character with Unicode class Zs (which includes the space character) as well as the horizontal tab character, the vertical tab character, and the form feed character. <grammar_production><name>whitespace</name> :: <rhs>Any character with Unicode class Zs </rhs><rhs>Horizontal tab character (U+0009) </rhs><rhs>Vertical tab character (U+000B) </rhs><rhs>Form feed character (U+000C) </rhs></grammar_production></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/9.3.xml b/mcs/docs/ecma334/9.3.xml
new file mode 100644 (file)
index 0000000..397898f
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<clause number="9.3" title="Lexical analysis">
+  <paragraph>The input production defines the lexical structure of a C# source file. Each source file in a C# program must conform to this lexical grammar production. <grammar_production><name>input</name> :: <rhs><non_terminal where="9.3">input-section</non_terminal><opt/></rhs></grammar_production><grammar_production><name><non_terminal where="9.3">input-section</non_terminal></name> :: <rhs><non_terminal where="9.3">input-section-part</non_terminal></rhs><rhs><non_terminal where="9.3">input-section</non_terminal><non_terminal where="9.3">input-section-part</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.3">input-section-part</non_terminal></name> :: <rhs><non_terminal where="9.3">input-elements</non_terminal><opt/><non_terminal where="9.3.1">new-line</non_terminal></rhs><rhs><non_terminal where="9.5">pp-directive</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.3">input-element</non_terminal>s</name> :: <rhs><non_terminal where="9.3">input-element</non_terminal></rhs><rhs><non_terminal where="9.3">input-elements</non_terminal><non_terminal where="9.3">input-element</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.3">input-element</non_terminal></name> :: <rhs><non_terminal where="9.3.3">whitespace</non_terminal></rhs><rhs><non_terminal where="9.3.2">comment</non_terminal></rhs><rhs><non_terminal where="9.4">token</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>Five basic elements make up the lexical structure of a C# source file: Line terminators (<hyperlink>9.3.1</hyperlink>), white space (<hyperlink>9.3.3</hyperlink>), comments (<hyperlink>9.3.2</hyperlink>), tokens (<hyperlink>9.4</hyperlink>), and pre-processing directives (<hyperlink>9.5</hyperlink>). Of these basic elements, only tokens are significant in the syntactic grammar of a C# program (<hyperlink>9.2.2</hyperlink>). </paragraph>
+  <paragraph>The lexical processing of a C# source file consists of reducing the file into a sequence of tokens which becomes the input to the syntactic analysis. Line terminators, white space, and comments can serve to separate tokens, and pre-processing directives can cause sections of the source file to be skipped, but otherwise these lexical elements have no impact on the syntactic structure of a C# program. </paragraph>
+  <paragraph>When several lexical grammar productions match a sequence of characters in a source file, the lexical processing always forms the longest possible lexical element. <example>[Example: For example, the character sequence // is processed as the beginning of a single-line comment because that lexical element is longer than a single / token. end example]</example> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/9.4.1.xml b/mcs/docs/ecma334/9.4.1.xml
new file mode 100644 (file)
index 0000000..b170e65
--- /dev/null
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+<clause number="9.4.1" title="Unicode escape sequences">
+  <paragraph>A Unicode escape sequence represents a Unicode character. Unicode escape sequences are processed in identifiers (<hyperlink>9.4.2</hyperlink>), regular string literals (<hyperlink>9.4.4.5</hyperlink>), and character literals (<hyperlink>9.4.4.4</hyperlink>). A Unicode character escape is not processed in any other location (for example, to form an operator, punctuator, or keyword). <grammar_production><name><non_terminal where="9.4.1">unicode-escape-sequence</non_terminal></name> :: <rhs><terminal>\u</terminal><non_terminal where="9.4.4.2">hex-digit</non_terminal><non_terminal where="9.4.4.2">hex-digit</non_terminal><non_terminal where="9.4.4.2">hex-digit</non_terminal><non_terminal where="9.4.4.2">hex-digit</non_terminal></rhs><rhs><terminal>\U</terminal><non_terminal where="9.4.4.2">hex-digit</non_terminal><non_terminal where="9.4.4.2">hex-digit</non_terminal><non_terminal where="9.4.4.2">hex-digit</non_terminal><non_terminal where="9.4.4.2">hex-digit</non_terminal><non_terminal where="9.4.4.2">hex-digit</non_terminal><non_terminal where="9.4.4.2">hex-digit</non_terminal><non_terminal where="9.4.4.2">hex-digit</non_terminal><non_terminal where="9.4.4.2">hex-digit</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>A Unicode escape sequence represents the single Unicode character formed by the hexadecimal number following the &quot;\u&quot; or &quot;\U&quot; characters. Since C# uses a 16-bit encoding of Unicode characters in characters and string values, a Unicode character in the range U+10000 to U+10FFFF is represented using two Unicode surrogate characters. Unicode characters with code points above 0x10FFFF are not supported. </paragraph>
+  <paragraph>Multiple translations are not performed. For instance, the string literal &quot;\u005Cu005C&quot; is equivalent to &quot;\u005C&quot; rather than &quot;\&quot;. <note>[Note: The Unicode value \u005C is the character &quot;\&quot;. end note]</note> </paragraph>
+  <paragraph>
+    <example>[Example: The example <code_example><![CDATA[
+class Class1  
+{  
+   static void Test(bool \u0066) {  
+      char c = '\u0066';  
+      if (\u0066)  
+      System.Console.WriteLine(c.ToString());  
+   }     
+}  
+]]></code_example>shows several uses of \u0066, which is the escape sequence for the letter &quot;f&quot;. The program is equivalent to <code_example><![CDATA[
+class Class1  
+{  
+   static void Test(bool f) {  
+      char c = 'f';  
+      if (f)  
+      System.Console.WriteLine(c.ToString());  
+   }     
+}  
+]]></code_example>end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/9.4.2.xml b/mcs/docs/ecma334/9.4.2.xml
new file mode 100644 (file)
index 0000000..709f9a0
--- /dev/null
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<clause number="9.4.2" title="Identifiers">
+  <paragraph>The rules for identifiers given in this section correspond exactly to those recommended by the Unicode Standard Annex 15 except that underscore is allowed as an initial character (as is traditional in the C programming language), Unicode escape sequences are permitted in identifiers, and the &quot;@&quot; character is allowed as a prefix to enable keywords to be used as identifiers. <grammar_production><name>identifier</name> :: <rhs><non_terminal where="9.4.2">available-identifier</non_terminal></rhs><rhs><terminal>@</terminal><non_terminal where="9.4.2">identifier-or-keyword</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.4.2">available-identifier</non_terminal></name> :: <rhs>An <non_terminal where="9.4.2">identifier-or-keyword</non_terminal> that is not a <non_terminal where="9.4.3">keyword</non_terminal> </rhs></grammar_production><grammar_production><name><non_terminal where="9.4.2">identifier-or-keyword</non_terminal></name> :: <rhs><non_terminal where="9.4.2">identifier-start-character</non_terminal><non_terminal where="9.4.2">identifier-part-characters</non_terminal><opt/></rhs></grammar_production><grammar_production><name><non_terminal where="9.4.2">identifier-start-character</non_terminal></name> :: <rhs><non_terminal where="9.4.2">letter-character</non_terminal></rhs><rhs>_ (the underscore character U+005F) </rhs></grammar_production><grammar_production><name><non_terminal where="9.4.2">identifier-part-character</non_terminal>s</name> :: <rhs><non_terminal where="9.4.2">identifier-part-character</non_terminal></rhs><rhs><non_terminal where="9.4.2">identifier-part-characters</non_terminal><non_terminal where="9.4.2">identifier-part-character</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.4.2">identifier-part-character</non_terminal></name> :: <rhs><non_terminal where="9.4.2">letter-character</non_terminal></rhs><rhs><non_terminal where="9.4.2">decimal-digit-character</non_terminal></rhs><rhs><non_terminal where="9.4.2">connecting-character</non_terminal></rhs><rhs><non_terminal where="9.4.2">combining-character</non_terminal></rhs><rhs><non_terminal where="9.4.2">formatting-character</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.4.2">letter-character</non_terminal></name> :: <rhs>A Unicode character of classes Lu, Ll, Lt, Lm, Lo, or Nl </rhs><rhs>A <non_terminal where="9.4.1">unicode-escape-sequence</non_terminal> representing a character of classes Lu, Ll, Lt, Lm, Lo, or Nl </rhs></grammar_production><grammar_production><name><non_terminal where="9.4.2">combining-character</non_terminal></name> :: <rhs>A Unicode character of classes Mn or Mc </rhs><rhs>A <non_terminal where="9.4.1">unicode-escape-sequence</non_terminal> representing a character of classes Mn or Mc </rhs></grammar_production><grammar_production><name><non_terminal where="9.4.2">decimal-digit-character</non_terminal></name> :: <rhs>A Unicode character of the class Nd </rhs><rhs>A <non_terminal where="9.4.1">unicode-escape-sequence</non_terminal> representing a character of the class Nd </rhs></grammar_production><grammar_production><name><non_terminal where="9.4.2">connecting-character</non_terminal></name> :: <rhs>A Unicode character of the class Pc </rhs><rhs>A <non_terminal where="9.4.1">unicode-escape-sequence</non_terminal> representing a character of the class Pc </rhs></grammar_production><grammar_production><name><non_terminal where="9.4.2">formatting-character</non_terminal></name> :: <rhs>A Unicode character of the class Cf </rhs><rhs>A <non_terminal where="9.4.1">unicode-escape-sequence</non_terminal> representing a character of the class Cf </rhs></grammar_production></paragraph>
+  <paragraph>
+    <note>[Note: For information on the Unicode character classes mentioned above, see The Unicode Standard, Verson 3.0, 4-5. end note]</note>
+  </paragraph>
+  <paragraph>
+    <example>[Example: Examples of valid identifiers include &quot;identifier1&quot;, &quot;_identifier2&quot;, and &quot;@if&quot;. end example]</example>
+  </paragraph>
+  <paragraph>An identifier in a conforming program must be in the canonical format defined by Unicode Normalization Form C, as defined by Unicode Standard Annex 15. The behavior when encountering an identifier not in Normalization Form C is implementation-defined; however, a diagnostic is not required. </paragraph>
+  <paragraph>The prefix &quot;@&quot; enables the use of keywords as identifiers, which is useful when interfacing with other programming languages. The character @ is not actually part of the identifier, so the identifier might be seen in other languages as a normal identifier, without the prefix. An identifier with an @ prefix is called a verbatim identifier. <note>[Note: Use of the @ prefix for identifiers that are not keywords is permitted, but strongly discouraged as a matter of style. end note]</note> </paragraph>
+  <paragraph>
+    <example>[Example: The example: <code_example><![CDATA[
+class @class  
+{  
+   public static void @static(bool @bool) {  
+      if (@bool)  
+      System.Console.WriteLine("true");  
+      else  
+      System.Console.WriteLine("false");  
+   }    
+}  
+class Class1  
+{  
+   static void M() {  
+      cl\u0061ss.st\u0061tic(true);  
+   }  
+}  
+]]></code_example>defines a class named &quot;class&quot; with a static method named &quot;static&quot; that takes a parameter named &quot;bool&quot;. Note that since Unicode escapes are not permitted in keywords, the token &quot;cl\u0061ss&quot; is an identifier, and is the same identifier as &quot;@class&quot;. end example]</example>
+  </paragraph>
+  <paragraph>Two identifiers are considered the same if they are identical after the following transformations are applied, in order: <list><list_item> The prefix &quot;@&quot;, if used, is removed. </list_item><list_item> Each <non_terminal where="9.4.1">unicode-escape-sequence</non_terminal> is transformed into its corresponding Unicode character. </list_item><list_item> Any <non_terminal where="9.4.2">formatting-character</non_terminal>s are removed. </list_item></list></paragraph>
+  <paragraph>Identifiers containing two consecutive underscore characters (U+005F) are reserved for use by the implementation; however, no diagnostic is required if such an identifier is defined. <note>[Note: For example, an implementation might provide extended keywords that begin with two underscores. end note]</note> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/9.4.3.xml b/mcs/docs/ecma334/9.4.3.xml
new file mode 100644 (file)
index 0000000..98e7370
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="9.4.3" title="Keywords">
+  <paragraph>A keyword is an identifier-like sequence of characters that is reserved, and cannot be used as an identifier except when prefaced by the @ character. <grammar_production><name>keyword</name> :: one of <rhs><keyword>abstract</keyword><keyword>as</keyword><keyword>base</keyword><keyword>bool</keyword><keyword>break</keyword></rhs><rhs><keyword>byte</keyword><keyword>case</keyword><keyword>catch</keyword><keyword>char</keyword><keyword>checked</keyword></rhs><rhs><keyword>class</keyword><keyword>const</keyword><keyword>continue</keyword><keyword>decimal</keyword><keyword>default</keyword></rhs><rhs><keyword>delegate</keyword><keyword>do</keyword><keyword>double</keyword><keyword>else</keyword><keyword>enum</keyword></rhs><rhs><keyword>event</keyword><keyword>explicit</keyword><keyword>extern</keyword><keyword>false</keyword><keyword>finally</keyword></rhs><rhs><keyword>fixed</keyword><keyword>float</keyword><keyword>for</keyword><keyword>foreach</keyword><keyword>goto</keyword></rhs><rhs><keyword>if</keyword><keyword>implicit</keyword><keyword>in</keyword><keyword>int</keyword><keyword>interface</keyword></rhs><rhs><keyword>internal</keyword><keyword>is</keyword><keyword>lock</keyword><keyword>long</keyword><keyword>namespace</keyword></rhs><rhs><keyword>new</keyword><keyword>null</keyword><keyword>object</keyword><keyword>operator</keyword><keyword>out</keyword></rhs><rhs><keyword>override</keyword><keyword>params</keyword><keyword>private</keyword><keyword>protected</keyword><keyword>public</keyword></rhs><rhs><keyword>readonly</keyword><keyword>ref</keyword><keyword>return</keyword><keyword>sbyte</keyword><keyword>sealed</keyword></rhs><rhs><keyword>short</keyword><keyword>sizeof</keyword><keyword>stackalloc</keyword><keyword>static</keyword><keyword>string</keyword></rhs><rhs><keyword>struct</keyword><keyword>switch</keyword><keyword>this</keyword><keyword>throw</keyword><keyword>true</keyword></rhs><rhs><keyword>try</keyword><keyword>typeof</keyword><keyword>uint</keyword><keyword>ulong</keyword><keyword>unchecked</keyword></rhs><rhs><keyword>unsafe</keyword><keyword>ushort</keyword><keyword>using</keyword><keyword>virtual</keyword><keyword>void</keyword></rhs><rhs><keyword>volatile</keyword><keyword>while</keyword></rhs></grammar_production></paragraph>
+  <paragraph>In some places in the grammar, specific identifiers have special meaning, but are not keywords. <note>[Note: For example, within a property declaration, the &quot;get&quot; and &quot;set&quot; identifiers have special meaning (<hyperlink>17.6.2</hyperlink>). An identifier other than get or set is never permitted in these locations, so this use does not conflict with a use of these words as identifiers. end note]</note> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/9.4.4.1.xml b/mcs/docs/ecma334/9.4.4.1.xml
new file mode 100644 (file)
index 0000000..5dd449e
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<clause number="9.4.4.1" title="Boolean literals">
+  <paragraph>There are two boolean literal values: true and false. <grammar_production><name><non_terminal where="9.4.4.1">boolean-literal</non_terminal></name> :: <rhs><keyword>true</keyword></rhs><rhs><keyword>false</keyword></rhs></grammar_production></paragraph>
+  <paragraph>The type of a <non_terminal where="9.4.4.1">boolean-literal</non_terminal> is <keyword>bool</keyword>. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/9.4.4.2.xml b/mcs/docs/ecma334/9.4.4.2.xml
new file mode 100644 (file)
index 0000000..2e7d0e4
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<clause number="9.4.4.2" title="Integer literals">
+  <paragraph>Integer literals are used to write values of types <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>long</keyword>, and <keyword>ulong</keyword>. Integer literals have two possible forms: <keyword>decimal</keyword> and hexadecimal. <grammar_production><name><non_terminal where="9.4.4.2">integer-literal</non_terminal></name> :: <rhs><non_terminal where="9.4.4.2">decimal-integer-literal</non_terminal></rhs><rhs><non_terminal where="9.4.4.2">hexadecimal-integer-literal</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.4.4.2">decimal-integer-literal</non_terminal></name> :: <rhs><non_terminal where="9.4.4.2">decimal-digits</non_terminal><non_terminal where="9.4.4.2">integer-type-suffix</non_terminal><opt/></rhs></grammar_production><grammar_production><name><non_terminal where="9.4.4.2">decimal-digit</non_terminal>s</name> :: <rhs><non_terminal where="9.4.4.2">decimal-digit</non_terminal></rhs><rhs><non_terminal where="9.4.4.2">decimal-digits</non_terminal><non_terminal where="9.4.4.2">decimal-digit</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.4.4.2">decimal-digit</non_terminal></name> :: one of <rhs><terminal>0</terminal><terminal>1</terminal><terminal>2</terminal><terminal>3</terminal><terminal>4</terminal><terminal>5</terminal><terminal>6</terminal><terminal>7</terminal><terminal>8</terminal><terminal>9</terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.4.4.2">integer-type-suffix</non_terminal></name> :: one of <rhs><terminal>U  u  L  l  UL  Ul  uL  ul  LU  Lu  lU  lu  </terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.4.4.2">hexadecimal-integer-literal</non_terminal></name> :: <rhs><terminal>0x</terminal><non_terminal where="9.4.4.2">hex-digits</non_terminal><non_terminal where="9.4.4.2">integer-type-suffix</non_terminal><opt/></rhs><rhs><terminal>0X</terminal><non_terminal where="9.4.4.2">hex-digits</non_terminal><non_terminal where="9.4.4.2">integer-type-suffix</non_terminal><opt/></rhs></grammar_production><grammar_production><name><non_terminal where="9.4.4.2">hex-digit</non_terminal>s</name> :: <rhs><non_terminal where="9.4.4.2">hex-digit</non_terminal></rhs><rhs><non_terminal where="9.4.4.2">hex-digits</non_terminal><non_terminal where="9.4.4.2">hex-digit</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.4.4.2">hex-digit</non_terminal></name> :: one of <rhs><terminal>0</terminal><terminal>1</terminal><terminal>2</terminal><terminal>3</terminal><terminal>4</terminal><terminal>5</terminal><terminal>6</terminal><terminal>7</terminal><terminal>8</terminal><terminal>9</terminal><terminal>A</terminal><terminal>B</terminal><terminal>C</terminal><terminal>D</terminal><terminal>E</terminal><terminal>F</terminal><terminal>a</terminal><terminal>b</terminal><terminal>c</terminal><terminal>d</terminal><terminal>e</terminal><terminal>f</terminal></rhs></grammar_production></paragraph>
+  <paragraph>The type of an integer literal is determined as follows: <list><list_item> If the literal has no suffix, it has the first of these types in which its value can be represented: <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>long</keyword>, <keyword>ulong</keyword>. </list_item><list_item> If the literal is suffixed by U or u, it has the first of these types in which its value can be represented: <keyword>uint</keyword>, <keyword>ulong</keyword>. </list_item><list_item> If the literal is suffixed by L or l, it has the first of these types in which its value can be represented: <keyword>long</keyword>, <keyword>ulong</keyword>. </list_item><list_item> If the literal is suffixed by UL, Ul, uL, ul, LU, Lu, lU, or lu, it is of type <keyword>ulong</keyword>. </list_item></list></paragraph>
+  <paragraph>If the value represented by an integer literal is outside the range of the <keyword>ulong</keyword> type, a compile-time error occurs. </paragraph>
+  <paragraph>
+    <note>[Note: As a matter of style, it is suggested that &quot;L&quot; be used instead of &quot;l&quot; when writing literals of type <keyword>long</keyword>, since it is easy to confuse the letter &quot;l&quot; with the digit &quot;1&quot;. end note]</note>
+  </paragraph>
+  <paragraph>To permit the smallest possible <keyword>int</keyword> and <keyword>long</keyword> values to be written as <keyword>decimal</keyword> integer literals, the following two rules exist: <list><list_item> When a <non_terminal where="9.4.4.2">decimal-integer-literal</non_terminal> with the value 2147483648 (2<super>31</super>) and no <non_terminal where="9.4.4.2">integer-type-suffix</non_terminal> appears as the token immediately following a unary minus operator token (<hyperlink>14.6.2</hyperlink>), the result is a constant of type <keyword>int</keyword> with the value <unicode>8722</unicode>2147483648 (<unicode>8722</unicode>2<super>31</super>). In all other situations, such a <non_terminal where="9.4.4.2">decimal-integer-literal</non_terminal> is of type <keyword>uint</keyword>. </list_item><list_item> When a <non_terminal where="9.4.4.2">decimal-integer-literal</non_terminal> with the value 9223372036854775808 (2<super>63</super>) and no <non_terminal where="9.4.4.2">integer-type-suffix</non_terminal> or the <non_terminal where="9.4.4.2">integer-type-suffix</non_terminal> L or l appears as the token immediately following a unary minus operator token (<hyperlink>14.6.2</hyperlink>), the result is a constant of type <keyword>long</keyword> with the value <unicode>8722</unicode>9223372036854775808 (<unicode>8722</unicode>2<super>63</super>). In all other situations, such a <non_terminal where="9.4.4.2">decimal-integer-literal</non_terminal> is of type <keyword>ulong</keyword>. </list_item></list></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/9.4.4.3.xml b/mcs/docs/ecma334/9.4.4.3.xml
new file mode 100644 (file)
index 0000000..d38714c
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<clause number="9.4.4.3" title="Real literals">
+  <paragraph>Real literals are used to write values of types <keyword>float</keyword>, <keyword>double</keyword>, and <keyword>decimal</keyword>. <grammar_production><name><non_terminal where="9.4.4.3">real-literal</non_terminal></name> :: <rhs><non_terminal where="9.4.4.2">decimal-digits</non_terminal><terminal>.</terminal><non_terminal where="9.4.4.2">decimal-digits</non_terminal><non_terminal where="9.4.4.3">exponent-part</non_terminal><opt/><non_terminal where="9.4.4.3">real-type-suffix</non_terminal><opt/></rhs><rhs><terminal>.</terminal><non_terminal where="9.4.4.2">decimal-digits</non_terminal><non_terminal where="9.4.4.3">exponent-part</non_terminal><opt/><non_terminal where="9.4.4.3">real-type-suffix</non_terminal><opt/></rhs><rhs><non_terminal where="9.4.4.2">decimal-digits</non_terminal><non_terminal where="9.4.4.3">exponent-part</non_terminal><non_terminal where="9.4.4.3">real-type-suffix</non_terminal><opt/></rhs><rhs><non_terminal where="9.4.4.2">decimal-digits</non_terminal><non_terminal where="9.4.4.3">real-type-suffix</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.4.4.3">exponent-part</non_terminal></name> :: <rhs><terminal>e</terminal><non_terminal where="9.4.4.3">sign</non_terminal><opt/><non_terminal where="9.4.4.2">decimal-digits</non_terminal></rhs><rhs><terminal>E</terminal><non_terminal where="9.4.4.3">sign</non_terminal><opt/><non_terminal where="9.4.4.2">decimal-digits</non_terminal></rhs></grammar_production><grammar_production><name>sign</name> :: one of <rhs><terminal>+</terminal><terminal>-</terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.4.4.3">real-type-suffix</non_terminal></name> :: one of <rhs><terminal>F  f  D  d  M  m </terminal></rhs></grammar_production></paragraph>
+  <paragraph>If no <non_terminal where="9.4.4.3">real-type-suffix</non_terminal> is specified, the type of the real literal is <keyword>double</keyword>. Otherwise, the <non_terminal where="9.4.4.3">real-type-suffix</non_terminal> determines the type of the real literal, as follows: <list><list_item> A real literal suffixed by F or f is of type <keyword>float</keyword>. <example>[Example: For example, the literals 1f, 1.5f, 1e10f, and 123.456F are all of type <keyword>float</keyword>. end example]</example> </list_item><list_item> A real literal suffixed by D or d is of type <keyword>double</keyword>. <example>[Example: For example, the literals 1d, 1.5d, 1e10d, and 123.456D are all of type <keyword>double</keyword>. end example]</example> </list_item><list_item> A real literal suffixed by M or m is of type <keyword>decimal</keyword>. <example>[Example: For example, the literals 1m, 1.5m, 1e10m, and 123.456M are all of type <keyword>decimal</keyword>. end example]</example> This literal is converted to a <keyword>decimal</keyword> value by taking the exact value, and, if necessary, rounding to the nearest representable value using banker's rounding (<hyperlink>11.1.6</hyperlink>). Any scale apparent in the literal is preserved unless the value is rounded or the value is zero (in which latter case the sign and scale will be 0). <note>[Note: Hence, the literal 2.900m will be parsed to form the <keyword>decimal</keyword> with sign 0, coefficient 2900, and scale 3. end note]</note> </list_item></list></paragraph>
+  <paragraph>If the specified literal cannot be represented in the indicated type, a compile-time error occurs. </paragraph>
+  <paragraph>The value of a real literal having type <keyword>float</keyword> or <keyword>double</keyword> is determined by using the IEEE &quot;round to nearest&quot; mode. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/9.4.4.4.xml b/mcs/docs/ecma334/9.4.4.4.xml
new file mode 100644 (file)
index 0000000..6c01576
--- /dev/null
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<clause number="9.4.4.4" title="Character literals">
+  <paragraph>A character literal represents a single character, and usually consists of a character in quotes, as in 'a'. <grammar_production><name><non_terminal where="9.4.4.4">character-literal</non_terminal></name> :: <rhs><terminal>'</terminal><non_terminal where="9.4.4.4">character</non_terminal><terminal>'</terminal></rhs></grammar_production><grammar_production><name>character</name> :: <rhs><non_terminal where="9.4.4.4">single-character</non_terminal></rhs><rhs><non_terminal where="9.4.4.4">simple-escape-sequence</non_terminal></rhs><rhs><non_terminal where="9.4.4.4">hexadecimal-escape-sequence</non_terminal></rhs><rhs><non_terminal where="9.4.1">unicode-escape-sequence</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.4.4.4">single-character</non_terminal></name> :: <rhs>Any character except ' (U+0027), \ (U+005C), and <non_terminal where="9.3.2">new-line-character</non_terminal> </rhs></grammar_production><grammar_production><name><non_terminal where="9.4.4.4">simple-escape-sequence</non_terminal></name> :: one of <rhs><terminal>\'</terminal><terminal>\&quot;</terminal><terminal>\\</terminal><terminal>\0</terminal><terminal>\a</terminal><terminal>\b</terminal><terminal>\f</terminal><terminal>\n</terminal><terminal>\r</terminal><terminal>\t</terminal><terminal>\v</terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.4.4.4">hexadecimal-escape-sequence</non_terminal></name> :: <rhs><terminal>\x</terminal><non_terminal where="9.4.4.2">hex-digit</non_terminal><non_terminal where="9.4.4.2">hex-digit</non_terminal><opt/><non_terminal where="9.4.4.2">hex-digit</non_terminal><opt/><non_terminal where="9.4.4.2">hex-digit</non_terminal><opt/></rhs></grammar_production></paragraph>
+  <paragraph>
+    <note>[Note: A character that follows a backslash character (\) in a character must be one of the following characters: ', &quot;, \, 0, a, b, f, n, r, t, u, U, x, v. Otherwise, a compile-time error occurs. end note]</note>
+  </paragraph>
+  <paragraph>A hexadecimal escape sequence represents a single Unicode character, with the value formed by the hexadecimal number following &quot;\x&quot;. </paragraph>
+  <paragraph>If the value represented by a character literal is greater than U+FFFF, a compile-time error occurs. </paragraph>
+  <paragraph>A Unicode character escape sequence (<hyperlink>9.4.1</hyperlink>) in a character literal must be in the range U+0000 to U+FFFF. </paragraph>
+  <paragraph>A simple escape sequence represents a Unicode character encoding, as described in the table below. <table_line>Escape </table_line>
+<table_line>sequence </table_line>
+<table_line>Character </table_line>
+<table_line>name </table_line>
+<table_line>Unicode </table_line>
+<table_line>encoding </table_line>
+<table_line>\' Single quote 0x0027 </table_line>
+<table_line>\&quot; Double quote 0x0022 </table_line>
+<table_line>\\ Backslash 0x005C </table_line>
+<table_line>\0 Null 0x0000 </table_line>
+<table_line>\a Alert 0x0007 </table_line>
+<table_line>\b Backspace 0x0008 </table_line>
+<table_line>\f Form feed 0x000C </table_line>
+<table_line>\n New line 0x000A </table_line>
+<table_line>\r Carriage return 0x000D </table_line>
+<table_line>\t Horizontal tab 0x0009 </table_line>
+<table_line>\v Vertical tab 0x000B </table_line>
+</paragraph>
+  <paragraph>The type of a <non_terminal where="9.4.4.4">character-literal</non_terminal> is <keyword>char</keyword>. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/9.4.4.5.xml b/mcs/docs/ecma334/9.4.4.5.xml
new file mode 100644 (file)
index 0000000..a5962cd
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<clause number="9.4.4.5" title="String literals">C# supports two forms of string literals: regular string literals and verbatim string literals. A regular string literal consists of zero or more characters enclosed in <keyword>double</keyword> quotes, as in &quot;hello, world&quot;, and may include both simple escape sequences (such as \t for the tab character), and hexadecimal and Unicode escape sequences. <paragraph>A verbatim string literal consists of an @ character followed by a double-quote character, zero or more </paragraph><paragraph>characters, and a closing double-quote character. <example>[Example: A simple example is @&quot;hello, world&quot;. end example]</example> In a verbatim string literal, the characters between the delimiters are interpreted verbatim, with the only exception being a <non_terminal where="9.4.4.5">quote-escape-sequence</non_terminal>. In particular, simple escape sequences, and hexadecimal and Unicode escape sequences are not processed in verbatim string literals. A verbatim string literal may span multiple lines. <grammar_production><name><non_terminal where="9.4.4.5">string-literal</non_terminal></name> :: <rhs><non_terminal where="9.4.4.5">regular-string-literal</non_terminal></rhs><rhs><non_terminal where="9.4.4.5">verbatim-string-literal</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.4.4.5">regular-string-literal</non_terminal></name> :: <rhs><terminal>&quot;</terminal><non_terminal where="9.4.4.5">regular-string-literal-characters</non_terminal><opt/><terminal>&quot;</terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.4.4.5">regular-string-literal-character</non_terminal>s</name> :: <rhs><non_terminal where="9.4.4.5">regular-string-literal-character</non_terminal></rhs><rhs><non_terminal where="9.4.4.5">regular-string-literal-characters</non_terminal><non_terminal where="9.4.4.5">regular-string-literal-character</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.4.4.5">regular-string-literal-character</non_terminal></name> :: <rhs><non_terminal where="9.4.4.5">single-regular-string-literal-character</non_terminal></rhs><rhs><non_terminal where="9.4.4.4">simple-escape-sequence</non_terminal></rhs><rhs><non_terminal where="9.4.4.4">hexadecimal-escape-sequence</non_terminal></rhs><rhs><non_terminal where="9.4.1">unicode-escape-sequence</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.4.4.5">single-regular-string-literal-character</non_terminal></name> :: <rhs>Any character except &quot; (U+0022), \ (U+005C), and <non_terminal where="9.3.2">new-line-character</non_terminal> </rhs></grammar_production><grammar_production><name><non_terminal where="9.4.4.5">verbatim-string-literal</non_terminal></name> :: <rhs><terminal>@&quot;</terminal><non_terminal where="9.4.4.5">verbatim-string-literal-characters</non_terminal><opt/><terminal>&quot;</terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.4.4.5">verbatim-string-literal-character</non_terminal>s</name> :: <rhs><non_terminal where="9.4.4.5">verbatim-string-literal-character</non_terminal></rhs><rhs><non_terminal where="9.4.4.5">verbatim-string-literal-characters</non_terminal><non_terminal where="9.4.4.5">verbatim-string-literal-character</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.4.4.5">verbatim-string-literal-character</non_terminal></name> :: <rhs><non_terminal where="9.4.4.5">single-verbatim-string-literal-character</non_terminal></rhs><rhs><non_terminal where="9.4.4.5">quote-escape-sequence</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.4.4.5">single-verbatim-string-literal-character</non_terminal></name> :: <rhs>Any character except &quot; </rhs></grammar_production><grammar_production><name><non_terminal where="9.4.4.5">quote-escape-sequence</non_terminal></name> :: <rhs><terminal>&quot;&quot;</terminal></rhs></grammar_production></paragraph><paragraph><note>[Note: A character that follows a backslash character (\) in a <non_terminal where="9.4.4.5">regular-string-literal-character</non_terminal> must be one of the following characters: ', &quot;, \, 0, a, b, f, n, r, t, u, U, x, v. Otherwise, a compile-time error occurs. end note]</note></paragraph><paragraph><example>[Example: The example <code_example><![CDATA[
+string a = "Happy birthday, Joel";      // Happy birthday, Joel  
+string b = @"Happy birthday, Joel";     // Happy birthday, Joel  
+string c = "hello \t world";          // hello    world  
+string d = @"hello \t world";         // hello \t world  
+string e = "Joe said \"Hello\" to me";   // Joe said "Hello" to me  
+string f = @"Joe said ""Hello"" to me";  // Joe said "Hello" to me  
+string g = "\\\\server\\share\\file.txt"; // \\server\share\file.txt  
+string h = @"\\server\share\file.txt";   // \\server\share\file.txt  
+string i = "one\r\ntwo\r\nthree";  
+string j = @"one  
+two  
+three";  
+]]></code_example>shows a variety of string literals. The last string literal, j, is a verbatim string literal that spans multiple lines. The characters between the quotation marks, including white space such as new line characters, are preserved verbatim. end example]</example></paragraph><paragraph><note>[Note: Since a hexadecimal escape sequence can have a variable number of hex digits, the string literal &quot;\x123&quot; contains a single character with hex value 123. To create a string containing the character with hex value 12 followed by the character 3, one could write &quot;\x00123&quot; or &quot;\x12&quot; + &quot;3&quot; instead. end note]</note></paragraph><paragraph>The type of a <non_terminal where="9.4.4.5">string-literal</non_terminal> is string. </paragraph><paragraph>Each string literal does not necessarily result in a new string instance. When two or more string literals that are equivalent according to the string equality operator (<hyperlink>14.9.7</hyperlink>), appear in the same assembly, these string literals refer to the same string instance. <example>[Example: For instance, the output produced by <code_example><![CDATA[
+class Test  
+{  
+   static void Main() {  
+      object a = "hello";  
+      object b = "hello";  
+      System.Console.WriteLine(a == b);  
+   }  
+}  
+]]></code_example>is True because the two literals refer to the same string instance. end example]</example> </paragraph></clause>
diff --git a/mcs/docs/ecma334/9.4.4.6.xml b/mcs/docs/ecma334/9.4.4.6.xml
new file mode 100644 (file)
index 0000000..d85529a
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<clause number="9.4.4.6" title="The null literal">
+  <paragraph>
+    <grammar_production><name><non_terminal where="9.4.4.6">null-literal</non_terminal></name> :: <rhs><keyword>null</keyword></rhs></grammar_production>
+  </paragraph>
+  <paragraph>The type of a <non_terminal where="9.4.4.6">null-literal</non_terminal> is the null type. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/9.4.4.xml b/mcs/docs/ecma334/9.4.4.xml
new file mode 100644 (file)
index 0000000..3799ba3
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="9.4.4" title="Literals">
+  <paragraph>A literal is a source code representation of a value. <grammar_production><name>literal</name> :: <rhs><non_terminal where="9.4.4.1">boolean-literal</non_terminal></rhs><rhs><non_terminal where="9.4.4.2">integer-literal</non_terminal></rhs><rhs><non_terminal where="9.4.4.3">real-literal</non_terminal></rhs><rhs><non_terminal where="9.4.4.4">character-literal</non_terminal></rhs><rhs><non_terminal where="9.4.4.5">string-literal</non_terminal></rhs><rhs><non_terminal where="9.4.4.6">null-literal</non_terminal></rhs></grammar_production></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/9.4.5.xml b/mcs/docs/ecma334/9.4.5.xml
new file mode 100644 (file)
index 0000000..6b8fb51
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="9.4.5" title="Operators and punctuators">
+  <paragraph>There are several kinds of operators and punctuators. Operators are used in expressions to describe operations involving one or more operands. <example>[Example: For example, the expression a + b uses the + operator to add the two operands a and b. end example]</example> Punctuators are for grouping and separating. <grammar_production><name><non_terminal where="9.4.5">operator-or-punctuator</non_terminal></name> :: one of <rhs><terminal>{</terminal><terminal>}</terminal><terminal>[</terminal><terminal>]</terminal><terminal>(</terminal><terminal>)</terminal><terminal>.</terminal><terminal>,</terminal><terminal>:</terminal><terminal>;</terminal></rhs><rhs><terminal>+</terminal><terminal>-</terminal><terminal>*</terminal><terminal>/</terminal><terminal>%</terminal><terminal>&amp;</terminal><terminal>|</terminal><terminal>^</terminal><terminal>!</terminal><terminal>~</terminal></rhs><rhs><terminal>=</terminal><terminal>&lt;</terminal><terminal>&gt;</terminal><terminal>?</terminal><terminal>++</terminal><terminal>--</terminal><terminal>&amp;&amp;</terminal><terminal>||</terminal><terminal>&lt;&lt;</terminal><terminal>&gt;&gt;</terminal></rhs><rhs><terminal>==</terminal><terminal>!=</terminal><terminal>&lt;=</terminal><terminal>&gt;=</terminal><terminal>+=</terminal><terminal>-=</terminal><terminal>*=</terminal><terminal>/=</terminal><terminal>%=</terminal><terminal>&amp;=</terminal></rhs><rhs><terminal>|=</terminal><terminal>^=</terminal><terminal>&lt;&lt;=</terminal><terminal>&gt;&gt;=</terminal><terminal>-&gt;</terminal></rhs></grammar_production></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/9.4.xml b/mcs/docs/ecma334/9.4.xml
new file mode 100644 (file)
index 0000000..a381868
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<clause number="9.4" title="Tokens">
+  <paragraph>There are several kinds of tokens: identifiers, keywords, literals, operators, and punctuators. White space and comments are not tokens, though they act as separators for tokens. <grammar_production><name>token</name> :: <rhs><non_terminal where="9.4.2">identifier</non_terminal></rhs><rhs><non_terminal where="9.4.3">keyword</non_terminal></rhs><rhs><non_terminal where="9.4.4.2">integer-literal</non_terminal></rhs><rhs><non_terminal where="9.4.4.3">real-literal</non_terminal></rhs><rhs><non_terminal where="9.4.4.4">character-literal</non_terminal></rhs><rhs><non_terminal where="9.4.4.5">string-literal</non_terminal></rhs><rhs><non_terminal where="9.4.5">operator-or-punctuator</non_terminal></rhs></grammar_production></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/9.5.1.xml b/mcs/docs/ecma334/9.5.1.xml
new file mode 100644 (file)
index 0000000..8d31504
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="9.5.1" title="Conditional compilation symbols">
+  <paragraph>The conditional compilation functionality provided by the <symbol>#if</symbol>, <symbol>#elif</symbol>, <symbol>#else</symbol>, and <symbol>#endif</symbol> directives is controlled through pre-processing expressions (<hyperlink>9.5.2</hyperlink>) and conditional compilation symbols. <grammar_production><name><non_terminal where="9.5.1">conditional-symbol</non_terminal></name> :: <rhs>Any <non_terminal where="9.4.2">identifier-or-keyword</non_terminal> except <keyword>true</keyword> or <keyword>false</keyword> </rhs></grammar_production></paragraph>
+  <paragraph>A conditional compilation symbol has two possible states: defined or undefined. At the beginning of the lexical processing of a source file, a conditional compilation symbol is undefined unless it has been explicitly defined by an external mechanism (such as a command-line compiler option). When a <symbol>#define</symbol> directive is processed, the conditional compilation symbol named in that directive becomes defined in that source file. The symbol remains defined until an <symbol>#undef</symbol> directive for that same symbol is processed, or until the end of the source file is reached. An implication of this is that <symbol>#define</symbol> and <symbol>#undef</symbol> directives in one source file have no effect on other source files in the same program. </paragraph>
+  <paragraph>The name space for conditional compilation symbols is distinct and separate from all other named entities in a C# program. Conditional compilation symbols can only be referenced in <symbol>#define</symbol> and <symbol>#undef</symbol> directives and in pre-processing expressions. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/9.5.2.xml b/mcs/docs/ecma334/9.5.2.xml
new file mode 100644 (file)
index 0000000..273c72a
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<clause number="9.5.2" title="Pre-processing expressions">
+  <paragraph>Pre-processing expressions can occur in <symbol>#if</symbol> and <symbol>#elif</symbol> directives. The operators !, ==, !=, &amp;&amp; and || are permitted in pre-processing expressions, and parentheses may be used for grouping. <grammar_production><name><non_terminal where="9.5.2">pp-expression</non_terminal></name> :: <rhs><non_terminal where="9.3.3">whitespace</non_terminal><opt/><non_terminal where="9.5.2">pp-or-expression</non_terminal><non_terminal where="9.3.3">whitespace</non_terminal><opt/></rhs></grammar_production><grammar_production><name><non_terminal where="9.5.2">pp-or-expression</non_terminal></name> :: <rhs><non_terminal where="9.5.2">pp-and-expression</non_terminal></rhs><rhs><non_terminal where="9.5.2">pp-or-expression</non_terminal><non_terminal where="9.3.3">whitespace</non_terminal><opt/><terminal>||</terminal><non_terminal where="9.3.3">whitespace</non_terminal><opt/><non_terminal where="9.5.2">pp-and-expression</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.5.2">pp-and-expression</non_terminal></name> :: <rhs><non_terminal where="9.5.2">pp-equality-expression</non_terminal></rhs><rhs><non_terminal where="9.5.2">pp-and-expression</non_terminal><non_terminal where="9.3.3">whitespace</non_terminal><opt/><terminal>&amp;&amp;</terminal><non_terminal where="9.3.3">whitespace</non_terminal><opt/><non_terminal where="9.5.2">pp-equality-expression</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.5.2">pp-equality-expression</non_terminal></name> :: <rhs><non_terminal where="9.5.2">pp-unary-expression</non_terminal></rhs><rhs><non_terminal where="9.5.2">pp-equality-expression</non_terminal><non_terminal where="9.3.3">whitespace</non_terminal><opt/><terminal>==</terminal><non_terminal where="9.3.3">whitespace</non_terminal><opt/><non_terminal where="9.5.2">pp-unary-expression</non_terminal></rhs><rhs><non_terminal where="9.5.2">pp-equality-expression</non_terminal><non_terminal where="9.3.3">whitespace</non_terminal><opt/><terminal>!=</terminal><non_terminal where="9.3.3">whitespace</non_terminal><opt/><non_terminal where="9.5.2">pp-unary-expression</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.5.2">pp-unary-expression</non_terminal></name> :: <rhs><non_terminal where="9.5.2">pp-primary-expression</non_terminal></rhs><rhs><terminal>!</terminal><non_terminal where="9.3.3">whitespace</non_terminal><opt/><non_terminal where="9.5.2">pp-unary-expression</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.5.2">pp-primary-expression</non_terminal></name> :: <rhs><keyword>true</keyword></rhs><rhs><keyword>false</keyword></rhs><rhs><non_terminal where="9.5.1">conditional-symbol</non_terminal></rhs><rhs><terminal>(</terminal><non_terminal where="9.3.3">whitespace</non_terminal><opt/><non_terminal where="9.5.2">pp-expression</non_terminal><non_terminal where="9.3.3">whitespace</non_terminal><opt/><terminal>)</terminal></rhs></grammar_production></paragraph>
+  <paragraph>When referenced in a pre-processing expression, a defined conditional compilation symbol has the boolean value true, and an undefined conditional compilation symbol has the boolean value false. </paragraph>
+  <paragraph>Evaluation of a pre-processing expression always yields a boolean value. The rules of evaluation for a  pre-processing expression are the same as those for a constant expression (<hyperlink>14.15</hyperlink>), except that the only  user-defined entities that can be referenced are conditional compilation symbols. </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/9.5.3.xml b/mcs/docs/ecma334/9.5.3.xml
new file mode 100644 (file)
index 0000000..99da994
--- /dev/null
@@ -0,0 +1,44 @@
+<?xml version="1.0"?>
+<clause number="9.5.3" title="Declaration directives">
+  <paragraph>The declaration directives are used to define or undefine conditional compilation symbols. <grammar_production><name><non_terminal where="9.5.3">pp-declaration</non_terminal></name> :: <rhs><non_terminal where="9.3.3">whitespace</non_terminal><opt/><terminal>#</terminal><non_terminal where="9.3.3">whitespace</non_terminal><opt/><terminal>define</terminal><non_terminal where="9.3.3">whitespace</non_terminal><non_terminal where="9.5.1">conditional-symbol</non_terminal><non_terminal where="9.5.3">pp-new-line</non_terminal></rhs><rhs><non_terminal where="9.3.3">whitespace</non_terminal><opt/><terminal>#</terminal><non_terminal where="9.3.3">whitespace</non_terminal><opt/><terminal>undef</terminal><non_terminal where="9.3.3">whitespace</non_terminal><non_terminal where="9.5.1">conditional-symbol</non_terminal><non_terminal where="9.5.3">pp-new-line</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.5.3">pp-new-line</non_terminal></name> :: <rhs><non_terminal where="9.3.3">whitespace</non_terminal><opt/><non_terminal where="9.3.2">single-line-comment</non_terminal><opt/><non_terminal where="9.3.1">new-line</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>The processing of a <symbol>#define</symbol> directive causes the given conditional compilation symbol to become defined, starting with the source line that follows the directive. Likewise, the processing of an <symbol>#undef</symbol> directive causes the given conditional compilation symbol to become undefined, starting with the source line that follows the directive. </paragraph>
+  <paragraph>Any <symbol>#define</symbol> and <symbol>#undef</symbol> directives in a source file must occur before the first token (<hyperlink>9.4</hyperlink>) in the source file; otherwise a compile-time error occurs. In intuitive terms, <symbol>#define</symbol> and <symbol>#undef</symbol> directives must precede any &quot;real code&quot; in the source file. </paragraph>
+  <paragraph>
+    <example>[Example: The example: <code_example><![CDATA[
+#define Enterprise  
+#if Professional || Enterprise  
+#define Advanced  
+#endif  
+namespace Megacorp.Data  
+{  
+   #if Advanced  
+   class PivotTable {...}  
+   #endif  
+}  
+]]></code_example>is valid because the <symbol>#define</symbol> directives precede the first token (the namespace keyword) in the source file. end example]</example>
+  </paragraph>
+  <paragraph>
+    <example>[Example: The following example results in a compile-time error because a <symbol>#define</symbol> follows real code: <code_example><![CDATA[
+#define A  
+namespace N  
+{  
+   #define B  
+   #if B  
+   class Class1 {}  
+   #endif  
+}  
+]]></code_example>end example]</example>
+  </paragraph>
+  <paragraph>A <symbol>#define</symbol> may define a conditional compilation symbol that is already defined, without there being any intervening <symbol>#undef</symbol> for that symbol. <example>[Example: The example below defines a conditional compilation symbol A and then defines it again. <code_example><![CDATA[
+#define A  
+#define A  
+]]></code_example></example></paragraph>
+  <paragraph>
+    <example>For compilers that allow conditional compilation symbols to be defined as compilation options, an alternative way for such redefinition to occur is to define the symbol as a compiler option as well as in the source. end example]</example>
+  </paragraph>
+  <paragraph>A <symbol>#undef</symbol> may &quot;undefine&quot; a conditional compilation symbol that is not defined. <example>[Example: The example below defines a conditional compilation symbol A and then undefines it twice; although the second <symbol>#undef</symbol> has no effect, it is still valid. <code_example><![CDATA[
+#define A  
+#undef A  
+#undef A  
+]]></code_example>end example]</example> </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/9.5.4.xml b/mcs/docs/ecma334/9.5.4.xml
new file mode 100644 (file)
index 0000000..5c5569a
--- /dev/null
@@ -0,0 +1,78 @@
+<?xml version="1.0"?>
+<clause number="9.5.4" title="Conditional compilation directives">
+  <paragraph>The conditional compilation directives are used to conditionally include or exclude portions of a source file. <grammar_production><name><non_terminal where="9.5.4">pp-conditional</non_terminal></name> :: <rhs><non_terminal where="9.5.4">pp-if-section</non_terminal><non_terminal where="9.5.4">pp-elif-sections</non_terminal><opt/><non_terminal where="9.5.4">pp-else-section</non_terminal><opt/><non_terminal where="9.5.4">pp-endif</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.5.4">pp-if-section</non_terminal></name> :: <rhs><non_terminal where="9.3.3">whitespace</non_terminal><opt/><terminal>#</terminal><non_terminal where="9.3.3">whitespace</non_terminal><opt/><terminal>if</terminal><non_terminal where="9.3.3">whitespace</non_terminal><non_terminal where="9.5.2">pp-expression</non_terminal><non_terminal where="9.5.3">pp-new-line</non_terminal><non_terminal where="9.5.4">conditional-section</non_terminal><opt/></rhs></grammar_production><grammar_production><name><non_terminal where="9.5.4">pp-elif-section</non_terminal>s</name> :: <rhs><non_terminal where="9.5.4">pp-elif-section</non_terminal></rhs><rhs><non_terminal where="9.5.4">pp-elif-sections</non_terminal><non_terminal where="9.5.4">pp-elif-section</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.5.4">pp-elif-section</non_terminal></name> :: <rhs><non_terminal where="9.3.3">whitespace</non_terminal><opt/><terminal>#</terminal><non_terminal where="9.3.3">whitespace</non_terminal><opt/><terminal>elif</terminal><non_terminal where="9.3.3">whitespace</non_terminal><non_terminal where="9.5.2">pp-expression</non_terminal><non_terminal where="9.5.3">pp-new-line</non_terminal><non_terminal where="9.5.4">conditional-section</non_terminal><opt/></rhs></grammar_production><grammar_production><name><non_terminal where="9.5.4">pp-else-section</non_terminal></name> :: <rhs><non_terminal where="9.3.3">whitespace</non_terminal><opt/><terminal>#</terminal><non_terminal where="9.3.3">whitespace</non_terminal><opt/><terminal>else</terminal><non_terminal where="9.5.3">pp-new-line</non_terminal><non_terminal where="9.5.4">conditional-section</non_terminal><opt/></rhs></grammar_production><grammar_production><name><non_terminal where="9.5.4">pp-endif</non_terminal></name> :: <rhs><non_terminal where="9.3.3">whitespace</non_terminal><opt/><terminal>#</terminal><non_terminal where="9.3.3">whitespace</non_terminal><opt/><terminal>endif</terminal><non_terminal where="9.5.3">pp-new-line</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.5.4">conditional-section</non_terminal></name> :: <rhs><non_terminal where="9.3">input-section</non_terminal></rhs><rhs><non_terminal where="9.5.4">skipped-section</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.5.4">skipped-section</non_terminal></name> :: <rhs><non_terminal where="9.5.4">skipped-section-part</non_terminal></rhs><rhs><non_terminal where="9.5.4">skipped-section</non_terminal><non_terminal where="9.5.4">skipped-section-part</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.5.4">skipped-section-part</non_terminal></name> :: <rhs><non_terminal where="9.5.4">skipped-characters</non_terminal><opt/><non_terminal where="9.3.1">new-line</non_terminal></rhs><rhs><non_terminal where="9.5">pp-directive</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.5.4">skipped-characters</non_terminal></name> :: <rhs><non_terminal where="9.3.3">whitespace</non_terminal><opt/><non_terminal where="9.5.4">not-number-sign</non_terminal><non_terminal where="9.3.2">input-characters</non_terminal><opt/></rhs></grammar_production><grammar_production><name><non_terminal where="9.5.4">not-number-sign</non_terminal></name> :: <rhs>Any <non_terminal where="9.3.2">input-character</non_terminal> except # </rhs></grammar_production></paragraph>
+  <paragraph>
+    <note>[Note: As indicated by the syntax, conditional compilation directives must be written as sets consisting of, in order, an <symbol>#if</symbol> directive, zero or more <symbol>#elif</symbol> directives, zero or one <symbol>#else</symbol> directive, and an <symbol>#endif</symbol> directive. Between the directives are conditional sections of source code. Each section is controlled by the immediately preceding directive. A conditional section may itself contain nested conditional compilation directives provided these directives form complete sets. end note]</note>
+  </paragraph>
+  <paragraph>A <non_terminal where="9.5.4">pp-conditional</non_terminal> selects at most one of the contained <non_terminal where="9.5.4">conditional-section</non_terminal>s for normal lexical processing: <list><list_item> The <non_terminal where="9.5.2">pp-expression</non_terminal>s of the <symbol>#if</symbol> and <symbol>#elif</symbol> directives are evaluated in order until one yields true. If an expression yields true, the <non_terminal where="9.5.4">conditional-section</non_terminal> of the corresponding directive is selected. </list_item><list_item> If all <non_terminal where="9.5.2">pp-expression</non_terminal>s yield false, and if an <symbol>#else</symbol> directive is present, the <non_terminal where="9.5.4">conditional-section</non_terminal> of the <symbol>#else</symbol> directive is selected. </list_item><list_item> Otherwise, no <non_terminal where="9.5.4">conditional-section</non_terminal> is selected. </list_item></list></paragraph>
+  <paragraph>The selected <non_terminal where="9.5.4">conditional-section</non_terminal>, if any, is processed as a normal input-section: the source code contained in the section must adhere to the lexical grammar; tokens are generated from the source code in the section; and pre-processing directives in the section have the prescribed effects. </paragraph>
+  <paragraph>The remaining <non_terminal where="9.5.4">conditional-section</non_terminal>s, if any, are processed as skipped-sections: except for pre-processing directives, the source code in the section need not adhere to the lexical grammar; no tokens are generated from the source code in the section; and pre-processing directives in the section must be lexically correct but are not otherwise processed. Within a <non_terminal where="9.5.4">conditional-section</non_terminal> that is being processed as a <non_terminal where="9.5.4">skipped-section</non_terminal>, any nested <non_terminal where="9.5.4">conditional-section</non_terminal>s (contained in nested <symbol>#if</symbol>...<symbol>#endif</symbol> and <symbol>#region</symbol>...<symbol>#endregion</symbol> constructs) are also processed as <non_terminal where="9.5.4">skipped-section</non_terminal>s. </paragraph>
+  <paragraph>
+    <example>[Example: The following example illustrates how conditional compilation directives can nest: <code_example><![CDATA[
+#define Debug    // Debugging on  
+#undef Trace    // Tracing off  
+class PurchaseTransaction  
+{  
+   void Commit() {  
+      #if Debug  
+      CheckConsistency();  
+      #if Trace  
+      WriteToLog(this.ToString());  
+      #endif  
+      #endif  
+      CommitHelper();  
+   }  
+}  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>Except for pre-processing directives, skipped source code is not subject to lexical analysis. For example, the following is valid despite the unterminated comment in the <symbol>#else</symbol> section: <code_example><![CDATA[
+#define Debug    // Debugging on  
+class PurchaseTransaction  
+{  
+   void Commit() {  
+      #if Debug  
+      CheckConsistency();  
+      #else  
+      /* Do something else  
+      #endif  
+   }  
+}  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>Note, however, that pre-processing directives are required to be lexically correct even in skipped sections of source code. </example>
+  </paragraph>
+  <paragraph>
+    <example>Pre-processing directives are not processed when they appear inside multi-line input elements. For example, the program: <code_example><![CDATA[
+class Hello  
+{  
+   static void Main() {  
+      System.Console.WriteLine(@"hello,   
+      #if Debug  
+      world  
+      #else  
+      Nebraska  
+      #endif  
+      ");  
+   }  
+}  
+]]></code_example>results in the output: <code_example><![CDATA[
+hello,  
+#if Debug  
+world  
+#else  
+Nebraska  
+#endif  
+]]></code_example></example>
+  </paragraph>
+  <paragraph>
+    <example>In peculiar cases, the set of pre-processing directives that is processed might depend on the evaluation of the <non_terminal where="9.5.2">pp-expression</non_terminal>. The example: <code_example><![CDATA[
+#if X  
+/*   
+#else  
+/* */ class Q { }  
+#endif   
+]]></code_example>always produces the same token stream (class Q <symbol>{</symbol> <symbol>}</symbol>), regardless of whether or not X is defined. If X is defined, the only processed directives are <symbol>#if</symbol> and <symbol>#endif</symbol>, due to the multi-line comment. If X is undefined, then three directives (<symbol>#if</symbol>, <symbol>#else</symbol>, <symbol>#endif</symbol>) are part of the directive set. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/9.5.5.xml b/mcs/docs/ecma334/9.5.5.xml
new file mode 100644 (file)
index 0000000..93c9919
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<clause number="9.5.5" title="Diagnostic directives">
+  <paragraph>The diagnostic directives are used to explicitly generate error and warning messages that are reported in the same way as other compile-time errors and warnings. <grammar_production><name><non_terminal where="9.5.5">pp-diagnostic</non_terminal></name> :: <rhs><non_terminal where="9.3.3">whitespace</non_terminal><opt/><terminal>#</terminal><non_terminal where="9.3.3">whitespace</non_terminal><opt/><terminal>error</terminal><non_terminal where="9.5.5">pp-message</non_terminal></rhs><rhs><non_terminal where="9.3.3">whitespace</non_terminal><opt/><terminal>#</terminal><non_terminal where="9.3.3">whitespace</non_terminal><opt/><terminal>warning</terminal><non_terminal where="9.5.5">pp-message</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.5.5">pp-message</non_terminal></name> :: <rhs><non_terminal where="9.3.1">new-line</non_terminal></rhs><rhs><non_terminal where="9.3.3">whitespace</non_terminal><non_terminal where="9.3.2">input-characters</non_terminal><opt/><non_terminal where="9.3.1">new-line</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>
+    <example>[Example: The example <code_example><![CDATA[
+#warning Code review needed before check-in  
+#if Debug && Retail  
+#error A build can't be both debug and retail  
+#endif  
+class Test {...}  
+]]></code_example>always produces a warning (&quot;Code review needed before check-in&quot;), and produces a compile-time error if the pre-processing identifiers Debug and Retail are both defined. Note that a <non_terminal where="9.5.5">pp-message</non_terminal> can contain arbitrary text; specifically, it need not contain well-formed tokens, as shown by the single quote in the word can't. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/9.5.6.xml b/mcs/docs/ecma334/9.5.6.xml
new file mode 100644 (file)
index 0000000..788e5a7
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<clause number="9.5.6" title="Region control">
+  <paragraph>The region directives are used to explicitly mark regions of source code. <grammar_production><name><non_terminal where="9.5.6">pp-region</non_terminal></name> :: <rhs><non_terminal where="9.5.6">pp-start-region</non_terminal><non_terminal where="9.5.4">conditional-section</non_terminal><opt/><non_terminal where="9.5.6">pp-end-region</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.5.6">pp-start-region</non_terminal></name> :: <rhs><non_terminal where="9.3.3">whitespace</non_terminal><opt/><terminal>#</terminal><non_terminal where="9.3.3">whitespace</non_terminal><opt/><terminal>region</terminal><non_terminal where="9.5.5">pp-message</non_terminal></rhs></grammar_production><grammar_production><name><non_terminal where="9.5.6">pp-end-region</non_terminal></name> :: <rhs><non_terminal where="9.3.3">whitespace</non_terminal><opt/><terminal>#</terminal><non_terminal where="9.3.3">whitespace</non_terminal><opt/><terminal>endregion</terminal><non_terminal where="9.5.5">pp-message</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>No semantic meaning is attached to a region; regions are intended for use by the programmer or by automated tools to mark a section of source code. The message specified in a <symbol>#region</symbol> or <symbol>#endregion</symbol> directive likewise has no semantic meaning; it merely serves to identify the region. Matching <symbol>#region</symbol> and <symbol>#endregion</symbol> directives may have different <non_terminal where="9.5.5">pp-message</non_terminal>s. </paragraph>
+  <paragraph>The lexical processing of a region: <code_example><![CDATA[
+#region  
+...  
+#endregion  
+]]></code_example>corresponds exactly to the lexical processing of a conditional compilation directive of the form: <code_example><![CDATA[
+#if true  
+...  
+#endif  
+]]></code_example></paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/9.5.7.xml b/mcs/docs/ecma334/9.5.7.xml
new file mode 100644 (file)
index 0000000..8824c26
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+<clause number="9.5.7" title="Line directives">
+  <paragraph>Line directives may be used to alter the line numbers and source file names that are reported by the compiler in output such as warnings and errors. </paragraph>
+  <paragraph>
+    <note>[Note: Line directives are most commonly used in meta-programming tools that generate C# source code from some other text input. end note]</note>
+    <grammar_production><name><non_terminal where="9.5.7">pp-line</non_terminal></name> :: <rhs><non_terminal where="9.3.3">whitespace</non_terminal><opt/><terminal>#</terminal><non_terminal where="9.3.3">whitespace</non_terminal><opt/><terminal>line</terminal><non_terminal where="9.3.3">whitespace</non_terminal><non_terminal where="9.5.7">line-indicator</non_terminal><non_terminal where="9.5.3">pp-new-line</non_terminal></rhs></grammar_production>
+    <grammar_production><name><non_terminal where="9.5.7">line-indicator</non_terminal></name> :: <rhs><non_terminal where="9.4.4.2">decimal-digits</non_terminal><non_terminal where="9.3.3">whitespace</non_terminal><non_terminal where="9.5.7">file-name</non_terminal></rhs><rhs><non_terminal where="9.4.4.2">decimal-digits</non_terminal></rhs><rhs><terminal>default</terminal></rhs></grammar_production>
+    <grammar_production><name><non_terminal where="9.5.7">file-name</non_terminal></name> :: <rhs><terminal>&quot;</terminal><non_terminal where="9.5.7">file-name-characters</non_terminal><terminal>&quot;</terminal></rhs></grammar_production>
+    <grammar_production><name><non_terminal where="9.5.7">file-name-character</non_terminal>s</name> :: <rhs><non_terminal where="9.5.7">file-name-character</non_terminal></rhs><rhs><non_terminal where="9.5.7">file-name-characters</non_terminal><non_terminal where="9.5.7">file-name-character</non_terminal></rhs></grammar_production>
+    <grammar_production><name><non_terminal where="9.5.7">file-name-character</non_terminal></name> :: <rhs>Any character except &quot; (U+0022), and <non_terminal where="9.3.1">new-line</non_terminal> </rhs></grammar_production>
+  </paragraph>
+  <paragraph>When no <symbol>#line</symbol> directives are present, the compiler reports true line numbers and source file names in its output. When processing a <symbol>#line</symbol> directive that includes a <non_terminal where="9.5.7">line-indicator</non_terminal> that is not default, the compiler treats the line after the directive as having the given line number (and file name, if specified). </paragraph>
+  <paragraph>A <symbol>#line</symbol> default directive reverses the effect of all preceding <symbol>#line</symbol> directives. The compiler reports true line information for subsequent lines, precisely as if no <symbol>#line</symbol> directives had been processed. </paragraph>
+  <paragraph>
+    <note>[Note: Note that a <non_terminal where="9.5.7">file-name</non_terminal> differs from a regular string literal in that escape characters are not processed; the '\' character simply designates an ordinary back-slash character within a <non_terminal where="9.5.7">file-name</non_terminal>. end note]</note>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/9.5.xml b/mcs/docs/ecma334/9.5.xml
new file mode 100644 (file)
index 0000000..bff755c
--- /dev/null
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<clause number="9.5" title="Pre-processing directives">
+  <paragraph>The pre-processing directives provide the ability to conditionally skip sections of source files, to report error and warning conditions, and to delineate distinct regions of source code. <note>[Note: The term &quot;pre-processing directives&quot; is used only for consistency with the C and C++ programming languages. In C#, there is no separate pre-processing step; pre-processing directives are processed as part of the lexical analysis phase. end note]</note> <grammar_production><name><non_terminal where="9.5">pp-directive</non_terminal></name> :: <rhs><non_terminal where="9.5.3">pp-declaration</non_terminal></rhs><rhs><non_terminal where="9.5.4">pp-conditional</non_terminal></rhs><rhs><non_terminal where="9.5.7">pp-line</non_terminal></rhs><rhs><non_terminal where="9.5.5">pp-diagnostic</non_terminal></rhs><rhs><non_terminal where="9.5.6">pp-region</non_terminal></rhs></grammar_production></paragraph>
+  <paragraph>The following pre-processing directives are available: <list><list_item><symbol>#define</symbol> and <symbol>#undef</symbol>, which are used to define and undefine, respectively, conditional compilation symbols (<hyperlink>9.5.3</hyperlink>). </list_item><list_item><symbol>#if</symbol>, <symbol>#elif</symbol>, <symbol>#else</symbol>, and <symbol>#endif</symbol>, which are used to conditionally skip sections of source code (<hyperlink>9.5.1</hyperlink>). </list_item><list_item><symbol>#line</symbol>, which is used to control line numbers emitted for errors and warnings (<hyperlink>9.5.7</hyperlink>). </list_item><list_item><symbol>#error</symbol> and <symbol>#warning</symbol>, which are used to issue errors and warnings, respectively (<hyperlink>9.5.5</hyperlink>). </list_item><list_item><symbol>#region</symbol> and <symbol>#endregion</symbol>, which are used to explicitly mark sections of source code (<hyperlink>9.5.6</hyperlink>). </list_item></list></paragraph>
+  <paragraph>A pre-processing directive always occupies a separate line of source code and always begins with a # character and a pre-processing directive name. White space may occur before the # character and between the # character and the directive name. </paragraph>
+  <paragraph>A source line containing a <symbol>#define</symbol>, <symbol>#undef</symbol>, <symbol>#if</symbol>, <symbol>#elif</symbol>, <symbol>#else</symbol>, <symbol>#endif</symbol>, or <symbol>#line</symbol> directive may end with a single-line comment. Delimited comments (the /* */ style of comments) are not permitted on source lines containing pre-processing directives. </paragraph>
+  <paragraph>Pre-processing directives are not tokens and are not part of the syntactic grammar of C#. However,  pre-processing directives can be used to include or exclude sequences of tokens and can in that way affect the meaning of a C# program. <example>[Example: For example, when compiled, the program <code_example><![CDATA[
+#define A  
+#undef B  
+class C  
+{  
+   #if A  
+   void F() {}  
+   #else  
+   void G() {}  
+   #endif  
+   #if B  
+   void H() {}  
+   #else  
+   void I() {}  
+   #endif  
+}  
+]]></code_example>results in the exact same sequence of tokens as the program <code_example><![CDATA[
+class C  
+{  
+   void F() {}  
+   void I() {}  
+}  
+]]></code_example></example></paragraph>
+  <paragraph>
+    <example>Thus, whereas lexically, the two programs are quite different, syntactically, they are identical. end example]</example>
+  </paragraph>
+</clause>
diff --git a/mcs/docs/ecma334/9.xml b/mcs/docs/ecma334/9.xml
new file mode 100644 (file)
index 0000000..59f0895
--- /dev/null
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<clause number="9" title="Lexical structure"/>
diff --git a/mcs/docs/ecma334/gentoc.pl b/mcs/docs/ecma334/gentoc.pl
new file mode 100644 (file)
index 0000000..95e8abf
--- /dev/null
@@ -0,0 +1,47 @@
+#!/usr/bin/perl
+
+use XML::LibXML;
+
+$parser = new XML::LibXML;
+
+opendir DIR, ".";
+foreach $file (readdir(DIR)) {
+       if ($file !~ /([\d\.]+)\.xml/) { next; }
+       $sec = $1;
+       
+       $xml = $parser->parse_file("$sec.xml");
+       $titles{$sec} = $xml->findvalue('/clause/@title');
+       
+       if ($sec =~ /^([\d\.]+)\.(\d+)$/) {
+               $parent = $1;
+               $sub = $2;
+       } else {
+               $parent = "";
+               $sub = $sec;
+       }
+
+       $sections{$parent}[$sub-1] = $sec;
+}
+closedir DIR;
+
+$doc = new XML::LibXML::Document;
+$toc = $doc->createElement('toc');
+$doc->setDocumentElement($toc);
+
+AddChildren($toc, '');
+
+print $doc->toString(1);
+
+sub AddChildren {
+       my $x = $sections{$_[1]};
+       my @x = @{ $x };
+       foreach my $s (@x) {
+               my $n = $doc->createElement('node');
+               $n->setAttribute('number', $s);
+               $n->setAttribute('name', $titles{$s});
+               $_[0]->appendChild($n);
+               
+               AddChildren($n, $s);
+       }
+}
+
diff --git a/mcs/docs/ecma334/toc.xml b/mcs/docs/ecma334/toc.xml
new file mode 100644 (file)
index 0000000..bdd7c3f
--- /dev/null
@@ -0,0 +1,559 @@
+<?xml version="1.0"?>
+<toc>
+  <node number="1" name="Scope"/>
+  <node number="2" name="Conformance"/>
+  <node number="3" name="References"/>
+  <node number="4" name="Definitions"/>
+  <node number="5" name="Notational conventions"/>
+  <node number="6" name="Acronyms and abbreviations"/>
+  <node number="7" name="General description"/>
+  <node number="8" name="Language Overview">
+    <node number="8.1" name="Getting started"/>
+    <node number="8.2" name="Types">
+      <node number="8.2.1" name="Predefined types"/>
+      <node number="8.2.2" name="Conversions"/>
+      <node number="8.2.3" name="Array types"/>
+      <node number="8.2.4" name="Type system unification"/>
+    </node>
+    <node number="8.3" name="Variables and parameters"/>
+    <node number="8.4" name="Automatic memory management"/>
+    <node number="8.5" name="Expressions"/>
+    <node number="8.6" name="Statements"/>
+    <node number="8.7" name="Classes">
+      <node number="8.7.1" name="Constants"/>
+      <node number="8.7.2" name="Fields"/>
+      <node number="8.7.3" name="Methods"/>
+      <node number="8.7.4" name="Properties"/>
+      <node number="8.7.5" name="Events"/>
+      <node number="8.7.6" name="Operators"/>
+      <node number="8.7.7" name="Indexers"/>
+      <node number="8.7.8" name="Instance constructors"/>
+      <node number="8.7.9" name="Destructors"/>
+      <node number="8.7.10" name="Static constructors"/>
+      <node number="8.7.11" name="Inheritance"/>
+    </node>
+    <node number="8.8" name="Structs"/>
+    <node number="8.9" name="Interfaces"/>
+    <node number="8.10" name="Delegates"/>
+    <node number="8.11" name="Enums"/>
+    <node number="8.12" name="Namespaces and assemblies"/>
+    <node number="8.13" name="Versioning"/>
+    <node number="8.14" name="Attributes"/>
+  </node>
+  <node number="9" name="Lexical structure">
+    <node number="9.1" name="Programs"/>
+    <node number="9.2" name="Grammars">
+      <node number="9.2.1" name="Lexical grammar"/>
+      <node number="9.2.2" name="Syntactic grammar"/>
+    </node>
+    <node number="9.3" name="Lexical analysis">
+      <node number="9.3.1" name="Line terminators"/>
+      <node number="9.3.2" name="Comments"/>
+      <node number="9.3.3" name="White space"/>
+    </node>
+    <node number="9.4" name="Tokens">
+      <node number="9.4.1" name="Unicode escape sequences"/>
+      <node number="9.4.2" name="Identifiers"/>
+      <node number="9.4.3" name="Keywords"/>
+      <node number="9.4.4" name="Literals">
+        <node number="9.4.4.1" name="Boolean literals"/>
+        <node number="9.4.4.2" name="Integer literals"/>
+        <node number="9.4.4.3" name="Real literals"/>
+        <node number="9.4.4.4" name="Character literals"/>
+        <node number="9.4.4.5" name="String literals"/>
+        <node number="9.4.4.6" name="The null literal"/>
+      </node>
+      <node number="9.4.5" name="Operators and punctuators"/>
+    </node>
+    <node number="9.5" name="Pre-processing directives">
+      <node number="9.5.1" name="Conditional compilation symbols"/>
+      <node number="9.5.2" name="Pre-processing expressions"/>
+      <node number="9.5.3" name="Declaration directives"/>
+      <node number="9.5.4" name="Conditional compilation directives"/>
+      <node number="9.5.5" name="Diagnostic directives"/>
+      <node number="9.5.6" name="Region control"/>
+      <node number="9.5.7" name="Line directives"/>
+    </node>
+  </node>
+  <node number="10" name="Basic concepts">
+    <node number="10.1" name="Application startup"/>
+    <node number="10.2" name="Application termination"/>
+    <node number="10.3" name="Declarations"/>
+    <node number="10.4" name="Members">
+      <node number="10.4.1" name="Namespace members"/>
+      <node number="10.4.2" name="Struct members"/>
+      <node number="10.4.3" name="Enumeration members"/>
+      <node number="10.4.4" name="Class members"/>
+      <node number="10.4.5" name="Interface members"/>
+      <node number="10.4.6" name="Array members"/>
+      <node number="10.4.7" name="Delegate members"/>
+    </node>
+    <node number="10.5" name="Member access">
+      <node number="10.5.1" name="Declared accessibility"/>
+      <node number="10.5.2" name="Accessibility domains"/>
+      <node number="10.5.3" name="Protected access for instance members"/>
+      <node number="10.5.4" name="Accessibility constraints"/>
+    </node>
+    <node number="10.6" name="Signatures and overloading"/>
+    <node number="10.7" name="Scopes">
+      <node number="10.7.1" name="Name hiding">
+        <node number="10.7.1.1" name="Hiding through nesting"/>
+        <node number="10.7.1.2" name="Hiding through inheritance"/>
+      </node>
+    </node>
+    <node number="10.8" name="Namespace and type names">
+      <node number="10.8.1" name="Fully qualified names"/>
+    </node>
+    <node number="10.9" name="Automatic memory management"/>
+    <node number="10.10" name="Execution order"/>
+  </node>
+  <node number="11" name="Types">
+    <node number="11.1" name="Value types">
+      <node number="11.1.1" name="Default constructors"/>
+      <node number="11.1.2" name="Struct types"/>
+      <node number="11.1.3" name="Simple types"/>
+      <node number="11.1.4" name="Integral types"/>
+      <node number="11.1.5" name="Floating point types"/>
+      <node number="11.1.6" name="The decimal type"/>
+      <node number="11.1.7" name="The bool type"/>
+      <node number="11.1.8" name="Enumeration types"/>
+    </node>
+    <node number="11.2" name="Reference types">
+      <node number="11.2.1" name="Class types"/>
+      <node number="11.2.2" name="The object type"/>
+      <node number="11.2.3" name="The string type"/>
+      <node number="11.2.4" name="Interface types"/>
+      <node number="11.2.5" name="Array types"/>
+      <node number="11.2.6" name="Delegate types"/>
+    </node>
+    <node number="11.3" name="Boxing and unboxing">
+      <node number="11.3.1" name="Boxing conversions"/>
+      <node number="11.3.2" name="Unboxing conversions"/>
+    </node>
+  </node>
+  <node number="12" name="Variables">
+    <node number="12.1" name="Variable categories">
+      <node number="12.1.1" name="Static variables"/>
+      <node number="12.1.2" name="Instance variables">
+        <node number="12.1.2.1" name="Instance variables in classes"/>
+        <node number="12.1.2.2" name="Instance variables in structs"/>
+      </node>
+      <node number="12.1.3" name="Array elements"/>
+      <node number="12.1.4" name="Value parameters"/>
+      <node number="12.1.5" name="Reference parameters"/>
+      <node number="12.1.6" name="Output parameters"/>
+      <node number="12.1.7" name="Local variables"/>
+    </node>
+    <node number="12.2" name="Default values"/>
+    <node number="12.3" name="Definite assignment">
+      <node number="12.3.1" name="Initially assigned variables"/>
+      <node number="12.3.2" name="Initially unassigned variables"/>
+      <node number="12.3.3" name="Precise rules for determining definite assignment">
+        <node number="12.3.3.1" name="General rules for statements"/>
+        <node number="12.3.3.2" name="Block statements, checked, and unchecked statements"/>
+        <node number="12.3.3.3" name="Expression statements"/>
+        <node number="12.3.3.4" name="Declaration statements"/>
+        <node number="12.3.3.5" name="If statements"/>
+        <node number="12.3.3.6" name="Switch statements"/>
+        <node number="12.3.3.7" name="While statements"/>
+        <node number="12.3.3.8" name="Do statements"/>
+        <node number="12.3.3.9" name="For statements"/>
+        <node number="12.3.3.10" name="Break, continue, and goto statements"/>
+        <node number="12.3.3.11" name="Throw statements"/>
+        <node number="12.3.3.12" name="Return statements"/>
+        <node number="12.3.3.13" name="Try-catch statements"/>
+        <node number="12.3.3.14" name="Try-finally statements"/>
+        <node number="12.3.3.15" name="Try-catch-finally statements"/>
+        <node number="12.3.3.16" name="Foreach statements"/>
+        <node number="12.3.3.17" name="Using statements"/>
+        <node number="12.3.3.18" name="Lock statements"/>
+        <node number="12.3.3.19" name="General rules for simple expressions"/>
+        <node number="12.3.3.20" name="General rules for expressions with embedded expressions"/>
+        <node number="12.3.3.21" name="Invocation expressions and object creation expressions"/>
+        <node number="12.3.3.22" name="Simple assignment expressions"/>
+        <node number="12.3.3.23" name="&amp;&amp; expressions"/>
+        <node number="12.3.3.24" name="|| expressions"/>
+        <node number="12.3.3.25" name="! expressions"/>
+        <node number="12.3.3.26" name="?: expressions"/>
+      </node>
+    </node>
+    <node number="12.4" name="Variable references"/>
+    <node number="12.5" name="Atomicity of variable references"/>
+  </node>
+  <node number="13" name="Conversions">
+    <node number="13.1" name="Implicit conversions">
+      <node number="13.1.1" name="Identity conversion"/>
+      <node number="13.1.2" name="Implicit numeric conversions"/>
+      <node number="13.1.3" name="Implicit enumeration conversions"/>
+      <node number="13.1.4" name="Implicit reference conversions"/>
+      <node number="13.1.5" name="Boxing conversions"/>
+      <node number="13.1.6" name="Implicit constant expression conversions"/>
+      <node number="13.1.7" name="User-defined implicit conversions"/>
+    </node>
+    <node number="13.2" name="Explicit conversions">
+      <node number="13.2.1" name="Explicit numeric conversions"/>
+      <node number="13.2.2" name="Explicit enumeration conversions"/>
+      <node number="13.2.3" name="Explicit reference conversions"/>
+      <node number="13.2.4" name="Unboxing conversions"/>
+      <node number="13.2.5" name="User-defined explicit conversions"/>
+    </node>
+    <node number="13.3" name="Standard conversions">
+      <node number="13.3.1" name="Standard implicit conversions"/>
+      <node number="13.3.2" name="Standard explicit conversions"/>
+    </node>
+    <node number="13.4" name="User-defined conversions">
+      <node number="13.4.1" name="Permitted user-defined conversions"/>
+      <node number="13.4.2" name="Evaluation of user-defined conversions"/>
+      <node number="13.4.3" name="User-defined implicit conversions"/>
+      <node number="13.4.4" name="User-defined explicit conversions"/>
+    </node>
+  </node>
+  <node number="14" name="Expressions">
+    <node number="14.1" name="Expression classifications">
+      <node number="14.1.1" name="Values of expressions"/>
+    </node>
+    <node number="14.2" name="Operators">
+      <node number="14.2.1" name="Operator precedence and associativity"/>
+      <node number="14.2.2" name="Operator overloading"/>
+      <node number="14.2.3" name="Unary operator overload resolution"/>
+      <node number="14.2.4" name="Binary operator overload resolution"/>
+      <node number="14.2.5" name="Candidate user-defined operators"/>
+      <node number="14.2.6" name="Numeric promotions">
+        <node number="14.2.6.1" name="Unary numeric promotions"/>
+        <node number="14.2.6.2" name="Binary numeric promotions"/>
+      </node>
+    </node>
+    <node number="14.3" name="Member lookup">
+      <node number="14.3.1" name="Base types"/>
+    </node>
+    <node number="14.4" name="Function members">
+      <node number="14.4.1" name="Argument lists"/>
+      <node number="14.4.2" name="Overload resolution">
+        <node number="14.4.2.1" name="Applicable function member"/>
+        <node number="14.4.2.2" name="Better function member"/>
+        <node number="14.4.2.3" name="Better conversion"/>
+      </node>
+      <node number="14.4.3" name="Function member invocation">
+        <node number="14.4.3.1" name="Invocations on boxed instances"/>
+      </node>
+    </node>
+    <node number="14.5" name="Primary expressions">
+      <node number="14.5.1" name="Literals"/>
+      <node number="14.5.2" name="Simple names">
+        <node number="14.5.2.1" name="Invariant meaning in blocks"/>
+      </node>
+      <node number="14.5.3" name="Parenthesized expressions"/>
+      <node number="14.5.4" name="Member access">
+        <node number="14.5.4.1" name="Identical simple names and type names"/>
+      </node>
+      <node number="14.5.5" name="Invocation expressions">
+        <node number="14.5.5.1" name="Method invocations"/>
+        <node number="14.5.5.2" name="Delegate invocations"/>
+      </node>
+      <node number="14.5.6" name="Element access">
+        <node number="14.5.6.1" name="Array access"/>
+        <node number="14.5.6.2" name="Indexer access"/>
+      </node>
+      <node number="14.5.7" name="This access"/>
+      <node number="14.5.8" name="Base access"/>
+      <node number="14.5.9" name="Postfix increment and decrement operators"/>
+      <node number="14.5.10" name="The new operator">
+        <node number="14.5.10.1" name="Object creation expressions"/>
+        <node number="14.5.10.2" name="Array creation expressions"/>
+        <node number="14.5.10.3" name="Delegate creation expressions"/>
+      </node>
+      <node number="14.5.11" name="The typeof operator"/>
+      <node number="14.5.12" name="The checked and unchecked operators"/>
+    </node>
+    <node number="14.6" name="Unary expressions">
+      <node number="14.6.1" name="Unary plus operator"/>
+      <node number="14.6.2" name="Unary minus operator"/>
+      <node number="14.6.3" name="Logical negation operator"/>
+      <node number="14.6.4" name="Bitwise complement operator"/>
+      <node number="14.6.5" name="Prefix increment and decrement operators"/>
+      <node number="14.6.6" name="Cast expressions"/>
+    </node>
+    <node number="14.7" name="Arithmetic operators">
+      <node number="14.7.1" name="Multiplication operator"/>
+      <node number="14.7.2" name="Division operator"/>
+      <node number="14.7.3" name="Remainder operator"/>
+      <node number="14.7.4" name="Addition operator"/>
+      <node number="14.7.5" name="Subtraction operator"/>
+    </node>
+    <node number="14.8" name="Shift operators"/>
+    <node number="14.9" name="Relational and type-testing operators">
+      <node number="14.9.1" name="Integer comparison operators"/>
+      <node number="14.9.2" name="Floating-point comparison operators"/>
+      <node number="14.9.3" name="Decimal comparison operators"/>
+      <node number="14.9.4" name="Boolean equality operators"/>
+      <node number="14.9.5" name="Enumeration comparison operators"/>
+      <node number="14.9.6" name="Reference type equality operators"/>
+      <node number="14.9.7" name="String equality operators"/>
+      <node number="14.9.8" name="Delegate equality operators"/>
+      <node number="14.9.9" name="The is operator"/>
+      <node number="14.9.10" name="The as operator"/>
+    </node>
+    <node number="14.10" name="Logical operators">
+      <node number="14.10.1" name="Integer logical operators"/>
+      <node number="14.10.2" name="Enumeration logical operators"/>
+      <node number="14.10.3" name="Boolean logical operators"/>
+    </node>
+    <node number="14.11" name="Conditional logical operators">
+      <node number="14.11.1" name="Boolean conditional logical operators"/>
+      <node number="14.11.2" name="User-defined conditional logical operators"/>
+    </node>
+    <node number="14.12" name="Conditional operator"/>
+    <node number="14.13" name="Assignment operators">
+      <node number="14.13.1" name="Simple assignment"/>
+      <node number="14.13.2" name="Compound assignment"/>
+      <node number="14.13.3" name="Event assignment"/>
+    </node>
+    <node number="14.14" name="Expression"/>
+    <node number="14.15" name="Constant expressions"/>
+    <node number="14.16" name="Boolean expressions"/>
+  </node>
+  <node number="15" name="Statements">
+    <node number="15.1" name="End points and reachability"/>
+    <node number="15.2" name="Blocks">
+      <node number="15.2.1" name="Statement lists"/>
+    </node>
+    <node number="15.3" name="The empty statement"/>
+    <node number="15.4" name="Labeled statements"/>
+    <node number="15.5" name="Declaration statements">
+      <node number="15.5.1" name="Local variable declarations"/>
+      <node number="15.5.2" name="Local constant declarations"/>
+    </node>
+    <node number="15.6" name="Expression statements"/>
+    <node number="15.7" name="Selection statements">
+      <node number="15.7.1" name="The if statement"/>
+      <node number="15.7.2" name="The switch statement"/>
+    </node>
+    <node number="15.8" name="Iteration statements">
+      <node number="15.8.1" name="The while statement"/>
+      <node number="15.8.2" name="The do statement"/>
+      <node number="15.8.3" name="The for statement"/>
+      <node number="15.8.4" name="The foreach statement"/>
+    </node>
+    <node number="15.9" name="Jump statements">
+      <node number="15.9.1" name="The break statement"/>
+      <node number="15.9.2" name="The continue statement"/>
+      <node number="15.9.3" name="The goto statement"/>
+      <node number="15.9.4" name="The return statement"/>
+      <node number="15.9.5" name="The throw statement"/>
+    </node>
+    <node number="15.10" name="The try statement"/>
+    <node number="15.11" name="The checked and unchecked statements"/>
+    <node number="15.12" name="The lock statement"/>
+    <node number="15.13" name="The using statement"/>
+  </node>
+  <node number="16" name="Namespaces">
+    <node number="16.1" name="Compilation units"/>
+    <node number="16.2" name="Namespace declarations"/>
+    <node number="16.3" name="Using directives">
+      <node number="16.3.1" name="Using alias directives"/>
+      <node number="16.3.2" name="Using namespace directives"/>
+    </node>
+    <node number="16.4" name="Namespace members"/>
+    <node number="16.5" name="Type declarations"/>
+  </node>
+  <node number="17" name="Classes">
+    <node number="17.1" name="Class declarations">
+      <node number="17.1.1" name="Class modifiers">
+        <node number="17.1.1.1" name="Abstract classes"/>
+        <node number="17.1.1.2" name="Sealed classes"/>
+      </node>
+      <node number="17.1.2" name="Class base specification">
+        <node number="17.1.2.1" name="Base classes"/>
+        <node number="17.1.2.2" name="Interface implementations"/>
+      </node>
+      <node number="17.1.3" name="Class body"/>
+    </node>
+    <node number="17.2" name="Class members">
+      <node number="17.2.1" name="Inheritance"/>
+      <node number="17.2.2" name="The new modifier"/>
+      <node number="17.2.3" name="Access modifiers"/>
+      <node number="17.2.4" name="Constituent types"/>
+      <node number="17.2.5" name="Static and instance members"/>
+      <node number="17.2.6" name="Nested types">
+        <node number="17.2.6.1" name="Fully qualified name"/>
+        <node number="17.2.6.2" name="Declared accessibility"/>
+        <node number="17.2.6.3" name="Hiding"/>
+        <node number="17.2.6.4" name="this access"/>
+        <node number="17.2.6.5" name="Access to private and protected members of the containing type"/>
+      </node>
+      <node number="17.2.7" name="Reserved member names">
+        <node number="17.2.7.1" name="Member Names Reserved for Properties"/>
+        <node number="17.2.7.2" name="Member Names Reserved for Events"/>
+        <node number="17.2.7.3" name="Member Names Reserved for Indexers"/>
+        <node number="17.2.7.4" name="Member Names Reserved for Destructors"/>
+      </node>
+    </node>
+    <node number="17.3" name="Constants"/>
+    <node number="17.4" name="Fields">
+      <node number="17.4.1" name="Static and instance fields"/>
+      <node number="17.4.2" name="Readonly fields">
+        <node number="17.4.2.1" name="Using static readonly fields for constants"/>
+        <node number="17.4.2.2" name="Versioning of constants and static readonly fields"/>
+      </node>
+      <node number="17.4.3" name="Volatile fields"/>
+      <node number="17.4.4" name="Field initialization"/>
+      <node number="17.4.5" name="Variable initializers">
+        <node number="17.4.5.1" name="Static field initialization"/>
+        <node number="17.4.5.2" name="Instance field initialization"/>
+      </node>
+    </node>
+    <node number="17.5" name="Methods">
+      <node number="17.5.1" name="Method parameters">
+        <node number="17.5.1.1" name="Value parameters"/>
+        <node number="17.5.1.2" name="Reference parameters"/>
+        <node number="17.5.1.3" name="Output parameters"/>
+        <node number="17.5.1.4" name="Parameter arrays"/>
+      </node>
+      <node number="17.5.2" name="Static and instance methods"/>
+      <node number="17.5.3" name="Virtual methods"/>
+      <node number="17.5.4" name="Override methods"/>
+      <node number="17.5.5" name="Sealed methods"/>
+      <node number="17.5.6" name="Abstract methods"/>
+      <node number="17.5.7" name="External methods"/>
+      <node number="17.5.8" name="Method body"/>
+      <node number="17.5.9" name="Method overloading"/>
+    </node>
+    <node number="17.6" name="Properties">
+      <node number="17.6.1" name="Static and instance properties"/>
+      <node number="17.6.2" name="Accessors"/>
+      <node number="17.6.3" name="Virtual, sealed, override, and abstract accessors"/>
+    </node>
+    <node number="17.7" name="Events">
+      <node number="17.7.1" name="Field-like events"/>
+      <node number="17.7.2" name="Event accessors"/>
+      <node number="17.7.3" name="Static and instance events"/>
+      <node number="17.7.4" name="Virtual, sealed, override, and abstract accessors"/>
+    </node>
+    <node number="17.8" name="Indexers">
+      <node number="17.8.1" name="Indexer overloading"/>
+    </node>
+    <node number="17.9" name="Operators">
+      <node number="17.9.1" name="Unary operators"/>
+      <node number="17.9.2" name="Binary operators"/>
+      <node number="17.9.3" name="Conversion operators"/>
+    </node>
+    <node number="17.10" name="Instance constructors">
+      <node number="17.10.1" name="Constructor initializers"/>
+      <node number="17.10.2" name="Instance variable initializers"/>
+      <node number="17.10.3" name="Constructor execution"/>
+      <node number="17.10.4" name="Default constructors"/>
+      <node number="17.10.5" name="Private constructors"/>
+      <node number="17.10.6" name="Optional instance constructor parameters"/>
+    </node>
+    <node number="17.11" name="Static constructors"/>
+    <node number="17.12" name="Destructors"/>
+  </node>
+  <node number="18" name="Structs">
+    <node number="18.1" name="Struct declarations">
+      <node number="18.1.1" name="Struct modifiers"/>
+      <node number="18.1.2" name="Struct interfaces"/>
+      <node number="18.1.3" name="Struct body"/>
+    </node>
+    <node number="18.2" name="Struct members"/>
+    <node number="18.3" name="Class and struct differences">
+      <node number="18.3.1" name="Value semantics"/>
+      <node number="18.3.2" name="Inheritance"/>
+      <node number="18.3.3" name="Assignment"/>
+      <node number="18.3.4" name="Default values"/>
+      <node number="18.3.5" name="Boxing and unboxing"/>
+      <node number="18.3.6" name="Meaning of this"/>
+      <node number="18.3.7" name="Field initializers"/>
+      <node number="18.3.8" name="Constructors"/>
+      <node number="18.3.9" name="Destructors"/>
+    </node>
+    <node number="18.4" name="Struct examples">
+      <node number="18.4.1" name="Database integer type"/>
+      <node number="18.4.2" name="Database boolean type"/>
+    </node>
+  </node>
+  <node number="19" name="Arrays">
+    <node number="19.1" name="Array types">
+      <node number="19.1.1" name="The System.Array type"/>
+    </node>
+    <node number="19.2" name="Array creation"/>
+    <node number="19.3" name="Array element access"/>
+    <node number="19.4" name="Array members"/>
+    <node number="19.5" name="Array covariance"/>
+    <node number="19.6" name="Array initializers"/>
+  </node>
+  <node number="20" name="Interfaces">
+    <node number="20.1" name="Interface declarations">
+      <node number="20.1.1" name="Interface modifiers"/>
+      <node number="20.1.2" name="Base interfaces"/>
+      <node number="20.1.3" name="Interface body"/>
+    </node>
+    <node number="20.2" name="Interface members">
+      <node number="20.2.1" name="Interface methods"/>
+      <node number="20.2.2" name="Interface properties"/>
+      <node number="20.2.3" name="Interface events"/>
+      <node number="20.2.4" name="Interface indexers"/>
+      <node number="20.2.5" name="Interface member access"/>
+    </node>
+    <node number="20.3" name="Fully qualified interface member names"/>
+    <node number="20.4" name="Interface implementations">
+      <node number="20.4.1" name="Explicit interface member implementations"/>
+      <node number="20.4.2" name="Interface mapping"/>
+      <node number="20.4.3" name="Interface implementation inheritance"/>
+      <node number="20.4.4" name="Interface re-implementation"/>
+      <node number="20.4.5" name="Abstract classes and interfaces"/>
+    </node>
+  </node>
+  <node number="21" name="Enums">
+    <node number="21.1" name="Enum declarations"/>
+    <node number="21.2" name="Enum modifiers"/>
+    <node number="21.3" name="Enum members"/>
+    <node number="21.4" name="Enum values and operations"/>
+  </node>
+  <node number="22" name="Delegates">
+    <node number="22.1" name="Delegate declarations"/>
+    <node number="22.2" name="Delegate instantiation"/>
+    <node number="22.3" name="Delegate invocation"/>
+  </node>
+  <node number="23" name="Exceptions">
+    <node number="23.1" name="Causes of exceptions"/>
+    <node number="23.2" name="The System.Exception class"/>
+    <node number="23.3" name="How exceptions are handled"/>
+    <node number="23.4" name="Common Exception Classes"/>
+  </node>
+  <node number="24" name="Attributes">
+    <node number="24.1" name="Attribute classes">
+      <node number="24.1.1" name="Attribute usage"/>
+      <node number="24.1.2" name="Positional and named parameters"/>
+      <node number="24.1.3" name="Attribute parameter types"/>
+    </node>
+    <node number="24.2" name="Attribute specification"/>
+    <node number="24.3" name="Attribute instances">
+      <node number="24.3.1" name="Compilation of an attribute"/>
+      <node number="24.3.2" name="Run-time retrieval of an attribute instance"/>
+    </node>
+    <node number="24.4" name="Reserved attributes">
+      <node number="24.4.1" name="The AttributeUsage attribute"/>
+      <node number="24.4.2" name="The Conditional attribute"/>
+      <node number="24.4.3" name="The Obsolete attribute"/>
+    </node>
+  </node>
+  <node number="25" name="Unsafe code">
+    <node number="25.1" name="Unsafe contexts"/>
+    <node number="25.2" name="Pointer types"/>
+    <node number="25.3" name="Fixed and moveable variables"/>
+    <node number="25.4" name="Pointer conversions"/>
+    <node number="25.5" name="Pointers in expressions">
+      <node number="25.5.1" name="Pointer indirection"/>
+      <node number="25.5.2" name="Pointer member access"/>
+      <node number="25.5.3" name="Pointer element access"/>
+      <node number="25.5.4" name="The address-of operator"/>
+      <node number="25.5.5" name="Pointer increment and decrement"/>
+      <node number="25.5.6" name="Pointer arithmetic"/>
+      <node number="25.5.7" name="Pointer comparison"/>
+      <node number="25.5.8" name="The sizeof operator"/>
+    </node>
+    <node number="25.6" name="The fixed statement"/>
+    <node number="25.7" name="Stack allocation"/>
+    <node number="25.8" name="Dynamic memory allocation"/>
+  </node>
+</toc>