csdoc-patches Mailing List for C Sharp Document Generator (XML/HTML) (Page 2)
Status: Planning
Brought to you by:
mastergaurav
You can subscribe to this list here.
2003 |
Jan
|
Feb
(46) |
Mar
(17) |
Apr
(11) |
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2004 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(65) |
Nov
(17) |
Dec
|
From: <mas...@us...> - 2004-10-30 13:54:05
|
Update of /cvsroot/csdoc/csdoc/src/mcsdoc/mcs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7278 Modified Files: ChangeLog.mcsdoc Removed Files: genericparser.cs interface.cs makefile.gnu makefile.old Log Message: 2004-10-30 Gaurav Vaish <mastergaurav AT users DOT sf DOT net> * genericparser.cs, * interface.cs, * makefile.gnu, * makefile.old : Removed files. Doing some cleanup. Index: ChangeLog.mcsdoc =================================================================== RCS file: /cvsroot/csdoc/csdoc/src/mcsdoc/mcs/ChangeLog.mcsdoc,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** ChangeLog.mcsdoc 30 Oct 2004 13:45:59 -0000 1.2 --- ChangeLog.mcsdoc 30 Oct 2004 13:53:55 -0000 1.3 *************** *** 1,2 **** --- 1,10 ---- + $Id$ + + 2004-10-30 Gaurav Vaish <mastergaurav AT users DOT sf DOT net> + + * genericparser.cs, + * interface.cs, + * makefile.gnu, + * makefile.old : Removed files. Doing some cleanup. 2004-10-30 Gaurav Vaish <mastergaurav AT users DOT sf DOT net> --- genericparser.cs DELETED --- --- interface.cs DELETED --- --- makefile.gnu DELETED --- --- makefile.old DELETED --- |
From: <mas...@us...> - 2004-10-30 13:46:11
|
Update of /cvsroot/csdoc/csdoc/src/mcsdoc/mcs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5473 Modified Files: ChangeLog.mcsdoc Added Files: mcsdoc.exe.config mcsdoc.exe.sources MCSDocUtils.cs Log Message: 2004-10-30 Gaurav Vaish <mastergaurav AT users DOT sf DOT net> * mcsdoc.exe.config, * mcsdoc.exe.sources, * MCSDocUtils.cs : Added new files. --- NEW FILE: mcsdoc.exe.config --- <configuration> <startup> <supportedRuntime version="v1.1.4322"/> </startup> <system.diagnostics> <trace autoflush="true" indentsize="4"> <listeners> <add name="compilerLogListener" type="System.Diagnostics.TextWriterTraceListener,System" initializeData="mcs.log" /> <remove type="System.Diagnostics.DefaultTraceListener,System"/> </listeners> </trace> </system.diagnostics> </configuration> --- NEW FILE: mcsdoc.exe.sources --- AssemblyInfo.cs anonymous.cs assign.cs attribute.cs driver.cs cs-tokenizer.cs cfold.cs class.cs codegen.cs const.cs constant.cs convert.cs decl.cs delegate.cs enum.cs ecore.cs expression.cs flowanalysis.cs iterators.cs literal.cs location.cs modifiers.cs namespace.cs parameter.cs pending.cs report.cs rootcontext.cs statement.cs support.cs typemanager.cs symbolwriter.cs tree.cs ../class/Mono.CSharp.Debugger/MonoSymbolFile.cs ../class/Mono.CSharp.Debugger/MonoSymbolTable.cs ../class/Mono.CSharp.Debugger/MonoSymbolWriter.cs ../class/corlib/Mono.Security.Cryptography/CryptoConvert.cs MCSDocUtils.cs --- NEW FILE: MCSDocUtils.cs --- #region Copyright Notice /** * $Id: MCSDocUtils.cs,v 1.1 2004/10/30 13:45:59 mastergaurav Exp $ * (C) 2004, Gaurav Vaish */ #endregion using System; using System.Collections; using Mono.CSharp; namespace MCSDoc { internal class MCSDocUtils { public static void ManageAttributeTypes(ArrayList types) { if(types == null || types.Count == 0) return; Console.WriteLine("\nRoot Type:"); foreach(TypeContainer tc in types) { Console.WriteLine(" " + tc.Name); } Console.WriteLine(); } public static void ManageTypeContainer(TypeContainer container) { //ManageTypeContainer("", tc); ListAllMembers(container); } static void ListAllMembers(TypeContainer root) { if(root.NamespaceEntry != null && root.NamespaceEntry.FullName.Length > 0) { Console.WriteLine("Root Namespace: " + root.NamespaceEntry.FullName); Console.WriteLine(); } else { Console.WriteLine("No root namespace.\n"); } ListTCs("", root, true); } static void ListTCs(string tab, TypeContainer tc, bool root) { if(!root) { string ttype = "Struct: "; if(tc is Class) ttype = "Class: "; Console.WriteLine(ttype + /*tab + */ tc.Name);// + " -:- " + objs.BaseType); //Console.WriteLine("Documentation: \n" + tc.Documentation); //Console.WriteLine(); } if(tc.Types != null && tc.Types.Count > 0) { foreach(TypeContainer objs in tc.Types) { if(objs.Documentation.Trim().Length > 0) { string type = "Struct: "; if(objs is Class) type = "Class: "; Console.WriteLine(type + /*tab + */ objs.Name);// + " -:- " + objs.BaseType); /* if(IsException(objs)) { Console.WriteLine("\t\t" + objs.Name + " is Exception"); } else if(IsAttribute(objs)) { Console.WriteLine("\t\t" + objs.Name + " is Attribute"); } */ //Console.WriteLine("Documentation: \n" + objs.Documentation); //Console.WriteLine(); } ListTCs(tab + "\t", objs, false); } } ListEnums(tab, tc.Enums); ListInterfaces(tab, tc.Interfaces); ListDelegates(tab, tc.Delegates); } static bool IsException(TypeContainer tc) { Type baseType = tc.BaseType; return (baseType == TypeManager.exception_type || baseType.IsSubclassOf(TypeManager.exception_type)); } static bool IsAttribute(TypeContainer tc) { Type baseType = tc.BaseType; return (baseType == TypeManager.attribute_type || baseType.IsSubclassOf(TypeManager.attribute_type)); } static void ListEnums(string tab, ArrayList enums) { if(enums != null && enums.Count > 0) { foreach(Mono.CSharp.Enum e in enums) { if(e.Documentation.Length > 0) { Console.WriteLine("Enum: " + /* tab + */ e.Name); //Console.WriteLine("Documentation: \n" + e.Documentation); //Console.WriteLine(); } } } } static void ListInterfaces(string tab, ArrayList interfaces) { if(interfaces != null && interfaces.Count > 0) { foreach(Interface i in interfaces) { if(i.Documentation.Length > 0) { Console.WriteLine("Iface: " + /* tab + */ i.Name); //Console.WriteLine("Documentation: \n" + i.Documentation); //Console.WriteLine(); } } } } static void ListDelegates(string tab, ArrayList delegs) { if(delegs != null && delegs.Count > 0) { foreach(Mono.CSharp.Delegate d in delegs) { if(d.Documentation.Length > 0) { Console.WriteLine("Deleg: " + /* tab + */ d.Name); //Console.WriteLine("Documentation: \n" + d.Documentation); //Console.WriteLine(); } } } } } } Index: ChangeLog.mcsdoc =================================================================== RCS file: /cvsroot/csdoc/csdoc/src/mcsdoc/mcs/ChangeLog.mcsdoc,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** ChangeLog.mcsdoc 30 Oct 2004 07:17:23 -0000 1.1 --- ChangeLog.mcsdoc 30 Oct 2004 13:45:59 -0000 1.2 *************** *** 2,5 **** --- 2,11 ---- 2004-10-30 Gaurav Vaish <mastergaurav AT users DOT sf DOT net> + * mcsdoc.exe.config, + * mcsdoc.exe.sources, + * MCSDocUtils.cs : Added new files. + + 2004-10-30 Gaurav Vaish <mastergaurav AT users DOT sf DOT net> + * ChangeLog.mcsdoc : Will contain all changes done by me. ChangeLog contains all modifications by mono team. |
From: <mas...@us...> - 2004-10-30 07:17:37
|
Update of /cvsroot/csdoc/csdoc/src/mcsdoc/mcs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30893 Added Files: ChangeLog.mcsdoc Log Message: 2004-10-30 Gaurav Vaish <mastergaurav AT users DOT sf DOT net> * ChangeLog.mcsdoc : Will contain all changes done by me. ChangeLog contains all modifications by mono team. --- NEW FILE: ChangeLog.mcsdoc --- 2004-10-30 Gaurav Vaish <mastergaurav AT users DOT sf DOT net> * ChangeLog.mcsdoc : Will contain all changes done by me. ChangeLog contains all modifications by mono team. |
From: <mas...@us...> - 2004-10-29 14:21:34
|
Update of /cvsroot/csdoc/csdoc/src/mcsdoc/build/platforms In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24888/build/platforms Added Files: linux.make win32.make Log Message: 2004-10-28 Gaurav Vaish * **/* : Getting the latest sync from mono repository. Will resume work pretty soon. Moving final work from csdoc to mcsdoc. --- NEW FILE: linux.make --- # -*- makefile -*- # # Platform-specific makefile rules. This one's for linux. # PLATFORM_DEBUG_FLAGS = -g PLATFORM_MCS_FLAGS = PLATFORM_RUNTIME = $(RUNTIME) PLATFORM_CORLIB = mscorlib.dll BOOTSTRAP_MCS = mcs RESGEN = MONO_PATH="$(topdir)/class/lib/$(PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(INTERNAL_RESGEN) PLATFORM_PATH_SEPARATOR = : # Define this if this ever will work on Linux # PLATFORM_MAKE_CORLIB_CMP = yes # This is for changing / to \ on windows PLATFORM_CHANGE_SEPARATOR_CMD = cat hidden_prefix = . hidden_suffix = platform-check: @set fnord $(BOOTSTRAP_MCS) ; if type $$2 >/dev/null 2>&1 ; then :; else \ echo "*** You need a C# compiler installed to build MCS. (make sure mcs works from the command line)" ; \ echo "*** Read INSTALL.txt for information on how to bootstrap" ; \ echo "*** a Mono installation." ; \ exit 1 ; \ fi # I tried this but apparently Make's version strings aren't that # ... consistent between releases. Whatever. # # @if ! $(MAKE) --version |grep '^GNU Make version 3' 1>/dev/null 2>&1 ; then \ # echo "*** You need to build MCS with GNU make. Try \`gmake'" ; \ # exit 1 ; \ # fi --- NEW FILE: win32.make --- # -*- makefile -*- # # Win32 platform-specific makefile rules. # PLATFORM_DEBUG_FLAGS = /debug+ /debug:full PLATFORM_MCS_FLAGS = /nologo /optimize PLATFORM_RUNTIME = PLATFORM_CORLIB = mscorlib.dll BOOTSTRAP_MCS = csc.exe MCS = $(BOOTSTRAP_MCS) RESGEN = resgen.exe PLATFORM_MAKE_CORLIB_CMP = yes PLATFORM_CHANGE_SEPARATOR_CMD=tr '/' '\\\\' PLATFORM_PATH_SEPARATOR = ; hidden_prefix = hidden_suffix = .tmp platform-check: |
Update of /cvsroot/csdoc/csdoc/src/mcsdoc/build/profiles In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24888/build/profiles Added Files: atomic.make bootstrap.make default.make net_1_0.make net_2_0.make net_2_0_bootstrap.make Log Message: 2004-10-28 Gaurav Vaish * **/* : Getting the latest sync from mono repository. Will resume work pretty soon. Moving final work from csdoc to mcsdoc. --- NEW FILE: atomic.make --- # -*- Makefile -*- # # The 'atomic' profile. # In this profile we compile everything relative to the already-installed # runtime, so we use the bootstrap (external) compiler for everything and # don't set MONO_PATH. # # (So the libraries are compiled and installed atomically, not incrementally.) MCS = $(BOOTSTRAP_MCS) # Causes some build errors #PROFILE_MCS_FLAGS = /d:NET_1_1 /lib:$(prefix)/lib # Get our installed libraries (an issue on windows) PROFILE_MCS_FLAGS = /lib:$(prefix)/lib # Check that installed libraries even exist. profile-check: @if test '!' -f $(prefix)/lib/I18N.dll ; then \ echo ; \ echo "$(prefix)/lib/I18N.dll does not exist." ; \ echo ; \ echo "This probably means that you are building from a miniature" ; \ echo "distribution of MCS or don't yet have an installed MCS at all." ; \ echo "The current build profile needs a complete installation of" ; \ echo "MCS to build against; you need to build using the default" ; \ echo "profile. Use this command:" ; \ echo ; \ echo " $(MAKE) PROFILE=default" ; \ echo ; \ exit 1 ; \ fi # Exciting, no? --- NEW FILE: bootstrap.make --- # -*- makefile -*- # # The default 'bootstrap' profile -- builds so that we link against # the libraries as we build them. # # We use the platform's native C# runtime and compiler if possible. # Note that we have sort of confusing terminology here; BOOTSTRAP_MCS # is what allows us to bootstrap ourselves, but when we are bootstrapping, # we use INTERNAL_MCS. # When bootstrapping, compile against our new assemblies. # (MONO_PATH doesn't just affect what assemblies are loaded to # run the compiler; /r: flags are by default loaded from whatever's # in the MONO_PATH too). MCS = MONO_PATH="$(topdir)/class/lib/$(PROFILE):$$MONO_PATH" $(RUNTIME) --debug $(topdir)/mcs/mcs.exe BOOTSTRAP_MCS = $(MCS) # nuttzing! profile-check: # Causes some build errors PROFILE_MCS_FLAGS = -d:NET_1_1 -d:ONLY_1_1 --- NEW FILE: default.make --- # -*- makefile -*- # # The default 'bootstrap' profile -- builds so that we link against # the libraries as we build them. # # We use the platform's native C# runtime and compiler if possible. # Note that we have sort of confusing terminology here; BOOTSTRAP_MCS # is what allows us to bootstrap ourselves, but when we are bootstrapping, # we use INTERNAL_MCS. # When bootstrapping, compile against our new assemblies. # (MONO_PATH doesn't just affect what assemblies are loaded to # run the compiler; /r: flags are by default loaded from whatever's # in the MONO_PATH too). ifdef PLATFORM_MONO_NATIVE MCS = MONO_PATH="$(topdir)/class/lib/$(PROFILE):$$MONO_PATH" $(INTERNAL_MCS) MBAS = MONO_PATH="$(topdir)/class/lib/$(PROFILE):$$MONO_PATH" $(INTERNAL_MBAS) else MCS = $(PLATFORM_RUNTIME) $(BOOTSTRAP_MCS) /lib:$(topdir)/class/lib/$(PROFILE) MBAS = $(PLATFORM_RUNTIME) $(BOOTSTRAP_MBAS) /lib:$(topdir)/class/lib/$(PROFILE) endif # nuttzing! profile-check: PROFILE_MCS_FLAGS = -d:NET_1_1 -d:ONLY_1_1 PROFILE_MBAS_FLAGS = -d:NET_1_1 -d:ONLY_1_1 FRAMEWORK_VERSION = 1.0 --- NEW FILE: net_1_0.make --- # -*- Makefile -*- # # Only build .NET 1.0 classes. # # If we want to combine this with, say, the atomic profile, # we should create 'atomic-net_1_0.make' which includes both. # # Ideally you could say 'make PROFILE="bootstrap net_1_0"' but # that would be pretty hard to code. include $(topdir)/build/profiles/default.make PROFILE_MCS_FLAGS = /d:NET_1_0 /d:ONLY_1_0 FRAMEWORK_VERSION = 1.0 # done --- NEW FILE: net_2_0.make --- # -*- makefile -*- # # The default 'bootstrap' profile -- builds so that we link against # the libraries as we build them. # # We use the platform's native C# runtime and compiler if possible. # Note that we have sort of confusing terminology here; BOOTSTRAP_MCS # is what allows us to bootstrap ourselves, but when we are bootstrapping, # we use INTERNAL_MCS. # When bootstrapping, compile against our new assemblies. # (MONO_PATH doesn't just affect what assemblies are loaded to # run the compiler; /r: flags are by default loaded from whatever's # in the MONO_PATH too). MCS = MONO_PATH="$(topdir)/class/lib/$(PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(INTERNAL_GMCS) # nuttzing! profile-check: PROFILE_MCS_FLAGS = -d:NET_1_1 -d:NET_2_0 -2 FRAMEWORK_VERSION = 2.0 --- NEW FILE: net_2_0_bootstrap.make --- # -*- makefile -*- # # Note that we're using the .NET 1.1 MCS but MONO_PATH points to the net_2_0_bootstrap directory. # We do it this way to get assembly version references right. # MCS = MONO_PATH="$(topdir)/class/lib/$(PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(INTERNAL_MCS) # Make sure that we're not invoked at the top-level. profile-check: echo "The 'net_2_0_bootstrap' profile is for internal use only" exit 1 PROFILE_MCS_FLAGS = -d:NET_1_1 -d:BOOTSTRAP_NET_2_0 -langversion:default FRAMEWORK_VERSION = 2.0 NO_SIGN_ASSEMBLY = yes |
From: <mas...@us...> - 2004-10-29 14:21:28
|
Update of /cvsroot/csdoc/csdoc/src/mcsdoc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24888 Added Files: makefile Log Message: 2004-10-28 Gaurav Vaish * **/* : Getting the latest sync from mono repository. Will resume work pretty soon. Moving final work from csdoc to mcsdoc. --- NEW FILE: makefile --- DIRS=jay mcs INSTALL= /usr/bin/install all: default default: for i in $(DIRS); do \ (cd $$i; make) || exit 1; \ done clean: for i in $(DIRS); do \ (cd $$i; make clean) \ done |
From: <mas...@us...> - 2004-10-29 14:21:28
|
Update of /cvsroot/csdoc/csdoc/src/mcsdoc/build/deps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24888/build/deps Added Files: .cvsignore Log Message: 2004-10-28 Gaurav Vaish * **/* : Getting the latest sync from mono repository. Will resume work pretty soon. Moving final work from csdoc to mcsdoc. --- NEW FILE: .cvsignore --- *.makefrag *.response *.stamp *.was_signed |
From: <mas...@us...> - 2004-10-29 14:20:18
|
Update of /cvsroot/csdoc/csdoc/src/mcsdoc/build/profiles In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24600/profiles Log Message: Directory /cvsroot/csdoc/csdoc/src/mcsdoc/build/profiles added to the repository |
From: <mas...@us...> - 2004-10-29 14:20:09
|
Update of /cvsroot/csdoc/csdoc/src/mcsdoc/build/platforms In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24512/platforms Log Message: Directory /cvsroot/csdoc/csdoc/src/mcsdoc/build/platforms added to the repository |
From: <mas...@us...> - 2004-10-29 14:20:08
|
Update of /cvsroot/csdoc/csdoc/src/mcsdoc/build/deps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24456/deps Log Message: Directory /cvsroot/csdoc/csdoc/src/mcsdoc/build/deps added to the repository |
From: <mas...@us...> - 2004-10-29 14:18:59
|
Update of /cvsroot/csdoc/csdoc/src/mcsdoc/build In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24248 Added Files: config-default.make executable.make library.make rules.make Log Message: 2004-10-28 Gaurav Vaish * **/* : Getting the latest sync from mono repository. Will resume work pretty soon. Moving final work from csdoc to mcsdoc. --- NEW FILE: config-default.make --- # -*- makefile -*- # # This makefile fragment has (default) configuration # settings for building MCS. # DO NOT EDIT THIS FILE! Create config.make and override settings # there. RUNTIME_FLAGS = TEST_HARNESS = $(topdir)/class/lib/$(PROFILE)/nunit-console.exe MCS_FLAGS = $(PLATFORM_DEBUG_FLAGS) MBAS_FLAGS = $(PLATFORM_DEBUG_FLAGS) LIBRARY_FLAGS = /noconfig CFLAGS = -g -O2 INSTALL = /usr/bin/install prefix = /usr/local RUNTIME = mono $(RUNTIME_FLAGS) TEST_RUNTIME = MONO_PATH="$(topdir)/class/lib/$(PROFILE)$(PLATFORM_PATH_SEPARATOR)$(TEST_MONO_PATH)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(RUNTIME) --debug # In case you want to add MCS_FLAGS, this lets you not have to # keep track of the default value DEFAULT_MCS_FLAGS := $(MCS_FLAGS) DEFAULT_MBAS_FLAGS := $(MBAS_FLAGS) # You shouldn't need to set these but might on a # weird platform. # CC = cc # SHELL = /bin/sh # MAKE = gmake --- NEW FILE: executable.make --- # -*- makefile -*- # # The rules for building a program. # I'd rather not create a response file here, # but since on Win32 we need to munge the paths # anyway, we might as well. base_prog = $(shell basename $(PROGRAM)) sourcefile = $(base_prog).sources PROGRAM_config := $(wildcard $(PROGRAM).config) ifeq (cat,$(PLATFORM_CHANGE_SEPARATOR_CMD)) response = $(sourcefile) else response = $(depsdir)/$(base_prog).response executable_CLEAN_FILES += $(response) endif makefrag = $(depsdir)/$(base_prog).makefrag pdb = $(patsubst %.exe,%.pdb,$(PROGRAM)) mdb = $(patsubst %.exe,%.mdb,$(PROGRAM)) executable_CLEAN_FILES += $(makefrag) $(pdb) $(mdb) ifndef PROGRAM_INSTALL_DIR PROGRAM_INSTALL_DIR = $(prefix)/bin endif all-local: $(PROGRAM) install-local: $(PROGRAM) $(PROGRAM_config) $(MKINSTALLDIRS) $(DESTDIR)$(PROGRAM_INSTALL_DIR) $(INSTALL_BIN) $(PROGRAM) $(DESTDIR)$(PROGRAM_INSTALL_DIR) -$(INSTALL_BIN) $(PROGRAM).mdb $(DESTDIR)$(PROGRAM_INSTALL_DIR) ifdef PROGRAM_config $(INSTALL_DATA) $(PROGRAM_config) $(DESTDIR)$(PROGRAM_INSTALL_DIR) endif uninstall-local: -rm -f $(DESTDIR)$(PROGRAM_INSTALL_DIR)/$(base_prog) $(DESTDIR)$(PROGRAM_INSTALL_DIR)/$(base_prog).mdb clean-local: -rm -f *.exe $(BUILT_SOURCES) $(executable_CLEAN_FILES) $(CLEAN_FILES) test-local: $(PROGRAM) @: run-test-local: @: run-test-ondotnet-local: @: DISTFILES = $(sourcefile) $(EXTRA_DISTFILES) dist-local: dist-default for f in `cat $(sourcefile)` ; do \ dest=`dirname $(distdir)/$$f` ; \ $(MKINSTALLDIRS) $$dest && cp $$f $$dest || exit 1 ; \ done ifndef PROGRAM_COMPILE PROGRAM_COMPILE = $(CSCOMPILE) endif $(PROGRAM): $(BUILT_SOURCES) $(EXTRA_SOURCES) $(response) $(PROGRAM_COMPILE) /target:exe /out:$@ $(BUILT_SOURCES) $(EXTRA_SOURCES) @$(response) $(makefrag): $(sourcefile) @echo Creating $@ ... @sed 's,^,$(PROGRAM): ,' $< > $@ ifneq ($(response),$(sourcefile)) $(response): $(sourcefile) @echo Creating $@ ... @( $(PLATFORM_CHANGE_SEPARATOR_CMD) ) <$< >$@ endif -include $(makefrag) all-local: $(makefrag) $(makefrag): $(topdir)/build/executable.make --- NEW FILE: library.make --- # -*- makefile -*- # # The rules for building our class libraries. # # The NO_TEST stuff is not too pleasant but whatcha # gonna do. # All the dep files now land in the same directory so we # munge in the library name to keep the files from clashing. sourcefile = $(LIBRARY).sources PLATFORM_excludes := $(wildcard $(LIBRARY).$(PLATFORM)-excludes) ifndef PLATFORM_excludes ifeq (cat,$(PLATFORM_CHANGE_SEPARATOR_CMD)) response = $(sourcefile) endif endif ifndef response response = $(depsdir)/$(PROFILE)_$(LIBRARY).response library_CLEAN_FILES += $(response) $(LIBRARY).mdb endif ifndef LIBRARY_NAME LIBRARY_NAME = $(LIBRARY) endif makefrag = $(depsdir)/$(PROFILE)_$(LIBRARY).makefrag the_lib = $(topdir)/class/lib/$(PROFILE)/$(LIBRARY_NAME) the_lib_signature_stamp = $(makefrag:.makefrag=.was_signed) the_pdb = $(the_lib:.dll=.pdb) the_mdb = $(the_lib).mdb library_CLEAN_FILES += $(makefrag) $(the_lib) $(the_pdb) \ $(the_mdb) $(the_lib_signature_stamp) ifndef NO_TEST test_nunit_lib = nunit.framework.dll nunit.core.dll nunit.util.dll test_nunit_dep = $(test_nunit_lib:%=$(topdir)/class/lib/$(PROFILE)/%) test_nunit_ref = $(test_nunit_dep:%=-r:%) library_CLEAN_FILES += TestResult*.xml ifndef test_against test_against = $(the_lib) test_dep = $(the_lib) endif ifndef test_lib test_lib = $(LIBRARY:.dll=_test_$(PROFILE).dll) test_sourcefile = $(LIBRARY:.dll=_test.dll.sources) else test_sourcefile = $(test_lib).sources endif test_pdb = $(test_lib:.dll=.pdb) test_response = $(depsdir)/$(test_lib).response test_makefrag = $(depsdir)/$(test_lib).makefrag test_flags = /r:$(test_against) $(test_nunit_ref) $(TEST_MCS_FLAGS) library_CLEAN_FILES += $(LIBRARY:.dll=_test*.dll) $(LIBRARY:.dll=_test*.pdb) $(test_response) $(test_makefrag) ifndef btest_lib btest_lib = $(LIBRARY:.dll=_btest_$(PROFILE).dll) btest_sourcefile = $(LIBRARY:.dll=_btest.dll.sources) else btest_sourcefile = $(btest_lib).sources endif btest_pdb = $(btest_lib:.dll=.pdb) btest_response = $(depsdir)/$(btest_lib).response btest_makefrag = $(depsdir)/$(btest_lib).makefrag btest_flags = /r:$(test_against) $(test_nunit_ref) $(TEST_MBAS_FLAGS) library_CLEAN_FILES += $(LIBRARY:.dll=_btest*.dll) $(LIBRARY:.dll=_btest*.pdb) $(btest_response) $(btest_makefrag) ifndef HAVE_CS_TESTS HAVE_CS_TESTS := $(wildcard $(test_sourcefile)) endif ifndef HAVE_VB_TESTS HAVE_VB_TESTS := $(wildcard $(btest_sourcefile)) endif endif gacutil = $(topdir)/tools/gacutil/gacutil.exe sn = $(topdir)/tools/security/sn.exe PACKAGE = 1.0 ifeq ($(PROFILE), net_2_0) PACKAGE = 2.0 endif ifeq ($(PLATFORM), win32) GACDIR = `cygpath -w $(DESTDIR)$(prefix)/lib` else GACDIR = $(DESTDIR)$(prefix)/lib endif all-local install-local test-local: $(the_lib) ifdef LIBRARY_INSTALL_DIR install-local: $(MKINSTALLDIRS) $(DESTDIR)$(LIBRARY_INSTALL_DIR) $(INSTALL_LIB) $(the_lib) $(DESTDIR)$(LIBRARY_INSTALL_DIR)/$(LIBRARY_NAME) -$(INSTALL_LIB) $(the_lib).mdb $(DESTDIR)$(LIBRARY_INSTALL_DIR)/$(LIBRARY_NAME).mdb uninstall-local: -rm -f $(DESTDIR)$(LIBRARY_INSTALL_DIR)/$(LIBRARY_NAME) $(DESTDIR)$(LIBRARY_INSTALL_DIR)/$(LIBRARY_NAME).mdb else install-local: $(gacutil) MONO_PATH="$(topdir)/class/lib/$(PROFILE):$$MONO_PATH" $(RUNTIME) $(gacutil) /i $(the_lib) /f /root $(GACDIR) /package $(PACKAGE) uninstall-local: $(gacutil) MONO_PATH="$(topdir)/class/lib/$(PROFILE):$$MONO_PATH" $(RUNTIME) $(gacutil) /u $(LIBRARY_NAME:.dll=) endif ifndef NO_SIGN_ASSEMBLY all-local install-local: $(the_lib_signature_stamp) ifndef LIBRARY_SNK LIBRARY_SNK = $(topdir)/class/mono.snk endif $(the_lib_signature_stamp): $(the_lib) $(sn) MONO_PATH="$(topdir)/class/lib/$(PROFILE):$$MONO_PATH" $(RUNTIME) $(sn) -q -R $(the_lib) $(LIBRARY_SNK) echo stamp > $@ endif clean-local: -rm -f $(library_CLEAN_FILES) $(CLEAN_FILES) test-local run-test-local run-test-ondotnet-local: @: ifndef NO_TEST $(test_nunit_dep): $(topdir)/build/deps/nunit-$(PROFILE).stamp @if test -f $@; then :; else rm -f $<; $(MAKE) $<; fi $(topdir)/build/deps/nunit-$(PROFILE).stamp: cd ${topdir}/nunit20 && $(MAKE) echo "stamp" >$@ endif test_assemblies := ifdef HAVE_CS_TESTS test_assemblies += $(test_lib) endif ifdef HAVE_VB_TESTS test_assemblies += $(btest_lib) endif ifdef test_assemblies test-local: $(test_assemblies) run-test-local: run-test-lib run-test-ondotnet-local: run-test-ondotnet-lib run-test-lib: test-local $(TEST_RUNTIME) $(TEST_HARNESS) /xml:TestResult-$(PROFILE).xml $(test_assemblies) run-test-ondotnet-lib: test-local $(TEST_HARNESS) /xml:TestResult-ondotnet-$(PROFILE).xml $(test_assemblies) endif DISTFILES = $(sourcefile) $(test_sourcefile) $(EXTRA_DISTFILES) TEST_FILES = ifdef HAVE_CS_TESTS TEST_FILES += `sed 's,^,Test/,' $(test_sourcefile)` endif ifdef HAVE_VB_TESTS TEST_FILES += `sed 's,^,Test/,' $(btest_sourcefile)` endif dist-local: dist-default for f in `cat $(sourcefile)` $(TEST_FILES) ; do \ case $$f in \ ../*) : ;; \ *) dest=`dirname $(distdir)/$$f` ; $(MKINSTALLDIRS) $$dest && cp $$f $$dest || exit 1 ;; \ esac ; done ifndef LIBRARY_COMPILE LIBRARY_COMPILE = $(CSCOMPILE) endif ifndef TEST_COMPILE TEST_COMPILE = $(CSCOMPILE) endif ifndef BTEST_COMPILE BTEST_COMPILE = $(BASCOMPILE) endif $(gacutil) $(sn): cd $(@D) && $(MAKE) $(@F) # The library $(the_lib): $(response) ifdef LIBRARY_USE_INTERMEDIATE_FILE $(LIBRARY_COMPILE) $(LIBRARY_FLAGS) $(LIB_MCS_FLAGS) /target:library /out:$(@F) @$(response) mv $(@F) $@ -mv $(@F).mdb $@.mdb else $(LIBRARY_COMPILE) $(LIBRARY_FLAGS) $(LIB_MCS_FLAGS) /target:library /out:$@ @$(response) endif $(makefrag): $(sourcefile) @echo Creating $@ ... @sed 's,^,$(the_lib): ,' $< >$@ ifneq ($(response),$(sourcefile)) $(response): $(sourcefile) $(PLATFORM_excludes) @echo Creating $@ ... @sort $(sourcefile) $(PLATFORM_excludes) | uniq -u | $(PLATFORM_CHANGE_SEPARATOR_CMD) >$@ endif -include $(makefrag) # for now, don't give any /lib flags or set MONO_PATH, since we # give a full path to the assembly. ifdef HAVE_CS_TESTS $(test_lib): $(test_dep) $(test_response) $(test_nunit_dep) $(TEST_COMPILE) /target:library /out:$@ $(test_flags) @$(test_response) $(test_response): $(test_sourcefile) @echo Creating $@ ... @sed 's,^,Test/,' $(test_sourcefile) | $(PLATFORM_CHANGE_SEPARATOR_CMD) >$@ $(test_makefrag): $(test_response) @echo Creating $@ ... @sed 's,^,$(test_lib): ,' $< >$@ -include $(test_makefrag) endif ifdef HAVE_VB_TESTS $(btest_lib): $(test_dep) $(btest_response) $(test_nunit_dep) $(BTEST_COMPILE) /target:library /out:$@ $(btest_flags) @$(btest_response) $(btest_response): $(btest_sourcefile) @echo Creating $@ ... @sed 's,^,Test/,' $(btest_sourcefile) | $(PLATFORM_CHANGE_SEPARATOR_CMD) >$@ $(btest_makefrag): $(btest_response) @echo Creating $@ ... @sed 's,^,$(btest_lib): ,' $< >$@ -include $(btest_makefrag) endif all-local: $(makefrag) $(test_makefrag) $(btest_makefrag) $(makefrag) $(test_makefrag) $(btest_makefrag): $(topdir)/build/library.make --- NEW FILE: rules.make --- # -*- makefile -*- # # This is the makefile fragment with default rules # for building things in MCS # # To customize the build, you should edit config.make. # If you need to edit this file, that's a bug; email # pe...@ne... about it. # Some more variables. The leading period in the sed expression prevents # thisdir = . from being changed into '..' for the toplevel directory. dots := $(shell echo $(thisdir) |sed -e 's,[^./][^/]*,..,g') topdir := $(dots) VERSION = 0.93 USE_MCS_FLAGS = $(LOCAL_MCS_FLAGS) $(PLATFORM_MCS_FLAGS) $(PROFILE_MCS_FLAGS) $(MCS_FLAGS) USE_MBAS_FLAGS = $(LOCAL_MBAS_FLAGS) $(PLATFORM_MBAS_FLAGS) $(PROFILE_MBAS_FLAGS) $(MBAS_FLAGS) USE_CFLAGS = $(LOCAL_CFLAGS) $(CFLAGS) CSCOMPILE = $(MCS) $(USE_MCS_FLAGS) BASCOMPILE = $(MBAS) $(USE_MBAS_FLAGS) CCOMPILE = $(CC) $(USE_CFLAGS) BOOT_COMPILE = $(BOOTSTRAP_MCS) $(USE_MCS_FLAGS) INSTALL_DATA = $(INSTALL) -m 644 INSTALL_BIN = $(INSTALL) -m 755 INSTALL_LIB = $(INSTALL_BIN) MKINSTALLDIRS = $(SHELL) $(topdir)/mkinstalldirs INTERNAL_MCS = $(RUNTIME) $(topdir)/mcs/mcs.exe INTERNAL_MBAS = $(RUNTIME) $(topdir)/mbas/mbas.exe INTERNAL_GMCS = $(RUNTIME) $(topdir)/gmcs/gmcs.exe INTERNAL_ILASM = $(RUNTIME) $(topdir)/ilasm/ilasm.exe INTERNAL_RESGEN = $(RUNTIME) $(topdir)/monoresgen/monoresgen.exe corlib = mscorlib.dll depsdir = $(topdir)/build/deps distdir = $(dots)/$(package)/$(thisdir) # Make sure these propagate if set manually export PLATFORM export PROFILE export MCS export MCS_FLAGS export CC export CFLAGS export INSTALL export MKINSTALLDIRS export TEST_HARNESS export BOOTSTRAP_MCS export DESTDIR export RESGEN # Get this so the platform.make platform-check rule doesn't become the # default target .DEFAULT: all default: all # Get initial configuration. pre-config is so that the builder can # override PLATFORM or PROFILE include $(topdir)/build/config-default.make -include $(topdir)/build/pre-config.make # Default PLATFORM and PROFILE if they're not already defined. ifndef PLATFORM ifeq ($(OS),Windows_NT) PLATFORM = win32 else PLATFORM = linux endif endif # Platform config include $(topdir)/build/platforms/$(PLATFORM).make ifdef PLATFORM_CORLIB corlib = $(PLATFORM_CORLIB) endif # Useful ifeq ($(PLATFORM_RUNTIME),$(RUNTIME)) PLATFORM_MONO_NATIVE = yes endif # Rest of the configuration ifndef PROFILE PROFILE = default endif include $(topdir)/build/profiles/$(PROFILE).make -include $(topdir)/build/config.make ifdef OVERRIDE_TARGET_ALL all: all.override else all: all.real endif all.real: all-recursive $(MAKE) all-local STD_TARGETS = test run-test run-test-ondotnet clean install uninstall $(STD_TARGETS): %: %-recursive $(MAKE) $@-local %-recursive: @set . $$MAKEFLAGS; \ case $$2 in --unix) shift ;; esac; \ case $$2 in *=*) dk="exit 1" ;; *k*) dk=: ;; *) dk="exit 1" ;; esac; \ list='$(SUBDIRS)'; for d in $$list ; do \ (cd $$d && $(MAKE) $*) || $$dk ; \ done # note: dist-local dep, extra subdirs, we invoke dist-recursive in the subdir too dist-recursive: dist-local @list='$(SUBDIRS) $(DIST_ONLY_SUBDIRS)'; for d in $$list ; do \ (cd $$d && $(MAKE) $@) || exit 1 ; \ done # Can only do this from the top dir # ## dist: dist-recursive dist-local # We invert the test here to not end in an error # if ChangeLog doesn't exist. # # Note that we error out if we try to dist a nonexistant # file. Seems reasonable to me. # # Pick up Makefile, makefile, or GNUmakefile dist-default: -mkdir -p $(distdir) test '!' -f ChangeLog || cp ChangeLog $(distdir) if test -f Makefile; then m=M; fi; \ if test -f makefile; then m=m; fi; \ if test -f GNUmakefile; then m=GNUm; fi; \ for f in $${m}akefile $(DISTFILES) ; do \ dest=`dirname $(distdir)/$$f` ; \ $(MKINSTALLDIRS) $$dest && cp $$f $$dest || exit 1 ; \ done # Useful withmcs: $(MAKE) MCS='$(INTERNAL_MCS)' BOOTSTRAP_MCS='$(INTERNAL_MCS)' all |
From: <mas...@us...> - 2004-10-29 14:18:39
|
Update of /cvsroot/csdoc/csdoc/src/mcsdoc/class/Mono.CSharp.Debugger In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24165/Mono.CSharp.Debugger Added Files: MonoSymbolFile.cs MonoSymbolTable.cs MonoSymbolWriter.cs Log Message: 2004-10-28 Gaurav Vaish * **/* : Getting the latest sync from mono repository. Will resume work pretty soon. Moving final work from csdoc to mcsdoc. --- NEW FILE: MonoSymbolFile.cs --- // // Mono.CSharp.Debugger/MonoSymbolFile.cs // // Author: // Martin Baulig (ma...@xi...) // // (C) 2003 Ximian, Inc. http://www.ximian.com // // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Reflection; using System.Collections; using System.Text; using System.Threading; using System.IO; namespace Mono.CompilerServices.SymbolWriter { public class MonoSymbolFileException : Exception { public MonoSymbolFileException () : base () { } public MonoSymbolFileException (string message, params object[] args) : base (String.Format (message, args)) { } } internal class MyMemoryStream : Stream { int length; int real_length; int position; int chunk_size = 4096; ArrayList chunks = new ArrayList (); private struct Chunk { public readonly int Offset; public readonly int Length; public byte[] Buffer; public Chunk (int offset, int length) { this.Offset = offset; this.Length = length; this.Buffer = new Byte [length]; } } public override long Position { get { return position; } set { if (value > length) throw new ArgumentOutOfRangeException (); position = (int) value; } } public override long Length { get { return length; } } public override bool CanRead { get { return true; } } public override bool CanWrite { get { return true; } } public override bool CanSeek { get { return true; } } public override void SetLength (long new_length) { if (new_length < length) throw new ArgumentException (); while (new_length >= real_length) { Chunk new_chunk = new Chunk (real_length, chunk_size); chunks.Add (new_chunk); real_length += chunk_size; } length = (int) new_length; } public override void Flush () { } public override long Seek (long offset, SeekOrigin origin) { int ref_point; switch (origin) { case SeekOrigin.Begin: ref_point = 0; break; case SeekOrigin.Current: ref_point = position; break; case SeekOrigin.End: ref_point = length; break; default: throw new ArgumentException ("Invalid SeekOrigin"); } if ((ref_point + offset < 0) || (offset > real_length)) throw new ArgumentOutOfRangeException (); position = ref_point + (int) offset; return position; } Chunk FindChunk (int offset) { return (Chunk) chunks [offset / chunk_size]; } public override int Read (byte[] buffer, int offset, int count) { int old_count = count; while (count > 0) { Chunk chunk = FindChunk (position); int coffset = position - chunk.Offset; int rest = chunk.Length - coffset; int size = System.Math.Min (count, rest); Array.Copy (chunk.Buffer, coffset, buffer, offset, size); position += size; offset += size; count -= size; } return old_count; } public override void Write (byte[] buffer, int offset, int count) { if (position + count > length) SetLength (position + count); while (count > 0) { Chunk chunk = FindChunk (position); int coffset = position - chunk.Offset; int rest = chunk.Length - coffset; int size = System.Math.Min (count, rest); Array.Copy (buffer, offset, chunk.Buffer, coffset, size); position += size; offset += size; count -= size; } } public byte[] GetContents () { byte[] retval = new byte [length]; position = 0; Read (retval, 0, length); return retval; } } internal class MyBinaryWriter : BinaryWriter { public MyBinaryWriter (Stream stream) : base (stream) { } public void WriteLeb128 (int value) { base.Write7BitEncodedInt (value); } } internal class MyBinaryReader : BinaryReader { public MyBinaryReader (Stream stream) : base (stream) { } public int ReadLeb128 () { return base.Read7BitEncodedInt (); } } public class MonoDebuggerSupport { static GetTypeFunc get_type; static GetMethodTokenFunc get_method_token; static GetMethodFunc get_method; static GetLocalTypeFromSignatureFunc local_type_from_sig; static GetGuidFunc get_guid; static CheckRuntimeVersionFunc check_runtime_version; delegate Type GetTypeFunc (Assembly assembly, int token); delegate int GetMethodTokenFunc (Assembly assembly, MethodBase method); delegate MethodBase GetMethodFunc (Assembly assembly, int token); delegate Type GetLocalTypeFromSignatureFunc (Assembly assembly, byte[] sig); delegate Guid GetGuidFunc (Module module); delegate string CheckRuntimeVersionFunc (string filename); static Delegate create_delegate (Type type, Type delegate_type, string name) { MethodInfo mi = type.GetMethod (name, BindingFlags.Static | BindingFlags.NonPublic); if (mi == null) throw new Exception ("Can't find " + name); return Delegate.CreateDelegate (delegate_type, mi); } static MonoDebuggerSupport () { get_type = (GetTypeFunc) create_delegate ( typeof (Assembly), typeof (GetTypeFunc), "MonoDebugger_GetType"); get_method_token = (GetMethodTokenFunc) create_delegate ( typeof (Assembly), typeof (GetMethodTokenFunc), "MonoDebugger_GetMethodToken"); get_method = (GetMethodFunc) create_delegate ( typeof (Assembly), typeof (GetMethodFunc), "MonoDebugger_GetMethod"); local_type_from_sig = (GetLocalTypeFromSignatureFunc) create_delegate ( typeof (Assembly), typeof (GetLocalTypeFromSignatureFunc), "MonoDebugger_GetLocalTypeFromSignature"); get_guid = (GetGuidFunc) create_delegate ( typeof (Module), typeof (GetGuidFunc), "Mono_GetGuid"); check_runtime_version = (CheckRuntimeVersionFunc) create_delegate ( typeof (Assembly), typeof (CheckRuntimeVersionFunc), "MonoDebugger_CheckRuntimeVersion"); } public static Type GetType (Assembly assembly, int token) { return get_type (assembly, token); } public static int GetMethodToken (MethodBase method) { return get_method_token (method.ReflectedType.Assembly, method); } public static MethodBase GetMethod (Assembly assembly, int token) { return get_method (assembly, token); } public static Type GetLocalTypeFromSignature (Assembly assembly, byte[] sig) { return local_type_from_sig (assembly, sig); } public static string CheckRuntimeVersion (string filename) { return check_runtime_version (filename); } public static Guid GetGuid (Module module) { return get_guid (module); } } public class MonoSymbolFile : IDisposable { ArrayList methods = new ArrayList (); ArrayList sources = new ArrayList (); Hashtable method_source_hash = new Hashtable (); Hashtable type_hash = new Hashtable (); OffsetTable ot; int last_type_index; int last_method_index; int last_source_index; int last_namespace_index; public int NumLineNumbers; public MonoSymbolFile () { } internal int AddSource (SourceFileEntry source) { sources.Add (source); return ++last_source_index; } internal int DefineType (Type type) { if (type_hash.Contains (type)) return (int) type_hash [type]; int index = ++last_type_index; type_hash.Add (type, index); return index; } internal void AddMethod (MethodEntry entry) { methods.Add (entry); } internal int GetNextTypeIndex () { return ++last_type_index; } internal int GetNextMethodIndex () { return ++last_method_index; } internal int GetNextNamespaceIndex () { return ++last_namespace_index; } byte [] stringBuffer; int maxCharsPerRound; static Encoding enc = Encoding.UTF8; internal string ReadString (int offset) { int old_pos = (int) reader.BaseStream.Position; reader.BaseStream.Position = offset; string text = reader.ReadString (); reader.BaseStream.Position = old_pos; return text; } void Write (MyBinaryWriter bw, Guid guid) { // Magic number and file version. bw.Write (OffsetTable.Magic); bw.Write (OffsetTable.Version); bw.Write (guid.ToByteArray ()); // // Offsets of file sections; we must write this after we're done // writing the whole file, so we just reserve the space for it here. // long offset_table_offset = bw.BaseStream.Position; ot.Write (bw); // // Write data sections. // ot.DataSectionOffset = (int) bw.BaseStream.Position; foreach (SourceFileEntry source in sources) source.WriteData (bw); ot.DataSectionSize = (int) bw.BaseStream.Position - ot.DataSectionOffset; // // Write out the method index // ot.MethodTableOffset = (int) bw.BaseStream.Position; for (int i = 0; i < methods.Count; i++) { MethodEntry entry = (MethodEntry) methods [i]; entry.WriteIndex (bw); } ot.MethodTableSize = (int) bw.BaseStream.Position - ot.MethodTableOffset; // // Write source table. // ot.SourceTableOffset = (int) bw.BaseStream.Position; for (int i = 0; i < sources.Count; i++) { SourceFileEntry source = (SourceFileEntry) sources [i]; source.Write (bw); } ot.SourceTableSize = (int) bw.BaseStream.Position - ot.SourceTableOffset; // // Fixup offset table. // ot.TypeCount = last_type_index; ot.MethodCount = methods.Count; ot.SourceCount = sources.Count; // // Write offset table. // ot.TotalFileSize = (int) bw.BaseStream.Position; bw.Seek ((int) offset_table_offset, SeekOrigin.Begin); ot.Write (bw); bw.Seek (0, SeekOrigin.End); } public byte[] CreateSymbolFile (Guid guid) { if (reader != null) throw new InvalidOperationException (); using (MyMemoryStream stream = new MyMemoryStream ()) { Write (new MyBinaryWriter (stream), guid); return stream.GetContents (); } } Assembly assembly; MyBinaryReader reader; Hashtable method_hash; Hashtable source_file_hash; Hashtable method_token_hash; Hashtable source_name_hash; protected MonoSymbolFile (string filename, Assembly assembly) { this.assembly = assembly; FileStream stream = new FileStream (filename, FileMode.Open, FileAccess.Read); reader = new MyBinaryReader (stream); Guid guid; try { long magic = reader.ReadInt64 (); long version = reader.ReadInt32 (); if (magic != OffsetTable.Magic) throw new MonoSymbolFileException ( "Symbol file `{0}' is not a valid " + "Mono symbol file", filename); if (version != OffsetTable.Version) throw new MonoSymbolFileException ( "Symbol file `{0}' has version {1}, " + "but expected {2}", filename, version, OffsetTable.Version); guid = new Guid (reader.ReadBytes (16)); ot = new OffsetTable (reader); } catch { throw new MonoSymbolFileException ( "Cannot read symbol file `{0}'", filename); } Module[] modules = assembly.GetModules (); Guid assembly_guid = MonoDebuggerSupport.GetGuid (modules [0]); if (guid != assembly_guid) throw new MonoSymbolFileException ( "Symbol file `{0}' does not match assembly `{1}'", filename, assembly.Location); method_hash = new Hashtable (); source_file_hash = new Hashtable (); } public static MonoSymbolFile ReadSymbolFile (Assembly assembly) { string filename = assembly.Location; string name = filename + ".mdb"; return new MonoSymbolFile (name, assembly); } public Assembly Assembly { get { return assembly; } } public int SourceCount { get { return ot.SourceCount; } } public int MethodCount { get { return ot.MethodCount; } } public int TypeCount { get { return ot.TypeCount; } } public int NamespaceCount { get { return last_namespace_index; } } internal int LineNumberCount = 0; internal int LocalCount = 0; internal int StringSize = 0; public SourceFileEntry GetSourceFile (int index) { if ((index < 1) || (index > ot.SourceCount)) throw new ArgumentException (); if (reader == null) throw new InvalidOperationException (); SourceFileEntry source = (SourceFileEntry) source_file_hash [index]; if (source != null) return source; reader.BaseStream.Position = ot.SourceTableOffset + SourceFileEntry.Size * (index - 1); source = new SourceFileEntry (this, reader); source_file_hash.Add (index, source); return source; } public SourceFileEntry[] Sources { get { if (reader == null) throw new InvalidOperationException (); SourceFileEntry[] retval = new SourceFileEntry [SourceCount]; for (int i = 0; i < SourceCount; i++) retval [i] = GetSourceFile (i + 1); return retval; } } public MethodIndexEntry GetMethodIndexEntry (int index) { int old_pos = (int) reader.BaseStream.Position; reader.BaseStream.Position = ot.MethodTableOffset + MethodIndexEntry.Size * (index - 1); MethodIndexEntry ie = new MethodIndexEntry (reader); reader.BaseStream.Position = old_pos; return ie; } public MethodEntry GetMethodByToken (int token) { if (reader == null) throw new InvalidOperationException (); if (method_token_hash == null) { method_token_hash = new Hashtable (); for (int i = 0; i < MethodCount; i++) { MethodIndexEntry ie = GetMethodIndexEntry (i + 1); method_token_hash.Add (ie.Token, i + 1); } } object value = method_token_hash [token]; if (value == null) return null; return GetMethod ((int) value); } public MethodEntry GetMethod (MethodBase method) { if (reader == null) throw new InvalidOperationException (); int token = MonoDebuggerSupport.GetMethodToken (method); return GetMethodByToken (token); } public MethodEntry GetMethod (int index) { if ((index < 1) || (index > ot.MethodCount)) throw new ArgumentException (); if (reader == null) throw new InvalidOperationException (); MethodEntry entry = (MethodEntry) method_hash [index]; if (entry != null) return entry; MethodIndexEntry ie = GetMethodIndexEntry (index); reader.BaseStream.Position = ie.FileOffset; entry = new MethodEntry (this, reader, index); method_hash.Add (index, entry); return entry; } public MethodEntry[] Methods { get { if (reader == null) throw new InvalidOperationException (); MethodEntry[] retval = new MethodEntry [MethodCount]; for (int i = 0; i < MethodCount; i++) retval [i] = GetMethod (i + 1); return retval; } } public MethodSourceEntry GetMethodSource (int index) { if ((index < 1) || (index > ot.MethodCount)) throw new ArgumentException (); if (reader == null) throw new InvalidOperationException (); object entry = method_source_hash [index]; if (entry != null) return (MethodSourceEntry) entry; MethodEntry method = GetMethod (index); foreach (MethodSourceEntry source in method.SourceFile.Methods) { if (source.Index == index) { method_source_hash.Add (index, source); return source; } } throw new MonoSymbolFileException ("Internal error."); } public int FindSource (string file_name) { if (reader == null) throw new InvalidOperationException (); if (source_name_hash == null) { source_name_hash = new Hashtable (); for (int i = 0; i < ot.SourceCount; i++) { SourceFileEntry source = GetSourceFile (i + 1); source_name_hash.Add (source.FileName, i); } } object value = source_name_hash [file_name]; if (value == null) return -1; return (int) value; } internal MyBinaryReader BinaryReader { get { if (reader == null) throw new InvalidOperationException (); return reader; } } void IDisposable.Dispose () { Dispose (true); } protected virtual void Dispose (bool disposing) { if (disposing) { if (reader != null) { reader.Close (); reader = null; } } } } } --- NEW FILE: MonoSymbolTable.cs --- // // Mono.CSharp.Debugger/MonoSymbolTable.cs // // Author: // Martin Baulig (ma...@xi...) // // (C) 2002 Ximian, Inc. http://www.ximian.com // // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections; using System.Text; using System.IO; // // Parts which are actually written into the symbol file are marked with // // #region This is actually written to the symbol file // #endregion // // Please do not modify these regions without previously talking to me. // // All changes to the file format must be synchronized in several places: // // a) The fields in these regions (and their order) must match the actual // contents of the symbol file. // // This helps people to understand the symbol file format without reading // too much source code, ie. you look at the appropriate region and then // you know what's actually in the file. // // It is also required to help me enforce b). // // b) The regions must be kept in sync with the unmanaged code in // mono/metadata/debug-mono-symfile.h // // When making changes to the file format, you must also increase two version // numbers: // // i) OffsetTable.Version in this file. // ii) MONO_SYMBOL_FILE_VERSION in mono/metadata/debug-mono-symfile.h // // After doing so, recompile everything, including the debugger. Symbol files // with different versions are incompatible to each other and the debugger and // the runtime enfore this, so you need to recompile all your assemblies after // changing the file format. // namespace Mono.CompilerServices.SymbolWriter { public struct OffsetTable { public const int Version = 38; public const long Magic = 0x45e82623fd7fa614; #region This is actually written to the symbol file public int TotalFileSize; public int DataSectionOffset; public int DataSectionSize; public int SourceCount; public int SourceTableOffset; public int SourceTableSize; public int MethodCount; public int MethodTableOffset; public int MethodTableSize; public int TypeCount; #endregion internal OffsetTable (BinaryReader reader) { TotalFileSize = reader.ReadInt32 (); DataSectionOffset = reader.ReadInt32 (); DataSectionSize = reader.ReadInt32 (); SourceCount = reader.ReadInt32 (); SourceTableOffset = reader.ReadInt32 (); SourceTableSize = reader.ReadInt32 (); MethodCount = reader.ReadInt32 (); MethodTableOffset = reader.ReadInt32 (); MethodTableSize = reader.ReadInt32 (); TypeCount = reader.ReadInt32 (); } internal void Write (BinaryWriter bw) { bw.Write (TotalFileSize); bw.Write (DataSectionOffset); bw.Write (DataSectionSize); bw.Write (SourceCount); bw.Write (SourceTableOffset); bw.Write (SourceTableSize); bw.Write (MethodCount); bw.Write (MethodTableOffset); bw.Write (MethodTableSize); bw.Write (TypeCount); } public override string ToString () { return String.Format ( "OffsetTable [{0} - {1}:{2} - {3}:{4}:{5} - {6}:{7}:{8} - {9}]", TotalFileSize, DataSectionOffset, DataSectionSize, SourceCount, SourceTableOffset, SourceTableSize, MethodCount, MethodTableOffset, MethodTableSize, TypeCount); } } public struct LineNumberEntry { #region This is actually written to the symbol file public readonly int Row; public readonly int Offset; #endregion public LineNumberEntry (int row, int offset) { this.Row = row; this.Offset = offset; } public static LineNumberEntry Null = new LineNumberEntry (0, 0); internal LineNumberEntry (BinaryReader reader) { Row = reader.ReadInt32 (); Offset = reader.ReadInt32 (); } internal void Write (BinaryWriter bw) { bw.Write (Row); bw.Write (Offset); } private class OffsetComparerClass : IComparer { public int Compare (object a, object b) { LineNumberEntry l1 = (LineNumberEntry) a; LineNumberEntry l2 = (LineNumberEntry) b; if (l1.Offset < l2.Offset) return -1; else if (l1.Offset > l2.Offset) return 1; else return 0; } } private class RowComparerClass : IComparer { public int Compare (object a, object b) { LineNumberEntry l1 = (LineNumberEntry) a; LineNumberEntry l2 = (LineNumberEntry) b; if (l1.Row < l2.Row) return -1; else if (l1.Row > l2.Row) return 1; else return 0; } } public static readonly IComparer OffsetComparer = new OffsetComparerClass (); public static readonly IComparer RowComparer = new RowComparerClass (); public override string ToString () { return String.Format ("[Line {0}:{1}]", Row, Offset); } } public class LexicalBlockEntry { public int Index; #region This is actually written to the symbol file public int StartOffset; public int EndOffset; #endregion public LexicalBlockEntry (int index, int start_offset) { this.Index = index; this.StartOffset = start_offset; } internal LexicalBlockEntry (int index, MyBinaryReader reader) { this.Index = index; this.StartOffset = reader.ReadInt32 (); this.EndOffset = reader.ReadInt32 (); } public void Close (int end_offset) { this.EndOffset = end_offset; } internal void Write (MyBinaryWriter bw) { bw.Write (StartOffset); bw.Write (EndOffset); } public override string ToString () { return String.Format ("[LexicalBlock {0}:{1}]", StartOffset, EndOffset); } } public struct LocalVariableEntry { #region This is actually written to the symbol file public readonly string Name; public readonly byte[] Signature; public readonly int BlockIndex; #endregion public LocalVariableEntry (string Name, byte[] Signature, int BlockIndex) { this.Name = Name; this.Signature = Signature; this.BlockIndex = BlockIndex; } internal LocalVariableEntry (MyBinaryReader reader) { Name = reader.ReadString (); int sig_length = reader.ReadLeb128 (); Signature = reader.ReadBytes (sig_length); BlockIndex = reader.ReadLeb128 (); } internal void Write (MonoSymbolFile file, MyBinaryWriter bw) { bw.Write (Name); bw.WriteLeb128 ((int) Signature.Length); bw.Write (Signature); bw.WriteLeb128 (BlockIndex); } public override string ToString () { return String.Format ("[LocalVariable {0}]", Name); } } public class SourceFileEntry { #region This is actually written to the symbol file public readonly int Index; int Count; int NamespaceCount; int NameOffset; int MethodOffset; int NamespaceTableOffset; #endregion MonoSymbolFile file; string file_name; ArrayList methods; ArrayList namespaces; bool creating; public static int Size { get { return 24; } } public SourceFileEntry (MonoSymbolFile file, string file_name) { this.file = file; this.file_name = file_name; this.Index = file.AddSource (this); creating = true; methods = new ArrayList (); namespaces = new ArrayList (); } public void DefineMethod (string name, int token, LocalVariableEntry[] locals, LineNumberEntry[] lines, LexicalBlockEntry[] blocks, int start, int end, int namespace_id) { if (!creating) throw new InvalidOperationException (); MethodEntry entry = new MethodEntry ( file, this, name, (int) token, locals, lines, blocks, start, end, namespace_id); methods.Add (entry); file.AddMethod (entry); } public int DefineNamespace (string name, string[] using_clauses, int parent) { if (!creating) throw new InvalidOperationException (); int index = file.GetNextNamespaceIndex (); NamespaceEntry ns = new NamespaceEntry (name, index, using_clauses, parent); namespaces.Add (ns); return index; } internal void WriteData (MyBinaryWriter bw) { NameOffset = (int) bw.BaseStream.Position; bw.Write (file_name); ArrayList list = new ArrayList (); foreach (MethodEntry entry in methods) list.Add (entry.Write (file, bw)); list.Sort (); Count = list.Count; MethodOffset = (int) bw.BaseStream.Position; foreach (MethodSourceEntry method in list) method.Write (bw); NamespaceCount = namespaces.Count; NamespaceTableOffset = (int) bw.BaseStream.Position; foreach (NamespaceEntry ns in namespaces) ns.Write (file, bw); } internal void Write (BinaryWriter bw) { bw.Write (Index); bw.Write (Count); bw.Write (NamespaceCount); bw.Write (NameOffset); bw.Write (MethodOffset); bw.Write (NamespaceTableOffset); } internal SourceFileEntry (MonoSymbolFile file, BinaryReader reader) { this.file = file; Index = reader.ReadInt32 (); Count = reader.ReadInt32 (); NamespaceCount = reader.ReadInt32 (); NameOffset = reader.ReadInt32 (); MethodOffset = reader.ReadInt32 (); NamespaceTableOffset = reader.ReadInt32 (); file_name = file.ReadString (NameOffset); } public string FileName { get { return file_name; } } public MethodSourceEntry[] Methods { get { if (creating) throw new InvalidOperationException (); BinaryReader reader = file.BinaryReader; int old_pos = (int) reader.BaseStream.Position; reader.BaseStream.Position = MethodOffset; ArrayList list = new ArrayList (); for (int i = 0; i < Count; i ++) list.Add (new MethodSourceEntry (reader)); reader.BaseStream.Position = old_pos; MethodSourceEntry[] retval = new MethodSourceEntry [Count]; list.CopyTo (retval, 0); return retval; } } public NamespaceEntry[] Namespaces { get { if (creating) throw new InvalidOperationException (); MyBinaryReader reader = file.BinaryReader; int old_pos = (int) reader.BaseStream.Position; reader.BaseStream.Position = NamespaceTableOffset; ArrayList list = new ArrayList (); for (int i = 0; i < NamespaceCount; i ++) list.Add (new NamespaceEntry (file, reader)); reader.BaseStream.Position = old_pos; NamespaceEntry[] retval = new NamespaceEntry [list.Count]; list.CopyTo (retval, 0); return retval; } } public override string ToString () { return String.Format ("SourceFileEntry ({0}:{1}:{2})", Index, file_name, Count); } } public struct MethodSourceEntry : IComparable { #region This is actually written to the symbol file public readonly int Index; public readonly int FileOffset; public readonly int StartRow; public readonly int EndRow; #endregion public MethodSourceEntry (int index, int file_offset, int start, int end) { this.Index = index; this.FileOffset = file_offset; this.StartRow = start; this.EndRow = end; } internal MethodSourceEntry (BinaryReader reader) { Index = reader.ReadInt32 (); FileOffset = reader.ReadInt32 (); StartRow = reader.ReadInt32 (); EndRow = reader.ReadInt32 (); } public static int Size { get { return 16; } } internal void Write (BinaryWriter bw) { bw.Write (Index); bw.Write (FileOffset); bw.Write (StartRow); bw.Write (EndRow); } public int CompareTo (object obj) { MethodSourceEntry method = (MethodSourceEntry) obj; if (method.StartRow < StartRow) return -1; else if (method.StartRow > StartRow) return 1; else return 0; } public override string ToString () { return String.Format ("MethodSourceEntry ({0}:{1}:{2}:{3})", Index, FileOffset, StartRow, EndRow); } } public struct MethodIndexEntry { #region This is actually written to the symbol file public readonly int FileOffset; public readonly int Token; #endregion public static int Size { get { return 8; } } public MethodIndexEntry (int offset, int token) { this.FileOffset = offset; this.Token = token; } internal MethodIndexEntry (BinaryReader reader) { FileOffset = reader.ReadInt32 (); Token = reader.ReadInt32 (); } internal void Write (BinaryWriter bw) { bw.Write (FileOffset); bw.Write (Token); } public override string ToString () { return String.Format ("MethodIndexEntry ({0}:{1:x})", FileOffset, Token); } } public class MethodEntry : IComparable { #region This is actually written to the symbol file public readonly int SourceFileIndex; public readonly int Token; public readonly int StartRow; public readonly int EndRow; public readonly int NumLocals; public readonly int NumLineNumbers; public readonly int NamespaceID; public readonly bool LocalNamesAmbiguous; int NameOffset; int TypeIndexTableOffset; int LocalVariableTableOffset; int LineNumberTableOffset; int NumLexicalBlocks; int LexicalBlockTableOffset; #endregion int file_offset; public readonly int Index; public readonly SourceFileEntry SourceFile; public readonly LineNumberEntry[] LineNumbers; public readonly int[] LocalTypeIndices; public readonly LocalVariableEntry[] Locals; public readonly LexicalBlockEntry[] LexicalBlocks; public readonly MonoSymbolFile SymbolFile; public static int Size { get { return 52; } } internal MethodEntry (MonoSymbolFile file, MyBinaryReader reader, int index) { this.SymbolFile = file; this.Index = index; SourceFileIndex = reader.ReadInt32 (); Token = reader.ReadInt32 (); StartRow = reader.ReadInt32 (); EndRow = reader.ReadInt32 (); NumLocals = reader.ReadInt32 (); NumLineNumbers = reader.ReadInt32 (); NameOffset = reader.ReadInt32 (); TypeIndexTableOffset = reader.ReadInt32 (); LocalVariableTableOffset = reader.ReadInt32 (); LineNumberTableOffset = reader.ReadInt32 (); NumLexicalBlocks = reader.ReadInt32 (); LexicalBlockTableOffset = reader.ReadInt32 (); NamespaceID = reader.ReadInt32 (); LocalNamesAmbiguous = reader.ReadInt32 () != 0; SourceFile = file.GetSourceFile (SourceFileIndex); if (LineNumberTableOffset != 0) { long old_pos = reader.BaseStream.Position; reader.BaseStream.Position = LineNumberTableOffset; LineNumbers = new LineNumberEntry [NumLineNumbers]; for (int i = 0; i < NumLineNumbers; i++) LineNumbers [i] = new LineNumberEntry (reader); reader.BaseStream.Position = old_pos; } if (LocalVariableTableOffset != 0) { long old_pos = reader.BaseStream.Position; reader.BaseStream.Position = LocalVariableTableOffset; Locals = new LocalVariableEntry [NumLocals]; for (int i = 0; i < NumLocals; i++) Locals [i] = new LocalVariableEntry (reader); reader.BaseStream.Position = old_pos; } if (TypeIndexTableOffset != 0) { long old_pos = reader.BaseStream.Position; reader.BaseStream.Position = TypeIndexTableOffset; LocalTypeIndices = new int [NumLocals]; for (int i = 0; i < NumLocals; i++) LocalTypeIndices [i] = reader.ReadInt32 (); reader.BaseStream.Position = old_pos; } if (LexicalBlockTableOffset != 0) { long old_pos = reader.BaseStream.Position; reader.BaseStream.Position = LexicalBlockTableOffset; LexicalBlocks = new LexicalBlockEntry [NumLexicalBlocks]; for (int i = 0; i < NumLexicalBlocks; i++) LexicalBlocks [i] = new LexicalBlockEntry (i, reader); reader.BaseStream.Position = old_pos; } } internal MethodEntry (MonoSymbolFile file, SourceFileEntry source, string name, int token, LocalVariableEntry[] locals, LineNumberEntry[] lines, LexicalBlockEntry[] blocks, int start_row, int end_row, int namespace_id) { this.SymbolFile = file; Index = file.GetNextMethodIndex (); Token = token; SourceFileIndex = source.Index; SourceFile = source; StartRow = start_row; EndRow = end_row; NamespaceID = namespace_id; LexicalBlocks = blocks; NumLexicalBlocks = LexicalBlocks != null ? LexicalBlocks.Length : 0; LineNumbers = BuildLineNumberTable (lines); NumLineNumbers = LineNumbers.Length; file.NumLineNumbers += NumLineNumbers; NumLocals = locals != null ? locals.Length : 0; Locals = locals; if (NumLocals <= 32) { // Most of the time, the O(n^2) factor is actually // less than the cost of allocating the hash table, // 32 is a rough number obtained through some testing. for (int i = 0; i < NumLocals; i ++) { string nm = locals [i].Name; for (int j = i + 1; j < NumLocals; j ++) { if (locals [j].Name == nm) { LocalNamesAmbiguous = true; goto locals_check_done; } } } locals_check_done : ; } else { Hashtable local_names = new Hashtable (); foreach (LocalVariableEntry local in locals) { if (local_names.Contains (local.Name)) { LocalNamesAmbiguous = true; break; } local_names.Add (local.Name, local); } } LocalTypeIndices = new int [NumLocals]; for (int i = 0; i < NumLocals; i++) LocalTypeIndices [i] = file.GetNextTypeIndex (); } static LineNumberEntry [] tmp_buff = new LineNumberEntry [20]; // BuildLineNumberTable() eliminates duplicate line numbers and ensures // we aren't going "backwards" since this would counfuse the runtime's // debugging code (and the debugger). // // In the line number table, the "offset" field most be strictly // monotonic increasing; that is, the next entry must not have an offset // which is equal to or less than the current one. // // The most common case is that our input (ie. the line number table as // we get it from mcs) contains several entries with the same offset // (and different line numbers) - but it may also happen that the offset // is decreasing (this can be considered as an exception, such lines will // simply be discarded). LineNumberEntry[] BuildLineNumberTable (LineNumberEntry[] line_numbers) { int pos = 0; int last_offset = -1; int last_row = -1; if (line_numbers == null) return new LineNumberEntry [0]; if (tmp_buff.Length < (line_numbers.Length + 1)) tmp_buff = new LineNumberEntry [(line_numbers.Length + 1) * 2]; for (int i = 0; i < line_numbers.Length; i++) { LineNumberEntry line = line_numbers [i]; if (line.Offset > last_offset) { if (last_row >= 0) tmp_buff [pos ++] = new LineNumberEntry (last_row, last_offset); last_row = line.Row; last_offset = line.Offset; } else if (line.Row > last_row) { last_row = line.Row; } } if (last_row >= 0) tmp_buff [pos ++] = new LineNumberEntry (last_row, last_offset); LineNumberEntry [] retval = new LineNumberEntry [pos]; Array.Copy (tmp_buff, retval, pos); return retval; } internal MethodSourceEntry Write (MonoSymbolFile file, MyBinaryWriter bw) { NameOffset = (int) bw.BaseStream.Position; TypeIndexTableOffset = (int) bw.BaseStream.Position; for (int i = 0; i < NumLocals; i++) bw.Write (LocalTypeIndices [i]); LocalVariableTableOffset = (int) bw.BaseStream.Position; for (int i = 0; i < NumLocals; i++) Locals [i].Write (file, bw); file.LocalCount += NumLocals; LineNumberTableOffset = (int) bw.BaseStream.Position; for (int i = 0; i < NumLineNumbers; i++) LineNumbers [i].Write (bw); file.LineNumberCount += NumLineNumbers; LexicalBlockTableOffset = (int) bw.BaseStream.Position; for (int i = 0; i < NumLexicalBlocks; i++) LexicalBlocks [i].Write (bw); file_offset = (int) bw.BaseStream.Position; bw.Write (SourceFileIndex); bw.Write (Token); bw.Write (StartRow); bw.Write (EndRow); bw.Write (NumLocals); bw.Write (NumLineNumbers); bw.Write (NameOffset); bw.Write (TypeIndexTableOffset); bw.Write (LocalVariableTableOffset); bw.Write (LineNumberTableOffset); bw.Write (NumLexicalBlocks); bw.Write (LexicalBlockTableOffset); bw.Write (NamespaceID); bw.Write (LocalNamesAmbiguous ? 1 : 0); return new MethodSourceEntry (Index, file_offset, StartRow, EndRow); } internal void WriteIndex (BinaryWriter bw) { new MethodIndexEntry (file_offset, Token).Write (bw); } public int CompareTo (object obj) { MethodEntry method = (MethodEntry) obj; if (method.Token < Token) return 1; else if (method.Token > Token) return -1; else return 0; } public override string ToString () { return String.Format ("[Method {0}:{1}:{2}:{3}:{4} - {6}:{7} - {5}]", Index, Token, SourceFileIndex, StartRow, EndRow, SourceFile, NumLocals, NumLineNumbers); } } public struct NamespaceEntry { #region This is actually written to the symbol file public readonly string Name; public readonly int Index; public readonly int Parent; public readonly string[] UsingClauses; #endregion public NamespaceEntry (string name, int index, string[] using_clauses, int parent) { this.Name = name; this.Index = index; this.Parent = parent; this.UsingClauses = using_clauses != null ? using_clauses : new string [0]; } internal NamespaceEntry (MonoSymbolFile file, MyBinaryReader reader) { Name = reader.ReadString (); Index = reader.ReadLeb128 (); Parent = reader.ReadLeb128 (); int count = reader.ReadLeb128 (); UsingClauses = new string [count]; for (int i = 0; i < count; i++) UsingClauses [i] = reader.ReadString (); } internal void Write (MonoSymbolFile file, MyBinaryWriter bw) { bw.Write (Name); bw.WriteLeb128 (Index); bw.WriteLeb128 (Parent); bw.WriteLeb128 (UsingClauses.Length); foreach (string uc in UsingClauses) bw.Write (uc); } public override string ToString () { return String.Format ("[Namespace {0}:{1}:{2}]", Name, Index, Parent); } } } --- NEW FILE: MonoSymbolWriter.cs --- // // Mono.CSharp.Debugger/MonoSymbolWriter.cs // // Author: // Martin Baulig (ma...@xi...) // // This is the default implementation of the System.Diagnostics.SymbolStore.ISymbolWriter // interface. // // (C) 2002 Ximian, Inc. http://www.ximian.com // // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Runtime.CompilerServices; using System.Collections; using System.IO; namespace Mono.CompilerServices.SymbolWriter { public interface ISourceFile { SourceFileEntry Entry { get; } } public interface ISourceMethod { string Name { get; } int NamespaceID { get; } int Token { get; } } public class MonoSymbolWriter { protected ArrayList locals = null; protected ArrayList methods = null; protected ArrayList sources = null; protected readonly MonoSymbolFile file; private string filename = null; LineNumberEntry [] current_method_lines; int current_method_lines_pos = 0; internal ISourceFile[] Sources { get { ISourceFile[] retval = new ISourceFile [sources.Count]; sources.CopyTo (retval, 0); return retval; } } private SourceMethod current_method = null; // // Interface IMonoSymbolWriter // public MonoSymbolWriter (string filename) { this.methods = new ArrayList (); this.sources = new ArrayList (); this.locals = new ArrayList (); this.file = new MonoSymbolFile (); this.filename = filename + ".mdb"; this.current_method_lines = new LineNumberEntry [50]; } public void CloseNamespace () { } public void DefineLocalVariable (string name, byte[] signature) { if (current_method == null) return; current_method.AddLocal (name, signature); } public void MarkSequencePoint (int offset, int line, int column) { if (current_method == null) return; if (current_method_lines_pos == current_method_lines.Length) { LineNumberEntry [] tmp = current_method_lines; current_method_lines = new LineNumberEntry [current_method_lines.Length * 2]; Array.Copy (tmp, current_method_lines, current_method_lines_pos); } current_method_lines [current_method_lines_pos++] = new LineNumberEntry (line, offset); } public void OpenMethod (ISourceFile file, ISourceMethod method, int startRow, int startColumn, int endRow, int endColumn) { SourceMethod source = new SourceMethod ( file, method, startRow, startColumn, endRow, endColumn); current_method = source; methods.Add (current_method); } public void CloseMethod () { current_method.SetLineNumbers ( current_method_lines, current_method_lines_pos); current_method_lines_pos = 0; current_method = null; } public SourceFileEntry DefineDocument (string url) { SourceFileEntry entry = new SourceFileEntry (file, url); sources.Add (entry); return entry; } public int DefineNamespace (string name, SourceFileEntry source, string[] using_clauses, int parent) { if ((source == null) || (using_clauses == null)) throw new NullReferenceException (); return source.DefineNamespace (name, using_clauses, parent); } public int OpenScope (int startOffset) { if (current_method == null) return 0; current_method.StartBlock (startOffset); return 0; } public void CloseScope (int endOffset) { if (current_method == null) return; current_method.EndBlock (endOffset); } protected byte[] CreateOutput (Guid guid) { foreach (SourceMethod method in methods) { method.SourceFile.Entry.DefineMethod ( method.Method.Name, method.Method.Token, method.Locals, method.Lines, method.Blocks, method.Start.Row, method.End.Row, method.Method.NamespaceID); } return file.CreateSymbolFile (guid); } public void WriteSymbolFile (Guid guid) { using (FileStream stream = new FileStream ( filename, FileMode.Create, FileAccess.Write)) { byte[] data = CreateOutput (guid); stream.Write (data, 0, data.Length); } } protected class SourceMethod { LineNumberEntry [] lines; private ArrayList _locals; private ArrayList _blocks; private Stack _block_stack; private int next_block_id = 0; private ISourceMethod _method; private ISourceFile _file; private LineNumberEntry _start, _end; private LexicalBlockEntry _implicit_block; public SourceMethod (ISourceFile file, ISourceMethod method, int startLine, int startColumn, int endLine, int endColumn) { this._file = file; this._method = method; this._start = new LineNumberEntry (startLine, 0); this._end = new LineNumberEntry (endLine, 0); this._implicit_block = new LexicalBlockEntry (0, 0); } public void StartBlock (int startOffset) { LexicalBlockEntry block = new LexicalBlockEntry ( ++next_block_id, startOffset); if (_block_stack == null) _block_stack = new Stack (); _block_stack.Push (block); if (_blocks == null) _blocks = new ArrayList (); _blocks.Add (block); } public void EndBlock (int endOffset) { LexicalBlockEntry block = (LexicalBlockEntry) _block_stack.Pop (); block.Close (endOffset); } public LexicalBlockEntry[] Blocks { get { if (_blocks == null) return new LexicalBlockEntry [0]; else { LexicalBlockEntry[] retval = new LexicalBlockEntry [_blocks.Count]; _blocks.CopyTo (retval, 0); return retval; } } } public LexicalBlockEntry CurrentBlock { get { if ((_block_stack != null) && (_block_stack.Count > 0)) return (LexicalBlockEntry) _block_stack.Peek (); else return _implicit_block; } } public LineNumberEntry[] Lines { get { return lines; } } public LocalVariableEntry[] Locals { get { if (_locals == null) return new LocalVariableEntry [0]; else { LocalVariableEntry[] retval = new LocalVariableEntry [_locals.Count]; _locals.CopyTo (retval, 0); return retval; } } } public void AddLocal (string name, byte[] signature) { if (_locals == null) _locals = new ArrayList (); _locals.Add (new LocalVariableEntry ( name, signature, CurrentBlock.Index)); } public ISourceFile SourceFile { get { return _file; } } public ISourceMethod Method { get { return _method; } } public LineNumberEntry Start { get { return _start; } } public LineNumberEntry End { get { return _end; } } // // Passes on the lines from the MonoSymbolWriter. This method is // free to mutate the lns array, and it does. // internal void SetLineNumbers (LineNumberEntry [] lns, int count) { int pos = 0; int last_offset = -1; int last_row = -1; for (int i = 0; i < count; i++) { LineNumberEntry line = lns [i]; if (line.Offset > last_offset) { if (last_row >= 0) lns [pos++] = new LineNumberEntry ( last_row, last_offset); last_row = line.Row; last_offset = line.Offset; } else if (line.Row > last_row) { last_row = line.Row; } } lines = new LineNumberEntry [count + ((last_row >= 0) ? 1 : 0)]; Array.Copy (lns, lines, pos); if (last_row >= 0) lines [pos] = new LineNumberEntry ( last_row, last_offset); } } } } |
From: <mas...@us...> - 2004-10-29 14:18:38
|
Update of /cvsroot/csdoc/csdoc/src/mcsdoc/class/corlib/Mono.Security.Cryptography In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24165/corlib/Mono.Security.Cryptography Added Files: CryptoConvert.cs Log Message: 2004-10-28 Gaurav Vaish * **/* : Getting the latest sync from mono repository. Will resume work pretty soon. Moving final work from csdoc to mcsdoc. --- NEW FILE: CryptoConvert.cs --- // // CryptoConvert.cs - Crypto Convertion Routines // // Author: // Sebastien Pouliot <seb...@xi...> // // (C) 2003 Motus Technologies Inc. (http://www.motus.com) // (C) 2004 Novell (http://www.novell.com) // // // Copyright (C) 2004 Novell, Inc (http://www.novell.com) // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Globalization; using System.Security.Cryptography; using System.Text; namespace Mono.Security.Cryptography { #if INSIDE_CORLIB internal #else public #endif sealed class CryptoConvert { private CryptoConvert () { } static private int ToInt32LE (byte [] bytes, int offset) { return (bytes [offset+3] << 24) | (bytes [offset+2] << 16) | (bytes [offset+1] << 8) | bytes [offset]; } static private uint ToUInt32LE (byte [] bytes, int offset) { return (uint)((bytes [offset+3] << 24) | (bytes [offset+2] << 16) | (bytes [offset+1] << 8) | bytes [offset]); } static private byte [] GetBytesLE (int val) { return new byte [] { (byte) (val & 0xff), (byte) ((val >> 8) & 0xff), (byte) ((val >> 16) & 0xff), (byte) ((val >> 24) & 0xff) }; } static private byte[] Trim (byte[] array) { for (int i=0; i < array.Length; i++) { if (array [i] != 0x00) { byte[] result = new byte [array.Length - i]; Buffer.BlockCopy (array, i, result, 0, result.Length); return result; } } return null; } // convert the key from PRIVATEKEYBLOB to RSA // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/Security/private_key_blobs.asp // e.g. SNK files, PVK files static public RSA FromCapiPrivateKeyBlob (byte[] blob) { return FromCapiPrivateKeyBlob (blob, 0); } static public RSA FromCapiPrivateKeyBlob (byte[] blob, int offset) { if (blob == null) throw new ArgumentNullException ("blob"); if (offset >= blob.Length) throw new ArgumentException ("blob is too small."); try { if ((blob [offset] != 0x07) || // PRIVATEKEYBLOB (0x07) (blob [offset+1] != 0x02) || // Version (0x02) (blob [offset+2] != 0x00) || // Reserved (word) (blob [offset+3] != 0x00) || (ToUInt32LE (blob, offset+8) != 0x32415352)) // DWORD magic = RSA2 throw new CryptographicException ("Invalid blob header"); // ALGID (CALG_RSA_SIGN, CALG_RSA_KEYX, ...) // int algId = ToInt32LE (blob, offset+4); // DWORD bitlen int bitLen = ToInt32LE (blob, offset+12); // DWORD public exponent RSAParameters rsap = new RSAParameters (); byte[] exp = new byte [4]; Buffer.BlockCopy (blob, offset+16, exp, 0, 4); Array.Reverse (exp); rsap.Exponent = Trim (exp); int pos = offset+20; // BYTE modulus[rsapubkey.bitlen/8]; int byteLen = (bitLen >> 3); rsap.Modulus = new byte [byteLen]; Buffer.BlockCopy (blob, pos, rsap.Modulus, 0, byteLen); Array.Reverse (rsap.Modulus); pos += byteLen; // BYTE prime1[rsapubkey.bitlen/16]; int byteHalfLen = (byteLen >> 1); rsap.P = new byte [byteHalfLen]; Buffer.BlockCopy (blob, pos, rsap.P, 0, byteHalfLen); Array.Reverse (rsap.P); pos += byteHalfLen; // BYTE prime2[rsapubkey.bitlen/16]; rsap.Q = new byte [byteHalfLen]; Buffer.BlockCopy (blob, pos, rsap.Q, 0, byteHalfLen); Array.Reverse (rsap.Q); pos += byteHalfLen; // BYTE exponent1[rsapubkey.bitlen/16]; rsap.DP = new byte [byteHalfLen]; Buffer.BlockCopy (blob, pos, rsap.DP, 0, byteHalfLen); Array.Reverse (rsap.DP); pos += byteHalfLen; // BYTE exponent2[rsapubkey.bitlen/16]; rsap.DQ = new byte [byteHalfLen]; Buffer.BlockCopy (blob, pos, rsap.DQ, 0, byteHalfLen); Array.Reverse (rsap.DQ); pos += byteHalfLen; // BYTE coefficient[rsapubkey.bitlen/16]; rsap.InverseQ = new byte [byteHalfLen]; Buffer.BlockCopy (blob, pos, rsap.InverseQ, 0, byteHalfLen); Array.Reverse (rsap.InverseQ); pos += byteHalfLen; // ok, this is hackish but CryptoAPI support it so... // note: only works because CRT is used by default // http://bugzilla.ximian.com/show_bug.cgi?id=57941 rsap.D = new byte [byteLen]; // must be allocated if (pos + byteLen + offset <= blob.Length) { // BYTE privateExponent[rsapubkey.bitlen/8]; Buffer.BlockCopy (blob, pos, rsap.D, 0, byteLen); Array.Reverse (rsap.D); } RSA rsa = (RSA)RSA.Create (); rsa.ImportParameters (rsap); return rsa; } catch (Exception e) { throw new CryptographicException ("Invalid blob.", e); } } static public byte[] ToCapiPrivateKeyBlob (RSA rsa) { RSAParameters p = rsa.ExportParameters (true); int keyLength = p.Modulus.Length; // in bytes byte[] blob = new byte [20 + (keyLength << 2) + (keyLength >> 1)]; blob [0] = 0x07; // Type - PRIVATEKEYBLOB (0x07) blob [1] = 0x02; // Version - Always CUR_BLOB_VERSION (0x02) // [2], [3] // RESERVED - Always 0 blob [5] = 0x24; // ALGID - Always 00 24 00 00 (for CALG_RSA_SIGN) blob [8] = 0x52; // Magic - RSA2 (ASCII in hex) blob [9] = 0x53; blob [10] = 0x41; blob [11] = 0x32; byte[] bitlen = GetBytesLE (keyLength << 3); blob [12] = bitlen [0]; // bitlen blob [13] = bitlen [1]; blob [14] = bitlen [2]; blob [15] = bitlen [3]; // public exponent (DWORD) int pos = 16; int n = p.Exponent.Length; while (n > 0) blob [pos++] = p.Exponent [--n]; // modulus pos = 20; byte[] part = p.Modulus; int len = part.Length; Array.Reverse (part, 0, len); Buffer.BlockCopy (part, 0, blob, pos, len); pos += len; // private key part = p.P; len = part.Length; Array.Reverse (part, 0, len); Buffer.BlockCopy (part, 0, blob, pos, len); pos += len; part = p.Q; len = part.Length; Array.Reverse (part, 0, len); Buffer.BlockCopy (part, 0, blob, pos, len); pos += len; part = p.DP; len = part.Length; Array.Reverse (part, 0, len); Buffer.BlockCopy (part, 0, blob, pos, len); pos += len; part = p.DQ; len = part.Length; Array.Reverse (part, 0, len); Buffer.BlockCopy (part, 0, blob, pos, len); pos += len; part = p.InverseQ; len = part.Length; Array.Reverse (part, 0, len); Buffer.BlockCopy (part, 0, blob, pos, len); pos += len; part = p.D; len = part.Length; Array.Reverse (part, 0, len); Buffer.BlockCopy (part, 0, blob, pos, len); return blob; } static public RSA FromCapiPublicKeyBlob (byte[] blob) { return FromCapiPublicKeyBlob (blob, 0); } static public RSA FromCapiPublicKeyBlob (byte[] blob, int offset) { if (blob == null) throw new ArgumentNullException ("blob"); if (offset >= blob.Length) throw new ArgumentException ("blob is too small."); try { if ((blob [offset] != 0x06) || // PUBLICKEYBLOB (0x06) (blob [offset+1] != 0x02) || // Version (0x02) (blob [offset+2] != 0x00) || // Reserved (word) (blob [offset+3] != 0x00) || (ToUInt32LE (blob, offset+8) != 0x31415352)) // DWORD magic = RSA1 throw new CryptographicException ("Invalid blob header"); // ALGID (CALG_RSA_SIGN, CALG_RSA_KEYX, ...) // int algId = ToInt32LE (blob, offset+4); // DWORD bitlen int bitLen = ToInt32LE (blob, offset+12); // DWORD public exponent RSAParameters rsap = new RSAParameters (); rsap.Exponent = new byte [3]; rsap.Exponent [0] = blob [offset+18]; rsap.Exponent [1] = blob [offset+17]; rsap.Exponent [2] = blob [offset+16]; int pos = offset+20; // BYTE modulus[rsapubkey.bitlen/8]; int byteLen = (bitLen >> 3); rsap.Modulus = new byte [byteLen]; Buffer.BlockCopy (blob, pos, rsap.Modulus, 0, byteLen); Array.Reverse (rsap.Modulus); RSA rsa = (RSA)RSA.Create (); rsa.ImportParameters (rsap); return rsa; } catch (Exception e) { throw new CryptographicException ("Invalid blob.", e); } } static public byte[] ToCapiPublicKeyBlob (RSA rsa) { RSAParameters p = rsa.ExportParameters (false); int keyLength = p.Modulus.Length; // in bytes byte[] blob = new byte [20 + keyLength]; blob [0] = 0x06; // Type - PUBLICKEYBLOB (0x06) blob [1] = 0x02; // Version - Always CUR_BLOB_VERSION (0x02) // [2], [3] // RESERVED - Always 0 blob [5] = 0x24; // ALGID - Always 00 24 00 00 (for CALG_RSA_SIGN) blob [8] = 0x52; // Magic - RSA1 (ASCII in hex) blob [9] = 0x53; blob [10] = 0x41; blob [11] = 0x31; byte[] bitlen = GetBytesLE (keyLength << 3); blob [12] = bitlen [0]; // bitlen blob [13] = bitlen [1]; blob [14] = bitlen [2]; blob [15] = bitlen [3]; // public exponent (DWORD) int pos = 16; int n = p.Exponent.Length; while (n > 0) blob [pos++] = p.Exponent [--n]; // modulus pos = 20; byte[] part = p.Modulus; int len = part.Length; Array.Reverse (part, 0, len); Buffer.BlockCopy (part, 0, blob, pos, len); pos += len; return blob; } // PRIVATEKEYBLOB // PUBLICKEYBLOB static public RSA FromCapiKeyBlob (byte[] blob) { return FromCapiKeyBlob (blob, 0); } static public RSA FromCapiKeyBlob (byte[] blob, int offset) { if (blob == null) throw new ArgumentNullException ("blob"); if (offset >= blob.Length) throw new ArgumentException ("blob is too small."); switch (blob [offset]) { case 0x00: // this could be a public key inside an header // like "sn -e" would produce if (blob [offset + 12] == 0x06) { return FromCapiPublicKeyBlob (blob, offset + 12); } break; case 0x06: return FromCapiPublicKeyBlob (blob, offset); case 0x07: return FromCapiPrivateKeyBlob (blob, offset); } throw new CryptographicException ("Unknown blob format."); } static public byte[] ToCapiKeyBlob (AsymmetricAlgorithm keypair, bool includePrivateKey) { if (keypair == null) throw new ArgumentNullException ("keypair"); // check between RSA and DSA (and potentially others like DH) if (keypair is RSA) return ToCapiKeyBlob ((RSA)keypair, includePrivateKey); else return null; // TODO } static public byte[] ToCapiKeyBlob (RSA rsa, bool includePrivateKey) { if (rsa == null) throw new ArgumentNullException ("rsa"); if (includePrivateKey) return ToCapiPrivateKeyBlob (rsa); else return ToCapiPublicKeyBlob (rsa); } static public string ToHex (byte[] input) { if (input == null) return null; StringBuilder sb = new StringBuilder (input.Length * 2); foreach (byte b in input) { sb.Append (b.ToString ("X2", CultureInfo.InvariantCulture)); } return sb.ToString (); } static private byte FromHexChar (char c) { if ((c >= 'a') && (c <= 'f')) return (byte) (c - 'a' + 10); if ((c >= 'A') && (c <= 'F')) return (byte) (c - 'A' + 10); if ((c >= '0') && (c <= '9')) return (byte) (c - '0'); throw new ArgumentException ("invalid hex char"); } static public byte[] FromHex (string hex) { if (hex == null) return null; if ((hex.Length & 0x1) == 0x1) throw new ArgumentException ("Length must be a multiple of 2"); byte[] result = new byte [hex.Length >> 1]; int n = 0; int i = 0; while (n < result.Length) { result [n] = (byte) (FromHexChar (hex [i++]) << 4); result [n++] += FromHexChar (hex [i++]); } return result; } } } |
Update of /cvsroot/csdoc/csdoc/src/mcsdoc/jay In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23922 Added Files: .cvsignore ACKNOWLEDGEMENTS ChangeLog NEW_FEATURES NOTES README README.jay closure.c defs.h depend error.c jay.1 lalr.c lr0.c main.c makefile makefile.gnu mkpar.c output.c reader.c skeleton skeleton.cs symtab.c verbose.c warshall.c Log Message: 2004-10-28 Gaurav Vaish * **/* : Getting the latest sync from mono repository. Will resume work pretty soon. Moving final work from csdoc to mcsdoc. --- NEW FILE: .cvsignore --- jay jay.exe --- NEW FILE: ACKNOWLEDGEMENTS --- Berkeley Yacc owes much to the unflagging efforts of Keith Bostic. His badgering kept me working on it long after I was ready to quit. Berkeley Yacc is based on the excellent algorithm for computing LALR(1) lookaheads developed by Tom Pennello and Frank DeRemer. The algorithm is described in their almost impenetrable article in TOPLAS 4,4. Finally, much of the credit for the latest version must go to those who pointed out deficiencies of my earlier releases. Among the most prolific contributors were Benson I. Margulies Dave Gentzel Antoine Verheijen Peter S. Housel Dale Smith Ozan Yigit John Campbell Bill Sommerfeld Paul Hilfinger Gary Bridgewater Dave Bakken Dan Lanciani Richard Sargent Parag Patel --- NEW FILE: ChangeLog --- 2004-06-10 Rafael Teixeira <raf...@ho...> * skeleton.cs: oops some uses of changed classes/interfaces also need to become internal. 2004-06-10 Atsushi Enomoto <at...@xi...> * skelton.cs: make classes/interfaces internal. 2004-06-03 Atsushi Enomoto <at...@xi...> * Makefile : ignore make run-test-ondotnet. Mon May 3 08:34:32 CEST 2004 Paolo Molaro <lu...@xi...> * main.c, defs.h: use the proper header files instead of broken prototypes (thanks to Marcus for reporting). 2004-03-13 Miguel de Icaza <mi...@xi...> * main.c (create_file_names): Try a few temp directories, since Windows uses a different directory naming scheme apparently: #47696 2004-03-05 Zoltan Varga <va...@fr...> * main.c: Applied patch from Albert Strasheim (136...@su...). Fix compilation under mingw. 2004-02-07 Miguel de Icaza <mi...@xi...> * skeleton.cs: Report the token that we errored on; Helps find parser errors. 2003-12-16 Atsushi Enomoto <at...@xi...> * skelton.cs : Added ErrorOutput text writer. 2003-10-08 Atsushi Enomoto <gi...@ki...> * output.c, skelton, skelton.cs : Renamed yyName[] to yyNames[] to make output CLS-compliant. 2003-05-16 Peter Williams <pe...@xi...> * main.c (print_skel_dir): New function called when jay is passed '-p'; prints the directory where the default skeleton files are installed ($(prefix)/share/jay). * makefile (CFLAGS): Add a -DSKEL_DIRECTORY to support print_skel_dir. * jay.1: Document the -p parameter. 2003-05-16 Peter Williams <pe...@xi...> * makefile (install): Call the install in makefile.gnu * makefile.gnu (install): Actually install jay and its skeleton files. 2003-02-09 Martin Baulig <ma...@xi...> * output.c: Use `#line default' instead of source file "-". 2003-01-13 Jackson Harper <ja...@la...> * skeleton.cs: Remove cleanup stuff, it has been moved to a better spot. 2003-01-13 Duncan Mak <du...@xi...> * skeleton.cs (cleanpup): Rename to cleanup to make it look more consistent. 2003-01-13 Jackson Harper <ja...@la...> * skeleton.cs: Call lexer.Cleanup when the lexer reaches the EOF. 2002-08-20 Miguel de Icaza <mi...@xi...> * skeleton.cs: Fix the code that expanded the arrays dynamically, it was broken, and instead was copying 0 elements. 2002-07-10 Alp Toker <al...@at...> * main.c: mktemp() is deprecated with gcc 3.1.1, use mkstemp() instead 2001-07-15 Sean MacIsaac <mac...@xi...> * makefile: added windows and unix targets. 2001-07-14 Sean MacIsaac <mac...@xi...> * main.c: fixed error in command line flag -c if it was not first option. --- NEW FILE: NEW_FEATURES --- The -r option has been implemented. The -r option tells Yacc to put the read-only tables in y.tab.c and the code and variables in y.code.c. Keith Bostic asked for this option so that :yyfix could be eliminated. The -l and -t options have been implemented. The -l option tells Yacc not to include #line directives in the code it produces. The -t option causes debugging code to be included in the compiled parser. The code for error recovery has been changed to implement the same algorithm as AT&T Yacc. There will still be differences in the way error recovery works because AT&T Yacc uses more default reductions than Berkeley Yacc. The environment variable TMPDIR determines the directory where temporary files will be created. If TMPDIR is defined, temporary files will be created in the directory whose pathname is the value of TMPDIR. By default, temporary files are created in /tmp. The keywords are now case-insensitive. For example, %nonassoc, %NONASSOC, %NonAssoc, and %nOnAsSoC are all equivalent. Commas and semicolons that are not part of C code are treated as commentary. Line-end comments, as in BCPL, are permitted. Line-end comments begin with // and end at the next end-of-line. Line-end comments are permitted in C code; they are converted to C comments on output. The form of y.output files has been changed to look more like those produced by AT&T Yacc. A new kind of declaration has been added. The form of the declaration is %ident string where string is a sequence of characters begining with a double quote and ending with either a double quote or the next end-of-line, whichever comes first. The declaration will cause a #ident directive to be written near the start of the output file. If a parser has been compiled with debugging code, that code can be enabled by setting an environment variable. If the environment variable YYDEBUG is set to 0, debugging output is suppressed. If it is set to 1, debugging output is written to standard output. --- NEW FILE: NOTES --- Berkeley Yacc reflects its origins. The reason so many routines use exactly six register variables is that Berkeley Yacc was developed on a VAX using PCC. PCC placed at most six variables in registers. I went to considerable effort to find which six variables most belonged in registers. Changes in machines and compilers make that effort worthless, perhaps even harmful. The code contains many instances where address calculations are performed in particular ways to optimize the code for the VAX. --- NEW FILE: README --- This is a port of Jay to C#, the original Jay can be found here: http://www.informatik.uni-osnabrueck.de/bernd/jay/ The original README from Jay is in `README.jay' Miguel --- NEW FILE: README.jay --- This version of Berkeley Yacc was taken from the BSD-Lite CD and targeted to Java by axe...@in... Makefile -> makefile removed Berkeleyisms, call it jay defs.h eliminate -dlpr options, %union, output_file, #ident eliminate sekeleton.c references error.c eliminate %union main.c eliminate -dlpr options, %union, output_file output.c eliminate -dlpr options, %union, output_file fix #define, short, -t/yyDebug respell YYERRCODE, YYTABLESIZE, YYFINAL, YYMAXTOKEN output trailer last switch to filter behaviour reader.c eliminate output_file, #ident #line -> // line, pass // yyvsp[] -> yyVals[yyTop], yyval -> yyVal skeleton.c -> skeleton Java skeleton test removed yacc.1 -> jay.1 adapted yyfix.* removed Types: there is a significant difference. yacc uses %union to cast the value stack and <tag> to select alternatives. This works for l- and r-values alike. jay uses Object as the value stack and <tag> to set a class. l-values must not be cast. $n should not be assigned to, but $$ usually is. $n is referenced, but $$ usually is not. Consequently jay casts $n and $<tag>$ but not $<>n and $$. This makes assignment to $n references to $$ kludgily possible. As another kludge, to prevent 'untyped' messages and to avoid unnecessary casts, casts to "Object" are not emitted. ------------------------------------------------------------------------------- Berkeley Yacc is an LALR(1) parser generator. Berkeley Yacc has been made as compatible as possible with AT&T Yacc. Berkeley Yacc can accept any input specification that conforms to the AT&T Yacc documentation. Specifications that take advantage of undocumented features of AT&T Yacc will probably be rejected. Berkeley Yacc is distributed with no warranty whatever. The code is certain to contain errors. Neither the author nor any contributor takes responsibility for any consequences of its use. Berkeley Yacc is in the public domain. The data structures and algorithms used in Berkeley Yacc are all either taken from documents available to the general public or are inventions of the author. Anyone may freely distribute source or binary forms of Berkeley Yacc whether unchanged or modified. Distributers may charge whatever fees they can obtain for Berkeley Yacc. Programs generated by Berkeley Yacc may be distributed freely. Please report bugs to rob...@en... Include a small example if possible. Please include the banner string from skeleton.c with the bug report. Do not expect rapid responses. --- NEW FILE: closure.c --- /* * Copyright (c) 1989 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * Robert Paul Corbett. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef lint static char sccsid[] = "@(#)closure.c 5.3 (Berkeley) 5/24/93"; #endif /* not lint */ #include "defs.h" short *itemset; short *itemsetend; unsigned *ruleset; static unsigned *first_derives; static unsigned *EFF; set_EFF() { register unsigned *row; register int symbol; register short *sp; register int rowsize; register int i; register int rule; rowsize = WORDSIZE(nvars); EFF = NEW2(nvars * rowsize, unsigned); row = EFF; for (i = start_symbol; i < nsyms; i++) { sp = derives[i]; for (rule = *sp; rule > 0; rule = *++sp) { symbol = ritem[rrhs[rule]]; if (ISVAR(symbol)) { symbol -= start_symbol; SETBIT(row, symbol); } } row += rowsize; } reflexive_transitive_closure(EFF, nvars); #ifdef DEBUG print_EFF(); #endif } set_first_derives() { register unsigned *rrow; register unsigned *vrow; register int j; register unsigned k; register unsigned cword; register short *rp; int rule; int i; int rulesetsize; int varsetsize; rulesetsize = WORDSIZE(nrules); varsetsize = WORDSIZE(nvars); first_derives = NEW2(nvars * rulesetsize, unsigned) - ntokens * rulesetsize; set_EFF(); rrow = first_derives + ntokens * rulesetsize; for (i = start_symbol; i < nsyms; i++) { vrow = EFF + ((i - ntokens) * varsetsize); k = BITS_PER_WORD; for (j = start_symbol; j < nsyms; k++, j++) { if (k >= BITS_PER_WORD) { cword = *vrow++; k = 0; } if (cword & (1 << k)) { rp = derives[j]; while ((rule = *rp++) >= 0) { SETBIT(rrow, rule); } } } vrow += varsetsize; rrow += rulesetsize; } #ifdef DEBUG print_first_derives(); #endif FREE(EFF); } closure(nucleus, n) short *nucleus; int n; { register int ruleno; register unsigned word; register unsigned i; register short *csp; register unsigned *dsp; register unsigned *rsp; register int rulesetsize; short *csend; unsigned *rsend; int symbol; int itemno; rulesetsize = WORDSIZE(nrules); rsp = ruleset; rsend = ruleset + rulesetsize; for (rsp = ruleset; rsp < rsend; rsp++) *rsp = 0; csend = nucleus + n; for (csp = nucleus; csp < csend; ++csp) { symbol = ritem[*csp]; if (ISVAR(symbol)) { dsp = first_derives + symbol * rulesetsize; rsp = ruleset; while (rsp < rsend) *rsp++ |= *dsp++; } } ruleno = 0; itemsetend = itemset; csp = nucleus; for (rsp = ruleset; rsp < rsend; ++rsp) { word = *rsp; if (word) { for (i = 0; i < BITS_PER_WORD; ++i) { if (word & (1 << i)) { itemno = rrhs[ruleno+i]; while (csp < csend && *csp < itemno) *itemsetend++ = *csp++; *itemsetend++ = itemno; while (csp < csend && *csp == itemno) ++csp; } } } ruleno += BITS_PER_WORD; } while (csp < csend) *itemsetend++ = *csp++; #ifdef DEBUG print_closure(n); #endif } finalize_closure() { FREE(itemset); FREE(ruleset); FREE(first_derives + ntokens * WORDSIZE(nrules)); } #ifdef DEBUG print_closure(n) int n; { register short *isp; printf("\n\nn = %d\n\n", n); for (isp = itemset; isp < itemsetend; isp++) printf(" %d\n", *isp); } print_EFF() { register int i, j; register unsigned *rowp; register unsigned word; register unsigned k; printf("\n\nEpsilon Free Firsts\n"); for (i = start_symbol; i < nsyms; i++) { printf("\n%s", symbol_name[i]); rowp = EFF + ((i - start_symbol) * WORDSIZE(nvars)); word = *rowp++; k = BITS_PER_WORD; for (j = 0; j < nvars; k++, j++) { if (k >= BITS_PER_WORD) { word = *rowp++; k = 0; } if (word & (1 << k)) printf(" %s", symbol_name[start_symbol + j]); } } } print_first_derives() { register int i; register int j; register unsigned *rp; register unsigned cword; register unsigned k; printf("\n\n\nFirst Derives\n"); for (i = start_symbol; i < nsyms; i++) { printf("\n%s derives\n", symbol_name[i]); rp = first_derives + i * WORDSIZE(nrules); k = BITS_PER_WORD; for (j = 0; j <= nrules; k++, j++) { if (k >= BITS_PER_WORD) { cword = *rp++; k = 0; } if (cword & (1 << k)) printf(" %d\n", j); } } fflush(stdout); } #endif --- NEW FILE: defs.h --- /* * Copyright (c) 1989 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * Robert Paul Corbett. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)defs.h 5.6 (Berkeley) 5/24/93 */ #include <assert.h> #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> /* machine-dependent definitions */ /* the following definitions are for the Tahoe */ /* they might have to be changed for other machines */ /* MAXCHAR is the largest unsigned character value */ /* MAXSHORT is the largest value of a C short */ /* MINSHORT is the most negative value of a C short */ /* MAXTABLE is the maximum table size */ /* BITS_PER_WORD is the number of bits in a C unsigned */ /* WORDSIZE computes the number of words needed to */ /* store n bits */ /* BIT returns the value of the n-th bit starting */ /* from r (0-indexed) */ /* SETBIT sets the n-th bit starting from r */ #define MAXCHAR 255 #define MAXSHORT 32767 #define MINSHORT -32768 #define MAXTABLE 32500 #define BITS_PER_WORD 32 #define WORDSIZE(n) (((n)+(BITS_PER_WORD-1))/BITS_PER_WORD) #define BIT(r, n) ((((r)[(n)>>5])>>((n)&31))&1) #define SETBIT(r, n) ((r)[(n)>>5]|=((unsigned)1<<((n)&31))) /* character names */ #define NUL '\0' /* the null character */ #define NEWLINE '\n' /* line feed */ #define SP ' ' /* space */ #define BS '\b' /* backspace */ #define HT '\t' /* horizontal tab */ #define VT '\013' /* vertical tab */ #define CR '\r' /* carriage return */ #define FF '\f' /* form feed */ #define QUOTE '\'' /* single quote */ #define DOUBLE_QUOTE '\"' /* double quote */ #define BACKSLASH '\\' /* backslash */ /* defines for constructing filenames */ #define CODE_SUFFIX ".code.c" #define DEFINES_SUFFIX ".tab.h" #define OUTPUT_SUFFIX ".tab.c" #define VERBOSE_SUFFIX ".output" /* keyword codes */ #define TOKEN 0 #define LEFT 1 #define RIGHT 2 #define NONASSOC 3 #define MARK 4 #define TEXT 5 #define TYPE 6 #define START 7 /* symbol classes */ #define UNKNOWN 0 #define TERM 1 #define NONTERM 2 /* the undefined value */ #define UNDEFINED (-1) /* action codes */ #define SHIFT 1 #define REDUCE 2 /* character macros */ #define IS_IDENT(c) (isalnum(c) || (c) == '_' || (c) == '.' || (c) == '$') #define IS_OCTAL(c) ((c) >= '0' && (c) <= '7') #define NUMERIC_VALUE(c) ((c) - '0') /* symbol macros */ #define ISTOKEN(s) ((s) < start_symbol) #define ISVAR(s) ((s) >= start_symbol) /* storage allocation macros */ #define CALLOC(k,n) (calloc((unsigned)(k),(unsigned)(n))) #define FREE(x) (free((char*)(x))) #define MALLOC(n) (malloc((unsigned)(n))) #define NEW(t) ((t*)allocate(sizeof(t))) #define NEW2(n,t) ((t*)allocate((unsigned)((n)*sizeof(t)))) #define REALLOC(p,n) (realloc((char*)(p),(unsigned)(n))) /* the structure of a symbol table entry */ typedef struct bucket bucket; struct bucket { struct bucket *link; struct bucket *next; char *name; char *tag; short value; short index; short prec; char class; char assoc; }; /* the structure of the LR(0) state machine */ typedef struct core core; struct core { struct core *next; struct core *link; short number; short accessing_symbol; short nitems; short items[1]; }; /* the structure used to record shifts */ typedef struct shifts shifts; struct shifts { struct shifts *next; short number; short nshifts; short shift[1]; }; /* the structure used to store reductions */ typedef struct reductions reductions; struct reductions { struct reductions *next; short number; short nreds; short rules[1]; }; /* the structure used to represent parser actions */ typedef struct action action; struct action { struct action *next; short symbol; short number; short prec; char action_code; char assoc; char suppressed; }; /* global variables */ extern char tflag; extern char vflag; extern char *myname; extern char *cptr; extern char *line; extern int lineno; extern int outline; extern char *action_file_name; extern char *input_file_name; extern char *prolog_file_name; extern char *local_file_name; extern char *verbose_file_name; extern FILE *action_file; extern FILE *input_file; extern FILE *prolog_file; extern FILE *local_file; extern FILE *verbose_file; extern int nitems; extern int nrules; extern int nsyms; extern int ntokens; extern int nvars; extern int ntags; extern char *line_format; extern char *default_line_format; extern int start_symbol; extern char **symbol_name; extern short *symbol_value; extern short *symbol_prec; extern char *symbol_assoc; extern short *ritem; extern short *rlhs; extern short *rrhs; extern short *rprec; extern char *rassoc; extern short **derives; extern char *nullable; extern bucket *first_symbol; extern bucket *last_symbol; extern int nstates; extern core *first_state; extern shifts *first_shift; extern reductions *first_reduction; extern short *accessing_symbol; extern core **state_table; extern shifts **shift_table; extern reductions **reduction_table; extern unsigned *LA; extern short *LAruleno; extern short *lookaheads; extern short *goto_map; extern short *from_state; extern short *to_state; extern action **parser; extern int SRtotal; extern int RRtotal; extern short *SRconflicts; extern short *RRconflicts; extern short *defred; extern short *rules_used; extern short nunused; extern short final_state; /* global functions */ extern char *allocate(); extern bucket *lookup(); extern bucket *make_bucket(); --- NEW FILE: depend --- closure.o: closure.c defs.h error.o: error.c defs.h lalr.o: lalr.c defs.h lr0.o: lr0.c defs.h main.o: main.c defs.h mkpar.o: mkpar.c defs.h output.o: output.c defs.h reader.o: reader.c defs.h symtab.o: symtab.c defs.h verbose.o: verbose.c defs.h warshall.o: warshall.c defs.h --- NEW FILE: error.c --- /* * Copyright (c) 1989 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * Robert Paul Corbett. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef lint static char sccsid[] = "@(#)error.c 5.3 (Berkeley) 6/1/90"; #endif /* not lint */ /* routines for printing error messages */ #include "defs.h" fatal(msg) char *msg; { fprintf(stderr, "%s: f - %s\n", myname, msg); done(2); } no_space() { fprintf(stderr, "%s: f - out of space\n", myname); done(2); } open_error(filename) char *filename; { fprintf(stderr, "%s: f - cannot open \"%s\"\n", myname, filename); done(2); } unexpected_EOF() { fprintf(stderr, "%s: e - line %d of \"%s\", unexpected end-of-file\n", myname, lineno, input_file_name); done(1); } print_pos(st_line, st_cptr) char *st_line; char *st_cptr; { register char *s; if (st_line == 0) return; for (s = st_line; *s != '\n'; ++s) { if (isprint(*s) || *s == '\t') putc(*s, stderr); else putc('?', stderr); } putc('\n', stderr); for (s = st_line; s < st_cptr; ++s) { if (*s == '\t') putc('\t', stderr); else putc(' ', stderr); } putc('^', stderr); putc('\n', stderr); } syntax_error(st_lineno, st_line, st_cptr) int st_lineno; char *st_line; char *st_cptr; { fprintf(stderr, "%s: e - line %d of \"%s\", syntax error\n", myname, st_lineno, input_file_name); print_pos(st_line, st_cptr); done(1); } unterminated_comment(c_lineno, c_line, c_cptr) int c_lineno; char *c_line; char *c_cptr; { fprintf(stderr, "%s: e - line %d of \"%s\", unmatched /*\n", myname, c_lineno, input_file_name); print_pos(c_line, c_cptr); done(1); } unterminated_string(s_lineno, s_line, s_cptr) int s_lineno; char *s_line; char *s_cptr; { fprintf(stderr, "%s: e - line %d of \"%s\", unterminated string\n", myname, s_lineno, input_file_name); print_pos(s_line, s_cptr); done(1); } unterminated_text(t_lineno, t_line, t_cptr) int t_lineno; char *t_line; char *t_cptr; { fprintf(stderr, "%s: e - line %d of \"%s\", unmatched %%{\n", myname, t_lineno, input_file_name); print_pos(t_line, t_cptr); done(1); } illegal_tag(t_lineno, t_line, t_cptr) int t_lineno; char *t_line; char *t_cptr; { fprintf(stderr, "%s: e - line %d of \"%s\", illegal tag\n", myname, t_lineno, input_file_name); print_pos(t_line, t_cptr); done(1); } illegal_character(c_cptr) char *c_cptr; { fprintf(stderr, "%s: e - line %d of \"%s\", illegal character\n", myname, lineno, input_file_name); print_pos(line, c_cptr); done(1); } used_reserved(s) char *s; { fprintf(stderr, "%s: e - line %d of \"%s\", illegal use of reserved symbol \ %s\n", myname, lineno, input_file_name, s); done(1); } tokenized_start(s) char *s; { fprintf(stderr, "%s: e - line %d of \"%s\", the start symbol %s cannot be \ declared to be a token\n", myname, lineno, input_file_name, s); done(1); } retyped_warning(s) char *s; { fprintf(stderr, "%s: w - line %d of \"%s\", the type of %s has been \ redeclared\n", myname, lineno, input_file_name, s); } reprec_warning(s) char *s; { fprintf(stderr, "%s: w - line %d of \"%s\", the precedence of %s has been \ redeclared\n", myname, lineno, input_file_name, s); } revalued_warning(s) char *s; { fprintf(stderr, "%s: w - line %d of \"%s\", the value of %s has been \ redeclared\n", myname, lineno, input_file_name, s); } terminal_start(s) char *s; { fprintf(stderr, "%s: e - line %d of \"%s\", the start symbol %s is a \ token\n", myname, lineno, input_file_name, s); done(1); } restarted_warning() { fprintf(stderr, "%s: w - line %d of \"%s\", the start symbol has been \ redeclared\n", myname, lineno, input_file_name); } no_grammar() { fprintf(stderr, "%s: e - line %d of \"%s\", no grammar has been \ specified\n", myname, lineno, input_file_name); done(1); } terminal_lhs(s_lineno) int s_lineno; { fprintf(stderr, "%s: e - line %d of \"%s\", a token appears on the lhs \ of a production\n", myname, s_lineno, input_file_name); done(1); } prec_redeclared() { fprintf(stderr, "%s: w - line %d of \"%s\", conflicting %%prec \ specifiers\n", myname, lineno, input_file_name); } unterminated_action(a_lineno, a_line, a_cptr) int a_lineno; char *a_line; char *a_cptr; { fprintf(stderr, "%s: e - line %d of \"%s\", unterminated action\n", myname, a_lineno, input_file_name); print_pos(a_line, a_cptr); done(1); } dollar_warning(a_lineno, i) int a_lineno; int i; { fprintf(stderr, "%s: w - line %d of \"%s\", $%d references beyond the \ end of the current rule\n", myname, a_lineno, input_file_name, i); } dollar_error(a_lineno, a_line, a_cptr) int a_lineno; char *a_line; char *a_cptr; { fprintf(stderr, "%s: e - line %d of \"%s\", illegal $-name\n", myname, a_lineno, input_file_name); print_pos(a_line, a_cptr); done(1); } untyped_lhs() { fprintf(stderr, "%s: w - line %d of \"%s\", $$ is untyped\n", myname, lineno, input_file_name); /** done(1); */ } untyped_rhs(i, s) int i; char *s; { fprintf(stderr, "%s: w - line %d of \"%s\", $%d (%s) is untyped\n", myname, lineno, input_file_name, i, s); /** done(1); */ } unknown_rhs(i) int i; { fprintf(stderr, "%s: e - line %d of \"%s\", $%d is untyped\n", myname, lineno, input_file_name, i); done(1); } default_action_warning() { fprintf(stderr, "%s: w - line %d of \"%s\", the default action assigns an \ undefined value to $$\n", myname, lineno, input_file_name); } undefined_goal(s) char *s; { fprintf(stderr, "%s: e - the start symbol %s is undefined\n", myname, s); done(1); } undefined_symbol_warning(s) char *s; { fprintf(stderr, "%s: w - the symbol %s is undefined\n", myname, s); } --- NEW FILE: jay.1 --- .\" Copyright (c) 1989, 1990 The Regents of the University of California. .\" All rights reserved. .\" .\" This code is derived from software contributed to Berkeley by .\" Robert Paul Corbett. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. All advertising materials mentioning features or use of this software .\" must display the following acknowledgement: .\" This product includes software developed by the University of .\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" @(#)yacc.1 5.8 (Berkeley) 5/24/93 .\" .TH JAY 1 "May 24, 1993 / July 8, 1998" .UC 6 .SH NAME jay \- an LALR(1) parser generator for Java and C# .SH SYNOPSIS .B jay [ -tv ] [ -c ] [ -p ] [ -b .I file_prefix .B ] [ -V .I yyValue .B ] .I filename .B < .I skeleton .SH DESCRIPTION .I Jay reads the grammar specification in the file .I filename and generates an LR(1) parser for it. The parsers consist of a set of LALR(1) parsing tables and a driver routine from the file .I skeleton written in the Java programming language. .I Jay writes the parse tables and the driver routine to standard output. .PP The following options are available: .RS .TP \fB-b \fIfile_prefix\fR The .B -b option changes the prefix prepended to the output file names to the string denoted by .IR file_prefix. The default prefix is the character .IR y. .TP .B -c The .B -c option makes jay generate C# code instead of the default Java. .TP .B -t The .B -t option arranges for debugging information to be incorporated in the compiled code. .TP .B -v The .B -v option causes a human-readable description of the generated parser to be written to the file .IR y.output. .TP .B -p The .B -p option causes .I jay to print the directory in which its sample skeleton files are installed. If a project wants to use the default skeleton file included with \fIjay\fR, it can use this option in a makefile to find the path to the .I skeleton or .I skeleton.cs file included with the jay distribution. .RE .PP If the environment variable TMPDIR is set, the string denoted by TMPDIR will be used as the name of the directory where the temporary files are created. .SH FILES .IR skeleton .br .IR y.output .br .IR /tmp/yacc.aXXXXXX .br .IR /tmp/yacc.tXXXXXX .br .IR /tmp/yacc.uXXXXXX .SH DIAGNOSTICS If there are rules that are never reduced, the number of such rules is reported on standard error. If there are any LALR(1) conflicts, the number of conflicts is reported on standard error. .SH HISTORY .I Jay is derived from Berkeley .I yacc . Input conventions closely follow those of .I yacc ; for details, consult the parser .I skeleton file and the commented example included with the sources. --- NEW FILE: lalr.c --- /* * Copyright (c) 1989 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * Robert Paul Corbett. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef lint static char sccsid[] = "@(#)lalr.c 5.3 (Berkeley) 6/1/90"; #endif /* not lint */ #include "defs.h" typedef struct shorts { struct shorts *next; short value; } shorts; int tokensetsize; short *lookaheads; short *LAruleno; unsigned *LA; short *accessing_symbol; core **state_table; shifts **shift_table; reductions **reduction_table; short *goto_map; short *from_state; short *to_state; short **transpose(); static int infinity; static int maxrhs; static int ngotos; static unsigned *F; static short **includes; static shorts **lookback; static short **R; static short *INDEX; static short *VERTICES; static int top; lalr() { tokensetsize = WORDSIZE(ntokens); set_state_table(); set_accessing_symbol(); set_shift_table(); set_reduction_table(); set_maxrhs(); initialize_LA(); set_goto_map(); initialize_F(); build_relations(); compute_FOLLOWS(); compute_lookaheads(); } set_state_table() { register core *sp; state_table = NEW2(nstates, core *); for (sp = first_state; sp; sp = sp->next) state_table[sp->number] = sp; } set_accessing_symbol() { register core *sp; accessing_symbol = NEW2(nstates, short); for (sp = first_state; sp; sp = sp->next) accessing_symbol[sp->number] = sp->accessing_symbol; } set_shift_table() { register shifts *sp; shift_table = NEW2(nstates, shifts *); for (sp = first_shift; sp; sp = sp->next) shift_table[sp->number] = sp; } set_reduction_table() { register reductions *rp; reduction_table = NEW2(nstates, reductions *); for (rp = first_reduction; rp; rp = rp->next) reduction_table[rp->number] = rp; } set_maxrhs() { register short *itemp; register short *item_end; register int length; register int max; length = 0; max = 0; item_end = ritem + nitems; for (itemp = ritem; itemp < item_end; itemp++) { if (*itemp >= 0) { length++; } else { if (length > max) max = length; length = 0; } } maxrhs = max; } initialize_LA() { register int i, j, k; register reductions *rp; lookaheads = NEW2(nstates + 1, short); k = 0; for (i = 0; i < nstates; i++) { lookaheads[i] = k; rp = reduction_table[i]; if (rp) k += rp->nreds; } lookaheads[nstates] = k; LA = NEW2(k * tokensetsize, unsigned); LAruleno = NEW2(k, short); lookback = NEW2(k, shorts *); k = 0; for (i = 0; i < nstates; i++) { rp = reduction_table[i]; if (rp) { for (j = 0; j < rp->nreds; j++) { LAruleno[k] = rp->rules[j]; k++; } } } } set_goto_map() { register shifts *sp; register int i; register int symbol; register int k; register short *temp_map; register int state2; register int state1; goto_map = NEW2(nvars + 1, short) - ntokens; temp_map = NEW2(nvars + 1, short) - ntokens; ngotos = 0; for (sp = first_shift; sp; sp = sp->next) { for (i = sp->nshifts - 1; i >= 0; i--) { symbol = accessing_symbol[sp->shift[i]]; if (ISTOKEN(symbol)) break; if (ngotos == MAXSHORT) fatal("too many gotos"); ngotos++; goto_map[symbol]++; } } k = 0; for (i = ntokens; i < nsyms; i++) { temp_map[i] = k; k += goto_map[i]; } for (i = ntokens; i < nsyms; i++) goto_map[i] = temp_map[i]; goto_map[nsyms] = ngotos; temp_map[nsyms] = ngotos; from_state = NEW2(ngotos, short); to_state = NEW2(ngotos, short); for (sp = first_shift; sp; sp = sp->next) { state1 = sp->number; for (i = sp->nshifts - 1; i >= 0; i--) { state2 = sp->shift[i]; symbol = accessing_symbol[state2]; if (ISTOKEN(symbol)) break; k = temp_map[symbol]++; from_state[k] = state1; to_state[k] = state2; } } FREE(temp_map + ntokens); } /* Map_goto maps a state/symbol pair into its numeric representation. */ int map_goto(state, symbol) int state; int symbol; { register int high; register int low; register int middle; register int s; low = goto_map[symbol]; high = goto_map[symbol + 1]; for (;;) { assert(low <= high); middle = (low + high) >> 1; s = from_state[middle]; if (s == state) return (middle); else if (s < state) low = middle + 1; else high = middle - 1; } } initialize_F() { register int i; register int j; register int k; register shifts *sp; register short *edge; register unsigned *rowp; register short *rp; register short **reads; register int nedges; register int stateno; register int symbol; register int nwords; nwords = ngotos * tokensetsize; F = NEW2(nwords, unsigned); reads = NEW2(ngotos, short *); edge = NEW2(ngotos + 1, short); nedges = 0; rowp = F; for (i = 0; i < ngotos; i++) { stateno = to_state[i]; sp = shift_table[stateno]; if (sp) { k = sp->nshifts; for (j = 0; j < k; j++) { symbol = accessing_symbol[sp->shift[j]]; if (ISVAR(symbol)) break; SETBIT(rowp, symbol); } for (; j < k; j++) { symbol = accessing_symbol[sp->shift[j]]; if (nullable[symbol]) edge[nedges++] = map_goto(stateno, symbol); } if (nedges) { reads[i] = rp = NEW2(nedges + 1, short); for (j = 0; j < nedges; j++) rp[j] = edge[j]; rp[nedges] = -1; nedges = 0; } } rowp += tokensetsize; } SETBIT(F, 0); digraph(reads); for (i = 0; i < ngotos; i++) { if (reads[i]) FREE(reads[i]); } FREE(reads); FREE(edge); } build_relations() { register int i; register int j; register int k; register short *rulep; register short *rp; register shifts *sp; register int length; register int nedges; register int done; register int state1; register int stateno; register int symbol1; register int symbol2; register short *shortp; register short *edge; register short *states; register short **new_includes; includes = NEW2(ngotos, short *); edge = NEW2(ngotos + 1, short); states = NEW2(maxrhs + 1, short); for (i = 0; i < ngotos; i++) { nedges = 0; state1 = from_state[i]; symbol1 = accessing_symbol[to_state[i]]; for (rulep = derives[symbol1]; *rulep >= 0; rulep++) { length = 1; states[0] = state1; stateno = state1; for (rp = ritem + rrhs[*rulep]; *rp >= 0; rp++) { symbol2 = *rp; sp = shift_table[stateno]; k = sp->nshifts; for (j = 0; j < k; j++) { stateno = sp->shift[j]; if (accessing_symbol[stateno] == symbol2) break; } states[length++] = stateno; } add_lookback_edge(stateno, *rulep, i); length--; done = 0; while (!done) { done = 1; rp--; if (ISVAR(*rp)) { stateno = states[--length]; edge[nedges++] = map_goto(stateno, *rp); if (nullable[*rp] && length > 0) done = 0; } } } if (nedges) { includes[i] = shortp = NEW2(nedges + 1, short); for (j = 0; j < nedges; j++) shortp[j] = edge[j]; shortp[nedges] = -1; } } new_includes = transpose(includes, ngotos); for (i = 0; i < ngotos; i++) if (includes[i]) FREE(includes[i]); FREE(includes); includes = new_includes; FREE(edge); FREE(states); } add_lookback_edge(stateno, ruleno, gotono) int stateno, ruleno, gotono; { register int i, k; register int found; register shorts *sp; i = lookaheads[stateno]; k = lookaheads[stateno + 1]; found = 0; while (!found && i < k) { if (LAruleno[i] == ruleno) found = 1; else ++i; } assert(found); sp = NEW(shorts); sp->next = lookback[i]; sp->value = gotono; lookback[i] = sp; } short ** transpose(R, n) short **R; int n; { register short **new_R; register short **temp_R; register short *nedges; register short *sp; register int i; register int k; nedges = NEW2(n, short); for (i = 0; i < n; i++) { sp = R[i]; if (sp) { while (*sp >= 0) nedges[*sp++]++; } } new_R = NEW2(n, short *); temp_R = NEW2(n, short *); for (i = 0; i < n; i++) { k = nedges[i]; if (k > 0) { sp = NEW2(k + 1, short); new_R[i] = sp; temp_R[i] = sp; sp[k] = -1; } } FREE(nedges); for (i = 0; i < n; i++) { sp = R[i]; if (sp) { while (*sp >= 0) *temp_R[*sp++]++ = i; } } FREE(temp_R); return (new_R); } compute_FOLLOWS() { digraph(includes); } compute_lookaheads() { register int i, n; register unsigned *fp1, *fp2, *fp3; register shorts *sp, *next; register unsigned *rowp; rowp = LA; n = lookaheads[nstates]; for (i = 0; i < n; i++) { fp3 = rowp + tokensetsize; for (sp = lookback[i]; sp; sp = sp->next) { fp1 = rowp; fp2 = F + tokensetsize * sp->value; while (fp1 < fp3) *fp1++ |= *fp2++; } rowp = fp3; } for (i = 0; i < n; i++) for (sp = lookback[i]; sp; sp = next) { next = sp->next; FREE(sp); } FREE(lookback); FREE(F); } digraph(relation) short **relation; { register int i; infinity = ngotos + 2; INDEX = NEW2(ngotos + 1, short); VERTICES = NEW2(ngotos + 1, short); top = 0; R = relation; for (i = 0; i < ngotos; i++) INDEX[i] = 0; for (i = 0; i < ngotos; i++) { if (INDEX[i] == 0 && R[i]) traverse(i); } FREE(INDEX); FREE(VERTICES); } traverse(i) register int i; { register unsigned *fp1; register unsigned *fp2; register unsigned *fp3; register int j; register short *rp; int height; unsigned *base; VERTICES[++top] = i; INDEX[i] = height = top; base = F + i * tokensetsize; fp3 = base + tokensetsize; rp = R[i]; if (rp) { while ((j = *rp++) >= 0) { if (INDEX[j] == 0) traverse(j); if (INDEX[i] > INDEX[j]) INDEX[i] = INDEX[j]; fp1 = base; fp2 = F + j * tokensetsize; while (fp1 < fp3) *fp1++ |= *fp2++; } } if (INDEX[i] == height) { for (;;) { j = VERTICES[top--]; INDEX[j] = infinity; if (i == j) break; fp1 = base; fp2 = F + j * tokensetsize; while (fp1 < fp3) *fp2++ = *fp1++; } } } --- NEW FILE: lr0.c --- /* * Copyright (c) 1989 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * Robert Paul Corbett. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef lint static char sccsid[] = "@(#)lr0.c 5.3 (Berkeley) 1/20/91"; #endif /* not lint */ #include "defs.h" extern short *itemset; extern short *itemsetend; extern unsigned *ruleset; int nstates; core *first_state; shifts *first_shift; reductions *first_reduction; int get_state(); core *new_state(); static core **state_set; static core *this_state; static core *last_state; static shifts *last_shift; static reductions *last_reduction; static int nshifts; static short *shift_symbol; static short *redset; static short *shiftset; static short **kernel_base; static short **kernel_end; static short *kernel_items; allocate_itemsets() { register short *itemp; register short *item_end; register int symbol; register int i; register int count; register int max; register short *symbol_count; count = 0; symbol_count = NEW2(nsyms, short); item_end = ritem + nitems; for (itemp = ritem; itemp < item_end; itemp++) { symbol = *itemp; if (symbol >= 0) { count++; symbol_count[symbol]++; } } kernel_base = NEW2(nsyms, short *); kernel_items = NEW2(count, short); count = 0; max = 0; for (i = 0; i < nsyms; i++) { kernel_base[i] = kernel_items + count; count += symbol_count[i]; if (max < symbol_count[i]) max = symbol_count[i]; } shift_symbol = symbol_count; kernel_end = NEW2(nsyms, short *); } allocate_storage() { allocate_itemsets(); shiftset = NEW2(nsyms, short); redset = NEW2(nrules + 1, short); state_set = NEW2(nitems, core *); } append_states() { register int i; register int j; register int symbol; #ifdef TRACE fprintf(stderr, "Entering append_states()\n"); #endif for (i = 1; i < nshifts; i++) { symbol = shift_symbol[i]; j = i; while (j > 0 && shift_symbol[j - 1] > symbol) { shift_symbol[j] = shift_symbol[j - 1]; j--; } shift_symbol[j] = symbol; } for (i = 0; i < nshifts; i++) { symbol = shift_symbol[i]; shiftset[i] = get_state(symbol); } } free_storage() { FREE(shift_symbol); FREE(redset); FREE(shiftset); FREE(kernel_base); FREE(kernel_end); FREE(kernel_items); FREE(state_set); } generate_states() { allocate_storage(); itemset = NEW2(nitems, short); ruleset = NEW2(WORDSIZE(nrules), unsigned); set_first_derives(); initialize_states(); while (this_state) { closure(this_state->items, this_state->nitems); save_reductions(); new_itemsets(); append_states(); if (nshifts > 0) save_shifts(); this_state = this_state->next; } finalize_closure(); free_storage(); } int get_state(symbol) int symbol; { register int key; register short *isp1; register short *isp2; register short *iend; register core *sp; register int found; register int n; #ifdef TRACE fprintf(stderr, "Entering get_state(%d)\n", symbol); #endif isp1 = kernel_base[symbol]; iend = kernel_end[symbol]; n = iend - isp1; key = *isp1; assert(0 <= key && key < nitems); sp = state_set[key]; if (sp) { found = 0; while (!found) { if (sp->nitems == n) { found = 1; isp1 = kernel_base[symbol]; isp2 = sp->items; while (found && isp1 < iend) { if (*isp1++ != *isp2++) found = 0; } } if (!found) { if (sp->link) { sp = sp->link; } else { sp = sp->link = new_state(symbol); found = 1; } } } } else { state_set[key] = sp = new_state(symbol); } return (sp->number); } initialize_states() { register int i; register short *start_derives; register core *p; start_derives = derives[start_symbol]; for (i = 0; start_derives[i] >= 0; ++i) continue; p = (core *) MALLOC(sizeof(core) + i*sizeof(short)); if (p == 0) no_space(); p->next = 0; p->link = 0; p->number = 0; p->accessing_symbol = 0; p->nitems = i; for (i = 0; start_derives[i] >= 0; ++i) p->items[i] = rrhs[start_derives[i]]; first_state = last_state = this_state = p; nstates = 1; } new_itemsets() { register int i; register int shiftcount; register short *isp; register short *ksp; register int symbol; for (i = 0; i < nsyms; i++) kernel_end[i] = 0; shiftcount = 0; isp = itemset; while (isp < itemsetend) { i = *isp++; symbol = ritem[i]; if (symbol > 0) { ksp = kernel_end[symbol]; if (!ksp) { shift_symbol[shiftcount++] = symbol; ksp = kernel_base[symbol]; } *ksp++ = i + 1; kernel_end[symbol] = ksp; } } nshifts = shiftcount; } core * new_state(symbol) int symbol; { register int n; register core *p; register short *isp1; register short *isp2; register short *iend; #ifdef TRACE fprintf(stderr, "Entering new_state(%d)\n", symbol); #endif if (nstates >= MAXSHORT) fatal("too many states"); isp1 = kernel_base[symbol]; iend = kernel_end[symbol]; n = iend - isp1; p = (core *) allocate((unsigned) (sizeof(core) + (n - 1) * sizeof(short))); p->accessing_symbol = symbol; p->number = nstates; p->nitems = n; isp2 = p->items; while (isp1 < iend) *isp2++ = *isp1++; last_state->next = p; last_state = p; nstates++; return (p); } /* show_cores is used for debugging */ show_cores() { core *p; int i, j, k, n; int itemno; k = 0; for (p = first_state; p; ++k, p = p->next) { if (k) printf("\n"); printf("state %d, number = %d, accessing symbol = %s\n", k, p->number, symbol_name[p->accessing_symbol]); n = p->nitems; for (i = 0; i < n; ++i) { itemno = p->items[i]; printf("%4d ", itemno); j = itemno; while (ritem[j] >= 0) ++j; printf("%s :", symbol_name[rlhs[-ritem[j]]]); j = rrhs[-ritem[j]]; while (j < itemno) printf(" %s", symbol_name[ritem[j++]]); printf(" ."); while (ritem[j] >= 0) printf(" %s", symbol_name[ritem[j++]]); printf("\n"); fflush(stdout); } } } /* show_ritems is used for debugging */ show_ritems() { int i; for (i = 0; i < nitems; ++i) printf("ritem[%d] = %d\n", i, ritem[i]); } /* show_rrhs is used for debugging */ show_rrhs() { int i; for (i = 0; i < nrules; ++i) printf("rrhs[%d] = %d\n", i, rrhs[i]); } /* show_shifts is used for debugging */ show_shifts() { shifts *p; int i, j, k; k = 0; for (p = first_shift; p; ++k, p = p->next) { if (k) printf("\n"); printf("shift %d, number = %d, nshifts = %d\n", k, p->number, p->nshifts); j = p->nshifts; for (i = 0; i < j; ++i) printf("\t%d\n", p->shift[i]); } } save_shifts() { register shifts *p; register short *sp1; register short *sp2; register short *send; p = (shifts *) allocate((unsigned) (sizeof(shifts) + (nshifts - 1) * sizeof(short))); p->number = this_state->number; p->nshifts = nshifts; sp1 = shiftset; sp2 = p->shift; send = shiftset + nshifts; while (sp1 < send) *sp2++ = *sp1++; if (last_shift) { last_shift->next = p; last_shift = p; } else { first_shift = p; last_shift = p; } } save_reductions() { register short *isp; register short *rp1; register short *rp2; register int item; register int count; register reductions *p; register short *rend; count = 0; for (isp = itemset; isp < itemsetend; isp++) { item = ritem[*isp]; if (item < 0) { redset[count++] = -item; } } if (count) { p = (reductions *) allocate((unsigned) (sizeof(reductions) + (count - 1) * sizeof(short))); p->number = this_state->number; p->nreds = count; rp1 = redset; rp2 = p->rules; rend = rp1 + count; while (rp1 < rend) *rp2++ = *rp1++; if (last_reduction) { last_reduction->next = p; last_reduction = p; } else { first_reduction = p; last_reduction = p; } } } set_derives() { register int i, k; register int lhs; register short *rules; derives = NEW2(nsyms, short *); rules = NEW2(nvars + nrules, short); k = 0; for (lhs = start_symbol; lhs < nsyms; lhs++) { derives[lhs] = rules + k; for (i = 0; i < nrules; i++) { if (rlhs[i] == lhs) { rules[k] = i; k++; } } rules[k] = -1; k++; } #ifdef DEBUG print_derives(); #endif } free_derives() { FREE(derives[start_symbol]); FREE(derives); } #ifdef DEBUG print_derives() { register int i; register short *sp; printf("\nDERIVES\n\n"); for (i = start_symbol; i < nsyms; i++) { printf("%s derives ", symbol_name[i]); for (sp = derives[i]; *sp >= 0; sp++) { printf(" %d", *sp); } putchar('\n'); } putchar('\n'); } #endif set_nullable() { register int i, j; register int empty; int done; nullable = MALLOC(nsyms); if (nullable == 0) no_space(); for (i = 0; i < nsyms; ++i) nullable[i] = 0; done = 0; while (!done) { done = 1; for (i = 1; i < nitems; i++) { empty = 1; while ((j = ritem[i]) >= 0) { if (!nullable[j]) empty = 0; ++i; } if (empty) { j = rlhs[-j]; if (!nullable[j]) { nullable[j] = 1; done = 0; } } } } #ifdef DEBUG for (i = 0; i < nsyms; i++) { if (nullable[i]) printf("%s is nullable\n", symbol_name[i]); else printf("%s is not nullable\n", symbol_name[i]); } #endif } free_nullable() { FREE(nullable); } lr0() { set_derives(); set_nullable(); generate_states(); } --- NEW FILE: main.c --- /* * Copyright (c) 1989 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * Robert Paul Corbett. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT S... [truncated message content] |
Update of /cvsroot/csdoc/csdoc/src/mcsdoc/mcs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23564 Added Files: .cvsignore AssemblyInfo.cs ChangeLog NOTES OTODO README TODO anonymous.cs assign.cs attribute.cs cfold.cs class.cs codegen.cs compiler.doc compiler.sln const.cs constant.cs convert.cs cs-parser.jay cs-tokenizer.cs decl.cs delegate.cs driver.cs ecore.cs enum.cs errors.cs expression.cs flowanalysis.cs gen-il.cs gen-treedump.cs generic.cs genericparser.cs interface.cs iterators.cs literal.cs location.cs makefile makefile.gnu makefile.old mcs.exe.config mcs.exe.sources modifiers.cs namespace.cs old-code.cs parameter.cs parameterCollection.cs parser.cs pending.cs report.cs rootcontext.cs statement.cs statementCollection.cs support.cs symbolwriter.cs tree.cs typemanager.cs Log Message: 2004-10-28 Gaurav Vaish * **/* : Getting the latest sync from mono repository. Will resume work pretty soon. Moving final work from csdoc to mcsdoc. --- NEW FILE: .cvsignore --- *.mdb *.pdb Web References Web References Web References bin compiler.csproj compiler.csproj.user compiler.exe compiler.pdb compiler.suo cs-parser.cs mcs obj semantic.cache y.output mcs.exe --- NEW FILE: AssemblyInfo.cs --- using System.Reflection; using System.Runtime.CompilerServices; [assembly: AssemblyVersion("1.1.1")] [assembly: AssemblyTitle ("Mono C# Compiler")] [assembly: AssemblyDescription ("Mono C# Compiler")] [assembly: AssemblyCopyright ("2001, 2002, 2003 Ximian, Inc.")] [assembly: AssemblyCompany ("Ximian, Inc.")] --- NEW FILE: ChangeLog --- 2004-10-27 Miguel de Icaza <mi...@xi...> * expression.cs (LocalVariableReference.DoResolveLValue): Check for obsolete use of a variable here. Fixes regression on errors cs0619-25 and cs0619-26. 2004-10-27 Marek Safar <mar...@se...> Fix #62358, implemented security attribute encoding. * attribute.cs (Attribute.CheckSecurityActionValididy): New method. Tests permitted SecurityAction for assembly or other types. (Assembly.ExtractSecurityPermissionSet): New method. Transforms data from SecurityPermissionAttribute to PermisionSet class. * class.cs (ApplyAttributeBuilder): Added special handling for System.Security.Permissions.SecurityAttribute based types. * codegen.cs (AssemblyClass.ApplyAttributeBuilder): Added [...17202 lines suppressed...] 2001-04-27 Miguel de Icaza <mi...@xi...> * System.CodeDOM/CodeBinaryOperatorExpression.cs: Rearrange enum to match the values in System.CodeDOM. Divid renamed to Divide. * System.CodeDOM/CodeForLoopStatement.cs: Always have valid statements. (Statements.set): remove. * System.CodeDOM/CodeCatchClause.cs: always have a valid statements. * System.CodeDOM/CodeIfStatement.cs: trueStatements and falseStatements always have valid values. * cs-parser.jay: Use System.CodeDOM now. --- NEW FILE: NOTES --- * Notes on improving error handling in MCS (from Axel Schreiner <at...@cs...>) I included the 'recover' example with C# as well. Currently the package is at <http://www.cs.rit.edu/~ats/projects/jay/>. I did change some names and the embedding that the user does somewhat, i.e., it is not directly compatible with what you did. Here is the important part about error recovery. To make the typical iterations bullet-proof, code them as follows: opt : // null | opt WORD { yyErrorFlag = 0; } | opt error seq : WORD | seq WORD { yyErrorFlag = 0; } | error | seq error list : WORD | list ',' WORD { yyErrorFlag = 0; } | error | list error | list error WORD { yyErrorFlag = 0; } | list ',' error i.e., throw in 'error' wherever a token can be. 'yyErrorFlag' need not be set to zero, but if it is done this way, second errors are caught earlier. This may introduce s/r conflicts, but they tend to be harmless. In your case -- the comment concerning error recovery at the beginning of your compiler jay file -- just adding 'error' to the different global things won't work. Your example will already have started to advance in one of the rules and 'error' is then not in the lookahead of wherever the parse then is. You need to put 'error' into the iteration above those global things. --- NEW FILE: OTODO --- ---- This is a list of old tasks, just here for historical value ---- Open question: Create a toplevel block for anonymous methods? Anonymous Methods ----------------- Plan: * Resolve anonymous methods before. * Each time a Local matches, if the mode is `InAnonymous', flag the VariableInfo for `proxying'. * During Resolve track the depth required for local variables. * Before Emit, create proxy classes with proper depth. * Emit. Notes on memory allocation -------------------------- Outdated: A run of the AllocationProfile shows that the compiler allocates roughly 30 megabytes of strings. From those, 20 megabytes come from LookupType. See the notes on current_container problems below on memory usage. LookupTypeReflection: --------------------- With something like `System.Object', LookupTypeReflection will be called twice: once to find out that `System' is not a type and once for System.Object. This is required because System.Reflection requires that the type/nested types are not separated by a dot but by a plus sign. A nested class would be My+Class (My being the toplevel, Class the nested one). It is interesting to look at the most called lookups when bootstrapping MCS: 647 LTR: ArrayList 713 LTR: System.Globalization 822 LTR: System.Object+Expression 904 LTR: Mono.CSharp.ArrayList 976 LTR: System.Runtime.CompilerServices 999 LTR: Type 1118 LTR: System.Runtime 1208 LTR: Mono.CSharp.Type 1373 LTR: Mono.Languages 1599 LTR: System.Diagnostics 2036 LTR: System.Text 2302 LTR: System.Reflection.Emit 2515 LTR: System.Collections 4527 LTR: System.Reflection 22273 LTR: Mono.CSharp 24245 LTR: System 27005 LTR: Mono Analysis: The top 9 lookups are done for things which are not types. Mono.CSharp.Type happens to be a common lookup: the class Type used heavily in the compiler in the default namespace. RED FLAG: Then `Type' is looked up alone a lot of the time, this happens in parameter declarations and am not entirely sure that this is correct (FindType will pass to LookupInterfaceOrClass a the current_type.FullName, which for some reason is null!). This seems to be a problem with a lost piece of context during FindType. System.Object is also used a lot as a toplevel class, and we assume it will have children, we should just shortcut this. A cache: Adding a cache and adding a catch for `System.Object' to flag that it wont be the root of a hierarchy reduced the MCS bootstrap time from 10.22 seconds to 8.90 seconds. This cache is currently enabled with SIMPLE_SPEEDUP in typemanager.cs. Memory consumption went down from 74 megs to 65 megs with this change. Major tasks: ------------ Pinned and volatile require type modifiers that can not be encoded with Reflection.Emit. * Revisit Primary-expression, as it has now been split into non-array-creation-expression and array-creation-expression. * Emit `pinned' for pinned local variables. Both `modreq' and pinned will require special hacks in the compiler. * Make sure that we are pinning the right variable * local_variable_declaration Not sure that this grammar is correct, we might have to resolve this during semantic analysis. * Optimizations In Indexers and Properties, probably support an EmitWithDup That emits the code to call Get and then leaves a this pointer in the stack, so that later a Store can be emitted using that this pointer (consider Property++ or Indexer++) * Use of local temporary in UnaryMutator We should get rid of the Localtemporary there for some cases This turns out to be very complex, at least for the post-version, because this case: a = i++ To produce optimal code, it is necessary for UnaryMutator to know that it is being assigned to a variable (the way the stack is laid out using dup requires the store to happen inside UnaryMutator). * Interface indexers I have not figured out why the Microsoft version puts an `instance' attribute, and I am not generating this `instance' attribute. Explanation: The reason for the `instance' attribute on indexers is that indexers only apply to instances * Check for Final when overriding, if the parent is Final, then we cant allow an override. Implement base indexer access. current_container/current_namespace and the DeclSpace ----------------------------------------------------- We are storing fully qualified names in the DeclSpace instead of the node, this is because `current_namespace' (Namepsace) is not a DeclSpace like `current_container'. The reason for storing the full names today is this: namespace X { class Y { } } namespace A { class Y { } } The problem is that we only use the namespace stack to track the "prefix" for typecontainers, but they are not typecontainers themselves, so we have to use fully qualified names, because both A.X and A.Y would be entered in the toplevel type container. If we use the short names, there would be a name clash. To fix this problem, we have to make namespaces DeclSpaces. The full size, contrasted with the size that could be stored is: corlib: Size of strings held: 368901 Size of strings short: 147863 System: Size of strings held: 212677 Size of strings short: 97521 System.XML: Size of strings held: 128055 Size of strings short: 35782 System.Data: Size of strings held: 117896 Size of strings short: 36153 System.Web: Size of strings held: 194527 Size of strings short: 58064 System.Windows.Forms: Size of strings held: 220495 Size of strings short: 64923 The use of DottedName --------------------- We could probably use a different system to represent names, like this: class Name { string simplename; Name parent; } So `System.ComponentModel' becomes: x: (System, null) y: (ComponentModel, x) The problem is that we would still need to construct the name to pass to GetType. This has been now implemented, its called "QualifiedIdentifier" TODO: 1. Create a "partial" emit context for each TypeContainer.. 2. EmitContext should be partially constructed. No IL Generator. interface_type review. parameter_array, line 952: `note: must be a single dimension array type'. Validate this Instance idea ------------- It would be nice to have things that can be "instances" to have an EmitInstance method (this would default to nothing). The idea is to be able to use efficiently the instance data on stack manipulations, as opposed to the current scheme, where we basically have a few special cases. * `yield' is no longer a keyword, it only has special meaning before a return or break keywords. * Study side effects with assign * Study TemporaryStorage/LocalStorage -> Merge/rename --- NEW FILE: README --- These are the sources to the Mono C# compiler --------------------------------------------- Read the mcs/docs/compiler.txt for an overview of the compiler. Testing the Compiler -------------------- You might want to use the `make btest' in this directory to have the compiler bootstrap itself, this is the basic regression test. Before commiting changes to MCS, make sure that all the tests in `mcs/tests' pass, and all the tests in 'mcs/errors' have the expected result, type: cd mcs # The top-level 'mcs' directory make compiler-tests If you want to test the installed compiler, you can run: cd mcs # The top-level 'mcs' directory make test-installed-compiler Full Bootstrap ============== To finally ensure the state of the compiler, it is ideal to do a full bootstrap, to do this, do: cd mcs make clean; make make install That installs the compiler and assemblies compiled by the new compiler. Then, repeat that step again: make clean make If things work, the compiler has not added a new regression while building the mscorlib and the compiler itself. Tests ===== When bugs are fixed, new tests must be added to the `mcs/tests' directory to excercise the problem and to guarantee that we keep the compiler in a good state. When an error is reported, it should be added to mcs/errors. We try to make the errors numbers be the same as the ones in Microsoft C#, if this is not possible, allocate a negative error number, and list it in mcs/errors/errors.txt --- NEW FILE: TODO --- NEW NOTES: ---------- ImplicitStandardConversionExists and ImplicitStandardConversion should always be the same, but there are a few diverging lines that must be studied: if (expr_type == target_type && !(expr is NullLiteral)) return expr; vs: if (expr_type == target_type) return true; Null Type --------- Need to introduce the NullType concept into the compiler, to address a few small buglets and remove the hardcoded values for NullLiteral. NullLiteral will be the only expression that has the NullType as its type. This is what must be used to test for Null literals, instead of `is NullLiteral', and this will introduce a couple of fixes to the rules. Revert Martin's patch to Conditional expression that worked around this bug: Reference r = xx ? null : null The right fix is to introduce NullType **************************************************************************************** * * The information on the rest of this file is mostly outdated, and its kept here for * historical reasons * **************************************************************************************** Error Reporting: ---------------- * Make yyerror show a nice syntax error, instead of the current mess. Iterators --------- * Reset should throw not implemented now. Optimization ideas ------------------ Currently when we build a type cache, it contains private members, internal members, and internal protected members; We should trim these out, as it shows up on the profile. We create too many Arraylists; When we know the size, we should create an array; During parsing we use arraylists to accumulate data, like this: thing: thing_list : thing { $$ =new ArrayList (); $$.Add ($1); } | thing_list thing { ArrayList a = $1; a.Add ($2); $$ = a; } We probably could start using "Pairs" there: thing_list : thing { $$ = new Pair ($1, null); } | thing_list thing { Pair p = $1; $$ = new Pair ($2, $1); } EmitContext.ResolveTypeTree --------------------------- We should investigate its usage. The problem is that by default this will be set when calling FindType, that triggers a more expensive lookup. I believe we should pass the current EmitContext (which has this turned off by default) to ResolveType/REsolveTypeExpr and then have the routines that need ResolveType to pass null as the emit context. DeclareLocal audit ------------------ DeclareLocal is used in various statements. The audit should be done in two steps: * Identify all the declare locals. * Identify its uses. * Find if we can make wrapper functions for all of them. Then we can move DeclareLocal into a helper class. This is required to fix foreach in iterators. Large project: -------------- Drop FindMembers as our API and instead extract all the data out of a type the first time into our own datastructures, and use that to navigate and search the type instead of the callback based FindMembers. Martin has some some of this work with his TypeHandle code that we could use for this. Ideas: ------ Instead of the hack that *knows* about System.Object not having any children classes, we should just make it simple for a probe to know that there is no need for it. Dead Code Elimination bugs: --------------------------- I should also resolve all the children expressions in Switch, Fixed, Using. Major tasks: ------------ Properties and 17.6.3: Finish it. readonly variables and ref/out BUGS ---- * Break/Continue statements A finally block should reset the InLoop/LoopBegin/LoopEnd, as they are logically outside the scope of the loop. * Break/continue part 2. They should transfer control to the finally block if inside a try/catch block. * Method Registration and error CS111 The way we use the method registration to signal 111 is wrong. Method registration should only be used to register methodbuilders, we need an alternate method of checking for duplicates. * > // CSC sets beforefieldinit > class X { > // .cctor will be generated by compiler > public static readonly object O = new System.Object (); > public static void Main () {} > } > PENDING TASKS ------------- * Merge test 89 and test-34 * Code cleanup The information when registering a method in InternalParameters is duplicated, you can always get the types from the InternalParameters * Emit modreq for volatiles Handle modreq from public apis. * Merge tree.cs, rootcontext.cs OPTIMIZATIONS ------------- * User Defined Conversions is doing way too many calls to do union sets that are not needed * Add test case for destructors * Places that use `Ldelema' are basically places where I will be initializing a value type. I could apply an optimization to disable the implicit local temporary from being created (by using the method in New). * Dropping TypeContainer as an argument to EmitContext My theory is that I can get rid of the TypeBuilder completely from the EmitContext, and have typecasts where it is used (from DeclSpace to where it matters). The only pending problem is that the code that implements Aliases is on TypeContainer, and probably should go in DeclSpace. * Tests Write tests for the various reference conversions. We have test for all the numeric conversions. * Optimizations: variable allocation. When local variables of a type are required, we should request the variable and later release it when we are done, so that the same local variable slot can be reused later on. * Add a cache for the various GetArrayMethod operations. * MakeUnionSet Callers If the types are the same, there is no need to compute the unionset, we can just use the list from one of the types. * Factor the lookup code for class declarations an interfaces (interface.cs:GetInterfaceByName) RECOMMENDATIONS --------------- * Use of lexer.Location in the parser Currently we do: TOKEN nt TERMINAL nt TERMINAL nt3 { $$ = new Blah ($2, $4, $6, lexer.Location); } This is bad, because the lexer.Location is for the last item in `nt3' We need to change that to use this pattern: TOKEN { oob_stack.Push (lexer.Location) } nt TERMINAL nt TERMINAL nt3 { $$ = new Blah ($3, $5, $7, (Location) oob_stack.Pop ()); } Notice how numbering of the arguments changes as the { oob_stack.Push (lexer.Location) } takes a "slot" in the productions. --- NEW FILE: anonymous.cs --- // // anonymous.cs: Support for anonymous methods // // Author: // Miguel de Icaza (mi...@xi...) // // (C) 2003, 2004 Novell, Inc. // // TODO: Ideally, we should have the helper classes emited as a hierarchy to map // their nesting, and have the visibility set to private, instead of NestedAssembly // // // using System; using System.Text; using System.Collections; using System.Reflection; using System.Reflection.Emit; [...1098 lines suppressed...] if (scopes [b.ID] != null){ LinkScope (scope, b.ID); break; } } if (scope.ParentScope == null && ParentCaptureContext != null){ CaptureContext pcc = ParentCaptureContext; for (Block b = Host.ContainingBlock; b != null; b = b.Parent){ if (pcc.scopes [b.ID] != null){ pcc.LinkScope (scope, b.ID); break; } } } } } } } --- NEW FILE: assign.cs --- // // assign.cs: Assignments. // // Author: // Miguel de Icaza (mi...@xi...) // Martin Baulig (ma...@gn...) // // (C) 2001, 2002, 2003 Ximian, Inc. // using System; using System.Reflection; using System.Reflection.Emit; namespace Mono.CSharp { /// <summary> /// This interface is implemented by expressions that can be assigned to. /// </summary> /// <remarks> /// This interface is implemented by Expressions whose values can not /// store the result on the top of the stack. /// /// Expressions implementing this (Properties, Indexers and Arrays) would /// perform an assignment of the Expression "source" into its final /// location. /// /// No values on the top of the stack are expected to be left by /// invoking this method. /// </remarks> public interface IAssignMethod { // // This is an extra version of Emit. If leave_copy is `true' // A copy of the expression will be left on the stack at the // end of the code generated for EmitAssign // void Emit (EmitContext ec, bool leave_copy); // // This method does the assignment // `source' will be stored into the location specified by `this' // if `leave_copy' is true, a copy of `source' will be left on the stack // if `prepare_for_load' is true, when `source' is emitted, there will // be data on the stack that it can use to compuatate its value. This is // for expressions like a [f ()] ++, where you can't call `f ()' twice. // void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool prepare_for_load); /* For simple assignments, this interface is very simple, EmitAssign is called with source as the source expression and leave_copy and prepare_for_load false. For compound assignments it gets complicated. EmitAssign will be called as before, however, prepare_for_load will be true. The @source expression will contain an expression which calls Emit. So, the calls look like: this.EmitAssign (ec, source, false, true) -> source.Emit (ec); -> [...] -> this.Emit (ec, false); -> end this.Emit (ec, false); -> end [...] end source.Emit (ec); end this.EmitAssign (ec, source, false, true) When prepare_for_load is true, EmitAssign emits a `token' on the stack that Emit will use for its state. Let's take FieldExpr as an example. assume we are emitting f ().y += 1; Here is the call tree again. This time, each call is annotated with the IL it produces: this.EmitAssign (ec, source, false, true) call f dup Binary.Emit () this.Emit (ec, false); ldfld y end this.Emit (ec, false); IntConstant.Emit () ldc.i4.1 end IntConstant.Emit add end Binary.Emit () stfld end this.EmitAssign (ec, source, false, true) Observe two things: 1) EmitAssign left a token on the stack. It was the result of f (). 2) This token was used by Emit leave_copy (in both EmitAssign and Emit) tells the compiler to leave a copy of the expression at that point in evaluation. This is used for pre/post inc/dec and for a = x += y. Let's do the above example with leave_copy true in EmitAssign this.EmitAssign (ec, source, true, true) call f dup Binary.Emit () this.Emit (ec, false); ldfld y end this.Emit (ec, false); IntConstant.Emit () ldc.i4.1 end IntConstant.Emit add end Binary.Emit () dup stloc temp stfld ldloc temp end this.EmitAssign (ec, source, true, true) And with it true in Emit this.EmitAssign (ec, source, false, true) call f dup Binary.Emit () this.Emit (ec, true); ldfld y dup stloc temp end this.Emit (ec, true); IntConstant.Emit () ldc.i4.1 end IntConstant.Emit add end Binary.Emit () stfld ldloc temp end this.EmitAssign (ec, source, false, true) Note that these two examples are what happens for ++x and x++, respectively. */ } /// <summary> /// An Expression to hold a temporary value. /// </summary> /// <remarks> /// The LocalTemporary class is used to hold temporary values of a given /// type to "simulate" the expression semantics on property and indexer /// access whose return values are void. /// /// The local temporary is used to alter the normal flow of code generation /// basically it creates a local variable, and its emit instruction generates /// code to access this value, return its address or save its value. /// /// If `is_address' is true, then the value that we store is the address to the /// real value, and not the value itself. /// /// This is needed for a value type, because otherwise you just end up making a /// copy of the value on the stack and modifying it. You really need a pointer /// to the origional value so that you can modify it in that location. This /// Does not happen with a class because a class is a pointer -- so you always /// get the indirection. /// /// The `is_address' stuff is really just a hack. We need to come up with a better /// way to handle it. /// </remarks> public class LocalTemporary : Expression, IMemoryLocation { LocalBuilder builder; bool is_address; public LocalTemporary (EmitContext ec, Type t) : this (ec, t, false) {} public LocalTemporary (EmitContext ec, Type t, bool is_address) { type = t; eclass = ExprClass.Value; loc = Location.Null; builder = ec.GetTemporaryLocal (is_address ? TypeManager.GetReferenceType (t): t); this.is_address = is_address; } public LocalTemporary (LocalBuilder b, Type t) { type = t; eclass = ExprClass.Value; loc = Location.Null; builder = b; } public void Release (EmitContext ec) { ec.FreeTemporaryLocal (builder, type); builder = null; } public override Expression DoResolve (EmitContext ec) { return this; } public override void Emit (EmitContext ec) { ILGenerator ig = ec.ig; ig.Emit (OpCodes.Ldloc, builder); // we need to copy from the pointer if (is_address) LoadFromPtr (ig, type); } // NB: if you have `is_address' on the stack there must // be a managed pointer. Otherwise, it is the type from // the ctor. public void Store (EmitContext ec) { ILGenerator ig = ec.ig; ig.Emit (OpCodes.Stloc, builder); } public void AddressOf (EmitContext ec, AddressOp mode) { // if is_address, than this is just the address anyways, // so we just return this. ILGenerator ig = ec.ig; if (is_address) ig.Emit (OpCodes.Ldloc, builder); else ig.Emit (OpCodes.Ldloca, builder); } public bool PointsToAddress { get { return is_address; } } } /// <summary> /// The Assign node takes care of assigning the value of source into /// the expression represented by target. /// </summary> public class Assign : ExpressionStatement { protected Expression target, source, real_source; protected LocalTemporary temp = null, real_temp = null; protected Assign embedded = null; protected bool is_embedded = false; protected bool must_free_temp = false; public Assign (Expression target, Expression source, Location l) { this.target = target; this.source = this.real_source = source; this.loc = l; } protected Assign (Assign embedded, Location l) : this (embedded.target, embedded.source, l) { this.is_embedded = true; } protected virtual Assign GetEmbeddedAssign (Location loc) { return new Assign (this, loc); } public Expression Target { get { return target; } set { target = value; } } public Expression Source { get { return source; } set { source = value; } } public static void error70 (EventInfo ei, Location l) { Report.Error (70, l, "The event '" + ei.Name + "' can only appear on the left-side of a += or -= (except when" + " used from within the type '" + ei.DeclaringType + "')"); } // // Will return either `this' or an instance of `New'. // public override Expression DoResolve (EmitContext ec) { // Create an embedded assignment if our source is an assignment. if (source is Assign) source = embedded = ((Assign) source).GetEmbeddedAssign (loc); real_source = source = source.Resolve (ec); if (source == null) return null; // // This is used in an embedded assignment. // As an example, consider the statement "A = X = Y = Z". // if (is_embedded && !(source is Constant)) { // If this is the innermost assignment (the "Y = Z" in our example), // create a new temporary local, otherwise inherit that variable // from our child (the "X = (Y = Z)" inherits the local from the // "Y = Z" assignment). if (embedded == null) { if (this is CompoundAssign) real_temp = temp = new LocalTemporary (ec, target.Type); else real_temp = temp = new LocalTemporary (ec, source.Type); } else temp = embedded.temp; // Set the source to the new temporary variable. // This means that the following target.ResolveLValue () will tell // the target to read it's source value from that variable. source = temp; } // If we have an embedded assignment, use the embedded assignment's temporary // local variable as source. if (embedded != null) source = (embedded.temp != null) ? embedded.temp : embedded.source; target = target.ResolveLValue (ec, source); if (target == null) return null; Type target_type = target.Type; Type source_type = real_source.Type; // If we're an embedded assignment, our parent will reuse our source as its // source, it won't read from our target. if (is_embedded) type = source_type; else type = target_type; eclass = ExprClass.Value; if (target is EventExpr) { EventInfo ei = ((EventExpr) target).EventInfo; Expression ml = MemberLookup ( ec, ec.ContainerType, ei.Name, MemberTypes.Event, AllBindingFlags | BindingFlags.DeclaredOnly, loc); if (ml == null) { // // If this is the case, then the Event does not belong // to this Type and so, according to the spec // is allowed to only appear on the left hand of // the += and -= operators // // Note that target will not appear as an EventExpr // in the case it is being referenced within the same type container; // it will appear as a FieldExpr in that case. // if (!(source is BinaryDelegate)) { error70 (ei, loc); return null; } } } if (source is New && target_type.IsValueType && (target.eclass != ExprClass.IndexerAccess) && (target.eclass != ExprClass.PropertyAccess)){ New n = (New) source; if (n.SetValueTypeVariable (target)) return n; else return null; } if (!(target is IAssignMethod) && (target.eclass != ExprClass.EventAccess)) { Report.Error (131, loc, "Left hand of an assignment must be a variable, " + "a property or an indexer"); return null; } if ((source.eclass == ExprClass.Type) && (source is TypeExpr)) { source.Error_UnexpectedKind ("variable or value", loc); return null; } else if ((RootContext.Version == LanguageVersion.ISO_1) && (source is MethodGroupExpr)){ ((MethodGroupExpr) source).ReportUsageError (); return null; } if (target_type == source_type) return this; // // If this assignemnt/operator was part of a compound binary // operator, then we allow an explicit conversion, as detailed // in the spec. // if (this is CompoundAssign){ CompoundAssign a = (CompoundAssign) this; Binary b = source as Binary; if (b != null){ // // 1. if the source is explicitly convertible to the // target_type // source = Convert.ExplicitConversion (ec, source, target_type, loc); if (source == null){ Convert.Error_CannotImplicitConversion (loc, source_type, target_type); return null; } // // 2. and the original right side is implicitly convertible to // the type of target // if (Convert.ImplicitStandardConversionExists (ec, a.original_source, target_type)) return this; // // In the spec 2.4 they added: or if type of the target is int // and the operator is a shift operator... // if (source_type == TypeManager.int32_type && (b.Oper == Binary.Operator.LeftShift || b.Oper == Binary.Operator.RightShift)) return this; Convert.Error_CannotImplicitConversion (loc, a.original_source.Type, target_type); return null; } } source = Convert.ImplicitConversionRequired (ec, source, target_type, loc); if (source == null) return null; // If we're an embedded assignment, we need to create a new temporary variable // for the converted value. Our parent will use this new variable as its source. // The same applies when we have an embedded assignment - in this case, we need // to convert our embedded assignment's temporary local variable to the correct // type and store it in a new temporary local. if (is_embedded || embedded != null) { type = target_type; temp = new LocalTemporary (ec, type); must_free_temp = true; } return this; } Expression EmitEmbedded (EmitContext ec) { // Emit an embedded assignment. if (real_temp != null) { // If we're the innermost assignment, `real_source' is the right-hand // expression which gets assigned to all the variables left of it. // Emit this expression and store its result in real_temp. real_source.Emit (ec); real_temp.Store (ec); } if (embedded != null) embedded.EmitEmbedded (ec); // This happens when we've done a type conversion, in this case source will be // the expression which does the type conversion from real_temp. // So emit it and store the result in temp; this is the var which will be read // by our parent. if (temp != real_temp) { source.Emit (ec); temp.Store (ec); } Expression temp_source = (temp != null) ? temp : source; ((IAssignMethod) target).EmitAssign (ec, temp_source, false, false); return temp_source; } void ReleaseEmbedded (EmitContext ec) { if (embedded != null) embedded.ReleaseEmbedded (ec); if (real_temp != null) real_temp.Release (ec); if (must_free_temp) temp.Release (ec); } void Emit (EmitContext ec, bool is_statement) { if (target is EventExpr) { ((EventExpr) target).EmitAddOrRemove (ec, source); return; } IAssignMethod am = (IAssignMethod) target; Expression temp_source; if (embedded != null) { temp_source = embedded.EmitEmbedded (ec); if (temp != null) { source.Emit (ec); temp.Store (ec); temp_source = temp; } } else temp_source = source; am.EmitAssign (ec, temp_source, !is_statement, this is CompoundAssign); if (embedded != null) { if (temp != null) temp.Release (ec); embedded.ReleaseEmbedded (ec); } } public override void Emit (EmitContext ec) { Emit (ec, false); } public override void EmitStatement (EmitContext ec) { Emit (ec, true); } } // // This class is used for compound assignments. // class CompoundAssign : Assign { Binary.Operator op; public Expression original_source; public CompoundAssign (Binary.Operator op, Expression target, Expression source, Location l) : base (target, source, l) { original_source = source; this.op = op; } protected CompoundAssign (CompoundAssign embedded, Location l) : this (embedded.op, embedded.target, embedded.source, l) { this.is_embedded = true; } protected override Assign GetEmbeddedAssign (Location loc) { return new CompoundAssign (this, loc); } public Expression ResolveSource (EmitContext ec) { return original_source.Resolve (ec); } public override Expression DoResolve (EmitContext ec) { original_source = original_source.Resolve (ec); if (original_source == null) return null; target = target.Resolve (ec); if (target == null) return null; // // Only now we can decouple the original source/target // into a tree, to guarantee that we do not have side // effects. // source = new Binary (op, target, original_source, loc); return base.DoResolve (ec); } } } --- NEW FILE: attribute.cs --- // // attribute.cs: Attribute Handler // // Author: Ravi Pratap (ra...@xi...) // Marek Safar (mar...@se...) // // Licensed under the terms of the GNU GPL // // (C) 2001 Ximian, Inc (http://www.ximian.com) // // using System; using System.Diagnostics; using System.Collections; using System.Collections.Specialized; using System.Reflection; using System.Reflection.Emit; using System.Runtime.InteropServices; [...1526 lines suppressed...] if (excluded != null) return excluded == TRUE ? true : false; ConditionalAttribute[] attrs = mb.GetCustomAttributes (TypeManager.conditional_attribute_type, true) as ConditionalAttribute[]; if (attrs.Length == 0) { analyzed_method_excluded.Add (mb, FALSE); return false; } foreach (ConditionalAttribute a in attrs) { if (RootContext.AllDefines.Contains (a.ConditionString)) { analyzed_method_excluded.Add (mb, FALSE); return false; } } analyzed_method_excluded.Add (mb, TRUE); return true; } } } --- NEW FILE: cfold.cs --- // // cfold.cs: Constant Folding // // Author: // Miguel de Icaza (mi...@xi...) // // (C) 2002, 2003 Ximian, Inc. // using System; namespace Mono.CSharp { public class ConstantFold { // // Performs the numeric promotions on the left and right expresions // and desposits the results on `lc' and `rc'. // [...1155 lines suppressed...] ((ULongConstant) right).Value; else if (left is LongConstant) bool_res = ((LongConstant) left).Value <= ((LongConstant) right).Value; else if (left is UIntConstant) bool_res = ((UIntConstant) left).Value <= ((UIntConstant) right).Value; else if (left is IntConstant) bool_res = ((IntConstant) left).Value <= ((IntConstant) right).Value; else return null; return new BoolConstant (bool_res); } return null; } } } --- NEW FILE: class.cs --- // // class.cs: Class and Struct handlers // // Authors: Miguel de Icaza (mi...@gn...) // Martin Baulig (ma...@gn...) // Marek Safar (mar...@se...) // // Licensed under the terms of the GNU GPL // // (C) 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com) // // // 2002-10-11 Miguel de Icaza <mi...@xi...> // // * class.cs: Following the comment from 2002-09-26 to AddMethod, I // have fixed a remaining problem: not every AddXXXX was adding a // fully qualified name. // // Now everyone registers a fully qualified name in the DeclSpace as [...7229 lines suppressed...] Type [] args; if (mi != null) args = TypeManager.GetArgumentTypes (mi); else args = TypeManager.GetArgumentTypes (pi); Type [] sigp = sig.Parameters; if (args.Length != sigp.Length) return false; for (int i = args.Length; i > 0; ){ i--; if (args [i] != sigp [i]) return false; } return true; } } } --- NEW FILE: codegen.cs --- // // codegen.cs: The code generator // // Author: // Miguel de Icaza (mi...@xi...) // // (C) 2001, 2002, 2003 Ximian, Inc. // (C) 2004 Novell, Inc. // //#define PRODUCTION using System; using System.IO; using System.Collections; using System.Collections.Specialized; using System.Reflection; using System.Reflection.Emit; using System.Runtime.InteropServices; using System.Security; using System.Security.Cryptography; [...1302 lines suppressed...] ApplyAttributeBuilder (null, new CustomAttributeBuilder (TypeManager.unverifiable_code_ctor, new object [0])); } public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder customBuilder) { if (a != null && a.Type == TypeManager.cls_compliant_attribute_type) { Report.Warning (3012, a.Location, "You must specify the CLSCompliant attribute on the assembly, not the module, to enable CLS compliance checking"); return; } Builder.SetCustomAttribute (customBuilder); } public override string[] ValidAttributeTargets { get { return attribute_targets; } } } } --- NEW FILE: compiler.doc --- Compiler operation The compiler has a number of phases: * Parsing. Initially the compiler parses all the source files and keeps a parsed representation in memory. Very syntax error checking is performed at this point. The compiler stores the information in classes whose names represent the language construct, for example, the "if" construct is stored in an `If' class. A class is stored in a `Class'. * The TypeManager The TypeManager loads all the assemblies that were referenced by the programmer. The CLR type system is used as our repository for types defined as well. So the same interface that is used to query the types, properties and flags about system types is the same interface that we use for our types. As we work our way through the code generation and semantic analysis, new types are entered into the Type system through the use of System.Reflection.Emit. The TypeManager will lookup types on both the user defined types and on the system defined ones. So special care has to be used. The order in which we proceeed from here is important. * Base class resolution and type definition. Once the parsing has happened, the compiler resolves the inheritance tree for interfaces. This is done recursively and we catch recursive interface definitions here. After this is done, we continue on with classes. Classes have can have an optional "parent" inherit from or the implicit System.Object class (for normal builds, builds with /nostdlib will allow you to compile class System.Object with no parent). At this point we do some error checking and verify that the inherits/implements section of a class is correct (since we have previously built the interface inheritance). By the time we are done, all classes, structs and interfaces have been created using System.Reflection.Emit and registered with the Type Manager. This allows us to define fields and resolve argument names for methods, properties, indexers and events. * Field generation Fields are generated next, we go through all the type containers (classes and structs) and enter the fields into their types. * Method, Properties, Indexers and events definitions Now all the methods, constructors, properties, indexers and events are entered. They are only `defined' using System.Reflection.Emit. No code generation will happen until everything has been entered into System.Reflection.Emit. This is important because to actually generate code we need to know everything about the environment in which the code is being generated. * Code Generation At this point all the definitions have been entered into the type manager through System.Reflection.Emit. We can now use System.Reflection to query all the information about the types. Your normal semantic analysis and code generation phase lives here. * Statements Most of the statements are handled in the codegen.cs file. * Expressions * Error reporting We should try to use the `Report.Error' and `Report.Warning' classes which are part of the RootContext (there is even a property to access it). Error reporting should try to use the same codes that the Microsoft compiler uses (if only so we can track which errors we handle and which ones we dont). If there is an error which is specific to MSC, use negative numbers, and register the number in mcs/errors/errors.txt Try to write a test case for any error that you run into the code of the compiler if there is none already. Put your test case in a file called csNNNN.cs in the mcs/errors directory, and have the first two lines be: // csNNNN.cs: This is the description. // Line: XXX Where `XXX' is the line where the error ocurrs. We will later use this as a regression test suite for catching errors in the compiler. --- NEW FILE: compiler.sln --- Microsoft Visual Studio Solution File, Format Version 8.00 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "compiler", "compiler.csproj", "{896D1461-B76B-41C0-ABE6-ACA2BB4F7B5A}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug Release = Release EndGlobalSection GlobalSection(ProjectConfiguration) = postSolution {896D1461-B76B-41C0-ABE6-ACA2BB4F7B5A}.Debug.ActiveCfg = Debug|.NET {896D1461-B76B-41C0-ABE6-ACA2BB4F7B5A}.Debug.Build.0 = Debug|.NET {896D1461-B76B-41C0-ABE6-ACA2BB4F7B5A}.Release.ActiveCfg = Release|.NET {896D1461-B76B-41C0-ABE6-ACA2BB4F7B5A}.Release.Build.0 = Release|.NET EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection GlobalSection(ExtensibilityAddIns) = postSolution EndGlobalSection EndGlobal --- NEW FILE: const.cs --- // // const.cs: Constant declarations. // // Author: // Miguel de Icaza (mi...@xi...) // // (C) 2001 Ximian, Inc. // // // // This is needed because the following situation arises: // // The FieldBuilder is declared with the real type for an enumeration // // When we attempt to set the value for the constant, the FieldBuilder.SetConstant // function aborts because it requires its argument to be of the same type // namespace Mono.CSharp { using System; using System.Reflection; using System.Reflection.Emit; using System.Collections; public class Const : FieldMember { public Expression Expr; EmitContext const_ec; bool resolved = false; object ConstantValue = null; bool in_transit = false; public const int AllowedModifiers = Modifiers.NEW | Modifiers.PUBLIC | Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE; public Const (TypeContainer parent, Expression constant_type, string name, Expression expr, int mod_flags, Attributes attrs, Location loc) : base (parent, constant_type, mod_flags, AllowedModifiers, new MemberName (name), null, attrs, loc) { Expr = expr; ModFlags |= Modifiers.STATIC; } public FieldAttributes FieldAttr { get { return FieldAttributes.Literal | FieldAttributes.Static | Modifiers.FieldAttr (ModFlags) ; } } #if DEBUG void dump_tree (Type t) { Console.WriteLine ("Dumping hierarchy"); while (t != null){ Console.WriteLine (" " + t.FullName + " " + (t.GetType ().IsEnum ? "yes" : "no")); t = t.BaseType; } } #endif /// <summary> /// Defines the constant in the @parent /// </summary> public override bool Define () { if (!base.Define ()) return false; const_ec = new EmitContext (Parent, Location, null, MemberType, ModFlags); Type ttype = MemberType; while (ttype.IsArray) ttype = TypeManager.GetElementType (ttype); if (!TypeManager.IsBuiltinType (ttype) && (!ttype.IsSubclassOf (TypeManager.enum_type)) && !(Expr is NullLiteral)) { Report.Error ( -3, Location, "Constant type is not valid (only system types are allowed)"); return false; } FieldBuilder = Parent.TypeBuilder.DefineField (Name, MemberType, FieldAttr); TypeManager.RegisterConstant (FieldBuilder, this); return true; } // // Changes the type of the constant expression `expr' to the Type `type' // Returns null on failure. // public static Constant ChangeType (Location loc, Constant expr, Type type) { if (type == TypeManager.object_type) return expr; bool fail; // from the null type to any reference-type. if (expr is NullLiteral && !type.IsValueType && !TypeManager.IsEnumType (type)) return NullLiteral.Null; if (!Convert.ImplicitStandardConversionExists (Convert.ConstantEC, expr, type)){ Convert.Error_CannotImplicitConversion (loc, expr.Type, type); return null; } object constant_value = TypeManager.ChangeType (expr.GetValue (), type, out fail); if (fail){ Convert.Error_CannotImplicitConversion (loc, expr.Type, type); // // We should always catch the error before this is ever // reached, by calling Convert.ImplicitStandardConversionExists // throw new Exception ( String.Format ("LookupConstantValue: This should never be reached {0} {1}", expr.Type, type)); } Constant retval; if (type == TypeManager.int32_type) retval = new IntConstant ((int) constant_value); else if (type == TypeManager.uint32_type) retval = new UIntConstant ((uint) constant_value); else if (type == TypeManager.int64_type) retval = new LongConstant ((long) constant_value); else if (type == TypeManager.uint64_type) retval = new ULongConstant ((ulong) constant_value); else if (type == TypeManager.float_type) retval = new FloatConstant ((float) constant_value); else if (type == TypeManager.double_type) retval = new DoubleConstant ((double) constant_value); else if (type == TypeManager.string_type) retval = new StringConstant ((string) constant_value); else if (type == TypeManager.short_type) retval = new ShortConstant ((short) constant_value); else if (type == TypeManager.ushort_type) retval = new UShortConstant ((ushort) constant_value); else if (type == TypeManager.sbyte_type) retval = new SByteConstant ((sbyte) constant_value); else if (type == TypeManager.byte_type) retval = new ByteConstant ((byte) constant_value); else if (type == TypeManager.char_type) retval = new CharConstant ((char) constant_value); else if (type == TypeManager.bool_type) retval = new BoolConstant ((bool) constant_value); else throw new Exception ("LookupConstantValue: Unhandled constant type: " + type); return retval; } /// <summary> /// Looks up the value of a constant field. Defines it if it hasn't /// already been. Similar to LookupEnumValue in spirit. /// </summary> public bool LookupConstantValue (out object value) { if (resolved) { value = ConstantValue; return true; } if (in_transit) { Report.Error (110, Location, "The evaluation of the constant value for `" + Name + "' involves a circular definition."); value = null; return false; } in_transit = true; int errors = Report.Errors; // // We might have cleared Expr ourselves in a recursive definition // if (Expr == null){ value = null; return false; } Expr = Expr.Resolve (const_ec); in_transit = false; if (Expr == null) { if (errors == Report.Errors) Report.Error (150, Location, "A constant value is expected"); value = null; return false; } Expression real_expr = Expr; Constant ce = Expr as Constant; if (ce == null){ UnCheckedExpr un_expr = Expr as UnCheckedExpr; CheckedExpr ch_expr = Expr as CheckedExpr; EmptyCast ec_expr = Expr as EmptyCast; if ((un_expr != null) && (un_expr.Expr is Constant)) Expr = un_expr.Expr; else if ((ch_expr != null) && (ch_expr.Expr is Constant)) Expr = ch_expr.Expr; else if ((ec_expr != null) && (ec_expr.Child is Constant)) Expr = ec_expr.Child; else if (Expr is ArrayCreation){ Report.Error (133, Location, "Arrays can not be constant"); } else { if (errors == Report.Errors) Report.Error (150, Location, "A constant value is expected"); value = null; return false; } ce = Expr as Constant; } if (MemberType != real_expr.Type) { ce = ChangeType (Location, ce, MemberType); if (ce == null){ value = null; return false; } Expr = ce; } ConstantValue = ce.GetValue (); if (MemberType.IsEnum){ // // This sadly does not work for our user-defined enumerations types ;-( // try { ConstantValue = System.Enum.ToObject ( MemberType, ConstantValue); } catch (ArgumentException){ Report.Error ( -16, Location, ".NET SDK 1.0 does not permit to create the constant "+ " field from a user-defined enumeration"); } } FieldBuilder.SetConstant (ConstantValue); if (!TypeManager.RegisterFieldValue (FieldBuilder, ConstantValue)) throw new Exception ("Cannot register const value"); value = ConstantValue; resolved = true; return true; } /// <summary> /// Emits the field value by evaluating the expression /// </summary> public override void Emit () { object value; LookupConstantValue (out value); if (OptAttributes != null) { OptAttributes.Emit (const_ec, this); } base.Emit (); } } } --- NEW FILE: constant.cs --- // // constant.cs: Constants. // // Author: // Miguel de Icaza (mi...@xi...) // // (C) 2001 Ximian, Inc. // // namespace Mono.CSharp { using System; using System.Reflection.Emit; /// <summary> /// Base class for constants and literals. /// </summary> public abstract class Constant : Expression { [...1074 lines suppressed...] } public override void Emit (EmitContext ec) { if (Value == null) ec.ig.Emit (OpCodes.Ldnull); else ec.ig.Emit (OpCodes.Ldstr, Value); } public override bool IsNegative { get { return false; } } } } --- NEW FILE: convert.cs --- // // conversion.cs: various routines for implementing conversions. // // Authors: // Miguel de Icaza (mi...@xi...) // Ravi Pratap (ra...@xi...) // // (C) 2001, 2002, 2003 Ximian, Inc. // namespace Mono.CSharp { using System; using System.Collections; using System.Diagnostics; using System.Reflection; using System.Reflection.Emit; // // A container class for all the conversion operations [...1789 lines suppressed...] Type target_type, Location l) { Expression ne = ImplicitConversionStandard (ec, expr, target_type, l); if (ne != null) return ne; ne = ExplicitNumericConversion (ec, expr, target_type, l); if (ne != null) return ne; ne = ExplicitReferenceConversion (expr, target_type); if (ne != null) return ne; Error_CannotConvertType (l, expr.Type, target_type); return null; } } } --- NEW FILE: cs-parser.jay --- %{ // // cs-parser.jay: The Parser for the C# compiler // // Authors: Miguel de Icaza (mi...@gn...) // Ravi Pratap (ra...@xi...) // // Licensed under the terms of the GNU GPL // // (C) 2001 Ximian, Inc (http://www.ximian.com) // // TODO: // (1) Figure out why error productions dont work. `type-declaration' is a // great spot to put an `error' because you can reproduce it with this input: // "public X { }" // // Possible optimization: // Run memory profiler with parsing only, and consider dropping // arraylists where not needed. Some pieces can use linked lists. [...4406 lines suppressed...] Console.WriteLine (e); } } void CheckToken (int error, int yyToken, string msg) { if (yyToken >= Token.FIRST_KEYWORD && yyToken <= Token.LAST_KEYWORD){ Report.Error (error, lexer.Location, String.Format ("{0}: `{1}' is a keyword", msg, yyNames [yyToken].ToLower ())); return; } Report.Error (error, lexer.Location, msg); } void CheckIdentifierToken (int yyToken) { CheckToken (1041, yyToken, "Identifier expected"); } /* end end end */ } --- NEW FILE: cs-tokenizer.cs --- // // cs-tokenizer.cs: The Tokenizer for the C# compiler // This also implements the preprocessor // // Author: Miguel de Icaza (mi...@gn...) // // Licensed under the terms of the GNU GPL // // (C) 2001, 2002 Ximian, Inc (http://www.ximian.com) // /* * TODO: * Make sure we accept the proper Unicode ranges, per the spec. * Report error 1032 */ using System; using System.Text; [...2013 lines suppressed...] return Token.ERROR; } return Token.EOF; } public void cleanup () { if (ifstack != null && ifstack.Count >= 1) { int state = (int) ifstack.Pop (); if ((state & REGION) != 0) Report.Error (1038, "#endregion directive expected"); else Report.Error (1027, "#endif directive expected"); } } } } --- NEW FILE: decl.cs --- // // decl.cs: Declaration base class for structs, classes, enums and interfaces. // // Author: Miguel de Icaza (mi...@gn...) // Marek Safar (mar...@se...) // // Licensed under the terms of the GNU GPL // // (C) 2001 Ximian, Inc (http://www.ximian.com) // // TODO: Move the method verification stuff from the class.cs and interface.cs here // using System; using System.Collections; using System.Globalization; using System.Reflection.Emit; using System.Reflection; [...1958 lines suppressed...] if ((entry.EntryType & tested_type) != tested_type) continue; MethodBase method_to_compare = (MethodBase)entry.Member; if (AttributeTester.AreOverloadedMethodParamsClsCompliant (method.ParameterTypes, TypeManager.GetArgumentTypes (method_to_compare))) continue; IMethodData md = TypeManager.GetMethod (method_to_compare); // TODO: now we are ignoring CLSCompliance(false) on method from other assembly which is buggy. // However it is exactly what csc does. if (md != null && !md.IsClsCompliaceRequired (method.Parent)) continue; Report.SymbolRelatedToPreviousError (entry.Member); Report.Error (3006, method.Location, "Overloaded method '{0}' differing only in ref or out, or in array rank, is not CLS-compliant", method.GetSignatureForError ()); } } } } --- NEW FILE: delegate.cs --- // // delegate.cs: Delegate Handler // // Authors: // Ravi Pratap (ra...@xi...) // Miguel de Icaza (mi...@xi...) // // Licensed under the terms of the GNU GPL // // (C) 2001 Ximian, Inc (http://www.ximian.com) // // using System; using System.Collections; using System.Reflection; using System.Reflection.Emit; using System.Text; namespace Mono.CSharp { /// <summary> /// Holds Delegates /// </summary> public class Delegate : DeclSpace { public Expression ReturnType; public Parameters Parameters; public ConstructorBuilder ConstructorBuilder; public MethodBuilder InvokeBuilder; public MethodBuilder BeginInvokeBuilder; public MethodBuilder EndInvokeBuilder; Type [] param_types; Type ret_type; static string[] attribute_targets = new string [] { "type", "return" }; Expression instance_expr; MethodBase delegate_method; ReturnParameter return_attributes; const int AllowedModifiers = Modifiers.NEW | Modifiers.PUBLIC | Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.UNSAFE | Modifiers.PRIVATE; public Delegate (NamespaceEntry ns, TypeContainer parent, Expression type, int mod_flags, MemberName name, Parameters param_list, Attributes attrs, Location l) : base (ns, parent, name, attrs, l) { this.ReturnType = type; ModFlags = Modifiers.Check (AllowedModifiers, mod_flags, IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE, l); Parameters = param_list; } public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb) { if (a.Target == AttributeTargets.ReturnValue) { if (return_attributes == null) return_attributes = new ReturnParameter (InvokeBuilder, Location); return_attributes.ApplyAttributeBuilder (a, cb); return; } base.ApplyAttributeBuilder (a, cb); } public override TypeBuilder DefineType () { if (TypeBuilder != null) return TypeBuilder; TypeAttributes attr = Modifiers.TypeAttr (ModFlags, IsTopLevel) | TypeAttributes.Class | TypeAttributes.Sealed; if (IsTopLevel) { if (TypeManager.NamespaceClash (Name, Location)) return null; ModuleBuilder builder = CodeGen.Module.Builder; TypeBuilder = builder.DefineType ( Name, attr, TypeManager.multicast_delegate_type); } else { TypeBuilder builder = Parent.TypeBuilder; string name = Name.Substring (1 + Name.LastIndexOf ('.')); TypeBuilder = builder.DefineNestedType ( name, attr, TypeManager.multicas... [truncated message content] |
From: <mas...@us...> - 2004-10-29 14:11:12
|
Update of /cvsroot/csdoc/csdoc/src/mcsdoc/class/Mono.CSharp.Debugger In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22498/Mono.CSharp.Debugger Log Message: Directory /cvsroot/csdoc/csdoc/src/mcsdoc/class/Mono.CSharp.Debugger added to the repository |
From: <mas...@us...> - 2004-10-29 14:10:52
|
Update of /cvsroot/csdoc/csdoc/src/mcsdoc/class/corlib/Mono.Security.Cryptography In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22431/Mono.Security.Cryptography Log Message: Directory /cvsroot/csdoc/csdoc/src/mcsdoc/class/corlib/Mono.Security.Cryptography added to the repository |
From: <mas...@us...> - 2004-10-29 14:10:36
|
Update of /cvsroot/csdoc/csdoc/src/mcsdoc/class/corlib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22227/corlib Log Message: Directory /cvsroot/csdoc/csdoc/src/mcsdoc/class/corlib added to the repository |
From: <mas...@us...> - 2004-10-29 14:04:44
|
Update of /cvsroot/csdoc/csdoc/src/mcsdoc/mcs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20737/mcs Log Message: Directory /cvsroot/csdoc/csdoc/src/mcsdoc/mcs added to the repository |
From: <mas...@us...> - 2004-10-29 14:04:43
|
Update of /cvsroot/csdoc/csdoc/src/mcsdoc/jay In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20737/jay Log Message: Directory /cvsroot/csdoc/csdoc/src/mcsdoc/jay added to the repository |
From: <mas...@us...> - 2004-10-29 14:04:43
|
Update of /cvsroot/csdoc/csdoc/src/mcsdoc/class In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20737/class Log Message: Directory /cvsroot/csdoc/csdoc/src/mcsdoc/class added to the repository |
From: <mas...@us...> - 2004-10-29 14:04:25
|
Update of /cvsroot/csdoc/csdoc/src/mcsdoc/build In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20616/build Log Message: Directory /cvsroot/csdoc/csdoc/src/mcsdoc/build added to the repository |
From: <mas...@us...> - 2004-10-29 13:58:08
|
Update of /cvsroot/csdoc/csdoc/src/mcs/build In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19178 Modified Files: config-default.make executable.make Log Message: Index: config-default.make =================================================================== RCS file: /cvsroot/csdoc/csdoc/src/mcs/build/config-default.make,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** config-default.make 6 Oct 2004 19:31:14 -0000 1.1 --- config-default.make 29 Oct 2004 13:57:58 -0000 1.2 *************** *** 16,20 **** prefix = /usr/local RUNTIME = mono $(RUNTIME_FLAGS) ! TEST_RUNTIME = MONO_PATH="$(topdir)/class/lib/$(PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(RUNTIME) --debug # In case you want to add MCS_FLAGS, this lets you not have to --- 16,20 ---- prefix = /usr/local RUNTIME = mono $(RUNTIME_FLAGS) ! TEST_RUNTIME = MONO_PATH="$(topdir)/class/lib/$(PROFILE)$(PLATFORM_PATH_SEPARATOR)$(TEST_MONO_PATH)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(RUNTIME) --debug # In case you want to add MCS_FLAGS, this lets you not have to Index: executable.make =================================================================== RCS file: /cvsroot/csdoc/csdoc/src/mcs/build/executable.make,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** executable.make 6 Oct 2004 19:31:14 -0000 1.1 --- executable.make 29 Oct 2004 13:57:58 -0000 1.2 *************** *** 59,63 **** ifndef PROGRAM_COMPILE - echo CSCOMPILE = $(CSCOMPILE) PROGRAM_COMPILE = $(CSCOMPILE) endif --- 59,62 ---- |
Update of /cvsroot/csdoc/csdoc/src/mcs/mcs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18346 Modified Files: ChangeLog TODO anonymous.cs assign.cs attribute.cs class.cs codegen.cs const.cs convert.cs cs-parser.jay decl.cs delegate.cs ecore.cs enum.cs expression.cs iterators.cs mcs.exe.config parameter.cs parser.cs report.cs rootcontext.cs statement.cs support.cs typemanager.cs Log Message: 2004-10-28 Gaurav Vaish * **/* :: Latest from mono/mcs Index: ChangeLog =================================================================== RCS file: /cvsroot/csdoc/csdoc/src/mcs/mcs/ChangeLog,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** ChangeLog 6 Oct 2004 19:28:29 -0000 1.1 --- ChangeLog 29 Oct 2004 13:54:36 -0000 1.2 *************** *** 1,2 **** --- 1,467 ---- + 2004-10-27 Miguel de Icaza <mi...@xi...> + + * expression.cs (LocalVariableReference.DoResolveLValue): Check + for obsolete use of a variable here. Fixes regression on errors + cs0619-25 and cs0619-26. + + 2004-10-27 Marek Safar <mar...@se...> + + Fix #62358, implemented security attribute encoding. + + * attribute.cs (Attribute.CheckSecurityActionValididy): New method. + Tests permitted SecurityAction for assembly or other types. + (Assembly.ExtractSecurityPermissionSet): New method. Transforms + data from SecurityPermissionAttribute to PermisionSet class. + + * class.cs (ApplyAttributeBuilder): Added special handling + for System.Security.Permissions.SecurityAttribute based types. + + * codegen.cs (AssemblyClass.ApplyAttributeBuilder): Added + special handling for System.Security.Permissions.SecurityAttribute + based types. + + * enum.cs (ApplyAttributeBuilder): Added special handling + for System.Security.Permissions.SecurityAttribute based types. + + * parameter.cs (ApplyAttributeBuilder): Added special handling + for System.Security.Permissions.SecurityAttribute based types. + + * rootcontext.cs: Next 2 core types. + + * typemanager.cs (TypeManager.security_permission_attr_type): + Built in type for the SecurityPermission Attribute. + (code_access_permission_type): Build in type. + + 2004-10-17 Miguel de Icaza <mi...@xi...> + + * expression.cs (LocalVariableReference.DoResolveBase, Emit): + Remove the tests for `ec.RemapToProxy' from here, and encapsulate + all of this information into + EmitContext.EmitCapturedVariableInstance. + + * codegen.cs (EmitCapturedVariableInstance): move here the + funcionality of emitting an ldarg.0 in the presence of a + remapping. This centralizes the instance emit code. + + (EmitContext.EmitThis): If the ScopeInfo contains a THIS field, + then emit a load of this: it means that we have reached the + topmost ScopeInfo: the one that contains the pointer to the + instance of the class hosting the anonymous method. + + * anonymous.cs (AddField, HaveCapturedFields): Propagate field + captures to the topmost CaptureContext. + + 2004-10-12 Miguel de Icaza <mi...@xi...> + + * expression.cs (LocalVariableReference): Move the knowledge about + the iterators into codegen's EmitCapturedVariableInstance. + + 2004-10-11 Miguel de Icaza <mi...@xi...> + + * codegen.cs (EmitContext.ResolveTopBlock): Emit a 1643 when not + all code paths return a value from an anonymous method (it is the + same as the 161 error, but for anonymous methods). + + 2004-10-08 Miguel de Icaza <mi...@xi...> + + The introduction of anonymous methods in the compiler changed + various ways of doing things in the compiler. The most + significant one is the hard split between the resolution phase + and the emission phases of the compiler. + + For instance, routines that referenced local variables no + longer can safely create temporary variables during the + resolution phase: they must do so from the emission phase, + since the variable might have been "captured", hence access to + it can not be done with the local-variable operations from the runtime. + + * statement.cs + + (Block.Flags): New flag `IsTopLevel' to indicate that this block + is a toplevel block. + + (ToplevelBlock): A new kind of Block, these are the blocks that + are created by the parser for all toplevel method bodies. These + include methods, accessors and anonymous methods. + + These contain some extra information not found in regular blocks: + A pointer to an optional CaptureContext (for tracking captured + local variables and parameters). A pointer to the parent + ToplevelBlock. + + (Return.Resolve): Catch missmatches when returning a value from an + anonymous method (error 1662). + Invoke NeedReturnLabel from the Resolve phase instead of the emit + phase. + + (Break.Resolve): ditto. + + (SwitchLabel): instead of defining the labels during the + resolution phase, we now turned the public ILLabel and ILLabelCode + labels into methods called GetILLabelCode() and GetILLabel() that + only define the label during the Emit phase. + + (GotoCase): Track the SwitchLabel instead of the computed label + (its contained therein). Emit the code by using + SwitchLabel.GetILLabelCode (). + + (LocalInfo.Flags.Captured): A new flag has been introduce to track + whether the Local has been captured or not. + + (LocalInfo.IsCaptured): New property, used to tell whether the + local has been captured. + + * anonymous.cs: Vastly updated to contain the anonymous method + support. + + The main classes here are: CaptureContext which tracks any + captured information for a toplevel block and ScopeInfo used to + track the activation frames for various local variables. + + Each toplevel block has an optional capture context associated + with it. When a method contains an anonymous method both the + toplevel method and the anonymous method will create a capture + context. When variables or parameters are captured, they are + recorded on the CaptureContext that owns them, for example: + + void Demo () { + int a; + MyDelegate d = delegate { + a = 1; + } + } + + Here `a' will be recorded as captured on the toplevel + CapturedContext, the inner captured context will not have anything + (it will only have data if local variables or parameters from it + are captured in a nested anonymous method. + + The ScopeInfo is used to track the activation frames for local + variables, for example: + + for (int i = 0; i < 10; i++) + for (int j = 0; j < 10; j++){ + MyDelegate d = delegate { + call (i, j); + } + } + + At runtime this captures a single captured variable `i', but it + captures 10 different versions of the variable `j'. The variable + `i' will be recorded on the toplevel ScopeInfo, while `j' will be + recorded on a child. + + The toplevel ScopeInfo will also track information like the `this' + pointer if instance variables were referenced (this is necessary + as the anonymous method lives inside a nested class in the host + type of the method). + + (AnonymousMethod): Expanded to track the Toplevel, implement + `AnonymousMethod.Compatible' to tell whether an anonymous method + can be converted to a target delegate type. + + The routine now also produces the anonymous method content + + (AnonymousDelegate): A helper class that derives from + DelegateCreation, this is used to generate the code necessary to + produce the delegate for the anonymous method that was created. + + * assign.cs: API adjustments for new changes in + Convert.ImplicitStandardConversionExists. + + * class.cs: Adjustments to cope with the fact that now toplevel + blocks are of type `ToplevelBlock'. + + * cs-parser.jay: Now we produce ToplevelBlocks for toplevel blocks + insteda of standard blocks. + + Flag errors if params arguments are passed to anonymous methods. + + * codegen.cs (EmitContext): Replace `InAnonymousMethod' with + `CurrentAnonymousMethod' which points to the current Anonymous + Method. The variable points to the AnonymousMethod class that + holds the code being compiled. It is set in the new EmitContext + created for the anonymous method. + + (EmitContext.Phase): Introduce a variable and an enumeration to + assist in enforcing some rules about when and where we are allowed + to invoke certain methods (EmitContext.NeedsReturnLabel is the + only one that enfonces this right now). + + (EmitContext.HaveCaptureInfo): new helper method that returns + whether we have a CapturedContext initialized. + + (EmitContext.CaptureVariable): New method used to register that a + LocalInfo must be flagged for capturing. + + (EmitContext.CapturedParameter): New method used to register that a + parameters must be flagged for capturing. + + (EmitContext.CapturedField): New method used to register that a + field must be flagged for capturing. + + (EmitContext.HaveCapturedVariables, + EmitContext.HaveCapturedFields): Return whether there are captured + variables or fields. + + (EmitContext.EmitMethodHostInstance): This is used to emit the + instance for the anonymous method. The instance might be null + (static methods), this (for anonymous methods that capture nothing + and happen to live side-by-side with the current method body) or a + more complicated expression if the method has a CaptureContext. + + (EmitContext.EmitTopBlock): Routine that drives the emission of + code: it will first resolve the top block, then emit any metadata + and then emit the code. The split is done so that we can extract + any anonymous methods and flag any captured variables/parameters. + + (EmitContext.ResolveTopBlock): Triggers the resolution phase, + during this phase, the ILGenerator should not be used as labels + and local variables declared here might not be accessible to any + code that is part of an anonymous method. + + Exceptions to this include the temporary variables that are + created by some statements internally for holding temporary + variables. + + (EmitContext.EmitMeta): New routine, in charge of emitting all the + metadata for a cb + + (EmitContext.TemporaryReturn): This method is typically called + from the Emit phase, and its the only place where we allow the + ReturnLabel to be defined other than the EmitMeta. The reason is + that otherwise we would have to duplicate a lot of logic in the + Resolve phases of various methods that today is on the Emit + phase. + + (EmitContext.NeedReturnLabel): This no longer creates the label, + as the ILGenerator is not valid during the resolve phase. + + (EmitContext.EmitThis): Extended the knowledge in this class to + work in anonymous methods in addition to iterators. + + (EmitContext.EmitCapturedVariableInstance): This emits whatever + code is necessary on the stack to access the instance to a local + variable (the variable will be accessed as a field). + + (EmitContext.EmitParameter, EmitContext.EmitAssignParameter, + EmitContext.EmitAddressOfParameter): Routines to support + parameters (not completed at this point). + + Removals: Removed RemapLocal and RemapLocalLValue. We probably + will also remove the parameters. + + * convert.cs (Convert): Define a `ConstantEC' which points to a + null. This is just to prefity some code that uses + ImplicitStandardConversion code and do not have an EmitContext + handy. + + The idea is to flag explicitly that at that point in time, it is + known that the conversion will not trigger the delegate checking + code in implicit conversions (which requires a valid + EmitContext). + + Everywhere: pass new EmitContext parameter since + ImplicitStandardConversionExists now requires it to check for + anonymous method conversions. + + (Convert.ImplicitStandardConversionExists): If the type of an + expression is the anonymous_method_type, and the type is a + delegate, we invoke the AnonymousMethod.Compatible method to check + whether an implicit conversion is possible. + + (Convert.ImplicitConversionStandard): Only do implicit method + group conversions if the language level is not ISO_1. + + * delegate.cs (Delegate.GetInvokeMethod): Common method to get the + MethodInfo for the Invoke method. used by Delegate and + AnonymousDelegate. + + * expression.cs (Binary.DoNumericPromotions): only allow anonymous + method conversions if the target type is a delegate. + + Removed extra debugging nops. + + (LocalVariableReference): Turn the `local_info' into a public + field. + + Add `prepared' field, the same hack used for FieldExprs to cope + with composed assignments, as Local variables do not necessarily + operate purely on the stack as they used to: they can be captured + fields. + + Add `temp' for a temporary result, like fields. + + Refactor DoResolve and DoResolveLValue into DoResolveBase. + + It now copes with Local variables that are captured and emits the + proper instance variable to load it from a field in the captured + case. + + (ParameterReference.DoResolveBase): During the resolve phase, + capture parameters if we are in an anonymous method. + + (ParameterReference.Emit, ParameterReference.AddressOf): If in an + anonymous method, use the EmitContext helper routines to emit the + parameter reference. + + * iterators.cs: Set RemapToProxy to true/false during the + EmitDispose class. + + * parameters.cs (GetParameterByName): New helper method. + + * typemanager.cs (anonymous_method_type) a new type that + represents an anonyous method. This is always an internal type, + used as a fencepost to test against the anonymous-methodness of an + expression. + + 2004-10-24 Marek Safar <mar...@se...> + + Fixed bugs #63705, #67130 + * decl.cs (MemberCache.MemberCache): Add parameter to distinguish + imported and defined interfaces. + (CacheEntry, EntryType): Changed to protected internal. + + * class.cs (TypeContainer.DoDefineMembers): Setup cache for + interfaces too. + + * typemanager.cs (LookupInterfaceContainer): New method. + Fills member container from base interfaces. + + 2004-10-20 Marek Safar <mar...@se...> + + * class.cs (MethodCore.CheckBase): Add errors 505, 533, 544, + 561 report. + (PropertyBase.FindOutParentMethod): Add errors 545, 546 report. + + 2004-10-18 Martin Baulig <ma...@xi...> + + Merged latest changes into gmcs. Please keep this comment in + here, it makes it easier for me to see what changed in MCS since + the last time I merged. + + 2004-10-18 Martin Baulig <ma...@xi...> + + * statement.cs (Fixed.Resolve): Don't access the TypeExpr's + `Type' directly, but call ResolveType() on it. + (Catch.Resolve): Likewise. + (Foreach.Resolve): Likewise. + + 2004-10-18 Martin Baulig <ma...@xi...> + + * expression.cs (Cast.DoResolve): Don't access the TypeExpr's + `Type' directly, but call ResolveType() on it. + (Probe.DoResolve): Likewise. + (ArrayCreation.LookupType): Likewise. + (TypeOf.DoResolve): Likewise. + (SizeOf.DoResolve): Likewise. + + 2004-10-18 Martin Baulig <ma...@xi...> + + * expression.cs (Invocation.BetterFunction): Put back + TypeManager.TypeToCoreType(). + + 2004-10-18 Raja R Harinath <rha...@no...> + + * class.cs (FieldMember.DoDefine): Reset ec.InUnsafe after doing + the ResolveType. + + 2004-10-18 Martin Baulig <ma...@xi...> + + * parameter.cs (Parameter.Resolve): Don't access the TypeExpr's + `Type' directly, but call ResolveType() on it. + + 2004-10-18 Martin Baulig <ma...@xi...> + + * class.cs (FieldMember.Define): Don't access the TypeExpr's + `Type' directly, but call ResolveType() on it. + (MemberBase.DoDefine): Likewise. + + * expression.cs (New.DoResolve): Don't access the TypeExpr's + `Type' directly, but call ResolveType() on it. + (ComposedCast.DoResolveAsTypeStep): Likewise. + + * statement.cs (LocalInfo.Resolve): Don't access the TypeExpr's + `Type' directly, but call ResolveType() on it. + + 2004-10-17 John Luke <joh...@gm...> + + * class.cs (Operator.GetSignatureForError): use CSharpName + + * parameter.cs (Parameter.GetSignatureForError): Returns + correct name even if was not defined. + + 2004-10-13 Raja R Harinath <rha...@no...> + + Fix #65816. + * class.cs (TypeContainer.EmitContext): New property. + (DefineNestedTypes): Create an emitcontext for each part. + (MethodCore.DoDefineParameters): Use container's emitcontext. + Pass type array to InternalParameters. + (MemberBase.DoDefine): Use container's emitcontext. + (FieldMember.Define): Likewise. + (Event.Define): Likewise. + (SetMethod.GetParameterInfo): Change argument to EmitContext. + Pass type array to InternalParameters. + (SetIndexerMethod.GetParameterInfo): Likewise. + (SetMethod.Define): Pass emitcontext to GetParameterInfo. + * delegate.cs (Define): Pass emitcontext to + ComputeAndDefineParameterTypes and GetParameterInfo. Pass type + array to InternalParameters. + * expression.cs (ParameterReference.DoResolveBase): Pass + emitcontext to GetParameterInfo. + (ComposedCast.DoResolveAsTypeStep): Remove check on + ec.ResolvingTypeTree. + * parameter.cs (Parameter.Resolve): Change argument to + EmitContext. Use ResolveAsTypeTerminal. + (Parameter.GetSignature): Change argument to EmitContext. + (Parameters.ComputeSignature): Likewise. + (Parameters.ComputeParameterTypes): Likewise. + (Parameters.GetParameterInfo): Likewise. + (Parameters.ComputeAndDefineParameterTypes): Likewise. + Re-use ComputeParameterTypes. Set ec.ResolvingTypeTree. + * support.cs (InternalParameters..ctor): Remove variant that takes + a DeclSpace. + * typemanager.cs (system_intptr_expr): New. + (InitExpressionTypes): Initialize it. + + 2004-10-12 Chris Toshok <to...@xi...> + + * cs-parser.jay: fix location for try_statement and catch_clause. + + 2004-10-11 Martin Baulig <ma...@xi...> + + * report.cs: Don't make --fatal abort on warnings, we have + -warnaserror for that. + + 2004-10-07 Raja R Harinath <rha...@no...> + + More DeclSpace.ResolveType avoidance. + * decl.cs (MemberCore.InUnsafe): New property. + * class.cs (MemberBase.DoDefine): Use ResolveAsTypeTerminal + with newly created EmitContext. + (FieldMember.Define): Likewise. + * delegate.cs (Delegate.Define): Likewise. + * ecore.cs (SimpleName.ResolveAsTypeStep): Lookup with alias + only if normal name-lookup fails. + (TypeExpr.DoResolve): Enable error-checking. + * expression.cs (ArrayCreation.DoResolve): Use ResolveAsTypeTerminal. + (SizeOf.DoResolve): Likewise. + (ComposedCast.DoResolveAsTypeStep): Likewise. + (StackAlloc.DoResolve): Likewise. + * statement.cs (Block.Flags): Add new flag 'Unsafe'. + (Block.Unsafe): New property. + (Block.EmitMeta): Set ec.InUnsafe as appropriate. + (Unsafe): Set 'unsafe' flag of contained block. + (LocalInfo.Resolve): Use ResolveAsTypeTerminal. + (Fixed.Resolve): Likewise. + (Catch.Resolve): Likewise. + (Using.ResolveLocalVariableDecls): Likewise. + (Foreach.Resolve): Likewise. + + 2004-10-05 John Luke <joh...@gm...> + + * cs-parser.jay: add location to error CS0175 + 2004-10-04 Miguel de Icaza <mi...@xi...> *************** *** 86,95 **** (Convert.ImplicitReferenceConversionExists): Likewise. - 2004-09-23 Martin Baulig <ma...@xi...> - - Merged latest changes into gmcs. Please keep this comment in - here, it makes it easier for me to see what changed in MCS since - the last time I merged. - 2004-09-23 Marek Safar <mar...@se...> --- 551,554 ---- Index: TODO =================================================================== RCS file: /cvsroot/csdoc/csdoc/src/mcs/mcs/TODO,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** TODO 6 Oct 2004 19:28:29 -0000 1.1 --- TODO 29 Oct 2004 13:54:36 -0000 1.2 *************** *** 1,2 **** --- 1,3 ---- + NEW NOTES: ---------- *************** *** 46,50 **** Iterators --------- - * Reset should throw not implemented now. --- 47,50 ---- Index: anonymous.cs =================================================================== RCS file: /cvsroot/csdoc/csdoc/src/mcs/mcs/anonymous.cs,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** anonymous.cs 6 Oct 2004 19:28:29 -0000 1.1 --- anonymous.cs 29 Oct 2004 13:54:36 -0000 1.2 *************** *** 5,12 **** // Miguel de Icaza (mi...@xi...) // ! // (C) 2003 Ximian, Inc. // using System; using System.Collections; using System.Reflection; --- 5,18 ---- // Miguel de Icaza (mi...@xi...) [...1140 lines suppressed...] + if (scopes [b.ID] != null){ + LinkScope (scope, b.ID); + break; + } + } + + if (scope.ParentScope == null && ParentCaptureContext != null){ + CaptureContext pcc = ParentCaptureContext; + + for (Block b = Host.ContainingBlock; b != null; b = b.Parent){ + if (pcc.scopes [b.ID] != null){ + pcc.LinkScope (scope, b.ID); + break; + } + } + } + } + } } } Index: assign.cs =================================================================== RCS file: /cvsroot/csdoc/csdoc/src/mcs/mcs/assign.cs,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** assign.cs 6 Oct 2004 19:28:29 -0000 1.1 --- assign.cs 29 Oct 2004 13:54:36 -0000 1.2 *************** *** 361,364 **** --- 361,365 ---- eclass = ExprClass.Value; + if (target is EventExpr) { EventInfo ei = ((EventExpr) target).EventInfo; *************** *** 443,447 **** // the type of target // ! if (Convert.ImplicitStandardConversionExists (a.original_source, target_type)) return this; --- 444,448 ---- // the type of target // ! if (Convert.ImplicitStandardConversionExists (ec, a.original_source, target_type)) return this; Index: attribute.cs =================================================================== RCS file: /cvsroot/csdoc/csdoc/src/mcs/mcs/attribute.cs,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** attribute.cs 6 Oct 2004 19:28:29 -0000 1.1 --- attribute.cs 29 Oct 2004 13:54:36 -0000 1.2 *************** *** 19,22 **** --- 19,24 ---- using System.Runtime.InteropServices; using System.Runtime.CompilerServices; + using System.Security; + using System.Security.Permissions; using System.Text; *************** *** 80,84 **** public Type Type; ! // Is non-null if type is AttributeUsageAttribute AttributeUsageAttribute usage_attribute; --- 82,86 ---- public Type Type; ! // Is non-null if type is AttributeUsageAttribute AttributeUsageAttribute usage_attribute; *************** *** 125,128 **** --- 127,144 ---- } + /// <summary> + /// This is rather hack. We report many emit attribute error with same error to be compatible with + /// csc. But because csc has to report them this way because error came from ilasm we needn't. + /// </summary> + public void Error_AttributeEmitError (string inner) + { + Report.Error (647, Location, "Error emitting '{0}' attribute because '{1}'", Name, inner); + } + + public void Error_InvalidSecurityParent () + { + Error_AttributeEmitError ("it is attached to invalid parent"); + } + void Error_AttributeConstructorMismatch () { *************** *** 710,713 **** --- 726,830 ---- } + /// <summary> + /// Tests permitted SecurityAction for assembly or other types + /// </summary> + public bool CheckSecurityActionValidity (bool for_assembly) + { + SecurityAction action = GetSecurityActionValue (); + + if ((action == SecurityAction.RequestMinimum || action == SecurityAction.RequestOptional || action == SecurityAction.RequestRefuse) && for_assembly) + return true; + + if (!for_assembly) { + if (action < SecurityAction.Demand || action > SecurityAction.InheritanceDemand) { + Error_AttributeEmitError ("SecurityAction is out of range"); + return false; + } + + if ((action != SecurityAction.RequestMinimum && action != SecurityAction.RequestOptional && action != SecurityAction.RequestRefuse) && !for_assembly) + return true; + } + + Error_AttributeEmitError (String.Concat ("SecurityAction '", action, "' is not valid for this declaration")); + return false; + } + + System.Security.Permissions.SecurityAction GetSecurityActionValue () + { + return (SecurityAction)pos_values [0]; + } + + /// <summary> + /// Creates instance of SecurityAttribute class and add result of CreatePermission method to permission table. + /// </summary> + /// <returns></returns> + public void ExtractSecurityPermissionSet (ListDictionary permissions) + { + if (TypeManager.LookupDeclSpace (Type) != null && RootContext.StdLib) { + Error_AttributeEmitError ("security custom attributes can not be referenced from defining assembly"); + return; + } + + SecurityAttribute sa; + // For all assemblies except corlib we can avoid all hacks + if (RootContext.StdLib) { + sa = (SecurityAttribute) Activator.CreateInstance (Type, pos_values); + + if (prop_info_arr != null) { + for (int i = 0; i < prop_info_arr.Length; ++i) { + PropertyInfo pi = prop_info_arr [i]; + pi.SetValue (sa, prop_values_arr [i], null); + } + } + } else { + Type temp_type = Type.GetType (Type.FullName); + // HACK: All mscorlib attributes have same ctor syntax + sa = (SecurityAttribute) Activator.CreateInstance (temp_type, new object[] { GetSecurityActionValue () } ); + + // All types are from newly created corlib but for invocation with old we need to convert them + if (prop_info_arr != null) { + for (int i = 0; i < prop_info_arr.Length; ++i) { + PropertyInfo emited_pi = prop_info_arr [i]; + PropertyInfo pi = temp_type.GetProperty (emited_pi.Name, emited_pi.PropertyType); + + object old_instance = pi.PropertyType.IsEnum ? + System.Enum.ToObject (pi.PropertyType, prop_values_arr [i]) : + prop_values_arr [i]; + + pi.SetValue (sa, old_instance, null); + } + } + } + + IPermission perm = sa.CreatePermission (); + SecurityAction action; + + if (perm.GetType().IsSubclassOf (TypeManager.code_access_permission_type)) { + action = GetSecurityActionValue (); + } else { + switch (GetSecurityActionValue ()) { + case SecurityAction.Demand: + action = (SecurityAction)13; + break; + case SecurityAction.LinkDemand: + action = (SecurityAction)14; + break; + case SecurityAction.InheritanceDemand: + action = (SecurityAction)15; + break; + default: + Error_AttributeEmitError ("Invalid SecurityAction for non-Code Access Security permission"); + return; + } + } + + PermissionSet ps = (PermissionSet)permissions [action]; + if (ps == null) { + ps = new PermissionSet (PermissionState.None); + permissions.Add (action, ps); + } + ps.AddPermission (sa.CreatePermission ()); + } + object GetValue (object value) { Index: class.cs =================================================================== RCS file: /cvsroot/csdoc/csdoc/src/mcs/mcs/class.cs,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** class.cs 6 Oct 2004 19:28:29 -0000 1.1 --- class.cs 29 Oct 2004 13:54:36 -0000 1.2 *************** *** 33,40 **** --- 33,43 ---- using System; using System.Collections; + using System.Collections.Specialized; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; + using System.Security; + using System.Security.Permissions; using System.Text; *************** *** 421,425 **** // The emit context for toplevel objects. EmitContext ec; ! // // Pointers to the default constructor and the default static constructor --- 424,432 ---- // The emit context for toplevel objects. EmitContext ec; ! ! public EmitContext EmitContext { ! get { return ec; } ! } ! // // Pointers to the default constructor and the default static constructor *************** *** 1278,1281 **** --- 1285,1289 ---- part.TypeBuilder = TypeBuilder; part.base_class_type = base_class_type; + part.ec = new EmitContext (part, Mono.CSharp.Location.Null, null, null, ModFlags); } } *************** *** 1311,1318 **** parent_container = TypeManager.LookupMemberContainer (TypeBuilder.BaseType); ! // TODO: ! //if (TypeBuilder.IsInterface) { ! // parent_container = TypeManager.LookupInterfaceContainer (base_inteface_types); ! //} if (IsTopLevel) { --- 1319,1324 ---- parent_container = TypeManager.LookupMemberContainer (TypeBuilder.BaseType); ! if (TypeBuilder.IsInterface) ! parent_container = TypeManager.LookupInterfaceContainer (base_inteface_types); if (IsTopLevel) { *************** *** 1395,1399 **** #if CACHE if (!(this is ClassPart)) ! member_cache = new MemberCache (this); #endif --- 1401,1405 ---- #if CACHE if (!(this is ClassPart)) ! member_cache = new MemberCache (this, false); #endif *************** *** 2587,2590 **** --- 2593,2597 ---- public abstract class ClassOrStruct : TypeContainer { bool hasExplicitLayout = false; + ListDictionary declarative_security; public ClassOrStruct (NamespaceEntry ns, TypeContainer parent, *************** *** 2620,2623 **** --- 2627,2638 ---- public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb) { + if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) { + if (declarative_security == null) + declarative_security = new ListDictionary (); + + a.ExtractSecurityPermissionSet (declarative_security); + return; + } + if (a.Type == TypeManager.struct_layout_attribute_type && (LayoutKind) a.GetPositionalValue (0) == LayoutKind.Explicit) *************** *** 2627,2630 **** --- 2642,2656 ---- } + public override void Emit() + { + base.Emit (); + + if (declarative_security != null) { + foreach (DictionaryEntry de in declarative_security) { + TypeBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value); + } + } + } + public override void Register () { *************** *** 2888,2892 **** public abstract class MethodCore : MemberBase { public readonly Parameters Parameters; ! protected Block block; // --- 2914,2918 ---- public abstract class MethodCore : MemberBase { public readonly Parameters Parameters; ! protected ToplevelBlock block; // *************** *** 2932,2936 **** } ! public Block Block { get { return block; --- 2958,2962 ---- } ! public ToplevelBlock Block { get { return block; *************** *** 2981,2984 **** --- 3007,3021 ---- return false; } + } else { + if (parent_method.IsAbstract && !IsInterface) { + Report.SymbolRelatedToPreviousError (parent_method); + Report.Error (533, Location, "'{0}' hides inherited abstract member", GetSignatureForError (Parent)); + return false; + } + } + + if (parent_method.IsSpecialName && !(this is PropertyBase)) { + Report.Error (561, Location, "'{0}': cannot override '{1}' because it is a special compiler-generated method", GetSignatureForError (Parent), TypeManager.GetFullNameSignature (parent_method)); + return false; } *************** *** 3001,3010 **** } if ((ModFlags & Modifiers.OVERRIDE) != 0) { ! Report.Error (115, Location, "'{0}': no suitable methods found to override", GetSignatureForError (Parent)); return false; } - MemberInfo conflict_symbol = Parent.FindMemberWithSameName (Name, !(this is Property)); if (conflict_symbol == null) { if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) { --- 3038,3054 ---- } + MemberInfo conflict_symbol = Parent.FindMemberWithSameName (Name, !(this is Property)); if ((ModFlags & Modifiers.OVERRIDE) != 0) { ! if (conflict_symbol != null) { ! Report.SymbolRelatedToPreviousError (conflict_symbol); ! if (this is PropertyBase) ! Report.Error (544, Location, "'{0}': cannot override because '{1}' is not a property", GetSignatureForError (Parent), TypeManager.GetFullNameSignature (conflict_symbol)); ! else ! Report.Error (505, Location, "'{0}': cannot override because '{1}' is not a method", GetSignatureForError (Parent), TypeManager.GetFullNameSignature (conflict_symbol)); ! } else ! Report.Error (115, Location, "'{0}': no suitable methods found to override", GetSignatureForError (Parent)); return false; } if (conflict_symbol == null) { if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) { *************** *** 3132,3136 **** if (!IsInterface && (parent_method.IsVirtual || parent_method.IsAbstract)) { if (RootContext.WarningLevel >= 2) ! Report.Warning (114, Location, "'{0}' hides inherited member '{1}'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword", GetSignatureForError (Parent), parent_method); } else Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent)); --- 3176,3180 ---- if (!IsInterface && (parent_method.IsVirtual || parent_method.IsAbstract)) { if (RootContext.WarningLevel >= 2) ! Report.Warning (114, Location, "'{0}' hides inherited member '{1}'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword", GetSignatureForError (Parent), TypeManager.CSharpSignature (parent_method)); } else Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent)); *************** *** 3169,3179 **** protected virtual bool DoDefineParameters () { // Check if arguments were correct ! parameter_types = Parameters.GetParameterInfo (Parent); if ((parameter_types == null) || !CheckParameters (Parent, parameter_types)) return false; ! parameter_info = new InternalParameters (Parent, Parameters); Parameter array_param = Parameters.ArrayParameter; --- 3213,3231 ---- protected virtual bool DoDefineParameters () { + EmitContext ec = Parent.EmitContext; + if (ec == null) + throw new InternalErrorException ("DoDefineParameters invoked too early"); + + bool old_unsafe = ec.InUnsafe; + ec.InUnsafe = InUnsafe; // Check if arguments were correct ! parameter_types = Parameters.GetParameterInfo (ec); ! ec.InUnsafe = old_unsafe; ! if ((parameter_types == null) || !CheckParameters (Parent, parameter_types)) return false; ! parameter_info = new InternalParameters (parameter_types, Parameters); Parameter array_param = Parameters.ArrayParameter; *************** *** 3337,3340 **** --- 3389,3393 ---- public MethodData MethodData; ReturnParameter return_attributes; + ListDictionary declarative_security; /// <summary> *************** *** 3463,3466 **** --- 3516,3526 ---- } + if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) { + if (declarative_security == null) + declarative_security = new ListDictionary (); + a.ExtractSecurityPermissionSet (declarative_security); + return; + } + if (a.Type == TypeManager.conditional_attribute_type) { if (IsOperator || IsExplicitImpl) { *************** *** 3614,3617 **** --- 3674,3684 ---- MethodData.Emit (Parent, this); base.Emit (); + + if (declarative_security != null) { + foreach (DictionaryEntry de in declarative_security) { + MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value); + } + } + Block = null; MethodData = null; *************** *** 3941,3944 **** --- 4008,4012 ---- public ConstructorBuilder ConstructorBuilder; public ConstructorInitializer Initializer; + ListDictionary declarative_security; // <summary> *************** *** 4006,4009 **** --- 4074,4085 ---- public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb) { + if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) { + if (declarative_security == null) { + declarative_security = new ListDictionary (); + } + a.ExtractSecurityPermissionSet (declarative_security); + return; + } + ConstructorBuilder.SetCustomAttribute (cb); } *************** *** 4195,4198 **** --- 4271,4280 ---- base.Emit (); + if (declarative_security != null) { + foreach (DictionaryEntry de in declarative_security) { + ConstructorBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value); + } + } + block = null; } *************** *** 4292,4296 **** Attributes OptAttributes { get; } ! Block Block { get; } EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig); --- 4374,4378 ---- Attributes OptAttributes { get; } ! ToplevelBlock Block { get; } EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig); *************** *** 4527,4531 **** ((MethodCore) member).Parameters.LabelParameters (ec, MethodBuilder, loc); ! Block block = method.Block; // --- 4609,4614 ---- ((MethodCore) member).Parameters.LabelParameters (ec, MethodBuilder, loc); ! SymbolWriter sw = CodeGen.SymbolWriter; ! ToplevelBlock block = method.Block; // *************** *** 4583,4587 **** } ! void EmitDestructor (EmitContext ec, Block block) { ILGenerator ig = ec.ig; --- 4666,4670 ---- } ! void EmitDestructor (EmitContext ec, ToplevelBlock block) { ILGenerator ig = ec.ig; *************** *** 4758,4761 **** --- 4841,4848 ---- protected virtual bool DoDefine () { + EmitContext ec = Parent.EmitContext; + if (ec == null) + throw new InternalErrorException ("MemberBase.DoDefine called too early"); + if (Name == null) throw new InternalErrorException (); *************** *** 4779,4786 **** // Lookup Type, verify validity ! MemberType = Parent.ResolveType (Type, false, Location); ! if (MemberType == null) return false; if ((Parent.ModFlags & Modifiers.SEALED) != 0){ if ((ModFlags & (Modifiers.VIRTUAL|Modifiers.ABSTRACT)) != 0){ --- 4866,4879 ---- // Lookup Type, verify validity ! bool old_unsafe = ec.InUnsafe; ! ec.InUnsafe = InUnsafe; ! Type = Type.ResolveAsTypeTerminal (ec, false); ! ec.InUnsafe = old_unsafe; ! ! if (Type == null) return false; + MemberType = Type.Type; + if ((Parent.ModFlags & Modifiers.SEALED) != 0){ if ((ModFlags & (Modifiers.VIRTUAL|Modifiers.ABSTRACT)) != 0){ *************** *** 4825,4834 **** if (IsExplicitImpl) { ! InterfaceType = Parent.ResolveType ( ! ExplicitInterfaceName.GetTypeExpression (Location), ! false, Location); ! if (InterfaceType == null) return false; if (InterfaceType.IsClass) { Report.Error (538, Location, "'{0}' in explicit interface declaration is not an interface", ExplicitInterfaceName); --- 4918,4928 ---- if (IsExplicitImpl) { ! Expression expr = ExplicitInterfaceName.GetTypeExpression (Location); ! TypeExpr texpr = expr.ResolveAsTypeTerminal (ec, false); ! if (texpr == null) return false; + InterfaceType = texpr.ResolveType (ec); + if (InterfaceType.IsClass) { Report.Error (538, Location, "'{0}' in explicit interface declaration is not an interface", ExplicitInterfaceName); *************** *** 4902,4906 **** [Flags] ! public enum Status : byte { ASSIGNED = 1, USED = 2 } static string[] attribute_targets = new string [] { "field" }; --- 4996,5003 ---- [Flags] ! public enum Status : byte { ! ASSIGNED = 1, ! USED = 2 ! } static string[] attribute_targets = new string [] { "field" }; *************** *** 4941,4945 **** } ! FieldBuilder.SetCustomAttribute (cb); } --- 5038,5046 ---- } ! if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) { ! a.Error_InvalidSecurityParent (); ! return; ! } ! FieldBuilder.SetCustomAttribute (cb); } *************** *** 4955,4958 **** --- 5056,5060 ---- protected readonly Object init; + // Private. Expression init_expr; *************** *** 5089,5097 **** public override bool Define() { ! MemberType = Parent.ResolveType (Type, false, Location); ! ! if (MemberType == null) return false; if (!CheckBase ()) return false; --- 5191,5207 ---- public override bool Define() { ! EmitContext ec = Parent.EmitContext; ! if (ec == null) ! throw new InternalErrorException ("FieldMember.Define called too early"); ! ! bool old_unsafe = ec.InUnsafe; ! ec.InUnsafe = InUnsafe; ! TypeExpr texpr = Type.ResolveAsTypeTerminal (ec, false); ! if (texpr == null) return false; + MemberType = texpr.ResolveType (ec); + ec.InUnsafe = old_unsafe; + if (!CheckBase ()) return false; *************** *** 5245,5253 **** // Null if the accessor is empty, or a Block if not // ! public Block Block; public Attributes Attributes; public Location Location; ! public Accessor (Block b, Attributes attrs, Location loc) { Block = b; --- 5355,5363 ---- // Null if the accessor is empty, or a Block if not // ! public ToplevelBlock Block; public Attributes Attributes; public Location Location; ! public Accessor (ToplevelBlock b, Attributes attrs, Location loc) { Block = b; *************** *** 5262,5266 **** public abstract class AbstractPropertyEventMethod: MemberCore, IMethodData { protected MethodData method_data; ! protected Block block; // The accessor are created event if they are not wanted. --- 5372,5377 ---- public abstract class AbstractPropertyEventMethod: MemberCore, IMethodData { protected MethodData method_data; ! protected ToplevelBlock block; ! protected ListDictionary declarative_security; // The accessor are created event if they are not wanted. *************** *** 5303,5307 **** #region IMethodData Members ! public Block Block { get { return block; --- 5414,5418 ---- #region IMethodData Members ! public ToplevelBlock Block { get { return block; *************** *** 5345,5348 **** --- 5456,5466 ---- } + if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) { + if (declarative_security == null) + declarative_security = new ListDictionary (); + a.ExtractSecurityPermissionSet (declarative_security); + return; + } + if (a.Target == AttributeTargets.Method) { method_data.MethodBuilder.SetCustomAttribute (cb); *************** *** 5374,5377 **** --- 5492,5502 ---- { method_data.Emit (container, this); + + if (declarative_security != null) { + foreach (DictionaryEntry de in declarative_security) { + method_data.MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value); + } + } + block = null; } *************** *** 5489,5503 **** } ! protected virtual InternalParameters GetParameterInfo (TypeContainer container) { Parameter [] parms = new Parameter [1]; parms [0] = new Parameter (method.Type, "value", Parameter.Modifier.NONE, null); ! return new InternalParameters ( ! container, new Parameters (parms, null, method.Location)); } public override MethodBuilder Define(TypeContainer container) { ! method_data = new MethodData (method, GetParameterInfo (container), method.ModFlags, method.flags, this); if (!method_data.Define (container)) --- 5614,5631 ---- } ! protected virtual InternalParameters GetParameterInfo (EmitContext ec) { Parameter [] parms = new Parameter [1]; parms [0] = new Parameter (method.Type, "value", Parameter.Modifier.NONE, null); ! Parameters parameters = new Parameters (parms, null, method.Location); ! Type [] types = parameters.GetParameterInfo (ec); ! return new InternalParameters (types, parameters); } public override MethodBuilder Define(TypeContainer container) { ! if (container.EmitContext == null) ! throw new InternalErrorException ("SetMethod.Define called too early"); ! method_data = new MethodData (method, GetParameterInfo (container.EmitContext), method.ModFlags, method.flags, this); if (!method_data.Define (container)) *************** *** 5613,5616 **** --- 5741,5749 ---- public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb) { + if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) { + a.Error_InvalidSecurityParent (); + return; + } + PropertyBuilder.SetCustomAttribute (cb); } *************** *** 5683,5686 **** --- 5816,5820 ---- } + // TODO: rename to Resolve...... protected override MethodInfo FindOutParentMethod (TypeContainer container, ref Type parent_ret_type) { *************** *** 5692,5703 **** parent_ret_type = parent_property.PropertyType; ! ! MethodInfo temp_m; ! temp_m = parent_property.GetGetMethod (true); ! if (temp_m != null) ! return temp_m; ! ! System.Diagnostics.Debug.Assert (parent_property.GetSetMethod (true) != null, "Internal error property without get/set"); ! return parent_property.GetSetMethod (true); } --- 5826,5845 ---- parent_ret_type = parent_property.PropertyType; ! MethodInfo get_accessor = parent_property.GetGetMethod (true); ! MethodInfo set_accessor = parent_property.GetSetMethod (true); ! ! if ((ModFlags & Modifiers.OVERRIDE) != 0) { ! if (Get != null && !Get.IsDummy && get_accessor == null) { ! Report.SymbolRelatedToPreviousError (parent_property); ! Report.Error (545, Location, "'{0}': cannot override because '{1}' does not have an overridable get accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (parent_property)); ! } ! ! if (Set != null && !Set.IsDummy && set_accessor == null) { ! Report.SymbolRelatedToPreviousError (parent_property); ! Report.Error (546, Location, "'{0}': cannot override because '{1}' does not have an overridable set accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (parent_property)); ! } ! } ! ! return get_accessor != null ? get_accessor : set_accessor; } *************** *** 6259,6262 **** --- 6401,6409 ---- public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb) { + if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) { + a.Error_InvalidSecurityParent (); + return; + } + EventBuilder.SetCustomAttribute (cb); } *************** *** 6293,6300 **** } Parameter [] parms = new Parameter [1]; parms [0] = new Parameter (Type, "value", Parameter.Modifier.NONE, null); ! InternalParameters ip = new InternalParameters ( ! Parent, new Parameters (parms, null, Location)); if (!CheckBase ()) --- 6440,6456 ---- } + EmitContext ec = Parent.EmitContext; + if (ec == null) + throw new InternalErrorException ("Event.Define called too early?"); + bool old_unsafe = ec.InUnsafe; + ec.InUnsafe = InUnsafe; + Parameter [] parms = new Parameter [1]; parms [0] = new Parameter (Type, "value", Parameter.Modifier.NONE, null); ! Parameters parameters = new Parameters (parms, null, Location); ! Type [] types = parameters.GetParameterInfo (ec); ! InternalParameters ip = new InternalParameters (types, parameters); ! ! ec.InUnsafe = old_unsafe; if (!CheckBase ()) *************** *** 6424,6428 **** } ! protected override InternalParameters GetParameterInfo (TypeContainer container) { Parameter [] fixed_parms = parameters.FixedParameters; --- 6580,6584 ---- } ! protected override InternalParameters GetParameterInfo (EmitContext ec) { Parameter [] fixed_parms = parameters.FixedParameters; *************** *** 6451,6456 **** Parameters set_formal_params = new Parameters (tmp, null, method.Location); ! return new InternalParameters (container, set_formal_params); } } --- 6607,6613 ---- Parameters set_formal_params = new Parameters (tmp, null, method.Location); + Type [] types = set_formal_params.GetParameterInfo (ec); ! return new InternalParameters (types, set_formal_params); } } *************** *** 6678,6682 **** public Operator (TypeContainer parent, OpType type, Expression ret_type, int mod_flags, Parameters parameters, ! Block block, Attributes attrs, Location loc) : base (parent, ret_type, mod_flags, AllowedModifiers, false, new MemberName ("op_" + type), attrs, parameters, loc) --- 6835,6839 ---- public Operator (TypeContainer parent, OpType type, Expression ret_type, int mod_flags, Parameters parameters, ! ToplevelBlock block, Attributes attrs, Location loc) : base (parent, ret_type, mod_flags, AllowedModifiers, false, new MemberName ("op_" + type), attrs, parameters, loc) *************** *** 6939,6943 **** { StringBuilder sb = new StringBuilder (); ! sb.AppendFormat ("{0}.operator {1} {2}({3}", tc.Name, GetName (OperatorType), Type.ToString (), Parameters.FixedParameters [0].GetSignatureForError ()); if (Parameters.FixedParameters.Length > 1) { --- 7096,7101 ---- { StringBuilder sb = new StringBuilder (); ! sb.AppendFormat ("{0}.operator {1} {2}({3}", tc.Name, GetName (OperatorType), Type.Type == null ? Type.ToString () : TypeManager.CSharpName (Type.Type), ! Parameters.FixedParameters [0].GetSignatureForError ()); if (Parameters.FixedParameters.Length > 1) { Index: codegen.cs =================================================================== RCS file: /cvsroot/csdoc/csdoc/src/mcs/mcs/codegen.cs,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** codegen.cs 6 Oct 2004 19:28:29 -0000 1.1 --- codegen.cs 29 Oct 2004 13:54:36 -0000 1.2 *************** *** 5,18 **** // Miguel de Icaza (mi...@xi...) // ! // (C) 2001 Ximian, Inc. // ! using System; using System.IO; using System.Collections; using System.Reflection; using System.Reflection.Emit; using System.Runtime.InteropServices; using System.Security.Cryptography; using Mono.Security.Cryptography; --- 5,22 ---- // Miguel de Icaza (mi...@xi...) // ! // (C) 2001, 2002, 2003 Ximian, Inc. ! // (C) 2004 Novell, Inc. // ! //#define PRODUCTION using System; using System.IO; using System.Collections; + using System.Collections.Specialized; using System.Reflection; using System.Reflection.Emit; using System.Runtime.InteropServices; + using System.Security; using System.Security.Cryptography; + using System.Security.Permissions; using Mono.Security.Cryptography; *************** *** 253,257 **** } } ! /// <summary> /// An Emit Context is created for each body of code (from methods, --- 257,261 ---- } } ! /// <summary> /// An Emit Context is created for each body of code (from methods, *************** *** 368,372 **** /// Whether we are inside an anonymous method. /// </summary> ! public bool InAnonymousMethod; /// <summary> --- 372,376 ---- /// Whether we are inside an anonymous method. /// </summary> ! public AnonymousMethod CurrentAnonymousMethod; /// <summary> *************** *** 393,396 **** --- 397,407 ---- /// <summary> + /// Anonymous methods can capture local variables and fields, + /// this object tracks it. It is copied from the TopLevelBlock + /// field. + /// </summary> + public CaptureContext capture_context; + + /// <summary> /// Trace when method is called and is obsolete then this member suppress message /// when call is inside next [Obsolete] method or type. *************** *** 398,405 **** public bool TestObsoleteMethodUsage = true; public Iterator CurrentIterator; ! FlowBranching current_flow_branching; public EmitContext (DeclSpace parent, DeclSpace ds, Location l, ILGenerator ig, Type return_type, int code_flags, bool is_constructor) --- 409,430 ---- public bool TestObsoleteMethodUsage = true; + /// <summary> + /// The current iterator + /// </summary> public Iterator CurrentIterator; ! /// <summary> ! /// Whether we are in the resolving stage or not ! /// </summary> ! enum Phase { ! Created, ! Resolving, ! Emitting ! } + Phase current_phase; + + FlowBranching current_flow_branching; + public EmitContext (DeclSpace parent, DeclSpace ds, Location l, ILGenerator ig, Type return_type, int code_flags, bool is_constructor) *************** *** 411,415 **** CheckState = RootContext.Checked; ConstantCheckState = true; ! IsStatic = (code_flags & Modifiers.STATIC) != 0; InIterator = (code_flags & Modifiers.METHOD_YIELDS) != 0; --- 436,440 ---- CheckState = RootContext.Checked; ConstantCheckState = true; ! IsStatic = (code_flags & Modifiers.STATIC) != 0; InIterator = (code_flags & Modifiers.METHOD_YIELDS) != 0; *************** *** 419,422 **** --- 444,448 ---- CurrentBlock = null; CurrentFile = 0; + current_phase = Phase.Created; if (parent != null){ *************** *** 429,433 **** } loc = l; ! if (ReturnType == TypeManager.void_type) ReturnType = null; --- 455,459 ---- } loc = l; ! if (ReturnType == TypeManager.void_type) ReturnType = null; *************** *** 452,455 **** --- 478,487 ---- } + public bool HaveCaptureInfo { + get { + return capture_context != null; + } + } + // <summary> // Starts a new code branching. This inherits the state of all local *************** *** 518,545 **** } ! public void EmitTopBlock (Block block, InternalParameters ip, Location loc) { ! bool unreachable = false; if (!Location.IsNull (loc)) CurrentFile = loc.File; ! if (block != null){ ! try { int errors = Report.Errors; ! block.EmitMeta (this, ip); if (Report.Errors == errors){ bool old_do_flow_analysis = DoFlowAnalysis; DoFlowAnalysis = true; ! current_flow_branching = FlowBranching.CreateBranching ( ! null, FlowBranching.BranchingType.Block, block, loc); if (!block.Resolve (this)) { current_flow_branching = null; DoFlowAnalysis = old_do_flow_analysis; ! return; } --- 550,688 ---- } ! public void CaptureVariable (LocalInfo li) { ! capture_context.AddLocal (CurrentAnonymousMethod, li); ! li.IsCaptured = true; ! } ! ! public void CaptureParameter (string name, Type t, int idx) ! { ! ! capture_context.AddParameter (this, CurrentAnonymousMethod, name, t, idx); ! } ! ! // ! // Use to register a field as captured ! // ! public void CaptureField (FieldExpr fe) ! { ! capture_context.AddField (fe); ! } ! ! // ! // Whether anonymous methods have captured variables ! // ! public bool HaveCapturedVariables () ! { ! if (capture_context != null) ! return capture_context.HaveCapturedVariables; ! return false; ! } ! ! // ! // Whether anonymous methods have captured fields or this. ! // ! public bool HaveCapturedFields () ! { ! if (capture_context != null) ! return capture_context.HaveCapturedFields; ! return false; ! } + // + // Emits the instance pointer for the host method + // + public void EmitMethodHostInstance (EmitContext target, AnonymousMethod am) + { + if (capture_context != null) + capture_context.EmitMethodHostInstance (target, am); + else if (IsStatic) + target.ig.Emit (OpCodes.Ldnull); + else + target.ig.Emit (OpCodes.Ldarg_0); + } + + // + // Returns whether the `local' variable has been captured by an anonymous + // method + // + public bool IsCaptured (LocalInfo local) + { + return capture_context.IsCaptured (local); + } + + public bool IsParameterCaptured (string name) + { + if (capture_context != null) + return capture_context.IsParameterCaptured (name); + return false; + } + + public void EmitMeta (ToplevelBlock b, InternalParameters ip) + { + if (capture_context != null) + capture_context.EmitHelperClasses (this); + b.EmitMeta (this); + + if (HasReturnLabel) + ReturnLabel = ig.DefineLabel (); + } + + // + // Here until we can fix the problem with Mono.CSharp.Switch, which + // currently can not cope with ig == null during resolve (which must + // be fixed for switch statements to work on anonymous methods). + // + public void EmitTopBlock (ToplevelBlock block, InternalParameters ip, Location loc) + { + if (block == null) + return; + + bool unreachable; + + if (ResolveTopBlock (null, block, ip, loc, out unreachable)){ + EmitMeta (block, ip); + + current_phase = Phase.Emitting; + EmitResolvedTopBlock (block, unreachable); + } + } + + public bool ResolveTopBlock (EmitContext anonymous_method_host, ToplevelBlock block, + InternalParameters ip, Location loc, out bool unreachable) + { + current_phase = Phase.Resolving; + + unreachable = false; + + capture_context = block.CaptureContext; + if (!Location.IsNull (loc)) CurrentFile = loc.File; ! #if PRODUCTION ! try { ! #endif int errors = Report.Errors; ! block.ResolveMeta (block, this, ip); + if (Report.Errors == errors){ bool old_do_flow_analysis = DoFlowAnalysis; DoFlowAnalysis = true; ! if (anonymous_method_host != null) ! current_flow_branching = FlowBranching.CreateBranching ( ! anonymous_method_host.CurrentBranching, FlowBranching.BranchingType.Block, ! block, loc); ! else ! current_flow_branching = FlowBranching.CreateBranching ( ! null, FlowBranching.BranchingType.Block, block, loc); if (!block.Resolve (this)) { current_flow_branching = null; DoFlowAnalysis = old_do_flow_analysis; ! return false; } *************** *** 549,554 **** DoFlowAnalysis = old_do_flow_analysis; - block.Emit (this); - if (reachability.AlwaysReturns || reachability.AlwaysThrows || --- 692,695 ---- *************** *** 556,560 **** unreachable = true; } ! } catch (Exception e) { Console.WriteLine ("Exception caught by the compiler while compiling:"); Console.WriteLine (" Block that caused the problem begin at: " + loc); --- 697,702 ---- unreachable = true; } ! #if PRODUCTION ! } catch (Exception e) { Console.WriteLine ("Exception caught by the compiler while compiling:"); Console.WriteLine (" Block that caused the problem begin at: " + loc); *************** *** 565,583 **** } Console.WriteLine (e.GetType ().FullName + ": " + e.Message); ! Console.WriteLine (Report.FriendlyStackTrace (e)); ! ! Environment.Exit (1); ! } } if (ReturnType != null && !unreachable){ if (!InIterator){ ! Report.Error (161, loc, "Not all code paths return a value"); ! return; } } if (HasReturnLabel) ig.MarkLabel (ReturnLabel); if (return_value != null){ ig.Emit (OpCodes.Ldloc, return_value); --- 707,739 --... [truncated message content] |
From: <mas...@us...> - 2004-10-07 08:13:25
|
Update of /cvsroot/csdoc/csdoc/src/mcs/build/platforms In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24910/platforms Log Message: Directory /cvsroot/csdoc/csdoc/src/mcs/build/platforms added to the repository |