changeset 1103:b30fe7e1dbb9

- Updated to DMD frontend 1.041. - Removed dmd/inifile.c , it's not under a free license, replaced with libconfig based config file.
author Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
date Thu, 12 Mar 2009 20:37:27 +0100
parents ae950bd712d3
children 81fd116b5dc9
files CMakeLists.txt dmd/Doxyfile dmd/access.c dmd/array.c dmd/arrayop.c dmd/attrib.c dmd/cast.c dmd/class.c dmd/cond.c dmd/cond.h dmd/constfold.c dmd/dchar.c dmd/declaration.c dmd/doc.c dmd/dsymbol.c dmd/entity.c dmd/expression.c dmd/expression.h dmd/func.c dmd/hdrgen.c dmd/identifier.c dmd/inifile.c dmd/interpret.c dmd/lexer.c dmd/lstring.c dmd/macro.c dmd/man.c dmd/mangle.c dmd/mars.c dmd/mars.h dmd/mem.c dmd/module.c dmd/module.h dmd/mtype.c dmd/mtype.h dmd/opover.c dmd/optimize.c dmd/parse.c dmd/rmem.h dmd/root.c dmd/root.h dmd/scope.c dmd/statement.c dmd/statement.h dmd/stringtable.c dmd/struct.c dmd/template.c dmd/template.h dmd/total.h gen/asmstmt.cpp gen/cl_helpers.cpp gen/configfile.cpp gen/configfile.h gen/main.cpp gen/statements.cpp gen/toir.cpp ldc.conf.in
diffstat 57 files changed, 1318 insertions(+), 2476 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Thu Mar 12 14:08:57 2009 +0100
+++ b/CMakeLists.txt	Thu Mar 12 20:37:27 2009 +0100
@@ -9,6 +9,19 @@
 	message(FATAL_ERROR "perl not found")
 endif(NOT PERL)
 
+include(FindPkgConfig)
+if(NOT PKG_CONFIG_FOUND)
+    message(FATAL_ERROR "pkg-config not found")
+else(NOT PKG_CONFIG_FOUND)
+    pkg_search_module(LIBCONFIGPP libconfig++)
+    if(NOT LIBCONFIGPP_FOUND)
+        message(FATAL_ERROR "libconfig++ not found")
+    endif(NOT LIBCONFIGPP_FOUND)
+    set(LIBCONFIG_CXXFLAGS ${LIBCONFIGPP_CFLAGS} CACHE STRING "libconfig++ compiler flags")
+    set(LIBCONFIG_LDFLAGS ${LIBCONFIGPP_LDFLAGS} CACHE STRING "libconfig++ linker flags")
+endif(NOT PKG_CONFIG_FOUND)
+
+
 find_program(LLVM_CONFIG llvm-config ${LLVM_INSTDIR}/bin DOC "path to llvm-config tool")
 # get llvm's install dir. a little hackish, we could do something like llvm-config --prefix, but this does as well
 string(REPLACE "/bin/llvm-config" "" LLVM_DIR ${LLVM_CONFIG})
@@ -39,7 +52,7 @@
 	OUTPUT_STRIP_TRAILING_WHITESPACE
 )
 execute_process(
-	COMMAND ${PERL_EXECUTABLE} ${LLVM_CONFIG} --libfiles bitwriter linker ipo instrumentation backend
+	COMMAND ${PERL_EXECUTABLE} ${LLVM_CONFIG} --libfiles bitwriter linker ipo instrumentation backend arm
 	OUTPUT_VARIABLE LLVM_LIBS
 	OUTPUT_STRIP_TRAILING_WHITESPACE
 )
@@ -161,9 +174,11 @@
 	set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib CACHE PATH "output dir for built libraries")
 	add_definitions(-DDEFAULT_TARGET_TRIPLE=\\"${DEFAULT_TARGET}\\")
     add_definitions(-DDEFAULT_ALT_TARGET_TRIPLE=\\"${DEFAULT_ALT_TARGET}\\")
+    add_definitions(-DLDC_INSTALL_PREFIX=\\"${CMAKE_INSTALL_PREFIX}\\")
 else(CMAKE_MINOR_VERSION LESS 6)
 	add_definitions(-DDEFAULT_TARGET_TRIPLE="${DEFAULT_TARGET}")
     add_definitions(-DDEFAULT_ALT_TARGET_TRIPLE="${DEFAULT_ALT_TARGET}")
+    add_definitions(-DLDC_INSTALL_PREFIX="${CMAKE_INSTALL_PREFIX}")
 endif(CMAKE_MINOR_VERSION LESS 6)
 
 add_executable(${LDC_EXE} ${LDC_SOURCE_FILES})
@@ -190,11 +205,11 @@
 	${LDC_EXE} PROPERTIES
 	OUTPUT_NAME ${LDC_EXE_NAME}
 	RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin
-	COMPILE_FLAGS "${LLVM_CXXFLAGS} -Wno-deprecated -Wno-write-strings"
+	COMPILE_FLAGS "${LLVM_CXXFLAGS} ${LIBCONFIG_CXXFLAGS} -Wno-deprecated -Wno-write-strings"
 )
 
 # LDFLAGS should actually be in target property LINK_FLAGS, but this works, and gets around linking problems
-target_link_libraries(${LDC_EXE} "${LLVM_LDFLAGS} ${LLVM_LIBS}")
+target_link_libraries(${LDC_EXE} "${LLVM_LDFLAGS} ${LLVM_LIBS} ${LIBCONFIG_LDFLAGS}")
 if(WIN32)
 	target_link_libraries(${LDC_EXE} psapi)
 	set(CONF_INST_DIR bin)
--- a/dmd/Doxyfile	Thu Mar 12 14:08:57 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1257 +0,0 @@
-# Doxyfile 1.5.2
-
-# This file describes the settings to be used by the documentation system
-# doxygen (www.doxygen.org) for a project
-#
-# All text after a hash (#) is considered a comment and will be ignored
-# The format is:
-#       TAG = value [value, ...]
-# For lists items can also be appended using:
-#       TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (" ")
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
-
-# This tag specifies the encoding used for all characters in the config file that
-# follow. The default is UTF-8 which is also the encoding used for all text before
-# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into
-# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of
-# possible encodings.
-
-DOXYFILE_ENCODING      = UTF-8
-
-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
-# by quotes) that should identify the project.
-
-PROJECT_NAME           = DMD
-
-# The PROJECT_NUMBER tag can be used to enter a project or revision number.
-# This could be handy for archiving the generated documentation or
-# if some version control system is used.
-
-PROJECT_NUMBER         = 1.022
-
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
-# base path where the generated documentation will be put.
-# If a relative path is entered, it will be relative to the location
-# where doxygen was started. If left blank the current directory will be used.
-
-OUTPUT_DIRECTORY       = docs
-
-# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
-# 4096 sub-directories (in 2 levels) under the output directory of each output
-# format and will distribute the generated files over these directories.
-# Enabling this option can be useful when feeding doxygen a huge amount of
-# source files, where putting all generated files in the same directory would
-# otherwise cause performance problems for the file system.
-
-CREATE_SUBDIRS         = NO
-
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all
-# documentation generated by doxygen is written. Doxygen will use this
-# information to generate all constant output in the proper language.
-# The default language is English, other supported languages are:
-# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
-# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian,
-# Italian, Japanese, Japanese-en (Japanese with English messages), Korean,
-# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian,
-# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
-
-OUTPUT_LANGUAGE        = English
-
-# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
-# include brief member descriptions after the members that are listed in
-# the file and class documentation (similar to JavaDoc).
-# Set to NO to disable this.
-
-BRIEF_MEMBER_DESC      = YES
-
-# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
-# the brief description of a member or function before the detailed description.
-# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
-# brief descriptions will be completely suppressed.
-
-REPEAT_BRIEF           = YES
-
-# This tag implements a quasi-intelligent brief description abbreviator
-# that is used to form the text in various listings. Each string
-# in this list, if found as the leading text of the brief description, will be
-# stripped from the text and the result after processing the whole list, is
-# used as the annotated text. Otherwise, the brief description is used as-is.
-# If left blank, the following values are used ("$name" is automatically
-# replaced with the name of the entity): "The $name class" "The $name widget"
-# "The $name file" "is" "provides" "specifies" "contains"
-# "represents" "a" "an" "the"
-
-ABBREVIATE_BRIEF       =
-
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
-# Doxygen will generate a detailed section even if there is only a brief
-# description.
-
-ALWAYS_DETAILED_SEC    = NO
-
-# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
-# inherited members of a class in the documentation of that class as if those
-# members were ordinary class members. Constructors, destructors and assignment
-# operators of the base classes will not be shown.
-
-INLINE_INHERITED_MEMB  = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
-# path before files name in the file list and in the header files. If set
-# to NO the shortest path that makes the file name unique will be used.
-
-FULL_PATH_NAMES        = YES
-
-# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
-# can be used to strip a user-defined part of the path. Stripping is
-# only done if one of the specified strings matches the left-hand part of
-# the path. The tag can be used to show relative paths in the file list.
-# If left blank the directory from which doxygen is run is used as the
-# path to strip.
-
-STRIP_FROM_PATH        =
-
-# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
-# the path mentioned in the documentation of a class, which tells
-# the reader which header file to include in order to use a class.
-# If left blank only the name of the header file containing the class
-# definition is used. Otherwise one should specify the include paths that
-# are normally passed to the compiler using the -I flag.
-
-STRIP_FROM_INC_PATH    =
-
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
-# (but less readable) file names. This can be useful is your file systems
-# doesn't support long names like on DOS, Mac, or CD-ROM.
-
-SHORT_NAMES            = NO
-
-# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
-# will interpret the first line (until the first dot) of a JavaDoc-style
-# comment as the brief description. If set to NO, the JavaDoc
-# comments will behave just like the Qt-style comments (thus requiring an
-# explicit @brief command for a brief description.
-
-JAVADOC_AUTOBRIEF      = NO
-
-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
-# treat a multi-line C++ special comment block (i.e. a block of //! or ///
-# comments) as a brief description. This used to be the default behaviour.
-# The new default is to treat a multi-line C++ comment block as a detailed
-# description. Set this tag to YES if you prefer the old behaviour instead.
-
-MULTILINE_CPP_IS_BRIEF = NO
-
-# If the DETAILS_AT_TOP tag is set to YES then Doxygen
-# will output the detailed description near the top, like JavaDoc.
-# If set to NO, the detailed description appears after the member
-# documentation.
-
-DETAILS_AT_TOP         = NO
-
-# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
-# member inherits the documentation from any documented member that it
-# re-implements.
-
-INHERIT_DOCS           = YES
-
-# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
-# a new page for each member. If set to NO, the documentation of a member will
-# be part of the file/class/namespace that contains it.
-
-SEPARATE_MEMBER_PAGES  = NO
-
-# The TAB_SIZE tag can be used to set the number of spaces in a tab.
-# Doxygen uses this value to replace tabs by spaces in code fragments.
-
-TAB_SIZE               = 8
-
-# This tag can be used to specify a number of aliases that acts
-# as commands in the documentation. An alias has the form "name=value".
-# For example adding "sideeffect=\par Side Effects:\n" will allow you to
-# put the command \sideeffect (or @sideeffect) in the documentation, which
-# will result in a user-defined paragraph with heading "Side Effects:".
-# You can put \n's in the value part of an alias to insert newlines.
-
-ALIASES                =
-
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
-# sources only. Doxygen will then generate output that is more tailored for C.
-# For instance, some of the names that are used will be different. The list
-# of all members will be omitted, etc.
-
-OPTIMIZE_OUTPUT_FOR_C  = NO
-
-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
-# sources only. Doxygen will then generate output that is more tailored for Java.
-# For instance, namespaces will be presented as packages, qualified scopes
-# will look different, etc.
-
-OPTIMIZE_OUTPUT_JAVA   = NO
-
-# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to
-# include (a tag file for) the STL sources as input, then you should
-# set this tag to YES in order to let doxygen match functions declarations and
-# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
-# func(std::string) {}). This also make the inheritance and collaboration
-# diagrams that involve STL classes more complete and accurate.
-
-BUILTIN_STL_SUPPORT    = NO
-
-# If you use Microsoft's C++/CLI language, you should set this option to YES to
-# enable parsing support.
-
-CPP_CLI_SUPPORT        = NO
-
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
-# tag is set to YES, then doxygen will reuse the documentation of the first
-# member in the group (if any) for the other members of the group. By default
-# all members of a group must be documented explicitly.
-
-DISTRIBUTE_GROUP_DOC   = NO
-
-# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
-# the same type (for instance a group of public functions) to be put as a
-# subgroup of that type (e.g. under the Public Functions section). Set it to
-# NO to prevent subgrouping. Alternatively, this can be done per class using
-# the \nosubgrouping command.
-
-SUBGROUPING            = YES
-
-#---------------------------------------------------------------------------
-# Build related configuration options
-#---------------------------------------------------------------------------
-
-# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
-# documentation are documented, even if no documentation was available.
-# Private class members and static file members will be hidden unless
-# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
-
-EXTRACT_ALL            = YES
-
-# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
-# will be included in the documentation.
-
-EXTRACT_PRIVATE        = NO
-
-# If the EXTRACT_STATIC tag is set to YES all static members of a file
-# will be included in the documentation.
-
-EXTRACT_STATIC         = NO
-
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
-# defined locally in source files will be included in the documentation.
-# If set to NO only classes defined in header files are included.
-
-EXTRACT_LOCAL_CLASSES  = YES
-
-# This flag is only useful for Objective-C code. When set to YES local
-# methods, which are defined in the implementation section but not in
-# the interface are included in the documentation.
-# If set to NO (the default) only methods in the interface are included.
-
-EXTRACT_LOCAL_METHODS  = NO
-
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
-# undocumented members of documented classes, files or namespaces.
-# If set to NO (the default) these members will be included in the
-# various overviews, but no documentation section is generated.
-# This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_MEMBERS     = NO
-
-# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
-# undocumented classes that are normally visible in the class hierarchy.
-# If set to NO (the default) these classes will be included in the various
-# overviews. This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_CLASSES     = NO
-
-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
-# friend (class|struct|union) declarations.
-# If set to NO (the default) these declarations will be included in the
-# documentation.
-
-HIDE_FRIEND_COMPOUNDS  = NO
-
-# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
-# documentation blocks found inside the body of a function.
-# If set to NO (the default) these blocks will be appended to the
-# function's detailed documentation block.
-
-HIDE_IN_BODY_DOCS      = NO
-
-# The INTERNAL_DOCS tag determines if documentation
-# that is typed after a \internal command is included. If the tag is set
-# to NO (the default) then the documentation will be excluded.
-# Set it to YES to include the internal documentation.
-
-INTERNAL_DOCS          = NO
-
-# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
-# file names in lower-case letters. If set to YES upper-case letters are also
-# allowed. This is useful if you have classes or files whose names only differ
-# in case and if your file system supports case sensitive file names. Windows
-# and Mac users are advised to set this option to NO.
-
-CASE_SENSE_NAMES       = YES
-
-# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
-# will show members with their full class and namespace scopes in the
-# documentation. If set to YES the scope will be hidden.
-
-HIDE_SCOPE_NAMES       = NO
-
-# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
-# will put a list of the files that are included by a file in the documentation
-# of that file.
-
-SHOW_INCLUDE_FILES     = YES
-
-# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
-# is inserted in the documentation for inline members.
-
-INLINE_INFO            = YES
-
-# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
-# will sort the (detailed) documentation of file and class members
-# alphabetically by member name. If set to NO the members will appear in
-# declaration order.
-
-SORT_MEMBER_DOCS       = YES
-
-# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
-# brief documentation of file, namespace and class members alphabetically
-# by member name. If set to NO (the default) the members will appear in
-# declaration order.
-
-SORT_BRIEF_DOCS        = NO
-
-# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
-# sorted by fully-qualified names, including namespaces. If set to
-# NO (the default), the class list will be sorted only by class name,
-# not including the namespace part.
-# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
-# Note: This option applies only to the class list, not to the
-# alphabetical list.
-
-SORT_BY_SCOPE_NAME     = NO
-
-# The GENERATE_TODOLIST tag can be used to enable (YES) or
-# disable (NO) the todo list. This list is created by putting \todo
-# commands in the documentation.
-
-GENERATE_TODOLIST      = YES
-
-# The GENERATE_TESTLIST tag can be used to enable (YES) or
-# disable (NO) the test list. This list is created by putting \test
-# commands in the documentation.
-
-GENERATE_TESTLIST      = YES
-
-# The GENERATE_BUGLIST tag can be used to enable (YES) or
-# disable (NO) the bug list. This list is created by putting \bug
-# commands in the documentation.
-
-GENERATE_BUGLIST       = YES
-
-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
-# disable (NO) the deprecated list. This list is created by putting
-# \deprecated commands in the documentation.
-
-GENERATE_DEPRECATEDLIST= YES
-
-# The ENABLED_SECTIONS tag can be used to enable conditional
-# documentation sections, marked by \if sectionname ... \endif.
-
-ENABLED_SECTIONS       =
-
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
-# the initial value of a variable or define consists of for it to appear in
-# the documentation. If the initializer consists of more lines than specified
-# here it will be hidden. Use a value of 0 to hide initializers completely.
-# The appearance of the initializer of individual variables and defines in the
-# documentation can be controlled using \showinitializer or \hideinitializer
-# command in the documentation regardless of this setting.
-
-MAX_INITIALIZER_LINES  = 30
-
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
-# at the bottom of the documentation of classes and structs. If set to YES the
-# list will mention the files that were used to generate the documentation.
-
-SHOW_USED_FILES        = YES
-
-# If the sources in your project are distributed over multiple directories
-# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
-# in the documentation. The default is NO.
-
-SHOW_DIRECTORIES       = NO
-
-# The FILE_VERSION_FILTER tag can be used to specify a program or script that
-# doxygen should invoke to get the current version for each file (typically from the
-# version control system). Doxygen will invoke the program by executing (via
-# popen()) the command <command> <input-file>, where <command> is the value of
-# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
-# provided by doxygen. Whatever the program writes to standard output
-# is used as the file version. See the manual for examples.
-
-FILE_VERSION_FILTER    =
-
-#---------------------------------------------------------------------------
-# configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-
-# The QUIET tag can be used to turn on/off the messages that are generated
-# by doxygen. Possible values are YES and NO. If left blank NO is used.
-
-QUIET                  = NO
-
-# The WARNINGS tag can be used to turn on/off the warning messages that are
-# generated by doxygen. Possible values are YES and NO. If left blank
-# NO is used.
-
-WARNINGS               = YES
-
-# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
-# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
-# automatically be disabled.
-
-WARN_IF_UNDOCUMENTED   = YES
-
-# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
-# potential errors in the documentation, such as not documenting some
-# parameters in a documented function, or documenting parameters that
-# don't exist or using markup commands wrongly.
-
-WARN_IF_DOC_ERROR      = YES
-
-# This WARN_NO_PARAMDOC option can be abled to get warnings for
-# functions that are documented, but have no documentation for their parameters
-# or return value. If set to NO (the default) doxygen will only warn about
-# wrong or incomplete parameter documentation, but not about the absence of
-# documentation.
-
-WARN_NO_PARAMDOC       = NO
-
-# The WARN_FORMAT tag determines the format of the warning messages that
-# doxygen can produce. The string should contain the $file, $line, and $text
-# tags, which will be replaced by the file and line number from which the
-# warning originated and the warning text. Optionally the format may contain
-# $version, which will be replaced by the version of the file (if it could
-# be obtained via FILE_VERSION_FILTER)
-
-WARN_FORMAT            = "$file:$line: $text"
-
-# The WARN_LOGFILE tag can be used to specify a file to which warning
-# and error messages should be written. If left blank the output is written
-# to stderr.
-
-WARN_LOGFILE           =
-
-#---------------------------------------------------------------------------
-# configuration options related to the input files
-#---------------------------------------------------------------------------
-
-# The INPUT tag can be used to specify the files and/or directories that contain
-# documented source files. You may enter file names like "myfile.cpp" or
-# directories like "/usr/src/myproject". Separate the files or directories
-# with spaces.
-
-INPUT                  =
-
-# This tag can be used to specify the character encoding of the source files that
-# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default
-# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding.
-# See http://www.gnu.org/software/libiconv for the list of possible encodings.
-
-INPUT_ENCODING         = UTF-8
-
-# If the value of the INPUT tag contains directories, you can use the
-# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
-# blank the following patterns are tested:
-# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
-# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py
-
-FILE_PATTERNS          =
-
-# The RECURSIVE tag can be used to turn specify whether or not subdirectories
-# should be searched for input files as well. Possible values are YES and NO.
-# If left blank NO is used.
-
-RECURSIVE              = NO
-
-# The EXCLUDE tag can be used to specify files and/or directories that should
-# excluded from the INPUT source files. This way you can easily exclude a
-# subdirectory from a directory tree whose root is specified with the INPUT tag.
-
-EXCLUDE                =
-
-# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
-# directories that are symbolic links (a Unix filesystem feature) are excluded
-# from the input.
-
-EXCLUDE_SYMLINKS       = NO
-
-# If the value of the INPUT tag contains directories, you can use the
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
-# certain files from those directories. Note that the wildcards are matched
-# against the file with absolute path, so to exclude all test directories
-# for example use the pattern */test/*
-
-EXCLUDE_PATTERNS       =
-
-# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
-# (namespaces, classes, functions, etc.) that should be excluded from the output.
-# The symbol name can be a fully qualified name, a word, or if the wildcard * is used,
-# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test
-
-EXCLUDE_SYMBOLS        =
-
-# The EXAMPLE_PATH tag can be used to specify one or more files or
-# directories that contain example code fragments that are included (see
-# the \include command).
-
-EXAMPLE_PATH           =
-
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
-# blank all files are included.
-
-EXAMPLE_PATTERNS       =
-
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
-# searched for input files to be used with the \include or \dontinclude
-# commands irrespective of the value of the RECURSIVE tag.
-# Possible values are YES and NO. If left blank NO is used.
-
-EXAMPLE_RECURSIVE      = NO
-
-# The IMAGE_PATH tag can be used to specify one or more files or
-# directories that contain image that are included in the documentation (see
-# the \image command).
-
-IMAGE_PATH             =
-
-# The INPUT_FILTER tag can be used to specify a program that doxygen should
-# invoke to filter for each input file. Doxygen will invoke the filter program
-# by executing (via popen()) the command <filter> <input-file>, where <filter>
-# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
-# input file. Doxygen will then use the output that the filter program writes
-# to standard output.  If FILTER_PATTERNS is specified, this tag will be
-# ignored.
-
-INPUT_FILTER           =
-
-# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
-# basis.  Doxygen will compare the file name with each pattern and apply the
-# filter if there is a match.  The filters are a list of the form:
-# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
-# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
-# is applied to all files.
-
-FILTER_PATTERNS        =
-
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
-# INPUT_FILTER) will be used to filter the input files when producing source
-# files to browse (i.e. when SOURCE_BROWSER is set to YES).
-
-FILTER_SOURCE_FILES    = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to source browsing
-#---------------------------------------------------------------------------
-
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will
-# be generated. Documented entities will be cross-referenced with these sources.
-# Note: To get rid of all source code in the generated output, make sure also
-# VERBATIM_HEADERS is set to NO.
-
-SOURCE_BROWSER         = NO
-
-# Setting the INLINE_SOURCES tag to YES will include the body
-# of functions and classes directly in the documentation.
-
-INLINE_SOURCES         = NO
-
-# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
-# doxygen to hide any special comment blocks from generated source code
-# fragments. Normal C and C++ comments will always remain visible.
-
-STRIP_CODE_COMMENTS    = YES
-
-# If the REFERENCED_BY_RELATION tag is set to YES (the default)
-# then for each documented function all documented
-# functions referencing it will be listed.
-
-REFERENCED_BY_RELATION = YES
-
-# If the REFERENCES_RELATION tag is set to YES (the default)
-# then for each documented function all documented entities
-# called/used by that function will be listed.
-
-REFERENCES_RELATION    = YES
-
-# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
-# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
-# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
-# link to the source code.  Otherwise they will link to the documentstion.
-
-REFERENCES_LINK_SOURCE = YES
-
-# If the USE_HTAGS tag is set to YES then the references to source code
-# will point to the HTML generated by the htags(1) tool instead of doxygen
-# built-in source browser. The htags tool is part of GNU's global source
-# tagging system (see http://www.gnu.org/software/global/global.html). You
-# will need version 4.8.6 or higher.
-
-USE_HTAGS              = NO
-
-# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
-# will generate a verbatim copy of the header file for each class for
-# which an include is specified. Set to NO to disable this.
-
-VERBATIM_HEADERS       = YES
-
-#---------------------------------------------------------------------------
-# configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
-# of all compounds will be generated. Enable this if the project
-# contains a lot of classes, structs, unions or interfaces.
-
-ALPHABETICAL_INDEX     = NO
-
-# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
-# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
-# in which this list will be split (can be a number in the range [1..20])
-
-COLS_IN_ALPHA_INDEX    = 5
-
-# In case all classes in a project start with a common prefix, all
-# classes will be put under the same header in the alphabetical index.
-# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
-# should be ignored while generating the index headers.
-
-IGNORE_PREFIX          =
-
-#---------------------------------------------------------------------------
-# configuration options related to the HTML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
-# generate HTML output.
-
-GENERATE_HTML          = YES
-
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `html' will be used as the default path.
-
-HTML_OUTPUT            = html
-
-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
-# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
-# doxygen will generate files with .html extension.
-
-HTML_FILE_EXTENSION    = .html
-
-# The HTML_HEADER tag can be used to specify a personal HTML header for
-# each generated HTML page. If it is left blank doxygen will generate a
-# standard header.
-
-HTML_HEADER            =
-
-# The HTML_FOOTER tag can be used to specify a personal HTML footer for
-# each generated HTML page. If it is left blank doxygen will generate a
-# standard footer.
-
-HTML_FOOTER            =
-
-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
-# style sheet that is used by each HTML page. It can be used to
-# fine-tune the look of the HTML output. If the tag is left blank doxygen
-# will generate a default style sheet. Note that doxygen will try to copy
-# the style sheet file to the HTML output directory, so don't put your own
-# stylesheet in the HTML output directory as well, or it will be erased!
-
-HTML_STYLESHEET        =
-
-# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
-# files or namespaces will be aligned in HTML using tables. If set to
-# NO a bullet list will be used.
-
-HTML_ALIGN_MEMBERS     = YES
-
-# If the GENERATE_HTMLHELP tag is set to YES, additional index files
-# will be generated that can be used as input for tools like the
-# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
-# of the generated HTML documentation.
-
-GENERATE_HTMLHELP      = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
-# be used to specify the file name of the resulting .chm file. You
-# can add a path in front of the file if the result should not be
-# written to the html output directory.
-
-CHM_FILE               =
-
-# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
-# be used to specify the location (absolute path including file name) of
-# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
-# the HTML help compiler on the generated index.hhp.
-
-HHC_LOCATION           =
-
-# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
-# controls if a separate .chi index file is generated (YES) or that
-# it should be included in the master .chm file (NO).
-
-GENERATE_CHI           = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
-# controls whether a binary table of contents is generated (YES) or a
-# normal table of contents (NO) in the .chm file.
-
-BINARY_TOC             = NO
-
-# The TOC_EXPAND flag can be set to YES to add extra items for group members
-# to the contents of the HTML help documentation and to the tree view.
-
-TOC_EXPAND             = NO
-
-# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
-# top of each HTML page. The value NO (the default) enables the index and
-# the value YES disables it.
-
-DISABLE_INDEX          = NO
-
-# This tag can be used to set the number of enum values (range [1..20])
-# that doxygen will group on one line in the generated HTML documentation.
-
-ENUM_VALUES_PER_LINE   = 4
-
-# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
-# generated containing a tree-like index structure (just like the one that
-# is generated for HTML Help). For this to work a browser that supports
-# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
-# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
-# probably better off using the HTML help feature.
-
-GENERATE_TREEVIEW      = NO
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
-# used to set the initial width (in pixels) of the frame in which the tree
-# is shown.
-
-TREEVIEW_WIDTH         = 250
-
-#---------------------------------------------------------------------------
-# configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
-# generate Latex output.
-
-GENERATE_LATEX         = YES
-
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `latex' will be used as the default path.
-
-LATEX_OUTPUT           = latex
-
-# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
-# invoked. If left blank `latex' will be used as the default command name.
-
-LATEX_CMD_NAME         = latex
-
-# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
-# generate index for LaTeX. If left blank `makeindex' will be used as the
-# default command name.
-
-MAKEINDEX_CMD_NAME     = makeindex
-
-# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
-# LaTeX documents. This may be useful for small projects and may help to
-# save some trees in general.
-
-COMPACT_LATEX          = NO
-
-# The PAPER_TYPE tag can be used to set the paper type that is used
-# by the printer. Possible values are: a4, a4wide, letter, legal and
-# executive. If left blank a4wide will be used.
-
-PAPER_TYPE             = a4wide
-
-# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
-# packages that should be included in the LaTeX output.
-
-EXTRA_PACKAGES         =
-
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
-# the generated latex document. The header should contain everything until
-# the first chapter. If it is left blank doxygen will generate a
-# standard header. Notice: only use this tag if you know what you are doing!
-
-LATEX_HEADER           =
-
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
-# is prepared for conversion to pdf (using ps2pdf). The pdf file will
-# contain links (just like the HTML output) instead of page references
-# This makes the output suitable for online browsing using a pdf viewer.
-
-PDF_HYPERLINKS         = NO
-
-# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
-# plain latex in the generated Makefile. Set this option to YES to get a
-# higher quality PDF documentation.
-
-USE_PDFLATEX           = NO
-
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
-# command to the generated LaTeX files. This will instruct LaTeX to keep
-# running if errors occur, instead of asking the user for help.
-# This option is also used when generating formulas in HTML.
-
-LATEX_BATCHMODE        = NO
-
-# If LATEX_HIDE_INDICES is set to YES then doxygen will not
-# include the index chapters (such as File Index, Compound Index, etc.)
-# in the output.
-
-LATEX_HIDE_INDICES     = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the RTF output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
-# The RTF output is optimized for Word 97 and may not look very pretty with
-# other RTF readers or editors.
-
-GENERATE_RTF           = NO
-
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `rtf' will be used as the default path.
-
-RTF_OUTPUT             = rtf
-
-# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
-# RTF documents. This may be useful for small projects and may help to
-# save some trees in general.
-
-COMPACT_RTF            = NO
-
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
-# will contain hyperlink fields. The RTF file will
-# contain links (just like the HTML output) instead of page references.
-# This makes the output suitable for online browsing using WORD or other
-# programs which support those fields.
-# Note: wordpad (write) and others do not support links.
-
-RTF_HYPERLINKS         = NO
-
-# Load stylesheet definitions from file. Syntax is similar to doxygen's
-# config file, i.e. a series of assignments. You only have to provide
-# replacements, missing definitions are set to their default value.
-
-RTF_STYLESHEET_FILE    =
-
-# Set optional variables used in the generation of an rtf document.
-# Syntax is similar to doxygen's config file.
-
-RTF_EXTENSIONS_FILE    =
-
-#---------------------------------------------------------------------------
-# configuration options related to the man page output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
-# generate man pages
-
-GENERATE_MAN           = NO
-
-# The MAN_OUTPUT tag is used to specify where the man pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `man' will be used as the default path.
-
-MAN_OUTPUT             = man
-
-# The MAN_EXTENSION tag determines the extension that is added to
-# the generated man pages (default is the subroutine's section .3)
-
-MAN_EXTENSION          = .3
-
-# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
-# then it will generate one additional man file for each entity
-# documented in the real man page(s). These additional files
-# only source the real man page, but without them the man command
-# would be unable to find the correct page. The default is NO.
-
-MAN_LINKS              = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the XML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_XML tag is set to YES Doxygen will
-# generate an XML file that captures the structure of
-# the code including all documentation.
-
-GENERATE_XML           = NO
-
-# The XML_OUTPUT tag is used to specify where the XML pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `xml' will be used as the default path.
-
-XML_OUTPUT             = xml
-
-# The XML_SCHEMA tag can be used to specify an XML schema,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
-
-XML_SCHEMA             =
-
-# The XML_DTD tag can be used to specify an XML DTD,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
-
-XML_DTD                =
-
-# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
-# dump the program listings (including syntax highlighting
-# and cross-referencing information) to the XML output. Note that
-# enabling this will significantly increase the size of the XML output.
-
-XML_PROGRAMLISTING     = YES
-
-#---------------------------------------------------------------------------
-# configuration options for the AutoGen Definitions output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
-# generate an AutoGen Definitions (see autogen.sf.net) file
-# that captures the structure of the code including all
-# documentation. Note that this feature is still experimental
-# and incomplete at the moment.
-
-GENERATE_AUTOGEN_DEF   = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the Perl module output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_PERLMOD tag is set to YES Doxygen will
-# generate a Perl module file that captures the structure of
-# the code including all documentation. Note that this
-# feature is still experimental and incomplete at the
-# moment.
-
-GENERATE_PERLMOD       = NO
-
-# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
-# the necessary Makefile rules, Perl scripts and LaTeX code to be able
-# to generate PDF and DVI output from the Perl module output.
-
-PERLMOD_LATEX          = NO
-
-# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
-# nicely formatted so it can be parsed by a human reader.  This is useful
-# if you want to understand what is going on.  On the other hand, if this
-# tag is set to NO the size of the Perl module output will be much smaller
-# and Perl will parse it just the same.
-
-PERLMOD_PRETTY         = YES
-
-# The names of the make variables in the generated doxyrules.make file
-# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
-# This is useful so different doxyrules.make files included by the same
-# Makefile don't overwrite each other's variables.
-
-PERLMOD_MAKEVAR_PREFIX =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor
-#---------------------------------------------------------------------------
-
-# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
-# evaluate all C-preprocessor directives found in the sources and include
-# files.
-
-ENABLE_PREPROCESSING   = YES
-
-# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
-# names in the source code. If set to NO (the default) only conditional
-# compilation will be performed. Macro expansion can be done in a controlled
-# way by setting EXPAND_ONLY_PREDEF to YES.
-
-MACRO_EXPANSION        = NO
-
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
-# then the macro expansion is limited to the macros specified with the
-# PREDEFINED and EXPAND_AS_DEFINED tags.
-
-EXPAND_ONLY_PREDEF     = NO
-
-# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
-# in the INCLUDE_PATH (see below) will be search if a #include is found.
-
-SEARCH_INCLUDES        = YES
-
-# The INCLUDE_PATH tag can be used to specify one or more directories that
-# contain include files that are not input files but should be processed by
-# the preprocessor.
-
-INCLUDE_PATH           =
-
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
-# patterns (like *.h and *.hpp) to filter out the header-files in the
-# directories. If left blank, the patterns specified with FILE_PATTERNS will
-# be used.
-
-INCLUDE_FILE_PATTERNS  =
-
-# The PREDEFINED tag can be used to specify one or more macro names that
-# are defined before the preprocessor is started (similar to the -D option of
-# gcc). The argument of the tag is a list of macros of the form: name
-# or name=definition (no spaces). If the definition and the = are
-# omitted =1 is assumed. To prevent a macro definition from being
-# undefined via #undef or recursively expanded use the := operator
-# instead of the = operator.
-
-PREDEFINED             =
-
-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
-# this tag can be used to specify a list of macro names that should be expanded.
-# The macro definition that is found in the sources will be used.
-# Use the PREDEFINED tag if you want to use a different macro definition.
-
-EXPAND_AS_DEFINED      =
-
-# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
-# doxygen's preprocessor will remove all function-like macros that are alone
-# on a line, have an all uppercase name, and do not end with a semicolon. Such
-# function macros are typically used for boiler-plate code, and will confuse
-# the parser if not removed.
-
-SKIP_FUNCTION_MACROS   = YES
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to external references
-#---------------------------------------------------------------------------
-
-# The TAGFILES option can be used to specify one or more tagfiles.
-# Optionally an initial location of the external documentation
-# can be added for each tagfile. The format of a tag file without
-# this location is as follows:
-#   TAGFILES = file1 file2 ...
-# Adding location for the tag files is done as follows:
-#   TAGFILES = file1=loc1 "file2 = loc2" ...
-# where "loc1" and "loc2" can be relative or absolute paths or
-# URLs. If a location is present for each tag, the installdox tool
-# does not have to be run to correct the links.
-# Note that each tag file must have a unique name
-# (where the name does NOT include the path)
-# If a tag file is not located in the directory in which doxygen
-# is run, you must also specify the path to the tagfile here.
-
-TAGFILES               =
-
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create
-# a tag file that is based on the input files it reads.
-
-GENERATE_TAGFILE       =
-
-# If the ALLEXTERNALS tag is set to YES all external classes will be listed
-# in the class index. If set to NO only the inherited external classes
-# will be listed.
-
-ALLEXTERNALS           = NO
-
-# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
-# in the modules index. If set to NO, only the current project's groups will
-# be listed.
-
-EXTERNAL_GROUPS        = YES
-
-# The PERL_PATH should be the absolute path and name of the perl script
-# interpreter (i.e. the result of `which perl').
-
-PERL_PATH              = /usr/bin/perl
-
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool
-#---------------------------------------------------------------------------
-
-# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
-# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
-# or super classes. Setting the tag to NO turns the diagrams off. Note that
-# this option is superseded by the HAVE_DOT option below. This is only a
-# fallback. It is recommended to install and use dot, since it yields more
-# powerful graphs.
-
-CLASS_DIAGRAMS         = YES
-
-# You can define message sequence charts within doxygen comments using the \msc
-# command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to
-# produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to
-# specify the directory where the mscgen tool resides. If left empty the tool is assumed to
-# be found in the default search path.
-
-MSCGEN_PATH            =
-
-# If set to YES, the inheritance and collaboration graphs will hide
-# inheritance and usage relations if the target is undocumented
-# or is not a class.
-
-HIDE_UNDOC_RELATIONS   = YES
-
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
-# available from the path. This tool is part of Graphviz, a graph visualization
-# toolkit from AT&T and Lucent Bell Labs. The other options in this section
-# have no effect if this option is set to NO (the default)
-
-HAVE_DOT               = NO
-
-# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect inheritance relations. Setting this tag to YES will force the
-# the CLASS_DIAGRAMS tag to NO.
-
-CLASS_GRAPH            = YES
-
-# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect implementation dependencies (inheritance, containment, and
-# class references variables) of the class with other documented classes.
-
-COLLABORATION_GRAPH    = YES
-
-# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for groups, showing the direct groups dependencies
-
-GROUP_GRAPHS           = YES
-
-# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
-# collaboration diagrams in a style similar to the OMG's Unified Modeling
-# Language.
-
-UML_LOOK               = NO
-
-# If set to YES, the inheritance and collaboration graphs will show the
-# relations between templates and their instances.
-
-TEMPLATE_RELATIONS     = NO
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
-# tags are set to YES then doxygen will generate a graph for each documented
-# file showing the direct and indirect include dependencies of the file with
-# other documented files.
-
-INCLUDE_GRAPH          = YES
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
-# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
-# documented header file showing the documented files that directly or
-# indirectly include this file.
-
-INCLUDED_BY_GRAPH      = YES
-
-# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will
-# generate a call dependency graph for every global function or class method.
-# Note that enabling this option will significantly increase the time of a run.
-# So in most cases it will be better to enable call graphs for selected
-# functions only using the \callgraph command.
-
-CALL_GRAPH             = NO
-
-# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will
-# generate a caller dependency graph for every global function or class method.
-# Note that enabling this option will significantly increase the time of a run.
-# So in most cases it will be better to enable caller graphs for selected
-# functions only using the \callergraph command.
-
-CALLER_GRAPH           = NO
-
-# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
-# will graphical hierarchy of all classes instead of a textual one.
-
-GRAPHICAL_HIERARCHY    = YES
-
-# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
-# then doxygen will show the dependencies a directory has on other directories
-# in a graphical way. The dependency relations are determined by the #include
-# relations between the files in the directories.
-
-DIRECTORY_GRAPH        = YES
-
-# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
-# generated by dot. Possible values are png, jpg, or gif
-# If left blank png will be used.
-
-DOT_IMAGE_FORMAT       = png
-
-# The tag DOT_PATH can be used to specify the path where the dot tool can be
-# found. If left blank, it is assumed the dot tool can be found in the path.
-
-DOT_PATH               =
-
-# The DOTFILE_DIRS tag can be used to specify one or more directories that
-# contain dot files that are included in the documentation (see the
-# \dotfile command).
-
-DOTFILE_DIRS           =
-
-# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
-# nodes that will be shown in the graph. If the number of nodes in a graph
-# becomes larger than this value, doxygen will truncate the graph, which is
-# visualized by representing a node as a red box. Note that doxygen will always
-# show the root nodes and its direct children regardless of this setting.
-
-DOT_GRAPH_MAX_NODES    = 50
-
-# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
-# background. This is disabled by default, which results in a white background.
-# Warning: Depending on the platform used, enabling this option may lead to
-# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
-# read).
-
-DOT_TRANSPARENT        = NO
-
-# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
-# files in one run (i.e. multiple -o and -T options on the command line). This
-# makes dot run faster, but since only newer versions of dot (>1.8.10)
-# support this, this feature is disabled by default.
-
-DOT_MULTI_TARGETS      = NO
-
-# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
-# generate a legend page explaining the meaning of the various boxes and
-# arrows in the dot generated graphs.
-
-GENERATE_LEGEND        = YES
-
-# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
-# remove the intermediate dot files that are used to generate
-# the various graphs.
-
-DOT_CLEANUP            = YES
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to the search engine
-#---------------------------------------------------------------------------
-
-# The SEARCHENGINE tag specifies whether or not a search engine should be
-# used. If set to NO the values of all tags below this one will be ignored.
-
-SEARCHENGINE           = NO
--- a/dmd/access.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/access.c	Thu Mar 12 20:37:27 2009 +0100
@@ -13,7 +13,7 @@
 #include <assert.h>
 
 #include "root.h"
-#include "mem.h"
+#include "rmem.h"
 
 #include "enum.h"
 #include "aggregate.h"
--- a/dmd/array.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/array.c	Thu Mar 12 20:37:27 2009 +0100
@@ -41,7 +41,7 @@
 #include "port.h"
 #include "root.h"
 #include "dchar.h"
-#include "mem.h"
+#include "rmem.h"
 
 
 /********************************* Array ****************************/
--- a/dmd/arrayop.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/arrayop.c	Thu Mar 12 20:37:27 2009 +0100
@@ -11,11 +11,7 @@
 #include <string.h>
 #include <assert.h>
 
-#if _WIN32 || IN_GCC  || IN_LLVM
-#include "mem.h"
-#else
-#include "../root/mem.h"
-#endif
+#include "rmem.h"
 
 #include "stringtable.h"
 
--- a/dmd/attrib.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/attrib.c	Thu Mar 12 20:37:27 2009 +0100
@@ -12,11 +12,7 @@
 #include <stdlib.h>
 #include <assert.h>
 
-#if _WIN32 || IN_GCC || IN_LLVM
-#include "mem.h"
-#elif POSIX
-#include "../root/mem.h"
-#endif
+#include "rmem.h"
 
 #include "init.h"
 #include "declaration.h"
@@ -151,6 +147,14 @@
 {
     //printf("AttribDeclaration::emitComment(sc = %p)\n", sc);
 
+    /* A general problem with this, illustrated by BUGZILLA 2516,
+     * is that attributes are not transmitted through to the underlying
+     * member declarations for template bodies, because semantic analysis
+     * is not done for template declaration bodies
+     * (only template instantiations).
+     * Hence, Ddoc omits attributes from template members.
+     */
+
     Array *d = include(NULL, NULL);
 
     if (d)
@@ -326,11 +330,17 @@
 	{ STCstatic,       TOKstatic },
 	{ STCextern,       TOKextern },
 	{ STCconst,        TOKconst },
+//	{ STCinvariant,    TOKimmutable },
+//	{ STCshared,       TOKshared },
 	{ STCfinal,        TOKfinal },
 	{ STCabstract,     TOKabstract },
 	{ STCsynchronized, TOKsynchronized },
 	{ STCdeprecated,   TOKdeprecated },
 	{ STCoverride,     TOKoverride },
+//	{ STCnothrow,      TOKnothrow },
+//	{ STCpure,         TOKpure },
+//	{ STCref,          TOKref },
+//	{ STCtls,          TOKtls },
     };
 
     int written = 0;
@@ -612,7 +622,7 @@
 
 	sc = sc->push();
 	sc->anonAgg = &aad;
-	sc->stc &= ~(STCauto | STCscope | STCstatic);
+	sc->stc &= ~(STCauto | STCscope | STCstatic | STCtls);
 	sc->inunion = isunion;
 	sc->offset = 0;
 	sc->flags = 0;
@@ -753,6 +763,7 @@
 
 Dsymbol *PragmaDeclaration::syntaxCopy(Dsymbol *s)
 {
+    //printf("PragmaDeclaration::syntaxCopy(%s)\n", toChars());
     PragmaDeclaration *pd;
 
     assert(!s);
@@ -1393,7 +1404,7 @@
 
 int CompileDeclaration::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
 {
-    //printf("CompileDeclaration::addMember(sc = %p)\n", sc);
+    //printf("CompileDeclaration::addMember(sc = %p, memnum = %d)\n", sc, memnum);
     this->sd = sd;
     if (memnum == 0)
     {	/* No members yet, so parse the mixin now
--- a/dmd/cast.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/cast.c	Thu Mar 12 20:37:27 2009 +0100
@@ -10,11 +10,7 @@
 #include <stdio.h>
 #include <assert.h>
 
-#if _WIN32 || IN_GCC || IN_LLVM
-#include "mem.h"
-#else
-#include "../root/mem.h"
-#endif
+#include "rmem.h"
 
 #include "expression.h"
 #include "mtype.h"
--- a/dmd/class.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/class.c	Thu Mar 12 20:37:27 2009 +0100
@@ -13,7 +13,7 @@
 #include <assert.h>
 
 #include "root.h"
-#include "mem.h"
+#include "rmem.h"
 
 #include "enum.h"
 #include "init.h"
@@ -857,7 +857,9 @@
     {
 	for (size_t i = 0; i < vtbl->dim; i++)
 	{
-	    FuncDeclaration *fd = (FuncDeclaration *)vtbl->data[i];
+	    FuncDeclaration *fd = ((Dsymbol*)vtbl->data[i])->isFuncDeclaration();
+	    if (!fd)
+		continue;		// the first entry might be a ClassInfo
 
 	    //printf("\t[%d] = %s\n", i, fd->toChars());
 	    if (ident == fd->ident &&
--- a/dmd/cond.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/cond.c	Thu Mar 12 20:37:27 2009 +0100
@@ -1,6 +1,6 @@
 
 // Compiler implementation of the D programming language
-// Copyright (c) 1999-2006 by Digital Mars
+// Copyright (c) 1999-2008 by Digital Mars
 // All Rights Reserved
 // written by Walter Bright
 // http://www.digitalmars.com
@@ -31,7 +31,7 @@
     {
 	for (int i = 0; i < ids->dim; i++)
 	{
-	    char *id = (char *)ids->data[i];
+	    const char *id = (const char *)ids->data[i];
 
 	    if (strcmp(id, ident->toChars()) == 0)
 		return TRUE;
@@ -75,7 +75,7 @@
 {
     if (!global.params.debugids)
 	global.params.debugids = new Array();
-    global.params.debugids->push((void*)ident);
+    global.params.debugids->push((void *)ident);
 }
 
 
@@ -127,13 +127,17 @@
 {
     static const char* reserved[] =
     {
-	"DigitalMars", "LLVM", "LDC", "LLVM64",
-    "X86", "X86_64", "PPC", "PPC64",
+	"DigitalMars", "X86", "X86_64",
 	"Windows", "Win32", "Win64",
-	"linux", "darwin", "Posix",
+	"linux", "Posix", "OSX", "FreeBSD",
 	"LittleEndian", "BigEndian",
 	"all",
 	"none",
+
+    // LDC
+    "LLVM", "LDC", "LLVM64",
+    "PPC", "PPC64",
+    "darwin",
     };
 
     for (unsigned i = 0; i < sizeof(reserved) / sizeof(reserved[0]); i++)
@@ -161,7 +165,7 @@
 {
     if (!global.params.versionids)
 	global.params.versionids = new Array();
-    global.params.versionids->push((void*)ident);
+    global.params.versionids->push((void *)ident);
 }
 
 
--- a/dmd/cond.h	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/cond.h	Thu Mar 12 20:37:27 2009 +0100
@@ -1,6 +1,6 @@
 
 // Compiler implementation of the D programming language
-// Copyright (c) 1999-2006 by Digital Mars
+// Copyright (c) 1999-2008 by Digital Mars
 // All Rights Reserved
 // written by Walter Bright
 // http://www.digitalmars.com
--- a/dmd/constfold.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/constfold.c	Thu Mar 12 20:37:27 2009 +0100
@@ -17,7 +17,7 @@
 #include <complex.h>
 #endif
 
-#include "mem.h"
+#include "rmem.h"
 #include "root.h"
 
 #include "mtype.h"
@@ -1172,7 +1172,7 @@
 	uinteger_t i = e2->toInteger();
 
 	if (i >= es1->len)
-        e1->error("string index %llu is out of bounds [0 .. %"PRIuSIZE"]", i, es1->len);
+	    e1->error("string index %ju is out of bounds [0 .. %zu]", i, es1->len);
 	else
 	{   unsigned value = es1->charAt(i);
 	    e = new IntegerExp(loc, value, type);
@@ -1184,8 +1184,7 @@
 	uinteger_t i = e2->toInteger();
 
 	if (i >= length)
-	{
-        e2->error("array index %llu is out of bounds %s[0 .. %llu]", i, e1->toChars(), length);
+	{   e2->error("array index %ju is out of bounds %s[0 .. %ju]", i, e1->toChars(), length);
 	}
 	else if (e1->op == TOKarrayliteral && !e1->checkSideEffect(2))
 	{   ArrayLiteralExp *ale = (ArrayLiteralExp *)e1;
@@ -1200,8 +1199,7 @@
 	if (e1->op == TOKarrayliteral && !e1->checkSideEffect(2))
 	{   ArrayLiteralExp *ale = (ArrayLiteralExp *)e1;
 	    if (i >= ale->elements->dim)
-	    {
-            e2->error("array index %llu is out of bounds %s[0 .. %u]", i, e1->toChars(), ale->elements->dim);
+	    {   e2->error("array index %ju is out of bounds %s[0 .. %u]", i, e1->toChars(), ale->elements->dim);
 	    }
 	    else
 	    {	e = (Expression *)ale->elements->data[i];
@@ -1251,7 +1249,7 @@
 	uinteger_t iupr = upr->toInteger();
 
 	if (iupr > es1->len || ilwr > iupr)
-        e1->error("string slice [%llu .. %llu] is out of bounds", ilwr, iupr);
+	    e1->error("string slice [%ju .. %ju] is out of bounds", ilwr, iupr);
 	else
 	{   integer_t value;
 	    void *s;
@@ -1278,7 +1276,7 @@
 	uinteger_t iupr = upr->toInteger();
 
 	if (iupr > es1->elements->dim || ilwr > iupr)
-        e1->error("array slice [%llu .. %llu] is out of bounds", ilwr, iupr);
+	    e1->error("array slice [%ju .. %ju] is out of bounds", ilwr, iupr);
 	else
 	{
 	    Expressions *elements = new Expressions();
--- a/dmd/dchar.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/dchar.c	Thu Mar 12 20:37:27 2009 +0100
@@ -14,7 +14,7 @@
 #include <assert.h>
 
 #include "dchar.h"
-#include "mem.h"
+#include "rmem.h"
 
 #if M_UNICODE
 
--- a/dmd/declaration.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/declaration.c	Thu Mar 12 20:37:27 2009 +0100
@@ -750,7 +750,7 @@
 	{   Argument *arg = Argument::getNth(tt->arguments, i);
 
 	    OutBuffer buf;
-        buf.printf("_%s_field_%"PRIuSIZE, ident->toChars(), i);
+	    buf.printf("_%s_field_%zu", ident->toChars(), i);
 	    buf.writeByte(0);
 	    char *name = (char *)buf.extractData();
 	    Identifier *id = new Identifier(name, TOKidentifier);
--- a/dmd/doc.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/doc.c	Thu Mar 12 20:37:27 2009 +0100
@@ -16,17 +16,7 @@
 #include <ctype.h>
 #include <assert.h>
 
-#if IN_GCC || IN_LLVM
-#include "mem.h"
-#else
-#if _WIN32
-#include "..\root\mem.h"
-#elif POSIX
-#include "../root/mem.h"
-#else
-#error "fix this"
-#endif
-#endif
+#include "rmem.h"
 
 #include "root.h"
 
--- a/dmd/dsymbol.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/dsymbol.c	Thu Mar 12 20:37:27 2009 +0100
@@ -12,7 +12,7 @@
 #include <string.h>
 #include <assert.h>
 
-#include "mem.h"
+#include "rmem.h"
 
 #include "mars.h"
 #include "dsymbol.h"
--- a/dmd/entity.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/entity.c	Thu Mar 12 20:37:27 2009 +0100
@@ -1,5 +1,5 @@
 
-// Copyright (c) 1999-2006 by Digital Mars
+// Copyright (c) 1999-2009 by Digital Mars
 // All Rights Reserved
 // written by Walter Bright
 // http://www.digitalmars.com
@@ -19,7 +19,7 @@
 
 struct NameId
 {
-    char *name;
+    const char *name;
     unsigned short value;
 };
 
--- a/dmd/expression.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/expression.c	Thu Mar 12 20:37:27 2009 +0100
@@ -1,6 +1,6 @@
 
 // Compiler implementation of the D programming language
-// Copyright (c) 1999-2008 by Digital Mars
+// Copyright (c) 1999-2009 by Digital Mars
 // All Rights Reserved
 // written by Walter Bright
 // http://www.digitalmars.com
@@ -11,12 +11,12 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <ctype.h>
+#include <math.h>
 #include <assert.h>
 #if _MSC_VER
 #include <complex>
 #else
 #endif
-#include <math.h>
 
 #if _WIN32 && __DMC__
 extern "C" char * __cdecl __locale_decpoint;
@@ -43,13 +43,7 @@
 #define integer_t dmd_integer_t
 #endif
 
-#if IN_GCC || IN_LLVM
-#include "mem.h"
-#elif _WIN32
-#include "..\root\mem.h"
-#elif POSIX
-#include "../root/mem.h"
-#endif
+#include "rmem.h"
 
 //#include "port.h"
 #include "mtype.h"
@@ -560,7 +554,7 @@
     size_t nparams = Argument::dim(tf->parameters);
 
     if (nargs > nparams && tf->varargs == 0)
-        error(loc, "expected %"PRIuSIZE" arguments, not %"PRIuSIZE, nparams, nargs);
+	error(loc, "expected %zu arguments, not %zu", nparams, nargs);
 
     n = (nargs > nparams) ? nargs : nparams;	// n = max(nargs, nparams)
 
@@ -585,7 +579,7 @@
 		{
 		    if (tf->varargs == 2 && i + 1 == nparams)
 			goto L2;
-            error(loc, "expected %"PRIuSIZE" arguments, not %"PRIuSIZE, nparams, nargs);
+		    error(loc, "expected %zu arguments, not %zu", nparams, nargs);
 		    break;
 		}
 		arg = p->defaultArg;
@@ -607,7 +601,7 @@
 		if (arg->implicitConvTo(p->type))
 		{
 		    if (nargs != nparams)
-                error(loc, "expected %"PRIuSIZE" arguments, not %"PRIuSIZE, nparams, nargs);
+		        error(loc, "expected %zu arguments, not %zu", nparams, nargs);
 		    goto L1;
 		}
 	     L2:
@@ -965,6 +959,18 @@
     va_end( ap );
 }
 
+void Expression::warning(const char *format, ...)
+{
+    if (global.params.warnings && !global.gag)
+    {
+	fprintf(stdmsg, "warning - ");
+	va_list ap;
+	va_start(ap, format);
+	::warning(loc, format, ap);
+	va_end( ap );
+    }
+}
+
 void Expression::rvalue()
 {
     if (type && type->toBasetype()->ty == Tvoid)
@@ -1319,7 +1325,8 @@
     return Expression::toChars();
 #else
     static char buffer[sizeof(value) * 3 + 1];
-    sprintf(buffer, "%lld", value);
+
+    sprintf(buffer, "%jd", value);
     return buffer;
 #endif
 }
@@ -1501,11 +1508,11 @@
 		break;
 
 	    case Tint64:
-		buf->printf("%lldL", v);
+		buf->printf("%jdL", v);
 		break;
 
 	    case Tuns64:
-		buf->printf("%lluLU", v);
+		buf->printf("%juLU", v);
 		break;
 
 	    case Tbit:
@@ -1534,17 +1541,17 @@
 	}
     }
     else if (v & 0x8000000000000000LL)
-	buf->printf("0x%llx", v);
+	buf->printf("0x%jx", v);
     else
-	buf->printf("%lld", v);
+	buf->printf("%jd", v);
 }
 
 void IntegerExp::toMangleBuffer(OutBuffer *buf)
 {
     if ((sinteger_t)value < 0)
-	buf->printf("N%lld", -value);
+	buf->printf("N%jd", -value);
     else
-	buf->printf("%lld", value);
+	buf->printf("%jd", value);
 }
 
 /******************************** RealExp **************************/
@@ -1617,8 +1624,12 @@
 
 int RealEquals(real_t x1, real_t x2)
 {
+#if __APPLE__
+    return (__inline_isnan(x1) && __inline_isnan(x2)) ||
+#else
     return // special case nans
 	   (isnan(x1) && isnan(x2)) ||
+#endif
 	   // and zero, in order to distinguish +0 from -0
 	   (x1 == 0 && x2 == 0 && 1./x1 == 1./x2) ||
 	   // otherwise just compare
@@ -1723,7 +1734,11 @@
      * 0X1.9P+2			=> 19P2
      */
 
+#if __APPLE__
+    if (__inline_isnan(value))
+#else
     if (isnan(value))
+#endif
 	buf->writestring("NAN");	// no -NAN bugs
     else
     {
@@ -3859,9 +3874,7 @@
 	type = var->type->pointerTo();
     VarDeclaration *v = var->isVarDeclaration();
     if (v)
-    {
-    v->checkNestedReference(sc, loc);
-    }
+	v->checkNestedReference(sc, loc);
     return this;
 }
 
@@ -7229,13 +7242,16 @@
 	}
 	else
 	{
-	    error("string slice [%llu .. %llu] is out of bounds", i1, i2);
+	    error("string slice [%ju .. %ju] is out of bounds", i1, i2);
 	    e = e1;
 	}
 	return e;
     }
 
-    type = t->nextOf()->arrayOf();
+    if (t->ty == Tarray)
+	type = e1->type;
+    else
+	type = t->nextOf()->arrayOf();
     return e;
 
 Lerror:
@@ -7610,9 +7626,9 @@
 	    }
 	    else
 	    {
-        error("array index [%llu] is outside array bounds [0 .. %"PRIuSIZE"]",
-            index, length);
-        e = e1;
+		error("array index [%ju] is outside array bounds [0 .. %zu]",
+			index, length);
+		e = e1;
 	    }
 	    break;
 	}
--- a/dmd/expression.h	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/expression.h	Thu Mar 12 20:37:27 2009 +0100
@@ -78,6 +78,7 @@
 void expandTuples(Expressions *exps);
 FuncDeclaration *hasThis(Scope *sc);
 Expression *fromConstInitializer(int result, Expression *e);
+int arrayExpressionCanThrow(Expressions *exps);
 
 struct Expression : Object
 {
@@ -97,6 +98,7 @@
     char *toChars();
     virtual void dump(int indent);
     void error(const char *format, ...);
+    void warning(const char *format, ...);
     virtual void rvalue();
 
     static Expression *combine(Expression *e1, Expression *e2);
--- a/dmd/func.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/func.c	Thu Mar 12 20:37:27 2009 +0100
@@ -337,8 +337,8 @@
 		    error("cannot override final function %s", fdv->toPrettyChars());
 
 #if DMDV2
-		if (!isOverride() && global.params.warnings)
-		    warning("%s: overrides base class function %s, but is not marked with 'override'", locToChars() fdv->toPrettyChars());
+		if (!isOverride())
+		    warning(loc, "overrides base class function %s, but is not marked with 'override'", fdv->toPrettyChars());
 #endif
 
 		if (fdv->toParent() == parent)
@@ -1083,9 +1083,7 @@
 		    if (offend)
 		    {   Expression *e;
 
-			if (global.params.warnings)
-			{   warning("%s: no return at end of function", locToChars());
-			}
+			warning(loc, "no return at end of function");
 
 			if (global.params.useAssert &&
 			    !global.params.useInline)
@@ -1095,7 +1093,7 @@
 			    e = new AssertExp(
 				  endloc,
 				  new IntegerExp(0),
-				  new StringExp(loc, "missing return expression")
+				  new StringExp(loc, (char *)"missing return expression")
 				);
 			}
 			else
@@ -2165,7 +2163,7 @@
 	enum TOK tok, ForeachStatement *fes)
     : FuncDeclaration(loc, endloc, NULL, STCundefined, type)
 {
-    char *id;
+    const char *id;
 
     if (fes)
 	id = "__foreachbody";
@@ -2310,7 +2308,7 @@
 
 char *CtorDeclaration::toChars()
 {
-    return "this";
+    return (char *)"this";
 }
 
 int CtorDeclaration::isVirtual()
@@ -2652,7 +2650,7 @@
     ad = parent->isAggregateDeclaration();
     if (!ad)
     {
-	error("invariants only are for struct/union/class definitions");
+	error("invariants are only for struct/union/class definitions");
 	return;
     }
     else if (ad->inv && ad->inv != this)
--- a/dmd/hdrgen.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/hdrgen.c	Thu Mar 12 20:37:27 2009 +0100
@@ -24,17 +24,7 @@
 #include <complex.h>
 #endif
 
-#if IN_GCC || IN_LLVM
-#include "mem.h"
-#else
-#if _WIN32
-#include "..\root\mem.h"
-#elif POSIX
-#include "../root/mem.h"
-#else
-#error "fix this"
-#endif
-#endif
+#include "rmem.h"
 
 #include "id.h"
 #include "init.h"
--- a/dmd/identifier.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/identifier.c	Thu Mar 12 20:37:27 2009 +0100
@@ -93,7 +93,7 @@
 {   OutBuffer buf;
 
     buf.writestring(prefix);
-    buf.printf("%"PRIuSIZE, i);
+    buf.printf("%zu", i);
 
     char *id = buf.toChars();
     buf.data = NULL;
--- a/dmd/inifile.c	Thu Mar 12 14:08:57 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,302 +0,0 @@
-
-// Copyright (c) 1999-2006 by Digital Mars
-// All Rights Reserved
-// written by Walter Bright
-// http://www.digitalmars.com
-
-
-#include	<stdio.h>
-#include	<string.h>
-#include	<stdlib.h>
-#include	<ctype.h>
-
-#if (defined (__SVR4) && defined (__sun))
-#include <alloca.h>
-#endif
-
-#include	"root.h"
-#include	"mem.h"
-
-#ifdef __MINGW32__
-#include <malloc.h>
-#endif
-
-#define LOG	0
-
-char *skipspace(const char *p);
-
-#if __GNUC__
-char *strupr(char *s)
-{
-    char *t = s;
-    
-    while (*s)
-    {
-	*s = toupper(*s);
-	s++;
-    }
-
-    return t;
-}
-#endif /* unix */
-
-/*****************************
- * Read and analyze .ini file.
- * Input:
- *	argv0	program name (argv[0])
- *	inifile	.ini file name
- */
-
-void inifile(char *argv0, const char *inifile)
-{
-    char *path;		// need path for @P macro
-    const char *filename;
-    OutBuffer buf;
-    int i;
-    int k;
-    int envsection = 0;
-
-#if LOG
-    printf("inifile(argv0 = '%s', inifile = '%s')\n", argv0, inifile);
-#endif
-    if (FileName::absolute(inifile))
-    {
-	filename = inifile;
-    }
-    else
-    {
-	/* Look for inifile in the following sequence of places:
-	 *	o current directory
-	 *	o home directory
-	 *	o directory off of argv0
-	 *	o /etc/
-	 */
-	if (FileName::exists(inifile))
-	{
-	    filename = inifile;
-	}
-	else
-	{
-	    filename = FileName::combine(getenv("HOME"), inifile);
-	    if (!FileName::exists(filename))
-	    {
-		filename = FileName::replaceName(argv0, (char*)inifile);
-		if (!FileName::exists(filename))
-		{
-#if POSIX
-
-#if 0
-#if __GLIBC__	    // This fix by Thomas Kuehne
-		    /* argv0 might be a symbolic link,
-		     * so try again looking past it to the real path
-		     */
-		    char* real_argv0 = realpath(argv0, NULL);
-		    if (real_argv0)
-		    {
-			filename = FileName::replaceName(real_argv0, inifile);
-			free(real_argv0);
-			if (FileName::exists(filename))
-			    goto Ldone;
-		    }
-#else
-#error use of glibc non-standard extension realpath(char*, NULL)
-#endif
-#endif
-
-	// old way; problem is that argv0 might not be on the PATH at all
-	// and some other instance might be found
-
-		    // Search PATH for argv0
-		    const char *p = getenv("PATH");
-		    Array *paths = FileName::splitPath(p);
-		    filename = FileName::searchPath(paths, argv0, 0);
-		    if (!filename)
-			goto Letc;		// argv0 not found on path
-		    filename = FileName::replaceName((char*)filename, (char*)inifile);
-		    if (FileName::exists(filename))
-			goto Ldone;
-#endif
-
-		    // Search /etc/ for inifile
-		Letc:
-		    filename = FileName::combine("/etc/", inifile);
-
-		Ldone:
-		    ;
-		}
-	    }
-	}
-    }
-    path = FileName::path(filename);
-#if LOG
-    printf("\tpath = '%s', filename = '%s'\n", path, filename);
-#endif
-
-    File file((char*)filename);
-
-    if (file.read())
-	return;			// error reading file
-
-    // Parse into lines
-    int eof = 0;
-    for (i = 0; i < file.len && !eof; i++)
-    {
-	int linestart = i;
-
-	for (; i < file.len; i++)
-	{
-	    switch (file.buffer[i])
-	    {
-		case '\r':
-		    break;
-
-		case '\n':
-		    // Skip if it was preceded by '\r'
-		    if (i && file.buffer[i - 1] == '\r')
-			goto Lskip;
-		    break;
-
-		case 0:
-		case 0x1A:
-		    eof = 1;
-		    break;
-
-		default:
-		    continue;
-	    }
-	    break;
-	}
-
-	// The line is file.buffer[linestart..i]
-	char *line;
-	int len;
-	char *p;
-	char *pn;
-
-	line = (char *)&file.buffer[linestart];
-	len = i - linestart;
-
-	buf.reset();
-
-	// First, expand the macros.
-	// Macros are bracketed by % characters.
-
-	for (k = 0; k < len; k++)
-	{
-	    if (line[k] == '%')
-	    {
-		int j;
-
-		for (j = k + 1; j < len; j++)
-		{
-		    if (line[j] == '%')
-		    {
-			if (j - k == 3 && memicmp(&line[k + 1], "@P", 2) == 0)
-			{
-			    // %@P% is special meaning the path to the .ini file
-			    p = path;
-			    if (!*p)
-				p = ".";
-			}
-			else
-			{   int len = j - k;
-			    char tmp[10];	// big enough most of the time
-
-			    if (len <= sizeof(tmp))
-				p = tmp;
-			    else
-				p = (char *)alloca(len);
-			    len--;
-			    memcpy(p, &line[k + 1], len);
-			    p[len] = 0;
-			    strupr(p);
-			    p = getenv(p);
-			    if (!p)
-				p = "";
-			}
-			buf.writestring(p);
-			k = j;
-			goto L1;
-		    }
-		}
-	    }
-	    buf.writeByte(line[k]);
-	 L1:
-	    ;
-	}
-
-	// Remove trailing spaces
-	while (buf.offset && isspace(buf.data[buf.offset - 1]))
-	    buf.offset--;
-
-	p = buf.toChars();
-
-	// The expanded line is in p.
-	// Now parse it for meaning.
-
-	p = skipspace(p);
-	switch (*p)
-	{
-	    case ';':		// comment
-	    case 0:		// blank
-		break;
-
-	    case '[':		// look for [Environment]
-		p = skipspace(p + 1);
-		for (pn = p; isalnum(*pn); pn++)
-		    ;
-		if (pn - p == 11 &&
-		    memicmp(p, "Environment", 11) == 0 &&
-		    *skipspace(pn) == ']'
-		   )
-		    envsection = 1;
-		else
-		    envsection = 0;
-		break;
-
-	    default:
-		if (envsection)
-		{
-		    pn = p;
-
-		    // Convert name to upper case;
-		    // remove spaces bracketing =
-		    for (p = pn; *p; p++)
-		    {   if (islower(*p))
-			    *p &= ~0x20;
-			else if (isspace(*p))
-			    memmove(p, p + 1, strlen(p));
-			else if (*p == '=')
-			{
-			    p++;
-			    while (isspace(*p))
-				memmove(p, p + 1, strlen(p));
-			    break;
-			}
-		    }
-
-		    putenv(strdup(pn));
-#if LOG
-		    printf("\tputenv('%s')\n", pn);
-		    //printf("getenv(\"TEST\") = '%s'\n",getenv("TEST"));
-#endif
-		}
-		break;
-	}
-
-     Lskip:
-	;
-    }
-}
-
-/********************
- * Skip spaces.
- */
-
-char *skipspace(const char *p)
-{
-    while (isspace(*p))
-	p++;
-    return (char *)p;
-}
-
--- a/dmd/interpret.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/interpret.c	Thu Mar 12 20:37:27 2009 +0100
@@ -12,7 +12,7 @@
 #include <stdlib.h>
 #include <assert.h>
 
-#include "mem.h"
+#include "rmem.h"
 
 #include "statement.h"
 #include "expression.h"
@@ -80,8 +80,8 @@
     if (semanticRun == 0 && scope)
     {
 	semantic3(scope);
-    if (global.errors)  // if errors compiling this function
-        return NULL;
+	if (global.errors)	// if errors compiling this function
+	    return NULL;
     }
     if (semanticRun < 2)
 	return NULL;
--- a/dmd/lexer.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/lexer.c	Thu Mar 12 20:37:27 2009 +0100
@@ -20,28 +20,21 @@
 #include <wchar.h>
 #include <stdlib.h>
 #include <assert.h>
+#include <math.h>
+
+#if _MSC_VER
+#include <time.h>
+#else
 #include <sys/time.h>
-#include <math.h>
+#endif
 
 #ifdef IN_GCC
-
 #include <time.h>
-#include "mem.h"
-
-#else
-
-#if __GNUC__
+#elif __GNUC__
 #include <time.h>
 #endif
 
-#if IN_LLVM
-#include "mem.h"
-#elif _WIN32
-#include "..\root\mem.h"
-#else
-#include "../root/mem.h"
-#endif
-#endif
+#include "rmem.h"
 
 #include "stringtable.h"
 
@@ -56,6 +49,10 @@
 extern "C" char * __cdecl __locale_decpoint;
 #endif
 
+#if _MSC_VER // workaround VC++ bug, labels and types should be in separate namespaces
+#define Lstring Lstr
+#endif
+
 extern int HtmlNamedEntity(unsigned char *p, int length);
 
 #define LS 0x2028	// UTF line separator
@@ -140,11 +137,11 @@
 	    break;
 
 	case TOKint64v:
-	    sprintf(buffer,"%lldL",(long long)int64value);
+	    sprintf(buffer,"%jdL",int64value);
 	    break;
 
 	case TOKuns64v:
-	    sprintf(buffer,"%lluUL",(unsigned long long)uns64value);
+	    sprintf(buffer,"%juUL",uns64value);
 	    break;
 
 #if IN_GCC
--- a/dmd/lstring.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/lstring.c	Thu Mar 12 20:37:27 2009 +0100
@@ -11,7 +11,7 @@
 #include <stdlib.h>
 
 #include "dchar.h"
-#include "mem.h"
+#include "rmem.h"
 #include "lstring.h"
 
 Lstring Lstring::zero = LSTRING_EMPTY();
--- a/dmd/macro.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/macro.c	Thu Mar 12 20:37:27 2009 +0100
@@ -16,19 +16,9 @@
 #include <ctype.h>
 #include <assert.h>
 
-#if IN_GCC || IN_LLVM
-#include "mem.h"
-#else
-#if _WIN32
-#include "..\root\mem.h"
-#elif POSIX
-#include "../root/mem.h"
-#else
-#error "fix this"
-#endif
-#endif
+#include "rmem.h"
+#include "root.h"
 
-#include "root.h"
 #include "macro.h"
 
 #define isidstart(c) (isalpha(c) || (c) == '_')
--- a/dmd/man.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/man.c	Thu Mar 12 20:37:27 2009 +0100
@@ -1,100 +1,102 @@
-
-// Compiler implementation of the D programming language
-// Copyright (c) 2008-2008 by Digital Mars
-// All Rights Reserved
-// written by Walter Bright
-// http://www.digitalmars.com
-// License for redistribution is by either the Artistic License
-// in artistic.txt, or the GNU General Public License in gnu.txt.
-// See the included readme.txt for details.
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <assert.h>
-
-#if _WIN32
-
-#include <windows.h>
-
-#pragma comment(lib,"shell32.lib")
-
-void browse(const char *url)
-{
-    ShellExecute(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL);
-}
-
-#endif
-
-#if linux
-
-#include	<sys/types.h>
-#include	<sys/wait.h>
-#include	<unistd.h>
-
-void browse(const char *url)
-{
-    pid_t childpid;
-    const char *args[3];
-
-    char *browser = getenv("BROWSER");
-    if (browser)
-	browser = strdup(browser);
-    else
-	browser = "firefox";
-
-    args[0] = browser;
-    args[1] = url;
-    args[2] = NULL;
-
-    childpid = fork();
-    if (childpid == 0)
-    {
-	execvp(args[0], (char**)args);
-	perror(args[0]);		// failed to execute
-	return;
-    }
-}
-
-#endif
-
-#if __APPLE__
-
-#include	<sys/types.h>
-#include	<sys/wait.h>
-#include	<unistd.h>
-
-void browse(const char *url)
-{
-    pid_t childpid;
-    const char *args[5];
-
-    char *browser = getenv("BROWSER");
-    if (browser)
-    {	browser = strdup(browser);
-	args[0] = browser;
-	args[1] = url;
-	args[2] = NULL;
-    }
-    else
-    {
-	//browser = "/Applications/Safari.app/Contents/MacOS/Safari";
-	args[0] = "open";
-	args[1] = "-a";
-	args[2] = "/Applications/Safari.app";
-	args[3] = url;
-	args[4] = NULL;
-    }
-
-    childpid = fork();
-    if (childpid == 0)
-    {
-	execvp(args[0], (char**)args);
-	perror(args[0]);		// failed to execute
-	return;
-    }
-}
-
-#endif
-
-
+
+// Compiler implementation of the D programming language
+// Copyright (c) 2008-2009 by Digital Mars
+// All Rights Reserved
+// written by Walter Bright
+// http://www.digitalmars.com
+// License for redistribution is by either the Artistic License
+// in artistic.txt, or the GNU General Public License in gnu.txt.
+// See the included readme.txt for details.
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#if _WIN32
+
+#include <windows.h>
+
+#pragma comment(lib,"shell32.lib")
+
+void browse(const char *url)
+{
+    ShellExecute(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL);
+}
+
+#endif
+
+#if linux
+
+#include	<sys/types.h>
+#include	<sys/wait.h>
+#include	<unistd.h>
+
+void browse(const char *url)
+{
+    pid_t childpid;
+    const char *args[3];
+
+    char *browser = getenv("BROWSER");
+    if (browser)
+	browser = strdup(browser);
+    else
+	browser = "x-www-browser";
+
+    args[0] = browser;
+    args[1] = url;
+    args[2] = NULL;
+
+    childpid = fork();
+    if (childpid == 0)
+    {
+	execvp(args[0], (char**)args);
+	perror(args[0]);		// failed to execute
+	return;
+    }
+}
+
+#endif
+
+#if __APPLE__
+
+#include	<sys/types.h>
+#include	<sys/wait.h>
+#include	<unistd.h>
+
+void browse(const char *url)
+{
+    pid_t childpid;
+    const char *args[5];
+
+    char *browser = getenv("BROWSER");
+    if (browser)
+    {	browser = strdup(browser);
+	args[0] = browser;
+	args[1] = url;
+	args[2] = NULL;
+    }
+    else
+    {
+	//browser = "/Applications/Safari.app/Contents/MacOS/Safari";
+	args[0] = "open";
+	args[1] = "-a";
+	args[2] = "/Applications/Safari.app";
+	args[3] = url;
+	args[4] = NULL;
+    }
+
+    childpid = fork();
+    if (childpid == 0)
+    {
+	execvp(args[0], (char**)args);
+	perror(args[0]);		// failed to execute
+	return;
+    }
+}
+
+#endif
+
+
+#if __FreeBSD__
+#endif
--- a/dmd/mangle.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/mangle.c	Thu Mar 12 20:37:27 2009 +0100
@@ -24,6 +24,10 @@
 #include "id.h"
 #include "module.h"
 
+#if TARGET_LINUX || TARGET_OSX
+char *cpp_mangle(Dsymbol *s);
+#endif
+
 char *mangle(Declaration *sthis)
 {
     OutBuffer buf;
@@ -110,8 +114,15 @@
 		case LINKc:
 		case LINKwindows:
 		case LINKpascal:
+		    return ident->toChars();
+
 		case LINKcpp:
+#if V2 && (TARGET_LINUX || TARGET_OSX)
+		    return cpp_mangle(this);
+#else
+		    // Windows C++ mangling is done by C++ back end
 		    return ident->toChars();
+#endif
 
 		case LINKdefault:
 		    error("forward declaration");
@@ -142,7 +153,7 @@
 #endif
     {
 	if (isMain())
-	    return "_Dmain";
+	    return (char *)"_Dmain";
 
     if (isWinMain() || isDllMain())
         return ident->toChars();
@@ -216,7 +227,7 @@
 	    p += 2;
 	buf.writestring(p);
     }
-    buf.printf("%"PRIuSIZE"%s", strlen(id), id);
+    buf.printf("%zu%s", strlen(id), id);
     id = buf.toChars();
     buf.data = NULL;
     //printf("TemplateInstance::mangle() %s = %s\n", toChars(), id);
@@ -243,7 +254,7 @@
 	    p += 2;
 	buf.writestring(p);
     }
-    buf.printf("%"PRIuSIZE"%s", strlen(id), id);
+    buf.printf("%zu%s", strlen(id), id);
     id = buf.toChars();
     buf.data = NULL;
     //printf("TemplateMixin::mangle() %s = %s\n", toChars(), id);
@@ -269,7 +280,7 @@
 	    p += 2;
 	buf.writestring(p);
     }
-    buf.printf("%"PRIuSIZE"%s", strlen(id), id);
+    buf.printf("%zu%s", strlen(id), id);
     id = buf.toChars();
     buf.data = NULL;
     //printf("Dsymbol::mangle() %s = %s\n", toChars(), id);
--- a/dmd/mars.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/mars.c	Thu Mar 12 20:37:27 2009 +0100
@@ -25,7 +25,7 @@
 #include <windows.h>
 #endif
 
-#include "mem.h"
+#include "rmem.h"
 #include "root.h"
 
 #include "mars.h"
@@ -105,6 +105,20 @@
     va_end( ap );
 }
 
+void warning(Loc loc, const char *format, ...)
+{
+    if (global.params.warnings && !global.gag)
+    {
+    fprintf(stdmsg, "warning - ");
+    va_list ap;
+    va_start(ap, format);
+    char* p = loc.toChars();
+    fprintf(stdmsg, "Warning: %s:", p?p:"");
+    vfprintf(stdmsg, format, ap);
+    va_end( ap );
+    }
+}
+
 void verror(Loc loc, const char *format, va_list ap)
 {
     if (!global.gag)
--- a/dmd/mars.h	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/mars.h	Thu Mar 12 20:37:27 2009 +0100
@@ -1,6 +1,6 @@
 
 // Compiler implementation of the D programming language
-// Copyright (c) 1999-2007 by Digital Mars
+// Copyright (c) 1999-2009 by Digital Mars
 // All Rights Reserved
 // written by Walter Bright
 // http://www.digitalmars.com
@@ -13,7 +13,49 @@
 
 #ifdef __DMC__
 #pragma once
-#endif /* __DMC__ */
+#endif
+
+/*
+It is very important to use version control macros correctly - the
+idea is that host and target are independent. If these are done
+correctly, cross compilers can be built.
+The host compiler and host operating system are also different,
+and are predefined by the host compiler. The ones used in
+dmd are:
+
+Macros defined by the compiler, not the code:
+
+    Compiler:
+	__DMC__		Digital Mars compiler
+	_MSC_VER	Microsoft compiler
+	__GNUC__	Gnu compiler
+
+    Host operating system:
+	_WIN32		Microsoft NT, Windows 95, Windows 98, Win32s,
+			Windows 2000, Win XP, Vista
+	_WIN64		Windows for AMD64
+	linux		Linux
+	__APPLE__	Mac OSX
+
+For the target systems, there are the target operating system and
+the target object file format:
+
+    Target operating system:
+	TARGET_WINDOS	Covers 32 bit windows and 64 bit windows
+	TARGET_LINUX	Covers 32 and 64 bit linux
+	TARGET_OSX	Covers 32 and 64 bit Mac OSX
+
+    It is expected that the compiler for each platform will be able
+    to generate 32 and 64 bit code from the same compiler binary.
+
+    Target object module format:
+	OMFOBJ		Intel Object Module Format, used on Windows
+	ELFOBJ		Elf Object Module Format, used on linux
+	MACHOBJ		Mach-O Object Module Format, used on Mac OSX
+
+    There are currently no macros for byte endianness order.
+ */
+
 
 #include <stdint.h>
 #include <stdarg.h>
@@ -35,6 +77,29 @@
 
 #define DMDV2	0	// Version 2.0 features
 #define BREAKABI 1	// 0 if not ready to break the ABI just yet
+#define STRUCTTHISREF V2	// if 'this' for struct is a reference, not a pointer
+
+/* Other targets are TARGET_LINUX and TARGET_OSX, which are
+ * set on the command line via the compiler makefile.
+ */
+
+#if _WIN32
+#define TARGET_WINDOS 1		// Windows dmd generates Windows targets
+#define OMFOBJ 1
+#endif
+
+#if TARGET_LINUX
+#ifndef ELFOBJ
+#define ELFOBJ 1
+#endif
+#endif
+
+#if TARGET_OSX
+#ifndef MACHOBJ
+#define MACHOBJ 1
+#endif
+#endif
+
 
 struct Array;
 
@@ -90,6 +155,7 @@
     bool useInline;     // inline expand functions
     bool warnings;      // enable warnings
     char Dversion;	// D version number
+    char safe;		// enforce safe memory model
 
     char *argv0;	// program name
     Array *imppath;	// array of char*'s of where to look for import modules
@@ -117,7 +183,7 @@
     Array *defaultlibnames;	// default libraries for non-debug builds
     Array *debuglibnames;	// default libraries for debug builds
 
-    char *xmlname;		// filename for XML output
+    const char *xmlname;	// filename for XML output
 
     // Hidden debug switches
     bool debuga;
@@ -156,24 +222,25 @@
 
 struct Global
 {
-    char *mars_ext;
-    char *sym_ext;
-    char *obj_ext;
+    const char *mars_ext;
+    const char *sym_ext;
+    const char *obj_ext;
 #if _WIN32
     char *obj_ext_alt;
 #endif
     char *ll_ext;
     char *bc_ext;
     char *s_ext;
-    char *doc_ext;	// for Ddoc generated files
-    char *ddoc_ext;	// for Ddoc macro include files
-    char *hdr_ext;	// for D 'header' import files
-    char *copyright;
-    char *written;
+    const char *lib_ext;
+    const char *doc_ext;	// for Ddoc generated files
+    const char *ddoc_ext;	// for Ddoc macro include files
+    const char *hdr_ext;	// for D 'header' import files
+    const char *copyright;
+    const char *written;
     Array *path;	// Array of char*'s which form the import lookup path
     Array *filePath;	// Array of char*'s which form the file import lookup path
     int structalign;
-    char *version;
+    const char *version;
     char *ldc_version;
     char *llvm_version;
 
@@ -251,19 +318,6 @@
 #include "d-gcc-complex_t.h"
 #endif
 
-// taken from GDC
-// for handling printf incompatibilities
-#if __MSVCRT__
-#define PRIuSIZE "Iu"
-#define PRIxSIZE "Ix"
-#elif __MINGW32__
-#define PRIuSIZE "u"
-#define PRIxSIZE "x"
-#else
-#define PRIuSIZE "zu"
-#define PRIxSIZE "zx"
-#endif
-
 struct Module;
 
 //typedef unsigned Loc;		// file location
@@ -333,6 +387,7 @@
     MATCHexact		// exact match
 };
 
+void warning(Loc loc, const char *format, ...);
 void error(Loc loc, const char *format, ...);
 void verror(Loc loc, const char *format, va_list);
 void fatal();
--- a/dmd/mem.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/mem.c	Thu Mar 12 20:37:27 2009 +0100
@@ -7,7 +7,7 @@
 #include <cstring>
 #include <cassert>
 
-#include "mem.h"
+#include "rmem.h"
 
 #if USE_BOEHM_GC
     // I needed to perfix the dir after upgrading to gc 7.0
--- a/dmd/module.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/module.c	Thu Mar 12 20:37:27 2009 +0100
@@ -24,7 +24,7 @@
 #include "gdc_alloca.h"
 #endif
 
-#include "mem.h"
+#include "rmem.h"
 
 #include "mars.h"
 #include "module.h"
@@ -88,6 +88,7 @@
 #ifdef IN_GCC
     strictlyneedmoduleinfo = 0;
 #endif
+    selfimports = 0;
     insearch = 0;
     searchCacheIdent = NULL;
     searchCacheSymbol = NULL;
@@ -145,9 +146,9 @@
     this->doHdrGen = doHdrGen;
 }
 
-File* Module::buildFilePath(char* forcename, char* path, char* ext)
+File* Module::buildFilePath(const char* forcename, const char* path, const char* ext)
 {
-    char *argobj;
+    const char *argobj;
     if (forcename)
 	argobj = forcename;
     else
@@ -160,9 +161,9 @@
 	if (fqnNames)
 	{
 	    if(md)
-		argobj = FileName::replaceName(argobj, md->toChars());
+		argobj = FileName::replaceName((char*)argobj, md->toChars());
 	    else
-		argobj = FileName::replaceName(argobj, toChars());
+		argobj = FileName::replaceName((char*)argobj, toChars());
 
 	    // add ext, otherwise forceExt will make nested.module into nested.bc
 	    size_t len = strlen(argobj);
@@ -926,7 +927,6 @@
 	{
 	    mi->insearch = 1;
 	    int r = mi->imports(m);
-	    mi->insearch = 0;
 	    if (r)
 		return r;
 	}
@@ -934,6 +934,33 @@
     return FALSE;
 }
 
+/*************************************
+ * Return !=0 if module imports itself.
+ */
+
+int Module::selfImports()
+{
+    //printf("Module::selfImports() %s\n", toChars());
+    if (!selfimports)
+    {
+	for (int i = 0; i < amodules.dim; i++)
+	{   Module *mi = (Module *)amodules.data[i];
+	    //printf("\t[%d] %s\n", i, mi->toChars());
+	    mi->insearch = 0;
+	}
+
+	selfimports = imports(this) + 1;
+
+	for (int i = 0; i < amodules.dim; i++)
+	{   Module *mi = (Module *)amodules.data[i];
+	    //printf("\t[%d] %s\n", i, mi->toChars());
+	    mi->insearch = 0;
+	}
+    }
+    return selfimports - 1;
+}
+
+
 /* =========================== ModuleDeclaration ===================== */
 
 ModuleDeclaration::ModuleDeclaration(Array *packages, Identifier *id)
--- a/dmd/module.h	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/module.h	Thu Mar 12 20:37:27 2009 +0100
@@ -80,6 +80,9 @@
     int strictlyneedmoduleinfo;
 #endif
 
+    int selfimports;		// 0: don't know, 1: does not, 2: does
+    int selfImports();		// returns !=0 if module imports itself
+
     int insearch;
     Identifier *searchCacheIdent;
     Dsymbol *searchCacheSymbol;	// cached value of search
@@ -173,7 +176,7 @@
     // LDC
     llvm::Module* genLLVMModule(int multiobj);
     void buildTargetFiles();
-    File* buildFilePath(char* forcename, char* path, char* ext);
+    File* buildFilePath(const char* forcename, const char* path, const char* ext);
     Module *isModule() { return this; }
     
     bool llvmForceLogging;
--- a/dmd/mtype.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/mtype.c	Thu Mar 12 20:37:27 2009 +0100
@@ -1,6 +1,6 @@
 
 // Compiler implementation of the D programming language
-// Copyright (c) 1999-2008 by Digital Mars
+// Copyright (c) 1999-2009 by Digital Mars
 // All Rights Reserved
 // written by Walter Bright
 // http://www.digitalmars.com
@@ -49,7 +49,7 @@
 static double zero = 0;
 #endif
 
-#include "mem.h"
+#include "rmem.h"
 
 #include "dsymbol.h"
 #include "mtype.h"
@@ -213,6 +213,7 @@
     mangleChar[Ttypeof] = '@';
     mangleChar[Ttuple] = 'B';
     mangleChar[Tslice] = '@';
+    mangleChar[Treturn] = '@';
 
     for (i = 0; i < TMAX; i++)
     {	if (!mangleChar[i])
@@ -709,6 +710,18 @@
     va_end( ap );
 }
 
+void Type::warning(Loc loc, const char *format, ...)
+{
+    if (global.params.warnings && !global.gag)
+    {
+	fprintf(stdmsg, "warning - ");
+	va_list ap;
+	va_start(ap, format);
+	::verror(loc, format, ap);
+	va_end( ap );
+    }
+}
+
 Identifier *Type::getTypeInfoIdent(int internal)
 {
     // _init_10TypeInfo_%s
@@ -721,7 +734,7 @@
     if (internal)
     {	buf.writeByte(mangleChar[ty]);
 	if (ty == Tarray)
-	    buf.writeByte(mangleChar[next->ty]);
+	    buf.writeByte(mangleChar[((TypeArray *)this)->next->ty]);
     }
     else
 	toDecoBuffer(&buf);
@@ -746,9 +759,8 @@
 
 void Type::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps)
 {
-    Type *t;
-
-    t = semantic(loc, sc);
+    //printf("Type::resolve() %s, %d\n", toChars(), ty);
+    Type *t = semantic(loc, sc);
     *pt = t;
     *pe = NULL;
     *ps = NULL;
@@ -1873,7 +1885,7 @@
 	dim = semanticLength(sc, tbn, dim);
 
 	dim = dim->optimize(WANTvalue | WANTinterpret);
-	if (sc->parameterSpecialization && dim->op == TOKvar &&
+	if (sc && sc->parameterSpecialization && dim->op == TOKvar &&
 	    ((VarExp *)dim)->var->storage_class & STCtemplateparameter)
 	{
 	    /* It could be a template parameter N which has no value yet:
@@ -1909,7 +1921,7 @@
 	    if (n && n2 / n != d2)
 	    {
 	      Loverflow:
-		error(loc, "index %lld overflow for static array", d1);
+		error(loc, "index %jd overflow for static array", d1);
 		dim = new IntegerExp(0, 1, tsize_t);
 	    }
 	}
@@ -1923,7 +1935,7 @@
 	    uinteger_t d = dim->toUInteger();
 
 	    if (d >= tt->arguments->dim)
-	    {	error(loc, "tuple index %llu exceeds %u", d, tt->arguments->dim);
+	    {	error(loc, "tuple index %ju exceeds %u", d, tt->arguments->dim);
 		return Type::terror;
 	    }
 	    Argument *arg = (Argument *)tt->arguments->data[(size_t)d];
@@ -1944,7 +1956,7 @@
 {
     buf->writeByte(mangleChar[ty]);
     if (dim)
-	buf->printf("%llu", dim->toInteger());
+	buf->printf("%ju", dim->toInteger());
     if (next)
 	next->toDecoBuffer(buf);
 }
@@ -2636,8 +2648,7 @@
 #if LOGDEFAULTINIT
     printf("TypeReference::defaultInit() '%s'\n", toChars());
 #endif
-    Expression *e;
-    e = new NullExp(loc);
+    Expression *e = new NullExp(loc);
     e->type = this;
     return e;
 }
@@ -3719,6 +3730,7 @@
 
 Type *TypeTypeof::syntaxCopy()
 {
+    //printf("TypeTypeof::syntaxCopy() %s\n", toChars());
     TypeTypeof *t;
 
     t = new TypeTypeof(loc, exp->syntaxCopy());
@@ -3954,7 +3966,16 @@
     s = sym->symtab->lookup(ident);
     if (!s)
     {
-	return getProperty(e->loc, ident);
+	if (ident == Id::max ||
+	    ident == Id::min ||
+	    ident == Id::init ||
+	    ident == Id::stringof ||
+	    !sym->memtype
+	   )
+	{
+	    return getProperty(e->loc, ident);
+	}
+	return sym->memtype->dotExp(sc, e, ident);
     }
     m = s->isEnumMember();
     em = m->value->copy();
@@ -5038,6 +5059,7 @@
 {
     //printf("TypeTuple(this = %p)\n", this);
     this->arguments = arguments;
+    //printf("TypeTuple() %s\n", toChars());
 #ifdef DEBUG
     if (arguments)
     {
@@ -5083,6 +5105,7 @@
 Type *TypeTuple::semantic(Loc loc, Scope *sc)
 {
     //printf("TypeTuple::semantic(this = %p)\n", this);
+    //printf("TypeTuple::semantic() %s\n", toChars());
     if (!deco)
 	deco = merge()->deco;
 
@@ -5206,7 +5229,7 @@
     uinteger_t i2 = upr->toUInteger();
 
     if (!(i1 <= i2 && i2 <= tt->arguments->dim))
-    {	error(loc, "slice [%llu..%llu] is out of range of [0..%u]", i1, i2, tt->arguments->dim);
+    {	error(loc, "slice [%ju..%ju] is out of range of [0..%u]", i1, i2, tt->arguments->dim);
 	return Type::terror;
     }
 
@@ -5251,7 +5274,7 @@
 	    sc = sc->pop();
 
 	    if (!(i1 <= i2 && i2 <= td->objects->dim))
-	    {   error(loc, "slice [%llu..%llu] is out of range of [0..%u]", i1, i2, td->objects->dim);
+	    {   error(loc, "slice [%ju..%ju] is out of range of [0..%u]", i1, i2, td->objects->dim);
 		goto Ldefault;
 	    }
 
--- a/dmd/mtype.h	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/mtype.h	Thu Mar 12 20:37:27 2009 +0100
@@ -37,10 +37,12 @@
 struct TypeInfoDeclaration;
 struct Dsymbol;
 struct TemplateInstance;
+struct CppMangleState;
 enum LINK;
 
 struct TypeBasic;
 struct HdrGenState;
+struct Argument;
 
 // Back end
 #if IN_GCC
@@ -99,7 +101,7 @@
     Ttypeof,
     Ttuple,
     Tslice,
-
+    Treturn,
     TMAX
 };
 
@@ -108,13 +110,16 @@
 extern int Tsize_t;
 extern int Tptrdiff_t;
 
+
 struct Type : Object
 {
     TY ty;
-    unsigned char mod;	// modifiers (MODconst, MODinvariant)
+    unsigned char mod;	// modifiers MODxxxx
+	/* pick this order of numbers so switch statements work better
+	 */
 	#define MODconst     1	// type is const
-	#define MODinvariant 2	// type is invariant
-    Type *next;
+	#define MODinvariant 4	// type is invariant
+	#define MODshared    2	// type is shared
     char *deco;
     Type *pto;		// merged pointer to this type
     Type *rto;		// reference to this type
@@ -242,9 +247,11 @@
     virtual Type *reliesOnTident();
     virtual Expression *toExpression();
     virtual int hasPointers();
+    Type *next;
     Type *nextOf() { return next; }
 
     static void error(Loc loc, const char *format, ...);
+    static void warning(Loc loc, const char *format, ...);
 
     // For backend
     virtual unsigned totym();
--- a/dmd/opover.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/opover.c	Thu Mar 12 20:37:27 2009 +0100
@@ -18,13 +18,7 @@
 #define integer_t dmd_integer_t
 #endif
 
-#if IN_GCC || IN_LLVM
-#include "mem.h"
-#elif POSIX
-#include "../root/mem.h"
-#elif _WIN32
-#include "..\root\mem.h"
-#endif
+#include "rmem.h"
 
 //#include "port.h"
 #include "mtype.h"
@@ -276,7 +270,7 @@
 		templateResolve(&m, td, sc, loc, NULL, &args2);
 	    }
 	}
-
+	
 	lastf = m.lastf;
 
 	if (s_r)
@@ -576,7 +570,7 @@
 	    if (s)
 	    {
 		fd = s->isFuncDeclaration();
-		if (fd)
+		if (fd) 
 		    inferApplyArgTypesX(fd, arguments);
 	    }
 	    break;
--- a/dmd/optimize.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/optimize.c	Thu Mar 12 20:37:27 2009 +0100
@@ -234,7 +234,7 @@
 		TypeSArray *ts = (TypeSArray *)ve->type;
 		integer_t dim = ts->dim->toInteger();
 		if (index < 0 || index >= dim)
-		    error("array index %lld is out of bounds [0..%lld]", index, dim);
+		    error("array index %jd is out of bounds [0..%jd]", index, dim);
 		e = new SymOffExp(loc, ve->var, index * ts->next->size());
 		e->type = type;
 		return e;
@@ -421,8 +421,7 @@
 	    integer_t i2 = e2->toInteger();
 	    d_uns64 sz = e1->type->size() * 8;
 	    if (i2 < 0 || i2 > sz)
-	    {
-        error("shift assign by %lld is outside the range 0..%"PRIuSIZE, i2, sz);
+	    {   error("shift assign by %jd is outside the range 0..%zu", i2, sz);
 		e2 = new IntegerExp(0);
 	    }
 	}
@@ -517,8 +516,7 @@
 	integer_t i2 = e->e2->toInteger();
 	d_uns64 sz = e->e1->type->size() * 8;
 	if (i2 < 0 || i2 > sz)
-	{
-        error("shift by %lld is outside the range 0..%"PRIuSIZE, i2, sz);
+	{   e->error("shift by %jd is outside the range 0..%zu", i2, sz);
 	    e->e2 = new IntegerExp(0);
 	}
 	if (e->e1->isConst() == 1)
--- a/dmd/parse.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/parse.c	Thu Mar 12 20:37:27 2009 +0100
@@ -13,7 +13,7 @@
 #include <stdio.h>
 #include <assert.h>
 
-#include "mem.h"
+#include "rmem.h"
 #include "lexer.h"
 #include "parse.h"
 #include "init.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmd/rmem.h	Thu Mar 12 20:37:27 2009 +0100
@@ -0,0 +1,16 @@
+#ifndef __RMEM_H__
+#define __RMEM_H__
+
+// jam memory stuff here
+
+#include "mem.h"
+
+#if (defined (__SVR4) && defined (__sun))
+#include <alloca.h>
+#endif
+
+#ifdef __MINGW32__
+#include <malloc.h>
+#endif
+
+#endif // __RMEM_H__
--- a/dmd/root.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/root.c	Thu Mar 12 20:37:27 2009 +0100
@@ -1,5 +1,5 @@
 
-// Copyright (c) 1999-2006 by Digital Mars
+// Copyright (c) 1999-2009 by Digital Mars
 // All Rights Reserved
 // written by Walter Bright
 // www.digitalmars.com
@@ -40,7 +40,7 @@
 #include "port.h"
 #include "root.h"
 #include "dchar.h"
-#include "mem.h"
+#include "rmem.h"
 #include "mars.h"
 
 #if 0 //__SC__ //def DEBUG
@@ -376,6 +376,9 @@
 			instring ^= 1;	// toggle inside/outside of string
 			continue;
 
+#if MACINTOSH
+		    case ',':
+#endif
 #if _WIN32
 		    case ';':
 #endif
@@ -1344,7 +1347,7 @@
 void File::checkoffset(size_t offset, size_t nbytes)
 {
     if (offset > len || offset + nbytes > len)
-	error("Corrupt file '%s': offset x%"PRIxSIZE" off end of file",toChars(),offset);
+	error("Corrupt file '%s': offset x%zx off end of file",toChars(),offset);
 }
 
 char *File::toChars()
@@ -1385,14 +1388,10 @@
 
 void OutBuffer::reserve(unsigned nbytes)
 {
-  //printf("OutBuffer::reserve: size = %d, offset = %d, nbytes = %d\n", size, offset, nbytes);
+    //printf("OutBuffer::reserve: size = %d, offset = %d, nbytes = %d\n", size, offset, nbytes);
     if (size - offset < nbytes)
     {
-#if defined (__x86_64__)
-	size = (offset + nbytes) * 2+2;
-#else
 	size = (offset + nbytes) * 2;
-#endif
 	data = (unsigned char *)mem.realloc(data, size);
     }
 }
--- a/dmd/root.h	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/root.h	Thu Mar 12 20:37:27 2009 +0100
@@ -37,6 +37,7 @@
 #define TYPEDEFS
 
 #if _MSC_VER
+#include <float.h>  // for _isnan
 typedef __int64 longlong;
 typedef unsigned __int64 ulonglong;
 #else
--- a/dmd/scope.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/scope.c	Thu Mar 12 20:37:27 2009 +0100
@@ -257,10 +257,7 @@
 		    sc->enclosing &&
 		    sc->enclosing->search(loc, ident, NULL))
 		{
-            // WTF ?
-		    if (global.params.warnings)
-			fprintf(stdmsg, "warning - ");
-		    error(s->loc, "array 'length' hides other 'length' name in outer scope");
+		    warning(s->loc, "array 'length' hides other 'length' name in outer scope");
 		}
 
 		//printf("\tfound %s.%s, kind = '%s'\n", s->parent ? s->parent->toChars() : "", s->toChars(), s->kind());
--- a/dmd/statement.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/statement.c	Thu Mar 12 20:37:27 2009 +0100
@@ -1,6 +1,6 @@
 
 // Compiler implementation of the D programming language
-// Copyright (c) 1999-2008 by Digital Mars
+// Copyright (c) 1999-2009 by Digital Mars
 // All Rights Reserved
 // written by Walter Bright
 // http://www.digitalmars.com
@@ -12,7 +12,7 @@
 #include <stdlib.h>
 #include <assert.h>
 
-#include "mem.h"
+#include "rmem.h"
 
 #include "statement.h"
 #include "expression.h"
@@ -96,6 +96,18 @@
     va_end( ap );
 }
 
+void Statement::warning(const char *format, ...)
+{
+    if (global.params.warnings && !global.gag)
+    {
+	fprintf(stdmsg, "warning - ");
+	va_list ap;
+	va_start(ap, format);
+	::verror(loc, format, ap);
+	va_end( ap );
+    }
+}
+
 int Statement::hasBreak()
 {
     //printf("Statement::hasBreak()\n");
@@ -539,10 +551,7 @@
 //printf("%s\n", s->toChars());
 	    if (!(result & BEfallthru) && !s->comeFrom())
 	    {
-		if (global.params.warnings)
-		{   fprintf(stdmsg, "warning - ");
-		    s->error("statement is not reachable");
-		}
+		s->warning("statement is not reachable");
 	    }
 
 	    result &= ~BEfallthru;
@@ -1029,9 +1038,11 @@
     sc = sc->push(sym);
     if (init)
 	init = init->semantic(sc);
+#if 0
     if (!condition)
 	// Use a default value
 	condition = new IntegerExp(loc, 1, Type::tboolean);
+#endif
     sc->noctor++;
     if (condition)
     {
@@ -1096,9 +1107,9 @@
 	result &= ~BEfallthru;	// the body must do the exiting
     if (body)
     {	int r = body->blockExit();
-	if (r & BEbreak)
+	if (r & (BEbreak | BEgoto))
 	    result |= BEfallthru;
-	result |= r & ~(BEbreak | BEcontinue);
+	result |= r & ~(BEfallthru | BEbreak | BEcontinue);
     }
     if (increment && increment->canThrow())
 	result |= BEthrow;
@@ -1669,7 +1680,7 @@
 		    default:		assert(0);
 		}
 		const char *r = (op == TOKforeach_reverse) ? "R" : "";
-		int j = sprintf(fdname, "_aApply%s%.*s%" PRIuSIZE, r, 2, fntab[flag], dim);
+		int j = sprintf(fdname, "_aApply%s%.*s%zu", r, 2, fntab[flag], dim);
 		assert(j < sizeof(fdname));
 		//LDC: Build arguments.
 		Arguments* args = new Arguments;
@@ -2323,9 +2334,7 @@
     if (!sc->sw->sdefault)
     {	hasNoDefault = 1;
 
-	if (global.params.warnings)
-	{   warning("%s: switch statement has no default", loc.toChars());
-	}
+	warning("switch statement has no default");
 
 	// Generate runtime error if the default is hit
 	Statements *a = new Statements();
@@ -3930,5 +3939,3 @@
 {
     return this;
 }
-
-
--- a/dmd/statement.h	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/statement.h	Thu Mar 12 20:37:27 2009 +0100
@@ -79,7 +79,7 @@
 #endif
 struct code;
 
-/* How a statement exits
+/* How a statement exits; this is returned by blockExit()
  */
 enum BE
 {
@@ -134,6 +134,7 @@
     char *toChars();
 
     void error(const char *format, ...);
+    void warning(const char *format, ...);
     virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
     virtual TryCatchStatement *isTryCatchStatement() { return NULL; }
     virtual GotoStatement *isGotoStatement() { return NULL; }
--- a/dmd/stringtable.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/stringtable.c	Thu Mar 12 20:37:27 2009 +0100
@@ -13,7 +13,7 @@
 #include <stdlib.h>
 
 #include "root.h"
-#include "mem.h"
+#include "rmem.h"
 #include "dchar.h"
 #include "lstring.h"
 #include "stringtable.h"
--- a/dmd/struct.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/struct.c	Thu Mar 12 20:37:27 2009 +0100
@@ -1,485 +1,510 @@
-
-// Compiler implementation of the D programming language
-// Copyright (c) 1999-2006 by Digital Mars
-// All Rights Reserved
-// written by Walter Bright
-// http://www.digitalmars.com
-// License for redistribution is by either the Artistic License
-// in artistic.txt, or the GNU General Public License in gnu.txt.
-// See the included readme.txt for details.
-
-#include <stdio.h>
-#include <assert.h>
-
-#include "root.h"
-#include "aggregate.h"
-#include "scope.h"
-#include "mtype.h"
-#include "declaration.h"
-#include "module.h"
-#include "id.h"
-#include "statement.h"
-
-/********************************* AggregateDeclaration ****************************/
-
-AggregateDeclaration::AggregateDeclaration(Loc loc, Identifier *id)
-    : ScopeDsymbol(id)
-{
-    this->loc = loc;
-
-    storage_class = 0;
-    protection = PROTpublic;
-    type = NULL;
-    handle = NULL;
-    structsize = 0;		// size of struct
-    alignsize = 0;		// size of struct for alignment purposes
-    structalign = 0;		// struct member alignment in effect
-    hasUnions = 0;
-    sizeok = 0;			// size not determined yet
-    isdeprecated = 0;
-    inv = NULL;
-    aggNew = NULL;
-    aggDelete = NULL;
-
-    stag = NULL;
-    sinit = NULL;
-    scope = NULL;
-}
-
-enum PROT AggregateDeclaration::prot()
-{
-    return protection;
-}
-
-void AggregateDeclaration::semantic2(Scope *sc)
-{
-    //printf("AggregateDeclaration::semantic2(%s)\n", toChars());
-    if (scope)
-    {	error("has forward references");
-	return;
-    }
-    if (members)
-    {
-	sc = sc->push(this);
-	for (size_t i = 0; i < members->dim; i++)
-	{
-	    Dsymbol *s = (Dsymbol *)members->data[i];
-	    s->semantic2(sc);
-	}
-	sc->pop();
-    }
-}
-
-void AggregateDeclaration::semantic3(Scope *sc)
-{   int i;
-
-    //printf("AggregateDeclaration::semantic3(%s)\n", toChars());
-    if (members)
-    {
-	sc = sc->push(this);
-	for (i = 0; i < members->dim; i++)
-	{
-	    Dsymbol *s = (Dsymbol *)members->data[i];
-	    s->semantic3(sc);
-	}
-	sc->pop();
-    }
-}
-
-void AggregateDeclaration::inlineScan()
-{   int i;
-
-    //printf("AggregateDeclaration::inlineScan(%s)\n", toChars());
-    if (members)
-    {
-	for (i = 0; i < members->dim; i++)
-	{
-	    Dsymbol *s = (Dsymbol *)members->data[i];
-	    //printf("inline scan aggregate symbol '%s'\n", s->toChars());
-	    s->inlineScan();
-	}
-    }
-}
-
-unsigned AggregateDeclaration::size(Loc loc)
-{
-    //printf("AggregateDeclaration::size() = %d\n", structsize);
-    if (!members)
-	error(loc, "unknown size");
-    if (sizeok != 1)
-    {	error(loc, "no size yet for forward reference");
-	//*(char*)0=0;
-    }
-    return structsize;
-}
-
-Type *AggregateDeclaration::getType()
-{
-    return type;
-}
-
-int AggregateDeclaration::isDeprecated()
-{
-    return isdeprecated;
-}
-
-/****************************
- * Do byte or word alignment as necessary.
- * Align sizes of 0, as we may not know array sizes yet.
- */
-
-void AggregateDeclaration::alignmember(unsigned salign, unsigned size, unsigned *poffset)
-{
-    //printf("salign = %d, size = %d, offset = %d\n",salign,size,*poffset);
-    if (salign > 1)
-    {	int sa;
-
-	switch (size)
-	{   case 1:
-		break;
-	    case 2:
-	    case_2:
-		*poffset = (*poffset + 1) & ~1;	// align to word
-		break;
-	    case 3:
-	    case 4:
-		if (salign == 2)
-		    goto case_2;
-		*poffset = (*poffset + 3) & ~3;	// align to dword
-		break;
-	    default:
-		*poffset = (*poffset + size - 1) & ~(size - 1);
-		break;
-	}
-    }
-    //printf("result = %d\n",*poffset);
-}
-
-
-void AggregateDeclaration::addField(Scope *sc, VarDeclaration *v)
-{
-    unsigned memsize;		// size of member
-    unsigned memalignsize;	// size of member for alignment purposes
-    unsigned xalign;		// alignment boundaries
-
-    //printf("AggregateDeclaration::addField('%s') %s\n", v->toChars(), toChars());
-
-    // Check for forward referenced types which will fail the size() call
-    Type *t = v->type->toBasetype();
-    if (t->ty == Tstruct /*&& isStructDeclaration()*/)
-    {	TypeStruct *ts = (TypeStruct *)t;
-
-	if (ts->sym->sizeok != 1)
-	{
-	    sizeok = 2;		// cannot finish; flag as forward referenced
-	    return;
-	}
-    }
-    if (t->ty == Tident)
-    {
-	sizeok = 2;		// cannot finish; flag as forward referenced
-	return;
-    }
-
-    memsize = v->type->size(loc);
-    memalignsize = v->type->alignsize();
-    xalign = v->type->memalign(sc->structalign);
-    alignmember(xalign, memalignsize, &sc->offset);
-    v->offset = sc->offset;
-    sc->offset += memsize;
-    if (sc->offset > structsize)
-	structsize = sc->offset;
-    if (sc->structalign < memalignsize)
-	memalignsize = sc->structalign;
-    if (alignsize < memalignsize)
-	alignsize = memalignsize;
-    //printf("\talignsize = %d\n", alignsize);
-
-    v->storage_class |= STCfield;
-    //printf(" addField '%s' to '%s' at offset %d, size = %d\n", v->toChars(), toChars(), v->offset, memsize);
-    fields.push(v);
-}
-
-
-/********************************* StructDeclaration ****************************/
-
-StructDeclaration::StructDeclaration(Loc loc, Identifier *id)
-    : AggregateDeclaration(loc, id)
-{
-    zeroInit = 0;	// assume false until we do semantic processing
-
-    // For forward references
-    type = new TypeStruct(this);
-}
-
-Dsymbol *StructDeclaration::syntaxCopy(Dsymbol *s)
-{
-    StructDeclaration *sd;
-
-    if (s)
-	sd = (StructDeclaration *)s;
-    else
-	sd = new StructDeclaration(loc, ident);
-    ScopeDsymbol::syntaxCopy(sd);
-    return sd;
-}
-
-void StructDeclaration::semantic(Scope *sc)
-{   int i;
-    Scope *sc2;
-
-    //printf("+StructDeclaration::semantic(this=%p, '%s')\n", this, toChars());
-
-    //static int count; if (++count == 20) *(char*)0=0;
-
-    assert(type);
-    if (!members)			// if forward reference
-	return;
-
-    if (symtab)
-    {   if (!scope)
-            return;             // semantic() already completed
-    }
-    else
-        symtab = new DsymbolTable();
-
-    Scope *scx = NULL;
-    if (scope)
-    {   sc = scope;
-        scx = scope;            // save so we don't make redundant copies
-        scope = NULL;
-    }
-
-    parent = sc->parent;
-    handle = type->pointerTo();
-    structalign = sc->structalign;
-    protection = sc->protection;
-    if (sc->stc & STCdeprecated)
-	isdeprecated = 1;
-    assert(!isAnonymous());
-    if (sc->stc & STCabstract)
-	error("structs, unions cannot be abstract");
-
-    if (sizeok == 0)		// if not already done the addMember step
-    {
-	for (i = 0; i < members->dim; i++)
-	{
-	    Dsymbol *s = (Dsymbol *)members->data[i];
-	    //printf("adding member '%s' to '%s'\n", s->toChars(), this->toChars());
-	    s->addMember(sc, this, 1);
-	}
-    }
-
-    sizeok = 0;
-    sc2 = sc->push(this);
-    sc2->stc = 0;
-    sc2->parent = this;
-    if (isUnionDeclaration())
-	sc2->inunion = 1;
-    sc2->protection = PROTpublic;
-    sc2->explicitProtection = 0;
-
-    int members_dim = members->dim;
-    for (i = 0; i < members_dim; i++)
-    {
-	Dsymbol *s = (Dsymbol *)members->data[i];
-	s->semantic(sc2);
-	if (isUnionDeclaration())
-	    sc2->offset = 0;
-#if 0
-	if (sizeok == 2)
-	{   //printf("forward reference\n");
-	    break;
-	}
-#endif
-    }
-
-    /* The TypeInfo_Struct is expecting an opEquals and opCmp with
-     * a parameter that is a pointer to the struct. But if there
-     * isn't one, but is an opEquals or opCmp with a value, write
-     * another that is a shell around the value:
-     *	int opCmp(struct *p) { return opCmp(*p); }
-     */
-
-    TypeFunction *tfeqptr;
-    {
-	Arguments *arguments = new Arguments;
-	Argument *arg = new Argument(STCin, handle, Id::p, NULL);
-
-	arguments->push(arg);
-	tfeqptr = new TypeFunction(arguments, Type::tint32, 0, LINKd);
-	tfeqptr = (TypeFunction *)tfeqptr->semantic(0, sc);
-    }
-
-    TypeFunction *tfeq;
-    {
-	Arguments *arguments = new Arguments;
-	Argument *arg = new Argument(STCin, type, NULL, NULL);
-
-	arguments->push(arg);
-	tfeq = new TypeFunction(arguments, Type::tint32, 0, LINKd);
-	tfeq = (TypeFunction *)tfeq->semantic(0, sc);
-    }
-
-    Identifier *id = Id::eq;
-    for (int i = 0; i < 2; i++)
-    {
-	Dsymbol *s = search_function(this, id);
-	FuncDeclaration *fdx = s ? s->isFuncDeclaration() : NULL;
-	if (fdx)
-	{   FuncDeclaration *fd = fdx->overloadExactMatch(tfeqptr);
-	    if (!fd)
-	    {	fd = fdx->overloadExactMatch(tfeq);
-		if (fd)
-		{   // Create the thunk, fdptr
-		    FuncDeclaration *fdptr = new FuncDeclaration(loc, loc, fdx->ident, STCundefined, tfeqptr);
-		    Expression *e = new IdentifierExp(loc, Id::p);
-		    e = new PtrExp(loc, e);
-		    Expressions *args = new Expressions();
-		    args->push(e);
-		    e = new IdentifierExp(loc, id);
-		    e = new CallExp(loc, e, args);
-		    fdptr->fbody = new ReturnStatement(loc, e);
-		    ScopeDsymbol *s = fdx->parent->isScopeDsymbol();
-		    assert(s);
-		    s->members->push(fdptr);
-		    fdptr->addMember(sc, s, 1);
-		    fdptr->semantic(sc2);
-		}
-	    }
-	}
-
-	id = Id::cmp;
-    }
-
-
-    sc2->pop();
-
-    if (sizeok == 2)
-    {	// semantic() failed because of forward references.
-	// Unwind what we did, and defer it for later
-	fields.setDim(0);
-	structsize = 0;
-	alignsize = 0;
-	structalign = 0;
-
-	scope = scx ? scx : new Scope(*sc);
-	scope->setNoFree();
-	scope->module->addDeferredSemantic(this);
-	//printf("\tdeferring %s\n", toChars());
-	return;
-    }
-
-    // 0 sized struct's are set to 1 byte
-    if (structsize == 0)
-    {
-	structsize = 1;
-	alignsize = 1;
-    }
-
-    // Round struct size up to next alignsize boundary.
-    // This will ensure that arrays of structs will get their internals
-    // aligned properly.
-    structsize = (structsize + alignsize - 1) & ~(alignsize - 1);
-
-    sizeok = 1;
-    Module::dprogress++;
-
-    //printf("-StructDeclaration::semantic(this=%p, '%s')\n", this, toChars());
-
-    // Determine if struct is all zeros or not
-    zeroInit = 1;
-    for (i = 0; i < fields.dim; i++)
-    {
-	Dsymbol *s = (Dsymbol *)fields.data[i];
-	VarDeclaration *vd = s->isVarDeclaration();
-	if (vd && !vd->isDataseg())
-	{
-	    if (vd->init)
-	    {
-		// Should examine init to see if it is really all 0's
-		zeroInit = 0;
-		break;
-	    }
-	    else
-	    {
-		if (!vd->type->isZeroInit())
-		{
-		    zeroInit = 0;
-		    break;
-		}
-	    }
-	}
-    }
-
-    /* Look for special member functions.
-     */
-    inv =    (InvariantDeclaration *)search(0, Id::classInvariant, 0);
-    aggNew =       (NewDeclaration *)search(0, Id::classNew,       0);
-    aggDelete = (DeleteDeclaration *)search(0, Id::classDelete,    0);
-
-    if (sc->func)
-    {
-	semantic2(sc);
-	semantic3(sc);
-    }
-}
-
-void StructDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
-{   int i;
-
-    buf->printf("%s ", kind());
-    if (!isAnonymous())
-	buf->writestring(toChars());
-    if (!members)
-    {
-	buf->writeByte(';');
-	buf->writenl();
-	return;
-    }
-    buf->writenl();
-    buf->writeByte('{');
-    buf->writenl();
-    for (i = 0; i < members->dim; i++)
-    {
-	Dsymbol *s = (Dsymbol *)members->data[i];
-
-	buf->writestring("    ");
-	s->toCBuffer(buf, hgs);
-    }
-    buf->writeByte('}');
-    buf->writenl();
-}
-
-
-const char *StructDeclaration::kind()
-{
-    return "struct";
-}
-
-/********************************* UnionDeclaration ****************************/
-
-UnionDeclaration::UnionDeclaration(Loc loc, Identifier *id)
-    : StructDeclaration(loc, id)
-{
-}
-
-Dsymbol *UnionDeclaration::syntaxCopy(Dsymbol *s)
-{
-    UnionDeclaration *ud;
-
-    if (s)
-	ud = (UnionDeclaration *)s;
-    else
-	ud = new UnionDeclaration(loc, ident);
-    StructDeclaration::syntaxCopy(ud);
-    return ud;
-}
-
-
-const char *UnionDeclaration::kind()
-{
-    return "union";
-}
-
-
+
+// Compiler implementation of the D programming language
+// Copyright (c) 1999-2009 by Digital Mars
+// All Rights Reserved
+// written by Walter Bright
+// http://www.digitalmars.com
+// License for redistribution is by either the Artistic License
+// in artistic.txt, or the GNU General Public License in gnu.txt.
+// See the included readme.txt for details.
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "root.h"
+#include "aggregate.h"
+#include "scope.h"
+#include "mtype.h"
+#include "declaration.h"
+#include "module.h"
+#include "id.h"
+#include "statement.h"
+
+/********************************* AggregateDeclaration ****************************/
+
+AggregateDeclaration::AggregateDeclaration(Loc loc, Identifier *id)
+    : ScopeDsymbol(id)
+{
+    this->loc = loc;
+
+    storage_class = 0;
+    protection = PROTpublic;
+    type = NULL;
+    handle = NULL;
+    structsize = 0;		// size of struct
+    alignsize = 0;		// size of struct for alignment purposes
+    structalign = 0;		// struct member alignment in effect
+    hasUnions = 0;
+    sizeok = 0;			// size not determined yet
+    isdeprecated = 0;
+    inv = NULL;
+    aggNew = NULL;
+    aggDelete = NULL;
+
+    stag = NULL;
+    sinit = NULL;
+    scope = NULL;
+#if V2
+    dtor = NULL;
+
+    ctor = NULL;
+    defaultCtor = NULL;
+#endif
+}
+
+enum PROT AggregateDeclaration::prot()
+{
+    return protection;
+}
+
+void AggregateDeclaration::semantic2(Scope *sc)
+{
+    //printf("AggregateDeclaration::semantic2(%s)\n", toChars());
+    if (scope)
+    {	error("has forward references");
+	return;
+    }
+    if (members)
+    {
+	sc = sc->push(this);
+	for (size_t i = 0; i < members->dim; i++)
+	{
+	    Dsymbol *s = (Dsymbol *)members->data[i];
+	    s->semantic2(sc);
+	}
+	sc->pop();
+    }
+}
+
+void AggregateDeclaration::semantic3(Scope *sc)
+{   int i;
+
+    //printf("AggregateDeclaration::semantic3(%s)\n", toChars());
+    if (members)
+    {
+	sc = sc->push(this);
+	for (i = 0; i < members->dim; i++)
+	{
+	    Dsymbol *s = (Dsymbol *)members->data[i];
+	    s->semantic3(sc);
+	}
+	sc->pop();
+    }
+}
+
+void AggregateDeclaration::inlineScan()
+{   int i;
+
+    //printf("AggregateDeclaration::inlineScan(%s)\n", toChars());
+    if (members)
+    {
+	for (i = 0; i < members->dim; i++)
+	{
+	    Dsymbol *s = (Dsymbol *)members->data[i];
+	    //printf("inline scan aggregate symbol '%s'\n", s->toChars());
+	    s->inlineScan();
+	}
+    }
+}
+
+unsigned AggregateDeclaration::size(Loc loc)
+{
+    //printf("AggregateDeclaration::size() = %d\n", structsize);
+    if (!members)
+	error(loc, "unknown size");
+    if (sizeok != 1)
+    {	error(loc, "no size yet for forward reference");
+	//*(char*)0=0;
+    }
+    return structsize;
+}
+
+Type *AggregateDeclaration::getType()
+{
+    return type;
+}
+
+int AggregateDeclaration::isDeprecated()
+{
+    return isdeprecated;
+}
+
+/****************************
+ * Do byte or word alignment as necessary.
+ * Align sizes of 0, as we may not know array sizes yet.
+ */
+
+void AggregateDeclaration::alignmember(
+	unsigned salign,	// struct alignment that is in effect
+	unsigned size,		// alignment requirement of field
+	unsigned *poffset)
+{
+    //printf("salign = %d, size = %d, offset = %d\n",salign,size,offset);
+    if (salign > 1)
+    {
+	assert(size != 3);
+	int sa = size;
+	if (sa == 0 || salign < sa)
+	    sa = salign;
+	*poffset = (*poffset + sa - 1) & ~(sa - 1);
+    }
+    //printf("result = %d\n",offset);
+}
+
+
+void AggregateDeclaration::addField(Scope *sc, VarDeclaration *v)
+{
+    unsigned memsize;		// size of member
+    unsigned memalignsize;	// size of member for alignment purposes
+    unsigned xalign;		// alignment boundaries
+
+    //printf("AggregateDeclaration::addField('%s') %s\n", v->toChars(), toChars());
+
+    // Check for forward referenced types which will fail the size() call
+    Type *t = v->type->toBasetype();
+    if (t->ty == Tstruct /*&& isStructDeclaration()*/)
+    {	TypeStruct *ts = (TypeStruct *)t;
+#if V2
+	if (ts->sym == this)
+	{
+	    error("cannot have field %s with same struct type", v->toChars());
+	}
+#endif
+
+	if (ts->sym->sizeok != 1)
+	{
+	    sizeok = 2;		// cannot finish; flag as forward referenced
+	    return;
+	}
+    }
+    if (t->ty == Tident)
+    {
+	sizeok = 2;		// cannot finish; flag as forward referenced
+	return;
+    }
+
+    memsize = v->type->size(loc);
+    memalignsize = v->type->alignsize();
+    xalign = v->type->memalign(sc->structalign);
+    alignmember(xalign, memalignsize, &sc->offset);
+    v->offset = sc->offset;
+    sc->offset += memsize;
+    if (sc->offset > structsize)
+	structsize = sc->offset;
+    if (sc->structalign < memalignsize)
+	memalignsize = sc->structalign;
+    if (alignsize < memalignsize)
+	alignsize = memalignsize;
+    //printf("\talignsize = %d\n", alignsize);
+
+    v->storage_class |= STCfield;
+    //printf(" addField '%s' to '%s' at offset %d, size = %d\n", v->toChars(), toChars(), v->offset, memsize);
+    fields.push(v);
+}
+
+
+/********************************* StructDeclaration ****************************/
+
+StructDeclaration::StructDeclaration(Loc loc, Identifier *id)
+    : AggregateDeclaration(loc, id)
+{
+    zeroInit = 0;	// assume false until we do semantic processing
+#if V2
+    hasIdentityAssign = 0;
+    cpctor = NULL;
+    postblit = NULL;
+#endif
+
+    // For forward references
+    type = new TypeStruct(this);
+}
+
+Dsymbol *StructDeclaration::syntaxCopy(Dsymbol *s)
+{
+    StructDeclaration *sd;
+
+    if (s)
+	sd = (StructDeclaration *)s;
+    else
+	sd = new StructDeclaration(loc, ident);
+    ScopeDsymbol::syntaxCopy(sd);
+    return sd;
+}
+
+void StructDeclaration::semantic(Scope *sc)
+{   int i;
+    Scope *sc2;
+
+    //printf("+StructDeclaration::semantic(this=%p, '%s')\n", this, toChars());
+
+    //static int count; if (++count == 20) *(char*)0=0;
+
+    assert(type);
+    if (!members)			// if forward reference
+	return;
+
+    if (symtab)
+    {   if (!scope)
+            return;             // semantic() already completed
+    }
+    else
+        symtab = new DsymbolTable();
+
+    Scope *scx = NULL;
+    if (scope)
+    {   sc = scope;
+        scx = scope;            // save so we don't make redundant copies
+        scope = NULL;
+    }
+
+    parent = sc->parent;
+#if STRUCTTHISREF
+    handle = type;
+#else
+    handle = type->pointerTo();
+#endif
+    structalign = sc->structalign;
+    protection = sc->protection;
+    if (sc->stc & STCdeprecated)
+	isdeprecated = 1;
+    assert(!isAnonymous());
+    if (sc->stc & STCabstract)
+	error("structs, unions cannot be abstract");
+#if V2
+    if (storage_class & STCinvariant)
+        type = type->invariantOf();
+    else if (storage_class & STCconst)
+        type = type->constOf();
+#endif
+
+    if (sizeok == 0)		// if not already done the addMember step
+    {
+	for (i = 0; i < members->dim; i++)
+	{
+	    Dsymbol *s = (Dsymbol *)members->data[i];
+	    //printf("adding member '%s' to '%s'\n", s->toChars(), this->toChars());
+	    s->addMember(sc, this, 1);
+	}
+    }
+
+    sizeok = 0;
+    sc2 = sc->push(this);
+    sc2->stc = 0;
+    sc2->parent = this;
+    if (isUnionDeclaration())
+	sc2->inunion = 1;
+    sc2->protection = PROTpublic;
+    sc2->explicitProtection = 0;
+
+    int members_dim = members->dim;
+    for (i = 0; i < members_dim; i++)
+    {
+	Dsymbol *s = (Dsymbol *)members->data[i];
+	s->semantic(sc2);
+	if (isUnionDeclaration())
+	    sc2->offset = 0;
+#if 0
+	if (sizeok == 2)
+	{   //printf("forward reference\n");
+	    break;
+	}
+#endif
+    }
+
+    /* The TypeInfo_Struct is expecting an opEquals and opCmp with
+     * a parameter that is a pointer to the struct. But if there
+     * isn't one, but is an opEquals or opCmp with a value, write
+     * another that is a shell around the value:
+     *	int opCmp(struct *p) { return opCmp(*p); }
+     */
+
+    TypeFunction *tfeqptr;
+    {
+	Arguments *arguments = new Arguments;
+	Argument *arg = new Argument(STCin, handle, Id::p, NULL);
+
+	arguments->push(arg);
+	tfeqptr = new TypeFunction(arguments, Type::tint32, 0, LINKd);
+	tfeqptr = (TypeFunction *)tfeqptr->semantic(0, sc);
+    }
+
+    TypeFunction *tfeq;
+    {
+	Arguments *arguments = new Arguments;
+	Argument *arg = new Argument(STCin, type, NULL, NULL);
+
+	arguments->push(arg);
+	tfeq = new TypeFunction(arguments, Type::tint32, 0, LINKd);
+	tfeq = (TypeFunction *)tfeq->semantic(0, sc);
+    }
+
+    Identifier *id = Id::eq;
+    for (int i = 0; i < 2; i++)
+    {
+	Dsymbol *s = search_function(this, id);
+	FuncDeclaration *fdx = s ? s->isFuncDeclaration() : NULL;
+	if (fdx)
+	{   FuncDeclaration *fd = fdx->overloadExactMatch(tfeqptr);
+	    if (!fd)
+	    {	fd = fdx->overloadExactMatch(tfeq);
+		if (fd)
+		{   // Create the thunk, fdptr
+		    FuncDeclaration *fdptr = new FuncDeclaration(loc, loc, fdx->ident, STCundefined, tfeqptr);
+		    Expression *e = new IdentifierExp(loc, Id::p);
+		    e = new PtrExp(loc, e);
+		    Expressions *args = new Expressions();
+		    args->push(e);
+		    e = new IdentifierExp(loc, id);
+		    e = new CallExp(loc, e, args);
+		    fdptr->fbody = new ReturnStatement(loc, e);
+		    ScopeDsymbol *s = fdx->parent->isScopeDsymbol();
+		    assert(s);
+		    s->members->push(fdptr);
+		    fdptr->addMember(sc, s, 1);
+		    fdptr->semantic(sc2);
+		}
+	    }
+	}
+
+	id = Id::cmp;
+    }
+#if V2
+    dtor = buildDtor(sc2);
+    postblit = buildPostBlit(sc2);
+    cpctor = buildCpCtor(sc2);
+    buildOpAssign(sc2);
+#endif
+
+    sc2->pop();
+
+    if (sizeok == 2)
+    {	// semantic() failed because of forward references.
+	// Unwind what we did, and defer it for later
+	fields.setDim(0);
+	structsize = 0;
+	alignsize = 0;
+	structalign = 0;
+
+	scope = scx ? scx : new Scope(*sc);
+	scope->setNoFree();
+	scope->module->addDeferredSemantic(this);
+	//printf("\tdeferring %s\n", toChars());
+	return;
+    }
+
+    // 0 sized struct's are set to 1 byte
+    if (structsize == 0)
+    {
+	structsize = 1;
+	alignsize = 1;
+    }
+
+    // Round struct size up to next alignsize boundary.
+    // This will ensure that arrays of structs will get their internals
+    // aligned properly.
+    structsize = (structsize + alignsize - 1) & ~(alignsize - 1);
+
+    sizeok = 1;
+    Module::dprogress++;
+
+    //printf("-StructDeclaration::semantic(this=%p, '%s')\n", this, toChars());
+
+    // Determine if struct is all zeros or not
+    zeroInit = 1;
+    for (i = 0; i < fields.dim; i++)
+    {
+	Dsymbol *s = (Dsymbol *)fields.data[i];
+	VarDeclaration *vd = s->isVarDeclaration();
+	if (vd && !vd->isDataseg())
+	{
+	    if (vd->init)
+	    {
+		// Should examine init to see if it is really all 0's
+		zeroInit = 0;
+		break;
+	    }
+	    else
+	    {
+		if (!vd->type->isZeroInit())
+		{
+		    zeroInit = 0;
+		    break;
+		}
+	    }
+	}
+    }
+
+    /* Look for special member functions.
+     */
+#if V2
+    ctor =   (CtorDeclaration *)search(0, Id::ctor, 0);
+#endif
+    inv =    (InvariantDeclaration *)search(0, Id::classInvariant, 0);
+    aggNew =       (NewDeclaration *)search(0, Id::classNew,       0);
+    aggDelete = (DeleteDeclaration *)search(0, Id::classDelete,    0);
+
+    if (sc->func)
+    {
+	semantic2(sc);
+	semantic3(sc);
+    }
+}
+
+void StructDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
+{   int i;
+
+    buf->printf("%s ", kind());
+    if (!isAnonymous())
+	buf->writestring(toChars());
+    if (!members)
+    {
+	buf->writeByte(';');
+	buf->writenl();
+	return;
+    }
+    buf->writenl();
+    buf->writeByte('{');
+    buf->writenl();
+    for (i = 0; i < members->dim; i++)
+    {
+	Dsymbol *s = (Dsymbol *)members->data[i];
+
+	buf->writestring("    ");
+	s->toCBuffer(buf, hgs);
+    }
+    buf->writeByte('}');
+    buf->writenl();
+}
+
+
+const char *StructDeclaration::kind()
+{
+    return "struct";
+}
+
+/********************************* UnionDeclaration ****************************/
+
+UnionDeclaration::UnionDeclaration(Loc loc, Identifier *id)
+    : StructDeclaration(loc, id)
+{
+}
+
+Dsymbol *UnionDeclaration::syntaxCopy(Dsymbol *s)
+{
+    UnionDeclaration *ud;
+
+    if (s)
+	ud = (UnionDeclaration *)s;
+    else
+	ud = new UnionDeclaration(loc, ident);
+    StructDeclaration::syntaxCopy(ud);
+    return ud;
+}
+
+
+const char *UnionDeclaration::kind()
+{
+    return "union";
+}
+
+
--- a/dmd/template.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/template.c	Thu Mar 12 20:37:27 2009 +0100
@@ -1,6 +1,6 @@
 
 // Compiler implementation of the D programming language
-// Copyright (c) 1999-2008 by Digital Mars
+// Copyright (c) 1999-2009 by Digital Mars
 // All Rights Reserved
 // written by Walter Bright
 // http://www.digitalmars.com
@@ -21,7 +21,7 @@
 #endif
 
 #include "root.h"
-#include "mem.h"
+#include "rmem.h"
 #include "stringtable.h"
 #include "mars.h"
 #include "identifier.h"
@@ -186,6 +186,16 @@
 	{
 	    goto Lnomatch;
 	}
+#if V2
+	VarDeclaration *v1 = s1->isVarDeclaration();
+	VarDeclaration *v2 = s2->isVarDeclaration();
+	if (v1 && v2 && v1->storage_class & v2->storage_class & STCmanifest)
+	{   ExpInitializer *ei1 = v1->init->isExpInitializer();
+	    ExpInitializer *ei2 = v2->init->isExpInitializer();
+	    if (ei1 && ei2 && !ei1->exp->equals(ei2->exp))
+		goto Lnomatch;
+	}
+#endif
     }
     else if (v1)
     {
@@ -253,6 +263,20 @@
     }
 }
 
+#if V2
+Object *objectSyntaxCopy(Object *o)
+{
+    if (!o)
+	return NULL;
+    Type *t = isType(o);
+    if (t)
+	return t->syntaxCopy();
+    Expression *e = isExpression(o);
+    if (e)
+	return e->syntaxCopy();
+    return o;
+}
+#endif
 
 
 /* ======================== TemplateDeclaration ============================= */
@@ -279,6 +303,9 @@
     this->loc = loc;
     this->parameters = parameters;
     this->origParameters = parameters;
+#if V2
+    this->constraint = constraint;
+#endif
     this->members = decldefs;
     this->overnext = NULL;
     this->overroot = NULL;
@@ -303,6 +330,11 @@
 	    p->data[i] = (void *)tp->syntaxCopy();
 	}
     }
+#if V2
+    Expression *e = NULL;
+    if (constraint)
+	e = constraint->syntaxCopy();
+#endif
     d = Dsymbol::arraySyntaxCopy(members);
     td = new TemplateDeclaration(loc, ident, p, d);
     
@@ -352,6 +384,7 @@
     paramsym->parent = sc->parent;
     Scope *paramscope = sc->push(paramsym);
     paramscope->parameterSpecialization = 1;
+    paramscope->stc = 0;
 
     if (global.params.doDocComments)
     {
@@ -512,6 +545,7 @@
     ScopeDsymbol *paramsym = new ScopeDsymbol();
     paramsym->parent = scope->parent;
     Scope *paramscope = scope->push(paramsym);
+    paramscope->stc = 0;
 
     // Attempt type deduction
     m = MATCHexact;
@@ -763,7 +797,8 @@
 	memcpy(dedargs->data, targsi->data, nargsi * sizeof(*dedargs->data));
 
 	for (i = 0; i < nargsi; i++)
-	{   TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
+	{   assert(i < parameters->dim);
+	    TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
 	    MATCH m;
 	    Declaration *sparam;
 
@@ -800,6 +835,7 @@
 	    Tuple *t = new Tuple();
 	    //printf("t = %p\n", t);
 	    dedargs->data[parameters->dim - 1] = (void *)t;
+	    declareParameter(paramscope, tp, t);
 	    goto L2;
 	}
 	else if (nfargs < nfparams - 1)
@@ -835,6 +871,7 @@
 		{   Expression *farg = (Expression *)fargs->data[fptupindex + i];
 		    t->objects.data[i] = (void *)farg->type;
 		}
+		declareParameter(paramscope, tp, t);
 		goto L2;
 	    }
 	    fptupindex = -1;
@@ -1020,7 +1057,7 @@
 		     */
 		    Declaration *sparam;
 		    dedargs->data[i] = (void *)oded;
-		    MATCH m2 = tp->matchArg(paramscope, dedargs, i, parameters, &dedtypes, &sparam);
+		    MATCH m2 = tp->matchArg(paramscope, dedargs, i, parameters, &dedtypes, &sparam, 0);
 		    //printf("m2 = %d\n", m2);
 		    if (!m2)
 			goto Lnomatch;
@@ -1077,7 +1114,7 @@
 }
 
 /**************************************************
- * Declare template parameter tp with value o.
+ * Declare template parameter tp with value o, and install it in the scope sc.
  */
 
 void TemplateDeclaration::declareParameter(Scope *sc, TemplateParameter *tp, Object *o)
@@ -1260,8 +1297,8 @@
     }
     if (td_ambig)
     {
-	error(loc, "%s matches more than one function template declaration, %s and %s",
-		toChars(), td_best->toChars(), td_ambig->toChars());
+	error(loc, "matches more than one function template declaration:\n  %s\nand:\n  %s",
+		td_best->toChars(), td_ambig->toChars());
     }
 
     /* The best match is td_best with arguments tdargs.
@@ -1794,11 +1831,20 @@
 	    Expression *e1 = isExpression(o1);
 	    Expression *e2 = isExpression(o2);
 
+	    Dsymbol *s1 = isDsymbol(o1);
+	    Dsymbol *s2 = isDsymbol(o2);
+
+	    Tuple *v1 = isTuple(o1);
+	    Tuple *v2 = isTuple(o2);
 #if 0
 	    if (t1)	printf("t1 = %s\n", t1->toChars());
 	    if (t2)	printf("t2 = %s\n", t2->toChars());
 	    if (e1)	printf("e1 = %s\n", e1->toChars());
 	    if (e2)	printf("e2 = %s\n", e2->toChars());
+	    if (s1)	printf("s1 = %s\n", s1->toChars());
+	    if (s2)	printf("s2 = %s\n", s2->toChars());
+	    if (v1)	printf("v1 = %s\n", v1->toChars());
+	    if (v2)	printf("v2 = %s\n", v2->toChars());
 #endif
 
 	    if (t1 && t2)
@@ -1845,7 +1891,33 @@
 		    dedtypes->data[j] = e1;
 		}
 	    }
-	    // BUG: Need to handle alias and tuple parameters
+	    else if (s1 && t2 && t2->ty == Tident)
+	    {
+		j = templateParameterLookup(t2, parameters);
+		if (j == -1)
+		    goto Lnomatch;
+		TemplateParameter *tp = (TemplateParameter *)parameters->data[j];
+		// BUG: use tp->matchArg() instead of the following
+		TemplateAliasParameter *ta = tp->isTemplateAliasParameter();
+		if (!ta)
+		    goto Lnomatch;
+		Dsymbol *s = (Dsymbol *)dedtypes->data[j];
+		if (s)
+		{
+		    if (!s1->equals(s))
+			goto Lnomatch;
+		}
+		else
+		{
+		    dedtypes->data[j] = s1;
+		}
+	    }
+	    else if (s1 && s2)
+	    {
+		if (!s1->equals(s2))
+		    goto Lnomatch;
+	    }
+	    // BUG: Need to handle tuple parameters
 	    else
 		goto Lnomatch;
 	}
@@ -2113,7 +2185,7 @@
 
 MATCH TemplateTypeParameter::matchArg(Scope *sc, Objects *tiargs,
 	int i, TemplateParameters *parameters, Objects *dedtypes,
-	Declaration **psparam)
+	Declaration **psparam, int flags)
 {
     //printf("TemplateTypeParameter::matchArg()\n");
     Type *t;
@@ -2357,7 +2429,7 @@
 
 MATCH TemplateAliasParameter::matchArg(Scope *sc,
 	Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes,
-	Declaration **psparam)
+	Declaration **psparam, int flags)
 {
     Dsymbol *sa;
     Object *oarg;
@@ -2569,7 +2641,7 @@
 
 MATCH TemplateValueParameter::matchArg(Scope *sc,
 	Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes,
-	Declaration **psparam)
+	Declaration **psparam, int flags)
 {
     //printf("TemplateValueParameter::matchArg()\n");
 
@@ -2766,7 +2838,7 @@
 MATCH TemplateTupleParameter::matchArg(Scope *sc,
 	Objects *tiargs, int i, TemplateParameters *parameters,
 	Objects *dedtypes,
-	Declaration **psparam)
+	Declaration **psparam, int flags)
 {
     //printf("TemplateTupleParameter::matchArg()\n");
 
@@ -3026,7 +3098,7 @@
 	}
     }
 
-    isNested(tiargs);
+    hasNestedArgs(tiargs);
 
     /* See if there is an existing TemplateInstantiation that already
      * implements the typeargs. If so, just refer to that one instead.
@@ -3101,12 +3173,16 @@
 
 	//if (scx && scx->scopesym) printf("3: scx is %s %s\n", scx->scopesym->kind(), scx->scopesym->toChars());
 	if (scx && scx->scopesym &&
-	    scx->scopesym->members && !scx->scopesym->isTemplateMixin() &&
-	    /* The following test should really be if scx->module recursively
-	     * imports itself. Because if it does, see bugzilla 2500.
+	    scx->scopesym->members && !scx->scopesym->isTemplateMixin()
+#if 1 // removed because it bloated compile times
+	    /* The problem is if A imports B, and B imports A, and both A
+	     * and B instantiate the same template, does the compilation of A
+	     * or the compilation of B do the actual instantiation?
+	     *
+	     * see bugzilla 2500.
 	     */
-	    //scx->module == tempdecl->getModule()
-	    !scx->module->imports(scx->module)
+	    && !scx->module->selfImports()
+#endif
 	   )
 	{
 	    //printf("\t1: adding to %s %s\n", scx->scopesym->kind(), scx->scopesym->toChars());
@@ -3151,7 +3227,10 @@
     scope = scope->push(argsym);
 
     // Declare each template parameter as an alias for the argument type
-    declareParameters(scope);
+    Scope *paramscope = scope->push();
+    paramscope->stc = 0;
+    declareParameters(paramscope);
+    paramscope->pop();
 
     // Add members of template instance to template instance symbol table
 //    parent = scope->scopesym;
@@ -3620,9 +3699,9 @@
  * generation of the TemplateDeclaration.
  */
 
-int TemplateInstance::isNested(Objects *args)
+int TemplateInstance::hasNestedArgs(Objects *args)
 {   int nested = 0;
-    //printf("TemplateInstance::isNested('%s')\n", tempdecl->ident->toChars());
+    //printf("TemplateInstance::hasNestedArgs('%s')\n", tempdecl->ident->toChars());
 
     /* A nested instance happens when an argument references a local
      * symbol that is on the stack.
@@ -3691,7 +3770,7 @@
 	}
 	else if (va)
 	{
-	    nested |= isNested(&va->objects);
+	    nested |= hasNestedArgs(&va->objects);
 	}
     }
     return nested;
@@ -3710,7 +3789,7 @@
 
     //printf("TemplateInstance::genIdent('%s')\n", tempdecl->ident->toChars());
     id = tempdecl->ident->toChars();
-    buf.printf("__T%"PRIuSIZE"%s", strlen(id), id);
+    buf.printf("__T%zu%s", strlen(id), id);
     args = tiargs;
     for (int i = 0; i < args->dim; i++)
     {   Object *o = (Object *)args->data[i];
@@ -3777,7 +3856,7 @@
 	    else
 	    {
 		char *p = sa->mangle();
-        buf.printf("%"PRIuSIZE"%s", strlen(p), p);
+		buf.printf("%zu%s", strlen(p), p);
 	    }
 	}
 	else if (va)
--- a/dmd/template.h	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/template.h	Thu Mar 12 20:37:27 2009 +0100
@@ -1,6 +1,6 @@
 
 // Compiler implementation of the D programming language
-// Copyright (c) 1999-2008 by Digital Mars
+// Copyright (c) 1999-2009 by Digital Mars
 // All Rights Reserved
 // written by Walter Bright
 // http://www.digitalmars.com
@@ -137,7 +137,7 @@
 
     /* Match actual argument against parameter.
      */
-    virtual MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam) = 0;
+    virtual MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam, int flags = 0) = 0;
 
     /* Create dummy argument based on parameter.
      */
@@ -163,7 +163,7 @@
     Object *specialization();
     Object *defaultArg(Loc loc, Scope *sc);
     int overloadMatch(TemplateParameter *);
-    MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
+    MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam, int flags);
     void *dummyArg();
 };
 
@@ -207,7 +207,7 @@
     Object *specialization();
     Object *defaultArg(Loc loc, Scope *sc);
     int overloadMatch(TemplateParameter *);
-    MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
+    MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam, int flags);
     void *dummyArg();
 };
 
@@ -235,7 +235,7 @@
     Object *specialization();
     Object *defaultArg(Loc loc, Scope *sc);
     int overloadMatch(TemplateParameter *);
-    MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
+    MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam, int flags);
     void *dummyArg();
 };
 
@@ -256,7 +256,7 @@
     Object *specialization();
     Object *defaultArg(Loc loc, Scope *sc);
     int overloadMatch(TemplateParameter *);
-    MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
+    MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam, int flags);
     void *dummyArg();
 };
 
@@ -318,7 +318,7 @@
     TemplateDeclaration *findTemplateDeclaration(Scope *sc);
     TemplateDeclaration *findBestMatch(Scope *sc);
     void declareParameters(Scope *sc);
-    int isNested(Objects *tiargs);
+    int hasNestedArgs(Objects *tiargs);
     Identifier *genIdent();
 
     TemplateInstance *isTemplateInstance() { return this; }
--- a/dmd/total.h	Thu Mar 12 14:08:57 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-
-// Compiler implementation of the D programming language
-// Copyright (c) 1999-2006 by Digital Mars
-// All Rights Reserved
-// written by Walter Bright
-// http://www.digitalmars.com
-// License for redistribution is by either the Artistic License
-// in artistic.txt, or the GNU General Public License in gnu.txt.
-// See the included readme.txt for details.
-
-#ifndef DMD_TOTAL_H
-#define DMD_TOTAL_H
-
-#ifdef __DMC__
-#pragma once
-#endif /* __DMC__ */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <wchar.h>
-
-#include "root.h"
-#include "stringtable.h"
-
-#include "arraytypes.h"
-#include "mars.h"
-#include "lexer.h"
-#include "parse.h"
-#include "identifier.h"
-#include "enum.h"
-#include "aggregate.h"
-#include "mtype.h"
-#include "expression.h"
-#include "declaration.h"
-#include "statement.h"
-#include "scope.h"
-#include "import.h"
-#include "module.h"
-#include "id.h"
-#include "cond.h"
-#include "version.h"
-
-#endif /* DMD_TOTAL_H */
--- a/gen/asmstmt.cpp	Thu Mar 12 14:08:57 2009 +0100
+++ b/gen/asmstmt.cpp	Thu Mar 12 20:37:27 2009 +0100
@@ -469,7 +469,7 @@
         needle = prefix + digits[i] + suffix;
         size_t pos = insnt.find(needle);
         if(std::string::npos != pos)
-            sprintf(buf, "%" PRIuSIZE, idx++);
+            sprintf(buf, "%lu", idx++);
         while(std::string::npos != (pos = insnt.find(needle)))
             insnt.replace(pos, needle.size(), buf);
     }
@@ -494,7 +494,7 @@
         needle = prefix + digits[i] + suffix;
         size_t pos = insnt.find(needle);
         if(std::string::npos != pos)
-            sprintf(buf, "%" PRIuSIZE, idx++);
+            sprintf(buf, "%lu", idx++);
         while(std::string::npos != (pos = insnt.find(needle)))
             insnt.replace(pos, needle.size(), buf);
     }
--- a/gen/cl_helpers.cpp	Thu Mar 12 14:08:57 2009 +0100
+++ b/gen/cl_helpers.cpp	Thu Mar 12 20:37:27 2009 +0100
@@ -1,7 +1,7 @@
 #include "gen/cl_helpers.h"
 
 #include "root.h"
-#include "mem.h"
+#include "rmem.h"
 
 #include <cctype>       // isupper, tolower
 #include <algorithm>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gen/configfile.cpp	Thu Mar 12 20:37:27 2009 +0100
@@ -0,0 +1,112 @@
+#include <iostream>
+#include <string>
+#include <cassert>
+
+#include "llvm/System/Path.h"
+
+#include "libconfig.h++"
+
+#include "gen/configfile.h"
+
+#include "mars.h"
+
+namespace sys = llvm::sys;
+
+ConfigFile::ConfigFile()
+{
+    cfg = new libconfig::Config;
+}
+
+ConfigFile::~ConfigFile()
+{
+    delete cfg;
+}
+
+bool ConfigFile::read(const char* argv0, void* mainAddr, const char* filename)
+{
+
+    // try to find the config file
+
+    // 1) try the current working dir
+    sys::Path p = sys::Path::GetCurrentDirectory();
+    p.appendComponent(filename);
+
+    if (!p.exists())
+    {
+        // 2) try the user home dir
+        p = sys::Path::GetUserHomeDirectory();
+        p.appendComponent(filename);
+
+        if (!p.exists())
+        {
+            // 3) try the install-prefix/etc
+            p = sys::Path(LDC_INSTALL_PREFIX);
+            p.appendComponent(filename);
+
+            if (!p.exists())
+            {
+                // 4) try next to the executable
+                p = sys::Path::GetMainExecutable(argv0, mainAddr);
+                p.eraseComponent();
+                p.appendComponent(filename);
+                if (!p.exists())
+                {
+                    // 5) fail load cfg, users still have the DFLAGS environment var
+                    std::cerr << "Error failed to locate the configuration file: " << filename << std::endl;
+                    return false;
+                }
+            }
+        }
+    }
+
+    try
+    {
+        // read the cfg
+        cfg->readFile(p.c_str());
+
+        // make sure there's a default group
+        if (!cfg->exists("default"))
+        {
+            std::cerr << "no default settings in configuration file" << std::endl;
+            return false;
+        }
+        libconfig::Setting& root = cfg->lookup("default");
+        if (!root.isGroup())
+        {
+            std::cerr << "default is not a group" << std::endl;
+            return false;
+        }
+
+        // handle switches
+        if (root.exists("switches"))
+        {
+            libconfig::Setting& arr = cfg->lookup("default.switches");
+            int len = arr.getLength();
+            for (int i=0; i<len; i++)
+            {
+                const char* v = arr[i];
+                switches.push_back(v);
+            }
+        }
+
+    }
+    catch(libconfig::FileIOException& fioe)
+    {
+        std::cerr << "Error reading configuration file: " << filename << std::endl;
+        return false;
+    }
+    catch(libconfig::ParseException& pe)
+    {
+        std::cerr << "Error parsing configuration file: " << filename
+            << "(" << pe.getLine() << "): " << pe.getError() << std::endl;
+        return false;
+    }
+    catch(...)
+    {
+        std::cerr << "Unknown exception caught!" << std::endl;
+        return false;
+    }
+
+    return true;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gen/configfile.h	Thu Mar 12 20:37:27 2009 +0100
@@ -0,0 +1,32 @@
+#ifndef LDC_CONF_CONFIGFILE_H
+#define LDC_CONF_CONFIGFILE_H
+
+#include <vector>
+
+namespace libconfig
+{
+    class Config;
+}
+
+class ConfigFile
+{
+public:
+    typedef std::vector<const char*>    s_vector;
+    typedef s_vector::iterator          s_iterator;
+
+public:
+    ConfigFile();
+    ~ConfigFile();
+
+    bool read(const char* argv0, void* mainAddr, const char* filename);
+
+    s_iterator switches_begin()   { return switches.begin(); }
+    s_iterator switches_end()     { return switches.end(); }
+
+private:
+    libconfig::Config* cfg;
+
+    s_vector switches;
+};
+
+#endif // LDC_CONF_CONFIGFILE_H
--- a/gen/main.cpp	Thu Mar 12 14:08:57 2009 +0100
+++ b/gen/main.cpp	Thu Mar 12 20:37:27 2009 +0100
@@ -21,7 +21,7 @@
 #include <windows.h>
 #endif
 
-#include "mem.h"
+#include "rmem.h"
 #include "root.h"
 
 #include "mars.h"
@@ -39,6 +39,8 @@
 #include "gen/cl_helpers.h"
 using namespace opts;
 
+#include "gen/configfile.h"
+
 extern void getenv_setargv(const char *envvar, int *pargc, char** *pargv);
 extern void backend_init();
 extern void backend_term();
@@ -144,15 +146,7 @@
     VersionCondition::addPredefinedGlobalIdent("D_Version2");
 #endif
 
-
-    // read the inifile
-#if DMDV2
-    inifile(global.params.argv0, "ldc2.conf");
-#else
-    inifile(global.params.argv0, "ldc.conf");
-#endif
-
-    // merge DFLAGS into argc/argv
+    // merge DFLAGS environment variable into argc/argv
     getenv_setargv("DFLAGS", &argc, &argv);
 #if 0
     for (int i = 0; i < argc; i++)
@@ -161,9 +155,38 @@
     }
 #endif
 
+    // build complete fixed up list of command line arguments
+    std::vector<const char*> final_args;
+    final_args.reserve(argc);
+
+    // insert argc + DFLAGS
+    final_args.insert(final_args.end(), &argv[0], &argv[argc]);
+
+    // read the configuration file
+    ConfigFile cfg_file;
+
+    // just ignore errors for now, they are still printed
+#if DMDV2
+#define CFG_FILENAME "ldc2.conf"
+#else
+#define CFG_FILENAME "ldc.conf"
+#endif
+    cfg_file.read(global.params.argv0, (void*)main, CFG_FILENAME);
+#undef CFG_FILENAME
+
+    // insert config file additions to the argument list
+    final_args.insert(final_args.end(), cfg_file.switches_begin(), cfg_file.switches_end());
+
+#if 0
+    for (size_t i = 0; i < final_args.size(); ++i)
+    {
+        printf("final_args[%zu] = %s\n", i, final_args[i]);
+    }
+#endif
+
     // Handle fixed-up arguments!
     cl::SetVersionPrinter(&printVersion);
-    cl::ParseCommandLineOptions(argc, argv, "LLVM-based D Compiler\n");
+    cl::ParseCommandLineOptions(final_args.size(), (char**)&final_args[0], "LLVM-based D Compiler\n", true);
 
     global.params.optimize = (global.params.optimizeLevel >= 0);
 
--- a/gen/statements.cpp	Thu Mar 12 14:08:57 2009 +0100
+++ b/gen/statements.cpp	Thu Mar 12 20:37:27 2009 +0100
@@ -9,7 +9,6 @@
 #include "llvm/Support/CFG.h"
 
 #include "mars.h"
-#include "total.h"
 #include "init.h"
 #include "mtype.h"
 #include "hdrgen.h"
--- a/gen/toir.cpp	Thu Mar 12 14:08:57 2009 +0100
+++ b/gen/toir.cpp	Thu Mar 12 20:37:27 2009 +0100
@@ -13,13 +13,14 @@
 #include "gen/llvm.h"
 
 #include "attrib.h"
-#include "total.h"
 #include "init.h"
 #include "mtype.h"
 #include "template.h"
 #include "hdrgen.h"
 #include "port.h"
-#include "mem.h"
+#include "rmem.h"
+#include "id.h"
+#include "enum.h"
 
 #include "gen/irstate.h"
 #include "gen/logger.h"
--- a/ldc.conf.in	Thu Mar 12 14:08:57 2009 +0100
+++ b/ldc.conf.in	Thu Mar 12 20:37:27 2009 +0100
@@ -1,2 +1,17 @@
-[Environment]
-DFLAGS=-I@RUNTIME_DIR@ -I@RUNTIME_DIR@/lib/common -L-L%@P%/../lib -d-version=Tango -defaultlib=@RUNTIME_AIO@ -debuglib=@RUNTIME_AIO@
+// This configuration file uses libconfig.
+// See http://www.hyperrealm.com/libconfig/ for syntax details.
+
+// The default group is required
+default:
+{
+    // 'switches' holds array of string that are appends to the command line
+    // arguments before they are parsed.
+    // {#} is replaced with the path to the directory holding the executable
+    switches = [
+        "-I@RUNTIME_DIR@",
+        "-I@RUNTIME_DIR@/lib/common",
+        "-L-L@PROJECT_BINARY_DIR@/../lib",
+        "-d-version=Tango",
+        "-defaultlib=@RUNTIME_AIO@"
+    ];
+};