changeset 149:78bf0fe43974

merge
author Trass3r
date Tue, 14 Sep 2010 15:46:50 +0200
parents 95b3ed3cddd5 (diff) 786ea1839396 (current diff)
children a79be6756969
files dmd/Scope.d dmd/Section.d dmd/ddoc/Sections.d
diffstat 369 files changed, 8612 insertions(+), 3537 deletions(-) [+]
line wrap: on
line diff
--- a/commands.linux.txt	Tue Aug 31 18:02:48 2010 +0200
+++ b/commands.linux.txt	Tue Sep 14 15:46:50 2010 +0200
@@ -48,6 +48,7 @@
 dmd/templates/Util.d
 dmd/expression/Util.d
 dmd/expression/Add.d
+dmd/expression/Bool.d
 dmd/expression/Xor.d
 dmd/expression/Ptr.d
 dmd/expression/Min.d
@@ -78,6 +79,7 @@
 dmd/ArrayLengthExp.d
 dmd/TypeInfoConstDeclaration.d
 dmd/TypeInfoInvariantDeclaration.d
+dmd/TypeInfoWildDeclaration.d
 dmd/TypeInfoSharedDeclaration.d
 dmd/TypeInfoStructDeclaration.d
 dmd/TypeInfoInterfaceDeclaration.d
@@ -113,7 +115,7 @@
 dmd/AliasThis.d
 dmd/AlignDeclaration.d
 dmd/AnonymousAggregateDeclaration.d
-dmd/Argument.d
+dmd/Parameter.d
 dmd/FuncExp.d
 dmd/ArrayLiteralExp.d
 dmd/AssocArrayLiteralExp.d
@@ -271,6 +273,8 @@
 dmd/Param.d
 dmd/Parser.d
 dmd/PostBlitDeclaration.d
+dmd/PowExp.d
+dmd/PowAssignExp.d
 dmd/PragmaDeclaration.d
 dmd/PragmaStatement.d
 dmd/ProtDeclaration.d
@@ -298,6 +302,7 @@
 dmd/SymbolDeclaration.d
 dmd/SynchronizedStatement.d
 dmd/TOK.d
+dmd/TRUST.d
 dmd/TY.d
 dmd/TemplateAliasParameter.d
 dmd/TemplateDeclaration.d
@@ -388,3 +393,4 @@
 dmd/backend/rel.d
 dmd/backend/LIST.d
 dmd/codegen/Util.d
+dmd/codegen/linkhelper.d
\ No newline at end of file
--- a/commands.txt	Tue Aug 31 18:02:48 2010 +0200
+++ b/commands.txt	Tue Sep 14 15:46:50 2010 +0200
@@ -43,6 +43,7 @@
 dmd\templates\Util.d
 dmd\expression\Util.d
 dmd\expression\Add.d
+dmd\expression\Bool.d
 dmd\expression\Xor.d
 dmd\expression\Ptr.d
 dmd\expression\Min.d
@@ -73,6 +74,7 @@
 dmd\ArrayLengthExp.d
 dmd\TypeInfoConstDeclaration.d
 dmd\TypeInfoInvariantDeclaration.d
+dmd\TypeInfoWildDeclaration.d
 dmd\TypeInfoSharedDeclaration.d
 dmd\TypeInfoStructDeclaration.d
 dmd\TypeInfoInterfaceDeclaration.d
@@ -108,7 +110,7 @@
 dmd\AliasThis.d
 dmd\AlignDeclaration.d
 dmd\AnonymousAggregateDeclaration.d
-dmd\Argument.d
+dmd\Parameter.d
 dmd\FuncExp.d
 dmd\ArrayLiteralExp.d
 dmd\AssocArrayLiteralExp.d
@@ -266,6 +268,8 @@
 dmd\Param.d
 dmd\Parser.d
 dmd\PostBlitDeclaration.d
+dmd\PowExp.d
+dmd\PowAssignExp.d
 dmd\PragmaDeclaration.d
 dmd\PragmaStatement.d
 dmd\ProtDeclaration.d
@@ -293,6 +297,7 @@
 dmd\SymbolDeclaration.d
 dmd\SynchronizedStatement.d
 dmd\TOK.d
+dmd\TRUST.d
 dmd\TY.d
 dmd\TemplateAliasParameter.d
 dmd\TemplateDeclaration.d
@@ -383,4 +388,5 @@
 dmd\backend\iasm.d
 dmd\backend\rel.d
 dmd\backend\LIST.d
-dmd\codegen\Util.d
\ No newline at end of file
+dmd\codegen\Util.d
+dmd\codegen\linkhelper.d
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ddmd.sln	Tue Sep 14 15:46:50 2010 +0200
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{002A2DE9-8BB6-484D-9802-7E4AD4084715}") = "ddmd", "ddmd.visualdproj", "{C58DB54F-7447-4ADC-80C0-7DD2392E5F28}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{C58DB54F-7447-4ADC-80C0-7DD2392E5F28}.Debug|Win32.ActiveCfg = Debug|Win32
+		{C58DB54F-7447-4ADC-80C0-7DD2392E5F28}.Debug|Win32.Build.0 = Debug|Win32
+		{C58DB54F-7447-4ADC-80C0-7DD2392E5F28}.Release|Win32.ActiveCfg = Release|Win32
+		{C58DB54F-7447-4ADC-80C0-7DD2392E5F28}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ddmd.visualdproj	Tue Sep 14 15:46:50 2010 +0200
@@ -0,0 +1,620 @@
+<DProject>
+ <ProjectGuid>{C58DB54F-7447-4ADC-80C0-7DD2392E5F28}</ProjectGuid>
+ <Config name="Debug">
+  <obj>0</obj>
+  <link>0</link>
+  <lib>0</lib>
+  <multiobj>0</multiobj>
+  <oneobj>0</oneobj>
+  <trace>0</trace>
+  <quiet>0</quiet>
+  <verbose>0</verbose>
+  <vtls>0</vtls>
+  <symdebug>1</symdebug>
+  <optimize>0</optimize>
+  <cpu>0</cpu>
+  <isX86_64>0</isX86_64>
+  <isLinux>0</isLinux>
+  <isOSX>0</isOSX>
+  <isWindows>0</isWindows>
+  <isFreeBSD>0</isFreeBSD>
+  <isSolaris>0</isSolaris>
+  <scheduler>0</scheduler>
+  <useDeprecated>0</useDeprecated>
+  <useAssert>0</useAssert>
+  <useInvariants>0</useInvariants>
+  <useIn>0</useIn>
+  <useOut>0</useOut>
+  <useArrayBounds>0</useArrayBounds>
+  <noboundscheck>0</noboundscheck>
+  <useSwitchError>0</useSwitchError>
+  <useUnitTests>1</useUnitTests>
+  <useInline>0</useInline>
+  <release>0</release>
+  <preservePaths>1</preservePaths>
+  <warnings>0</warnings>
+  <infowarnings>0</infowarnings>
+  <pic>0</pic>
+  <cov>0</cov>
+  <nofloat>0</nofloat>
+  <Dversion>2</Dversion>
+  <ignoreUnsupportedPragmas>0</ignoreUnsupportedPragmas>
+  <otherDMD>0</otherDMD>
+  <program>$(DMDInstallDir)windows\bin\dmd.exe</program>
+  <imppath />
+  <fileImppath />
+  <outdir>$(ConfigurationName)</outdir>
+  <objdir>$(OutDir)</objdir>
+  <objname />
+  <libname />
+  <doDocComments>0</doDocComments>
+  <docdir />
+  <docname />
+  <ddocfiles />
+  <doHdrGeneration>0</doHdrGeneration>
+  <hdrdir />
+  <hdrname />
+  <doXGeneration>1</doXGeneration>
+  <xfilename>$(IntDir)\$(ProjectName).json</xfilename>
+  <debuglevel>0</debuglevel>
+  <debugids />
+  <versionlevel>0</versionlevel>
+  <versionids>DMDV2 TX86 MARS _WIN32 TARGET_WINDOS OMFOBJ WindowsXP DumbClone BREAKABI SEH STRUCTTHISREF CCASTSYNTAX CARRAYDECL SNAN_DEFAULT_INIT SARRAYVALUE</versionids>
+  <dump_source>0</dump_source>
+  <mapverbosity>0</mapverbosity>
+  <createImplib>0</createImplib>
+  <defaultlibname />
+  <debuglibname />
+  <moduleDepsFile />
+  <run>0</run>
+  <runargs />
+  <runCv2pdb>1</runCv2pdb>
+  <pathCv2pdb>$(VisualDInstallDir)cv2pdb\cv2pdb.exe</pathCv2pdb>
+  <objfiles />
+  <linkswitches />
+  <libfiles>dmd.lib</libfiles>
+  <libpaths />
+  <deffile />
+  <resfile />
+  <exefile>$(OutDir)\$(ProjectName).exe</exefile>
+  <additionalOptions />
+  <preBuildCommand>dmc -c bridge\bridge.cpp</preBuildCommand>
+  <postBuildCommand />
+  <debugtarget>$(TARGETPATH)</debugtarget>
+  <debugarguments />
+  <debugworkingdir />
+  <debugattach>0</debugattach>
+  <debugremote />
+  <filesToClean>*.obj</filesToClean>
+ </Config>
+ <Config name="Release">
+  <obj>0</obj>
+  <link>0</link>
+  <lib>0</lib>
+  <multiobj>0</multiobj>
+  <oneobj>0</oneobj>
+  <trace>0</trace>
+  <quiet>0</quiet>
+  <verbose>0</verbose>
+  <vtls>0</vtls>
+  <symdebug>0</symdebug>
+  <optimize>1</optimize>
+  <cpu>0</cpu>
+  <isX86_64>0</isX86_64>
+  <isLinux>0</isLinux>
+  <isOSX>0</isOSX>
+  <isWindows>0</isWindows>
+  <isFreeBSD>0</isFreeBSD>
+  <isSolaris>0</isSolaris>
+  <scheduler>0</scheduler>
+  <useDeprecated>0</useDeprecated>
+  <useAssert>0</useAssert>
+  <useInvariants>0</useInvariants>
+  <useIn>0</useIn>
+  <useOut>0</useOut>
+  <useArrayBounds>0</useArrayBounds>
+  <noboundscheck>0</noboundscheck>
+  <useSwitchError>0</useSwitchError>
+  <useUnitTests>0</useUnitTests>
+  <useInline>1</useInline>
+  <release>1</release>
+  <preservePaths>1</preservePaths>
+  <warnings>0</warnings>
+  <infowarnings>0</infowarnings>
+  <pic>0</pic>
+  <cov>0</cov>
+  <nofloat>0</nofloat>
+  <Dversion>2</Dversion>
+  <ignoreUnsupportedPragmas>0</ignoreUnsupportedPragmas>
+  <otherDMD>0</otherDMD>
+  <program>$(DMDInstallDir)windows\bin\dmd.exe</program>
+  <imppath />
+  <fileImppath />
+  <outdir>$(ConfigurationName)</outdir>
+  <objdir>$(OutDir)</objdir>
+  <objname />
+  <libname />
+  <doDocComments>0</doDocComments>
+  <docdir />
+  <docname />
+  <ddocfiles />
+  <doHdrGeneration>0</doHdrGeneration>
+  <hdrdir />
+  <hdrname />
+  <doXGeneration>1</doXGeneration>
+  <xfilename>$(IntDir)\$(ProjectName).json</xfilename>
+  <debuglevel>0</debuglevel>
+  <debugids />
+  <versionlevel>0</versionlevel>
+  <versionids>DMDV2 TX86 MARS _WIN32 TARGET_WINDOS OMFOBJ WindowsXP DumbClone BREAKABI SEH STRUCTTHISREF CCASTSYNTAX CARRAYDECL SNAN_DEFAULT_INIT SARRAYVALUE</versionids>
+  <dump_source>0</dump_source>
+  <mapverbosity>0</mapverbosity>
+  <createImplib>0</createImplib>
+  <defaultlibname />
+  <debuglibname />
+  <moduleDepsFile />
+  <run>0</run>
+  <runargs />
+  <runCv2pdb>0</runCv2pdb>
+  <pathCv2pdb>$(VisualDInstallDir)cv2pdb\cv2pdb.exe</pathCv2pdb>
+  <objfiles />
+  <linkswitches />
+  <libfiles>dmdrelease.lib</libfiles>
+  <libpaths />
+  <deffile />
+  <resfile />
+  <exefile>$(OutDir)\$(ProjectName).exe</exefile>
+  <additionalOptions />
+  <preBuildCommand />
+  <postBuildCommand />
+  <debugtarget>$(TARGETPATH)</debugtarget>
+  <debugarguments />
+  <debugworkingdir />
+  <debugattach>0</debugattach>
+  <debugremote />
+  <filesToClean>*.obj</filesToClean>
+ </Config>
+ <Folder name="ddmd">
+  <Folder name="rt">
+   <File path="rt\memory.d" />
+  </Folder>
+  <Folder name="dbg">
+   <Folder name="image">
+    <File path="dbg\image\PE.d" />
+   </Folder>
+   <Folder name="symbol">
+    <File path="dbg\symbol\CodeView.d" />
+   </Folder>
+   <File path="dbg\CallStackInfo.d" />
+   <File path="dbg\Debug.d" />
+  </Folder>
+  <Folder name="dmd">
+   <Folder name="backend">
+    <File path="dmd\backend\BC.d" />
+    <File path="dmd\backend\block.d" />
+    <File path="dmd\backend\Blockx.d" />
+    <File path="dmd\backend\Classsym.d" />
+    <File path="dmd\backend\code.d" />
+    <File path="dmd\backend\Config.d" />
+    <File path="dmd\backend\Configv.d" />
+    <File path="dmd\backend\con_t.d" />
+    <File path="dmd\backend\cse_t.d" />
+    <File path="dmd\backend\Cstate.d" />
+    <File path="dmd\backend\DT.d" />
+    <File path="dmd\backend\dt_t.d" />
+    <File path="dmd\backend\elem.d" />
+    <File path="dmd\backend\enum_t.d" />
+    <File path="dmd\backend\F.d" />
+    <File path="dmd\backend\FL.d" />
+    <File path="dmd\backend\Funcsym.d" />
+    <File path="dmd\backend\func_t.d" />
+    <File path="dmd\backend\glue.d" />
+    <File path="dmd\backend\iasm.d" />
+    <File path="dmd\backend\immed_t.d" />
+    <File path="dmd\backend\LANG.d" />
+    <File path="dmd\backend\LINKAGE.d" />
+    <File path="dmd\backend\LIST.d" />
+    <File path="dmd\backend\mTY.d" />
+    <File path="dmd\backend\mTYman.d" />
+    <File path="dmd\backend\OPER.d" />
+    <File path="dmd\backend\PARAM.d" />
+    <File path="dmd\backend\REG.d" />
+    <File path="dmd\backend\REGMAX.d" />
+    <File path="dmd\backend\regm_t.d" />
+    <File path="dmd\backend\rel.d" />
+    <File path="dmd\backend\RTLSYM.d" />
+    <File path="dmd\backend\SC.d" />
+    <File path="dmd\backend\SEN.d" />
+    <File path="dmd\backend\SFL.d" />
+    <File path="dmd\backend\Srcpos.d" />
+    <File path="dmd\backend\STR.d" />
+    <File path="dmd\backend\StringTab.d" />
+    <File path="dmd\backend\struct_t.d" />
+    <File path="dmd\backend\Symbol.d" />
+    <File path="dmd\backend\SYMIDX.d" />
+    <File path="dmd\backend\symtab_t.d" />
+    <File path="dmd\backend\targ_types.d" />
+    <File path="dmd\backend\template_t.d" />
+    <File path="dmd\backend\TF.d" />
+    <File path="dmd\backend\Thunk.d" />
+    <File path="dmd\backend\token_t.d" />
+    <File path="dmd\backend\TYFL.d" />
+    <File path="dmd\backend\TYM.d" />
+    <File path="dmd\backend\TYPE.d" />
+    <File path="dmd\backend\Util.d" />
+    <File path="dmd\backend\vec_t.d" />
+   </Folder>
+   <Folder name="codegen">
+    <File path="dmd\codegen\Util.d" />
+    <File path="dmd\codegen\linkhelper.d" />
+   </Folder>
+   <Folder name="condition">
+    <Folder name="util">
+     <File path="dmd\condition\util\findCondition.d" />
+    </Folder>
+   </Folder>
+   <Folder name="declaration">
+    <File path="dmd\declaration\Match.d" />
+   </Folder>
+   <Folder name="expression">
+    <Folder name="util">
+     <File path="dmd\expression\util\arrayTypeCompatible.d" />
+    </Folder>
+    <File path="dmd\expression\Add.d" />
+    <File path="dmd\expression\And.d" />
+    <File path="dmd\expression\ArrayLength.d" />
+    <File path="dmd\expression\Bool.d" />
+    <File path="dmd\expression\Cat.d" />
+    <File path="dmd\expression\Cmp.d" />
+    <File path="dmd\expression\Com.d" />
+    <File path="dmd\expression\Div.d" />
+    <File path="dmd\expression\Equal.d" />
+    <File path="dmd\expression\Identity.d" />
+    <File path="dmd\expression\Index.d" />
+    <File path="dmd\expression\Min.d" />
+    <File path="dmd\expression\Mod.d" />
+    <File path="dmd\expression\Mul.d" />
+    <File path="dmd\expression\Neg.d" />
+    <File path="dmd\expression\Not.d" />
+    <File path="dmd\expression\Or.d" />
+    <File path="dmd\expression\Ptr.d" />
+    <File path="dmd\expression\shift_optimize.d" />
+    <File path="dmd\expression\Shl.d" />
+    <File path="dmd\expression\Shr.d" />
+    <File path="dmd\expression\Slice.d" />
+    <File path="dmd\expression\Ushr.d" />
+    <File path="dmd\expression\Util.d" />
+    <File path="dmd\expression\Xor.d" />
+   </Folder>
+   <Folder name="interpret">
+    <File path="dmd\interpret\Util.d" />
+   </Folder>
+   <Folder name="templates">
+    <File path="dmd\templates\Util.d" />
+   </Folder>
+   <Folder name="type">
+    <File path="dmd\type\Util.d" />
+   </Folder>
+   <File path="dmd\AddAssignExp.d" />
+   <File path="dmd\AddExp.d" />
+   <File path="dmd\AddrExp.d" />
+   <File path="dmd\AggregateDeclaration.d" />
+   <File path="dmd\AliasDeclaration.d" />
+   <File path="dmd\AliasThis.d" />
+   <File path="dmd\AlignDeclaration.d" />
+   <File path="dmd\AndAndExp.d" />
+   <File path="dmd\AndAssignExp.d" />
+   <File path="dmd\AndExp.d" />
+   <File path="dmd\AnonDeclaration.d" />
+   <File path="dmd\AnonymousAggregateDeclaration.d" />
+   <File path="dmd\Array.d" />
+   <File path="dmd\ArrayExp.d" />
+   <File path="dmd\ArrayInitializer.d" />
+   <File path="dmd\ArrayLengthExp.d" />
+   <File path="dmd\ArrayLiteralExp.d" />
+   <File path="dmd\ArrayScopeSymbol.d" />
+   <File path="dmd\ArrayTypes.d" />
+   <File path="dmd\AsmStatement.d" />
+   <File path="dmd\AssertExp.d" />
+   <File path="dmd\AssignExp.d" />
+   <File path="dmd\AssocArrayLiteralExp.d" />
+   <File path="dmd\AttribDeclaration.d" />
+   <File path="dmd\BaseClass.d" />
+   <File path="dmd\BE.d" />
+   <File path="dmd\BinExp.d" />
+   <File path="dmd\BoolExp.d" />
+   <File path="dmd\BreakStatement.d" />
+   <File path="dmd\BUILTIN.d" />
+   <File path="dmd\CallExp.d" />
+   <File path="dmd\CaseRangeStatement.d" />
+   <File path="dmd\CaseStatement.d" />
+   <File path="dmd\Cast.d" />
+   <File path="dmd\CastExp.d" />
+   <File path="dmd\CatAssignExp.d" />
+   <File path="dmd\Catch.d" />
+   <File path="dmd\CatExp.d" />
+   <File path="dmd\ClassDeclaration.d" />
+   <File path="dmd\ClassInfoDeclaration.d" />
+   <File path="dmd\CmpExp.d" />
+   <File path="dmd\ComExp.d" />
+   <File path="dmd\CommaExp.d" />
+   <File path="dmd\CompileDeclaration.d" />
+   <File path="dmd\CompileExp.d" />
+   <File path="dmd\CompileStatement.d" />
+   <File path="dmd\Complex.d" />
+   <File path="dmd\ComplexExp.d" />
+   <File path="dmd\CompoundDeclarationStatement.d" />
+   <File path="dmd\CompoundStatement.d" />
+   <File path="dmd\CondExp.d" />
+   <File path="dmd\Condition.d" />
+   <File path="dmd\ConditionalDeclaration.d" />
+   <File path="dmd\ConditionalStatement.d" />
+   <File path="dmd\ContinueStatement.d" />
+   <File path="dmd\CppMangleState.d" />
+   <File path="dmd\CSX.d" />
+   <File path="dmd\CtorDeclaration.d" />
+   <File path="dmd\Dchar.d" />
+   <File path="dmd\DebugCondition.d" />
+   <File path="dmd\DebugSymbol.d" />
+   <File path="dmd\Declaration.d" />
+   <File path="dmd\DeclarationExp.d" />
+   <File path="dmd\DeclarationStatement.d" />
+   <File path="dmd\DefaultInitExp.d" />
+   <File path="dmd\DefaultStatement.d" />
+   <File path="dmd\DelegateExp.d" />
+   <File path="dmd\DeleteDeclaration.d" />
+   <File path="dmd\DeleteExp.d" />
+   <File path="dmd\DivAssignExp.d" />
+   <File path="dmd\DivExp.d" />
+   <File path="dmd\DocComment.d" />
+   <File path="dmd\DollarExp.d" />
+   <File path="dmd\DoStatement.d" />
+   <File path="dmd\DotExp.d" />
+   <File path="dmd\DotIdExp.d" />
+   <File path="dmd\DotTemplateExp.d" />
+   <File path="dmd\DotTemplateInstanceExp.d" />
+   <File path="dmd\DotTypeExp.d" />
+   <File path="dmd\DotVarExp.d" />
+   <File path="dmd\Dsymbol.d" />
+   <File path="dmd\DsymbolExp.d" />
+   <File path="dmd\DsymbolTable.d" />
+   <File path="dmd\DtorDeclaration.d" />
+   <File path="dmd\DVCondition.d" />
+   <File path="dmd\DYNCAST.d" />
+   <File path="dmd\EnumDeclaration.d" />
+   <File path="dmd\EnumMember.d" />
+   <File path="dmd\EnumUtils.d" />
+   <File path="dmd\EqualExp.d" />
+   <File path="dmd\ErrorExp.d" />
+   <File path="dmd\Escape.d" />
+   <File path="dmd\ExpInitializer.d" />
+   <File path="dmd\Expression.d" />
+   <File path="dmd\ExpStatement.d" />
+   <File path="dmd\File.d" />
+   <File path="dmd\FileExp.d" />
+   <File path="dmd\FileInitExp.d" />
+   <File path="dmd\FileName.d" />
+   <File path="dmd\ForeachRangeStatement.d" />
+   <File path="dmd\ForeachStatement.d" />
+   <File path="dmd\ForStatement.d" />
+   <File path="dmd\FuncAliasDeclaration.d" />
+   <File path="dmd\FuncDeclaration.d" />
+   <File path="dmd\FuncExp.d" />
+   <File path="dmd\FuncLiteralDeclaration.d" />
+   <File path="dmd\Global.d" />
+   <File path="dmd\GlobalExpressions.d" />
+   <File path="dmd\Gnuc.d" />
+   <File path="dmd\GotoCaseStatement.d" />
+   <File path="dmd\GotoDefaultStatement.d" />
+   <File path="dmd\GotoStatement.d" />
+   <File path="dmd\HaltExp.d" />
+   <File path="dmd\HdrGenState.d" />
+   <File path="dmd\Id.d" />
+   <File path="dmd\Identifier.d" />
+   <File path="dmd\IdentifierExp.d" />
+   <File path="dmd\IdentityExp.d" />
+   <File path="dmd\IfStatement.d" />
+   <File path="dmd\ILS.d" />
+   <File path="dmd\Import.d" />
+   <File path="dmd\IndexExp.d" />
+   <File path="dmd\InExp.d" />
+   <File path="dmd\Initializer.d" />
+   <File path="dmd\InlineCostState.d" />
+   <File path="dmd\InlineDoState.d" />
+   <File path="dmd\InlineScanState.d" />
+   <File path="dmd\IntegerExp.d" />
+   <File path="dmd\InterfaceDeclaration.d" />
+   <File path="dmd\InterState.d" />
+   <File path="dmd\IntRange.d" />
+   <File path="dmd\InvariantDeclaration.d" />
+   <File path="dmd\IRState.d" />
+   <File path="dmd\IsExp.d" />
+   <File path="dmd\Json.d" />
+   <File path="dmd\Keyword.d" />
+   <File path="dmd\LabelDsymbol.d" />
+   <File path="dmd\LabelStatement.d" />
+   <File path="dmd\Lexer.d" />
+   <File path="dmd\Library.d" />
+   <File path="dmd\LineInitExp.d" />
+   <File path="dmd\LINK.d" />
+   <File path="dmd\LinkDeclaration.d" />
+   <File path="dmd\Loc.d" />
+   <File path="dmd\Lstring.d" />
+   <File path="dmd\Macro.d" />
+   <File path="dmd\MATCH.d" />
+   <File path="dmd\MinAssignExp.d" />
+   <File path="dmd\MinExp.d" />
+   <File path="dmd\MOD.d" />
+   <File path="dmd\ModAssignExp.d" />
+   <File path="dmd\ModExp.d" />
+   <File path="dmd\Module.d" />
+   <File path="dmd\ModuleDeclaration.d" />
+   <File path="dmd\ModuleInfoDeclaration.d" />
+   <File path="dmd\MulAssignExp.d" />
+   <File path="dmd\MulExp.d" />
+   <File path="dmd\NegExp.d" />
+   <File path="dmd\NewAnonClassExp.d" />
+   <File path="dmd\NewDeclaration.d" />
+   <File path="dmd\NewExp.d" />
+   <File path="dmd\NotExp.d" />
+   <File path="dmd\NullExp.d" />
+   <File path="dmd\ObjModule.d" />
+   <File path="dmd\OnScopeStatement.d" />
+   <File path="dmd\Optimize.d" />
+   <File path="dmd\OrAssignExp.d" />
+   <File path="dmd\OrExp.d" />
+   <File path="dmd\OrOrExp.d" />
+   <File path="dmd\OutBuffer.d" />
+   <File path="dmd\OverExp.d" />
+   <File path="dmd\OverloadSet.d" />
+   <File path="dmd\Package.d" />
+   <File path="dmd\Param.d" />
+   <File path="dmd\Parser.d" />
+   <File path="dmd\ParseStatementFlags.d" />
+   <File path="dmd\PASS.d" />
+   <File path="dmd\PeelStatement.d" />
+   <File path="dmd\Port.d" />
+   <File path="dmd\PostBlitDeclaration.d" />
+   <File path="dmd\PostExp.d" />
+   <File path="dmd\PragmaDeclaration.d" />
+   <File path="dmd\PragmaStatement.d" />
+   <File path="dmd\PREC.d" />
+   <File path="dmd\PROT.d" />
+   <File path="dmd\ProtDeclaration.d" />
+   <File path="dmd\PtrExp.d" />
+   <File path="dmd\RealExp.d" />
+   <File path="dmd\RemoveExp.d" />
+   <File path="dmd\RET.d" />
+   <File path="dmd\ReturnStatement.d" />
+   <File path="dmd\Scope.d" />
+   <File path="dmd\ScopeDsymbol.d" />
+   <File path="dmd\ScopeExp.d" />
+   <File path="dmd\ScopeStatement.d" />
+   <File path="dmd\Section.d" />
+   <File path="dmd\ShlAssignExp.d" />
+   <File path="dmd\ShlExp.d" />
+   <File path="dmd\ShrAssignExp.d" />
+   <File path="dmd\ShrExp.d" />
+   <File path="dmd\SliceExp.d" />
+   <File path="dmd\Statement.d" />
+   <File path="dmd\StaticAssert.d" />
+   <File path="dmd\StaticAssertStatement.d" />
+   <File path="dmd\StaticCtorDeclaration.d" />
+   <File path="dmd\StaticDtorDeclaration.d" />
+   <File path="dmd\StaticIfCondition.d" />
+   <File path="dmd\StaticIfDeclaration.d" />
+   <File path="dmd\STC.d" />
+   <File path="dmd\StorageClassDeclaration.d" />
+   <File path="dmd\String.d" />
+   <File path="dmd\StringEntry.d" />
+   <File path="dmd\StringExp.d" />
+   <File path="dmd\StringTable.d" />
+   <File path="dmd\StringValue.d" />
+   <File path="dmd\StructDeclaration.d" />
+   <File path="dmd\StructInitializer.d" />
+   <File path="dmd\StructLiteralExp.d" />
+   <File path="dmd\SuperExp.d" />
+   <File path="dmd\SwitchErrorStatement.d" />
+   <File path="dmd\SwitchStatement.d" />
+   <File path="dmd\SymbolDeclaration.d" />
+   <File path="dmd\SymbolExp.d" />
+   <File path="dmd\SymOffExp.d" />
+   <File path="dmd\SynchronizedStatement.d" />
+   <File path="dmd\TemplateAliasParameter.d" />
+   <File path="dmd\TemplateDeclaration.d" />
+   <File path="dmd\TemplateExp.d" />
+   <File path="dmd\TemplateInstance.d" />
+   <File path="dmd\TemplateMixin.d" />
+   <File path="dmd\TemplateParameter.d" />
+   <File path="dmd\TemplateThisParameter.d" />
+   <File path="dmd\TemplateTupleParameter.d" />
+   <File path="dmd\TemplateTypeParameter.d" />
+   <File path="dmd\TemplateValueParameter.d" />
+   <File path="dmd\TFLAGS.d" />
+   <File path="dmd\ThisDeclaration.d" />
+   <File path="dmd\ThisExp.d" />
+   <File path="dmd\ThrowStatement.d" />
+   <File path="dmd\TOK.d" />
+   <File path="dmd\Token.d" />
+   <File path="dmd\TraitsExp.d" />
+   <File path="dmd\TryCatchStatement.d" />
+   <File path="dmd\TryFinallyStatement.d" />
+   <File path="dmd\Tuple.d" />
+   <File path="dmd\TupleDeclaration.d" />
+   <File path="dmd\TupleExp.d" />
+   <File path="dmd\TY.d" />
+   <File path="dmd\Type.d" />
+   <File path="dmd\TypeAArray.d" />
+   <File path="dmd\TypeArray.d" />
+   <File path="dmd\TypeBasic.d" />
+   <File path="dmd\TypeClass.d" />
+   <File path="dmd\TypeDArray.d" />
+   <File path="dmd\TypedefDeclaration.d" />
+   <File path="dmd\TypeDelegate.d" />
+   <File path="dmd\TypeEnum.d" />
+   <File path="dmd\TypeExp.d" />
+   <File path="dmd\TypeFunction.d" />
+   <File path="dmd\TypeIdentifier.d" />
+   <File path="dmd\TypeidExp.d" />
+   <File path="dmd\TypeInfoArrayDeclaration.d" />
+   <File path="dmd\TypeInfoAssociativeArrayDeclaration.d" />
+   <File path="dmd\TypeInfoClassDeclaration.d" />
+   <File path="dmd\TypeInfoConstDeclaration.d" />
+   <File path="dmd\TypeInfoDeclaration.d" />
+   <File path="dmd\TypeInfoDelegateDeclaration.d" />
+   <File path="dmd\TypeInfoEnumDeclaration.d" />
+   <File path="dmd\TypeInfoFunctionDeclaration.d" />
+   <File path="dmd\TypeInfoInterfaceDeclaration.d" />
+   <File path="dmd\TypeInfoInvariantDeclaration.d" />
+   <File path="dmd\TypeInfoPointerDeclaration.d" />
+   <File path="dmd\TypeInfoSharedDeclaration.d" />
+   <File path="dmd\TypeInfoStaticArrayDeclaration.d" />
+   <File path="dmd\TypeInfoStructDeclaration.d" />
+   <File path="dmd\TypeInfoTupleDeclaration.d" />
+   <File path="dmd\TypeInfoTypedefDeclaration.d" />
+   <File path="dmd\TypeInstance.d" />
+   <File path="dmd\TypeNewArray.d" />
+   <File path="dmd\TypeNext.d" />
+   <File path="dmd\TypePointer.d" />
+   <File path="dmd\TypeQualified.d" />
+   <File path="dmd\TypeReference.d" />
+   <File path="dmd\TypeReturn.d" />
+   <File path="dmd\TypeSArray.d" />
+   <File path="dmd\TypeSlice.d" />
+   <File path="dmd\TypeStruct.d" />
+   <File path="dmd\TypeTuple.d" />
+   <File path="dmd\TypeTypedef.d" />
+   <File path="dmd\TypeTypeof.d" />
+   <File path="dmd\UAddExp.d" />
+   <File path="dmd\UnaExp.d" />
+   <File path="dmd\UnionDeclaration.d" />
+   <File path="dmd\UnitTestDeclaration.d" />
+   <File path="dmd\UnrolledLoopStatement.d" />
+   <File path="dmd\UshrAssignExp.d" />
+   <File path="dmd\UshrExp.d" />
+   <File path="dmd\Utf.d" />
+   <File path="dmd\Util.d" />
+   <File path="dmd\VarDeclaration.d" />
+   <File path="dmd\VarExp.d" />
+   <File path="dmd\VersionCondition.d" />
+   <File path="dmd\VersionSymbol.d" />
+   <File path="dmd\VoidInitializer.d" />
+   <File path="dmd\VolatileStatement.d" />
+   <File path="dmd\WANT.d" />
+   <File path="dmd\WhileStatement.d" />
+   <File path="dmd\WithScopeSymbol.d" />
+   <File path="dmd\WithStatement.d" />
+   <File path="dmd\XorAssignExp.d" />
+   <File path="dmd\XorExp.d" />
+   <File path="dmd\common.d" />
+   <File path="dmd\Parameter.d" />
+   <File path="dmd\TRUST.d" />
+   <File path="dmd\PowExp.d" />
+   <File path="dmd\TypeInfoWildDeclaration.d" />
+   <File path="dmd\PowAssignExp.d" />
+  </Folder>
+  <File path="bridge.obj" />
+  <File path="ddmd.def" />
+  <File path="main.d" />
+ </Folder>
+</DProject>
--- a/dmd/AddAssignExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/AddAssignExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,11 +1,13 @@
 module dmd.AddAssignExp;
 
+import dmd.common;
+import dmd.expression.Add;
 import dmd.BinExp;
 import dmd.Loc;
 import dmd.Expression;
 import dmd.Scope;
 import dmd.InterState;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.STC;
 import dmd.OutBuffer;
 import dmd.ArrayTypes;
@@ -19,6 +21,7 @@
 import dmd.AssignExp;
 import dmd.Global;
 import dmd.Id;
+import dmd.ArrayLengthExp;
 
 import dmd.backend.OPER;
 import dmd.backend.elem;
@@ -47,6 +50,13 @@
 		Type tb1 = e1.type.toBasetype();
 		Type tb2 = e2.type.toBasetype();
 
+        if (e1.op == TOKarraylength)
+        {
+	        e = ArrayLengthExp.rewriteOpAssign(this);
+	        e = e.semantic(sc);
+	        return e;
+        }
+        
 		if (e1.op == TOK.TOKslice)
 		{
 			typeCombine(sc);
@@ -141,7 +151,7 @@
 	
     override Expression interpret(InterState istate)
 	{
-		assert(false);
+    	return interpretAssignCommon(istate, &Add);
 	}
 	
     override void buildArrayIdent(OutBuffer buf, Expressions arguments)
@@ -149,16 +159,9 @@
 		AssignExp_buildArrayIdent(buf, arguments, "Add");
 	}
 	
-    override Expression buildArrayLoop(Arguments fparams)
+    override Expression buildArrayLoop(Parameters fparams)
 	{
-		/* Evaluate assign expressions right to left		
-		 */								
-		Expression ex2 = e2.buildArrayLoop(fparams);		
-		Expression ex1 = e1.buildArrayLoop(fparams);		
-		Argument param = cast(Argument)fparams.data[0];		
-		param.storageClass = STCundefined;					
-		Expression e = new AddAssignExp(Loc(0), ex1, ex2);		
-		return e;							
+		return AssignExp_buildArrayLoop!(typeof(this))(fparams);
 	}
 
     override Identifier opId()    /* For operator overloading */
--- a/dmd/AddExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/AddExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.AddExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Identifier;
 import dmd.backend.elem;
@@ -113,7 +114,7 @@
 
 	override Expression interpret(InterState istate)
 	{
-		assert(false);
+		return interpretCommon(istate, &Add);
 	}
 
 	override void buildArrayIdent(OutBuffer buf, Expressions arguments)
@@ -121,14 +122,9 @@
 		Exp_buildArrayIdent(buf, arguments, "Add");
 	}
 
-	override Expression buildArrayLoop(Arguments fparams)
+	override Expression buildArrayLoop(Parameters fparams)
 	{
-		/* Evaluate assign expressions left to right		
-		 */								
-		Expression ex1 = e1.buildArrayLoop(fparams);		
-		Expression ex2 = e2.buildArrayLoop(fparams);		
-		Expression e = new AddExp(Loc(0), ex1, ex2);			
-		return e;							
+		return Exp_buildArrayLoop!(typeof(this))(fparams);
 	}
 
 	override bool isCommutative()
--- a/dmd/AddrExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/AddrExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.AddrExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.UnaExp;
 import dmd.MATCH;
@@ -65,7 +66,6 @@
 				return new ErrorExp();
 			}
 
-		//printf("test3 deco = %p\n", e1.type.deco);
 			type = e1.type.pointerTo();
 
 			// See if this should really be a delegate
@@ -126,6 +126,11 @@
 		return this;
 	}
 
+    override void checkEscape()
+    {
+        e1.checkEscapeRef();
+    }
+    
 	override elem* toElem(IRState* irs)
 	{
 		elem* e;
--- a/dmd/AggregateDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/AggregateDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.AggregateDeclaration;
 
+import dmd.common;
 import dmd.ScopeDsymbol;
 import dmd.Type;
 import dmd.Id;
@@ -108,9 +109,8 @@
 			ClassDeclaration cdthis = dthis.isClassDeclaration();
 			if (cdthis)
 			{
-				for (int i = 0; i < cdthis.baseclasses.dim; i++)
+				foreach (b; cdthis.baseclasses)
 				{   
-					BaseClass b = cast(BaseClass)cdthis.baseclasses.data[i];
 					PROT access = b.base.getAccess(smember);
 
 					if (access >= PROT.PROTprotected || accessCheckX(smember, sfunc, b.base, cdscope))
@@ -126,10 +126,8 @@
 			ClassDeclaration cdthis = dthis.isClassDeclaration();
 			if (cdthis)
 			{
-				for (int i = 0; i < cdthis.baseclasses.dim; i++)
+				foreach (b; cdthis.baseclasses)
 				{   
-					BaseClass b = cast(BaseClass)cdthis.baseclasses.data[i];
-
 					if (accessCheckX(smember, sfunc, b.base, cdscope))
 						return true;
 				}
@@ -143,7 +141,7 @@
 class AggregateDeclaration : ScopeDsymbol
 {
     Type type;
-    uint storage_class;
+    StorageClass storage_class;
     PROT protection = PROT.PROTpublic;
     Type handle;		// 'this' type
     uint structsize;	// size of struct
@@ -156,10 +154,11 @@
 				// 1: size is correct
 				// 2: cannot determine size; fwd referenced
     bool isdeprecated;		// true if deprecated
-
+	
+version (DMDV2) {
     bool isnested;		// true if is nested
     VarDeclaration vthis;	// 'this' parameter if this aggregate is nested
-
+}
     // Special member functions
     InvariantDeclaration inv;		// invariant
     NewDeclaration aggNew;		// allocator
--- a/dmd/AliasDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/AliasDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.AliasDeclaration;
 
+import dmd.common;
 import dmd.LINK;
 import dmd.Declaration;
 import dmd.TypedefDeclaration;
@@ -99,9 +100,10 @@
 		}
 		this.inSemantic = 1;
 
+version(DMDV1) {   // don't really know why this is here
 		if (storage_class & STC.STCconst)
 			error("cannot be const");
-
+}
 		storage_class |= sc.stc & STC.STCdeprecated;
 
 		// Given:
@@ -127,11 +129,12 @@
 			goto L2;			// it's a symbolic alias
 
 ///version (DMDV2) {
+        type = type.addStorageClass(storage_class);
 		if (storage_class & (STC.STCref | STCnothrow | STCpure))
 		{	// For 'ref' to be attached to function types, and picked
 			// up by Type.resolve(), it has to go into sc.
 			sc = sc.push();
-			sc.stc |= storage_class & (STCref | STCnothrow | STCpure);
+		    sc.stc |= storage_class & (STCref | STCnothrow | STCpure | STCshared);
 			type.resolve(loc, sc, &e, &t, &s);
 			sc = sc.pop();
 		}
--- a/dmd/AliasThis.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/AliasThis.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.AliasThis;
 
+import dmd.common;
 import dmd.Dsymbol;
 import dmd.Identifier;
 import dmd.Loc;
--- a/dmd/AlignDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/AlignDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.AlignDeclaration;
 
+import dmd.common;
 import dmd.AttribDeclaration;
 import dmd.OutBuffer;
 import dmd.HdrGenState;
--- a/dmd/AndAndExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/AndAndExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.AndAndExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.InterState;
 import dmd.Loc;
--- a/dmd/AndAssignExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/AndAssignExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,7 @@
 module dmd.AndAssignExp;
 
+import dmd.common;
+import dmd.expression.And;
 import dmd.BinExp;
 import dmd.Loc;
 import dmd.Expression;
@@ -29,7 +31,7 @@
 	
     override Expression interpret(InterState istate)
 	{
-		assert(false);
+    	return interpretAssignCommon(istate, &And);
 	}
 	
     override void buildArrayIdent(OutBuffer buf, Expressions arguments)
@@ -37,9 +39,9 @@
 		AssignExp_buildArrayIdent(buf, arguments, "And");
 	}
 	
-    override Expression buildArrayLoop(Arguments fparams)
+    override Expression buildArrayLoop(Parameters fparams)
 	{
-		assert(false);
+		return AssignExp_buildArrayLoop!(typeof(this))(fparams);
 	}
 
     override Identifier opId()    /* For operator overloading */
--- a/dmd/AndExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/AndExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.AndExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Identifier;
 import dmd.InterState;
@@ -49,11 +50,10 @@
 			else
 			{
 				typeCombine(sc);
-				if (e1.op != TOK.TOKslice && e2.op != TOK.TOKslice)
-				{   
+				if (!e1.isArrayOperand())
 					e1.checkIntegral();
+				if (!e2.isArrayOperand())
 					e2.checkIntegral();
-				}
 			}
 		}
 		return this;
@@ -75,7 +75,7 @@
 
 	override Expression interpret(InterState istate)
 	{
-		assert(false);
+		return interpretCommon(istate, &And);
 	}
 
 	override void buildArrayIdent(OutBuffer buf, Expressions arguments)
@@ -83,14 +83,9 @@
 		Exp_buildArrayIdent(buf, arguments, "And");
 	}
 
-	override Expression buildArrayLoop(Arguments fparams)
+	override Expression buildArrayLoop(Parameters fparams)
 	{
-		/* Evaluate assign expressions left to right		
-		 */								
-		Expression ex1 = e1.buildArrayLoop(fparams);		
-		Expression ex2 = e2.buildArrayLoop(fparams);		
-		Expression e = new AndExp(Loc(0), ex1, ex2);			
-		return e;							
+		return Exp_buildArrayLoop!(typeof(this))(fparams);
 	}
 
 	override IntRange getIntRange()
--- a/dmd/AnonDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/AnonDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.AnonDeclaration;
 
+import dmd.common;
 import dmd.OutBuffer;
 import dmd.Loc;
 import dmd.Scope;
--- a/dmd/AnonymousAggregateDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/AnonymousAggregateDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.AnonymousAggregateDeclaration;
 
+import dmd.common;
 import dmd.AggregateDeclaration;
 import dmd.Loc;
 
--- a/dmd/Argument.d	Tue Aug 31 18:02:48 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,304 +0,0 @@
-module dmd.Argument;
-
-import dmd.Type;
-import dmd.Identifier;
-import dmd.TypeArray;
-import dmd.TypeFunction;
-import dmd.TypeDelegate;
-import dmd.TypeTuple;
-import dmd.TY;
-import dmd.Expression;
-import dmd.OutBuffer;
-import dmd.HdrGenState;
-import dmd.ArrayTypes;
-import dmd.StorageClassDeclaration;
-import dmd.Global;
-import dmd.MOD;
-import dmd.CppMangleState;
-import dmd.STC;
-
-class Argument
-{
-    //enum InOut inout;
-    STC storageClass;
-    Type type;
-    Identifier ident;
-    Expression defaultArg;
-
-    this(STC storageClass, Type type, Identifier ident, Expression defaultArg)
-	{
-		this.type = type;
-		this.ident = ident;
-		this.storageClass = storageClass;
-		this.defaultArg = defaultArg;
-	}
-	
-	Argument clone()
-	{
-		return new Argument(storageClass, type, ident, defaultArg);
-	}
-	
-    Argument syntaxCopy()
-	{
-		return new Argument(storageClass, type ? type.syntaxCopy() : null, ident, defaultArg ? defaultArg.syntaxCopy() : null);
-	}
-	
-	/****************************************************
-	 * Determine if parameter is a lazy array of delegates.
-	 * If so, return the return type of those delegates.
-	 * If not, return null.
-	 */
-    Type isLazyArray()
-	{
-	//    if (inout == Lazy)
-		{
-			Type tb = type.toBasetype();
-			if (tb.ty == Tsarray || tb.ty == Tarray)
-			{
-				Type tel = (cast(TypeArray)tb).next.toBasetype();
-				if (tel.ty == Tdelegate)
-				{
-					TypeDelegate td = cast(TypeDelegate)tel;
-					TypeFunction tf = cast(TypeFunction)td.next;
-
-					if (!tf.varargs && Argument.dim(tf.parameters) == 0)
-					{
-						return tf.next;	// return type of delegate
-					}
-				}
-			}
-		}
-		return null;
-	}
-	
-    void toDecoBuffer(OutBuffer buf)
-	{
-		if (storageClass & STC.STCscope)
-			buf.writeByte('M');
-		switch (storageClass & (STC.STCin | STC.STCout | STC.STCref | STC.STClazy))
-		{   
-			case STC.STCundefined:
-			case STC.STCin:
-				break;
-			case STC.STCout:
-				buf.writeByte('J');
-				break;
-			case STC.STCref:
-				buf.writeByte('K');
-				break;
-			case STC.STClazy:
-				buf.writeByte('L');
-				break;
-		}
-static if (false) {
-		int mod = 0x100;
-		if (type.toBasetype().ty == TY.Tclass)
-			mod = 0;
-		type.toDecoBuffer(buf, mod);
-} else {
-		//type.toHeadMutable().toDecoBuffer(buf, 0);
-		type.toDecoBuffer(buf, 0);
-}
-	}
-	
-    static Arguments arraySyntaxCopy(Arguments args)
-	{
-		Arguments a = null;
-
-		if (args)
-		{
-			a = new Arguments();
-			a.setDim(args.dim);
-
-			for (size_t i = 0; i < a.dim; i++)
-			{   
-				Argument arg = cast(Argument)args.data[i];
-
-				arg = arg.syntaxCopy();
-				a.data[i] = cast(void*)arg;
-			}
-		}
-	
-		return a;
-	}
-	
-    static string argsTypesToChars(Arguments args, int varargs)
-	{
-		scope OutBuffer buf = new OutBuffer();
-
-	static if (true) {
-		HdrGenState hgs;
-		argsToCBuffer(buf, &hgs, args, varargs);
-	} else {
-		buf.writeByte('(');
-		if (args)
-		{	
-			OutBuffer argbuf = new OutBuffer();
-			HdrGenState hgs;
-
-			for (int i = 0; i < args.dim; i++)
-			{   
-				if (i)
-					buf.writeByte(',');
-				Argument arg = cast(Argument)args.data[i];
-				argbuf.reset();
-				arg.type.toCBuffer2(&argbuf, &hgs, 0);
-				buf.write(&argbuf);
-			}
-			if (varargs)
-			{
-				if (i && varargs == 1)
-					buf.writeByte(',');
-				buf.writestring("...");
-			}
-		}
-		buf.writeByte(')');
-	}
-		return buf.toChars();
-	}
-	
-    static void argsCppMangle(OutBuffer buf, CppMangleState* cms, Arguments arguments, int varargs)
-	{
-		assert(false);
-	}
-	
-    static void argsToCBuffer(OutBuffer buf, HdrGenState* hgs, Arguments arguments, int varargs)
-	{
-		buf.writeByte('(');
-		if (arguments)
-		{	
-			int i;
-			scope OutBuffer argbuf = new OutBuffer();
-
-			for (i = 0; i < arguments.dim; i++)
-			{
-				if (i)
-					buf.writestring(", ");
-				Argument arg = cast(Argument)arguments.data[i];
-
-				if (arg.storageClass & STCout)
-					buf.writestring("out ");
-				else if (arg.storageClass & STCref)
-					buf.writestring((global.params.Dversion == 1) ? "inout " : "ref ");
-				else if (arg.storageClass & STCin)
-					buf.writestring("in ");
-				else if (arg.storageClass & STClazy)
-					buf.writestring("lazy ");
-				else if (arg.storageClass & STCalias)
-					buf.writestring("alias ");
-				else if (arg.storageClass & STCauto)
-					buf.writestring("auto ");
-
-				uint stc = arg.storageClass;
-				if (arg.type && arg.type.mod & MODshared)
-					stc &= ~STCshared;
-
-				StorageClassDeclaration.stcToCBuffer(buf, stc & (STCconst | STCimmutable | STCshared | STCscope));
-
-				argbuf.reset();
-				if (arg.storageClass & STCalias)
-				{	
-					if (arg.ident)
-						argbuf.writestring(arg.ident.toChars());
-				}
-				else
-					arg.type.toCBuffer(argbuf, arg.ident, hgs);
-				if (arg.defaultArg)
-				{
-					argbuf.writestring(" = ");
-					arg.defaultArg.toCBuffer(argbuf, hgs);
-				}
-				buf.write(argbuf);
-			}
-			if (varargs)
-			{
-				if (i && varargs == 1)
-					buf.writeByte(',');
-				buf.writestring("...");
-			}
-		}
-		buf.writeByte(')');
-	}
-	
-    static void argsToDecoBuffer(OutBuffer buf, Arguments arguments)
-	{
-		//printf("Argument::argsToDecoBuffer()\n");
-
-		// Write argument types
-		if (arguments)
-		{
-			size_t dim = Argument.dim(arguments);
-			for (size_t i = 0; i < dim; i++)
-			{
-				Argument arg = Argument.getNth(arguments, i);
-				arg.toDecoBuffer(buf);
-			}
-		}
-	}
-	
-    static int isTPL(Arguments arguments)
-	{
-		assert(false);
-	}
-
-	/***************************************
-	 * Determine number of arguments, folding in tuples.
-	 */	
-    static size_t dim(Arguments args)
-	{
-		size_t n = 0;
-		if (args)
-		{
-			for (size_t i = 0; i < args.dim; i++)
-			{   
-				Argument arg = cast(Argument)args.data[i];
-				Type t = arg.type.toBasetype();
-
-				if (t.ty == TY.Ttuple)
-				{   
-					TypeTuple tu = cast(TypeTuple)t;
-					n += dim(tu.arguments);
-				}
-				else
-					n++;
-			}
-		}
-		return n;
-	}
-	
-	/***************************************
-	 * Get nth Argument, folding in tuples.
-	 * Returns:
-	 *	Argument	nth Argument
-	 *	null		not found, *pn gets incremented by the number
-	 *			of Arguments
-	 */
-    static Argument getNth(Arguments args, size_t nth, size_t* pn = null)
-	{
-		if (!args)
-			return null;
-
-		size_t n = 0;
-		for (size_t i = 0; i < args.dim; i++)
-		{   
-			Argument arg = cast(Argument)args.data[i];
-			Type t = arg.type.toBasetype();
-
-			if (t.ty == TY.Ttuple)
-			{   TypeTuple tu = cast(TypeTuple)t;
-				arg = getNth(tu.arguments, nth - n, &n);
-				if (arg)
-					return arg;
-			}
-			else if (n == nth)
-				return arg;
-			else
-				n++;
-		}
-
-		if (pn)
-			*pn += n;
-
-		return null;
-	}
-}
--- a/dmd/Array.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/Array.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.Array;
 
+import dmd.common;
 import core.memory;
 
 import std.exception;
@@ -204,14 +205,14 @@
         return _dim;
     }    
 */
-
+/* 
+	// Use [] for accessing members instead
+	// or ptr() to get the pointer to the first element
     @property T *data()
     {
         return _data;
     }
-
-	
-
+*/
     @property T *ptr()
     {
         return _data;
@@ -245,6 +246,12 @@
         _data[_dim++] = elem;
     }
     
+	final void zero()
+	{
+		memset(_data, 0, dim * T.sizeof);
+		// TODO fix to assign T.init
+	}
+	
     final void reserve(size_t nentries)
 	{
         //printf("Array::reserve: size = %d, offset = %d, nbytes = %d\n", size, offset, nbytes);
--- a/dmd/ArrayExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/ArrayExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.ArrayExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Identifier;
 import dmd.UnaExp;
--- a/dmd/ArrayInitializer.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/ArrayInitializer.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.ArrayInitializer;
 
+import dmd.common;
 import dmd.ArrayTypes;
 import dmd.Type;
 import dmd.TypeAArray;
@@ -56,9 +57,9 @@
 				e = e.syntaxCopy();
 			ai.index[i] = e;
 
-			Initializer init = cast(Initializer)value.data[i];
+			auto init = value[i];
 			init = init.syntaxCopy();
-			ai.value.data[i] = cast(void*)init;
+			ai.value[i] = init;
 		}
 		return ai;
 	}
@@ -66,7 +67,7 @@
     void addInit(Expression index, Initializer value)
 	{
 		this.index.push(index);
-		this.value.push(cast(void*)value);
+		this.value.push(value);
 		dim = 0;
 		type = null;
 	}
@@ -97,8 +98,6 @@
 		length = 0;
 		foreach (size_t i, Expression idx; index)
 		{	
-			Initializer val;
-
 			if (idx)
 			{   
 				idx = idx.semantic(sc);
@@ -107,9 +106,9 @@
 				length = cast(uint)idx.toInteger();
 			}
 
-			val = cast(Initializer)value.data[i];
+			Initializer val = value[i];
 			val = val.semantic(sc, t.nextOf());
-			value.data[i] = cast(void*)val;
+			value[i] = val;
 			length++;
 			if (length == 0)
 				error(loc, "array dimension overflow");
@@ -123,9 +122,22 @@
 		return this;
 	}
 	
+    int isAssociativeArray()
+    {
+        for (size_t i = 0; i < value.dim; i++)
+        {
+	        if (index[i])
+	            return 1;
+        }
+        return 0;
+    }
+    
     override Type inferType(Scope sc)
 	{
 		//printf("ArrayInitializer.inferType() %s\n", toChars());
+        assert(0);
+        return null;
+static if (false) {
 		type = Type.terror;
 		for (size_t i = 0; i < value.dim; i++)
 		{
@@ -133,14 +145,15 @@
 				goto Laa;
 		}
 
-		for (size_t i = 0; i < value.dim; i++)
+		foreach (size_t i, Initializer iz; value)
 		{
-			Initializer iz = cast(Initializer)value.data[i];
 			if (iz)
 			{   
 				Type t = iz.inferType(sc);
 				if (i == 0)
-				{	
+				{	/* BUG: This gets the type from the first element.
+        		 * Fix to use all the elements to figure out the type.
+	        	 */	
 					t = new TypeSArray(t, new IntegerExp(value.dim));
 					t = t.semantic(loc, sc);
 					type = t;
@@ -150,9 +163,10 @@
 		return type;
 
 	Laa:
-		/* It's possibly an associative array initializer
-	     */
-	    Initializer iz = cast(Initializer)value.data[0];
+        /* It's possibly an associative array initializer.
+         * BUG: inferring type from first member.
+         */
+	    Initializer iz = value[0];
 	    Expression indexinit = index[0];
 	    if (iz && indexinit)
 		{
@@ -165,6 +179,7 @@
 		else
 			error(loc, "cannot infer type from this array initializer");
 		return type;
+}
 	}
 
 	/********************************
@@ -220,7 +235,7 @@
 			if (index[i])
 				j = cast(uint)(index[i].toInteger());
 			assert(j < edim);
-			Initializer iz = cast(Initializer)value.data[i];
+			Initializer iz = value[i];
 			if (!iz)
 				goto Lno;
 			Expression ex = iz.toExpression();
@@ -256,7 +271,7 @@
 	    return null;
 	}
 	
-    Initializer toAssocArrayInitializer()
+    Expression toAssocArrayLiteral()
 	{
 		assert(false);
 	}
@@ -272,7 +287,7 @@
 		Type tb = type.toBasetype();
 		Type tn = tb.nextOf().toBasetype();
 
-		scope Array dts = new Array();
+		scope dts = new Vector!(dt_t*)();
 		uint size;
 		uint length;
 		uint i;
@@ -298,11 +313,11 @@
 			//printf("\tindex[%d] = %p, length = %u, dim = %u\n", i, idx, length, dim);
 
 			assert(length < dim);
-			val = cast(Initializer)value.data[i];
+			val = value[i];
 			dt = val.toDt();
-			if (dts.data[length])
+			if (dts[length])
 				error(loc, "duplicate initializations for index %d", length);
-			dts.data[length] = cast(void*)dt;
+			dts[length] = dt;
 			length++;
 		}
 
@@ -319,7 +334,7 @@
 		pdtend = &d;
 		for (i = 0; i < dim; i++)
 		{
-			dt = cast(dt_t*)dts.data[i];
+			dt = dts[i];
 			if (dt)
 				pdtend = dtcat(pdtend, dt);
 			else
--- a/dmd/ArrayLengthExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/ArrayLengthExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,6 +1,8 @@
 module dmd.ArrayLengthExp;
 
+import dmd.common;
 import dmd.Expression;
+import dmd.BinExp;
 import dmd.backend.elem;
 import dmd.UnaExp;
 import dmd.InterState;
@@ -12,6 +14,16 @@
 import dmd.TOK;
 import dmd.Type;
 import dmd.WANT;
+import dmd.VarExp;
+import dmd.VarDeclaration;
+import dmd.PtrExp;
+import dmd.Lexer;
+import dmd.Identifier;
+import dmd.ExpInitializer;
+import dmd.DeclarationExp;
+import dmd.CommaExp;
+import dmd.AssignExp;
+import dmd.AddrExp;
 
 import dmd.expression.ArrayLength;
 
@@ -27,8 +39,6 @@
 
 	override Expression semantic(Scope sc)
 	{
-		Expression e;
-
 	version (LOGSEMANTIC) {
 		printf("ArrayLengthExp::semantic('%s')\n", toChars());
 	}
@@ -42,6 +52,35 @@
 		return this;
 	}
 
+	static Expression rewriteOpAssign(BinExp exp)
+	{
+		Expression e;
+
+		assert(exp.e1.op == TOKarraylength);
+		auto ale = cast(ArrayLengthExp)exp.e1;
+		if (ale.e1.op == TOK.TOKvar)
+		{
+		    e = opAssignToOp(exp.loc, exp.op, ale, exp.e2);
+		    e = new AssignExp(exp.loc, ale.syntaxCopy(), e);
+		}
+		else
+		{
+		    /*    auto tmp = &array;
+		     *    (*tmp).length = (*tmp).length op e2
+		     */
+		    Identifier id = Lexer.uniqueId("__arraylength");
+		    ExpInitializer ei = new ExpInitializer(ale.loc, new AddrExp(ale.loc, ale.e1));
+		    VarDeclaration tmp = new VarDeclaration(ale.loc, ale.e1.type.pointerTo(), id, ei);
+
+		    Expression e1 = new ArrayLengthExp(ale.loc, new PtrExp(ale.loc, new VarExp(ale.loc, tmp)));
+		    Expression elvalue = e1.syntaxCopy();
+		    e = opAssignToOp(exp.loc, exp.op, e1, exp.e2);
+		    e = new AssignExp(exp.loc, elvalue, e);
+		    e = new CommaExp(exp.loc, new DeclarationExp(ale.loc, tmp), e);
+		}
+		return e;
+	}
+    
 	override Expression optimize(int result)
 	{
 		//printf("ArrayLengthExp::optimize(result = %d) %s\n", result, toChars());
--- a/dmd/ArrayLiteralExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/ArrayLiteralExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.ArrayLiteralExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.backend.elem;
 import dmd.InterState;
@@ -15,6 +16,7 @@
 import dmd.HdrGenState;
 import dmd.backend.dt_t;
 import dmd.InlineScanState;
+import dmd.GlobalExpressions;
 import dmd.Array;
 import dmd.ArrayTypes;
 import dmd.TOK;
@@ -56,58 +58,19 @@
 
 	override Expression semantic(Scope sc)
 	{
-		Expression e;
-		Type t0 = null;
-
 	version (LOGSEMANTIC) {
 		printf("ArrayLiteralExp.semantic('%s')\n", toChars());
 	}
 		if (type)
 			return this;
 
-		// Run semantic() on each element
-		foreach (ref Expression e; elements)
-		{	
-			e = e.semantic(sc);
-			assert(e.type);
-		}
+		arrayExpressionSemantic(elements, sc);    // run semantic() on each element
 
 		expandTuples(elements);
 
-		foreach (size_t i, Expression e; elements)
-		{	
-			if (!e.type)
-				error("%s has no value", e.toChars());
-
-			e = resolveProperties(sc, e);
-
-			ubyte committed = 1;
-			if (e.op == TOKstring)
-				committed = (cast(StringExp)e).committed;
-
-			if (!t0)
-			{   
-				t0 = e.type;
-				// Convert any static arrays to dynamic arrays
-				if (t0.ty == Tsarray)
-				{
-					t0 = (cast(TypeSArray)t0).next.arrayOf();
-					e = e.implicitCastTo(sc, t0);
-				}
-			}
-			else
-				e = e.implicitCastTo(sc, t0);
-
-			if (!committed && e.op == TOKstring)
-			{   
-				auto se = cast(StringExp)e;
-				se.committed = 0;
-			}
-			elements[i] = e;
-		}
-
-		if (!t0)
-			t0 = Type.tvoid;
+		Type t0;
+		elements = arrayExpressionToCommonType(sc, elements, &t0);
+		
 		type = new TypeSArray(t0, new IntegerExp(elements.dim));
 		type = type.semantic(loc, sc);
 		return this;
@@ -237,7 +200,56 @@
 
 	override Expression interpret(InterState istate)
 	{
-		assert(false);
+		Expressions expsx = null;
+
+version (LOG) {
+		printf("ArrayLiteralExp.interpret() %.*s\n", toChars());
+}
+		if (elements)
+		{
+			foreach (size_t i, Expression e; elements)
+			{   
+				Expression ex;
+
+				ex = e.interpret(istate);
+				if (ex is EXP_CANT_INTERPRET)
+				    goto Lerror;
+
+				/* If any changes, do Copy On Write
+				 */
+				if (ex != e)
+				{
+					if (!expsx)
+					{
+						expsx = new Expressions();
+						expsx.setDim(elements.dim);
+						for (size_t j = 0; j < elements.dim; j++)
+						{
+							expsx[j] = elements[j];
+						}
+					}
+					expsx[i] = ex;
+				}
+			}
+		}
+		if (elements && expsx)
+		{
+			expandTuples(expsx);
+			if (expsx.dim != elements.dim)
+			    goto Lerror;
+			
+			ArrayLiteralExp ae = new ArrayLiteralExp(loc, expsx);
+			ae.type = type;
+			
+			return ae;
+		}
+		return this;
+
+    Lerror:
+        if (expsx)
+	        delete expsx;
+        error("cannot interpret array literal");
+        return EXP_CANT_INTERPRET;
 	}
 
 	override MATCH implicitConvTo(Type t)
--- a/dmd/ArrayScopeSymbol.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/ArrayScopeSymbol.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.ArrayScopeSymbol;
 
+import dmd.common;
 import dmd.ScopeDsymbol;
 import dmd.Expression;
 import dmd.TypeTuple;
--- a/dmd/ArrayTypes.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/ArrayTypes.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,21 +1,20 @@
 module dmd.ArrayTypes;
 
+import dmd.common;
 import dmd.Array;
-
-class TemplateParameters : Array { final typeof(this) copy() { auto a = new typeof(this); copyTo(a); return a; } }
-
-class Statements : Array { final typeof(this) copy() { auto a = new typeof(this); copyTo(a); return a; } }
-
-class BaseClasses : Array { final typeof(this) copy() { auto a = new typeof(this); copyTo(a); return a; } }
-
-class ClassDeclarations : Array { final typeof(this) copy() { auto a = new typeof(this); copyTo(a); return a; } }
+import dmd.TemplateParameter;
+import dmd.Statement;
+import dmd.BaseClass;
+import dmd.ClassDeclaration;
+import dmd.Parameter;
+import dmd.Identifier;
+import dmd.Initializer;
 
-//class Dsymbols : Array { final typeof(this) copy() { auto a = new typeof(this); copyTo(a); return a; } }
-
-class Objects : Array { final typeof(this) copy() { auto a = new typeof(this); copyTo(a); return a; } }
-
-class Arguments : Array { final typeof(this) copy() { auto a = new typeof(this); copyTo(a); return a; } }
-
-class Identifiers : Array { final typeof(this) copy() { auto a = new typeof(this); copyTo(a); return a; } }
-
-class Initializers : Array { final typeof(this) copy() { auto a = new typeof(this); copyTo(a); return a; } }
\ No newline at end of file
+alias Vector!Object Objects;
+alias Vector!TemplateParameter TemplateParameters;
+alias Vector!Statement Statements;
+alias Vector!BaseClass BaseClasses;
+alias Vector!ClassDeclaration ClassDeclarations;
+alias Vector!Parameter Parameters;
+alias Vector!Identifier Identifiers;
+alias Vector!Initializer Initializers;
\ No newline at end of file
--- a/dmd/AsmStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/AsmStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.AsmStatement;
 
+import dmd.common;
 import dmd.Loc;
 import dmd.Statement;
 import dmd.Token;
@@ -58,12 +59,16 @@
     override Statement semantic(Scope sc)
 	{
 		//printf("AsmStatement.semantic()\n");
-
-		if (global.params.safe && !sc.module_.safe)
-		{
-			error("inline assembler not allowed in safe mode");
-		}
-
+//static if (true) {
+        if (sc.func && sc.func.isSafe())
+        	error("inline assembler not allowed in @safe function %s", sc.func.toChars());
+//} else {
+//		if (global.params.safe && !sc.module_.safe)
+//		{
+//			error("inline assembler not allowed in safe mode");
+//		}
+//}
+        
 		OP* o;
 		OPND* o1 = null;
 		OPND* o2 = null;
--- a/dmd/AssertExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/AssertExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.AssertExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.backend.elem;
 import dmd.UnaExp;
--- a/dmd/AssignExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/AssignExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,10 +1,11 @@
 module dmd.AssignExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Identifier;
 import dmd.backend.elem;
 import dmd.InterState;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.IndexExp;
 import dmd.CallExp;
 import dmd.CastExp;
@@ -389,7 +390,7 @@
 		buf.writestring("Assign");
 	}
 
-	override Expression buildArrayLoop(Arguments fparams)
+	override Expression buildArrayLoop(Parameters fparams)
 	{
 		/* Evaluate assign expressions right to left
 		 */
@@ -403,7 +404,7 @@
 		ex2 = new CastExp(Loc(0), ex2, e1.type.nextOf());
 	}
 		Expression ex1 = e1.buildArrayLoop(fparams);
-		Argument param = cast(Argument)fparams.data[0];
+		auto param = fparams[0];
 		param.storageClass = STCundefined;
 		Expression e = new AssignExp(Loc(0), ex1, ex2);
 		return e;
@@ -411,9 +412,6 @@
 
 	override elem* toElem(IRState* irs)
 	{
-		elem* e;
-		IndexExp ae;
-		int r;
 		Type t1b;
 
 		//printf("AssignExp.toElem('%s')\n", toChars());
@@ -426,45 +424,25 @@
 			//	_d_arraysetlength(e2, sizeelem, &ale.e1);
 
 			ArrayLengthExp ale = cast(ArrayLengthExp)e1;
-			elem* p1;
-			elem* p2;
-			elem* p3;
-			elem* ep;
-			Type t1;
 
-			p1 = e2.toElem(irs);
-			p3 = ale.e1.toElem(irs);
+			auto p1 = e2.toElem(irs);
+			auto p3 = ale.e1.toElem(irs);
 			p3 = addressElem(p3, null);
-			t1 = ale.e1.type.toBasetype();
+			Type t1 = ale.e1.type.toBasetype();
 
-static if (true) {
 			// call _d_arraysetlengthT(ti, e2, &ale.e1);
-			p2 = t1.getTypeInfo(null).toElem(irs);
-			ep = el_params(p3, p1, p2, null);	// c function
-			r = t1.nextOf().isZeroInit(Loc(0)) ? RTLSYM.RTLSYM_ARRAYSETLENGTHT : RTLSYM.RTLSYM_ARRAYSETLENGTHIT;
-} else {
-			if (t1.next.isZeroInit())
-			{   
-				p2 = t1.getTypeInfo(null).toElem(irs);
-				ep = el_params(p3, p1, p2, null);	// c function
-				r = RTLSYM.RTLSYM_ARRAYSETLENGTHT;
-			}
-			else
-			{
-				p2 = el_long(TYM.TYint, t1.next.size());
-				ep = el_params(p3, p2, p1, null);	// c function
-				Expression init = t1.next.defaultInit();
-				ep = el_param(el_long(TYM.TYint, init.type.size()), ep);
-				elem* ei = init.toElem(irs);
-				ep = el_param(ei, ep);
-				r = RTLSYM.RTLSYM_ARRAYSETLENGTH3;
-			}
-}
-			e = el_bin(OPER.OPcall, type.totym(), el_var(rtlsym[r]), ep);
+			auto p2 = t1.getTypeInfo(null).toElem(irs);
+			auto ep = el_params(p3, p1, p2, null);	// c function
+			int r = t1.nextOf().isZeroInit(Loc(0)) ? RTLSYM.RTLSYM_ARRAYSETLENGTHT : RTLSYM.RTLSYM_ARRAYSETLENGTHIT;
+
+			auto e = el_bin(OPER.OPcall, type.totym(), el_var(rtlsym[r]), ep);
 			el_setLoc(e, loc);
 			return e;
 		}
-
+		
+		elem *e;
+		IndexExp ae;
+		
 		// Look for array[]=n
 		if (e1.op == TOK.TOKslice)
 		{
@@ -559,7 +537,7 @@
 				elem_print(enbytes);
 	}
 
-				if (global.params.useArrayBounds && eupr && ta.ty != TY.Tpointer)
+				if (irs.arrayBoundsCheck() && eupr && ta.ty != TY.Tpointer)
 				{
 					elem *c1;
 					elem *c2;
@@ -650,16 +628,13 @@
 				/* It's array1[]=array2[]
 				 * which is a memcpy
 				 */
-				elem* eto;
-				elem* efrom;
-				elem* esize;
 				elem* ep;
 
-				eto = e1.toElem(irs);
-				efrom = e2.toElem(irs);
+				auto eto = e1.toElem(irs);
+				auto efrom = e2.toElem(irs);
 
 				uint size = cast(uint)t1.nextOf().size();
-				esize = el_long(TYM.TYint, size);
+				auto esize = el_long(TYM.TYint, size);
 
 				/* Determine if we need to do postblit
 				 */
@@ -669,16 +644,12 @@
 
 				assert(e2.type.ty != TY.Tpointer);
 
-				if (!postblit && !global.params.useArrayBounds)
+				if (!postblit && !irs.arrayBoundsCheck())
 				{	
-					elem* epto;
-					elem* epfr;
-					elem* elen;
-					elem* ex;
-
-					ex = el_same(&eto);
+					auto ex = el_same(&eto);
 
 					// Determine if elen is a constant
+					elem *elen;
 					if (eto.Eoper == OPER.OPpair && eto.E1.Eoper == OPER.OPconst)
 					{
 						elen = el_copytree(eto.E1);
@@ -690,8 +661,8 @@
 					}
 
 					esize = el_bin(OPER.OPmul, TYM.TYint, elen, esize);
-					epto = array_toPtr(e1.type, ex);
-					epfr = array_toPtr(e2.type, efrom);
+					auto epto = array_toPtr(e1.type, ex);
+					auto epfr = array_toPtr(e2.type, efrom);
 	static if (true) {
 					// memcpy() is faster, so if we can't beat 'em, join 'em
 					e = el_params(esize, epfr, epto, null);
--- a/dmd/AssocArrayLiteralExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/AssocArrayLiteralExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.AssocArrayLiteralExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.GlobalExpressions;
 import dmd.WANT;
@@ -50,24 +51,17 @@
 	override Expression semantic(Scope sc)
 	{
 		Expression e;
-		Type tkey = null;
-		Type tvalue = null;
 
 		version (LOGSEMANTIC) {
 			printf("AssocArrayLiteralExp.semantic('%s')\n", toChars());
 		}
 
-		// Run semantic() on each element
-		for (size_t i = 0; i < keys.dim; i++)
-		{	auto key = keys[i];
-			auto value = values[i];
+		if (type)
+			return this;
 
-			key = key.semantic(sc);
-			value = value.semantic(sc);
-
-			keys[i] = key;
-			values[i] = value;
-		}
+		// Run semantic() on each element
+		arrayExpressionSemantic(keys, sc);
+		arrayExpressionSemantic(values, sc);
 		expandTuples(keys);
 		expandTuples(values);
 		if (keys.dim != values.dim)
@@ -76,34 +70,12 @@
 			keys.setDim(0);
 			values.setDim(0);
 		}
-		for (size_t i = 0; i < keys.dim; i++)
-		{	auto key = keys[i];
-			auto value = values[i];
-
-			if (!key.type)
-				error("%s has no value", key.toChars());
-			if (!value.type)
-				error("%s has no value", value.toChars());
-			key = resolveProperties(sc, key);
-			value = resolveProperties(sc, value);
-
-			if (!tkey)
-				tkey = key.type;
-			else
-				key = key.implicitCastTo(sc, tkey);
-			keys[i] = key;
-
-			if (!tvalue)
-				tvalue = value.type;
-			else
-				value = value.implicitCastTo(sc, tvalue);
-			values[i] = value;
-		}
-
-		if (!tkey)
-			tkey = Type.tvoid;
-		if (!tvalue)
-			tvalue = Type.tvoid;
+		
+		Type tkey;
+		Type tvalue;
+		keys = arrayExpressionToCommonType(sc, keys, &tkey);
+		values = arrayExpressionToCommonType(sc, values, &tvalue);
+		
 		type = new TypeAArray(tvalue, tkey);
 		type = type.semantic(loc, sc);
 		return this;
@@ -147,6 +119,8 @@
 		assert(t.ty == Taarray);
 		auto ta = cast(TypeAArray)t;
 
+static if(false)
+{
 		/* Unfortunately, the hash function for Aa (array of chars) is custom and
 		 * different from Axa and Aya, which get the generic hash function.
 		 * So, rewrite the type of the AArray so that if it's key type
@@ -160,6 +134,7 @@
 			ta = new TypeAArray(ta.nextOf(), tkey);
 			ta = cast(TypeAArray)ta.merge();
 		}
+}
 
 		e = el_param(e, ta.getTypeInfo(null).toElem(irs));
 
--- a/dmd/AttribDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/AttribDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.AttribDeclaration;
 
+import dmd.common;
 import dmd.Dsymbol;
 import dmd.Array;
 import dmd.Scope;
@@ -39,7 +40,7 @@
 		return m;
 	}
 	
-    void setScopeNewSc(Scope sc, STC stc, LINK linkage, PROT protection, int explicitProtection, uint structalign)
+    void setScopeNewSc(Scope sc, StorageClass stc, LINK linkage, PROT protection, int explicitProtection, uint structalign)
 	{
 		if (decl)
 		{
@@ -65,7 +66,7 @@
 		}
 	}
 	
-    void semanticNewSc(Scope sc, STC stc, LINK linkage, PROT protection, int explicitProtection, uint structalign)
+    void semanticNewSc(Scope sc, StorageClass stc, LINK linkage, PROT protection, int explicitProtection, uint structalign)
 	{
 		if (decl)
 		{
--- a/dmd/BaseClass.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/BaseClass.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.BaseClass;
 
+import dmd.common;
 import dmd.Type;
 import dmd.PROT;
 import dmd.ClassDeclaration;
@@ -132,7 +133,7 @@
 			baseInterfaces[i] = b;
 
 			if (i)				// single inheritance is i==0
-				vtblInterfaces.push(cast(void*)b);	// only need for M.I.
+				vtblInterfaces.push(b);	// only need for M.I.
 			b.copyBaseInterfaces(vtblInterfaces);
 		}
 		//printf("-copyBaseInterfaces\n");
--- a/dmd/BinExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/BinExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.BinExp;
 
+import dmd.common;
 import dmd.SliceExp;
 import dmd.IndexExp;
 import dmd.StructDeclaration;
@@ -53,7 +54,7 @@
 import dmd.PREC;
 import dmd.StringValue;
 import dmd.StringTable;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.Statement;
 import dmd.ForeachRangeStatement;
 import dmd.ArrayLengthExp;
@@ -124,11 +125,8 @@
     TY ty = cast(TY)Type.impcnvResult[t1b.ty][t2b.ty];
     if (ty != TY.Terror)
     {
-		TY ty1;
-		TY ty2;
-
-		ty1 = cast(TY)Type.impcnvType1[t1b.ty][t2b.ty];
-		ty2 = cast(TY)Type.impcnvType2[t1b.ty][t2b.ty];
+		auto ty1 = cast(TY)Type.impcnvType1[t1b.ty][t2b.ty];
+		auto ty2 = cast(TY)Type.impcnvType2[t1b.ty][t2b.ty];
 
 		if (t1b.ty == ty1)	// if no promotions
 		{
@@ -205,16 +203,24 @@
 		}
     }
     else if ((t1.ty == TY.Tsarray || t1.ty == TY.Tarray) &&
-	     e2.op == TOK.TOKnull && t2.ty == TY.Tpointer && t2.nextOf().ty == TY.Tvoid)
-    {	/*  (T[n] op void*)
-		 *  (T[] op void*)
-		 */
+	     (e2.op == TOK.TOKnull && t2.ty == TY.Tpointer && t2.nextOf().ty == TY.Tvoid ||
+	      e2.op == TOK.TOKarrayliteral && t2.ty == TY.Tsarray && t2.nextOf().ty == TY.Tvoid && (cast(TypeSArray)t2).dim.toInteger() == 0)
+	    )
+    {	/*  (T[n] op void*)   => T[]
+	 *  (T[]  op void*)   => T[]
+	 *  (T[n] op void[0]) => T[]
+	 *  (T[]  op void[0]) => T[]
+	 */
 		goto Lx1;
     }
     else if ((t2.ty == TY.Tsarray || t2.ty == TY.Tarray) &&
-	     e1.op == TOK.TOKnull && t1.ty == TY.Tpointer && t1.nextOf().ty == TY.Tvoid)
-    {	/*  (void* op T[n])
-		 *  (void* op T[])
+	     (e1.op == TOK.TOKnull && t1.ty == TY.Tpointer && t1.nextOf().ty == TY.Tvoid ||
+	      e1.op == TOK.TOKarrayliteral && t1.ty == TY.Tsarray && t1.nextOf().ty == TY.Tvoid && (cast(TypeSArray)t1).dim.toInteger() == 0)
+	    )
+    {	/*  (void*   op T[n]) => T[]
+	 *  (void*   op T[])  => T[]
+	 *  (void[0] op T[n]) => T[]
+	 *  (void[0] op T[])  => T[]
 		 */
 		goto Lx2;
     }
@@ -312,7 +318,7 @@
 	     e2.implicitConvTo(t1.nextOf().arrayOf()))
     {
      Lx1:
-		t = t1.nextOf().arrayOf();
+		t = t1.nextOf().arrayOf();	// T[]
 		e1 = e1.castTo(sc, t);
 		e2 = e2.castTo(sc, t);
     }
@@ -449,6 +455,13 @@
 			if (e)
 				return e;
 
+			if (e1.op == TOK.TOKarraylength)
+			{
+				e = ArrayLengthExp.rewriteOpAssign(this);
+				e = e.semantic(sc);
+				return e;
+			}
+			
 			if (e1.op == TOKslice)
 			{   
 				// T[] op= ...
@@ -489,6 +502,13 @@
 			if (e)
 				return e;
 
+			if (e1.op == TOKarraylength)
+			{
+				e = ArrayLengthExp.rewriteOpAssign(this);
+				e = e.semantic(sc);
+				return e;
+			}
+			
 			if (e1.op == TOK.TOKslice)
 			{   // T[] op= ...
 				typeCombine(sc);
@@ -532,6 +552,7 @@
 			case TOK.TOKandass:
 			case TOK.TOKorass:
 			case TOK.TOKxorass:
+            case TOK.TOKpowass:
 			case TOK.TOKin:
 			case TOK.TOKremove:
 				return true;
@@ -654,7 +675,7 @@
 
     bool isunsigned()
 	{
-		assert(false);
+		return e1.type.isunsigned() || e2.type.isunsigned();
 	}
 	
     void incompatibleTypes()
@@ -669,25 +690,83 @@
 		assert(false);
 	}
 
-    void scanForNestedRef(Scope *sc)
+    void scanForNestedRef(Scope sc)
 	{
-		assert(false);
+		e1.scanForNestedRef(sc);
+		e2.scanForNestedRef(sc);
 	}
-	
-    Expression interpretCommon(InterState istate, Expression *(*fp)(Type *, Expression *, Expression *))
+
+	Expression interpretCommon(InterState istate, Expression function(Type, Expression, Expression) fp)
 	{
-		assert(false);
+		Expression e;
+		Expression e1;
+		Expression e2;
+
+version(LOG)
+{
+		writef("BinExp::interpretCommon() %s\n", toChars());
+}
+		e1 = this.e1.interpret(istate);
+		if (e1 is EXP_CANT_INTERPRET)
+			goto Lcant;
+		if (e1.isConst() != 1)
+			goto Lcant;
+
+		e2 = this.e2.interpret(istate);
+		if (e2 is EXP_CANT_INTERPRET)
+			goto Lcant;
+		if (e2.isConst() != 1)
+			goto Lcant;
+
+		e = fp(type, e1, e2);
+		return e;
+
+	Lcant:
+		return EXP_CANT_INTERPRET;
 	}
 
-    Expression interpretCommon2(InterState istate, Expression *(*fp)(TOK, Type *, Expression *, Expression *))
+	Expression interpretCommon2(InterState istate, Expression function(TOK, Type, Expression, Expression) fp)
 	{
-		assert(false);
+		Expression e;
+		Expression e1;
+		Expression e2;
+
+version(LOG)
+{
+		writef("BinExp::interpretCommon2() %s\n", toChars());
+}
+		e1 = this.e1.interpret(istate);
+		if (e1 is EXP_CANT_INTERPRET)
+			goto Lcant;
+		if (e1.isConst() != 1 &&
+			e1.op != TOKnull &&
+			e1.op != TOKstring &&
+			e1.op != TOKarrayliteral &&
+			e1.op != TOKstructliteral)
+			goto Lcant;
+
+		e2 = this.e2.interpret(istate);
+		if (e2 is EXP_CANT_INTERPRET)
+			goto Lcant;
+		if (e2.isConst() != 1 &&
+			e2.op != TOKnull &&
+			e2.op != TOKstring &&
+			e2.op != TOKarrayliteral &&
+			e2.op != TOKstructliteral)
+			goto Lcant;
+
+		e = fp(op, type, e1, e2);
+		return e;
+
+	Lcant:
+		return EXP_CANT_INTERPRET;
 	}
 	
-    Expression interpretAssignCommon(InterState istate, Expression (*fp)(Type, Expression, Expression), int post = 0)
+    Expression interpretAssignCommon(InterState istate, Expression function(Type, Expression, Expression) fp, int post = 0)
 	{
-version (LOG) {
-		printf("BinExp.interpretAssignCommon() %.*s\n", toChars());
+version (LOG)
+{
+		writef("BinExp.interpretAssignCommon() %.*s\n", toChars());
 }
 		Expression e = EXP_CANT_INTERPRET;
 		Expression e1 = this.e1;
@@ -725,7 +804,7 @@
 			}
 			else if (v && v.value && (v.value.op==TOKindex || v.value.op == TOKdotvar))
 			{
-				// It is no longer be a TOKvar, eg when a[4] is passed by ref.
+				// It is no longer a TOKvar, eg when a[4] is passed by ref.
 				e1 = v.value;	    
 			}
 		}
@@ -748,13 +827,13 @@
 			VarExp ve = cast(VarExp)e1;
 			VarDeclaration v = ve.var.isVarDeclaration();
 			assert(v);
-			if (v && v.isDataseg())
+			if (v && !v.isCTFE())
 			{   
 				// Can't modify global or static data
 				error("%s cannot be modified at compile time", v.toChars());
 				return EXP_CANT_INTERPRET;
 			}
-			if (v && !v.isDataseg())
+			if (v && v.isCTFE())
 			{
 				Expression ev = v.value;
 				if (fp && !ev)
@@ -770,7 +849,7 @@
 					 */
 					if (v.type.toBasetype().ty == Tstruct && e2.op == TOKint64)
 					{
-						e2 = v.type.defaultInit(Loc(0));
+						e2 = v.type.defaultInitLiteral(Loc(0));
 					}
 					e2 = Cast(v.type, v.type, e2);
 				}
@@ -794,7 +873,7 @@
 		{	
 			VarDeclaration v = (cast(VarExp)aggregate).var.isVarDeclaration();
 
-			if (v.isDataseg())
+			if (!v.isCTFE())
 			{   
 				// Can't modify global or static data
 				error("%s cannot be modified at compile time", v.toChars());
@@ -871,7 +950,7 @@
 			SymOffExp soe = cast(SymOffExp)(cast(PtrExp)e1).e1;
 			VarDeclaration v = soe.var.isVarDeclaration();
 
-			if (v.isDataseg())
+			if (!v.isCTFE())
 			{
 				error("%s cannot be modified at compile time", v.toChars());
 				return EXP_CANT_INTERPRET;
@@ -919,7 +998,7 @@
 			IndexExp ie = cast(IndexExp)e1;
 			VarExp ve = cast(VarExp)ie.e1;
 			VarDeclaration v = ve.var.isVarDeclaration();
-			if (!v || v.isDataseg())
+			if (!v || !v.isCTFE())
 			{
 				error("%s cannot be modified at compile time", v ? v.toChars(): "void");
 				return EXP_CANT_INTERPRET;
@@ -1087,7 +1166,7 @@
 			IndexExp ie = cast(IndexExp)aggregate;
 			VarExp ve = cast(VarExp)(ie.e1);
 			VarDeclaration v = ve.var.isVarDeclaration();
-			if (!v || v.isDataseg())
+			if (!v || !v.isCTFE())
 			{
 				error("%s cannot be modified at compile time", v ? v.toChars(): "void");
 				return EXP_CANT_INTERPRET;
@@ -1110,8 +1189,7 @@
 				if (telem.ty != Tstruct) { return EXP_CANT_INTERPRET; }
 
 				// Create a default struct literal...
-				StructDeclaration sym = (cast(TypeStruct)telem).sym;
-				StructLiteralExp structinit = createDefaultInitStructLiteral(v.loc, sym);
+				Expression structinit = telem.defaultInitLiteral(v.loc);
 
 				// ... and use to create a blank array literal
 				size_t dim = cast(size_t)(cast(TypeSArray)t2).dim.toInteger();
@@ -1179,7 +1257,7 @@
 			SliceExp sexp = cast(SliceExp)e1;
 			VarExp ve = cast(VarExp)(sexp.e1);
 			VarDeclaration v = ve.var.isVarDeclaration();
-			if (!v || v.isDataseg())
+			if (!v || !v.isCTFE())
 			{
 				error("%s cannot be modified at compile time", v.toChars());
 				return EXP_CANT_INTERPRET;
@@ -1323,7 +1401,8 @@
 		}
 		return e;
 	}
-	
+
+	version(DMDV2)
     override bool canThrow()
 	{
 		return e1.canThrow() || e2.canThrow();
@@ -1382,7 +1461,7 @@
 			return new ErrorExp();
 		}
 		
-		Expressions arguments = new Expressions();
+		auto arguments = new Expressions();
 
 		/* The expression to generate an array operation for is mangled
 		 * into a name to use as the array operation function name.
@@ -1597,9 +1676,9 @@
 				 *	return p;
 				 */
 
-				Arguments fparams = new Arguments();
+				auto fparams = new Parameters();
 				Expression loopbody = buildArrayLoop(fparams);
-				Argument p = cast(Argument)fparams.data[0 /*fparams.dim - 1*/];
+				auto p = fparams[0 /*fparams.dim - 1*/];
 version (DMDV1) {
 				// for (size_t i = 0; i < p.length; i++)
 				Initializer init = new ExpInitializer(0, new IntegerExp(0, 0, Type.tsize_t));
@@ -1612,7 +1691,7 @@
 } else {
 				// foreach (i; 0 .. p.length)
 				Statement s1 = new ForeachRangeStatement(Loc(0), TOKforeach,
-					new Argument(STC.STCundefined, null, Id.p, null),
+					new Parameter(STC.STCundefined, null, Id.p, null),
 					new IntegerExp(Loc(0), 0, Type.tint32),
 					new ArrayLengthExp(Loc(0), new IdentifierExp(Loc(0), p.ident)),
 					new ExpStatement(Loc(0), loopbody));
@@ -1900,6 +1979,8 @@
 					case TOK.TOKleg:
 					case TOK.TOKue:
 						break;
+					default:
+						break;	///
 				}
 
 				return e;
@@ -1949,6 +2030,15 @@
 
 		return e;
 	}
+	final void AssignExp_buildArrayIdent(OutBuffer buf, Expressions arguments, string Str)
+	{							
+		/* Evaluate assign expressions right to left	
+		 */							
+		e2.buildArrayIdent(buf, arguments);		
+		e1.buildArrayIdent(buf, arguments);		
+		buf.writestring(Str);				
+		buf.writestring("ass");				
+	}
 	
 	final void Exp_buildArrayIdent(OutBuffer buf, Expressions arguments, string Str)
 	{									
@@ -1959,13 +2049,25 @@
 		buf.writestring(Str);						
 	}
 	
-	final void AssignExp_buildArrayIdent(OutBuffer buf, Expressions arguments, string Str)
-	{							
-		/* Evaluate assign expressions right to left	
-		 */							
-		e2.buildArrayIdent(buf, arguments);		
-		e1.buildArrayIdent(buf, arguments);		
-		buf.writestring(Str);				
-		buf.writestring("ass");				
+	final Expression AssignExp_buildArrayLoop(AssignExpType)(Parameters fparams)// if (is (AssignExpType : AssignExp))
+	{
+		/* Evaluate assign expressions right to left
+		 */
+		Expression ex2 = e2.buildArrayLoop(fparams);
+		Expression ex1 = e1.buildArrayLoop(fparams);
+		auto param = fparams[0];
+		param.storageClass = STCundefined;
+		Expression e = new AssignExpType(Loc(0), ex1, ex2);
+		return e;
 	}
-}
+	
+	final Expression Exp_buildArrayLoop(ExpType)(Parameters fparams) if (is (ExpType : BinExp))
+	{
+		/* Evaluate assign expressions left to right
+		 */
+		Expression ex1 = e1.buildArrayLoop(fparams);
+		Expression ex2 = e2.buildArrayLoop(fparams);
+		Expression e = new ExpType(Loc(0), ex1, ex2);
+		return e;
+	}
+}
\ No newline at end of file
--- a/dmd/BoolExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/BoolExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.BoolExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.backend.elem;
 import dmd.UnaExp;
@@ -10,6 +11,7 @@
 import dmd.IRState;
 import dmd.TOK;
 
+import dmd.expression.Bool;
 import dmd.backend.OPER;
 import dmd.backend.Util;
 
@@ -23,7 +25,7 @@
 
 	override Expression semantic(Scope sc)
 	{
-		UnaExp.semantic(sc);
+		super.semantic(sc);
 		e1 = resolveProperties(sc, e1);
 		e1 = e1.checkToBoolean();
 		type = Type.tboolean;
@@ -32,7 +34,16 @@
 
 	override Expression optimize(int result)
 	{
-		assert(false);
+		Expression e;
+
+	    e1 = e1.optimize(result);
+	    if (e1.isConst() == 1)
+	    {
+	        e = Bool(type, e1);
+	    }
+	    else
+	        e = this;
+	    return e;
 	}
 
 	override Expression interpret(InterState istate)
--- a/dmd/BreakStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/BreakStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.BreakStatement;
 
+import dmd.common;
 import dmd.Statement;
 import dmd.Loc;
 import dmd.Identifier;
--- a/dmd/CallExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/CallExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.CallExp;
 
+import dmd.common;
 import dmd.ErrorExp;
 import dmd.Expression;
 import dmd.Cast;
@@ -48,6 +49,7 @@
 import dmd.DotVarExp;
 import dmd.DotIdExp;
 import dmd.TY;
+import dmd.TRUST;
 import dmd.Id;
 import dmd.TypeAArray;
 import dmd.RemoveExp;
@@ -184,7 +186,8 @@
 
 					return new RemoveExp(loc, dotid.e1, key);
 				}
-				else if (e1ty == TY.Tarray || e1ty == TY.Tsarray || e1ty == TY.Taarray)
+				else if (e1ty == TY.Tarray || e1ty == TY.Tsarray ||
+				         (e1ty == Taarray && dotid.ident != Id.apply && dotid.ident != Id.applyReverse))
 				{
 					if (!arguments)
 						arguments = new Expressions();
@@ -212,25 +215,25 @@
 				 * If not, go with partial explicit specialization.
 				 */
 				ti.semanticTiargs(sc);
-				uint errors = global.errors;
-				global.gag++;
-				ti.semantic(sc);
-				global.gag--;
-				if (errors != global.errors)
+				if (ti.needsTypeInference(sc))
 				{
-					/* Didn't work, go with partial explicit specialization
+					/* Go with partial explicit specialization
 					 */
-					global.errors = errors;
 					targsi = ti.tiargs;
 					tierror = ti;			// for error reporting
 					e1 = new IdentifierExp(loc, ti.name);
 				}
+				else
+				{
+					ti.semantic(sc);
+				}
 			}
 		}
 
 		/* This recognizes:
 		 *	expr.foo!(tiargs)(funcargs)
 		 */
+Ldotti:
 		if (e1.op == TOK.TOKdotti && !e1.type)
 		{	
 			DotTemplateInstanceExp se = cast(DotTemplateInstanceExp)e1;
@@ -241,6 +244,7 @@
 				 * If not, go with partial explicit specialization.
 				 */
 				ti.semanticTiargs(sc);
+static if (false) {
 				Expression etmp = e1.trySemantic(sc);
 				if (etmp)
 					e1 = etmp;	// it worked
@@ -250,6 +254,24 @@
 					tierror = ti;		// for error reporting
 					e1 = new DotIdExp(loc, se.e1, ti.name);
 				}
+} else {
+				if (!ti.tempdecl)
+				{
+					se.getTempdecl(sc);
+				}
+				if (ti.tempdecl && ti.needsTypeInference(sc))
+				{
+				/* Go with partial explicit specialization
+				 */
+					targsi = ti.tiargs;
+					tierror = ti;			// for error reporting
+					e1 = new DotIdExp(loc, se.e1, ti.name);
+				}
+				else
+				{
+					e1 = e1.semantic(sc);
+				}
+}
 			}
 		}
 }
@@ -264,7 +286,21 @@
 		}
 		else
 		{
-			UnaExp.semantic(sc);
+			if (e1.op == TOK.TOKdot)
+			{
+				auto die = cast(DotIdExp)e1;
+				e1 = die.semantic(sc, 1);
+				/* Look for e1 having been rewritten to expr.opDispatch!(string)
+				 * We handle such earlier, so go back.
+				 * Note that in the rewrite, we carefully did not run semantic() on e1
+				 */
+				if (e1.op == TOK.TOKdotti && !e1.type)
+				{
+					goto Ldotti;
+				}
+			}
+			else
+				UnaExp.semantic(sc);
 
 			/* Look for e1 being a lazy parameter
 			 */
@@ -391,7 +427,7 @@
 		}
 
 		arrayExpressionSemantic(arguments, sc);
-		preFunctionArguments(loc, sc, arguments);
+		preFunctionParameters(loc, sc, arguments);
 
 		if (e1.op == TOK.TOKdotvar && t1.ty == TY.Tfunction ||
 			e1.op == TOK.TOKdottd)
@@ -448,6 +484,7 @@
 			checkDeprecated(sc, f);
 	version (DMDV2) {
 			checkPurity(sc, f);
+			checkSafety(sc, f);
 	}
 			accessCheck(loc, sc, ue.e1, f);
 			if (!f.needThis())
@@ -471,7 +508,7 @@
 				printf("e1 = %s\n", e1.toChars());
 				printf("e1.type = %s\n", e1.type.toChars());
 }
-				// Const member function can take const/immutable/mutable this
+				// Const member function can take const/immutable/mutable/inout this
 				if (!(f.type.isConst()))
 				{
 					// Check for const/immutable compatibility
@@ -480,14 +517,14 @@
 						tthis = tthis.nextOf().toBasetype();
 
 	static if (false) {	// this checking should have been already done
-					if (f.type.isInvariant())
+					if (f.type.isImmutable())
 					{
-						if (tthis.mod != MOD.MODinvariant)
+						if (tthis.mod != MOD.MODimmutable)
 							error("%s can only be called with an immutable object", e1.toChars());
 					}
 					else if (f.type.isShared())
 					{
-						if (tthis.mod != MOD.MODinvariant && tthis.mod != MOD.MODshared && tthis.mod != (MOD.MODshared | MOD.MODconst))
+						if (tthis.mod != MOD.MODimmutable && tthis.mod != MOD.MODshared && tthis.mod != (MOD.MODshared | MOD.MODconst))
 							error("shared %s can only be called with a shared or immutable object", e1.toChars());
 					}
 					else
@@ -561,6 +598,7 @@
 					checkDeprecated(sc, f);
 version (DMDV2) {
 					checkPurity(sc, f);
+					checkSafety(sc, f);
 }
 					e1 = new DotVarExp(e1.loc, e1, f);
 					e1 = e1.semantic(sc);
@@ -600,6 +638,7 @@
 				checkDeprecated(sc, f);
 version (DMDV2) {
 				checkPurity(sc, f);
+				checkSafety(sc, f);
 }
 				e1 = new DotVarExp(e1.loc, e1, f);
 				e1 = e1.semantic(sc);
@@ -667,6 +706,10 @@
 				{
 					error("pure function '%s' cannot call impure delegate '%s'", sc.func.toChars(), e1.toChars());
 				}
+				if (sc.func && sc.func.isSafe() && tf.trust <= TRUST.TRUSTsystem)
+				{
+					error("safe function '%s' cannot call system delegate '%s'", sc.func.toChars(), e1.toChars());
+				}
 				goto Lcheckargs;
 			}
 			else if (t1.ty == TY.Tpointer && (cast(TypePointer)t1).next.ty == TY.Tfunction)
@@ -677,6 +720,10 @@
 				{
 					error("pure function '%s' cannot call impure function pointer '%s'", sc.func.toChars(), e1.toChars());
 				}
+				if (sc.func && sc.func.isSafe() && !(cast(TypeFunction)t1).trust <= TRUST.TRUSTsystem)
+				{
+					error("safe function '%s' cannot call system function pointer '%s'", sc.func.toChars(), e1.toChars());
+				}
 				e.type = t1;
 				e1 = e;
 			}
@@ -706,8 +753,7 @@
 			else
 			{   
 				error("function expected before (), not %s of type %s", e1.toChars(), e1.type.toChars());
-				type = Type.terror;
-				return this;
+				return new ErrorExp();
 			}
 		}
 		else if (e1.op == TOK.TOKvar)
@@ -724,6 +770,7 @@
 			checkDeprecated(sc, f);
 version (DMDV2) {
 			checkPurity(sc, f);
+			checkSafety(sc, f);
 }
 
 			if (f.needThis() && hasThis(sc))
@@ -747,12 +794,11 @@
 
 	Lcheckargs:
 		assert(tf.ty == TY.Tfunction);
-		type = tf.next;
 
 		if (!arguments)
 			arguments = new Expressions();
 
-		functionArguments(loc, sc, tf, arguments);
+		type = functionParameters(loc, sc, tf, arguments);
 
 		if (!type)
 		{
--- a/dmd/CaseRangeStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/CaseRangeStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.CaseRangeStatement;
 
+import dmd.common;
 import dmd.Statement;
 import dmd.ArrayTypes;
 import dmd.Expression;
@@ -76,7 +77,7 @@
 				s = new ExpStatement(loc, null);
 			Expression e = new IntegerExp(loc, i, first.type);
 			Statement cs = new CaseStatement(loc, e, s);
-			statements.push(cast(void*)cs);
+			statements.push(cs);
 		}
 		Statement s = new CompoundStatement(loc, statements);
 		s = s.semantic(sc);
--- a/dmd/CaseStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/CaseStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.CaseStatement;
 
+import dmd.common;
 import dmd.Statement;
 import dmd.Expression;
 import dmd.Statement;
--- a/dmd/Cast.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/Cast.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.Cast;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Type;
 import dmd.Loc;
@@ -60,6 +61,9 @@
 		}
     }
 
+    if (e1.op == TOK.TOKarrayliteral && typeb == tb)
+        return e1;
+
     if (e1.isConst() != 1)
 		return EXP_CANT_INTERPRET;
 
--- a/dmd/CastExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/CastExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,6 +1,8 @@
 module dmd.CastExp;
 
+import dmd.common;
 import dmd.Expression;
+import dmd.GlobalExpressions;
 import dmd.TY;
 import dmd.TypeStruct;
 import dmd.ErrorExp;
@@ -106,6 +108,12 @@
 				}
 			}
 
+			if (e1.op == TOKtemplate)
+			{
+			    error("cannot cast template %s to type %s", e1.toChars(), to.toChars());
+			    return new ErrorExp();
+			}
+
 			Type t1b = e1.type.toBasetype();
 			Type tob = to.toBasetype();
 			if (tob.ty == TY.Tstruct &&
@@ -145,14 +153,18 @@
 			to = Type.terror;
 		}
 
-		if (global.params.safe && !sc.module_.safe && !sc.intypeof)
+//static if (true) {
+		if (sc.func && sc.func.isSafe() && !sc.intypeof)
+//} else {
+//		if (global.params.safe && !sc.module_.safe && !sc.intypeof)
+//}
 		{	// Disallow unsafe casts
 			Type tob = to.toBasetype();
 			Type t1b = e1.type.toBasetype();
 			if (!t1b.isMutable() && tob.isMutable())
 			{   // Cast not mutable to mutable
 			  Lunsafe:
-				error("cast from %s to %s not allowed in safe mode", e1.type.toChars(), to.toChars());
+				error("cast from %s to %s not allowed in safe code", e1.type.toChars(), to.toChars());
 			}
 			else if (t1b.isShared() && !tob.isShared())
 				// Cast away shared
@@ -171,6 +183,10 @@
 					// Cast away pointer to shared
 					goto Lunsafe;
 
+        	    if (t1bn.isWild() && !tobn.isConst() && !tobn.isWild())
+            		// Cast wild to anything but const | wild
+		            goto Lunsafe;
+
 				if (tobn.isTypeBasic() && tobn.size() < t1bn.size()) {
 					// Allow things like casting a long* to an int*
 					;
@@ -358,12 +374,34 @@
 
 	override Expression interpret(InterState istate)
 	{
-		assert(false);
+		Expression e;
+		Expression e1;
+
+version (LOG) {
+		printf("CastExp.interpret() %.*s\n", toChars());
+}
+		e1 = this.e1.interpret(istate);
+		if (e1 is EXP_CANT_INTERPRET)
+			goto Lcant;
+		return Cast(type, to, e1);
+
+	Lcant:
+version (LOG) {
+		printf("CastExp.interpret() %.*s CANT\n", toChars());
+}
+		return EXP_CANT_INTERPRET;
 	}
 
 	override bool checkSideEffect(int flag)
 	{
-		assert(false);
+		/* if not:
+		 *  cast(void)
+		 *  cast(classtype)func()
+		 */
+		if (!to.equals(Type.tvoid) && !(to.ty == Tclass && e1.op == TOKcall && e1.type.ty == Tclass))
+			return Expression.checkSideEffect(flag);
+			
+		return true;
 	}
 
 	override void checkEscape()
@@ -391,27 +429,7 @@
 			to.toCBuffer(buf, null, hgs);
 		else
 		{
-			switch (mod)
-			{   
-				case MODundefined:
-					break;
-				case MODconst:
-					buf.writestring(Token.tochars[TOKconst]);
-					break;
-				case MODinvariant:
-					buf.writestring(Token.tochars[TOKimmutable]);
-					break;
-				case MODshared:
-					buf.writestring(Token.tochars[TOKshared]);
-					break;
-				case MODshared | MODconst:
-					buf.writestring(Token.tochars[TOKshared]);
-					buf.writeByte(' ');
-					buf.writestring(Token.tochars[TOKconst]);
-					break;
-				default:
-					assert(0);
-			}
+			MODtoBuffer(buf, mod);
 		}
 	}
 		buf.writeByte(')');
@@ -429,7 +447,7 @@
 			Expression.buildArrayIdent(buf, arguments);
 	}
 
-	override Expression buildArrayLoop(Arguments fparams)
+	override Expression buildArrayLoop(Parameters fparams)
 	{
 		Type tb = type.toBasetype();
 		if (tb.ty == Tarray || tb.ty == Tsarray)
--- a/dmd/CatAssignExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/CatAssignExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,11 +1,13 @@
 module dmd.CatAssignExp;
 
+import dmd.common;
 import dmd.BinExp;
 import dmd.Loc;
 import dmd.Expression;
 import dmd.Scope;
 import dmd.InterState;
 import dmd.SliceExp;
+import dmd.ErrorExp;
 import dmd.Identifier;
 import dmd.IRState;
 import dmd.TOK;
@@ -19,6 +21,7 @@
 import dmd.backend.TYM;
 import dmd.backend.mTY;
 
+import dmd.expression.Cat;
 import dmd.expression.Util;
 
 class CatAssignExp : BinExp
@@ -54,10 +57,16 @@
 
 		e2.rvalue();
 
+        Type tb1next = tb1.nextOf();
+
 		if ((tb1.ty == Tarray) &&
 			(tb2.ty == Tarray || tb2.ty == Tsarray) &&
 			(e2.implicitConvTo(e1.type) ||
-			tb2.nextOf().implicitConvTo(tb1.nextOf()))
+//version(DMDV2) {
+			tb2.nextOf().implicitConvTo(tb1next)
+//}
+            )
+
 		   )
 		{	// Append array
 			e2 = e2.castTo(sc, e1.type);
@@ -65,25 +74,37 @@
 			e = this;
 		}
 		else if ((tb1.ty == Tarray) &&
-			e2.implicitConvTo(tb1.nextOf())
+			e2.implicitConvTo(tb1next)
 		   )
 		{	// Append element
-			e2 = e2.castTo(sc, tb1.nextOf());
+			e2 = e2.castTo(sc, tb1next);
 			type = e1.type;
 			e = this;
 		}
-		else
-		{
-			error("cannot append type %s to type %s", tb2.toChars(), tb1.toChars());
-			type = Type.tint32;
-			e = this;
-		}
+        else if (tb1.ty == Tarray &&
+	        (tb1next.ty == Tchar || tb1next.ty == Twchar) &&
+	        e2.implicitConvTo(Type.tdchar)
+           )
+        {	// Append dchar to char[] or wchar[]
+	        e2 = e2.castTo(sc, Type.tdchar);
+	        type = e1.type;
+	        e = this;
+
+	        /* Do not allow appending wchar to char[] because if wchar happens
+	         * to be a surrogate pair, nothing good can result.
+	         */
+        }
+        else
+        {
+	        error("cannot append type %s to type %s", tb2.toChars(), tb1.toChars());
+	        e = new ErrorExp();
+        }
 		return e;
 	}
 	
     override Expression interpret(InterState istate)
 	{
-		assert(false);
+    	return interpretAssignCommon(istate, &Cat);
 	}
 
     override Identifier opId()    /* For operator overloading */
@@ -98,16 +119,30 @@
 		Type tb1 = e1.type.toBasetype();
 		Type tb2 = e2.type.toBasetype();
 
-		if (tb1.ty == Tarray || tb2.ty == Tsarray)
-		{   elem* e1;
-			elem* e2;
-			elem* ep;
+		if (tb1.ty == Tarray && tb2.ty == Tdchar &&
+			(tb1.nextOf().ty == Tchar || tb1.nextOf().ty == Twchar))
+		{	// Append dchar to char[] or wchar[]
 
-			e1 = this.e1.toElem(irs);
+			auto e1 = this.e1.toElem(irs);
 			e1 = el_una(OPaddr, TYnptr, e1);
 
-			e2 = this.e2.toElem(irs);
-			if (tybasic(e2.Ety) == TYstruct)
+			auto e2 = this.e2.toElem(irs);
+
+			auto ep = el_params(e2, e1, null);
+			int rtl = (tb1.nextOf().ty == Tchar)
+				? RTLSYM_ARRAYAPPENDCD
+				: RTLSYM_ARRAYAPPENDWD;
+			e = el_bin(OPcall, TYdarray, el_var(rtlsym[rtl]), ep);
+			el_setLoc(e,loc);
+		}
+		else if (tb1.ty == Tarray || tb2.ty == Tsarray)
+		{
+			auto e1 = this.e1.toElem(irs);
+			e1 = el_una(OPaddr, TYnptr, e1);
+
+			auto e2 = this.e2.toElem(irs);
+		
+			if (tybasic(e2.Ety) == TYstruct || tybasic(e2.Ety) == TYarray)
 			{
 				e2 = el_una(OPstrpar, TYstruct, e2);
 				e2.Enumbytes = e2.E1.Enumbytes;
@@ -118,23 +153,13 @@
 			if ((tb2.ty == Tarray || tb2.ty == Tsarray) &&
 				tb1n.equals(tb2.nextOf().toBasetype()))
 			{   // Append array
-		static if (true) {
-				ep = el_params(e2, e1, this.e1.type.getTypeInfo(null).toElem(irs), null);
+				auto ep = el_params(e2, e1, this.e1.type.getTypeInfo(null).toElem(irs), null);
 				e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYAPPENDT]), ep);
-		} else {
-				ep = el_params(el_long(TYint, tb1n.size()), e2, e1, null);
-				e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYAPPEND]), ep);
-		}
 			}
 			else
 			{   // Append element
-		static if (true) {
-				ep = el_params(e2, e1, this.e1.type.getTypeInfo(null).toElem(irs), null);
+				auto ep = el_params(e2, e1, this.e1.type.getTypeInfo(null).toElem(irs), null);
 				e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYAPPENDCT]), ep);
-		} else {
-				ep = el_params(e2, el_long(TYint, tb1n.size()), e1, null);
-				e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYAPPENDC]), ep);
-		}
 			}
 			el_setLoc(e,loc);
 		}
--- a/dmd/CatExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/CatExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.CatExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Identifier;
 import dmd.InterState;
@@ -13,6 +14,7 @@
 import dmd.MATCH;
 import dmd.ArrayLiteralExp;
 import dmd.StringExp;
+import dmd.ErrorExp;
 import dmd.WANT;
 import dmd.Id;
 import dmd.GlobalExpressions;
@@ -58,10 +60,14 @@
 			e1.type.print();
 			e2.type.print();
 }
+        	Type tb1next = tb1.nextOf();
+	        Type tb2next = tb2.nextOf();
+            
 			if ((tb1.ty == Tsarray || tb1.ty == Tarray) &&
-				e2.type.implicitConvTo(tb1.nextOf()) >= MATCHconst)
+				e2.implicitConvTo(tb1next) >= MATCHconvert)
 			{
-				type = tb1.nextOf().arrayOf();
+				e2 = e2.implicitCastTo(sc, tb1next);
+                type = tb1next.arrayOf();
 				if (tb2.ty == Tarray)
 				{	
 					// Make e2 into [e2]
@@ -71,9 +77,10 @@
 				return this;
 			}
 			else if ((tb2.ty == Tsarray || tb2.ty == Tarray) &&
-				e1.type.implicitConvTo(tb2.nextOf()) >= MATCHconst)
+				e1.implicitConvTo(tb2next) >= MATCHconvert)
 			{
-				type = tb2.nextOf().arrayOf();
+				e1 = e1.implicitCastTo(sc, tb2next);
+                type = tb2next.arrayOf();
 				if (tb1.ty == Tarray)
 				{	
 					// Make e1 into [e1]
@@ -85,12 +92,12 @@
 
 			if ((tb1.ty == Tsarray || tb1.ty == Tarray) &&
 				(tb2.ty == Tsarray || tb2.ty == Tarray) &&
-				(tb1.nextOf().mod || tb2.nextOf().mod) &&
-				(tb1.nextOf().mod != tb2.nextOf().mod)
+	            (tb1next.mod || tb2next.mod) &&
+	            (tb1next.mod != tb2next.mod)
 			   )
 			{
-				Type t1 = tb1.nextOf().mutableOf().constOf().arrayOf();
-				Type t2 = tb2.nextOf().mutableOf().constOf().arrayOf();
+        	    Type t1 = tb1next.mutableOf().constOf().arrayOf();
+        	    Type t2 = tb2next.mutableOf().constOf().arrayOf();
 				if (e1.op == TOKstring && !(cast(StringExp)e1).committed)
 					e1.type = t1;
 				else
@@ -107,8 +114,8 @@
 			Type tb = type.toBasetype();
 			if (tb.ty == Tsarray)
 				type = tb.nextOf().arrayOf();
-			if (type.ty == Tarray && tb1.nextOf() && tb2.nextOf() &&
-				tb1.nextOf().mod != tb2.nextOf().mod)
+	        if (type.ty == Tarray && tb1next && tb2next &&
+	            tb1next.mod != tb2next.mod)
 			{
 				type = type.nextOf().toHeadMutable().arrayOf();
 			}
@@ -132,8 +139,7 @@
 				//printf("(%s) ~ (%s)\n", e1.toChars(), e2.toChars());
 				error("Can only concatenate arrays, not (%s ~ %s)",
 				e1.type.toChars(), e2.type.toChars());
-				type = Type.tint32;
-				e = this;
+				return new ErrorExp();
 			}
 			e.type = e.type.semantic(loc, sc);
 			return e;
--- a/dmd/Catch.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/Catch.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.Catch;
 
+import dmd.common;
 import dmd.Loc;
 import dmd.Type;
 import dmd.Scope;
--- a/dmd/ClassDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/ClassDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.ClassDeclaration;
 
+import dmd.common;
 import dmd.AggregateDeclaration;
 import dmd.InterfaceDeclaration;
 import dmd.ThisDeclaration;
@@ -9,7 +10,7 @@
 import dmd.CtorDeclaration;
 import dmd.TypeIdentifier;
 import dmd.STC;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.TypeTuple;
 import dmd.TY;
 import dmd.LINK;
@@ -24,6 +25,7 @@
 import dmd.ArrayTypes;
 import dmd.BaseClass;
 import dmd.ClassInfoDeclaration;
+import dmd.TypeInfoClassDeclaration;
 import dmd.Loc;
 import dmd.Identifier;
 import dmd.Dsymbol;
@@ -62,7 +64,7 @@
 import std.string;
 
 version (DMDV2) {
-	enum CLASSINFO_SIZE = (0x3C+16+4);	// value of ClassInfo.size
+	enum CLASSINFO_SIZE = (0x3C+12+4);	// value of ClassInfo.size
 } else {
 	enum CLASSINFO_SIZE = (0x3C+12+4);	// value of ClassInfo.size
 }
@@ -86,6 +88,10 @@
     static __gshared ClassDeclaration classinfo;
 
     ClassDeclaration baseClass;	// null only if this is Object
+version(DMDV1) {
+    CtorDeclaration *ctor;
+    CtorDeclaration *defaultCtor;	// default constructor
+}
     FuncDeclaration staticCtor;
     FuncDeclaration staticDtor;
     Array vtbl;				// Array of FuncDeclaration's making up the vtbl[]
@@ -101,12 +107,14 @@
     BaseClasses vtblInterfaces;	// array of base interfaces that have
 					// their own vtbl[]
 
-    ClassInfoDeclaration vclassinfo;	// the ClassInfo object for this ClassDeclaration
+    TypeInfoClassDeclaration vclassinfo;	// the ClassInfo object for this ClassDeclaration
     bool com;				// true if this is a COM class (meaning
 					// it derives from IUnknown)
     bool isauto;				// true if this is an auto class
     bool isabstract;			// true if abstract class
-
+version(DMDV1) {
+    int isnested;			// !=0 if is nested
+}
     int inuse;				// to prevent recursive attempts
 
     this(Loc loc, Identifier id, BaseClasses baseclasses)
@@ -250,6 +258,13 @@
 						Type.typeinfoshared.error("%s", msg);
 					Type.typeinfoshared = this;
 				}
+
+	            if (id == Id.TypeInfo_Wild)
+	            {
+                    if (Type.typeinfowild)
+		                Type.typeinfowild.error("%s", msg);
+		            Type.typeinfowild = this;
+	            }
 	}
 			}
 
@@ -260,7 +275,8 @@
 				object = this;
 			}
 
-			if (id is Id.ClassInfo)
+//			if (id is Id.ClassInfo)
+			if (id is Id.TypeInfo_Class)
 			{   
 				if (classinfo)
 					classinfo.error("%s", msg);
@@ -294,11 +310,11 @@
 		cd.storage_class |= storage_class;
 
 		cd.baseclasses.setDim(this.baseclasses.dim);
-		for (int i = 0; i < cd.baseclasses.dim; i++)
+		for (size_t i = 0; i < cd.baseclasses.dim; i++)
 		{
-			BaseClass b = cast(BaseClass)this.baseclasses.data[i];
-			BaseClass b2 = new BaseClass(b.type.syntaxCopy(), b.protection);
-			cd.baseclasses.data[i] = cast(void*)b2;
+			auto b = this.baseclasses[i];
+			auto b2 = new BaseClass(b.type.syntaxCopy(), b.protection);
+			cd.baseclasses[i] = b2;
 		}
 
 		ScopeDsymbol.syntaxCopy(cd);
@@ -336,7 +352,7 @@
 			return;
 		}
 		if (symtab)
-		{	if (!scope_)
+		{	if (sizeok == 1 || !scope_)
 		{   //printf("\tsemantic for '%s' is already completed\n", toChars());
 			return;		// semantic() already completed
 		}
@@ -363,9 +379,9 @@
 		error("cannot create C++ classes");
 
 		// Expand any tuples in baseclasses[]
-		for (int i = 0; i < baseclasses.dim; )
+		for (size_t i = 0; i < baseclasses.dim; )
 		{	
-			BaseClass b = cast(BaseClass)baseclasses.data[i];
+			auto b = baseclasses[i];
 		//printf("test1 %s %s\n", toChars(), b.type.toChars());
 			b.type = b.type.semantic(loc, sc);
 		//printf("test2\n");
@@ -376,12 +392,12 @@
 				TypeTuple tup = cast(TypeTuple)tb;
 				enum PROT protection = b.protection;
 				baseclasses.remove(i);
-				size_t dim = Argument.dim(tup.arguments);
+				size_t dim = Parameter.dim(tup.arguments);
 				for (size_t j = 0; j < dim; j++)
 				{	
-					Argument arg = Argument.getNth(tup.arguments, j);
+					auto arg = Parameter.getNth(tup.arguments, j);
 					b = new BaseClass(arg.type, protection);
-					baseclasses.insert(i + j, cast(void*)b);
+					baseclasses.insert(i + j, b);
 				}
 			}
 			else
@@ -395,7 +411,7 @@
 			BaseClass b;
 			Type tb;
 
-			b = cast(BaseClass)baseclasses.data[0];
+			b = baseclasses[0];
 			//b.type = b.type.semantic(loc, sc);
 			tb = b.type.toBasetype();
 			if (tb.ty != TY.Tclass)
@@ -463,7 +479,7 @@
 		BaseClass b;
 		Type tb;
 
-		b = cast(BaseClass)baseclasses.data[i];
+		b = baseclasses[i];
 		b.type = b.type.semantic(loc, sc);
 		tb = b.type.toBasetype();
 		if (tb.ty == TY.Tclass)
@@ -492,7 +508,7 @@
 			// Check for duplicate interfaces
 			for (size_t j = (baseClass ? 1 : 0); j < i; j++)
 			{
-			BaseClass b2 = cast(BaseClass)baseclasses.data[j];
+			auto b2 = baseclasses[j];
 			if (b2.base == tc.sym)
 				error("inherits from duplicate interface %s", b2.base.toChars());
 			}
@@ -537,7 +553,7 @@
 			}
 			bt = tbase.semantic(loc, sc).toBasetype();
 			b = new BaseClass(bt, PROT.PROTpublic);
-			baseclasses.shift(cast(void*)b);
+			baseclasses.shift(b);
 			assert(b.type.ty == TY.Tclass);
 			tc = cast(TypeClass)(b.type);
 			baseClass = tc.sym;
@@ -546,7 +562,7 @@
 		}
 
 		interfaces_dim = baseclasses.dim;
-		interfaces = cast(BaseClass*)baseclasses.data;
+		interfaces = baseclasses.ptr;
 
 		if (baseClass)
 		{
@@ -664,7 +680,7 @@
 
 		if (isCOMclass())
 		{
-version (_WIN32) {
+version (Windows) {
 		sc.linkage = LINK.LINKwindows;
 } else {
 		/* This enables us to use COM objects under Linux and
@@ -690,6 +706,22 @@
 		structsize = sc.offset;
 		Scope scsave = sc.clone();
 		sizeok = 0;
+
+        /* Set scope so if there are forward references, we still might be able to
+         * resolve individual members like enums.
+         */
+        foreach (s; members)
+        {
+	        /* There are problems doing this in the general case because
+	         * Scope keeps track of things like 'offset'
+	         */
+	        if (s.isEnumDeclaration() || (s.isAggregateDeclaration() && s.ident))
+	        {
+	            //printf("setScope %s %s\n", s->kind(), s->toChars());
+	            s.setScope(sc);
+	        }
+        }
+            
 		foreach (Dsymbol s; members) {
 			s.semantic(sc);
 		}
@@ -763,9 +795,8 @@
 }
 
 		// Allocate instance of each new interface
-		for (int i = 0; i < vtblInterfaces.dim; i++)
+		foreach (b; vtblInterfaces)
 		{
-			BaseClass b = cast(BaseClass)vtblInterfaces.data[i];
 			uint thissize = PTRSIZE;
 
 			alignmember(structalign, thissize, &sc.offset);
@@ -812,10 +843,8 @@
 			if (baseclasses.dim)
 				buf.writestring(" : ");
 		}
-		for (int i = 0; i < baseclasses.dim; i++)
+		foreach (size_t i, BaseClass b; baseclasses)
 		{
-			BaseClass b = cast(BaseClass)baseclasses.data[i];
-
 			if (i)
 				buf.writeByte(',');
 			//buf.writestring(b.base.ident.toChars());
@@ -847,10 +876,8 @@
 		if (!cd)
 			return 0;
 		//printf("ClassDeclaration::isBaseOf2(this = '%s', cd = '%s')\n", toChars(), cd.toChars());
-		for (int i = 0; i < cd.baseclasses.dim; i++)
+		foreach (b; cd.baseclasses)
 		{	
-			BaseClass b = cast(BaseClass)cd.baseclasses.data[i];
-
 			if (b.base is this || isBaseOf2(b.base))
 				return 1;
 		}
@@ -866,10 +893,8 @@
 		if (!cd)
 			return 0;
 		//printf("ClassDeclaration::isBaseOf2(this = '%s', cd = '%s')\n", toChars(), cd.toChars());
-		for (int i = 0; i < cd.baseclasses.dim; i++)
+		foreach (b; cd.baseclasses)
 		{	
-			BaseClass b = cast(BaseClass)cd.baseclasses.data[i];
-
 			if (b.base == this || isBaseOf2(b.base))
 				return 1;
 		}
@@ -904,10 +929,8 @@
 
 			int i;
 
-			for (i = 0; i < baseclasses.dim; i++)
+			foreach (b; baseclasses)
 			{
-				BaseClass b = cast(BaseClass)baseclasses.data[i];
-
 				if (b.base)
 				{
 					if (!b.base.symtab)
@@ -1015,11 +1038,18 @@
 			if (b.base.isCPPinterface() && id)
 				id.cpp = 1;
 
-			vtblInterfaces.push(cast(void*)b);
+			vtblInterfaces.push(b);
 			b.copyBaseInterfaces(vtblInterfaces);
 		}
 	}
 
+version(DMDV1)
+{
+    int isNested()
+	{
+		assert(false);
+	}
+}
     bool isCOMclass()
 	{
 		return com;
@@ -1120,17 +1150,14 @@
 		else
 		{
 			PROT access;
-			int i;
 
 			if (smember.isDeclaration().isStatic())
 			{
 				access_ret = smember.prot();
 			}
 
-			for (i = 0; i < baseclasses.dim; i++)
+			foreach (b; baseclasses)
 			{   
-				BaseClass b = cast(BaseClass)baseclasses.data[i];
-
 				access = b.base.getAccess(smember);
 				switch (access)
 				{
@@ -1170,7 +1197,7 @@
 
     override void addLocalClass(ClassDeclarations aclasses)
 	{
-		aclasses.push(cast(void*)this);
+		aclasses.push(this);
 	}
 
     // Back end
@@ -1289,7 +1316,7 @@
 
 		// Put out the TypeInfo
 		type.getTypeInfo(null);
-		type.vtinfo.toObjFile(multiobj);
+		//type.vtinfo.toObjFile(multiobj);
 
 		//////////////////////////////////////////////
 
@@ -1313,7 +1340,7 @@
 			OffsetTypeInfo[] offTi;
 			void *defaultConstructor;
 			const(MemberInfo[]) function(string) xgetMembers;	// module getMembers() function
-			TypeInfo typeinfo;
+			//TypeInfo typeinfo;
 		   }
 		 */
 		dt_t* dt = null;
@@ -1426,7 +1453,7 @@
 			dtdword(&dt, 0);	// module getMembers() function
 	}
 
-		dtxoff(&dt, type.vtinfo.toSymbol(), 0, TYnptr);	// typeinfo
+		//dtxoff(&dt, type.vtinfo.toSymbol(), 0, TYnptr);	// typeinfo
 		//dtdword(&dt, 0);
 
 		//////////////////////////////////////////////
@@ -1435,16 +1462,16 @@
 		// of the fixup (*)
 
 		offset += vtblInterfaces.dim * (4 * PTRSIZE);
-		for (size_t i = 0; i < vtblInterfaces.dim; i++)
+		foreach (b; vtblInterfaces)
 		{	
-			BaseClass b = cast(BaseClass)vtblInterfaces.data[i];
 			ClassDeclaration id = b.base;
 
 			/* The layout is:
-			 *  {
+	         *  struct Interface
+             *  {
 			 *	ClassInfo *interface;
 			 *	void *[] vtbl;
-			 *	unsigned offset;
+			 *	ptrdiff_t offset;
 			 *  }
 			 */
 
@@ -1465,9 +1492,8 @@
 		// Put out the vtblInterfaces.data[].vtbl[]
 		// This must be mirrored with ClassDeclaration.baseVtblOffset()
 		//printf("putting out %d interface vtbl[]s for '%s'\n", vtblInterfaces.dim, toChars());
-		for (size_t i = 0; i < vtblInterfaces.dim; i++)
+		foreach (size_t i, BaseClass b; vtblInterfaces)
 		{	
-			BaseClass b = cast(BaseClass)vtblInterfaces.data[i];
 			ClassDeclaration id = b.base;
 			int j;
 
@@ -1486,8 +1512,6 @@
 			assert(id.vtbl.dim == b.vtbl.dim);
 			for (; j < id.vtbl.dim; j++)
 			{
-				FuncDeclaration fd;
-
 				assert(j < b.vtbl.dim);
 		static if (false) {
 				Object o = cast(Object)b.vtbl.data[j];
@@ -1499,7 +1523,7 @@
 					printf("s.kind() = '%s'\n", s.kind());
 				}
 		}
-				fd = cast(FuncDeclaration)b.vtbl.data[j];
+				auto fd = cast(FuncDeclaration)b.vtbl.data[j];
 				if (fd)
 					dtxoff(&dt, fd.toThunkSymbol(b.offset), 0, TYnptr);
 				else
@@ -1516,10 +1540,8 @@
 
 		for (cd = this.baseClass; cd; cd = cd.baseClass)
 		{
-			for (int k = 0; k < cd.vtblInterfaces.dim; k++)
+			foreach (size_t k, BaseClass bs; cd.vtblInterfaces)
 			{   
-				BaseClass bs = cast(BaseClass)cd.vtblInterfaces.data[k];
-
 				if (bs.fillVtbl(this, bvtbl, 0))
 				{
 					//printf("\toverriding vtbl[] for %s\n", bs.base.toChars());
@@ -1650,7 +1672,7 @@
 							{
 								TypeFunction tf = cast(TypeFunction)fd.type;
 								if (tf.ty == Tfunction)
-									warning("%s%s is hidden by %s\n", fd.toPrettyChars(), Argument.argsTypesToChars(tf.parameters, tf.varargs), toChars());
+									warning("%s%s is hidden by %s\n", fd.toPrettyChars(), Parameter.argsTypesToChars(tf.parameters, tf.varargs), toChars());
 								else
 									warning("%s is hidden by %s\n", fd.toPrettyChars(), toChars());
 							}
@@ -1697,10 +1719,8 @@
 		csymoffset = CLASSINFO_SIZE;
 		csymoffset += vtblInterfaces.dim * (4 * PTRSIZE);
 
-		for (size_t i = 0; i < vtblInterfaces.dim; i++)
+		foreach (b; vtblInterfaces)
 		{
-			BaseClass b = cast(BaseClass)vtblInterfaces.data[i];
-
 			if (b == bc)
 				return csymoffset;
 			csymoffset += b.base.vtbl.dim * PTRSIZE;
@@ -1715,10 +1735,8 @@
 
 		for (cd = this.baseClass; cd; cd = cd.baseClass)
 		{
-			for (int k = 0; k < cd.vtblInterfaces.dim; k++)
+			foreach(bs; cd.vtblInterfaces)
 			{   
-				BaseClass bs = cast(BaseClass)cd.vtblInterfaces.data[k];
-
 				if (bs.fillVtbl(this, null, 0))
 				{
 					if (bc == bs)
@@ -1883,10 +1901,8 @@
 		// Interface vptr initializations
 		toSymbol();						// define csym
 
-		for (size_t i = 0; i < vtblInterfaces.dim; i++)
+		foreach (b; vtblInterfaces)
 		{	
-			BaseClass b = cast(BaseClass)vtblInterfaces.data[i];
-
 ///		version (1 || INTERFACE_VIRTUAL) {
 			for (ClassDeclaration cd2 = cd; 1; cd2 = cd2.baseClass)
 			{
--- a/dmd/ClassInfoDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/ClassInfoDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.ClassInfoDeclaration;
 
+import dmd.common;
 import dmd.VarDeclaration;
 import dmd.ClassDeclaration;
 import dmd.Dsymbol;
@@ -19,9 +20,9 @@
 
 class ClassInfoDeclaration : VarDeclaration
 {
-    ClassDeclaration cd;
+	ClassDeclaration cd;
 
-    this(ClassDeclaration cd)
+	this(ClassDeclaration cd)
 	{
 		super(Loc(0), ClassDeclaration.classinfo.type, cd.ident, null);
 		
@@ -29,26 +30,25 @@
 		storage_class = STC.STCstatic | STC.STCgshared;
 	}
 	
-    override Dsymbol syntaxCopy(Dsymbol)
+	override Dsymbol syntaxCopy(Dsymbol)
 	{
-		assert(false);
+		 assert(false);		// should never be produced by syntax
+		 return null;
 	}
 	
-    override void semantic(Scope sc)
+	override void semantic(Scope sc)
 	{
-		assert(false);
 	}
 
-    override void emitComment(Scope sc)
+	override void emitComment(Scope sc)
 	{
-		assert(false);
 	}
 
 	override void toJsonBuffer(OutBuffer buf)
 	{
 	}
-    
-    override Symbol* toSymbol()
+	
+	override Symbol* toSymbol()
 	{
 		return cd.toSymbol();
 	}
--- a/dmd/CmpExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/CmpExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.CmpExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Identifier;
 import dmd.backend.elem;
@@ -140,7 +141,7 @@
 
 	override Expression interpret(InterState istate)
 	{
-		assert(false);
+		return interpretCommon2(istate, &Cmp);
 	}
 
 	override int isBit()
--- a/dmd/ComExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/ComExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.ComExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Identifier;
 import dmd.backend.elem;
@@ -12,6 +13,7 @@
 import dmd.ArrayTypes;
 import dmd.TOK;
 import dmd.TY;
+import dmd.Id;
 
 import dmd.backend.Util;
 import dmd.backend.OPER;
@@ -68,17 +70,20 @@
 
 	override void buildArrayIdent(OutBuffer buf, Expressions arguments)
 	{
-		assert(false);
+		e1.buildArrayIdent(buf, arguments);
+		buf.writestring("Com");
 	}
 
-	override Expression buildArrayLoop(Arguments fparams)
+	override Expression buildArrayLoop(Parameters fparams)
 	{
-		assert(false);
+		Expression ex1 = e1.buildArrayLoop(fparams);
+		Expression e = new ComExp(Loc(0), ex1);
+		return e;
 	}
 
 	override Identifier opId()
 	{
-		assert(false);
+		return Id.com;
 	}
 
 	override elem* toElem(IRState* irs)
--- a/dmd/CommaExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/CommaExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.CommaExp;
 
+import dmd.common;
 import dmd.Loc;
 import dmd.BinExp;
 import dmd.IRState;
@@ -37,6 +38,11 @@
 		e2.checkEscape();
 	}
 	
+    override void checkEscapeRef()
+    {
+        e2.checkEscapeRef();
+    }
+    
     override IntRange getIntRange()
 	{
 		assert(false);
--- a/dmd/CompileDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/CompileDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.CompileDeclaration;
 
+import dmd.common;
 import dmd.AttribDeclaration;
 import dmd.WANT;
 import dmd.TOK;
--- a/dmd/CompileExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/CompileExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.CompileExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.UnaExp;
 import dmd.OutBuffer;
--- a/dmd/CompileStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/CompileStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.CompileStatement;
 
+import dmd.common;
 import dmd.Statement;
 import dmd.Expression;
 import dmd.Loc;
@@ -60,7 +61,7 @@
 		while (p.token.value != TOK.TOKeof)
 		{
 			Statement s = p.parseStatement(ParseStatementFlags.PSsemi | ParseStatementFlags.PScurlyscope);
-			a.push(cast(void*)s);
+			a.push(s);
 		}
 		return a;
 	}
--- a/dmd/Complex.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/Complex.d	Tue Sep 14 15:46:50 2010 +0200
@@ -4,4 +4,6 @@
 {
 	T re;
 	T im;
+	
+	public static const Complex zero = Complex(0, 0);
 }
\ No newline at end of file
--- a/dmd/ComplexExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/ComplexExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.ComplexExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.InterState;
 import dmd.Type;
@@ -13,6 +14,7 @@
 import dmd.TY;
 import dmd.Port;
 import dmd.Complex;
+import dmd.expression.Util;
 
 import dmd.backend.dt_t;
 import dmd.backend.elem;
@@ -104,7 +106,10 @@
 
 	override bool isBool(bool result)
 	{
-		assert(false);
+		if (result)
+			return value != Complex!(real).zero;
+		else
+			return value == Complex!(real).zero;
 	}
 
 	override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
@@ -114,10 +119,15 @@
 
 	override void toMangleBuffer(OutBuffer buf)
 	{
-		assert(false);
+		buf.writeByte('c');
+		real r = toReal();
+		realToMangleBuffer(buf, r);
+		buf.writeByte('c');	// separate the two
+		r = toImaginary();
+		realToMangleBuffer(buf, r);
 	}
+	
 version (_DH) {
-
 	OutBuffer hexp;
 }
 
--- a/dmd/CompoundDeclarationStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/CompoundDeclarationStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.CompoundDeclarationStatement;
 
+import dmd.common;
 import dmd.CompoundStatement;
 import dmd.Loc;
 import dmd.ArrayTypes;
@@ -21,10 +22,10 @@
 		a.setDim(statements.dim);
 		for (size_t i = 0; i < statements.dim; i++)
 		{	
-			Statement s = cast(Statement)statements.data[i];
+			Statement s = statements[i];
 			if (s)
 				s = s.syntaxCopy();
-			a.data[i] = cast(void*)s;
+			a[i] = s;
 		}
 		CompoundDeclarationStatement cs = new CompoundDeclarationStatement(loc, a);
 		return cs;
--- a/dmd/CompoundStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/CompoundStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.CompoundStatement;
 
+import dmd.common;
 import dmd.Loc;
 import dmd.Statement;
 import dmd.Array;
@@ -42,8 +43,8 @@
 		
 		statements = new Statements();
 		statements.reserve(2);
-		statements.push(cast(void*)s1);
-		statements.push(cast(void*)s2);
+		statements.push(s1);
+		statements.push(s2);
 	}
 	
     override Statement syntaxCopy()
@@ -51,12 +52,11 @@
 		Statements a = new Statements();
 		a.setDim(statements.dim);
 
-		for (size_t i = 0; i < statements.dim; i++)
+		foreach (size_t i, Statement s; statements)
 		{	
-			Statement s = cast(Statement)statements.data[i];
 			if (s)
 				s = s.syntaxCopy();
-			a.data[i] = cast(void*)s;
+			a[i] = s;
 		}
 
 		return new CompoundStatement(loc, a);
@@ -64,8 +64,8 @@
 	
 	override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
 	{
-		for (int i = 0; i < statements.dim; i++)
-		{   Statement s = cast(Statement) statements.data[i];
+		foreach (s; statements)
+		{
 			if (s)
 				s.toCBuffer(buf, hgs);
 		}
@@ -82,7 +82,7 @@
 
 		for (size_t i = 0; i < statements.dim; )
 		{
-			s = cast(Statement) statements.data[i];
+			s = statements[i];
 			if (s)
 			{   
 				Statements a = s.flatten(sc);
@@ -96,7 +96,7 @@
 				
 				s = s.semantic(sc);
 
-				statements.data[i] = cast(void*)s;
+				statements[i] = s;
 				if (s)
 				{
 					Statement sentry;
@@ -109,11 +109,11 @@
 						sentry = sentry.semantic(sc);
 						if (s.isDeclarationStatement())
 						{	
-							statements.insert(i, cast(void*)sentry);
+							statements.insert(i, sentry);
 							i++;
 						}
 						else
-							statements.data[i] = cast(void*)sentry;
+							statements[i] = sentry;
 					}
 					if (sexception)
 					{
@@ -143,7 +143,7 @@
 
 							for (int j = i + 1; j < statements.dim; j++)
 							{
-								aa.push(statements.data[j]);
+								aa.push(statements[j]);
 							}
 							body_ = new CompoundStatement(Loc(0), aa);
 							body_ = new ScopeStatement(Loc(0), body_);
@@ -162,7 +162,7 @@
 								s = new TryFinallyStatement(Loc(0), s, sfinally);
 							s = s.semantic(sc);
 							statements.setDim(i + 1);
-							statements.push(cast(void*)s);
+							statements.push(s);
 							break;
 						}
 					}
@@ -170,7 +170,7 @@
 					{
 						if (0 && i + 1 == statements.dim)
 						{
-							statements.push(cast(void*)sfinally);
+							statements.push(sfinally);
 						}
 						else
 						{
@@ -184,13 +184,13 @@
 
 							for (int j = i + 1; j < statements.dim; j++)
 							{
-								aa.push(statements.data[j]);
+								aa.push(statements[j]);
 							}
 							body_ = new CompoundStatement(Loc(0), aa);
 							s = new TryFinallyStatement(Loc(0), body_, sfinally);
 							s = s.semantic(sc);
 							statements.setDim(i + 1);
-							statements.push(cast(void*)s);
+							statements.push(s);
 							break;
 						}
 					}
@@ -200,22 +200,28 @@
 		}
 		if (statements.dim == 1)
 		{
-			return cast(Statement)statements.data[0];
+			return statements[0];
 		}
 		return this;
 	}
 	
     override bool usesEH()
 	{
-		assert(false);
+		foreach (Statement s; statements)
+		{	
+			if (s && s.usesEH())
+				return true;
+		}
+		
+		return false;
 	}
 	
     override BE blockExit()
 	{
 		//printf("CompoundStatement::blockExit(%p) %d\n", this, statements->dim);
 		BE result = BE.BEfallthru;
-		for (size_t i = 0; i < statements.dim; i++)
-		{	Statement s = cast(Statement)statements.data[i];
+		foreach (s; statements)
+		{
 			if (s)
 			{
 				//printf("result = x%x\n", result);
@@ -243,9 +249,8 @@
 	
     override bool isEmpty()
 	{
-		for (int i = 0; i < statements.dim; i++)
+		foreach (s; statements)
 		{	
-			Statement s = cast(Statement) statements.data[i];
 			if (s && !s.isEmpty())
 				return false;
 		}
@@ -261,9 +266,8 @@
 	{
 		ReturnStatement rs = null;
 
-		for (int i = 0; i < statements.dim; i++)
+		foreach(s; statements)
 		{	
-			Statement s = cast(Statement) statements.data[i];
 			if (s)
 			{
 				rs = s.isReturnStatement();
@@ -285,10 +289,8 @@
 			istate.start = null;
 		if (statements)
 		{
-			for (size_t i = 0; i < statements.dim; i++)
+			foreach(s; statements)
 			{   
-				Statement s = cast(Statement)statements.data[i];
-
 				if (s)
 				{
 					e = s.interpret(istate);
@@ -307,9 +309,8 @@
 	{
 		int cost = 0;
 
-		for (size_t i = 0; i < statements.dim; i++)
+		foreach(s; statements)
 		{	
-			Statement s = cast(Statement)statements.data[i];
 			if (s)
 			{
 				cost += s.inlineCost(ics);
@@ -326,9 +327,8 @@
 		Expression e = null;
 
 		//printf("CompoundStatement.doInline() %d\n", statements.dim);
-		for (size_t i = 0; i < statements.dim; i++)
+		foreach(s; statements)
 		{	
-			Statement s = cast(Statement)statements.data[i];
 			if (s)
 			{
 				Expression e2 = s.doInline(ids);
@@ -355,11 +355,10 @@
 	
     override Statement inlineScan(InlineScanState* iss)
 	{
-		for (size_t i = 0; i < statements.dim; i++)
+		foreach(ref Statement s; statements)
 		{	
-			Statement s = cast(Statement) statements.data[i];
 			if (s)
-				statements.data[i] = cast(void*)s.inlineScan(iss);
+				s = s.inlineScan(iss);
 		}
 
 		return this;
@@ -369,10 +368,8 @@
 	{
 		if (statements)
 		{
-			size_t dim = statements.dim;
-			for (size_t i = 0 ; i < dim ; i++)
+			foreach(s; statements)
 			{
-				Statement s = cast(Statement)statements.data[i];
 				if (s !is null)
 				{
 					s.toIR(irs);
--- a/dmd/CondExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/CondExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,9 +1,12 @@
 module dmd.CondExp;
 
+import dmd.common;
 import dmd.BinExp;
 import dmd.Loc;
+import dmd.PtrExp;
 import dmd.MATCH;
 import dmd.Expression;
+import dmd.GlobalExpressions;
 import dmd.Scope;
 import dmd.InterState;
 import dmd.OutBuffer;
@@ -159,7 +162,20 @@
 	
     override Expression interpret(InterState istate)
 	{
-		assert(false);
+version (LOG) {
+		printf("CondExp.interpret() %.*s\n", toChars());
+}
+		Expression e = econd.interpret(istate);
+		if (e !is EXP_CANT_INTERPRET)
+		{
+			if (e.isBool(true))
+				e = e1.interpret(istate);
+			else if (e.isBool(false))
+				e = e2.interpret(istate);
+			else
+				e = EXP_CANT_INTERPRET;
+		}
+		return e;
 	}
 
     override void checkEscape()
@@ -168,24 +184,49 @@
 		e2.checkEscape();
 	}
 
+    override void checkEscapeRef()
+    {
+        e1.checkEscapeRef();
+        e2.checkEscapeRef();
+    }
+    
     override int isLvalue()
 	{
-		assert(false);
+		return e1.isLvalue() && e2.isLvalue();
 	}
 
-    override Expression toLvalue(Scope sc, Expression e)
+    override Expression toLvalue(Scope sc, Expression ex)
 	{
-		assert(false);
+		PtrExp e;
+
+		// convert (econd ? e1 : e2) to *(econd ? &e1 : &e2)
+		e = new PtrExp(loc, this, type);
+
+		e1 = e1.addressOf(sc);
+		//e1 = e1.toLvalue(sc, null);
+
+		e2 = e2.addressOf(sc);
+		//e2 = e2.toLvalue(sc, null);
+
+		typeCombine(sc);
+
+		type = e2.type;
+		return e;
 	}
 
     override Expression modifiableLvalue(Scope sc, Expression e)
 	{
-		assert(false);
+        //error("conditional expression %s is not a modifiable lvalue", toChars());
+        e1 = e1.modifiableLvalue(sc, e1);
+        e2 = e2.modifiableLvalue(sc, e1);
+        return toLvalue(sc, this);
 	}
 
     override Expression checkToBoolean()
 	{
-		assert(false);
+		e1 = e1.checkToBoolean();
+		e2 = e2.checkToBoolean();
+		return this;
 	}
 
     override bool checkSideEffect(int flag)
--- a/dmd/Condition.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/Condition.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.Condition;
 
+import dmd.common;
 import dmd.Loc;
 import dmd.Scope;
 import dmd.ScopeDsymbol;
--- a/dmd/ConditionalDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/ConditionalDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.ConditionalDeclaration;
 
+import dmd.common;
 import dmd.AttribDeclaration;
 import dmd.Condition;
 import dmd.Array;
--- a/dmd/ConditionalStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/ConditionalStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.ConditionalStatement;
 
+import dmd.common;
 import dmd.Statement;
 import dmd.Condition;
 import dmd.Loc;
@@ -61,8 +62,8 @@
 		else
 			s = elsebody;
 
-		Statements a = new Statements();
-		a.push(cast(void*)s);
+		auto a = new Statements();
+		a.push(s);
 
 		return a;
 	}
--- a/dmd/ContinueStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/ContinueStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.ContinueStatement;
 
+import dmd.common;
 import dmd.Statement;
 import dmd.FuncDeclaration;
 import dmd.IntegerExp;
--- a/dmd/CppMangleState.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/CppMangleState.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.CppMangleState;
 
+import dmd.common;
 import dmd.Array;
 import dmd.OutBuffer;
 
--- a/dmd/CtorDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/CtorDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.CtorDeclaration;
 
+import dmd.common;
 import dmd.FuncDeclaration;
 import dmd.ArrayTypes;
 import dmd.Loc;
@@ -18,15 +19,15 @@
 import dmd.Statement;
 import dmd.ReturnStatement;
 import dmd.CompoundStatement;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.Id;
 
 class CtorDeclaration : FuncDeclaration
 {
-	Arguments arguments;
+	Parameters arguments;
     int varargs;
 
-    this(Loc loc, Loc endloc, Arguments arguments, int varargs)
+    this(Loc loc, Loc endloc, Parameters arguments, int varargs)
 	{
 		super(loc, endloc, Id.ctor, STC.STCundefined, null);
 		
@@ -45,7 +46,7 @@
 		f.fbody    = fbody    ? fbody.syntaxCopy()    : null;
 		assert(!fthrows); // deprecated
 
-		f.arguments = Argument.arraySyntaxCopy(arguments);
+		f.arguments = Parameter.arraySyntaxCopy(arguments);
 		return f;
 	}
 	
@@ -102,7 +103,7 @@
 		sc.pop();
 
 		// See if it's the default constructor
-		if (ad && varargs == 0 && Argument.dim(arguments) == 0)
+		if (ad && varargs == 0 && Parameter.dim(arguments) == 0)
 		{	if (ad.isStructDeclaration())
 			error("default constructor not allowed for structs");
 		else
--- a/dmd/DVCondition.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/DVCondition.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.DVCondition;
 
+import dmd.common;
 import dmd.Condition;
 import dmd.Identifier;
 import dmd.Module;
--- a/dmd/Dchar.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/Dchar.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.Dchar;
 
+import dmd.common;
 import core.stdc.wchar_;
 import core.stdc.string;
 import core.stdc.ctype;
--- a/dmd/DebugCondition.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/DebugCondition.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.DebugCondition;
 
+import dmd.common;
 import dmd.DVCondition;
 import dmd.Module;
 import dmd.Identifier;
@@ -51,9 +52,9 @@
 				else
 				{	
 					if (!mod.debugidsNot)
-						mod.debugidsNot = new Array();
+						mod.debugidsNot = new Vector!string();
 
-					mod.debugidsNot.push(cast(void*)new String(ident.toChars()));
+					mod.debugidsNot.push(ident.toChars());
 				}
 			}
 			else if (level <= global.params.debuglevel || level <= mod.debuglevel)
--- a/dmd/DebugSymbol.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/DebugSymbol.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,49 +1,96 @@
 module dmd.DebugSymbol;
 
+import dmd.common;
 import dmd.Dsymbol;
 import dmd.Identifier;
 import dmd.Loc;
 import dmd.Scope;
 import dmd.ScopeDsymbol;
+import dmd.Module;
 import dmd.HdrGenState;
+import dmd.Array;
 import dmd.OutBuffer;
 
+import dmd.condition.util.findCondition;
+
+/* DebugSymbol's happen for statements like:
+ *	debug = identifier;
+ *	debug = integer;
+ */
 class DebugSymbol : Dsymbol
 {
     uint level;
 
     this(Loc loc, Identifier ident)
 	{
-		assert(false);
+		super(ident);
+		this.loc = loc;
 	}
 
     this(Loc loc, uint level)
 	{
-		assert(false);
+		this.level = level;
+		this.loc = loc;
 	}
 
     override Dsymbol syntaxCopy(Dsymbol s)
 	{
-		assert(false);
+		assert(!s);
+		DebugSymbol ds = new DebugSymbol(loc, ident);
+		ds.level = level;
+		return ds;
 	}
 
-    override bool addMember(Scope sc, ScopeDsymbol s, bool memnum)
+    override bool addMember(Scope sc, ScopeDsymbol sd, bool memnum)
 	{
-		assert(false);
+		//printf("DebugSymbol.addMember('%s') %s\n", sd.toChars(), toChars());
+		Module m;
+
+		// Do not add the member to the symbol table,
+		// just make sure subsequent debug declarations work.
+		m = sd.isModule();
+		if (ident)
+		{
+			if (!m)
+				error("declaration must be at module level");
+			else
+			{
+				if (findCondition(m.debugidsNot, ident))
+					error("defined after use");
+				if (!m.debugids)
+					m.debugids = new Vector!string();
+				m.debugids.push(ident.toChars());	///
+			}
+		}
+		else
+		{
+			if (!m)
+				error("level declaration must be at module level");
+			else
+				m.debuglevel = level;
+		}
+		
+		return false;
 	}
 	
     override void semantic(Scope sc)
 	{
-		assert(false);
+		//printf("DebugSymbol.semantic() %s\n", toChars());
 	}
 	
     override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
 	{
-		assert(false);
+		buf.writestring("debug = ");
+		if (ident)
+			buf.writestring(ident.toChars());
+		else
+			buf.printf("%u", level);
+		buf.writestring(";");
+		buf.writenl();
 	}
 	
     override string kind()
 	{
-		assert(false);
+		return "debug";
 	}
 }
--- a/dmd/Declaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/Declaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.Declaration;
 
+import dmd.common;
 import dmd.Dsymbol;
 import dmd.Type;
 import dmd.TypedefDeclaration;
@@ -81,7 +82,7 @@
 {
     Type type;
     Type originalType;		// before semantic analysis
-    STC storage_class = STC.STCundefined;
+    StorageClass storage_class = STC.STCundefined;
     PROT protection = PROT.PROTundefined;
     LINK linkage = LINK.LINKdefault;
     int inuse;			// used to detect cycles
@@ -157,7 +158,7 @@
 				string p = null;
 				if (isConst())
 					p = "const";
-				else if (isInvariant())
+				else if (isImmutable())
 					p = "immutable";
 				else if (storage_class & STC.STCmanifest)
 					p = "enum";
@@ -251,7 +252,6 @@
 }
 
 			case LINK.LINKdefault:
-				assert(false);
 				error("forward declaration");
 				return ident.toChars();
 
@@ -271,7 +271,7 @@
 		return p;
 	}
 	
-    int isStatic() { return storage_class & STC.STCstatic; }
+    bool isStatic() { return (storage_class & STC.STCstatic) != 0; }
 	
     bool isStaticConstructor()
 	{
@@ -303,33 +303,33 @@
 		return false;
 	}
 	
-    int isCtorinit()     { return storage_class & STC.STCctorinit; }
+    bool isCtorinit()     { return (storage_class & STC.STCctorinit) != 0; }
     
-	int isFinal()        { return storage_class & STC.STCfinal; }
+	bool isFinal()        { return (storage_class & STC.STCfinal) != 0; }
     
 	bool isAbstract()     { return (storage_class & STC.STCabstract)  != 0; }
     
 	bool isConst()        { return (storage_class & STC.STCconst) != 0; }
     
-	int isInvariant()    { return storage_class & STC.STCinvariant; }
+	bool isImmutable()    { return (storage_class & STC.STCimmutable) != 0; }
     
-	int isAuto()         { return storage_class & STC.STCauto; }
+	bool isAuto()         { return (storage_class & STC.STCauto) != 0; }
     
-	int isScope()        { return storage_class & (STC.STCscope | STC.STCauto); }
+	bool isScope()        { return (storage_class & (STC.STCscope | STC.STCauto)) != 0; }
     
-	int isSynchronized() { return storage_class & STC.STCsynchronized; }
+	bool isSynchronized() { return (storage_class & STC.STCsynchronized) != 0; }
     
-	int isParameter()    { return storage_class & STC.STCparameter; }
+	bool isParameter()    { return (storage_class & STC.STCparameter) != 0; }
     
 	override bool isDeprecated()   { return (storage_class & STC.STCdeprecated)  != 0; }
     
-	int isOverride()     { return storage_class & STC.STCoverride; }
+	bool isOverride()     { return (storage_class & STC.STCoverride) != 0; }
 
-    int isIn()    { return storage_class & STC.STCin; }
+    bool isIn()    { return (storage_class & STC.STCin) != 0; }
     
-	int isOut()   { return storage_class & STC.STCout; }
+	bool isOut()   { return (storage_class & STC.STCout) != 0; }
     
-	int isRef()   { return storage_class & STC.STCref; }
+	bool isRef()   { return (storage_class & STC.STCref) != 0; }
 
     override PROT prot()
 	{
--- a/dmd/DeclarationExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/DeclarationExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.DeclarationExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.backend.elem;
 import dmd.InterState;
@@ -147,7 +148,7 @@
 					e = null;
 			}
 ///version (DMDV2) {
-			else if (s == v && (v.isConst() || v.isInvariant()) && v.init)
+			else if (s == v && (v.isConst() || v.isImmutable()) && v.init)
 ///} else {
 ///			else if (s == v && v.isConst() && v.init)
 ///}
@@ -197,7 +198,8 @@
 
 	override void scanForNestedRef(Scope sc)
 	{
-		assert(false);
+		//printf("DeclarationExp.scanForNestedRef() %s\n", toChars());
+		declaration.parent = sc.parent;
 	}
 
 version (DMDV2) {
@@ -264,6 +266,7 @@
 			declaration.isClassDeclaration() ||
 			declaration.isFuncDeclaration() ||
 			declaration.isTypedefDeclaration() ||
+        	declaration.isAttribDeclaration() ||
 			declaration.isTemplateMixin()
 		)
 			return COST_MAX;
--- a/dmd/DeclarationStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/DeclarationStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.DeclarationStatement;
 
+import dmd.common;
 import dmd.Loc;
 import dmd.ExpStatement;
 import dmd.Dsymbol;
--- a/dmd/DefaultInitExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/DefaultInitExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.DefaultInitExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.OutBuffer;
 import dmd.Loc;
@@ -18,8 +19,6 @@
 		this.subop = subop;
 	}
 
-	abstract Expression resolve(Loc loc, Scope sc);
-
 	override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
 	{
 		buf.writestring(Token.toChars(subop));
--- a/dmd/DefaultStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/DefaultStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.DefaultStatement;
 
+import dmd.common;
 import dmd.Statement;
 import dmd.Loc;
 import dmd.Scope;
--- a/dmd/DelegateExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/DelegateExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.DelegateExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.backend.elem;
 import dmd.AggregateDeclaration;
--- a/dmd/DeleteDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/DeleteDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.DeleteDeclaration;
 
+import dmd.common;
 import dmd.FuncDeclaration;
 import dmd.ArrayTypes;
 import dmd.Loc;
@@ -8,55 +9,101 @@
 import dmd.OutBuffer;
 import dmd.HdrGenState;
 import dmd.STC;
+import dmd.Id;
+import dmd.Parameter;
+import dmd.ClassDeclaration;
+import dmd.TypeFunction;
+import dmd.Type;
+import dmd.LINK;
+import dmd.TY;
 
 class DeleteDeclaration : FuncDeclaration
 {
-	Arguments arguments;
+	Parameters arguments;
 
-    this(Loc loc, Loc endloc, Arguments arguments)
+    this(Loc loc, Loc endloc, Parameters arguments)
 	{
-		assert(false);
-		super(loc, endloc, null, STC.init, null);
+		super(loc, endloc, Id.classDelete, STCstatic, null);
+		this.arguments = arguments;
 	}
 	
     override Dsymbol syntaxCopy(Dsymbol)
 	{
-		assert(false);
+		DeleteDeclaration f;
+
+		f = new DeleteDeclaration(loc, endloc, null);
+
+		FuncDeclaration.syntaxCopy(f);
+
+		f.arguments = Parameter.arraySyntaxCopy(arguments);
+
+		return f;
 	}
 	
     override void semantic(Scope sc)
 	{
-		assert(false);
+		ClassDeclaration cd;
+
+		//printf("DeleteDeclaration.semantic()\n");
+
+		parent = sc.parent;
+		Dsymbol parent = toParent();
+		cd = parent.isClassDeclaration();
+		if (!cd && !parent.isStructDeclaration())
+		{
+			error("new allocators only are for class or struct definitions");
+		}
+		type = new TypeFunction(arguments, Type.tvoid, 0, LINKd);
+
+		type = type.semantic(loc, sc);
+		assert(type.ty == Tfunction);
+
+		// Check that there is only one argument of type void*
+		TypeFunction tf = cast(TypeFunction)type;
+		if (Parameter.dim(tf.parameters) != 1)
+		{
+			error("one argument of type void* expected");
+		}
+		else
+		{
+			auto a = Parameter.getNth(tf.parameters, 0);
+			if (!a.type.equals(Type.tvoid.pointerTo()))
+				error("one argument of type void* expected, not %s", a.type.toChars());
+		}
+
+		FuncDeclaration.semantic(sc);
 	}
 	
     override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
 	{
-		assert(false);
+		buf.writestring("delete");
+		Parameter.argsToCBuffer(buf, hgs, arguments, 0);
+		bodyToCBuffer(buf, hgs);
 	}
 	
     override string kind()
 	{
-		assert(false);
+		return "deallocator";
 	}
 
     override bool isDelete()
 	{
-		assert(false);
+		return true;
 	}
 	
     override bool isVirtual()
 	{
-		assert(false);
+		return false;
 	}
 	
     override bool addPreInvariant()
 	{
-		assert(false);
+		return false;
 	}
 	
     override bool addPostInvariant()
 	{
-		assert(false);
+		return false;
 	}
 	
 version (_DH) {
--- a/dmd/DeleteExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/DeleteExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.DeleteExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.backend.elem;
 import dmd.UnaExp;
@@ -188,7 +189,7 @@
 				elem* ep;
 				elem* keyti;
 
-				if (tybasic(ekey.Ety) == TYstruct)
+				if (tybasic(ekey.Ety) == TYstruct || tybasic(ekey.Ety) == TYarray)
 				{
 					ekey = el_una(OPstrpar, TYstruct, ekey);
 					ekey.Enumbytes = ekey.E1.Enumbytes;
--- a/dmd/DivAssignExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/DivAssignExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.DivAssignExp;
 
+import dmd.common;
 import dmd.BinExp;
 import dmd.Loc;
 import dmd.Expression;
@@ -16,10 +17,12 @@
 import dmd.CommaExp;
 import dmd.RealExp;
 import dmd.AssignExp;
+import dmd.ArrayLengthExp;
 
 import dmd.backend.elem;
 import dmd.backend.OPER;
 import dmd.backend.Util;
+import dmd.expression.Div;
 import dmd.expression.Util;
 
 class DivAssignExp : BinExp
@@ -40,6 +43,15 @@
 		if (e)
 			return e;
 
+version(DMDV2) {
+    if (e1.op == TOK.TOKarraylength)
+    {
+	e = ArrayLengthExp.rewriteOpAssign(this);
+	e = e.semantic(sc);
+	return e;
+    }
+}
+
 		if (e1.op == TOKslice)
 		{	// T[] -= ...
 			typeCombine(sc);
@@ -94,7 +106,7 @@
 	
     override Expression interpret(InterState istate)
 	{
-		assert(false);
+    	return interpretAssignCommon(istate, &Div);
 	}
 	
     override void buildArrayIdent(OutBuffer buf, Expressions arguments)
@@ -102,9 +114,9 @@
 		AssignExp_buildArrayIdent(buf, arguments, "Div");
 	}
 	
-    override Expression buildArrayLoop(Arguments fparams)
+    override Expression buildArrayLoop(Parameters fparams)
 	{
-		assert(false);
+		return AssignExp_buildArrayLoop!(typeof(this))(fparams);
 	}
 
     override Identifier opId()    /* For operator overloading */
--- a/dmd/DivExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/DivExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.DivExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Identifier;
 import dmd.backend.elem;
@@ -41,11 +42,11 @@
 			return e;
 
 		typeCombine(sc);
-		if (e1.op != TOK.TOKslice && e2.op != TOK.TOKslice)
-		{	
+		if (!e1.isArrayOperand())
 			e1.checkArithmetic();
+		if (!e2.isArrayOperand())
 			e2.checkArithmetic();
-		}
+
 		if (type.isfloating())
 		{	
 			Type t1 = e1.type;
@@ -107,7 +108,7 @@
 
 	override Expression interpret(InterState istate)
 	{
-		assert(false);
+		return interpretCommon(istate, &Div);
 	}
 
 	override void buildArrayIdent(OutBuffer buf, Expressions arguments)
@@ -115,14 +116,9 @@
 		Exp_buildArrayIdent(buf, arguments, "Div");
 	}
 
-	override Expression buildArrayLoop(Arguments fparams)
+	override Expression buildArrayLoop(Parameters fparams)
 	{
-		/* Evaluate assign expressions left to right		
-		 */								
-		Expression ex1 = e1.buildArrayLoop(fparams);		
-		Expression ex2 = e2.buildArrayLoop(fparams);		
-		Expression e = new DivExp(Loc(0), ex1, ex2);			
-		return e;							
+		return Exp_buildArrayLoop!(typeof(this))(fparams);
 	}
 
 	override IntRange getIntRange()
--- a/dmd/DoStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/DoStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.DoStatement;
 
+import dmd.common;
 import dmd.Statement;
 import dmd.Expression;
 import dmd.Loc;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmd/DocComment.d	Tue Sep 14 15:46:50 2010 +0200
@@ -0,0 +1,51 @@
+module dmd.DocComment;
+
+import dmd.common;
+import dmd.Array;
+import dmd.Section;
+import dmd.Macro;
+import dmd.Escape;
+import dmd.Scope;
+import dmd.Dsymbol;
+import dmd.OutBuffer;
+
+class DocComment
+{
+    Array sections;		// Section*[]
+
+    Section summary;
+    Section copyright;
+    Section macros;
+    Macro** pmacrotable;
+    Escape** pescapetable;
+
+    this()
+	{
+		assert(false);
+	}
+
+    static DocComment parse(Scope sc, Dsymbol s, ubyte* comment)
+	{
+		assert(false);
+	}
+	
+    static void parseMacros(Escape** pescapetable, Macro** pmacrotable, ubyte* m, uint mlen)
+	{
+		assert(false);
+	}
+	
+    static void parseEscapes(Escape** pescapetable, ubyte* textstart, uint textlen)
+	{
+		assert(false);
+	}
+
+    void parseSections(ubyte* comment)
+	{
+		assert(false);
+	}
+	
+    void writeSections(Scope sc, Dsymbol s, OutBuffer buf)
+	{
+		assert(false);
+	}
+}
\ No newline at end of file
--- a/dmd/DollarExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/DollarExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,11 +1,12 @@
-module dmd.DollarExp;
-
-import dmd.IdentifierExp;
-import dmd.Loc;
-import dmd.Identifier;
-import dmd.TOK;
-import dmd.Id;
-
+module dmd.DollarExp;
+
+import dmd.common;
+import dmd.IdentifierExp;
+import dmd.Loc;
+import dmd.Identifier;
+import dmd.TOK;
+import dmd.Id;
+
 class DollarExp : IdentifierExp
 {
 	this(Loc loc)
--- a/dmd/DotExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/DotExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,8 +1,12 @@
 module dmd.DotExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Loc;
 import dmd.Scope;
+import dmd.ScopeExp;
+import dmd.TemplateDeclaration;
+import dmd.DotTemplateExp;
 import dmd.BinExp;
 import dmd.TOK;
 
@@ -10,13 +14,31 @@
 {
 	this(Loc loc, Expression e1, Expression e2)
 	{
-		assert(false);
-		super(loc, TOK.init, 0, e1, e2);
+		super(loc, TOKdotexp, DotExp.sizeof, e1, e2);
 	}
 
 	override Expression semantic(Scope sc)
 	{
-		assert(false);
+version (LOGSEMANTIC) {
+		printf("DotExp.semantic('%s')\n", toChars());
+		if (type) printf("\ttype = %s\n", type.toChars());
+}
+		e1 = e1.semantic(sc);
+		e2 = e2.semantic(sc);
+		if (e2.op == TOKimport)
+		{
+			ScopeExp se = cast(ScopeExp)e2;
+			TemplateDeclaration td = se.sds.isTemplateDeclaration();
+			if (td)
+			{   
+				Expression e = new DotTemplateExp(loc, e1, td);
+				e = e.semantic(sc);
+				return e;
+			}
+		}
+		if (!type)
+			type = e2.type;
+		return this;
 	}
 }
 
--- a/dmd/DotIdExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/DotIdExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.DotIdExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Identifier;
 import dmd.IntegerExp;
@@ -55,6 +56,12 @@
 
 	override Expression semantic(Scope sc)
 	{
+		// Indicate we didn't come from CallExp::semantic()
+		return semantic(sc, 0);
+	}
+
+	Expression semantic(Scope sc, int flag)
+	{
 		Expression e;
 		Expression eleft;
 		Expression eright;
@@ -148,7 +155,7 @@
 			{   
 				auto ee = te.exps[i];
 				ee = ee.semantic(sc);
-				ee = new DotIdExp(e.loc, ee, Id.offsetof);
+				ee = new DotIdExp(ee.loc, ee, Id.offsetof);
 				exps[i] = ee;
 			}
 			e = new TupleExp(loc, exps);
@@ -186,7 +193,7 @@
 			 * The check for 'is sds our current module' is because
 			 * the current module should have access to its own imports.
 			 */
-			Dsymbol s = ie.sds.search(loc, ident,
+			Dsymbol s = ie.sds.search(loc, ident, //0);
 				(ie.sds.isModule() && ie.sds != sc.module_) ? 1 : 0);
 			if (s)
 			{
@@ -337,11 +344,13 @@
 			 */
 			uint errors = global.errors;
 			global.gag++;
+			Type t1 = e1.type;
 			e = e1.type.dotExp(sc, e1, ident);
 			global.gag--;
 			if (errors != global.errors)	// if failed to find the property
 			{
 				global.errors = errors;
+				e1.type = t1;		// kludge to restore type
 				e = new DotIdExp(loc, new IdentifierExp(loc, Id.empty), ident);
 				e = new CallExp(loc, e, e1);
 			}
@@ -352,7 +361,8 @@
 		else
 		{
 			e = e1.type.dotExp(sc, e1, ident);
-			e = e.semantic(sc);
+			if (!(flag && e.op == TOK.TOKdotti))	// let CallExp::semantic() handle this
+				e = e.semantic(sc);
 			return e;
 		}
 	}
--- a/dmd/DotTemplateExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/DotTemplateExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.DotTemplateExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.UnaExp;
 import dmd.OutBuffer;
--- a/dmd/DotTemplateInstanceExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/DotTemplateInstanceExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,7 @@
 module dmd.DotTemplateInstanceExp;
 
+import dmd.common;
+import dmd.ArrayTypes;
 import dmd.Expression;
 import dmd.UnaExp;
 import dmd.OutBuffer;
@@ -22,6 +24,10 @@
 import dmd.DotVarExp;
 import dmd.TemplateDeclaration;
 import dmd.Dsymbol;
+import dmd.DotTemplateExp;
+import dmd.DotIdExp;
+import dmd.TemplateExp;
+import dmd.DsymbolExp;
 
 import dmd.expression.Util;
 
@@ -32,141 +38,106 @@
 {
 	TemplateInstance ti;
 
-	this(Loc loc, Expression e, TemplateInstance ti)
+	this(Loc loc, Expression e, Identifier name, Objects tiargs)
 	{
 		super(loc, TOK.TOKdotti, DotTemplateInstanceExp.sizeof, e);
 		//printf("DotTemplateInstanceExp()\n");
-		this.ti = ti;
+		this.ti = new TemplateInstance(loc, name);
+		this.ti.tiargs = tiargs;
 	}
 
 	override Expression syntaxCopy()
 	{
-		DotTemplateInstanceExp de = new DotTemplateInstanceExp(loc, e1.syntaxCopy(), cast(TemplateInstance)ti.syntaxCopy(null));
+		DotTemplateInstanceExp de = new DotTemplateInstanceExp(loc, e1.syntaxCopy(), ti.name, TemplateInstance.arraySyntaxCopy(ti.tiargs));
 		return de;
 	}
 
-	override Expression semantic(Scope sc)
+	TemplateDeclaration getTempdecl(Scope sc)
 	{
-		Dsymbol s;
-		Dsymbol s2;
-		TemplateDeclaration td;
-		Expression e;
-		Identifier id;
-		Type t1;
-		Expression eleft = null;
-		Expression eright;
-
-	version (LOGSEMANTIC) {
-		printf("DotTemplateInstanceExp.semantic('%s')\n", toChars());
-	}
-		//e1.print();
-		//print();
-		e1 = e1.semantic(sc);
-		t1 = e1.type;
-		if (t1)
-			t1 = t1.toBasetype();
-		//t1.print();
-
-		/* Extract the following from e1:
-		 *	s: the symbol which ti should be a member of
-		 *	eleft: if not null, it is the 'this' pointer for ti
-		 */
-
-		if (e1.op == TOKdotexp)
-		{	
-			DotExp de = cast(DotExp)e1;
-			eleft = de.e1;
-			eright = de.e2;
-		}
-		else
-		{	
-			eleft = null;
-			eright = e1;
-		}
-		if (eright.op == TOKimport)
+version(LOGSEMANTIC) {
+		printf("DotTemplateInstanceExp::getTempdecl('%s')\n", toChars());
+}
+		if (!ti.tempdecl)
 		{
-			s = (cast(ScopeExp)eright).sds;
-		}
-		else if (e1.op == TOKtype)
-		{
-			s = t1.isClassHandle();
-			if (!s)
+			Expression e = new DotIdExp(loc, e1, ti.name);
+			e = e.semantic(sc);
+			if (e.op == TOKdottd)
 			{
-				if (t1.ty == Tstruct)
-					s = (cast(TypeStruct)t1).sym;
-				else
-					goto L1;
+				auto dte = cast(DotTemplateExp)e;
+				ti.tempdecl = dte.td;
+			}
+			else if (e.op == TOKimport)
+			{
+				auto se = cast(ScopeExp)e;
+				ti.tempdecl = se.sds.isTemplateDeclaration();
 			}
 		}
-		else if (t1 && (t1.ty == Tstruct || t1.ty == Tclass))
-		{
-			s = t1.toDsymbol(sc);
-			eleft = e1;
-		}
-		else if (t1 && t1.ty == Tpointer)
-		{
-			t1 = (cast(TypePointer)t1).next.toBasetype();
-			if (t1.ty != Tstruct)
-				goto L1;
-			s = t1.toDsymbol(sc);
-			eleft = e1;
-		}
-		else
-		{
-		  L1:
-			error("template %s is not a member of %s", ti.toChars(), e1.toChars());
-			goto Lerr;
-		}
-
-		assert(s);
-		id = ti.name;
-		s2 = s.search(loc, id, 0);
-		if (!s2)
+		return ti.tempdecl;
+	}
+	
+	override Expression semantic(Scope sc)
+	{
+version (LOGSEMANTIC) {
+		printf("DotTemplateInstanceExp.semantic('%s')\n", toChars());
+}
+		Expression eleft;
+		Expression e = new DotIdExp(loc, e1, ti.name);
+L1:
+		e = e.semantic(sc);
+		if (e.op == TOKdottd)
 		{
-			if (!s.ident)
-				error("template identifier %s is not a member of undefined %s", id.toChars(), s.kind());
-			else
-				error("template identifier %s is not a member of %s %s", id.toChars(), s.kind(), s.ident.toChars());
-			goto Lerr;
-		}
-		s = s2;
-		s.semantic(sc);
-		s = s.toAlias();
-		td = s.isTemplateDeclaration();
-		if (!td)
-		{
-			error("%s is not a template", id.toChars());
-			goto Lerr;
-		}
-		if (global.errors)
-			goto Lerr;
-
-		ti.tempdecl = td;
-
-		if (eleft)
-		{	
-			Declaration v;
-
+			DotTemplateExp dte = cast(DotTemplateExp )e;
+			TemplateDeclaration td = dte.td;
+			eleft = dte.e1;
+			ti.tempdecl = td;
 			ti.semantic(sc);
-			s = ti.inst.toAlias();
-			v = s.isDeclaration();
+			Dsymbol s = ti.inst.toAlias();
+			Declaration v = s.isDeclaration();
 			if (v)
-			{   
+			{
 				e = new DotVarExp(loc, eleft, v);
 				e = e.semantic(sc);
 				return e;
 			}
-		}
-
-		e = new ScopeExp(loc, ti);
-		if (eleft)
-		{
+			e = new ScopeExp(loc, ti);
 			e = new DotExp(loc, eleft, e);
+			e = e.semantic(sc);
+			return e;
 		}
-		e = e.semantic(sc);
-		return e;
+		else if (e.op == TOKimport)
+		{
+			auto se = cast(ScopeExp)e;
+			TemplateDeclaration td = se.sds.isTemplateDeclaration();
+			if (!td)
+			{
+				error("%s is not a template", e.toChars());
+				return new ErrorExp();
+			}
+			ti.tempdecl = td;
+			e = new ScopeExp(loc, ti);
+			e = e.semantic(sc);
+			return e;
+		}
+		else if (e.op == TOKdotexp)
+		{
+			DotExp de = cast(DotExp )e;
 
-	Lerr:
+			if (de.e2.op == TOKimport)
+			{
+				// This should *really* be moved to ScopeExp::semantic()
+				ScopeExp se = cast(ScopeExp )de.e2;
+				de.e2 = new DsymbolExp(loc, se.sds);
+				de.e2 = de.e2.semantic(sc);
+			}
+
+			if (de.e2.op == TOKtemplate)
+			{
+				auto te = cast(TemplateExp) de.e2;
+				e = new DotTemplateExp(loc,de.e1,te.td);
+			}
+		goto L1;
+		}
+		error("%s isn't a template", e.toChars());
 		return new ErrorExp();
 	}
 
--- a/dmd/DotTypeExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/DotTypeExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.DotTypeExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.backend.elem;
 import dmd.UnaExp;
@@ -13,6 +14,8 @@
 import dmd.PREC;
 import dmd.expression.Util;
 
+import dmd.backend.Util;
+
 class DotTypeExp : UnaExp
 {
 	Dsymbol sym;
@@ -42,7 +45,13 @@
 
 	override elem* toElem(IRState* irs)
 	{
-		assert(false);
+		// Just a pass-thru to e1
+		elem *e;
+
+		//printf("DotTypeExp.toElem() %s\n", toChars());
+		e = e1.toElem(irs);
+		el_setLoc(e,loc);
+		return e;
 	}
 }
 
--- a/dmd/DotVarExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/DotVarExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.DotVarExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Declaration;
 import dmd.backend.elem;
@@ -68,12 +69,11 @@
 				 * with:
 				 *	tuple(e1.a, e1.b, e1.c)
 				 */
-				Expressions exps = new Expressions;
+				auto exps = new Expressions;
 
 				exps.reserve(tup.objects.dim);
-				for (size_t i = 0; i < tup.objects.dim; i++)
+				foreach (o; tup.objects)
 				{   
-					Object o = cast(Object)tup.objects.data[i];
 					if (auto e = cast(Expression)o)
 					{
 						if (e.op != TOK.TOKdsymbol)
@@ -187,7 +187,7 @@
 			if (!t1.isMutable() || (t1.ty == TY.Tpointer && !t1.nextOf().isMutable()) ||
 				!var.type.isMutable() || !var.type.isAssignable() || var.storage_class & STC.STCmanifest)
 			{
-				error("cannot modify const/immutable expression %s", toChars());
+				error("cannot modify const/immutable/inout expression %s", toChars());
 			}
 }
 		}
@@ -225,7 +225,41 @@
 
 	override Expression interpret(InterState istate)
 	{
-		assert(false);
+		Expression e = EXP_CANT_INTERPRET;
+
+version (LOG) {
+		printf("DotVarExp.interpret() %.*s\n", toChars());
+}
+
+		Expression ex = e1.interpret(istate);
+		if (ex !is EXP_CANT_INTERPRET)
+		{
+			if (ex.op == TOKstructliteral)
+			{   
+				StructLiteralExp se = cast(StructLiteralExp)ex;
+				VarDeclaration v = var.isVarDeclaration();
+				if (v)
+				{	
+					e = se.getField(type, v.offset);
+					if (!e)
+		            {
+		                error("couldn't find field %s in %s", v.toChars(), type.toChars());
+						e = EXP_CANT_INTERPRET;
+                    }
+					return e;
+				}
+			}
+            else
+            {
+				error("%s.%s is not yet implemented at compile time", ex.toChars(), var.toChars());
+			}
+		}
+
+version (LOG) {
+		if (e is EXP_CANT_INTERPRET)
+			printf("DotVarExp.interpret() %.*s = EXP_CANT_INTERPRET\n", toChars());
+}
+		return e;
 	}
 
 	override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
--- a/dmd/Dsymbol.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/Dsymbol.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.Dsymbol;
 
+import dmd.common;
 import dmd.Loc;
 import dmd.STC;
 import dmd.Scope;
@@ -578,7 +579,7 @@
 	
     AggregateDeclaration isThis()	// is a 'this' required to access the member
 	{
-		assert(false);
+		return null;
 	}
 	
     ClassDeclaration isClassMember()	// are we a member of a class?
--- a/dmd/DsymbolExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/DsymbolExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.DsymbolExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.OutBuffer;
 import dmd.EnumMember;
@@ -33,6 +34,7 @@
 import dmd.HdrGenState;
 import dmd.Dsymbol;
 import dmd.TOK;
+import dmd.ErrorExp;
 
 class DsymbolExp : Expression
 {
@@ -149,6 +151,7 @@
 			if (!f.type.deco)
 			{
 				error("forward reference to %s", toChars());
+				return new ErrorExp();
 			}
 			return new VarExp(loc, f, hasOverloads);
 		}
--- a/dmd/DsymbolTable.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/DsymbolTable.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.DsymbolTable;
 
+import dmd.common;
 import dmd.StringTable;
 import dmd.Dsymbol;
 import dmd.Identifier;
--- a/dmd/DtorDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/DtorDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.DtorDeclaration;
 
+import dmd.common;
 import dmd.FuncDeclaration;
 import dmd.Loc;
 import dmd.Global;
--- a/dmd/EnumDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/EnumDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.EnumDeclaration;
 
+import dmd.common;
 import dmd.ScopeDsymbol;
 import dmd.AddExp;
 import dmd.Type;
@@ -57,8 +58,10 @@
     Expression minval;
     Expression defaultval;	// default initializer
 }
-    bool isdeprecated;
-
+	bool isdeprecated = false;
+	bool isdone = false;	// 0: not done
+							// 1: semantic() successfully completed
+    
     this(Loc loc, Identifier id, Type memtype)
 	{
 		super(id);
@@ -102,7 +105,7 @@
 
 		if (symtab)			// if already done
 		{	
-			if (!scope_)
+			if (isdone || !scope_)
 				return;		// semantic() already completed
 		}
 		else
@@ -145,7 +148,8 @@
 					return;
 				}
 			}
-static if (false) {
+static if (false)
+{
 		// Decided to abandon this restriction for D 2.0
 			if (!memtype.isintegral())
 			{   error("base type must be of integral type, not %s", memtype.toChars());
@@ -154,6 +158,8 @@
 }
 		}
 
+		isdone = true;
+
 		type = type.semantic(loc, sc);
 		if (isAnonymous())
 			sce = sc;
--- a/dmd/EnumMember.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/EnumMember.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.EnumMember;
 
+import dmd.common;
 import dmd.Dsymbol;
 import dmd.Expression;
 import dmd.Type;
--- a/dmd/EqualExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/EqualExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.EqualExp;
 
+import dmd.common;
 import dmd.ErrorExp;
 import dmd.Expression;
 import dmd.Id;
@@ -142,12 +143,12 @@
 
 	override Expression interpret(InterState istate)
 	{
-		assert(false);
+		return interpretCommon2(istate, &Equal);
 	}
 
-	override int isBit()
+	override bool isBit()
 	{
-		assert(false);
+		return true;
 	}
 
 	override bool isCommutative()
@@ -180,21 +181,13 @@
 		//printf("EqualExp::toElem()\n");
 		if (t1.ty == Tstruct)
 		{	// Do bit compare of struct's
-			elem* es1;
-			elem* es2;
-			elem* ecount;
 
-			es1 = e1.toElem(irs);
-			es2 = e2.toElem(irs);
-		static if (true) {
+			auto es1 = e1.toElem(irs);
+			auto es2 = e2.toElem(irs);
 			es1 = addressElem(es1, t1);
 			es2 = addressElem(es2, t2);
-		} else {
-			es1 = el_una(OPaddr, TYnptr, es1);
-			es2 = el_una(OPaddr, TYnptr, es2);
-		}
 			e = el_param(es1, es2);
-			ecount = el_long(TYint, t1.size());
+			auto ecount = el_long(TYint, t1.size());
 			e = el_bin(OPmemcmp, TYint, e, ecount);
 			e = el_bin(eop, TYint, e, el_long(TYint, 0));
 			el_setLoc(e,loc);
@@ -213,24 +206,20 @@
 		else if ((t1.ty == Tarray || t1.ty == Tsarray) &&
 			 (t2.ty == Tarray || t2.ty == Tsarray))
 		{
-			elem* ea1;
-			elem* ea2;
-			elem* ep;
 			Type telement = t1.nextOf().toBasetype();
-			int rtlfunc;
 
-			ea1 = e1.toElem(irs);
+			auto ea1 = e1.toElem(irs);
 			ea1 = array_toDarray(t1, ea1);
-			ea2 = e2.toElem(irs);
+			auto ea2 = e2.toElem(irs);
 			ea2 = array_toDarray(t2, ea2);
 
 		version (DMDV2) {
-			ep = el_params(telement.arrayOf().getInternalTypeInfo(null).toElem(irs),
+			auto ep = el_params(telement.arrayOf().getInternalTypeInfo(null).toElem(irs),
 				ea2, ea1, null);
-			rtlfunc = RTLSYM_ARRAYEQ2;
+			int rtlfunc = RTLSYM_ARRAYEQ2;
 		} else {
-			ep = el_params(telement.getInternalTypeInfo(null).toElem(irs), ea2, ea1, null);
-			rtlfunc = RTLSYM_ARRAYEQ;
+			auto ep = el_params(telement.getInternalTypeInfo(null).toElem(irs), ea2, ea1, null);
+			int rtlfunc = RTLSYM_ARRAYEQ;
 		}
 			e = el_bin(OPcall, TYint, el_var(rtlsym[rtlfunc]), ep);
 			if (op == TOKnotequal)
--- a/dmd/ErrorExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/ErrorExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.ErrorExp;
 
+import dmd.common;
 import dmd.OutBuffer;
 import dmd.IntegerExp;
 import dmd.Loc;
--- a/dmd/ExpInitializer.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/ExpInitializer.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.ExpInitializer;
 
+import dmd.common;
 import dmd.Initializer;
 import dmd.DelegateExp;
 import dmd.Loc;
--- a/dmd/ExpStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/ExpStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.ExpStatement;
 
+import dmd.common;
 import dmd.Loc;
 import dmd.Statement;
 import dmd.AssertExp;
--- a/dmd/Expression.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/Expression.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,8 +1,9 @@
 module dmd.Expression;
 
+import dmd.common;
 import dmd.Loc;
 import dmd.TOK;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.IdentifierExp;
 import dmd.Type;
 import dmd.WANT;
@@ -52,6 +53,7 @@
 import dmd.Complex;
 
 import dmd.backend.elem;
+import dmd.backend.Util;
 import dmd.backend.dt_t;
 
 import core.memory;
@@ -135,6 +137,11 @@
 
 		if (t.ty == TY.Tfunction || e.op == TOK.TOKoverloadset)
 		{
+static if(false)
+{
+		    if (t.ty == Tfunction && !(cast(TypeFunction)t).isproperty)
+			error(e.loc, "not a property %s\n", e.toChars());
+}
 			e = new CallExp(e.loc, e);
 			e = e.semantic(sc);
 		}
@@ -651,6 +658,10 @@
 	{
 	}
     
+    void checkEscapeRef()
+    {
+    }
+    
     void checkScalar()
 	{
 		if (!type.isscalar())
@@ -699,12 +710,25 @@
 static if (true) {
 		if (sc.func)
 		{
+			/* Given:
+			 * void f()
+			 * { pure void g()
+			 *   {
+			 *	void h()
+			 *	{
+			 *	   void i() { }
+			 *	}
+			 *   }
+			 * }
+			 * g() can call h() but not f()
+			 * i() can call h() and g() but not f()
+			 */
 			FuncDeclaration outerfunc = sc.func;
 			while (outerfunc.toParent2() && outerfunc.toParent2().isFuncDeclaration())
 			{
 				outerfunc = outerfunc.toParent2().isFuncDeclaration();
 			}
-			if (outerfunc.isPure()  && !sc.intypeof && (!f.isNested() && !f.isPure()))
+			if (outerfunc.isPure() && !sc.intypeof && (!f.isNested() && !f.isPure()))
 				error("pure function '%s' cannot call impure function '%s'\n",
 				sc.func.toChars(), f.toChars());
 		}
@@ -714,6 +738,14 @@
 			sc.func.toChars(), .toChars());
 }
 	}
+	
+	void checkSafety(Scope sc, FuncDeclaration f)
+	{
+		if (sc.func && sc.func.isSafe() && !sc.intypeof &&
+			!f.isSafe() && !f.isTrusted())
+			error("safe function '%s' cannot call system function '%s'\n",
+				sc.func.toChars(), f.toChars());
+	}
     
 	/*****************************
 	 * Check that expression can be tested for true or false.
@@ -737,14 +769,13 @@
     
     Expression checkToPointer()
 	{
-		Expression e;
-		Type tb;
+		//writef("Expression::checkToPointer()\n");
+		Expression e = this;
 
-		//printf("Expression::checkToPointer()\n");
-		e = this;
-
+version(SARRAYVALUE) {} else
+{
 		// If C static array, convert to pointer
-		tb = type.toBasetype();
+		Type tb = type.toBasetype();
 		if (tb.ty == Tsarray)
 		{	
 			TypeSArray ts = cast(TypeSArray)tb;
@@ -754,6 +785,7 @@
 				e = new AddrExp(loc, this);
 			e.type = ts.next.pointerTo();
 		}
+}
 		return e;
 	}
     
@@ -883,9 +915,12 @@
 		return false;
 	}
     
-    int isBit()
+	/********************************
+	 * Does this expression result in either a 1 or a 0?
+	 */
+	int isBit()
 	{
-		assert(false);
+		return false;
 	}
 
 	/********************************
@@ -926,6 +961,14 @@
 }
 	}
     
+	/****************************************
+	 * Resolve __LINE__ and __FILE__ to loc.
+	 */
+	Expression resolveLoc(Loc loc, Scope sc)
+	{
+	    return this;
+	}
+
     int inlineCost(InlineCostState* ics)
 	{
 		return 1;
@@ -981,11 +1024,11 @@
 		arguments.shift(this);
 	}
     
-    Expression buildArrayLoop(Arguments fparams)
+    Expression buildArrayLoop(Parameters fparams)
 	{
 		Identifier id = Identifier.generateId("c", fparams.dim);
-		Argument param = new Argument(STC.STCundefined, type, id, null);
-		fparams.shift(cast(void*)param);
+		auto param = new Parameter(STC.STCundefined, type, id, null);
+		fparams.shift(param);
 		Expression e = new IdentifierExp(Loc(0), id);
 		return e;
 	}
@@ -1024,12 +1067,21 @@
     // Back end
     elem* toElem(IRState* irs)
 	{
+		print();
 		assert(false);
+		return null;
 	}
     
     dt_t** toDt(dt_t** pdt)
 	{
-		assert(false);
+		debug
+		{
+			writef("Expression::toDt() %d\n", op);
+			dump(0);
+		}
+		error("non-constant expression %s", toChars());
+		pdt = dtnzeros(pdt, 1);
+		return pdt;
 	}
 }
 
--- a/dmd/File.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/File.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.File;
 
+import dmd.common;
 import dmd.FileName;
 import dmd.Array;
 import dmd.Util;
@@ -47,7 +48,7 @@
 			if (ref_ == 0) {
 				///free(buffer);
 			} else {
-version (_WIN32) {
+version (Windows) {
 				if (ref_ == 2) {
 					UnmapViewOfFile(buffer);
 				}
@@ -77,7 +78,8 @@
 
     int read()
 	{
-version (POSIX) {
+version (Posix)
+{
 		int result = 0;
 
 		string name = this.name.toChars();
@@ -145,7 +147,7 @@
 	err1:
 		result = 1;
 		return result;
-} else version (_WIN32) {
+} else version (Windows) {
 		DWORD size;
 		DWORD numread;
 		HANDLE h;
@@ -275,7 +277,7 @@
 	err:
 		return 1;
 		
-} else version (_WIN32) {
+} else version (Windows) {
 		HANDLE h;
 		DWORD numwritten;
 
--- a/dmd/FileExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/FileExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.FileExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.UnaExp;
 import dmd.OutBuffer;
--- a/dmd/FileInitExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/FileInitExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.FileInitExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Loc;
 import dmd.Scope;
@@ -22,7 +23,7 @@
 		return this;
 	}
 
-	override Expression resolve(Loc loc, Scope sc)
+	override Expression resolveLoc(Loc loc, Scope sc)
 	{
 		//printf("FileInitExp::resolve() %.*s\n", toChars());
 		string s = loc.filename ? loc.filename : sc.module_.ident.toChars();
--- a/dmd/FileName.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/FileName.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.FileName;
 
+import dmd.common;
 import dmd.String;
 import dmd.Array;
 import dmd.OutBuffer;
@@ -41,7 +42,8 @@
 
     override hash_t hashCode()
 	{
-version (_WIN32) {
+version (Windows)
+{
 		// We need a different hashCode because it must be case-insensitive
 		size_t len = str.length;
 		hash_t hash = 0;
@@ -110,11 +112,11 @@
 
 	static pure bool absolute(const(char)[] name)
 	{
-version (_WIN32)
+version (Windows)
 {
 		return (name[0] == '\\') ||
 			(name[0] == '/')  ||
-			(name[0] && name[1] == ':');
+			((name.length > 1) && (name[1] == ':'));
 }
 else version (POSIX)
 {
@@ -143,7 +145,8 @@
 				case '/':
 					return null;
 }
-version (_WIN32) {
+version (Windows)
+{
 				case '\\':
 				case ':':
 				case '/':
@@ -188,11 +191,13 @@
 		{
 			switch (c)
 			{
-version (POSIX) {
+version (Posix)
+{
 				case '/':
 				   return str[i+1..$];
 }
-version (_WIN32) {
+version (Windows)
+{
 				case '/':
 				case '\\':
 					return str[i+1..$];
@@ -230,13 +235,16 @@
 		if (n > str.ptr)
 		{
 			auto p = n - 1;
-version (POSIX) {
+version (Posix)
+{
 			if (*p == '/')
 				n--;
-} else version (_WIN32) {
+} else version (Windows)
+{
 			if (*p == '\\' || *p == '/')
 				n--;
-} else {
+} else
+{
 			static assert(false);
 }
 		}
@@ -263,13 +271,16 @@
 
 		char* f = cast(char*)GC.malloc(pathlen + 1 + namelen + 1);
 		memcpy(f, path.ptr, pathlen);
-version (POSIX) {
+version (Posix)
+{
 		if (path[pathlen - 1] != '/')
 		{
 			f[pathlen] = '/';
 			pathlen++;
 		}
-} else version (_WIN32) {
+}
+else version (Windows)
+{
 		if (path[pathlen - 1] != '\\' &&
 			path[pathlen - 1] != '/' &&
 			path[pathlen - 1] != ':')
@@ -277,7 +288,9 @@
 			f[pathlen] = '\\';
 			pathlen++;
 		}
-} else {
+}
+else
+{
 		static assert(false);
 }
 		memcpy(f + pathlen, name.ptr, namelen + 1);
@@ -300,13 +313,15 @@
 
 		memcpy(f, path.ptr, pathlen);
 
-version (POSIX) {
+version (Posix) {
 		if (path[pathlen - 1] != '/')
 		{
 			f[pathlen] = '/';
 			pathlen++;
 		}
-} else version (_WIN32) {
+}
+else version (Windows)
+{
 		if (path[pathlen - 1] != '\\' && 
 			path[pathlen - 1] != '/'  &&
 			path[pathlen - 1] != ':')
@@ -314,7 +329,9 @@
 			f[pathlen] = '\\';
 			pathlen++;
 		}
-} else {
+}
+else
+{
 		static assert(0);
 }
 		memcpy(f + pathlen, name.ptr, namelen + 1);
@@ -355,10 +372,10 @@
 	version (MACINTOSH) {
 						case ',':
 	}
-	version (_WIN32) {
+	version (Windows) {
 						case ';':
 	}
-	version (POSIX) {
+	version (Posix) {
 						case ':':
 	}
 							p++;
@@ -451,7 +468,7 @@
 
 version (POSIX) {
 		return cmp(e,ext) == 0;
-} else version (_WIN32) {
+} else version (Windows) {
 		return icmp(e,ext) == 0;
 } else {
 		static assert(0);
@@ -466,9 +483,9 @@
 	{
 		scope File file = new File(this);
 
-version (_WIN32) {
+version (Win32) {
 		file.touchtime = GC.malloc(WIN32_FIND_DATA.sizeof);	// keep same file time
-} else version (POSIX) {
+} else version (Posix) {
 		file.touchtime = GC.malloc(stat_t.sizeof); // keep same file time
 } else {
 		static assert(0);
@@ -537,7 +554,7 @@
 
     static int exists(string name)
 	{
-version (POSIX) {
+version (Posix) {
 		stat_t st;
 
 		if (stat(toStringz(name), &st) < 0)
@@ -545,7 +562,7 @@
 		if (S_ISDIR(st.st_mode))
 			return 2;
 		return 1;
-} else version (_WIN32) {
+} else version (Win32) {
 		HANDLE h = CreateFileA(toStringz(name), GENERIC_READ, FILE_SHARE_READ, null, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, HANDLE.init);	///
 		if (h == INVALID_HANDLE_VALUE) {
 			return 0;
@@ -569,6 +586,8 @@
 	
     static void ensurePathExists(string path)
 	{
+		if (path.length == 0)
+			return;
 		try {
 			mkdirRecurse(path);
 		} catch {
--- a/dmd/ForStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/ForStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,7 +1,9 @@
 module dmd.ForStatement;
 
+import dmd.common;
 import dmd.Statement;
 import dmd.Expression;
+import dmd.GlobalExpressions;
 import dmd.Loc;
 import dmd.Scope;
 import dmd.InterState;
@@ -155,7 +157,79 @@
 	
     override Expression interpret(InterState istate)
 	{
-		assert(false);
+version (LOG) {
+		printf("ForStatement.interpret()\n");
+}
+		if (istate.start == this)
+			istate.start = null;
+		
+		Expression e;
+
+		if (init)
+		{
+			e = init.interpret(istate);
+			if (e is EXP_CANT_INTERPRET)
+				return e;
+			assert(!e);
+		}
+
+		if (istate.start)
+		{
+			e = body_ ? body_.interpret(istate) : null;
+			if (istate.start)
+				return null;
+			if (e is EXP_CANT_INTERPRET)
+				return e;
+			if (e is EXP_BREAK_INTERPRET)
+				return null;
+			if (e is EXP_CONTINUE_INTERPRET)
+				goto Lcontinue;
+			if (e)
+				return e;
+		}
+
+		while (true)
+		{
+			if (!condition)
+				goto Lhead;
+			e = condition.interpret(istate);
+			if (e is EXP_CANT_INTERPRET)
+				break;
+			if (!e.isConst())
+			{   
+				e = EXP_CANT_INTERPRET;
+				break;
+			}
+			if (e.isBool(true))
+			{
+			Lhead:
+				e = body_ ? body_.interpret(istate) : null;
+				if (e is EXP_CANT_INTERPRET)
+					break;
+				if (e is EXP_BREAK_INTERPRET)
+				{   
+					e = null;
+					break;
+				}
+				if (e && e !is EXP_CONTINUE_INTERPRET)
+					break;
+			Lcontinue:
+				if (increment)
+				{
+					e = increment.interpret(istate);
+					if (e is EXP_CANT_INTERPRET)
+						break;
+				}
+			}
+			else if (e.isBool(false))
+			{
+				e = null;
+				break;
+			}
+			else
+				assert(0);
+		}
+		return e;
 	}
 	
     override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
--- a/dmd/ForeachRangeStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/ForeachRangeStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,9 +1,10 @@
 module dmd.ForeachRangeStatement;
 
+import dmd.common;
 import dmd.Statement;
 import dmd.TOK;
 import dmd.Token;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.Expression;
 import dmd.Statement;
 import dmd.VarDeclaration;
@@ -36,14 +37,14 @@
 class ForeachRangeStatement : Statement
 {
     TOK op;		// TOK.TOKforeach or TOK.TOKforeach_reverse
-    Argument arg;		// loop index variable
+    Parameter arg;		// loop index variable
     Expression lwr;
     Expression upr;
     Statement body_;
 
     VarDeclaration key = null;
 
-    this(Loc loc, TOK op, Argument arg, Expression lwr, Expression upr, Statement body_)
+    this(Loc loc, TOK op, Parameter arg, Expression lwr, Expression upr, Statement body_)
 	{
 		super(loc);
 		this.op = op;
@@ -120,17 +121,17 @@
 		ie = new ExpInitializer(loc, (op == TOKforeach) ? upr : lwr);
 		VarDeclaration tmp = new VarDeclaration(loc, arg.type, id, ie);
 
-		Statements cs = new Statements();
+		auto cs = new Statements();
 		// Keep order of evaluation as lwr, then upr
 		if (op == TOKforeach)
 		{
-			cs.push(cast(void*)new DeclarationStatement(loc, new DeclarationExp(loc, key)));
-			cs.push(cast(void*)new DeclarationStatement(loc, new DeclarationExp(loc, tmp)));
+			cs.push(new DeclarationStatement(loc, new DeclarationExp(loc, key)));
+			cs.push(new DeclarationStatement(loc, new DeclarationExp(loc, tmp)));
 		}
 		else
 		{
-			cs.push(cast(void*)new DeclarationStatement(loc, new DeclarationExp(loc, tmp)));
-			cs.push(cast(void*)new DeclarationStatement(loc, new DeclarationExp(loc, key)));
+			cs.push(new DeclarationStatement(loc, new DeclarationExp(loc, tmp)));
+			cs.push(new DeclarationStatement(loc, new DeclarationExp(loc, key)));
 		}
 		Statement forinit = new CompoundDeclarationStatement(loc, cs);
 
--- a/dmd/ForeachStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/ForeachStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.ForeachStatement;
 
+import dmd.common;
 import dmd.Statement;
 import dmd.TOK;
 import dmd.Token;
@@ -63,7 +64,7 @@
 import dmd.AddAssignExp;
 import dmd.CmpExp;
 import dmd.Id;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.STC;
 
 import dmd.expression.Util;
@@ -73,7 +74,7 @@
 class ForeachStatement : Statement
 {
     TOK op;		// TOKforeach or TOKforeach_reverse
-    Arguments arguments;	// array of Argument*'s
+    Parameters arguments;	// array of Argument*'s
     Expression aggr;
     Statement body_;
 
@@ -85,7 +86,7 @@
     Array cases;	// put breaks, continues, gotos and returns here
     Array gotos;	// forward referenced goto's go here
 
-    this(Loc loc, TOK op, Arguments arguments, Expression aggr, Statement body_)
+    this(Loc loc, TOK op, Parameters arguments, Expression aggr, Statement body_)
 	{
 		super(loc);
 		
@@ -100,9 +101,9 @@
 	
     override Statement syntaxCopy()
 	{
-		Arguments args = Argument.arraySyntaxCopy(arguments);
+		auto args = Parameter.arraySyntaxCopy(arguments);
 		Expression exp = aggr.syntaxCopy();
-		ForeachStatement s = new ForeachStatement(loc, op, args, exp,
+		auto s = new ForeachStatement(loc, op, args, exp,
 		body_ ? body_.syntaxCopy() : null);
 		return s;
 	}
@@ -114,6 +115,7 @@
 		Statement s = this;
 		size_t dim = arguments.dim;
 		TypeAArray taa = null;
+        Dsymbol sapply = null;
 
 		Type tn = null;
 		Type tnv = null;
@@ -152,7 +154,7 @@
 				return s;
 			}
 
-			TypeTuple tuple = cast(TypeTuple)tab;
+			auto tuple = cast(TypeTuple)tab;
 			Statements statements = new Statements();
 			//printf("aggr: op = %d, %s\n", aggr.op, aggr.toChars());
 			size_t n;
@@ -164,7 +166,7 @@
 			}
 			else if (aggr.op == TOK.TOKtype)	// type tuple
 			{
-				n = Argument.dim(tuple.arguments);
+				n = Parameter.dim(tuple.arguments);
 			}
 			else
 				assert(0);
@@ -177,10 +179,10 @@
 				if (te)
 					e = te.exps[k];
 				else
-					t = Argument.getNth(tuple.arguments, k).type;
+					t = Parameter.getNth(tuple.arguments, k).type;
 
-				Argument arg = cast(Argument)arguments.data[0];
-				Statements st = new Statements();
+				auto arg = arguments[0];
+				auto st = new Statements();
 
 				if (dim == 2)
 				{   
@@ -202,8 +204,8 @@
 					VarDeclaration var = new VarDeclaration(loc, arg.type, arg.ident, ie);
 					var.storage_class |= STC.STCmanifest;
 					DeclarationExp de = new DeclarationExp(loc, var);
-					st.push(cast(void*)new ExpStatement(loc, de));
-					arg = cast(Argument)arguments.data[1];	// value
+					st.push(new ExpStatement(loc, de));
+					arg = arguments[1];	// value
 				}
 				// Declare value
 				if (arg.storageClass & (STC.STCout | STC.STCref | STC.STClazy))
@@ -214,7 +216,7 @@
 					Type tb = e.type.toBasetype();
 					if ((tb.ty == TY.Tfunction || tb.ty == TY.Tsarray) && e.op == TOK.TOKvar)
 					{   
-						VarExp ve = cast(VarExp)e;
+						auto ve = cast(VarExp)e;
 						var = new AliasDeclaration(loc, arg.ident, ve.var);
 					}
 					else
@@ -233,13 +235,13 @@
 					var = new AliasDeclaration(loc, arg.ident, t);
 				}
 
-				DeclarationExp de = new DeclarationExp(loc, var);
-				st.push(cast(void*)new ExpStatement(loc, de));
+				auto de = new DeclarationExp(loc, var);
+				st.push(new ExpStatement(loc, de));
 
-				st.push(cast(void*)body_.syntaxCopy());
+				st.push(body_.syntaxCopy());
 				s = new CompoundStatement(loc, st);
 				s = new ScopeStatement(loc, s);
-				statements.push(cast(void*)s);
+				statements.push(s);
 			}
 
 			s = new UnrolledLoopStatement(loc, statements);
@@ -254,6 +256,9 @@
 		sc.noctor++;
 
 	Lagain:
+        Identifier idapply = (op == TOK.TOKforeach_reverse)
+		        ? Id.applyReverse : Id.apply;
+        sapply = null;
 		switch (tab.ty)
 		{
 			case TY.Tarray:
@@ -273,10 +278,10 @@
 				tn = tab.nextOf().toBasetype();
 				if (tn.ty == TY.Tchar || tn.ty == TY.Twchar || tn.ty == TY.Tdchar)
 				{	
-					Argument arg;
+					Parameter arg;
 
 					int i = (dim == 1) ? 0 : 1;	// index of value
-					arg = cast(Argument)arguments.data[i];
+					arg = arguments[i];
 					arg.type = arg.type.semantic(loc, sc);
 					tnv = arg.type.toBasetype();
 					if (tnv.ty != tn.ty && (tnv.ty == TY.Tchar || tnv.ty == TY.Twchar || tnv.ty == TY.Tdchar))
@@ -285,7 +290,7 @@
 							error("foreach: value of UTF conversion cannot be ref");
 						if (dim == 2)
 						{	
-							arg = cast(Argument)arguments.data[0];
+							arg = arguments[0];
 							if (arg.storageClass & STC.STCref)
 								error("foreach: key cannot be ref");
 						}
@@ -296,9 +301,9 @@
 				for (size_t i = 0; i < dim; i++)
 				{	
 					// Declare args
-					Argument arg = cast(Argument)arguments.data[i];
+					auto arg = arguments[i];
 					Type argtype = arg.type.semantic(loc, sc);
-					VarDeclaration var = new VarDeclaration(loc, argtype, arg.ident, null);
+					auto var = new VarDeclaration(loc, argtype, arg.ident, null);
 					var.storage_class |= STC.STCforeach;
 					var.storage_class |= arg.storageClass & (STC.STCin | STC.STCout | STC.STCref | STC.STC_TYPECTOR);
 					if (var.storage_class & (STC.STCref | STC.STCout))
@@ -355,9 +360,9 @@
 				else
 					key.init = new ExpInitializer(loc, new IntegerExp(0));
 
-				Statements cs = new Statements();
-				cs.push(cast(void*)new DeclarationStatement(loc, new DeclarationExp(loc, tmp)));
-				cs.push(cast(void*)new DeclarationStatement(loc, new DeclarationExp(loc, key)));
+				auto cs = new Statements();
+				cs.push(new DeclarationStatement(loc, new DeclarationExp(loc, tmp)));
+				cs.push(new DeclarationStatement(loc, new DeclarationExp(loc, key)));
 				Statement forinit = new CompoundDeclarationStatement(loc, cs);
 
 				Expression cond;
@@ -444,6 +449,15 @@
 			case TY.Tclass:
 			case TY.Tstruct:
 version (DMDV2) {
+	            /* Prefer using opApply, if it exists
+	             */
+	            if (dim != 1)	// only one argument allowed with ranges
+		        goto Lapply;
+
+	            sapply = search_function(cast(AggregateDeclaration)tab.toDsymbol(sc), idapply);
+	            if (sapply)
+		        goto Lapply;
+
 			{   /* Look for range iteration, i.e. the properties
 				 * .empty, .next, .retreat, .head and .rear
 				 *    foreach (e; aggr) { ... }
@@ -453,9 +467,6 @@
 				 *        ...
 				 *    }
 				 */
-				if (dim != 1)	// only one argument allowed with ranges
-				goto Lapply;
-
 				AggregateDeclaration ad = (tab.ty == TY.Tclass)
 					? cast(AggregateDeclaration)(cast(TypeClass)tab).sym
 					: cast(AggregateDeclaration)(cast(TypeStruct)tab).sym;
@@ -507,12 +518,12 @@
 				e = new VarExp(loc, r);
 				Expression einit = new DotIdExp(loc, e, idhead);
 		//	    einit = einit.semantic(sc);
-				Argument arg = cast(Argument)arguments.data[0];
-				VarDeclaration ve = new VarDeclaration(loc, arg.type, arg.ident, new ExpInitializer(loc, einit));
+				auto arg = arguments[0];
+				auto ve = new VarDeclaration(loc, arg.type, arg.ident, new ExpInitializer(loc, einit));
 				ve.storage_class |= STC.STCforeach;
 				ve.storage_class |= arg.storageClass & (STC.STCin | STC.STCout | STC.STCref | STC.STC_TYPECTOR);
 
-				DeclarationExp de = new DeclarationExp(loc, ve);
+				auto de = new DeclarationExp(loc, ve);
 
 				Statement body2 = new CompoundStatement(loc, new DeclarationStatement(loc, de), this.body_);
 				s = new ForStatement(loc, init, condition, increment, body2);
@@ -530,16 +541,9 @@
 			case TY.Tdelegate:
 			Lapply:
 			{   
-				FuncDeclaration fdapply;
-				Arguments args;
 				Expression ec;
 				Expression e;
-				FuncLiteralDeclaration fld;
-				Argument a;
-				Type t;
-				Expression flde;
-				Identifier id;
-				Type tret;
+				Parameter a;
 
 				if (!checkForArgTypes())
 				{	
@@ -547,12 +551,12 @@
 					return this;
 				}
 
-				tret = func.type.nextOf();
+				Type tret = func.type.nextOf();
 
 				// Need a variable to hold value from any return statements in body.
 				if (!sc.func.vresult && tret && tret != Type.tvoid)
 				{	
-					VarDeclaration v = new VarDeclaration(loc, tret, Id.result, null);
+					auto v = new VarDeclaration(loc, tret, Id.result, null);
 					v.noauto = true;
 					v.semantic(sc);
 					if (!sc.insert(v))
@@ -565,10 +569,11 @@
 				/* Turn body into the function literal:
 				 *	int delegate(ref T arg) { body }
 				 */
-				args = new Arguments();
+				auto args = new Parameters();
 				for (size_t i = 0; i < dim; i++)
 				{
-					Argument arg = cast(Argument)arguments.data[i];
+					auto arg = arguments[i];
+                    Identifier id;
 
 					arg.type = arg.type.semantic(loc, sc);
 					if (arg.storageClass & STC.STCref)
@@ -576,45 +581,42 @@
 					else
 					{   // Make a copy of the ref argument so it isn't
 						// a reference.
-						VarDeclaration v;
-						Initializer ie;
-
 						id = Lexer.uniqueId("__applyArg", i);
 
-						ie = new ExpInitializer(Loc(0), new IdentifierExp(Loc(0), id));
-						v = new VarDeclaration(Loc(0), arg.type, arg.ident, ie);
+						Initializer ie = new ExpInitializer(Loc(0), new IdentifierExp(Loc(0), id));
+						auto v = new VarDeclaration(Loc(0), arg.type, arg.ident, ie);
 						s = new DeclarationStatement(Loc(0), v);
 						body_ = new CompoundStatement(loc, s, body_);
 					}
-					a = new Argument(STC.STCref, arg.type, id, null);
-					args.push(cast(void*)a);
+					a = new Parameter(STC.STCref, arg.type, id, null);
+					args.push(a);
 				}
-				t = new TypeFunction(args, Type.tint32, 0, LINK.LINKd);
-				fld = new FuncLiteralDeclaration(loc, Loc(0), t, TOK.TOKdelegate, this);
+				Type t = new TypeFunction(args, Type.tint32, 0, LINK.LINKd);
+				FuncLiteralDeclaration fld = new FuncLiteralDeclaration(loc, Loc(0), t, TOK.TOKdelegate, this);
 				fld.fbody = body_;
-				flde = new FuncExp(loc, fld);
+				Expression flde = new FuncExp(loc, fld);
 				flde = flde.semantic(sc);
 				fld.tookAddressOf = 0;
 
 				// Resolve any forward referenced goto's
-				for (int i = 0; i < gotos.dim; i++)
+				for (size_t i = 0; i < gotos.dim; i++)
 				{	
-					CompoundStatement cs = cast(CompoundStatement)gotos.data[i];
-					GotoStatement gs = cast(GotoStatement)cs.statements.data[0];
+					auto cs = cast(CompoundStatement)gotos.data[i];
+					auto gs = cast(GotoStatement)cs.statements[0];
 
 					if (!gs.label.statement)
 					{   
 						// 'Promote' it to this scope, and replace with a return
 						cases.push(cast(void*)gs);
 						s = new ReturnStatement(Loc(0), new IntegerExp(cases.dim + 1));
-						cs.statements.data[0] = cast(void*)s;
+						cs.statements[0] = s;
 					}
 				}
 
 				if (tab.ty == TY.Taarray)
 				{
 					// Check types
-					Argument arg = cast(Argument)arguments.data[0];
+					auto arg = arguments[0];
 					if (dim == 2)
 					{
 						if (arg.storageClass & STC.STCref)
@@ -622,7 +624,7 @@
 						if (!arg.type.equals(taa.index))
 							error("foreach: index must be type %s, not %s", taa.index.toChars(), arg.type.toChars());
 
-						arg = cast(Argument)arguments.data[1];
+						arg = arguments[1];
 					}
 					if (!arg.type.equals(taa.nextOf()))
 						error("foreach: value must be type %s, not %s", taa.nextOf().toChars(), arg.type.toChars());
@@ -630,6 +632,7 @@
 					/* Call:
 					 *	_aaApply(aggr, keysize, flde)
 					 */
+		            FuncDeclaration fdapply;
 					if (dim == 2)
 						fdapply = FuncDeclaration.genCfunc(Type.tindex, "_aaApply2");
 					else
@@ -673,7 +676,7 @@
 					string r = (op == TOK.TOKforeach_reverse) ? "R" : "";
 					int j = sprintf(fdname.ptr, "_aApply%.*s%.*s%zd".ptr, r, 2, fntab[flag].ptr, dim);
 					assert(j < fdname.sizeof);
-					fdapply = FuncDeclaration.genCfunc(Type.tindex, fdname[0..j].idup);
+					FuncDeclaration fdapply = FuncDeclaration.genCfunc(Type.tindex, fdname[0..j].idup);
 
 					ec = new VarExp(Loc(0), fdapply);
 					auto exps = new Expressions();
@@ -699,10 +702,9 @@
 				else
 				{
 					assert(tab.ty == TY.Tstruct || tab.ty == TY.Tclass);
-					Identifier idapply = (op == TOK.TOKforeach_reverse)
-							? Id.applyReverse : Id.apply;
-					Dsymbol sapply = search_function(cast(AggregateDeclaration)tab.toDsymbol(sc), idapply);
-					Expressions exps = new Expressions();
+					auto exps = new Expressions();
+		            if (!sapply)
+		                sapply = search_function(cast(AggregateDeclaration)tab.toDsymbol(sc), idapply);
 static if (false) {
 					TemplateDeclaration td;
 					if (sapply && (td = sapply.isTemplateDeclaration()) !is null)
@@ -710,11 +712,9 @@
 						/* Call:
 						 *	aggr.apply!(fld)()
 						 */
-						TemplateInstance ti = new TemplateInstance(loc, idapply);
 						Objects tiargs = new Objects();
 						tiargs.push(cast(void*)fld);
-						ti.tiargs = tiargs;
-						ec = new DotTemplateInstanceExp(loc, aggr, ti);
+						ec = new DotTemplateInstanceExp(loc, aggr, idapply, tiargs);
 					}
 					else
 					{
@@ -743,19 +743,19 @@
 				else
 				{	// Construct a switch statement around the return value
 					// of the apply function.
-					Statements a2 = new Statements();
+					auto a2 = new Statements();
 
 					// default: break; takes care of cases 0 and 1
 					s = new BreakStatement(Loc(0), null);
 					s = new DefaultStatement(Loc(0), s);
-					a2.push(cast(void*)s);
+					a2.push(s);
 
 					// cases 2...
 					for (int i = 0; i < cases.dim; i++)
 					{
 						s = cast(Statement)cases.data[i];
 						s = new CaseStatement(Loc(0), new IntegerExp(i + 2), s);
-						a2.push(cast(void*)s);
+						a2.push(s);
 					}
 
 					s = new CompoundStatement(loc, a2);
@@ -780,9 +780,8 @@
 	{
 		bool result = true;
 
-		for (size_t i = 0; i < arguments.dim; i++)
+		foreach (arg; arguments)
 		{	
-			Argument arg = cast(Argument)arguments.data[i];
 			if (!arg.type)
 			{
 				error("cannot infer type for %s", arg.ident.toChars());
@@ -841,7 +840,7 @@
 		buf.writestring(" (");
 		for (int i = 0; i < arguments.dim; i++)
 		{
-			Argument a = cast(Argument)arguments.data[i];
+			auto a = arguments[i];
 			if (i)
 				buf.writestring(", ");
 			if (a.storageClass & STCref) 
--- a/dmd/FuncAliasDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/FuncAliasDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.FuncAliasDeclaration;
 
+import dmd.common;
 import dmd.FuncDeclaration;
 
 import dmd.backend.Symbol;
--- a/dmd/FuncDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/FuncDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.FuncDeclaration;
 
+import dmd.common;
 import dmd.Declaration;
 import dmd.DotIdExp;
 import dmd.AddrExp;
@@ -53,7 +54,7 @@
 import dmd.PtrExp;
 import dmd.DeclarationExp;
 import dmd.InlineDoState;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.StructDeclaration;
 import dmd.ClassDeclaration;
 import dmd.InterfaceDeclaration;
@@ -72,6 +73,7 @@
 import dmd.TypeFunction;
 import dmd.Expression;
 import dmd.STC;
+import dmd.TRUST;
 import dmd.Dsymbol;
 import dmd.Scope;
 import dmd.OutBuffer;
@@ -193,7 +195,7 @@
     int nestedFrameRef;			// !=0 if nested variables referenced
 }
 
-    this(Loc loc, Loc endloc, Identifier id, STC storage_class, Type type)
+    this(Loc loc, Loc endloc, Identifier id, StorageClass storage_class, Type type)
 	{
 		super(id);
 
@@ -307,37 +309,59 @@
 			originalType = type;
 		if (!type.deco)
 		{
-			/* Apply const and invariant storage class
+    	    sc = sc.push();
+	        sc.stc |= storage_class & STC.STCref;	// forward refness to function type
+	        type = type.semantic(loc, sc);
+	        sc = sc.pop();
+            
+			/* Apply const, immutable and shared storage class
 			 * to the function type
 			 */
-			type = type.semantic(loc, sc);
-			STC stc = storage_class;
-			if (type.isInvariant())
+			StorageClass stc = storage_class;
+			if (type.isImmutable())
 				stc |= STC.STCimmutable;
 			if (type.isConst())
 				stc |= STC.STCconst;
 			if (type.isShared() || storage_class & STC.STCsynchronized)
 				stc |= STC.STCshared;
+	        if (type.isWild())
+	            stc |= STC.STCwild;
 			switch (stc & STC.STC_TYPECTOR)
 			{
 				case STC.STCimmutable:
 				case STC.STCimmutable | STC.STCconst:
 				case STC.STCimmutable | STC.STCconst | STC.STCshared:
 				case STC.STCimmutable | STC.STCshared:
+                case STC.STCimmutable | STC.STCwild:
+	            case STC.STCimmutable | STC.STCconst | STC.STCwild:
+	            case STC.STCimmutable | STC.STCconst | STC.STCshared | STC.STCwild:
+	            case STC.STCimmutable | STC.STCshared | STC.STCwild:
 				// Don't use toInvariant(), as that will do a merge()
 				type = type.makeInvariant();
 				goto Lmerge;
 	
 				case STC.STCconst:
+	            case STC.STCconst | STC.STCwild:
 				type = type.makeConst();
 				goto Lmerge;
 	
 				case STC.STCshared | STC.STCconst:
+	            case STC.STCshared | STC.STCconst | STC.STCwild:
 				type = type.makeSharedConst();
 				goto Lmerge;
 	
 				case STC.STCshared:
 				type = type.makeShared();
+		        goto Lmerge;
+
+	            case STC.STCwild:
+		        type = type.makeWild();
+		        goto Lmerge;
+
+	            case STC.STCshared | STC.STCwild:
+		        type = type.makeSharedWild();
+		        goto Lmerge;
+
 				Lmerge:
 					if (!(type.ty == Tfunction && !type.nextOf()))
 						/* Can't do merge if return type is not known yet
@@ -352,14 +376,14 @@
 				assert(0);
 			}
 		}
-		//type.print();
+        storage_class &= ~STC.STCref;
 		if (type.ty != TY.Tfunction)
 		{
 		error("%s must be a function", toChars());
 		return;
 		}
 		f = cast(TypeFunction)type;
-		size_t nparams = Argument.dim(f.parameters);
+		size_t nparams = Parameter.dim(f.parameters);
 
 		linkage = sc.linkage;
 	//    if (!parent)
@@ -376,7 +400,7 @@
 		if (isAbstract() && !isVirtual())
 		error("non-virtual functions cannot be abstract");
 
-		if ((f.isConst() || f.isInvariant()) && !isThis())
+		if ((f.isConst() || f.isImmutable()) && !isThis())
 		error("without 'this' cannot be const/immutable");
 
 		if (isAbstract() && isFinal())
@@ -732,7 +756,7 @@
 
 			case 1:
 			{
-			Argument arg0 = Argument.getNth(f.parameters, 0);
+			auto arg0 = Parameter.getNth(f.parameters, 0);
 			if (arg0.type.ty != TY.Tarray ||
 				arg0.type.nextOf().ty != TY.Tarray ||
 				arg0.type.nextOf().nextOf().ty != TY.Tchar ||
@@ -766,7 +790,7 @@
 		}
 		else
 		{
-			Argument arg0 = Argument.getNth(f.parameters, 0);
+			auto arg0 = Parameter.getNth(f.parameters, 0);
 			Type t0 = arg0.type.toBasetype();
 			Type tb = sd ? sd.type : cd.type;
 			if (arg0.type.implicitConvTo(tb) ||
@@ -775,7 +799,7 @@
 			{
 			if (nparams == 1)
 				goto Lassignerr;
-			Argument arg1 = Argument.getNth(f.parameters, 1);
+			auto arg1 = Parameter.getNth(f.parameters, 1);
 			if (arg1.defaultArg)
 				goto Lassignerr;
 			}
@@ -816,12 +840,12 @@
 					outId = Id.result;	// provide a default
 
 				Loc loc = fensure.loc;
-				Arguments arguments = new Arguments();
-				Argument a = null;
+				auto arguments = new Parameters();
+				Parameter a = null;
 				if (outId)
 				{	
-					a = new Argument(STCref, f.nextOf(), outId, null);
-					arguments.push(cast(void*)a);
+					a = new Parameter(STCref, f.nextOf(), outId, null);
+					arguments.push(a);
 				}
 				TypeFunction tf = new TypeFunction(arguments, Type.tvoid, 0, LINKd);
 				FuncDeclaration fd = new FuncDeclaration(loc, loc, Id.ensure, STCundefined, tf);
@@ -922,8 +946,10 @@
 		sc2.sw = null;
 		sc2.fes = fes;
 		sc2.linkage = LINK.LINKd;
-		sc2.stc &= ~(STC.STCauto | STC.STCscope | STC.STCstatic | STC.STCabstract | STC.STCdeprecated | STC.STC_TYPECTOR | STC.STCfinal | STC.STCtls | STC.STCgshared | STC.STCref);
-		sc2.protection = PROT.PROTpublic;
+        sc2.stc &= ~(STC.STCauto | STC.STCscope | STC.STCstatic | STC.STCabstract | STC.STCdeprecated |
+			        STC.STC_TYPECTOR | STC.STCfinal | STC.STCtls | STC.STCgshared | STC.STCref |
+			        STCproperty | STCsafe | STCtrusted | STCsystem);
+        sc2.protection = PROT.PROTpublic;
 		sc2.explicitProtection = 0;
 		sc2.structalign = 8;
 		sc2.incontract = 0;
@@ -961,7 +987,7 @@
 				thandle = thandle.nextOf().constOf().pointerTo();
 				}
 			}
-			else if (storage_class & STC.STCimmutable || type.isInvariant())
+			else if (storage_class & STC.STCimmutable || type.isImmutable())
 			{
 				if (thandle.ty == TY.Tclass)
 				thandle = thandle.invariantOf();
@@ -1050,29 +1076,29 @@
 			}
 }
 		}
-
+static if(false) {
 		// Propagate storage class from tuple parameters to their element-parameters.
 		if (f.parameters)
 		{
-			for (size_t i = 0; i < f.parameters.dim; i++)
-			{	Argument arg = cast(Argument)f.parameters.data[i];
-
+			foreach (arg; f.parameters)
+			{
 			//printf("[%d] arg.type.ty = %d %s\n", i, arg.type.ty, arg.type.toChars());
 			if (arg.type.ty == TY.Ttuple)
-			{   TypeTuple t = cast(TypeTuple)arg.type;
-				size_t dim = Argument.dim(t.arguments);
+			{   auto t = cast(TypeTuple)arg.type;
+				size_t dim = Parameter.dim(t.arguments);
 				for (size_t j = 0; j < dim; j++)
-				{	Argument narg = Argument.getNth(t.arguments, j);
-				narg.storageClass = arg.storageClass;
+				{
+                    auto narg = Parameter.getNth(t.arguments, j);
+				    narg.storageClass = arg.storageClass;
 				}
 			}
 			}
 		}
-
+}
 		/* Declare all the function parameters as variables
 		 * and install them in parameters[]
 		 */
-		size_t nparams = Argument.dim(f.parameters);
+		size_t nparams = Parameter.dim(f.parameters);
 		if (nparams)
 		{   /* parameters[] has all the tuples removed, as the back end
 			 * doesn't know about tuples
@@ -1081,7 +1107,7 @@
 			parameters.reserve(nparams);
 			for (size_t i = 0; i < nparams; i++)
 			{
-			Argument arg = Argument.getNth(f.parameters, i);
+			auto arg = Parameter.getNth(f.parameters, i);
 			Identifier id = arg.ident;
 			if (!id)
 			{
@@ -1113,26 +1139,25 @@
 		// but not in parameters[].
 		if (f.parameters)
 		{
-			for (size_t i = 0; i < f.parameters.dim; i++)
-			{	Argument arg = cast(Argument)f.parameters.data[i];
-
+			foreach (arg; f.parameters)
+			{
 			if (!arg.ident)
 				continue;			// never used, so ignore
 			if (arg.type.ty == TY.Ttuple)
-			{   TypeTuple t = cast(TypeTuple)arg.type;
-				size_t dim = Argument.dim(t.arguments);
+			{   auto t = cast(TypeTuple)arg.type;
+				size_t dim = Parameter.dim(t.arguments);
 				Objects exps = new Objects();
 				exps.setDim(dim);
 				for (size_t j = 0; j < dim; j++)
-				{	Argument narg = Argument.getNth(t.arguments, j);
+				{	auto narg = Parameter.getNth(t.arguments, j);
 				assert(narg.ident);
 				VarDeclaration v = sc2.search(Loc(0), narg.ident, null).isVarDeclaration();
 				assert(v);
 				Expression e = new VarExp(v.loc, v);
-				exps.data[j] = cast(void*)e;
+				exps[j] = e;
 				}
 				assert(arg.ident);
-				TupleDeclaration v = new TupleDeclaration(loc, arg.ident, exps);
+				auto v = new TupleDeclaration(loc, arg.ident, exps);
 				//printf("declaring tuple %s\n", v.toChars());
 				v.isexp = 1;
 				if (!sc2.insert(v))
@@ -1191,15 +1216,16 @@
 
 			if (outId)
 			{	// Declare result variable
-			VarDeclaration v;
 			Loc loc = this.loc;
 
 			if (fensure)
 				loc = fensure.loc;
 
-			v = new VarDeclaration(loc, type.nextOf(), outId, null);
+			auto v = new VarDeclaration(loc, type.nextOf(), outId, null);
 			v.noauto = true;
 version (DMDV2) {
+		    if (!isVirtual())
+		        v.storage_class |= STC.STCconst;
 			if (f.isref)
 			{
 				v.storage_class |= STC.STCref | STC.STCforeach;
@@ -1430,7 +1456,7 @@
 		}
 
 		{
-			Statements a = new Statements();
+			auto a = new Statements();
 
 			// Merge in initialization of 'out' parameters
 			if (parameters)
@@ -1442,7 +1468,7 @@
 				assert(v.init);
 				ExpInitializer ie = v.init.isExpInitializer();
 				assert(ie);
-				a.push(cast(void*)new ExpStatement(Loc(0), ie.exp));
+				a.push(new ExpStatement(Loc(0), ie.exp));
 				}
 			}
 			}
@@ -1472,7 +1498,7 @@
 				Expression e = new SymOffExp(Loc(0), p, offset);
 				e = new AssignExp(Loc(0), e1, e);
 				e.type = t;
-				a.push(cast(void*)new ExpStatement(Loc(0), e));
+				a.push(new ExpStatement(Loc(0), e));
 				p.isargptr = true;
 }
 			}
@@ -1488,7 +1514,7 @@
 			e = new AssignExp(Loc(0), e1, e);
 			e.op = TOK.TOKconstruct;
 			e = e.semantic(sc2);
-			a.push(cast(void*)new ExpStatement(Loc(0), e));
+			a.push(new ExpStatement(Loc(0), e));
 			}
 
 			// Merge contracts together with body into one compound statement
@@ -1500,7 +1526,7 @@
 			}
 } else {
 			if (frequire && global.params.useIn)
-			a.push(cast(void*)frequire);
+			a.push(frequire);
 }
 
 			// Precondition invariant
@@ -1542,17 +1568,17 @@
 			}
 			if (e)
 			{
-				ExpStatement s = new ExpStatement(Loc(0), e);
-				a.push(cast(void*)s);
+				auto s = new ExpStatement(Loc(0), e);
+				a.push(s);
 			}
 			}
 
 			if (fbody)
-			a.push(cast(void*)fbody);
+			a.push(fbody);
 
 			if (fensure)
 			{
-			a.push(cast(void*)returnLabel.statement);
+			a.push(returnLabel.statement);
 
 			if (type.nextOf().ty != TY.Tvoid)
 			{
@@ -1563,8 +1589,8 @@
 				{	e = e.implicitCastTo(sc, tintro.nextOf());
 				e = e.semantic(sc);
 				}
-				ReturnStatement s = new ReturnStatement(Loc(0), e);
-				a.push(cast(void*)s);
+				auto s = new ReturnStatement(Loc(0), e);
+				a.push(s);
 			}
 			}
 
@@ -1898,7 +1924,7 @@
 
 				//printf("tf = %s, args = %s\n", tf.deco, ((Expression *)arguments.data[0]).type.deco);
 				error(loc, "%s%s is not callable using argument types %s",
-				Argument.argsTypesToChars(tf.parameters, tf.varargs),
+				Parameter.argsTypesToChars(tf.parameters, tf.varargs),
 				buf2.toChars(),
 				buf.toChars());
 				return m.anyf;		// as long as it's not a FuncAliasDeclaration
@@ -1911,8 +1937,8 @@
 
 				error(loc, "called with argument types:\n\t(%s)\nmatches both:\n\t%s%s\nand:\n\t%s%s",
 					buf.toChars(),
-					m.lastf.toPrettyChars(), Argument.argsTypesToChars(t1.parameters, t1.varargs),
-					m.nextf.toPrettyChars(), Argument.argsTypesToChars(t2.parameters, t2.varargs));
+					m.lastf.toPrettyChars(), Parameter.argsTypesToChars(t1.parameters, t1.varargs),
+					m.nextf.toPrettyChars(), Parameter.argsTypesToChars(t2.parameters, t2.varargs));
 } else {
 				error(loc, "overloads %s and %s both match argument list for %s",
 					m.lastf.type.toChars(),
@@ -1944,8 +1970,8 @@
 
 		TypeFunction tf = cast(TypeFunction)type;
 		TypeFunction tg = cast(TypeFunction)g.type;
-		size_t nfparams = Argument.dim(tf.parameters);
-		size_t ngparams = Argument.dim(tg.parameters);
+		size_t nfparams = Parameter.dim(tf.parameters);
+		size_t ngparams = Parameter.dim(tg.parameters);
 		MATCH match = MATCHexact;
 
 		/* If both functions have a 'this' pointer, and the mods are not
@@ -1968,7 +1994,7 @@
 		args.setDim(nfparams);
 		for (int u = 0; u < nfparams; u++)
 		{
-			Argument p = Argument.getNth(tf.parameters, u);
+			auto p = Parameter.getNth(tf.parameters, u);
 			Expression e;
 			if (p.storageClass & (STCref | STCout))
 			{
@@ -2253,6 +2279,18 @@
 		return (cast(TypeFunction)this.type).ispure;
 	}
 	
+	int isSafe()
+	{
+		assert(type.ty == TY.Tfunction);
+		return (cast(TypeFunction)this.type).trust == TRUST.TRUSTsafe;
+	}
+
+	int isTrusted()
+	{
+		assert(type.ty == TY.Tfunction);
+		return (cast(TypeFunction)this.type).trust == TRUST.TRUSTtrusted;
+	}
+	
     bool isNested()
 	{
 		//if (!toParent())
@@ -2288,7 +2326,7 @@
 		return isMember() && !(isStatic() || protection == PROT.PROTprivate || protection == PROT.PROTpackage) && toParent().isClassDeclaration();
 	}
 	
-    override int isFinal()
+    override bool isFinal()
 	{
 		ClassDeclaration cd;
 static if (false) {
@@ -2339,13 +2377,28 @@
 }
 		if (global.errors)
 			return null;
+version(DMDV1)
+{
 		if (ident == Id.aaLen)
 			return interpret_aaLen(istate, arguments);
 		else if (ident == Id.aaKeys)
 			return interpret_aaKeys(istate, arguments);
 		else if (ident == Id.aaValues)
 			return interpret_aaValues(istate, arguments);
-
+}
+else version(DMDV2)
+{
+		if (thisarg && (!arguments || arguments.dim == 0))
+		{
+			if (ident == Id.length)
+				return interpret_length(istate, thisarg);
+			else if (ident == Id.keys)
+				return interpret_keys(istate, thisarg, this);
+			else if (ident == Id.values)
+				return interpret_values(istate, thisarg, this);
+		}
+}
+	
 		if (cantInterpret || semanticRun == 3)
 			return null;
 
@@ -2368,20 +2421,20 @@
 		assert(tb.ty == Tfunction);
 		TypeFunction tf = cast(TypeFunction)tb;
 		Type tret = tf.next.toBasetype();
-		if (tf.varargs)
+		if (tf.varargs && arguments && parameters && arguments.dim != parameters.dim)
 		{	
 			cantInterpret = 1;
-			error("Variadic functions are not yet implemented in CTFE");
+			error("C-style variadic functions are not yet implemented in CTFE");
 			return null;
 		}
 		
 		// Ensure there are no lazy parameters
 		if (tf.parameters)
 		{	
-			size_t dim = Argument.dim(tf.parameters);
+			size_t dim = Parameter.dim(tf.parameters);
 			for (size_t i = 0; i < dim; i++)
 			{   
-				Argument arg = Argument.getNth(tf.parameters, i);
+				auto arg = Parameter.getNth(tf.parameters, i);
 				if (arg.storageClass & STClazy)
 				{   
 					cantInterpret = 1;
@@ -2419,7 +2472,7 @@
 			for (size_t i = 0; i < dim; i++)
 			{   
 				Expression earg = arguments[i];
-				Argument arg = Argument.getNth(tf.parameters, i);
+				auto arg = Parameter.getNth(tf.parameters, i);
 
 				if (arg.storageClass & (STCout | STCref))
 				{
@@ -2448,7 +2501,7 @@
 			for (size_t i = 0; i < dim; i++)
 			{   
 				auto earg = eargs[i];
-				Argument arg = Argument.getNth(tf.parameters, i);
+				auto arg = Parameter.getNth(tf.parameters, i);
 				auto v = cast(VarDeclaration)parameters[i];
 				vsave[i] = v.value;
 version (LOG) {
@@ -2516,7 +2569,7 @@
 			}
 		}
 		// Don't restore the value of 'this' upon function return
-		if (needThis() && thisarg.op==TOKvar) {
+		if (needThis() && thisarg.op == TOKvar && istate) {
 			VarDeclaration thisvar = (cast(VarExp)thisarg).var.isVarDeclaration();
  			foreach (size_t i, Dsymbol s; istate.vars)
 			{   
@@ -2531,7 +2584,7 @@
 
 		/* Save the values of the local variables used
 		 */
-		scope Expressions valueSaves = new Expressions();
+		scope valueSaves = new Expressions();
 		if (istate && !isNested())
 		{
 			//printf("saving local variables...\n");
@@ -3804,6 +3857,35 @@
 		}
 	}
 
+    /*********************************************
+     * Return the function's parameter list, and whether
+     * it is variadic or not.
+     */
+
+    Parameters getParameters(int *pvarargs)
+    {
+        Parameters fparameters;
+        int fvarargs;
+
+        if (type)
+        {
+	        assert(type.ty == Tfunction);
+	        auto fdtype = cast(TypeFunction)type;
+	        fparameters = fdtype.parameters;
+	        fvarargs = fdtype.varargs;
+        }
+        else // Constructors don't have type's
+        {
+            CtorDeclaration fctor = isCtorDeclaration();
+	        assert(fctor);
+	        fparameters = fctor.arguments;
+	        fvarargs = fctor.varargs;
+        }
+        if (pvarargs)
+	    *pvarargs = fvarargs;
+        return fparameters;
+    }
+
     override FuncDeclaration isFuncDeclaration() { return this; }
 }
 
--- a/dmd/FuncExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/FuncExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.FuncExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.backend.elem;
 import dmd.OutBuffer;
@@ -86,7 +87,8 @@
 
 	override void scanForNestedRef(Scope sc)
 	{
-		assert(false);
+		//printf("FuncExp.scanForNestedRef(%s)\n", toChars());
+		//fd.parent = sc.parent;
 	}
 
 	override string toChars()
@@ -121,7 +123,8 @@
 
 	override int inlineCost(InlineCostState* ics)
 	{
-		assert(false);
+		// Right now, this makes the function be output to the .obj file twice.
+		return COST_MAX;
 	}
 }
 
--- a/dmd/FuncLiteralDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/FuncLiteralDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.FuncLiteralDeclaration;
 
+import dmd.common;
 import dmd.FuncDeclaration;
 import dmd.TOK;
 import dmd.Loc;
--- a/dmd/Global.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/Global.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.Global;
 
+import dmd.common;
 import dmd.Array;
 import dmd.Param;
 
@@ -38,7 +39,7 @@
     string[] path;	// Array of char*'s which form the import lookup path
     string[] filePath;	// Array of char*'s which form the file import lookup path
     int structalign = 8;
-    string version_ = "v2.036";
+    string version_ = "v2.039";
 
     Param params;
     uint errors;	// number of errors reported so far
--- a/dmd/GlobalExpressions.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/GlobalExpressions.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.GlobalExpressions;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.TOK;
 import dmd.Loc;
--- a/dmd/GotoCaseStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/GotoCaseStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.GotoCaseStatement;
 
+import dmd.common;
 import dmd.Statement;
 import dmd.Expression;
 import dmd.CaseStatement;
@@ -12,6 +13,11 @@
 import dmd.BE;
 import dmd.WANT;
 
+import dmd.backend.Util;
+import dmd.backend.block;
+import dmd.backend.BC;
+import dmd.backend.Blockx;
+
 class GotoCaseStatement : Statement
 {
     Expression exp;		// NULL, or which case to goto
@@ -74,6 +80,39 @@
 
     override void toIR(IRState* irs)
 	{
-		assert(false);
+		block* b;
+		Blockx* blx = irs.blx;
+		block* bdest = cs.cblock;
+
+		if (!bdest)
+		{
+			bdest = block_calloc(blx);
+			cs.cblock = bdest;
+		}
+
+		b = blx.curblock;
+
+		// The rest is equivalent to GotoStatement
+
+		// Adjust exception handler scope index if in different try blocks
+		if (b.Btry != bdest.Btry)
+		{
+			// Check that bdest is in an enclosing try block
+			for (block* bt = b.Btry; bt != bdest.Btry; bt = bt.Btry)
+			{
+				if (!bt)
+				{
+					//printf("b.Btry = %p, bdest.Btry = %p\n", b.Btry, bdest.Btry);
+					error("cannot goto into try block");
+					break;
+				}
+			}
+
+			//setScopeIndex(blx, b, bdest.Btry ? bdest.Btry.Bscope_index : -1);
+		}
+
+		list_append(&b.Bsucc,bdest);
+		incUsage(irs, loc);
+		block_next(blx, BC.BCgoto, null);
 	}
 }
--- a/dmd/GotoDefaultStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/GotoDefaultStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.GotoDefaultStatement;
 
+import dmd.common;
 import dmd.Statement;
 import dmd.SwitchStatement;
 import dmd.Loc;
--- a/dmd/GotoStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/GotoStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.GotoStatement;
 
+import dmd.common;
 import dmd.Loc;
 import dmd.Scope;
 import dmd.Statement;
@@ -55,10 +56,10 @@
 			 * so we can patch it later, and add it to a 'look at this later'
 			 * list.
 			 */
-			Statements a = new Statements();
+			auto a = new Statements();
 			Statement s;
 
-			a.push(cast(void*)this);
+			a.push(this);
 			s = new CompoundStatement(loc, a);
 			sc.fes.gotos.push(cast(void*)s);		// 'look at this later' list
 			return s;
--- a/dmd/HaltExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/HaltExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.HaltExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.backend.elem;
 import dmd.OutBuffer;
--- a/dmd/IRState.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/IRState.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.IRState;
 
+import dmd.common;
 import dmd.Statement;
 import dmd.Module;
 import dmd.Dsymbol;
@@ -8,6 +9,10 @@
 import dmd.FuncDeclaration;
 import dmd.Global;
 import dmd.Loc;
+import dmd.TRUST;
+import dmd.TY;
+import dmd.TypeFunction;
+import dmd.Type;
 
 import dmd.backend.Symbol;
 import dmd.backend.Blockx;
@@ -123,6 +128,28 @@
 		}
 		return cast(FuncDeclaration)(bc.symbol);
 	}
+
+    /**********************
+     * Return !=0 if do array bounds checking
+     */
+    int arrayBoundsCheck()
+    {
+        int result = global.params.useArrayBounds;
+
+        if (result == 1)
+        {
+            // For safe functions only
+	        result = 0;
+	        FuncDeclaration fd = getFunc();
+	        if (fd)
+	        {
+                Type t = fd.type;
+	            if (t.ty == TY.Tfunction && (cast(TypeFunction)t).trust == TRUST.TRUSTsafe)
+		        result = 1;
+	        }
+        }
+        return result;
+    }
 }
 
 /*********************************************
--- a/dmd/Id.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/Id.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.Id;
 
+import dmd.common;
 import dmd.Identifier;
 import dmd.Lexer;
 
@@ -78,7 +79,6 @@
 		ID( "coverage", "__coverage" ),
 		ID( "__vptr" ),
 		ID( "__monitor" ),
-		ID( "system" ),
 
 		ID( "TypeInfo" ),
 		ID( "TypeInfo_Class" ),
@@ -96,6 +96,8 @@
 		ID( "TypeInfo_Const" ),
 		ID( "TypeInfo_Invariant" ),
 		ID( "TypeInfo_Shared" ),
+        ID( "TypeInfo_Wild", "TypeInfo_Inout" ),
+            
 		ID( "elements" ),
 		ID( "_arguments_typeinfo" ),
 		ID( "_arguments" ),
@@ -145,6 +147,9 @@
 		ID( "idup" ),
 
 		ID( "property" ),
+        ID( "safe" ),
+        ID( "trusted" ),
+        ID( "system" ),
 
 		// For inline assembler
 		ID( "___out", "out" ),
@@ -210,8 +215,12 @@
 		ID( "opIn_r" ),
 		ID( "opStar" ),
 		ID( "opDot" ),
+        ID( "opDispatch" ),
 		ID( "opImplicitCast" ),
-
+        ID( "pow", "opPow" ),
+        ID( "pow_r", "opPow_r" ),
+        ID( "powass", "opPowAssign" ),
+    
 		ID( "classNew", "new" ),
 		ID( "classDelete", "delete" ),
 
@@ -271,6 +280,7 @@
 		ID( "cos" ),
 		ID( "tan" ),
 		ID( "_sqrt", "sqrt" ),
+        ID( "_pow", "pow" ),
 		ID( "fabs" ),
 
 		// Traits
@@ -286,6 +296,9 @@
 		ID( "isVirtualFunction" ),
 		ID( "isAbstractFunction" ),
 		ID( "isFinalFunction" ),
+        ID( "isRef" ),
+        ID( "isOut" ),
+        ID( "isLazy" ),
 		ID( "hasMember" ),
 		ID( "getMember" ),
 		ID( "getVirtualFunctions" ),
--- a/dmd/Identifier.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/Identifier.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.Identifier;
 
+import dmd.common;
 import dmd.TOK;
 import dmd.DYNCAST;
 import dmd.Lexer;
--- a/dmd/IdentifierExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/IdentifierExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.IdentifierExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Declaration;
 import dmd.TY;
--- a/dmd/IdentityExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/IdentityExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.IdentityExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.InterState;
 import dmd.Loc;
@@ -52,12 +53,10 @@
 
 	override Expression optimize(int result)
 	{
-		Expression e;
-
 		//printf("IdentityExp.optimize(result = %d) %s\n", result, toChars());
 		e1 = e1.optimize(WANT.WANTvalue | (result & WANT.WANTinterpret));
 		e2 = e2.optimize(WANT.WANTvalue | (result & WANT.WANTinterpret));
-		e = this;
+		Expression e = this;
 
 		if ((this.e1.isConst() && this.e2.isConst()) || (this.e1.op == TOK.TOKnull && this.e2.op == TOK.TOKnull))
 		{
@@ -71,7 +70,7 @@
 
 	override Expression interpret(InterState istate)
 	{
-		assert(false);
+		return interpretCommon2(istate, &Identity);
 	}
 
 	override elem* toElem(IRState* irs)
--- a/dmd/IfStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/IfStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,7 +1,8 @@
 module dmd.IfStatement;
 
+import dmd.common;
 import dmd.Statement;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.Loc;
 import dmd.Expression;
 import dmd.VarDeclaration;
@@ -31,14 +32,14 @@
 
 class IfStatement : Statement
 {
-    Argument arg;
+    Parameter arg;
     Expression condition;
     Statement ifbody;
     Statement elsebody;
 
     VarDeclaration match;	// for MatchExpression results
 
-    this(Loc loc, Argument arg, Expression condition, Statement ifbody, Statement elsebody)
+    this(Loc loc, Parameter arg, Expression condition, Statement ifbody, Statement elsebody)
 	{
 		super(loc);
 		this.arg = arg;
@@ -57,7 +58,7 @@
 		if (elsebody)
 			e = elsebody.syntaxCopy();
 
-		Argument a = arg ? arg.syntaxCopy() : null;
+		Parameter a = arg ? arg.syntaxCopy() : null;
 		IfStatement s = new IfStatement(loc, a, condition.syntaxCopy(), i, e);
 		return s;
 	}
--- a/dmd/Import.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/Import.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,7 +1,9 @@
 module dmd.Import;
 
+import dmd.common;
 import dmd.Dsymbol;
 import dmd.Array;
+import dmd.ArrayTypes;
 import dmd.DsymbolTable;
 import dmd.PROT;
 import dmd.Identifier;
@@ -40,7 +42,7 @@
 
 class Import : Dsymbol
 {
-	Array packages;		// array of Identifier's representing packages
+	Identifiers packages;		// array of Identifier's representing packages
 	Identifier id;		// module Identifier
 	Identifier aliasId;
 	int isstatic;		// !=0 if static import
@@ -54,7 +56,7 @@
 	Module mod;
 	Package pkg;		// leftmost package/module
 
-	this(Loc loc, Array packages, Identifier id, Identifier aliasId, int isstatic)
+	this(Loc loc, Identifiers packages, Identifier id, Identifier aliasId, int isstatic)
 	{
 		super(id);
 		
@@ -73,7 +75,7 @@
 			this.ident = aliasId;
 		// Kludge to change Import identifier to first package
 		else if (packages && packages.dim)
-			this.ident = cast(Identifier)packages.data[0];
+			this.ident = packages[0];
 	}
 	
 	void addAlias(Identifier name, Identifier alias_)
@@ -246,9 +248,8 @@
 
 		if (packages)
 		{
-			for (size_t i = 0; i < packages.dim; i++)
+			foreach (pid; packages)
 			{
-			Identifier pid = cast(Identifier)packages.data[i];
 			ob.printf("%s.", pid.toChars());
 			}
 		}
--- a/dmd/InExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/InExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.InExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Identifier;
 import dmd.Loc;
--- a/dmd/IndexExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/IndexExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.IndexExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.backend.elem;
 import dmd.InterState;
@@ -12,6 +13,7 @@
 import dmd.ScopeDsymbol;
 import dmd.TY;
 import dmd.ArrayScopeSymbol;
+import dmd.PREC;
 import dmd.TypeNext;
 import dmd.TypeSArray;
 import dmd.TypeAArray;
@@ -23,7 +25,7 @@
 import dmd.WANT;
 import dmd.TupleExp;
 import dmd.TypeTuple;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.TypeExp;
 import dmd.VarExp;
 import dmd.STC;
@@ -34,6 +36,7 @@
 import dmd.expression.util.arrayTypeCompatible;
 import dmd.expression.Util;
 import dmd.expression.Index;
+import dmd.expression.ArrayLength;
 
 import dmd.backend.Symbol;
 import dmd.backend.Util;
@@ -156,7 +159,7 @@
 				else if (e1.op == TOKtype)
 				{
 					tup = cast(TypeTuple)t1;
-					length = Argument.dim(tup.arguments);
+					length = Parameter.dim(tup.arguments);
 				}
 				else
 					assert(0);
@@ -164,9 +167,9 @@
 				if (index < length)
 				{
 					if (e1.op == TOKtuple)
-						e = cast(Expression)te.exps.data[cast(size_t)index];
+						e = te.exps[cast(size_t)index];
 					else
-						e = new TypeExp(e1.loc, Argument.getNth(tup.arguments, cast(size_t)index).type);
+						e = new TypeExp(e1.loc, Parameter.getNth(tup.arguments, cast(size_t)index).type);
 				}
 				else
 				{
@@ -187,7 +190,7 @@
 
 	override int isLvalue()
 	{
-		assert(false);
+		return true;
 	}
 
 	override Expression toLvalue(Scope sc, Expression e)
@@ -212,7 +215,10 @@
 
 	override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
 	{
-		assert(false);
+		expToCBuffer(buf, hgs, e1, PREC.PREC_primary);
+		buf.writeByte('[');
+		expToCBuffer(buf, hgs, e2, PREC.PREC_assign);
+		buf.writeByte(']');
 	}
 
 	override Expression optimize(int result)
@@ -245,7 +251,35 @@
 
 	override Expression interpret(InterState istate)
 	{
-		assert(false);
+		Expression e;
+		Expression e1;
+		Expression e2;
+
+	version (LOG) {
+		printf("IndexExp.interpret() %s\n", toChars());
+	}
+		e1 = this.e1.interpret(istate);
+		if (e1 is EXP_CANT_INTERPRET)
+			goto Lcant;
+
+		if (e1.op == TOKstring || e1.op == TOKarrayliteral)
+		{
+			/* Set the $ variable
+			 */
+			e = ArrayLength(Type.tsize_t, e1);
+			if (e is EXP_CANT_INTERPRET)
+				goto Lcant;
+			if (lengthVar)
+				lengthVar.value = e;
+		}
+
+		e2 = this.e2.interpret(istate);
+		if (e2 is EXP_CANT_INTERPRET)
+			goto Lcant;
+		return Index(type, e1, e2);
+
+	Lcant:
+		return EXP_CANT_INTERPRET;
 	}
 
 	override Expression doInline(InlineDoState ids)
@@ -287,7 +321,14 @@
 
 	override void scanForNestedRef(Scope sc)
 	{
-		assert(false);
+		e1.scanForNestedRef(sc);
+
+		if (lengthVar)
+		{	
+			//printf("lengthVar\n");
+			lengthVar.parent = sc.parent;
+		}
+		e2.scanForNestedRef(sc);
 	}
 
 	override elem* toElem(IRState* irs)
@@ -342,7 +383,7 @@
 			ep = el_params(n2, valuesize, keyti, n1, null);
 			e = el_bin(OPcall, TYnptr, el_var(s), ep);
 
-			if (global.params.useArrayBounds)
+			if (irs.arrayBoundsCheck())
 			{
 				elem* ea;
 
@@ -365,7 +406,7 @@
 			elem* einit = resolveLengthVar(lengthVar, &n1, t1);
 			elem* n2 = e2.toElem(irs);
 
-			if (global.params.useArrayBounds)
+			if (irs.arrayBoundsCheck())
 			{
 				elem* elength;
 				elem* n2x;
--- a/dmd/Initializer.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/Initializer.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.Initializer;
 
+import dmd.common;
 import dmd.Loc;
 import dmd.Scope;
 import dmd.Type;
@@ -37,7 +38,6 @@
     Type inferType(Scope sc)
 	{
     	error(loc, "cannot infer type from initializer");
-    	halt();
     	return Type.terror;
 	}
 	
@@ -64,10 +64,10 @@
 			a = new Initializers();
 			a.setDim(ai.dim);
 			for (int i = 0; i < a.dim; i++)
-			{   Initializer e = cast(Initializer)ai.data[i];
+			{   Initializer e = ai[i];
 
 				e = e.syntaxCopy();
-				a.data[i] = cast(void*) e;
+				a[i] =  e;
 			}
 			}
 			return a;
--- a/dmd/InlineCostState.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/InlineCostState.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.InlineCostState;
 
+import dmd.common;
 import dmd.FuncDeclaration;
 import dmd.Expression;
 
--- a/dmd/InlineDoState.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/InlineDoState.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.InlineDoState;
 
+import dmd.common;
 import dmd.Array;
 import dmd.Dsymbol;
 import dmd.VarDeclaration;
--- a/dmd/InlineScanState.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/InlineScanState.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.InlineScanState;
 
+import dmd.common;
 import dmd.FuncDeclaration;
 import dmd.ExpInitializer;
 import dmd.Dsymbol;
@@ -30,7 +31,7 @@
 		{
 			for (size_t i = 0; i < td.objects.dim; i++)
 			{   
-				DsymbolExp se = cast(DsymbolExp)td.objects.data[i];
+				auto se = cast(DsymbolExp)td.objects[i];
 				assert(se.op == TOKdsymbol);
 				scanVar(se.s, iss);
 			}
--- a/dmd/IntegerExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/IntegerExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.IntegerExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.backend.elem;
 import dmd.TY;
@@ -168,11 +169,7 @@
 					 */
 					if (!global.errors)
 					{
-						printf("ty = %d, %d\n", type.ty, t.ty);
-						if (type.ty == Tenum) {
-							printf("test1\n");
-						}
-						///type.print();
+						writef("%s %p\n", type.toChars(), type);
 						assert(0);
 					}
 					break;
@@ -212,7 +209,8 @@
 
 	override bool isBool(bool result)
 	{
-		return result ? value != 0 : value == 0;
+        int r = toInteger() != 0;
+        return cast(bool)(result ? r : !r);
 	}
 
 	override MATCH implicitConvTo(Type t)
--- a/dmd/InterState.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/InterState.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.InterState;
 
+import dmd.common;
 import dmd.FuncDeclaration;
 import dmd.Dsymbol;
 import dmd.Expression;
--- a/dmd/InterfaceDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/InterfaceDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.InterfaceDeclaration;
 
+import dmd.common;
 import dmd.ClassDeclaration;
 import dmd.Loc;
 import dmd.DsymbolTable;
@@ -7,7 +8,7 @@
 import dmd.Type;
 import dmd.TY;
 import dmd.LINK;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.Util;
 import dmd.TypeTuple;
 import dmd.PROT;
@@ -49,7 +50,15 @@
 	
     override Dsymbol syntaxCopy(Dsymbol s)
 	{
-		assert(false);
+		InterfaceDeclaration id;
+
+		if (s)
+			id = cast(InterfaceDeclaration)s;
+		else
+			id = new InterfaceDeclaration(loc, ident, null);
+
+		ClassDeclaration.syntaxCopy(id);
+		return id;
 	}
 	
     override void semantic(Scope sc)
@@ -95,7 +104,7 @@
 		// Expand any tuples in baseclasses[]
 		for (size_t i = 0; i < baseclasses.dim; )
 		{	
-			BaseClass b = cast(BaseClass)baseclasses.data[0];
+			auto b = baseclasses[0];
 			b.type = b.type.semantic(loc, sc);
 			Type tb = b.type.toBasetype();
 
@@ -103,11 +112,11 @@
 			{   TypeTuple tup = cast(TypeTuple)tb;
 				PROT protection = b.protection;
 				baseclasses.remove(i);
-				size_t dim = Argument.dim(tup.arguments);
+				size_t dim = Parameter.dim(tup.arguments);
 				for (size_t j = 0; j < dim; j++)
-				{	Argument arg = Argument.getNth(tup.arguments, j);
+				{	auto arg = Parameter.getNth(tup.arguments, j);
 				b = new BaseClass(arg.type, protection);
-				baseclasses.insert(i + j, cast(void*)b);
+				baseclasses.insert(i + j, b);
 				}
 			}
 			else
@@ -124,7 +133,7 @@
 			BaseClass b;
 			Type tb;
 
-			b = cast(BaseClass)baseclasses.data[i];
+			b = baseclasses[i];
 			b.type = b.type.semantic(loc, sc);
 			tb = b.type.toBasetype();
 			if (tb.ty == TY.Tclass)
@@ -142,7 +151,7 @@
 				// Check for duplicate interfaces
 				for (size_t j = 0; j < i; j++)
 				{
-					BaseClass b2 = cast(BaseClass)baseclasses.data[j];
+					auto b2 = baseclasses[j];
 					if (b2.base is tc.sym)
 						error("inherits from duplicate interface %s", b2.base.toChars());
 				}
@@ -179,7 +188,7 @@
 		}
 
 		interfaces_dim = baseclasses.dim;
-		interfaces = cast(BaseClass*)baseclasses.data;
+		interfaces = baseclasses.ptr;
 
 		interfaceSemantic(sc);
 
@@ -194,7 +203,7 @@
 			// Skip if b has already appeared
 			for (int k = 0; k < i; k++)
 			{
-				if (b == interfaces[i])
+				if (b == interfaces[k])
 				goto Lcontinue;
 			}
 
@@ -398,7 +407,7 @@
 	#if DMDV2
 			const(MemberInfo[]) function(string) xgetMembers;	// module getMembers() function
 	#endif
-			TypeInfo typeinfo;
+			//TypeInfo typeinfo;
 		   }
 		 */
 		dt_t *dt = null;
@@ -463,7 +472,7 @@
 		dtdword(&dt, 0);
 	}
 
-		dtxoff(&dt, type.vtinfo.toSymbol(), 0, TYnptr);	// typeinfo
+		//dtxoff(&dt, type.vtinfo.toSymbol(), 0, TYnptr);	// typeinfo
 
 		//////////////////////////////////////////////
 
@@ -471,9 +480,8 @@
 		// of the fixup (*)
 
 		offset += vtblInterfaces.dim * (4 * PTRSIZE);
-		for (size_t i = 0; i < vtblInterfaces.dim; i++)
+		foreach (b; vtblInterfaces)
 		{	
-			BaseClass b = cast(BaseClass)vtblInterfaces.data[i];
 			ClassDeclaration id = b.base;
 
 			// ClassInfo
--- a/dmd/InvariantDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/InvariantDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.InvariantDeclaration;
 
+import dmd.common;
 import dmd.FuncDeclaration;
 import dmd.Loc;
 import dmd.Dsymbol;
--- a/dmd/IsExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/IsExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.IsExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Identifier;
 import dmd.ArrayTypes;
@@ -27,7 +28,7 @@
 import dmd.TypeFunction;
 import dmd.MATCH;
 import dmd.TypePointer;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.Token;
 
 class IsExp : Expression
@@ -64,8 +65,8 @@
 			p.setDim(parameters.dim);
 			for (int i = 0; i < p.dim; i++)
 			{   
-				TemplateParameter tp = cast(TemplateParameter)parameters.data[i];
-				p.data[i] = cast(void*)tp.syntaxCopy();
+				auto tp = parameters[i];
+				p[i] = tp.syntaxCopy();
 			}
 		}
 
@@ -83,6 +84,7 @@
 		Type tded;
 
 		/* is(targ id tok tspec)
+		 * is(targ id :  tok2)
 		 * is(targ id == tok2)
 		 */
 
@@ -144,13 +146,19 @@
 
 				case TOKinvariant:
 				case TOKimmutable:
-					if (!targ.isInvariant())
+					if (!targ.isImmutable())
 						goto Lno;
 					tded = targ;
 					break;
 
 				case TOKshared:
 					if (!targ.isShared())
+            		    goto Lno;
+            		tded = targ;
+		            break;
+
+        	    case TOKwild:
+		            if (!targ.isWild())
 						goto Lno;
 					tded = targ;
 					break;
@@ -162,12 +170,11 @@
 						goto Lno;
 					else
 					{   ClassDeclaration cd = (cast(TypeClass)targ).sym;
-						Arguments args = new Arguments;
+						auto args = new Parameters;
 						args.reserve(cd.baseclasses.dim);
-						for (size_t i = 0; i < cd.baseclasses.dim; i++)
+						foreach (b; cd.baseclasses)
 						{	
-							BaseClass b = cast(BaseClass)cd.baseclasses.data[i];
-							args.push(cast(void*)new Argument(STCin, b.type, null, null));
+							args.push(new Parameter(STCin, b.type, null, null));
 						}
 						tded = new TypeTuple(args);
 					}
@@ -194,15 +201,15 @@
 					/* Generate tuple from function parameter types.
 					 */
 					assert(tded.ty == Tfunction);
-					Arguments params = (cast(TypeFunction)tded).parameters;
-					size_t dim = Argument.dim(params);
-					Arguments args = new Arguments;
+					auto params = (cast(TypeFunction)tded).parameters;
+					size_t dim = Parameter.dim(params);
+					auto args = new Parameters;
 					args.reserve(dim);
 					for (size_t i = 0; i < dim; i++)
 					{   
-						Argument arg = Argument.getNth(params, i);
+						auto arg = Parameter.getNth(params, i);
 						assert(arg && arg.type);
-						args.push(cast(void*)new Argument(arg.storageClass, arg.type, null, null));
+						args.push(new Parameter(arg.storageClass, arg.type, null, null));
 					}
 					tded = new TypeTuple(args);
 					break;
@@ -238,14 +245,13 @@
 			 * If true, declare id as an alias for the specialized type.
 			 */
 
-			MATCH m;
 			assert(parameters && parameters.dim);
 
-			scope Objects dedtypes = new Objects();
+			scope dedtypes = new Objects();
 			dedtypes.setDim(parameters.dim);
 			dedtypes.zero();
 
-			m = targ.deduceType(null, tspec, parameters, dedtypes);
+			MATCH m = targ.deduceType(null, tspec, parameters, dedtypes);
 			if (m == MATCHnomatch ||
 				(m != MATCHexact && tok == TOKequal))
 			{
@@ -253,19 +259,19 @@
 			}
 			else
 			{
-				tded = cast(Type)dedtypes.data[0];
+				tded = cast(Type)dedtypes[0];
 				if (!tded)
 				tded = targ;
 
 				scope Objects tiargs = new Objects();
 				tiargs.setDim(1);
-				tiargs.data[0] = cast(void*)targ;
+				tiargs[0] = targ;
 
 				/* Declare trailing parameters
 				 */
 				for (int i = 1; i < parameters.dim; i++)
 				{	
-					TemplateParameter tp = cast(TemplateParameter)parameters.data[i];
+					auto tp = parameters[i];
 					Declaration s = null;
 
 					m = tp.matchArg(sc, tiargs, i, parameters, dedtypes, &s);
@@ -358,7 +364,7 @@
 			for (int i = 1; i < parameters.dim; i++)
 			{
 				buf.writeByte(',');
-				TemplateParameter tp = cast(TemplateParameter)parameters.data[i];
+				auto tp = parameters[i];
 				tp.toCBuffer(buf, hgs);
 			}
 		}
--- a/dmd/Json.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/Json.d	Tue Sep 14 15:46:50 2010 +0200
@@ -3,6 +3,7 @@
  */
 module dmd.Json;
 
+import dmd.common;
 import dmd.String;
 import std.stdio : write, writef;
 
@@ -23,7 +24,7 @@
 
 void json_generate(Array modules)
 {
-	OutBuffer buf;
+	OutBuffer buf = new OutBuffer();
 
 	buf.writestring("[\n");
 	for (int i = 0; i < modules.dim; i++)
--- a/dmd/Keyword.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/Keyword.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.Keyword;
 
+import dmd.common;
 import dmd.TOK;
 
 struct Keyword
--- a/dmd/LabelDsymbol.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/LabelDsymbol.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.LabelDsymbol;
 
+import dmd.common;
 import dmd.Dsymbol;
 import dmd.LabelStatement;
 import dmd.Identifier;
--- a/dmd/LabelStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/LabelStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.LabelStatement;
 
+import dmd.common;
 import dmd.Statement;
 import dmd.Identifier;
 import dmd.TryFinallyStatement;
@@ -76,12 +77,12 @@
 			if (a)
 			{
 				if (!a.dim)
-					a.push(cast(void*)new ExpStatement(loc, null));
+					a.push(new ExpStatement(loc, null));
 
-				Statement s = cast(Statement)a.data[0];
+				Statement s = a[0];
 
 				s = new LabelStatement(loc, ident, s);
-				a.data[0] = cast(void*)s;
+				a[0] = s;
 			}
 		}
 
--- a/dmd/Lexer.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/Lexer.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.Lexer;
 
+import dmd.common;
 import dmd.StringTable;
 import dmd.OutBuffer;
 import dmd.Token;
@@ -496,7 +497,9 @@
 		Token.tochars[TOK.TOKorass]		= "|=";
 		Token.tochars[TOK.TOKidentifier]	= "identifier";
 		Token.tochars[TOK.TOKat]		= "@";
-
+        Token.tochars[TOK.TOKpow]		= "^^";
+        Token.tochars[TOK.TOKpowass]		= "^^=";
+        
 		 // For debugging
 		Token.tochars[TOKerror]		= "error";
 		Token.tochars[TOK.TOKdotexp]		= "dotexp";
@@ -747,16 +750,29 @@
 				case 'Z':
 				case '_':
 				case_ident:
-				{   ubyte c;
-				StringValue *sv;
-				Identifier id;
+				{
+                ubyte c;
 
-				do
-				{
-					c = *++p;
-				} while (isidchar(c) || (c & 0x80 && isUniAlpha(decodeUTF())));
-				sv = stringtable.update((cast(immutable(char)*)t.ptr)[0.. p - t.ptr]);	///
-				id = cast(Identifier) sv.ptrvalue;
+		        while (1)
+		        {
+		            c = *++p;
+		            if (isidchar(c))
+			            continue;
+		            else if (c & 0x80)
+		            {
+                        ubyte *s = p;
+			            uint u = decodeUTF();
+			            if (isUniAlpha(u))
+    			            continue;
+			            error("char 0x%04x not allowed in identifier", u);
+			            p = s;
+		            }
+		            break;
+		        }
+
+		        StringValue *sv = stringtable.update((cast(immutable(char)*)t.ptr)[0.. p - t.ptr]);
+		        Identifier id = cast(Identifier) sv.ptrvalue;
+                    
 				if (id is null)
 				{   id = new Identifier(sv.lstring.string_, TOK.TOKidentifier);
 					sv.ptrvalue = cast(void*)id;
@@ -1257,6 +1273,28 @@
 				else
 					t.value = TOK.TOKtilde;		// ~
 				return;
+                
+version(DMDV2) {
+	    case '^':
+		p++;
+		if (*p == '^')
+		{   p++;
+		    if (*p == '=')
+		    {   p++;
+			t.value = TOKpowass;  // ^^=
+		    }
+		    else
+			t.value = TOKpow;     // ^^
+		}
+		else if (*p == '=')
+		{   p++;
+		    t.value = TOKxorass;    // ^=
+		}
+		else
+		    t.value = TOKxor;       // ^
+		return;
+}
+
 /*
 		#define SINGLE(c,tok) case c: p++; t.value = tok; return;
 
@@ -1288,8 +1326,9 @@
 
 				DOUBLE('*', TOKmul, '=', TOKmulass)
 				DOUBLE('%', TOKmod, '=', TOKmodass)
+#if DMDV1
 				DOUBLE('^', TOKxor, '=', TOKxorass)
-
+#endif
 		#undef DOUBLE
 */
 
@@ -1325,7 +1364,7 @@
 						t.value = TOK.TOKmod;
 					}
 					return;
-					
+version(DMDV1) {
 				case '^':
 					p++;
 					if (*p == '=') {
@@ -1335,30 +1374,30 @@
 						t.value = TOK.TOKxor;
 					}
 					return;
-
+}
 				case '#':
 				p++;
 				pragma_();
 				continue;
 
 				default:
-				{	ubyte c = *p;
+				{	uint c = *p;
 
 				if (c & 0x80)
-				{   uint u = decodeUTF();
+				{   c = decodeUTF();
 
 					// Check for start of unicode identifier
-					if (isUniAlpha(u))
+					if (isUniAlpha(c))
 					goto case_ident;
 
-					if (u == PS || u == LS)
+					if (c == PS || c == LS)
 					{
 					loc.linnum++;
 					p++;
 					continue;
 					}
 				}
-				if (isprint(c))
+				if (c < 0x80 && isprint(c))
 					error("unsupported char '%c'", c);
 				else
 					error("unsupported char 0x%02x", c);
@@ -1691,7 +1730,7 @@
 					if (u == PS || u == LS)
 					loc.linnum++;
 					else
-					error("non-hex character \\u%x", u);
+					error("non-hex character \\u%04x", u);
 				}
 				else
 					error("non-hex character '%c'", c);
@@ -2627,7 +2666,7 @@
 
 		stringbuffer.writeByte(0);
 
-	version (_WIN32) { /// && __DMC__
+	version (Windows) { /// && __DMC__
 		char* save = __locale_decpoint;
 		__locale_decpoint = cast(char*)".".ptr;
 	}
@@ -2675,7 +2714,7 @@
 			}
 		}
 		
-	version (_WIN32) { ///&& __DMC__
+	version (Windows) { ///&& __DMC__
 		__locale_decpoint = save;
 	}
 		if (errno == ERANGE)
--- a/dmd/Library.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/Library.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.Library;
 
+import dmd.common;
 import dmd.File;
 import dmd.Array;
 import dmd.StringTable;
--- a/dmd/LineInitExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/LineInitExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.LineInitExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Loc;
 import dmd.Scope;
@@ -21,7 +22,7 @@
 		return this;
 	}
 
-	override Expression resolve(Loc loc, Scope sc)
+	override Expression resolveLoc(Loc loc, Scope sc)
 	{
 		Expression e = new IntegerExp(loc, loc.linnum, Type.tint32);
 		e = e.castTo(sc, type);
--- a/dmd/LinkDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/LinkDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.LinkDeclaration;
 
+import dmd.common;
 import dmd.AttribDeclaration;
 import dmd.LINK;
 import dmd.OutBuffer;
--- a/dmd/Loc.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/Loc.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.Loc;
 
+import dmd.common;
 import dmd.Module;
 import dmd.OutBuffer;
 
--- a/dmd/Lstring.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/Lstring.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.Lstring;
 
+import dmd.common;
 import dmd.Dchar;
 
 struct Lstring
--- a/dmd/MOD.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/MOD.d	Tue Sep 14 15:46:50 2010 +0200
@@ -5,8 +5,9 @@
 	MODundefined = 0,
 	MODconst = 1,	// type is const
 	MODshared = 2,	// type is shared
-	MODinvariant = 4,	// type is immutable
 	MODimmutable = 4,	// type is immutable
+	MODwild	= 8,	// type is wild
+	MODmutable = 0x10,	// type is mutable (only used in wildcard matching)
 }
 
 import dmd.EnumUtils;
--- a/dmd/Macro.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/Macro.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,113 +1,5 @@
 module dmd.Macro;
 
-struct Macro	/// ???
-{
-}
-
-/**
-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
-	__FreeBSD__	FreeBSD
-	__sun&&__SVR4	Solaris, OpenSolaris (yes, both macros are necessary)
-
-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
-	TARGET_FREEBSD	Covers 32 and 64 bit FreeBSD
-	TARGET_SOLARIS	Covers 32 and 64 bit Solaris
-	TARGET_NET	Covers .Net
-
-    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, FreeBSD and Solaris
-	MACHOBJ		Mach-O Object Module Format, used on Mac OSX
-
-    There are currently no macros for byte endianness order.
- */
-//version definitions from mars.h
-
-version(IN_GCC) // Changes for the GDC compiler by David Friedman
+struct Macro
 {
-	static assert(false, "GDC not supported");
-}
-
-// default to DMDV2
-version(DMDV1) {} else
-version = DMDV2; // Version 2.0 features
-version = BREAKABI;	// 0 if not ready to break the ABI just yet
-version(DMDV2)
-{
-	version = STRUCTTHISREF;	// if 'this' for struct is a reference, not a pointer
-	version = SNAN_DEFAULT_INIT;// if floats are default initialized to signalling NaN
-	version = SARRAYVALUE;		// static arrays are value types
-}
-
-// Set if C++ mangling is done by the front end
-version(DMDV2)
-{
-	version(POSIX) // TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS
-		version = CPP_MANGLE;
-}
-
-/* Other targets are TARGET_LINUX, TARGET_OSX, TARGET_FREEBSD and
- * TARGET_SOLARIS, which are
- * set on the command line via the compiler makefile.
- */
-
-version(_WIN32)
-{
-	version = TARGET_WINDOS;		// Windows dmd generates Windows targets
-	version = OMFOBJ;
-}
-
-version(TARGET_LINUX)
-	version = ELFOBJ;
-version(TARGET_FREEBSD)
-	version = ELFOBJ;
-version(TARGET_SOLARIS)
-	version = ELFOBJ;
-
-
-version(TARGET_OSX)
-	version = MACHOBJ;
-
-/* TODO:
-//Modify OutBuffer::writewchar to write the correct size of wchar
-#if _WIN32
-#define writewchar writeword
-#else
-//This needs a configuration test...
-#define writewchar write4
-#endif
-
-#define INTERFACE_OFFSET	0	// if 1, put classinfo as first entry
-//in interface vtbl[]'s
-#define INTERFACE_VIRTUAL	0	// 1 means if an interface appears
-//in the inheritance graph multiple
-//times, only one is used
-*/
\ No newline at end of file
+}
\ No newline at end of file
--- a/dmd/MinAssignExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/MinAssignExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,7 @@
 module dmd.MinAssignExp;
 
+import dmd.common;
+import dmd.expression.Min;
 import dmd.BinExp;
 import dmd.Loc;
 import dmd.Expression;
@@ -12,6 +14,7 @@
 import dmd.TY;
 import dmd.TOK;
 import dmd.Id;
+import dmd.ArrayLengthExp;
 
 import dmd.backend.elem;
 import dmd.backend.Util;
@@ -38,6 +41,13 @@
 		if (e)
 			return e;
 
+        if (e1.op == TOKarraylength)
+        {
+	        e = ArrayLengthExp.rewriteOpAssign(this);
+	        e = e.semantic(sc);
+	        return e;
+        }
+
 		if (e1.op == TOKslice)
 		{	// T[] -= ...
 			typeCombine(sc);
@@ -69,7 +79,7 @@
 	
     override Expression interpret(InterState istate)
 	{
-		assert(false);
+    	return interpretAssignCommon(istate, &Min);
 	}
 	
     override void buildArrayIdent(OutBuffer buf, Expressions arguments)
@@ -77,9 +87,9 @@
 		AssignExp_buildArrayIdent(buf, arguments, "Min");
 	}
 	
-    override Expression buildArrayLoop(Arguments fparams)
+    override Expression buildArrayLoop(Parameters fparams)
 	{
-		assert(false);
+		return AssignExp_buildArrayLoop!(typeof(this))(fparams);
 	}
 
     override Identifier opId()    /* For operator overloading */
--- a/dmd/MinExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/MinExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.MinExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.TY;
 import dmd.ErrorExp;
@@ -139,7 +140,7 @@
 
 	override Expression interpret(InterState istate)
 	{
-		assert(false);
+		return interpretCommon(istate, &Min);
 	}
 
 	override void buildArrayIdent(OutBuffer buf, Expressions arguments)
@@ -147,14 +148,9 @@
 		Exp_buildArrayIdent(buf, arguments, "Min");
 	}
 
-	override Expression buildArrayLoop(Arguments fparams)
+	override Expression buildArrayLoop(Parameters fparams)
 	{
-		/* Evaluate assign expressions left to right		
-		 */								
-		Expression ex1 = e1.buildArrayLoop(fparams);		
-		Expression ex2 = e2.buildArrayLoop(fparams);		
-		Expression e = new MinExp(Loc(0), ex1, ex2);			
-		return e;							
+		return Exp_buildArrayLoop!(typeof(this))(fparams);
 	}
 
 	override Identifier opId()
--- a/dmd/ModAssignExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/ModAssignExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,7 @@
 module dmd.ModAssignExp;
 
+import dmd.common;
+import dmd.expression.Mod;
 import dmd.BinExp;
 import dmd.Loc;
 import dmd.Expression;
@@ -31,17 +33,17 @@
 	
     override Expression interpret(InterState istate)
 	{
-		assert(false);
+    	return interpretAssignCommon(istate, &Mod);
 	}
 	
     override void buildArrayIdent(OutBuffer buf, Expressions arguments)
 	{
-		assert(false);
+		AssignExp_buildArrayIdent(buf, arguments, "Mod");
 	}
 	
-    override Expression buildArrayLoop(Arguments fparams)
+    override Expression buildArrayLoop(Parameters fparams)
 	{
-		assert(false);
+		return AssignExp_buildArrayLoop!(typeof(this))(fparams);
 	}
 
     override Identifier opId()    /* For operator overloading */
--- a/dmd/ModExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/ModExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.ModExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Identifier;
 import dmd.backend.elem;
@@ -40,11 +41,11 @@
 			return e;
 
 		typeCombine(sc);
-		if (e1.op != TOKslice && e2.op != TOKslice)
-		{	
+		if (!e1.isArrayOperand())
 			e1.checkArithmetic();
+		if (!e2.isArrayOperand())
 			e2.checkArithmetic();
-		}
+
 		if (type.isfloating())
 		{	
 			type = e1.type;
@@ -74,7 +75,7 @@
 
 	override Expression interpret(InterState istate)
 	{
-		assert(false);
+		return interpretCommon(istate, &Mod);
 	}
 
 	override void buildArrayIdent(OutBuffer buf, Expressions arguments)
@@ -82,14 +83,9 @@
 		Exp_buildArrayIdent(buf, arguments, "Mod");
 	}
 
-	override Expression buildArrayLoop(Arguments fparams)
+	override Expression buildArrayLoop(Parameters fparams)
 	{
-		/* Evaluate assign expressions left to right		
-		 */								
-		Expression ex1 = e1.buildArrayLoop(fparams);		
-		Expression ex2 = e2.buildArrayLoop(fparams);		
-		Expression e = new ModExp(Loc(0), ex1, ex2);			
-		return e;							
+		return Exp_buildArrayLoop!(typeof(this))(fparams);
 	}
 
 	override Identifier opId()
--- a/dmd/Module.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/Module.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.Module;
 
+import dmd.common;
 import dmd.Package;
 import dmd.DsymbolTable;
 import dmd.backend.TYM;
@@ -222,8 +223,8 @@
     ModuleInfoDeclaration vmoduleinfo;
 
     uint debuglevel;	// debug level
-    Array debugids;		// debug identifiers
-    Array debugidsNot;		// forward referenced debug identifiers
+    Vector!string debugids;		// debug identifiers
+    Vector!string debugidsNot;		// forward referenced debug identifiers
 
     uint versionlevel;	// version level
     Array versionids;		// version identifiers
@@ -296,7 +297,7 @@
 		symfile = new File(symfilename);
 	}
 
-    static Module load(Loc loc, Array packages, Identifier ident)
+    static Module load(Loc loc, Vector!Identifier packages, Identifier ident)
 	{
 		Module m;
 		string filename;
@@ -313,14 +314,15 @@
 			scope OutBuffer buf = new OutBuffer();
 			int i;
 
-			for (i = 0; i < packages.dim; i++)
+			foreach (pid; packages)
 			{   
-				Identifier pid = cast(Identifier)packages.data[i];
-
 				buf.writestring(pid.toChars());
-version (_WIN32) {
+version (Windows)
+{
 				buf.writeByte('\\');
-} else {
+}
+else
+{
 				buf.writeByte('/');
 }
 			}
@@ -375,9 +377,8 @@
 			writef("import    ");
 			if (packages)
 			{
-				for (size_t i = 0; i < packages.dim; i++)
+				foreach (pid; packages)
 				{   
-					Identifier pid = cast(Identifier)packages.data[i];
 					writef("%s.", pid.toChars());
 				}
 			}
@@ -1673,9 +1674,8 @@
 			}
 		}
 
-		for (int i = 0; i < aclasses.dim; i++)
+		foreach (cd; aclasses)
 		{
-			ClassDeclaration cd = cast(ClassDeclaration)aclasses.data[i];
 			dtxoff(&dt, cd.toSymbol(), 0, TYM.TYnptr);
 		}
 
--- a/dmd/ModuleDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/ModuleDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,15 +1,16 @@
 module dmd.ModuleDeclaration;
 
+import dmd.common;
 import dmd.Identifier;
-import dmd.Array;
+import dmd.ArrayTypes;
 
 class ModuleDeclaration
 {
     Identifier id;
-    Array packages;		// array of Identifier's representing packages
+    Identifiers packages;		// array of Identifier's representing packages
     bool safe;
 
-    this(Array packages, Identifier id, bool safe)
+    this(Identifiers packages, Identifier id, bool safe)
 	{
 		this.packages = packages;
 		this.id = id;
--- a/dmd/ModuleInfoDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/ModuleInfoDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.ModuleInfoDeclaration;
 
+import dmd.common;
 import dmd.VarDeclaration;
 import dmd.Module;
 import dmd.OutBuffer;
@@ -11,34 +12,32 @@
 
 class ModuleInfoDeclaration : VarDeclaration
 {
-    Module mod;
+	Module mod;
 
-    this(Module mod)
+	this(Module mod)
 	{
-		assert(false);
-		super(Loc(0), null, null, null);
+		super(Loc(0), Module.moduleinfo.type, mod.ident, null);
 	}
 	
-    override Dsymbol syntaxCopy(Dsymbol)
+	override Dsymbol syntaxCopy(Dsymbol)
 	{
-		assert(false);
+		assert(false);		  // should never be produced by syntax
+		return null;
 	}
 	
-    override void semantic(Scope sc)
+	override void semantic(Scope sc)
 	{
-		assert(false);
 	}
 
-    void emitComment(Scope *sc)
+	void emitComment(Scope *sc)
 	{
-		assert(false);
 	}
 
 	override void toJsonBuffer(OutBuffer buf)
 	{
 	}
 
-    override Symbol* toSymbol()
+	override Symbol* toSymbol()
 	{
 		assert(false);
 	}
--- a/dmd/MulAssignExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/MulAssignExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.MulAssignExp;
 
+import dmd.common;
 import dmd.BinExp;
 import dmd.Loc;
 import dmd.Expression;
@@ -13,9 +14,11 @@
 import dmd.TOK;
 import dmd.Type;
 import dmd.TY;
+import dmd.ArrayLengthExp;
 
 import dmd.backend.elem;
 import dmd.backend.OPER;
+import dmd.expression.Mul;
 import dmd.expression.Util;
 
 class MulAssignExp : BinExp
@@ -36,6 +39,15 @@
 		if (e)
 			return e;
 
+version(DMDV2) {
+        if (e1.op == TOK.TOKarraylength)
+        {
+	        e = ArrayLengthExp.rewriteOpAssign(this);
+	        e = e.semantic(sc);
+	        return e;
+        }
+}
+        
 		if (e1.op == TOKslice)
 		{	// T[] -= ...
 			typeCombine(sc);
@@ -86,7 +98,7 @@
 	
     override Expression interpret(InterState istate)
 	{
-		assert(false);
+    	return interpretAssignCommon(istate, &Mul);
 	}
 	
     override void buildArrayIdent(OutBuffer buf, Expressions arguments)
@@ -94,9 +106,9 @@
 		AssignExp_buildArrayIdent(buf, arguments, "Mul");
 	}
 	
-    override Expression buildArrayLoop(Arguments fparams)
+    override Expression buildArrayLoop(Parameters fparams)
 	{
-		assert(false);
+		return AssignExp_buildArrayLoop!(typeof(this))(fparams);
 	}
 
     override Identifier opId()    /* For operator overloading */
--- a/dmd/MulExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/MulExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.MulExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Identifier;
 import dmd.backend.elem;
@@ -46,11 +47,11 @@
 			return e;
 
 		typeCombine(sc);
-		if (e1.op != TOKslice && e2.op != TOKslice)
-		{	
+		if (!e1.isArrayOperand())
 			e1.checkArithmetic();
+		if (!e2.isArrayOperand())
 			e2.checkArithmetic();
-		}
+
 		if (type.isfloating())
 		{	
 			Type t1 = e1.type;
@@ -112,7 +113,7 @@
 
 	override Expression interpret(InterState istate)
 	{
-		assert(false);
+		return interpretCommon(istate, &Mul);
 	}
 
 	override void buildArrayIdent(OutBuffer buf, Expressions arguments)
@@ -120,14 +121,9 @@
 		Exp_buildArrayIdent(buf, arguments, "Mul");
 	}
 
-	override Expression buildArrayLoop(Arguments fparams)
+	override Expression buildArrayLoop(Parameters fparams)
 	{
-		/* Evaluate assign expressions left to right		
-		 */								
-		Expression ex1 = e1.buildArrayLoop(fparams);		
-		Expression ex2 = e2.buildArrayLoop(fparams);		
-		Expression e = new MulExp(Loc(0), ex1, ex2);			
-		return e;							
+		return Exp_buildArrayLoop!(typeof(this))(fparams);
 	}
 
 	override bool isCommutative()
--- a/dmd/NegExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/NegExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.NegExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Identifier;
 import dmd.backend.elem;
@@ -41,7 +42,7 @@
 				return e;
 
 			e1.checkNoBool();
-			if (e1.op != TOKslice)
+			if (!e1.isArrayOperand())
 				e1.checkArithmetic();
 
 			type = e1.type;
@@ -71,12 +72,15 @@
 
 	override void buildArrayIdent(OutBuffer buf, Expressions arguments)
 	{
-		assert(false);
+		e1.buildArrayIdent(buf, arguments);
+		buf.writestring("Neg");
 	}
 
-	override Expression buildArrayLoop(Arguments fparams)
+	override Expression buildArrayLoop(Parameters fparams)
 	{
-		assert(false);
+		Expression ex1 = e1.buildArrayLoop(fparams);
+		Expression e = new NegExp(Loc(0), ex1);
+		return e;
 	}
 
 	override Identifier opId()
--- a/dmd/NewAnonClassExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/NewAnonClassExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,13 +1,19 @@
 module dmd.NewAnonClassExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.OutBuffer;
 import dmd.Loc;
 import dmd.Scope;
 import dmd.ClassDeclaration;
+import dmd.DeclarationExp;
+import dmd.NewExp;
+import dmd.CommaExp;
+import dmd.PREC;
 import dmd.HdrGenState;
 import dmd.ArrayTypes;
 import dmd.TOK;
+import dmd.expression.Util;
 
 class NewAnonClassExp : Expression
 {
@@ -20,33 +26,75 @@
 
 	this(Loc loc, Expression thisexp, Expressions newargs, ClassDeclaration cd, Expressions arguments)
 	{
-		assert(false);
-		super(loc, TOK.init, 0);
+		super(loc, TOKnewanonclass, NewAnonClassExp.sizeof);
+		this.thisexp = thisexp;
+		this.newargs = newargs;
+		this.cd = cd;
+		this.arguments = arguments;
 	}
 
 	override Expression syntaxCopy()
 	{
-		assert(false);
+		return new NewAnonClassExp(loc, 
+			thisexp ? thisexp.syntaxCopy() : null,
+			arraySyntaxCopy(newargs),
+			cast(ClassDeclaration)cd.syntaxCopy(null),
+			arraySyntaxCopy(arguments));
 	}
-
+	
 	override Expression semantic(Scope sc)
 	{
-		assert(false);
+version (LOGSEMANTIC) {
+		printf("NewAnonClassExp.semantic() %s\n", toChars());
+		//printf("thisexp = %p\n", thisexp);
+		//printf("type: %s\n", type.toChars());
+}
+
+		Expression d = new DeclarationExp(loc, cd);
+		d = d.semantic(sc);
+
+		Expression n = new NewExp(loc, thisexp, newargs, cd.type, arguments);
+
+		Expression c = new CommaExp(loc, d, n);
+		return c.semantic(sc);
 	}
 
 	override bool checkSideEffect(int flag)
 	{
-		assert(false);
+		return true;
 	}
 
-	void toCBuffer(OutBuffer buf, HdrGenState hgs)
+	void toCBuffer(OutBuffer buf, HdrGenState* hgs)
 	{
-		assert(false);
+		if (thisexp)
+		{	
+			expToCBuffer(buf, hgs, thisexp, PREC.PREC_primary);
+			buf.writeByte('.');
+		}
+		buf.writestring("new");
+		if (newargs && newargs.dim)
+		{
+			buf.writeByte('(');
+			argsToCBuffer(buf, newargs, hgs);
+			buf.writeByte(')');
+		}
+		buf.writestring(" class ");
+		if (arguments && arguments.dim)
+		{
+			buf.writeByte('(');
+			argsToCBuffer(buf, arguments, hgs);
+			buf.writeByte(')');
+		}
+		//buf.writestring(" { }");
+		if (cd)
+		{
+			cd.toCBuffer(buf, hgs);
+		}
 	}
 
 	override bool canThrow()
 	{
-		assert(false);
+		return true;
 	}
 }
 
--- a/dmd/NewDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/NewDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,58 +1,108 @@
 module dmd.NewDeclaration;
 
+import dmd.common;
 import dmd.FuncDeclaration;
 import dmd.Loc;
 import dmd.ArrayTypes;
 import dmd.Dsymbol;
+import dmd.Parameter;
+import dmd.ClassDeclaration;
+import dmd.Type;
+import dmd.TypeFunction;
+import dmd.LINK;
+import dmd.TY;
 import dmd.Scope;
 import dmd.OutBuffer;
 import dmd.HdrGenState;
 import dmd.STC;
+import dmd.Id;
 
 class NewDeclaration : FuncDeclaration
 {
-	Arguments arguments;
+	Parameters arguments;
     int varargs;
 
-    this(Loc loc, Loc endloc, Arguments arguments, int varargs)
+    this(Loc loc, Loc endloc, Parameters arguments, int varargs)
 	{
-		assert(false);
-		super(loc, loc, null, STC.init, null);
+		super(loc, endloc, Id.classNew, STCstatic, null);
+		this.arguments = arguments;
+		this.varargs = varargs;
 	}
 
     override Dsymbol syntaxCopy(Dsymbol)
 	{
-		assert(false);
+		NewDeclaration f;
+
+		f = new NewDeclaration(loc, endloc, null, varargs);
+
+		FuncDeclaration.syntaxCopy(f);
+
+		f.arguments = Parameter.arraySyntaxCopy(arguments);
+
+		return f;
 	}
 
     override void semantic(Scope sc)
 	{
-		assert(false);
+		ClassDeclaration cd;
+		Type tret;
+
+		//printf("NewDeclaration.semantic()\n");
+
+		parent = sc.parent;
+		Dsymbol parent = toParent();
+		cd = parent.isClassDeclaration();
+		if (!cd && !parent.isStructDeclaration())
+		{
+			error("new allocators only are for class or struct definitions");
+		}
+		tret = Type.tvoid.pointerTo();
+		type = new TypeFunction(arguments, tret, varargs, LINKd);
+
+		type = type.semantic(loc, sc);
+		assert(type.ty == Tfunction);
+
+		// Check that there is at least one argument of type size_t
+		TypeFunction tf = cast(TypeFunction)type;
+		if (Parameter.dim(tf.parameters) < 1)
+		{
+			error("at least one argument of type size_t expected");
+		}
+		else
+		{
+			auto a = Parameter.getNth(tf.parameters, 0);
+			if (!a.type.equals(Type.tsize_t))
+				error("first argument must be type size_t, not %s", a.type.toChars());
+		}
+
+		FuncDeclaration.semantic(sc);
 	}
 
     override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
 	{
-		assert(false);
+		buf.writestring("new");
+		Parameter.argsToCBuffer(buf, hgs, arguments, varargs);
+		bodyToCBuffer(buf, hgs);
 	}
 
     override string kind()
 	{
-		assert(false);
+		return "allocator";
 	}
 
     override bool isVirtual()
 	{
-		assert(false);
+		return false;
 	}
 
     override bool addPreInvariant()
 	{
-		assert(false);
+		return false;
 	}
 
     override bool addPostInvariant()
 	{
-		assert(false);
+		return false;
 	}
 
     override NewDeclaration isNewDeclaration() { return this; }
--- a/dmd/NewExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/NewExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.NewExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.NewDeclaration;
 import dmd.CtorDeclaration;
@@ -113,9 +114,9 @@
 		//printf("tb: %s, deco = %s\n", tb.toChars(), tb.deco);
 
 		arrayExpressionSemantic(newargs, sc);
-		preFunctionArguments(loc, sc, newargs);
+		preFunctionParameters(loc, sc, newargs);
 		arrayExpressionSemantic(arguments, sc);
-		preFunctionArguments(loc, sc, arguments);
+		preFunctionParameters(loc, sc, arguments);
 
 		if (thisexp && tb.ty != Tclass)
 			error("e.new is only for allocating nested classes, not %s", tb.toChars());
@@ -247,7 +248,7 @@
 
 				if (!arguments)
 					arguments = new Expressions();
-				functionArguments(loc, sc, tf, arguments);
+				functionParameters(loc, sc, tf, arguments);
 			}
 			else
 			{
@@ -268,7 +269,7 @@
 				assert(allocator);
 
 				tf = cast(TypeFunction)f.type;
-				functionArguments(loc, sc, tf, newargs);
+				functionParameters(loc, sc, tf, newargs);
 			}
 			else
 			{
@@ -298,7 +299,7 @@
 
 				if (!arguments)
 					arguments = new Expressions();
-				functionArguments(loc, sc, tf, arguments);
+				functionParameters(loc, sc, tf, arguments);
 			}
 			else
 			{
@@ -319,7 +320,7 @@
 				assert(allocator);
 
 				tf = cast(TypeFunction)f.type;
-				functionArguments(loc, sc, tf, newargs);
+				functionParameters(loc, sc, tf, newargs);
 		static if (false) {
 				e = new VarExp(loc, f);
 				e = new CallExp(loc, e, newargs);
@@ -719,7 +720,7 @@
 
 	override bool checkSideEffect(int flag)
 	{
-		assert(false);
+		return true;
 	}
 
 	override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
--- a/dmd/NotExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/NotExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.NotExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.backend.elem;
 import dmd.UnaExp;
--- a/dmd/NullExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/NullExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.NullExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.backend.elem;
 import dmd.InterState;
@@ -20,9 +21,10 @@
 {
 	ubyte committed;
 
-	this(Loc loc)
+	this(Loc loc, Type type = null)
 	{
 		super(loc, TOK.TOKnull, NullExp.sizeof);
+        this.type = type;
 	}
 
 	override Expression semantic(Scope sc)
@@ -137,7 +139,7 @@
 
 	override Expression interpret(InterState istate)
 	{
-		assert(false);
+		return this;
 	}
 
 	override elem* toElem(IRState* irs)
--- a/dmd/OnScopeStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/OnScopeStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.OnScopeStatement;
 
+import dmd.common;
 import dmd.Statement;
 import dmd.OutBuffer;
 import dmd.HdrGenState;
--- a/dmd/Optimize.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/Optimize.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.Optimize;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.TOK;
 import dmd.VarExp;
@@ -21,9 +22,9 @@
 
     Expression e = null;
     if (!v)
-	return e;
+    	return e;
 
-    if (v.isConst() || v.isInvariant() || v.storage_class & STC.STCmanifest)
+    if (v.isConst() || v.isImmutable() || v.storage_class & STC.STCmanifest)
     {
 	if (!v.type)
 	{
--- a/dmd/OrAssignExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/OrAssignExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,7 @@
 module dmd.OrAssignExp;
 
+import dmd.common;
+import dmd.expression.Or;
 import dmd.BinExp;
 import dmd.Loc;
 import dmd.Expression;
@@ -29,17 +31,17 @@
 	
     override Expression interpret(InterState istate)
 	{
-		assert(false);
+    	return interpretAssignCommon(istate, &Or);
 	}
 	
     override void buildArrayIdent(OutBuffer buf, Expressions arguments)
 	{
-		assert(false);
+		AssignExp_buildArrayIdent(buf, arguments, "Or");
 	}
 	
-    override Expression buildArrayLoop(Arguments fparams)
+    override Expression buildArrayLoop(Parameters fparams)
 	{
-		assert(false);
+		return AssignExp_buildArrayLoop!(typeof(this))(fparams);
 	}
 
     override Identifier opId()    /* For operator overloading */
--- a/dmd/OrExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/OrExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.OrExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Identifier;
 import dmd.InterState;
@@ -48,11 +49,10 @@
 			else
 			{
 				typeCombine(sc);
-				if (e1.op != TOK.TOKslice && e2.op != TOK.TOKslice)
-				{
+				if (!e1.isArrayOperand())
 					e1.checkIntegral();
+				if (!e2.isArrayOperand())
 					e2.checkIntegral();
-				}
 			}
 		}
 
@@ -76,17 +76,17 @@
 
 	override Expression interpret(InterState istate)
 	{
-		assert(false);
+		return interpretCommon(istate, &Or);
 	}
 
 	override void buildArrayIdent(OutBuffer buf, Expressions arguments)
 	{
-		assert(false);
+		Exp_buildArrayIdent(buf, arguments, "Or");
 	}
 
-	override Expression buildArrayLoop(Arguments fparams)
+	override Expression buildArrayLoop(Parameters fparams)
 	{
-		assert(false);
+		return Exp_buildArrayLoop!(typeof(this))(fparams);
 	}
 
 	override MATCH implicitConvTo(Type t)
--- a/dmd/OrOrExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/OrOrExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.OrOrExp;
 
+import dmd.common;
 import dmd.BinExp;
 import dmd.Scope;
 import dmd.InterState;
--- a/dmd/OutBuffer.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/OutBuffer.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.OutBuffer;
 
+import dmd.common;
 import std.stdarg;
 import std.exception;
 
@@ -94,7 +95,7 @@
 	
     final void writenl()			// write newline
 	{
-version (_WIN32)
+version (Windows)
 {
 	version (M_UNICODE)
 	{
--- a/dmd/OverExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/OverExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.OverExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.OverloadSet;
 import dmd.Scope;
@@ -7,6 +8,8 @@
 import dmd.TOK;
 import dmd.Type;
 
+//! overload set
+version(DMDV2)
 class OverExp : Expression
 {
 	OverloadSet vars;
@@ -21,12 +24,12 @@
 
 	override int isLvalue()
 	{
-		assert(false);
+		return true;
 	}
 
 	override Expression toLvalue(Scope sc, Expression e)
 	{
-		assert(false);
+		return this;
 	}
 }
 
--- a/dmd/OverloadSet.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/OverloadSet.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.OverloadSet;
 
+import dmd.common;
 import dmd.Dsymbol;
 import dmd.ArrayTypes;
 
--- a/dmd/PREC.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/PREC.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.PREC;
 
+import dmd.common;
 import dmd.TOK;
 
 /**********************************
@@ -24,6 +25,7 @@
     PREC_shift,
     PREC_add,
     PREC_mul,
+    PREC_pow,
     PREC_unary,
     PREC_primary,
 }
--- a/dmd/Package.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/Package.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,8 +1,9 @@
 module dmd.Package;
 
+import dmd.common;
 import dmd.ScopeDsymbol;
 import dmd.Identifier;
-import dmd.Array;
+import dmd.ArrayTypes;
 import dmd.DsymbolTable;
 import dmd.Scope;
 import dmd.Dsymbol;
@@ -21,7 +22,7 @@
 		assert(false);
 	}
 
-    static DsymbolTable resolve(Array packages, Dsymbol* pparent, Package* ppkg)
+    static DsymbolTable resolve(Identifiers packages, Dsymbol* pparent, Package* ppkg)
 	{
 		DsymbolTable dst = Module.modules;
 		Dsymbol parent = null;
@@ -32,9 +33,8 @@
 
 		if (packages)
 		{
-			for (int i = 0; i < packages.dim; i++)
+			foreach (pid; packages)
 			{   
-				Identifier pid = cast(Identifier)packages.data[i];
 				Dsymbol p = dst.lookup(pid);
 				if (!p)
 				{
--- a/dmd/Param.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/Param.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.Param;
 
+import dmd.common;
 import dmd.Array;
 import dmd.OutBuffer;
 
@@ -30,7 +31,10 @@
     bool useInvariants;	// generate class invariant checks
     bool useIn;		// generate precondition checks
     bool useOut;	// generate postcondition checks
-    bool useArrayBounds; // generate array bounds checks
+    byte useArrayBounds; // 0: no array bounds checks
+			 // 1: array bounds checks for safe functions only
+			 // 2: array bounds checks for all functions
+    bool noboundscheck;	// no array bounds checking at all
     bool useSwitchError; // check for switches without a default
     bool useUnitTests;	// generate unittest code
     bool useInline;	// inline expand functions
@@ -42,7 +46,6 @@
     bool nofloat;	// code should not pull in floating point support
     byte Dversion;	// D version number
     bool ignoreUnsupportedPragmas;	// rather than error on them
-    bool safe;		// enforce safe memory model
 
     string argv0;	// program name
     Array imppath;	// array of char*'s of where to look for import modules
@@ -64,7 +67,7 @@
 	string xfilename;	// write JSON file to xfilename
 
     uint debuglevel;	// debug level
-    Array debugids;		// debug identifiers
+    Vector!string debugids;		// debug identifiers
 
     uint versionlevel;	// version level
     Array versionids;		// version identifiers
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmd/Parameter.d	Tue Sep 14 15:46:50 2010 +0200
@@ -0,0 +1,304 @@
+module dmd.Parameter;
+
+import dmd.common;
+import dmd.Type;
+import dmd.Identifier;
+import dmd.TypeArray;
+import dmd.TypeFunction;
+import dmd.TypeDelegate;
+import dmd.TypeTuple;
+import dmd.TY;
+import dmd.Expression;
+import dmd.OutBuffer;
+import dmd.HdrGenState;
+import dmd.ArrayTypes;
+import dmd.StorageClassDeclaration;
+import dmd.Global;
+import dmd.MOD;
+import dmd.CppMangleState;
+import dmd.STC;
+
+class Parameter
+{
+    //enum InOut inout;
+    StorageClass storageClass;
+    Type type;
+    Identifier ident;
+    Expression defaultArg;
+
+    this(StorageClass storageClass, Type type, Identifier ident, Expression defaultArg)
+	{
+		this.type = type;
+		this.ident = ident;
+		this.storageClass = storageClass;
+		this.defaultArg = defaultArg;
+	}
+	
+	Parameter clone()
+	{
+		return new Parameter(storageClass, type, ident, defaultArg);
+	}
+	
+    Parameter syntaxCopy()
+	{
+		return new Parameter(storageClass, type ? type.syntaxCopy() : null, ident, defaultArg ? defaultArg.syntaxCopy() : null);
+	}
+	
+	/****************************************************
+	 * Determine if parameter is a lazy array of delegates.
+	 * If so, return the return type of those delegates.
+	 * If not, return null.
+	 */
+    Type isLazyArray()
+	{
+	//    if (inout == Lazy)
+		{
+			Type tb = type.toBasetype();
+			if (tb.ty == Tsarray || tb.ty == Tarray)
+			{
+				Type tel = (cast(TypeArray)tb).next.toBasetype();
+				if (tel.ty == Tdelegate)
+				{
+					TypeDelegate td = cast(TypeDelegate)tel;
+					TypeFunction tf = cast(TypeFunction)td.next;
+
+					if (!tf.varargs && Parameter.dim(tf.parameters) == 0)
+					{
+						return tf.next;	// return type of delegate
+					}
+				}
+			}
+		}
+		return null;
+	}
+	
+    void toDecoBuffer(OutBuffer buf)
+	{
+		if (storageClass & STC.STCscope)
+			buf.writeByte('M');
+		switch (storageClass & (STC.STCin | STC.STCout | STC.STCref | STC.STClazy))
+		{   
+			case STC.STCundefined:
+			case STC.STCin:
+				break;
+			case STC.STCout:
+				buf.writeByte('J');
+				break;
+			case STC.STCref:
+				buf.writeByte('K');
+				break;
+			case STC.STClazy:
+				buf.writeByte('L');
+				break;
+		}
+static if (false) {
+		int mod = 0x100;
+		if (type.toBasetype().ty == TY.Tclass)
+			mod = 0;
+		type.toDecoBuffer(buf, mod);
+} else {
+		//type.toHeadMutable().toDecoBuffer(buf, 0);
+		type.toDecoBuffer(buf, 0);
+}
+	}
+	
+    static Parameters arraySyntaxCopy(Parameters args)
+	{
+		typeof(return) a = null;
+
+		if (args)
+		{
+			a = new Parameters();
+			a.setDim(args.dim);
+
+			for (size_t i = 0; i < a.dim; i++)
+			{   
+				auto arg = args[i];
+
+				arg = arg.syntaxCopy();
+				a[i] = arg;
+			}
+		}
+	
+		return a;
+	}
+	
+    static string argsTypesToChars(Parameters args, int varargs)
+	{
+		scope OutBuffer buf = new OutBuffer();
+
+	static if (true) {
+		HdrGenState hgs;
+		argsToCBuffer(buf, &hgs, args, varargs);
+	} else {
+		buf.writeByte('(');
+		if (args)
+		{	
+			OutBuffer argbuf = new OutBuffer();
+			HdrGenState hgs;
+
+			for (int i = 0; i < args.dim; i++)
+			{   
+				if (i)
+					buf.writeByte(',');
+				auto arg = cast(Parameter)args.data[i];
+				argbuf.reset();
+				arg.type.toCBuffer2(&argbuf, &hgs, 0);
+				buf.write(&argbuf);
+			}
+			if (varargs)
+			{
+				if (i && varargs == 1)
+					buf.writeByte(',');
+				buf.writestring("...");
+			}
+		}
+		buf.writeByte(')');
+	}
+		return buf.toChars();
+	}
+	
+    static void argsCppMangle(OutBuffer buf, CppMangleState* cms, Parameters arguments, int varargs)
+	{
+		assert(false);
+	}
+	
+    static void argsToCBuffer(OutBuffer buf, HdrGenState* hgs, Parameters arguments, int varargs)
+	{
+		buf.writeByte('(');
+		if (arguments)
+		{	
+			int i;
+			scope OutBuffer argbuf = new OutBuffer();
+
+			for (i = 0; i < arguments.dim; i++)
+			{
+				if (i)
+					buf.writestring(", ");
+				auto arg = arguments[i];
+
+	            if (arg.storageClass & STCauto)
+		            buf.writestring("auto ");
+
+				if (arg.storageClass & STCout)
+					buf.writestring("out ");
+				else if (arg.storageClass & STCref)
+					buf.writestring((global.params.Dversion == 1) ? "inout " : "ref ");
+				else if (arg.storageClass & STCin)
+					buf.writestring("in ");
+				else if (arg.storageClass & STClazy)
+					buf.writestring("lazy ");
+				else if (arg.storageClass & STCalias)
+					buf.writestring("alias ");
+
+				StorageClass stc = arg.storageClass;
+				if (arg.type && arg.type.mod & MODshared)
+					stc &= ~STCshared;
+
+				StorageClassDeclaration.stcToCBuffer(buf, stc & (STCconst | STCimmutable | STCshared | STCscope));
+
+				argbuf.reset();
+				if (arg.storageClass & STCalias)
+				{	
+					if (arg.ident)
+						argbuf.writestring(arg.ident.toChars());
+				}
+				else
+					arg.type.toCBuffer(argbuf, arg.ident, hgs);
+				if (arg.defaultArg)
+				{
+					argbuf.writestring(" = ");
+					arg.defaultArg.toCBuffer(argbuf, hgs);
+				}
+				buf.write(argbuf);
+			}
+			if (varargs)
+			{
+				if (i && varargs == 1)
+					buf.writeByte(',');
+				buf.writestring("...");
+			}
+		}
+		buf.writeByte(')');
+	}
+	
+    static void argsToDecoBuffer(OutBuffer buf, Parameters arguments)
+	{
+		//printf("Parameter::argsToDecoBuffer()\n");
+
+		// Write argument types
+		if (arguments)
+		{
+			size_t dim = Parameter.dim(arguments);
+			for (size_t i = 0; i < dim; i++)
+			{
+				auto arg = Parameter.getNth(arguments, i);
+				arg.toDecoBuffer(buf);
+			}
+		}
+	}
+	
+    static int isTPL(Parameters arguments)
+	{
+		assert(false);
+	}
+
+	/***************************************
+	 * Determine number of arguments, folding in tuples.
+	 */	
+    static size_t dim(Parameters args)
+	{
+		size_t n = 0;
+		if (args)
+		{
+			foreach (arg; args)
+			{   
+				Type t = arg.type.toBasetype();
+
+				if (t.ty == TY.Ttuple)
+				{   
+					auto tu = cast(TypeTuple)t;
+					n += dim(tu.arguments);
+				}
+				else
+					n++;
+			}
+		}
+		return n;
+	}
+	
+	/***************************************
+	 * Get nth Parameter, folding in tuples.
+	 * Returns:
+	 *	Parameter	nth Parameter
+	 *	null		not found, *pn gets incremented by the number
+	 *			of Parameters
+	 */
+    static Parameter getNth(Parameters args, size_t nth, size_t* pn = null)
+	{
+		if (!args)
+			return null;
+
+		size_t n = 0;
+		foreach (arg; args)
+		{   
+			Type t = arg.type.toBasetype();
+
+			if (t.ty == TY.Ttuple)
+			{   TypeTuple tu = cast(TypeTuple)t;
+				arg = getNth(tu.arguments, nth - n, &n);
+				if (arg)
+					return arg;
+			}
+			else if (n == nth)
+				return arg;
+			else
+				n++;
+		}
+
+		if (pn)
+			*pn += n;
+
+		return null;
+	}
+}
--- a/dmd/Parser.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/Parser.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.Parser;
 
+import dmd.common;
 import dmd.Lexer;
 import dmd.PostBlitDeclaration;
 import dmd.FileInitExp;
@@ -78,6 +79,7 @@
 import dmd.DivAssignExp;
 import dmd.AndAssignExp;
 import dmd.AddAssignExp;
+import dmd.PowAssignExp;
 import dmd.ModuleDeclaration;
 import dmd.CaseRangeStatement;
 import dmd.CommaExp;
@@ -137,7 +139,7 @@
 import dmd.CompoundStatement;
 import dmd.ConditionalStatement;
 import dmd.CompoundDeclarationStatement;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.ParseStatementFlags;
 import dmd.TypeNewArray;
 import dmd.TypeNext;
@@ -202,6 +204,8 @@
 import dmd.VersionSymbol;
 import dmd.AliasThis;
 import dmd.Global;
+import dmd.TRUST;
+import dmd.PowExp;
 
 import core.stdc.string : memcpy;
 
@@ -234,6 +238,7 @@
 			bool safe = false;
 
 			nextToken();
+static if(false) {
 version (DMDV2) {
 			if (token.value == TOK.TOKlparen)
 			{
@@ -253,6 +258,7 @@
 				check(TOK.TOKrparen);
 			}
 }
+}
 
 			if (token.value != TOK.TOKidentifier)
 			{
@@ -261,13 +267,13 @@
 			}
 			else
 			{
-				Array a = null;
+				Identifiers a = null;
 				Identifier id = token.ident;
 				while (nextToken() == TOK.TOKdot)
 				{
 					if (!a)
-						a = new Array();
-					a.push(cast(void*)id);
+						a = new Identifiers();
+					a.push(id);
 					nextToken();
 					if (token.value != TOK.TOKidentifier)
 					{   error("Identifier expected following package");
@@ -310,8 +316,8 @@
 		Dsymbols a;
 		Dsymbols aelse;
 		PROT prot;
-		STC stc;
-		STC storageClass;
+		StorageClass stc;
+		StorageClass storageClass;
 		Condition  condition;
 		string comment;
 
@@ -491,6 +497,12 @@
 			stc = STC.STCshared;
 			goto Lstc;
 
+	        case TOKwild:
+		    if (peek(&token).value == TOK.TOKlparen)
+		        goto Ldeclaration;
+		    stc = STCwild;
+		    goto Lstc;
+
 			case TOK.TOKfinal:	  stc = STC.STCfinal;	 goto Lstc;
 			case TOK.TOKauto:	  stc = STC.STCauto;	 goto Lstc;
 			case TOK.TOKscope:	  stc = STC.STCscope;	 goto Lstc;
@@ -506,6 +518,7 @@
 			case TOK.TOKgshared:      
 				stc = STC.STCgshared;	 goto Lstc;
 			//case TOK.TOKmanifest:	  stc = STC.STCmanifest;	 goto Lstc;
+	        case TOK.TOKat:           stc = parseAttribute(); goto Lstc;
 }
 
 			Lstc:
@@ -521,6 +534,7 @@
 				case TOK.TOKinvariant:
 				case TOK.TOKimmutable:
 				case TOK.TOKshared:
+		        case TOKwild:
 				// If followed by a (, it is not a storage class
 				if (peek(&token).value == TOK.TOKlparen)
 					break;
@@ -528,6 +542,8 @@
 					stc = STC.STCconst;
 				else if (token.value == TOK.TOKshared)
 					stc = STC.STCshared;
+			    else if (token.value == TOKwild)
+			        stc = STC.STCwild;
 				else
 					stc = STC.STCimmutable;
 				goto Lstc;
@@ -544,6 +560,7 @@
 				case TOK.TOKtls:          stc = STC.STCtls;		 goto Lstc;
 				case TOK.TOKgshared:      stc = STC.STCgshared;	 goto Lstc;
 				//case TOK.TOKmanifest:	  stc = STC.STCmanifest;	 goto Lstc;
+		        case TOK.TOKat:           stc = parseAttribute(); goto Lstc;
 				default:
 				break;
 			}
@@ -750,7 +767,7 @@
 	 */
 version (DMDV2)
 {
-    Dsymbols parseAutoDeclarations(STC storageClass, const(char)[] comment)
+    Dsymbols parseAutoDeclarations(StorageClass storageClass, const(char)[] comment)
 	{
 		auto a = new Dsymbols;
 
@@ -834,10 +851,10 @@
 		}
 		return a;
 	}
-	
-    void composeStorageClass(STC stc)
+version(DMDV2) {
+    void composeStorageClass(StorageClass stc)
 	{
-		STC u = stc;
+		StorageClass u = stc;
 		u &= STC.STCconst | STC.STCimmutable | STC.STCmanifest;
 		if (u & (u - 1))
 			error("conflicting storage class %s", Token.toChars(token.value));
@@ -846,8 +863,39 @@
 		u &= STC.STCgshared | STC.STCshared | STC.STCtls;
 		if (u & (u - 1))
 			error("conflicting storage class %s", Token.toChars(token.value));
+        u = stc;
+        u &= STCsafe | STCsystem | STCtrusted;
+        if (u & (u - 1))
+	        error("conflicting attribute @%s", token.toChars());
 	}
-	
+}
+    
+/***********************************************
+ * Parse storage class, lexer is on '@'
+ */
+
+version(DMDV2) {
+    StorageClass parseAttribute()
+    {
+        nextToken();
+        StorageClass stc = STCundefined;
+        if (token.value != TOKidentifier)
+        {
+	        error("identifier expected after @, not %s", token.toChars());
+        }
+        else if (token.ident == Id.property)
+	        stc = STCproperty;
+        else if (token.ident == Id.safe)
+	        stc = STCsafe;
+        else if (token.ident == Id.trusted)
+	        stc = STCtrusted;
+        else if (token.ident == Id.system)
+	        stc = STCsystem;
+        else
+	        error("valid attribute identifiers are @property, @safe, @trusted, @system, not @%s", token.toChars());
+        return stc;
+    }
+}
 	/**************************************
 	 * Parse constraint.
 	 * Constraint is of the form:
@@ -1068,7 +1116,7 @@
 					}
 					tp = new TemplateValueParameter(loc, tp_ident, tp_valtype, tp_specvalue, tp_defaultvalue);
 				}
-				tpl.push(cast(void*)tp);
+				tpl.push(tp);
 				if (token.value != TOKcomma)
 					break;
 				nextToken();
@@ -1202,7 +1250,7 @@
 				if (isDeclaration(&token, 0, TOKreserved, null))
 				{	// Template argument is a type
 					Type ta = parseType();
-					tiargs.push(cast(void*)ta);
+					tiargs.push(ta);
 				}
 				else
 				{	// Template argument is an expression
@@ -1221,9 +1269,8 @@
 							 * a deduced type.
 							 */
 							TemplateParameters tpl = null;
-							for (int i = 0; i < tf.parameters.dim; i++)
+							foreach (param; tf.parameters)
 							{   
-								Argument param = cast(Argument)tf.parameters.data[i];
 								if (param.ident is null &&
 									param.type &&
 									param.type.ty == Tident &&
@@ -1233,14 +1280,14 @@
 									/* Switch parameter type to parameter identifier,
 									 * parameterize with template type parameter _T
 									 */
-									TypeIdentifier pt = cast(TypeIdentifier)param.type;
+									auto pt = cast(TypeIdentifier)param.type;
 									param.ident = pt.ident;
 									Identifier id = Lexer.uniqueId("__T");
 									param.type = new TypeIdentifier(pt.loc, id);
-									TemplateParameter tp = new TemplateTypeParameter(fd.loc, id, null, null);
+									auto tp = new TemplateTypeParameter(fd.loc, id, null, null);
 									if (!tpl)
 										tpl = new TemplateParameters();
-									tpl.push(cast(void*)tp);
+									tpl.push(tp);
 								}
 							}
 
@@ -1251,13 +1298,13 @@
 								decldefs.push(fd);
 								auto tempdecl = new TemplateDeclaration(fd.loc, fd.ident, tpl, null, decldefs);
 								tempdecl.literal = 1;	// it's a template 'literal'
-								tiargs.push(cast(void*)tempdecl);
+								tiargs.push(tempdecl);
 								goto L1;
 							}
 						}
 					}
 
-					tiargs.push(cast(void*)ea);
+					tiargs.push(ea);
 				}
 			 L1:
 				if (token.value != TOKcomma)
@@ -1310,7 +1357,7 @@
 			case TOKwchar:	 ta = Type.twchar; goto LabelX;
 			case TOKdchar:	 ta = Type.tdchar; goto LabelX;
 			LabelX:
-				tiargs.push(cast(void*)ta);
+				tiargs.push(ta);
 				nextToken();
 				break;
 
@@ -1336,7 +1383,7 @@
 			{   
 				// Template argument is an expression
 				Expression ea = parsePrimaryExp();
-				tiargs.push(cast(void*)ea);
+				tiargs.push(ea);
 				break;
 			}
 
@@ -1428,9 +1475,12 @@
 			}
 			else if (id == Id.System)
 			{
-version (_WIN32) {
+version (Windows)
+{
 				link = LINK.LINKwindows;
-} else {
+}
+else
+{
 				link = LINK.LINKc;
 }
 			}
@@ -1572,7 +1622,7 @@
 			nextToken();
 			nextToken();
 			check(TOK.TOKrparen);
-			PostBlitDeclaration f = new PostBlitDeclaration(loc, Loc(0));
+			auto f = new PostBlitDeclaration(loc, Loc(0));
 			parseContracts(f);
 			return f;
 		}
@@ -1586,7 +1636,7 @@
 		{	tpl = parseTemplateParameterList();
 
 			int varargs;
-			Arguments arguments = parseParameters(&varargs);
+			auto arguments = parseParameters(&varargs);
 
 			Expression constraint = null;
 			if (tpl)
@@ -1605,7 +1655,7 @@
 		/* Just a regular constructor
 		 */
 		int varargs;
-		Arguments arguments = parseParameters(&varargs);
+		auto arguments = parseParameters(&varargs);
 		CtorDeclaration f = new CtorDeclaration(loc, Loc(0), arguments, varargs);
 		parseContracts(f);
 		return f;
@@ -1714,19 +1764,49 @@
 		return f;
 	}
 	
+	/*****************************************
+	 * Parse a new definition:
+	 *	new(arguments) { body }
+	 * Current token is 'new'.
+	 */
     NewDeclaration parseNew()
 	{
-		assert(false);
+		NewDeclaration f;
+		scope arguments = new Parameters();
+		int varargs;
+		Loc loc = this.loc;
+
+		nextToken();
+		arguments = parseParameters(&varargs);
+		f = new NewDeclaration(loc, Loc(0), arguments, varargs);
+		parseContracts(f);
+		return f;
 	}
 	
+	/*****************************************
+	 * Parse a delete definition:
+	 *	delete(arguments) { body }
+	 * Current token is 'delete'.
+	 */
     DeleteDeclaration parseDelete()
 	{
-		assert(false);
+		DeleteDeclaration f;
+		scope Parameters arguments;
+		int varargs;
+		Loc loc = this.loc;
+
+		nextToken();
+		arguments = parseParameters(&varargs);
+		if (varargs)
+			error("... not allowed in delete function parameter list");
+		f = new DeleteDeclaration(loc, Loc(0), arguments);
+		parseContracts(f);
+		return f;
 	}
 	
-    Arguments parseParameters(int* pvarargs)
+    Parameters parseParameters(int* pvarargs)
 	{
-		Arguments arguments = new Arguments();
+		auto arguments = new Parameters();
 		int varargs = 0;
 		int hasdefault = 0;
 
@@ -1735,9 +1815,9 @@
 		{   Type *tb;
 		Identifier ai = null;
 		Type at;
-		Argument a;
-		STC storageClass = STC.STCundefined;
-		STC stc;
+		Parameter a;
+		StorageClass storageClass = STC.STCundefined;
+		StorageClass stc;
 		Expression ae;
 
 		for ( ;1; nextToken())
@@ -1770,14 +1850,23 @@
 				goto Ldefault;
 				stc = STC.STCshared;
 				goto L2;
+                
+		    case TOKwild:
+		        if (peek(&token).value == TOK.TOKlparen)
+			    goto Ldefault;
+		        stc = STCwild;
+		        goto L2;
 
 			case TOK.TOKin:	   stc = STC.STCin;		goto L2;
 			case TOK.TOKout:	   stc = STC.STCout;	goto L2;
+version(D1INOUT) {
 			case TOK.TOKinout:
+}
 			case TOK.TOKref:	   stc = STC.STCref;	goto L2;
 			case TOK.TOKlazy:	   stc = STC.STClazy;	goto L2;
 			case TOK.TOKscope:	   stc = STC.STCscope;	goto L2;
 			case TOK.TOKfinal:	   stc = STC.STCfinal;	goto L2;
+		    case TOK.TOKauto:	   stc = STCauto;	    goto L2;
 			L2:
 				if (storageClass & stc ||
 				(storageClass & STC.STCin && stc & (STC.STCconst | STC.STCscope)) ||
@@ -1847,14 +1936,14 @@
 				if (storageClass & (STC.STCout | STC.STCref))
 					error("variadic argument cannot be out or ref");
 				varargs = 2;
-				a = new Argument(storageClass, at, ai, ae);
-				arguments.push(cast(void*)a);
+				a = new Parameter(storageClass, at, ai, ae);
+				arguments.push(a);
 				nextToken();
 				break;
 				}
 			L3:
-				a = new Argument(storageClass, at, ai, ae);
-				arguments.push(cast(void*)a);
+				a = new Parameter(storageClass, at, ai, ae);
+				arguments.push(a);
 				if (token.value == TOK.TOKcomma)
 				{   nextToken();
 				goto L1;
@@ -2112,8 +2201,8 @@
 			}
 			if (token.value == TOK.TOKidentifier)
 			{
-				BaseClass b = new BaseClass(parseBasicType(), protection);
-				baseclasses.push(cast(void*)b);
+				auto b = new BaseClass(parseBasicType(), protection);
+				baseclasses.push(b);
 				if (token.value != TOK.TOKcomma)
 					break;
 			}
@@ -2131,7 +2220,7 @@
 		Import s;
 		Identifier id;
 		Identifier aliasid = null;
-		Array a;
+		Identifiers a;
 		Loc loc;
 
 		//printf("Parser.parseImport()\n");
@@ -2157,8 +2246,8 @@
 			while (token.value == TOK.TOKdot)
 			{
 				if (!a)
-					a = new Array();
-				a.push(cast(void*)id);
+					a = new Identifiers();
+				a.push(id);
 				nextToken();
 				if (token.value != TOK.TOKidentifier)
 				{   
@@ -2246,6 +2335,17 @@
 			t = t.makeSharedConst();
 			return t;
 		}
+        else if (token.value == TOKwild && peekNext() == TOKshared && peekNext2() != TOKlparen ||
+	             token.value == TOKshared && peekNext() == TOKwild && peekNext2() != TOKlparen)
+        {
+	        nextToken();
+	        nextToken();
+	        /* shared wild type
+	         */
+	        t = parseType(pident, tpl);
+	        t = t.makeSharedWild();
+	        return t;
+        }
 		else if (token.value == TOK.TOKconst && peekNext() != TOK.TOKlparen)
 		{
 			nextToken();
@@ -2274,6 +2374,15 @@
 			t = t.makeShared();
 			return t;
 		}
+        else if (token.value == TOKwild && peekNext() != TOKlparen)
+        {
+	        nextToken();
+	        /* wild type
+	         */
+	        t = parseType(pident, tpl);
+	        t = t.makeWild();
+	        return t;
+        }
 		else
 			t = parseBasicType();	
 		t = parseDeclarator(t, pident, tpl);
@@ -2401,10 +2510,24 @@
 			check(TOK.TOKrparen);
 			if (t.isConst())
 			t = t.makeSharedConst();
+	        else if (t.isWild())
+		    t = t.makeSharedWild();
 			else
 			t = t.makeShared();
 			break;
 
+	    case TOKwild:
+	        // wild(type)
+	        nextToken();
+	        check(TOK.TOKlparen);
+	        t = parseType();
+	        check(TOK.TOKrparen);
+	        if (t.isShared())
+		    t = t.makeSharedWild();
+	        else
+		    t = t.makeWild();
+	        break;
+            
 		default:
 			error("basic type expected, not %s", token.toChars());
 			t = Type.tint32;
@@ -2453,11 +2576,11 @@
 				{
 					//printf("it's type[expression]\n");
 					inBrackets++;
-					Expression e = parseExpression();		// [ expression ]
+					Expression e = parseAssignExp();		// [ expression ]
 					if (token.value == TOK.TOKslice)
 					{
 					nextToken();
-					Expression e2 = parseExpression();	// [ exp .. exp ]
+					Expression e2 = parseAssignExp();	// [ exp .. exp ]
 					t = new TypeSlice(t, e, e2);
 					}
 					else
@@ -2472,27 +2595,52 @@
 				{	// Handle delegate declaration:
 				//	t delegate(parameter list) nothrow pure
 				//	t function(parameter list) nothrow pure
-				Arguments arguments;
+				Parameters arguments;
 				int varargs;
 				bool ispure = false;
 				bool isnothrow = false;
+		        bool isproperty = false;
 				TOK save = token.value;
+		        TRUST trust = TRUSTdefault;
 	
 				nextToken();
 				arguments = parseParameters(&varargs);
 				while (1)
 				{   // Postfixes
 					if (token.value == TOK.TOKpure)
-					ispure = true;
+					    ispure = true;
 					else if (token.value == TOK.TOKnothrow)
-					isnothrow = true;
+					    isnothrow = true;
+		            else if (token.value == TOKat)
+		            {	StorageClass stc = parseAttribute();
+			            switch (cast(uint)(stc >> 32))
+			            {   case STCproperty >> 32:
+				                isproperty = true;
+				                break;
+			                case STCsafe >> 32:
+				                trust = TRUSTsafe;
+				                break;
+			                case STCsystem >> 32:
+				                trust = TRUSTsystem;
+				                break;
+			                case STCtrusted >> 32:
+				                trust = TRUSTtrusted;
+				                break;
+			                case 0:
+				                break;
+			                default:
+    				            assert(0);
+			            }
+		            }
 					else
-					break;
+					    break;
 					nextToken();
 				}
 				TypeFunction tf = new TypeFunction(arguments, t, varargs, linkage);
 				tf.ispure = ispure;
 				tf.isnothrow = isnothrow;
+		        tf.isproperty = isproperty;
+		        tf.trust = trust;
 				if (save == TOK.TOKdelegate)
 					t = new TypeDelegate(tf);
 				else
@@ -2581,7 +2729,7 @@
 			else
 			{
 				//printf("It's a static array\n");
-				Expression e = parseExpression();	// [ expression ]
+				Expression e = parseAssignExp();	// [ expression ]
 				ta = new TypeSArray(t, e);
 				check(TOK.TOKrbracket);
 			}
@@ -2616,7 +2764,7 @@
 			}
 
 			int varargs;
-			Arguments arguments = parseParameters(&varargs);
+			auto arguments = parseParameters(&varargs);
 			Type tf = new TypeFunction(arguments, t, varargs, linkage);
 
 			/* Parse const/invariant/nothrow/pure postfix
@@ -2647,6 +2795,14 @@
 						nextToken();
 						continue;
 
+                    case TOKwild:
+			            if (tf.isShared())
+				        tf = tf.makeSharedWild();
+			            else
+				        tf = tf.makeWild();
+			            nextToken();
+			            continue;
+
 					case TOK.TOKnothrow:
 						(cast(TypeFunction)tf).isnothrow = 1;
 						nextToken();
@@ -2658,19 +2814,31 @@
 						continue;
 
 					case TOK.TOKat:
-						nextToken();
-						if (token.value != TOK.TOKidentifier)
-						{   error("attribute identifier expected");
-						nextToken();
-						continue;
-						}
-						Identifier id = token.ident;
-						if (id is Id.property)
-						(cast(TypeFunction)tf).isproperty = 1;
-						else
-						error("valid attribute identifiers are @property, not @%s", id.toChars());
-						nextToken();
-						continue;
+    	            {
+                        StorageClass stc = parseAttribute();
+	                    auto tfunc = cast(TypeFunction)tf;
+		                switch (cast(uint)(stc >> 32))
+		                {
+                        case STCproperty >> 32:
+		                    tfunc.isproperty = 1;
+			                break;
+			            case STCsafe >> 32:
+			                tfunc.trust = TRUSTsafe;
+			                break;
+			            case STCsystem >> 32:
+			                tfunc.trust = TRUSTsystem;
+			                break;
+			            case STCtrusted >> 32:
+			                tfunc.trust = TRUSTtrusted;
+			                break;
+			            case 0:
+			                break;
+			            default:
+			                assert(0);
+					    }
+					    nextToken();
+					    continue;
+                    }
 					default:
 						break;	///
 				}
@@ -2699,9 +2867,9 @@
 		return ts;
 	}
 	
-    Dsymbols parseDeclarations(STC storage_class)
+    Dsymbols parseDeclarations(StorageClass storage_class)
 	{
-		STC stc;
+		StorageClass stc;
 		Type ts;
 		Type t;
 		Type tfirst;
@@ -2767,6 +2935,12 @@
 			if (peek(&token).value == TOK.TOKlparen)
 				break;
 			stc = STC.STCshared;
+		    goto L1;
+
+	        case TOKwild:
+		    if (peek(&token).value == TOK.TOKlparen)
+		        break;
+		    stc = STC.STCwild;
 			goto L1;
 
 			case TOK.TOKstatic:	stc = STC.STCstatic;	 goto L1;
@@ -2784,6 +2958,7 @@
 			case TOK.TOKtls:        stc = STC.STCtls;		 goto L1;
 			case TOK.TOKgshared:    stc = STC.STCgshared;	 goto L1;
 			case TOK.TOKenum:	stc = STC.STCmanifest;	 goto L1;
+	        case TOK.TOKat:         stc = parseAttribute();  goto L1;
 }
 			L1:
 			if (storage_class & stc)
@@ -2914,7 +3089,7 @@
 			auto tf = cast(TypeFunction)t;
 			Expression constraint = null;
 static if (false) {
-			if (Argument.isTPL(tf.parameters))
+			if (Parameter.isTPL(tf.parameters))
 			{
 			if (!tpl)
 				tpl = new TemplateParameters();
@@ -2995,7 +3170,6 @@
 	
     void parseContracts(FuncDeclaration f)
 	{
-		Type tb;
 		LINK linksave = linkage;
 
 		// The following is irrelevant, as it is overridden by sc.linkage in
@@ -3038,7 +3212,7 @@
 			check(TOK.TOKlparen);
 			while (1)
 			{
-			tb = parseBasicType();
+			Type tb = parseBasicType();
 			f.fthrows.push(tb);
 			if (token.value == TOK.TOKcomma)
 			{   nextToken();
@@ -3162,9 +3336,8 @@
 		case TOK.TOKline:
 }
 		Lexp:
-		{   Expression exp;
-
-			exp = parseExpression();
+		{
+			auto exp = parseExpression();
 			check(TOK.TOKsemicolon, "statement");
 			s = new ExpStatement(loc, exp);
 			break;
@@ -3187,6 +3360,16 @@
 				condition = parseStaticIfCondition();
 				goto Lcondition;
 			}
+	        if (tt.value == TOK.TOKstruct || tt.value == TOK.TOKunion || tt.value == TOK.TOKclass)
+	        {
+		        nextToken();
+		        auto a = parseBlock();
+		        Dsymbol d = new StorageClassDeclaration(STCstatic, a);
+		        s = new DeclarationStatement(loc, d);
+		        if (flags & ParseStatementFlags.PSscope)
+		            s = new ScopeStatement(loc, s);
+		        break;
+	        }
 			goto Ldeclaration;
 		}
 
@@ -3218,10 +3401,12 @@
 version (DMDV2) {
 		case TOK.TOKimmutable:
 		case TOK.TOKshared:
+        case TOKwild:
 		case TOK.TOKnothrow:
 		case TOK.TOKpure:
 		case TOK.TOKtls:
 		case TOK.TOKgshared:
+	    case TOK.TOKat:
 }
 	//	case TOK.TOKtypeof:
 		Ldeclaration:
@@ -3235,7 +3420,7 @@
 			foreach(Dsymbol d; a)
 			{
 				s = new DeclarationStatement(loc, d);
-				as.push(cast(void*)s);
+				as.push(s);
 			}
 			s = new CompoundDeclarationStatement(loc, as);
 			}
@@ -3308,7 +3493,7 @@
 			Statements statements = new Statements();
 			while (token.value != TOK.TOKrcurly && token.value != TOKeof)
 			{
-			statements.push(cast(void*)parseStatement(ParseStatementFlags.PSsemi | ParseStatementFlags.PScurlyscope));
+			statements.push(parseStatement(ParseStatementFlags.PSsemi | ParseStatementFlags.PScurlyscope));
 			}
 			endloc = this.loc;
 			s = new CompoundStatement(loc, statements);
@@ -3397,26 +3582,23 @@
 		case TOK.TOKforeach_reverse:
 		{
 			TOK op = token.value;
-			Arguments arguments;
-
-			Statement d;
-			Statement body_;
-			Expression aggr;
 
 			nextToken();
 			check(TOK.TOKlparen);
 
-			arguments = new Arguments();
+			auto arguments = new Parameters();
 
 			while (1)
 			{
-			Type tb;
 			Identifier ai = null;
 			Type at;
-			STC storageClass = STC.STCundefined;
-			Argument a;
-
-			if (token.value == TOK.TOKinout || token.value == TOK.TOKref)
+			StorageClass storageClass = STC.STCundefined;
+
+		if (token.value == TOKref
+//#if D1INOUT
+//			|| token.value == TOKinout
+//#endif
+		   )
 			{   storageClass = STC.STCref;
 				nextToken();
 			}
@@ -3434,8 +3616,8 @@
 			if (!ai)
 				error("no identifier for declarator %s", at.toChars());
 			  Larg:
-			a = new Argument(storageClass, at, ai, null);
-			arguments.push(cast(void*)a);
+			auto a = new Parameter(storageClass, at, ai, null);
+			arguments.push(a);
 			if (token.value == TOK.TOKcomma)
 			{   nextToken();
 				continue;
@@ -3444,28 +3626,28 @@
 			}
 			check(TOK.TOKsemicolon);
 
-			aggr = parseExpression();
+			Expression aggr = parseExpression();
 			if (token.value == TOK.TOKslice && arguments.dim == 1)
 			{
-			Argument a = cast(Argument)arguments.data[0];
+			auto a = arguments[0];
 			delete arguments;
 			nextToken();
 			Expression upr = parseExpression();
 			check(TOK.TOKrparen);
-			body_ = parseStatement(cast(ParseStatementFlags)0);
+			auto body_ = parseStatement(cast(ParseStatementFlags)0);
 			s = new ForeachRangeStatement(loc, op, a, aggr, upr, body_);
 			}
 			else
 			{
 			check(TOK.TOKrparen);
-			body_ = parseStatement(cast(ParseStatementFlags)0);
+			auto body_ = parseStatement(cast(ParseStatementFlags)0);
 			s = new ForeachStatement(loc, op, arguments, aggr, body_);
 			}
 			break;
 		}
 
 		case TOK.TOKif:
-		{   Argument arg = null;
+		{   Parameter arg = null;
 			Expression condition2;
 			Statement ifbody2;
 			Statement elsebody2;
@@ -3481,7 +3663,7 @@
 				Token *tt = peek(&token);
 				if (tt.value == TOK.TOKassign)
 				{
-					arg = new Argument(STC.STCundefined, null, token.ident, null);
+					arg = new Parameter(STC.STCundefined, null, token.ident, null);
 					nextToken();
 					nextToken();
 				}
@@ -3502,7 +3684,7 @@
 
 			at = parseType(&ai);
 			check(TOK.TOKassign);
-			arg = new Argument(STC.STCundefined, at, ai, null);
+			arg = new Parameter(STC.STCundefined, at, ai, null);
 			}
 
 			// Check for " ident;"
@@ -3511,7 +3693,7 @@
 			Token *tt = peek(&token);
 			if (tt.value == TOK.TOKcomma || tt.value == TOK.TOKsemicolon)
 			{
-				arg = new Argument(STC.STCundefined, null, token.ident, null);
+				arg = new Parameter(STC.STCundefined, null, token.ident, null);
 				nextToken();
 				nextToken();
 				if (1 || !global.params.useDeprecated)
@@ -3627,14 +3809,14 @@
 		case TOK.TOKcase:
 		{   Expression exp;
 			Statements statements;
-			scope Array cases = new Array();	// array of Expression's
+			scope cases = new Expressions();	// array of Expression's
 			Expression last = null;
 
 			while (1)
 			{
 			nextToken();
 			exp = parseAssignExp();
-			cases.push(cast(void*)exp);
+			cases.push(exp);
 			if (token.value != TOK.TOKcomma)
 				break;
 			}
@@ -3660,7 +3842,7 @@
 			   token.value != TOKeof &&
 			   token.value != TOK.TOKrcurly)
 			{
-			statements.push(cast(void*)parseStatement(ParseStatementFlags.PSsemi | ParseStatementFlags.PScurlyscope));
+			statements.push(parseStatement(ParseStatementFlags.PSsemi | ParseStatementFlags.PScurlyscope));
 			}
 			s = new CompoundStatement(loc, statements);
 			s = new ScopeStatement(loc, s);
@@ -3676,7 +3858,7 @@
 				// Keep cases in order by building the case statements backwards
 				for (int i = cases.dim; i; i--)
 				{
-					exp = cast(Expression)cases.data[i - 1];
+					exp = cases[i - 1];
 					s = new CaseStatement(loc, exp, s);
 				}
 			}
@@ -3696,7 +3878,7 @@
 			   token.value != TOKeof &&
 			   token.value != TOK.TOKrcurly)
 			{
-			statements.push(cast(void*)parseStatement(ParseStatementFlags.PSsemi | ParseStatementFlags.PScurlyscope));
+			statements.push(parseStatement(ParseStatementFlags.PSsemi | ParseStatementFlags.PScurlyscope));
 			}
 			s = new CompoundStatement(loc, statements);
 			s = new ScopeStatement(loc, s);
@@ -3941,7 +4123,7 @@
 						s = new LabelStatement(labelloc, label, s);
 						label = null;
 					}
-					statements.push(cast(void*)s);
+					statements.push(s);
 				}
 				nextToken();
 				continue;
@@ -4264,12 +4446,14 @@
 		if ((t.value == TOK.TOKconst ||
 			t.value == TOK.TOKinvariant ||
 			t.value == TOK.TOKimmutable ||
+	        t.value == TOKwild ||
 			t.value == TOK.TOKshared) &&
 			peek(t).value != TOK.TOKlparen)
 		{
 			/* const type
 			* immutable type
 			* shared type
+	        * wild type
 			*/
 			t = peek(t);
 		}
@@ -4428,7 +4612,8 @@
 		case TOK.TOKinvariant:
 		case TOK.TOKimmutable:
 		case TOK.TOKshared:
-			// const(type)  or  immutable(type)  or  shared(type)
+    	case TOKwild:
+			// const(type)  or  immutable(type)  or  shared(type)  or  wild(type)
 			t = peek(t);
 			if (t.value != TOK.TOKlparen)
 			goto Lfalse;
@@ -4593,6 +4778,7 @@
 							case TOK.TOKinvariant:
 							case TOK.TOKimmutable:
 							case TOK.TOKshared:
+                            case TOKwild:
 							case TOK.TOKpure:
 							case TOK.TOKnothrow:
 								t = peek(t);
@@ -4653,18 +4839,22 @@
 					t = peek(t);
 					break;
 
+version(D1INOUT) {
+	            case TOKinout:
+}
 				case TOKin:
 				case TOKout:
-				case TOKinout:
 				case TOKref:
 				case TOKlazy:
 				case TOKfinal:
+	            case TOKauto:
 					continue;
 
 				case TOKconst:
 				case TOKinvariant:
 				case TOKimmutable:
 				case TOKshared:
+	            case TOKwild:
 					t = peek(t);
 					if (t.value == TOKlparen)
 					{
@@ -5104,13 +5294,20 @@
 		}
 
 		case TOK.TOKtypeid:
-		{   Type tt;
-
+		{
 			nextToken();
 			check(TOK.TOKlparen, "typeid");
-			tt = parseType();		// ( type )
+	        Object o;
+	        if (isDeclaration(&token, 0, TOKreserved, null))
+	        {	// argument is a type
+		        o = parseType();
+	        }
+	        else
+	        {	// argument is an expression
+		        o = parseAssignExp();
+	        }
 			check(TOK.TOKrparen);
-			e = new TypeidExp(loc, tt);
+		    e = new TypeidExp(loc, o);
 			break;
 		}
 
@@ -5170,6 +5367,7 @@
 					 token.value == TOK.TOKinvariant && peek(&token).value == TOK.TOKrparen ||
 					 token.value == TOK.TOKimmutable && peek(&token).value == TOK.TOKrparen ||
 					 token.value == TOK.TOKshared && peek(&token).value == TOK.TOKrparen ||
+                     token.value == TOKwild && peek(&token).value == TOKrparen ||
 	///}
 					 token.value == TOK.TOKfunction ||
 					 token.value == TOK.TOKdelegate ||
@@ -5192,7 +5390,7 @@
 					check(TOK.TOKrparen);
 					}
 					TemplateParameter tp = new TemplateTypeParameter(loc2, ident, null, null);
-					tpl.insert(0, cast(void*)tp);
+					tpl.insert(0, tp);
 				}
 				else
 					check(TOK.TOKrparen);
@@ -5312,18 +5510,20 @@
 			 * (parameters) { body }
 			 * { body }
 			 */
-			Arguments arguments;
+			Parameters arguments;
 			int varargs;
 			FuncLiteralDeclaration fd;
 			Type tt;
 			bool isnothrow = false;
 			bool ispure = false;
-
+	        bool isproperty = false;
+	        TRUST trust = TRUSTdefault;
+            
 			if (token.value == TOK.TOKlcurly)
 			{
 			tt = null;
 			varargs = 0;
-			arguments = new Arguments();
+			arguments = new Parameters();
 			}
 			else
 			{
@@ -5341,8 +5541,31 @@
 				ispure = true;
 				else if (token.value == TOK.TOKnothrow)
 				isnothrow = true;
+		        else if (token.value == TOKat)
+		        {
+                    StorageClass stc = parseAttribute();
+			        switch (cast(uint)(stc >> 32))
+			        {
+                        case STCproperty >> 32:
+				            isproperty = true;
+				            break;
+			            case STCsafe >> 32:
+				            trust = TRUSTsafe;
+				            break;
+			            case STCsystem >> 32:
+				            trust = TRUSTsystem;
+				            break;
+			            case STCtrusted >> 32:
+				            trust = TRUSTtrusted;
+				            break;
+			            case 0:
+				            break;
+			            default:
+    				        assert(0);
+			        }
+	            }
 				else
-				break;
+	    			break;
 				nextToken();
 			}
 			}
@@ -5350,6 +5573,8 @@
 			TypeFunction tf = new TypeFunction(arguments, tt, varargs, linkage);
 			tf.ispure = ispure;
 			tf.isnothrow = isnothrow;
+	        tf.isproperty = isproperty;
+	        tf.trust = trust;
 			fd = new FuncLiteralDeclaration(loc, Loc(0), tf, save, null);
 			parseContracts(fd);
 			e = new FuncExp(loc, fd);
@@ -5437,7 +5662,7 @@
 			nextToken();
 			check(TOK.TOKlparen);
 			/* Look for cast(), cast(const), cast(immutable),
-			 * cast(shared), cast(shared const)
+			 * cast(shared), cast(shared const), cast(wild), cast(shared wild)
 			 */
 			MOD m;
 			if (token.value == TOK.TOKrparen)
@@ -5452,7 +5677,7 @@
 			}
 			else if ((token.value == TOK.TOKimmutable || token.value == TOK.TOKinvariant) && peekNext() == TOK.TOKrparen)
 			{
-			m = MOD.MODinvariant;
+			m = MOD.MODimmutable;
 			goto Lmod2;
 			}
 			else if (token.value == TOK.TOKshared && peekNext() == TOK.TOKrparen)
@@ -5460,10 +5685,22 @@
 			m = MOD.MODshared;
 			goto Lmod2;
 			}
+	        else if (token.value == TOKwild && peekNext() == TOK.TOKrparen)
+	        {
+		    m = MODwild;
+		    goto Lmod2;
+	        }
+	        else if (token.value == TOKwild && peekNext() == TOK.TOKshared && peekNext2() == TOK.TOKrparen ||
+		         token.value == TOK.TOKshared && peekNext() == TOKwild && peekNext2() == TOK.TOKrparen)
+	        {
+		    m = MOD.MODshared | MOD.MODwild;
+		    goto Lmod3;
+	        }
 			else if (token.value == TOK.TOKconst && peekNext() == TOK.TOKshared && peekNext2() == TOK.TOKrparen ||
 				 token.value == TOK.TOKshared && peekNext() == TOK.TOKconst && peekNext2() == TOK.TOKrparen)
 			{
 			m = MOD.MODshared | MOD.MODconst;
+	          Lmod3:
 			nextToken();
 			  Lmod2:
 			nextToken();
@@ -5590,6 +5827,15 @@
 			break;
 		}
 		assert(e);
+
+        // ^^ is right associative and has higher precedence than the unary operators
+        while (token.value == TOK.TOKpow)
+        {
+	        nextToken();
+	        Expression e2 = parseUnaryExp();
+	        e = new PowExp(loc, e, e2);
+        }
+
 		return e;
 	}
 	
@@ -5611,14 +5857,15 @@
 				if (token.value == TOK.TOKnot && peekNext() != TOK.TOKis)
 				{   // identifier!(template-argument-list)
 				TemplateInstance tempinst = new TemplateInstance(loc, id);
+			    Objects tiargs;
 				nextToken();
 				if (token.value == TOK.TOKlparen)
 					// ident!(template_arguments)
-					tempinst.tiargs = parseTemplateArgumentList();
+					tiargs = parseTemplateArgumentList();
 				else
 					// ident!template_argument
-					tempinst.tiargs = parseTemplateArgument();
-				e = new DotTemplateInstanceExp(loc, e, tempinst);
+					tiargs = parseTemplateArgument();
+				e = new DotTemplateInstanceExp(loc, e, id, tiargs);
 				}
 				else
 				e = new DotIdExp(loc, e, id);
@@ -5715,8 +5962,8 @@
 			switch (token.value)
 			{
 				case TOK.TOKmul: nextToken(); e2 = parseUnaryExp(); e = new MulExp(loc,e,e2); continue;
-				case TOK.TOKdiv: nextToken(); e2 = parseUnaryExp(); e = new DivExp(loc,e,e2); continue;
-				case TOK.TOKmod: nextToken(); e2 = parseUnaryExp(); e = new ModExp(loc,e,e2); continue;
+	            case TOK.TOKdiv: nextToken(); e2 = parseUnaryExp(); e = new DivExp(loc,e,e2); continue;
+	            case TOK.TOKmod: nextToken(); e2 = parseUnaryExp(); e = new ModExp(loc,e,e2); continue;
 
 				default:
 				break;
@@ -5983,6 +6230,7 @@
 				case TOK.TOKmulass:  nextToken(); e2 = parseAssignExp(); e = new MulAssignExp(loc,e,e2); continue;
 				case TOK.TOKdivass:  nextToken(); e2 = parseAssignExp(); e = new DivAssignExp(loc,e,e2); continue;
 				case TOK.TOKmodass:  nextToken(); e2 = parseAssignExp(); e = new ModAssignExp(loc,e,e2); continue;
+				case TOK.TOKpowass:  nextToken(); e2 = parseAssignExp(); e = new PowAssignExp(loc,e,e2); continue;
 				case TOK.TOKandass:  nextToken(); e2 = parseAssignExp(); e = new AndAssignExp(loc,e,e2); continue;
 				case TOK.TOKorass:   nextToken(); e2 = parseAssignExp(); e = new OrAssignExp(loc,e,e2); continue;
 				case TOK.TOKxorass:  nextToken(); e2 = parseAssignExp(); e = new XorAssignExp(loc,e,e2); continue;
--- a/dmd/PeelStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/PeelStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.PeelStatement;
 
+import dmd.common;
 import dmd.Statement;
 import dmd.Scope;
 import dmd.Loc;
--- a/dmd/Port.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/Port.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.Port;
 
+import dmd.common;
 import core.stdc.math;
 
 struct Port
--- a/dmd/PostBlitDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/PostBlitDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.PostBlitDeclaration;
 
+import dmd.common;
 import dmd.FuncDeclaration;
 import dmd.Global;
 import dmd.LINK;
--- a/dmd/PostExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/PostExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.PostExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Identifier;
 import dmd.backend.elem;
@@ -69,11 +70,8 @@
 
 	override elem* toElem(IRState* irs)
 	{
-		elem* e;
-		elem* einc;
-
-		e = e1.toElem(irs);
-		einc = e2.toElem(irs);
+		auto e = e1.toElem(irs);
+		auto einc = e2.toElem(irs);
 		e = el_bin((op == TOKplusplus) ? OPpostinc : OPpostdec,
 			e.Ety,e,einc);
 		el_setLoc(e,loc);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmd/PowAssignExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -0,0 +1,77 @@
+module dmd.PowAssignExp;
+
+import dmd.BinExp;
+import dmd.Scope;
+import dmd.Loc;
+import dmd.Identifier;
+import dmd.Expression;
+import dmd.TOK;
+import dmd.STC;
+import dmd.PowExp;
+import dmd.AssignExp;
+import dmd.Lexer;
+import dmd.VarDeclaration;
+import dmd.ExpInitializer;
+import dmd.DeclarationExp;
+import dmd.VarExp;
+import dmd.CommaExp;
+import dmd.ErrorExp;
+import dmd.Id;
+
+// Only a reduced subset of operations for now.
+class PowAssignExp : BinExp
+{
+    this(Loc loc, Expression e1, Expression e2)
+    {
+        super(loc, TOK.TOKpowass, PowAssignExp.sizeof, e1, e2);
+    }
+    
+    override Expression semantic(Scope sc)
+    {
+        Expression e;
+
+        if (type)
+	    return this;
+
+        BinExp.semantic(sc);
+        e2 = resolveProperties(sc, e2);
+
+        e = op_overload(sc);
+        if (e)
+	        return e;
+
+        e1 = e1.modifiableLvalue(sc, e1);
+        assert(e1.type && e2.type);
+
+        if ( (e1.type.isintegral() || e1.type.isfloating()) &&
+	     (e2.type.isintegral() || e2.type.isfloating()))
+        {
+	        if (e1.op == TOKvar)
+	        {   // Rewrite: e1 = e1 ^^ e2
+	            e = new PowExp(loc, e1.syntaxCopy(), e2);
+	            e = new AssignExp(loc, e1, e);
+	        }
+	        else
+	        {   // Rewrite: ref tmp = e1; tmp = tmp ^^ e2
+	            Identifier id = Lexer.uniqueId("__powtmp");
+	            auto v = new VarDeclaration(e1.loc, e1.type, id, new ExpInitializer(loc, e1));
+	            v.storage_class |= STC.STCref | STC.STCforeach;
+	            Expression de = new DeclarationExp(e1.loc, v);
+	            VarExp ve = new VarExp(e1.loc, v);
+	            e = new PowExp(loc, ve, e2);
+	            e = new AssignExp(loc, new VarExp(e1.loc, v), e);
+	            e = new CommaExp(loc, de, e);
+	        }
+	        e = e.semantic(sc);
+	        return e;
+        }
+        error("%s ^^= %s is not supported", e1.type.toChars(), e2.type.toChars() );
+        return new ErrorExp();
+    }
+    
+    // For operator overloading
+    Identifier opId()
+    {
+        return Id.powass;
+    }
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmd/PowExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -0,0 +1,171 @@
+module dmd.PowExp;
+
+import dmd.BinExp;
+import dmd.Scope;
+import dmd.Loc;
+import dmd.Identifier;
+import dmd.Expression;
+import dmd.TOK;
+import dmd.Module;
+import dmd.Id;
+import dmd.IdentifierExp;
+import dmd.DotIdExp;
+import dmd.CallExp;
+import dmd.ErrorExp;
+import dmd.CommaExp;
+import dmd.AndExp;
+import dmd.CondExp;
+import dmd.IntegerExp;
+import dmd.Type;
+import dmd.Lexer;
+import dmd.VarDeclaration;
+import dmd.ExpInitializer;
+import dmd.VarExp;
+import dmd.DeclarationExp;
+import dmd.MulExp;
+import dmd.WANT;
+
+version(DMDV2) {
+
+class PowExp : BinExp
+{
+    this(Loc loc, Expression e1, Expression e2)
+    {
+        super(loc, TOK.TOKpow, PowExp.sizeof, e1, e2);
+    }
+        
+    override Expression semantic(Scope sc)
+    {
+        Expression e;
+
+        if (type)
+	        return this;
+
+        //printf("PowExp::semantic() %s\n", toChars());
+        BinExp.semanticp(sc);
+        e = op_overload(sc);
+        if (e)
+	        return e;
+
+        assert(e1.type && e2.type);
+        if ( (e1.type.isintegral() || e1.type.isfloating()) &&
+	     (e2.type.isintegral() || e2.type.isfloating()))
+        {
+	        // For built-in numeric types, there are several cases.
+	        // TODO: backend support, especially for  e1 ^^ 2.
+            
+	        bool wantSqrt = false;	
+        	e1 = e1.optimize(0);
+	        e2 = e2.optimize(0);
+	        	
+	        // Replace 1 ^^ x or 1.0^^x by (x, 1)
+	        if ((e1.op == TOK.TOKint64 && e1.toInteger() == 1) ||
+		        (e1.op == TOK.TOKfloat64 && e1.toReal() == 1.0))
+	        {
+	            typeCombine(sc);
+	            e = new CommaExp(loc, e2, e1);
+	            e = e.semantic(sc);
+	            return e;
+ 	        }
+	        // Replace -1 ^^ x by (x&1) ? -1 : 1, where x is integral
+	        if (e2.type.isintegral() && e1.op == TOKint64 && cast(long)e1.toInteger() == -1)
+	        {
+	            typeCombine(sc);
+	            Type resultType = type;
+	            e = new AndExp(loc, e2, new IntegerExp(loc, 1, e2.type));
+	            e = new CondExp(loc, e, new IntegerExp(loc, -1, resultType), new IntegerExp(loc, 1, resultType));
+	            e = e.semantic(sc);
+	            return e;
+	        }
+	        // All other negative integral powers are illegal
+	        if ((e1.type.isintegral()) && (e2.op == TOK.TOKint64) && cast(long)e2.toInteger() < 0)
+	        {
+	            error("cannot raise %s to a negative integer power. Did you mean (cast(real)%s)^^%s ?",
+		        e1.type.toBasetype().toChars(), e1.toChars(), e2.toChars());
+	            return new ErrorExp();
+	        }
+	
+	        // Deal with x^^2, x^^3 immediately, since they are of practical importance.
+	        // Don't bother if x is a literal, since it will be constant-folded anyway.
+	        if ( (  (e2.op == TOK.TOKint64 && (e2.toInteger() == 2 || e2.toInteger() == 3)) 
+	             ||	(e2.op == TOK.TOKfloat64 && (e2.toReal() == 2.0 || e2.toReal() == 3.0))
+	             ) && (e1.op == TOK.TOKint64 || e1.op == TOK.TOKfloat64)
+	           )
+	        {
+	            typeCombine(sc);
+	            // Replace x^^2 with (tmp = x, tmp*tmp)
+	            // Replace x^^3 with (tmp = x, tmp*tmp*tmp) 
+	            Identifier idtmp = Lexer.uniqueId("__tmp");
+	            VarDeclaration tmp = new VarDeclaration(loc, e1.type.toBasetype(), idtmp, new ExpInitializer(Loc(0), e1));
+	            VarExp ve = new VarExp(loc, tmp);
+	            Expression ae = new DeclarationExp(loc, tmp);
+	            Expression me = new MulExp(loc, ve, ve);
+	            if ( (e2.op == TOK.TOKint64 && e2.toInteger() == 3) 
+	              || (e2.op == TOK.TOKfloat64 && e2.toReal() == 3.0))
+		        me = new MulExp(loc, me, ve);
+	            e = new CommaExp(loc, ae, me);
+	            e = e.semantic(sc);
+	            return e;
+	        }
+
+	        static int importMathChecked = 0;
+	        if (!importMathChecked)
+	        {
+	            importMathChecked = 1;
+	            for (int i = 0; i < Module.amodules.dim; i++)
+	            {
+                    auto mi = cast(Module)Module.amodules.data[i];
+		            //printf("\t[%d] %s\n", i, mi->toChars());
+		            if (mi.ident == Id.math &&
+		                mi.parent.ident == Id.std &&
+		                !mi.parent.parent)
+		                goto L1;
+	            }
+	            error("must import std.math to use ^^ operator");
+
+	         L1: ;
+	        }
+ 
+ 	        e = new IdentifierExp(loc, Id.empty);
+ 	        e = new DotIdExp(loc, e, Id.std);
+ 	        e = new DotIdExp(loc, e, Id.math);
+ 	        if (e2.op == TOK.TOKfloat64 && e2.toReal() == 0.5)
+ 	        {   // Replace e1 ^^ 0.5 with .std.math.sqrt(x)
+	            typeCombine(sc);
+ 	            e = new CallExp(loc, new DotIdExp(loc, e, Id._sqrt), e1);
+ 	        }
+ 	        else 
+	        {
+	            // Replace e1 ^^ e2 with .std.math.pow(e1, e2)
+	            // We don't combine the types if raising to an integer power (because
+	            // integer powers are treated specially by std.math.pow).
+	            if (!e2.type.isintegral())
+		            typeCombine(sc);
+	            e = new CallExp(loc, new DotIdExp(loc, e, Id._pow), e1, e2);	
+ 	        }	
+ 	        e = e.semantic(sc);
+	        // Always constant fold integer powers of literals. This will run the interpreter
+	        // on .std.math.pow
+	        if ((e1.op == TOK.TOKfloat64 || e1.op == TOK.TOKint64) && (e2.op == TOK.TOKint64))
+	            e = e.optimize(WANT.WANTvalue | WANT.WANTinterpret);
+
+	        return e;
+        }
+        error("%s ^^ %s is not supported", e1.type.toChars(), e2.type.toChars() );
+        return new ErrorExp();
+    }
+   
+
+    // For operator overloading
+    override Identifier opId()
+    {
+        return Id.pow;
+    }
+    
+    override Identifier opId_r()
+    {
+        return Id.pow_r;
+    }
+}
+
+}
\ No newline at end of file
--- a/dmd/PragmaDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/PragmaDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.PragmaDeclaration;
 
+import dmd.common;
 import dmd.ArrayTypes;
 import dmd.AttribDeclaration;
 import dmd.Loc;
@@ -60,7 +61,7 @@
 					if (e.op == TOKstring)
 					{
 						auto se = cast(StringExp)e;
-						writef("%s", se.toChars()[1..$-3] /*se.len, cast(char*)se.string_*/);
+						writef("%s", se.toChars()[1..$-2]); // strip the '"'s, TODO: change to original?: /*se.len, cast(char*)se.string_*/
 					}
 					else
 						writef(e.toChars());
@@ -126,6 +127,7 @@
 ///		goto Lnodecl;
 ///		}
 ///	}
+///version(DMDV2) {
 		else if (ident == Id.startaddress)
 		{
 			if (!args || args.dim != 1)
@@ -142,6 +144,7 @@
 			}
 			goto Lnodecl;
 		}
+///}
 ///	version (TARGET_NET) {
 ///		else if (ident == Lexer.idPool("assembly"))
 ///		{
--- a/dmd/PragmaStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/PragmaStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,7 +1,12 @@
 module dmd.PragmaStatement;
 
+import dmd.common;
+import dmd.expression.Util;
 import dmd.Statement;
+import dmd.StringExp;
+import dmd.Id;
 import dmd.Identifier;
+import dmd.Dsymbol;
 import dmd.Expression;
 import dmd.Loc;
 import dmd.Identifier;
@@ -10,44 +15,168 @@
 import dmd.HdrGenState;
 import dmd.IRState;
 import dmd.BE;
+import dmd.TOK;
+import dmd.WANT;
 
 class PragmaStatement : Statement
 {
-    Identifier ident;
-    Expressions args;		// array of Expression's
-    Statement body_;
+	Identifier ident;
+	Expressions args;		// array of Expression's
+	Statement body_;
 
-    this(Loc loc, Identifier ident, Expressions args, Statement body_)
+	this(Loc loc, Identifier ident, Expressions args, Statement body_)
 	{
 		super(loc);
+		this.ident = ident;
+		this.args = args;
+		this.body_ = body_;
 	}
 	
-    override Statement syntaxCopy()
+	override Statement syntaxCopy()
 	{
-		assert(false);
+		Statement b = null;
+		if (body_)
+		b = body_.syntaxCopy();
+		PragmaStatement s = new PragmaStatement(loc,
+			ident, Expression.arraySyntaxCopy(args), b);
+		return s;
+
 	}
 	
-    override Statement semantic(Scope sc)
+	override Statement semantic(Scope sc)
 	{
-		assert(false);
-	}
+		// Should be merged with PragmaDeclaration
+		//writef("PragmaStatement.semantic() %s\n", toChars());
+		//writef("body = %p\n", body_);
+		if (ident == Id.msg)
+		{
+			if (args)
+			{
+				foreach (Expression e; args)
+				{
+					e = e.semantic(sc);
+					e = e.optimize(WANTvalue | WANTinterpret);
+					if (e.op == TOK.TOKstring)
+					{
+						StringExp se = cast(StringExp)e;
+						writef("%.*s", se.len, cast(char*)se.string_);
+					}
+					else
+						writef(e.toChars());
+				}
+				writef("\n");
+			}
+		}
+		else if (ident == Id.lib)
+		{
+static if (true)
+{
+			/* Should this be allowed?
+			 */
+			error("pragma(lib) not allowed as statement");
+}
+else
+{
+			if (!args || args.dim != 1)
+				error("string expected for library name");
+			else
+			{
+				Expression e = args[0];
 	
-    override bool usesEH()
-	{
-		assert(false);
+				e = e.semantic(sc);
+				e = e.optimize(WANTvalue | WANTinterpret);
+				args[0] = e;
+				if (e.op != TOKstring)
+					error("string expected for library name, not '%s'", e.toChars());
+				else if (global.params.verbose)
+				{
+					StringExp se = cast(StringExp)e;
+					writef("library   %.*s\n", se.len, se.string_);
+				}
+			}
+}
+		}
+//version(DMDV2) // TODO:
+//{
+		else if (ident == Id.startaddress)
+		{
+			if (!args || args.dim != 1)
+				error("function name expected for start address");
+			else
+			{
+				Expression e = args[0];
+				e = e.semantic(sc);
+				e = e.optimize(WANTvalue | WANTinterpret);
+				args[0] = e;
+				Dsymbol sa = getDsymbol(e);
+				if (!sa || !sa.isFuncDeclaration())
+					error("function name expected for start address, not '%s'", e.toChars());
+				if (body_)
+				{
+					body_ = body_.semantic(sc);
+				}
+				return this;
+			}
+		}
+//}
+		else
+			error("unrecognized pragma(%s)", ident.toChars());
+
+		if (body_)
+		{
+		body_ = body_.semantic(sc);
+		}
+		return body_;
 	}
 	
-    override BE blockExit()
+	override bool usesEH()
+	{
+		return body_ && body_.usesEH();
+	}
+	
+	override BE blockExit()
 	{
-		assert(false);
+		BE result = BEfallthru;
+static if (false) // currently, no code is generated for Pragma's, so it's just fallthru
+{
+		if (arrayExpressionCanThrow(args))
+			result |= BEthrow;
+		if (body_)
+			result |= body_.blockExit();
+}
+			return result;
 	}
 	
-    override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
+	override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
 	{
-		assert(false);
+		buf.writestring("pragma (");
+		buf.writestring(ident.toChars());
+		if (args && args.dim)
+		{
+			buf.writestring(", ");
+			argsToCBuffer(buf, args, hgs);
+		}
+		buf.writeByte(')');
+		if (body_)
+		{
+			buf.writenl();
+			buf.writeByte('{');
+			buf.writenl();
+	
+			body_.toCBuffer(buf, hgs);
+	
+			buf.writeByte('}');
+			buf.writenl();
+		}
+		else
+		{
+			buf.writeByte(';');
+			buf.writenl();
+		}
+
 	}
 	
-    override void toIR(IRState* irs)
+	override void toIR(IRState* irs)
 	{
 		assert(false);
 	}
--- a/dmd/ProtDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/ProtDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.ProtDeclaration;
 
+import dmd.common;
 import dmd.AttribDeclaration;
 import dmd.PROT;
 import dmd.OutBuffer;
--- a/dmd/PtrExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/PtrExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.PtrExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Identifier;
 import dmd.backend.elem;
@@ -84,7 +85,12 @@
 	{
 		return 1;
 	}
-
+    
+    override void checkEscapeRef()
+    {
+        e1.checkEscape();
+    }
+    
 	override Expression toLvalue(Scope sc, Expression e)
 	{
 static if (false) {
--- a/dmd/RealExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/RealExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,7 @@
 module dmd.RealExp;
 
+import dmd.common;
+import dmd.Complex;
 import dmd.Expression;
 import dmd.backend.elem;
 import dmd.InterState;
@@ -14,13 +16,13 @@
 import dmd.Port;
 import dmd.TY;
 
+import dmd.expression.Util;
+
 import dmd.backend.dt_t;
 import dmd.backend.Util;
 import dmd.backend.TYM;
 import dmd.backend.mTY;
 
-import dmd.Complex;
-
 import std.stdio;
 
 class RealExp : Expression
@@ -37,7 +39,20 @@
 
 	override bool equals(Object o)
 	{
-		assert(false);
+		if (this is o)
+			return true;
+		
+		Expression e = cast(Expression)o;
+		if (e.op == TOKfloat64) {
+			RealExp ne = cast(RealExp)e;
+			if (type.toHeadMutable().equals(ne.type.toHeadMutable())) {
+				if (RealEquals(value, ne.value)) {
+					return true;
+				}
+			}
+		}
+		
+		return 0;
 	}
 
 	override Expression semantic(Scope sc)
@@ -109,7 +124,7 @@
 
 	override bool isBool(bool result)
 	{
-		assert(false);
+		return result ? (value != 0) : (value == 0);
 	}
 
 	override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
@@ -119,7 +134,8 @@
 
 	override void toMangleBuffer(OutBuffer buf)
 	{
-		assert(false);
+		buf.writeByte('e');
+		realToMangleBuffer(buf, value);
 	}
 
 	override elem* toElem(IRState* irs)
--- a/dmd/RemoveExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/RemoveExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.RemoveExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.backend.elem;
 import dmd.Loc;
@@ -38,7 +39,7 @@
 		elem* ep;
 		elem* keyti;
 
-		if (tybasic(ekey.Ety) == TYstruct)
+		if (tybasic(ekey.Ety) == TYstruct || tybasic(ekey.Ety) == TYarray)
 		{
 			ekey = el_una(OPstrpar, TYstruct, ekey);
 			ekey.Enumbytes = ekey.E1.Enumbytes;
--- a/dmd/ReturnStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/ReturnStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.ReturnStatement;
 
+import dmd.common;
 import dmd.Loc;
 import dmd.Statement;
 import dmd.GotoStatement;
@@ -34,6 +35,7 @@
 import dmd.VarDeclaration;
 import dmd.GlobalExpressions;
 import dmd.BE;
+import dmd.Global;
 
 import dmd.codegen.Util;
 
@@ -172,14 +174,46 @@
 			if (fd.returnLabel && tbret.ty != TY.Tvoid) {
 				;
 			} else if (fd.inferRetType) {
-				if (fd.type.nextOf()) {
-					if (!exp.type.equals(fd.type.nextOf()))
-						error("mismatched function return type inference of %s and %s", exp.type.toChars(), fd.type.nextOf().toChars());
+				auto tf = cast(TypeFunction)fd.type;
+	            assert(tf.ty == TY.Tfunction);
+	            Type tfret = tf.nextOf();
+	            if (tfret)
+                {
+   					if (!exp.type.equals(tfret))
+						error("mismatched function return type inference of %s and %s", exp.type.toChars(), tfret.toChars());
+		            /* The "refness" is determined by the first return statement,
+		             * not all of them. This means:
+		             *    return 3; return x;  // ok, x can be a value
+		             *    return x; return 3;  // error, 3 is not an lvalue
+		             */
 				}
 				else
 				{
-					(cast(TypeFunction)fd.type).next = exp.type;
-					fd.type = fd.type.semantic(loc, sc);
+		            if (tf.isref)
+		            {   /* Determine "refness" of function return:
+		                 * if it's an lvalue, return by ref, else return by value
+		                 */
+		                if (exp.isLvalue())
+		                {
+			                /* Return by ref
+			                 * (but first ensure it doesn't fail the "check for
+			                 * escaping reference" test)
+			                 */
+			                uint errors = global.errors;
+			                global.gag++;
+			                exp.checkEscapeRef();
+			                global.gag--;
+			                if (errors != global.errors)
+			                {   tf.isref = false;	// return by value
+			                    global.errors = errors;
+			                }
+		                }
+		                else
+			                tf.isref = false;	// return by value
+		            }
+		            tf.next = exp.type;
+		            fd.type = tf.semantic(loc, sc);
+
 					if (!fd.tintro)
 					{   
 						tret = fd.type.nextOf();
@@ -289,19 +323,14 @@
 				else
 					exp = exp.toLvalue(sc, exp);
 
-				if (exp.op == TOK.TOKvar)
-				{	
-					VarExp ve = cast(VarExp)exp;
-					VarDeclaration v = ve.var.isVarDeclaration();
-					if (v && !v.isDataseg() && !(v.storage_class & (STC.STCref | STC.STCout))) {
-						error("escaping reference to local variable %s", v.toChars());
-					}
-				}
+				exp.checkEscapeRef();
 			}
-
-			//exp.dump(0);
-			//exp.print();
-			exp.checkEscape();
+            else
+            {
+			    //exp.dump(0);
+			    //exp.print();
+			    exp.checkEscape();
+            }
 		}
 
 		/* BUG: need to issue an error on:
--- a/dmd/STC.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/STC.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,6 +1,6 @@
 module dmd.STC;
 
-enum STC
+enum STC : ulong
 {
     STCundefined    = 0,
     STCstatic	    = 1,
@@ -23,7 +23,6 @@
     STCctorinit     = 0x20000,		// can only be set inside constructor
     STCtemplateparameter = 0x40000,	// template parameter
     STCscope	    = 0x80000,		// template parameter
-    STCinvariant    = 0x100000,
     STCimmutable    = 0x100000,
     STCref	    = 0x200000,
     STCinit	    = 0x400000,		// has explicit initializer
@@ -36,8 +35,17 @@
     STCshared       = 0x20000000,	// accessible from multiple threads
     STCgshared      = 0x40000000,	// accessible from multiple threads
 					// but not typed as "shared"
-    STC_TYPECTOR    = (STCconst | STCimmutable | STCshared),
+    STCwild         = 0x80000000,	// for "wild" type constructor
+    STC_TYPECTOR    = (STCconst | STCimmutable | STCshared | STCwild),
+
+    // attributes
+	STCproperty		= 0x100000000,
+	STCsafe			= 0x200000000,
+	STCtrusted		= 0x400000000,
+	STCsystem		= 0x800000000,
+	STCctfe			= 0x1000000000,	// can be used in CTFE, even if it is static
 }
+alias STC StorageClass;
 
 import dmd.EnumUtils;
 mixin(BringToCurrentScope!(STC));
\ No newline at end of file
--- a/dmd/Scope.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/Scope.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.Scope;
 
+import dmd.common;
 import dmd.Module;
 import dmd.ScopeDsymbol;
 import dmd.FuncDeclaration;
@@ -77,7 +78,7 @@
     PROT protection = PROT.PROTpublic;	// protection for class members
     int explicitProtection;	// set if in an explicit protection attribute
 
-    STC stc;		// storage class
+    StorageClass stc;		// storage class
 
     SCOPE flags;
 
@@ -136,6 +137,7 @@
 		this.sd = null;
 		this.sw = enclosing.sw;
 		this.tf = enclosing.tf;
+        this.tinst = enclosing.tinst;
 		this.tinst = enclosing.tinst;
 		this.sbreak = enclosing.sbreak;
 		this.scontinue = enclosing.scontinue;
@@ -170,13 +172,7 @@
 	
 	Scope clone()
 	{
-		// similar code is used in Type.clone()
-		// TODO: move to Util or something...
-		size_t size = __traits(classInstanceSize, typeof(this));
-		void* mem = GC.malloc(size);
-		memcpy(mem, cast(void*)this, size);
-		
-		return cast(typeof(this))mem;
+		return cloneThis(this);
 	}
 
     Scope push()
--- a/dmd/ScopeDsymbol.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/ScopeDsymbol.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.ScopeDsymbol;
 
+import dmd.common;
 import dmd.Dsymbol;
 import dmd.Declaration;
 import dmd.Array;
@@ -247,8 +248,8 @@
 		if (!tfgetmembers)
 		{
 			Scope sc;
-			Arguments arguments = new Arguments();
-			Arguments arg = new Argument(STCin, Type.tchar.constOf().arrayOf(), null, null);
+			auto arguments = new Arguments();
+			auto arg = new Argument(STCin, Type.tchar.constOf().arrayOf(), null, null);
 			arguments.push(arg);
 
 			Type tret = null;
--- a/dmd/ScopeExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/ScopeExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.ScopeExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.backend.elem;
 import dmd.ScopeDsymbol;
--- a/dmd/ScopeStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/ScopeStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.ScopeStatement;
 
+import dmd.common;
 import dmd.Statement;
 import dmd.Loc;
 import dmd.Scope;
--- a/dmd/ShlAssignExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/ShlAssignExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.ShlAssignExp;
 
+import dmd.common;
 import dmd.BinExp;
 import dmd.Loc;
 import dmd.Expression;
@@ -10,8 +11,10 @@
 import dmd.TOK;
 import dmd.Id;
 import dmd.Type;
+import dmd.ArrayLengthExp;
 import dmd.backend.elem;
 import dmd.backend.OPER;
+import dmd.expression.Shl;
 import dmd.expression.Util;
 
 class ShlAssignExp : BinExp
@@ -33,6 +36,13 @@
 		if (e)
 			return e;
 
+        if (e1.op == TOK.TOKarraylength)
+        {
+	        e = ArrayLengthExp.rewriteOpAssign(this);
+	        e = e.semantic(sc);
+	        return e;
+        }
+
 		e1 = e1.modifiableLvalue(sc, e1);
 		e1.checkScalar();
 		e1.checkNoBool();
@@ -46,7 +56,7 @@
 	
     override Expression interpret(InterState istate)
 	{
-		assert(false);
+    	return interpretAssignCommon(istate, &Shl);
 	}
 
     override Identifier opId()    /* For operator overloading */
--- a/dmd/ShlExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/ShlExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.ShlExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Identifier;
 import dmd.backend.elem;
@@ -56,7 +57,7 @@
 
 	override Expression interpret(InterState istate)
 	{
-		assert(false);
+		return interpretCommon(istate, &Shl);
 	}
 
 	override IntRange getIntRange()
--- a/dmd/ShrAssignExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/ShrAssignExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.ShrAssignExp;
 
+import dmd.common;
 import dmd.BinExp;
 import dmd.Loc;
 import dmd.Expression;
@@ -10,10 +11,13 @@
 import dmd.Id;
 import dmd.TOK;
 import dmd.Type;
+import dmd.ArrayLengthExp;
+import dmd.CastExp;
 
 import dmd.backend.elem;
 import dmd.backend.OPER;
 
+import dmd.expression.Shr;
 import dmd.expression.Util;
 
 class ShrAssignExp : BinExp
@@ -34,6 +38,13 @@
 		if (e)
 			return e;
 
+        if (e1.op == TOK.TOKarraylength)
+        {
+	        e = ArrayLengthExp.rewriteOpAssign(this);
+	        e = e.semantic(sc);
+	        return e;
+        }
+        
 		e1 = e1.modifiableLvalue(sc, e1);
 		e1.checkScalar();
 		e1.checkNoBool();
@@ -48,7 +59,7 @@
 	
     override Expression interpret(InterState istate)
 	{
-		assert(false);
+    	return interpretAssignCommon(istate, &Shr);
 	}
 
     override Identifier opId()    /* For operator overloading */
@@ -58,6 +69,15 @@
 
     override elem* toElem(IRState* irs)
 	{
-		return toElemBin(irs, OPshrass);
+	    //printf("ShrAssignExp::toElem() %s, %s\n", e1->type->toChars(), e1->toChars());
+		Type t1 = e1.type;
+		if (e1.op == TOK.TOKcast)
+		{
+			// Use the type before it was integrally promoted to int
+			auto ce = cast(CastExp)e1;
+			t1 = ce.e1.type;
+		}
+		return toElemBin(irs, t1.isunsigned() ? OPER.OPshrass : OPER.OPashrass);
+
 	}
 }
--- a/dmd/ShrExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/ShrExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.ShrExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Identifier;
 import dmd.InterState;
@@ -54,7 +55,7 @@
 
 	override Expression interpret(InterState istate)
 	{
-		assert(false);
+		return interpretCommon(istate, &Shr);
 	}
 
 	override IntRange getIntRange()
@@ -74,7 +75,7 @@
 
 	override elem* toElem(IRState* irs)
 	{
-		return toElemBin(irs, OPER.OPshr);
+		return toElemBin(irs, e1.type.isunsigned() ? OPER.OPshr : OPER.OPashr);
 	}
 }
 
--- a/dmd/SliceExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/SliceExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.SliceExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.expression.ArrayLength;
 import dmd.backend.elem;
@@ -30,7 +31,7 @@
 import dmd.VarDeclaration;
 import dmd.ErrorExp;
 import dmd.TypeExp;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.ExpInitializer;
 import dmd.IRState;
 import dmd.InlineDoState;
@@ -199,7 +200,7 @@
 			else if (e1.op == TOKtype)	// slicing a type tuple
 			{   
 				tup = cast(TypeTuple)t;
-				length = Argument.dim(tup.arguments);
+				length = Parameter.dim(tup.arguments);
 			}
 			else
 				assert(0);
@@ -222,12 +223,12 @@
 				}
 				else
 				{	
-					Arguments args = new Arguments;
+					auto args = new Parameters;
 					args.reserve(j2 - j1);
 					for (size_t i = j1; i < j2; i++)
 					{   
-						Argument arg = Argument.getNth(tup.arguments, i);
-						args.push(cast(void*)arg);
+						auto arg = Parameter.getNth(tup.arguments, i);
+						args.push(arg);
 					}
 					e = new TypeExp(e1.loc, new TypeTuple(args));
 				}
@@ -264,6 +265,11 @@
 	{
 		e1.checkEscape();
 	}
+    
+    override void checkEscapeRef()
+    {
+        e1.checkEscapeRef();
+    }
 
 version (DMDV2) {
 	override int isLvalue()
@@ -378,36 +384,26 @@
 
 	override elem* toElem(IRState* irs)
 	{
-		elem* e;
-		Type t1;
-
 		//printf("SliceExp.toElem()\n");
-		t1 = e1.type.toBasetype();
-		e = e1.toElem(irs);
+		auto t1 = e1.type.toBasetype();
+		auto e = e1.toElem(irs);
 		if (lwr)
 		{
-			elem* elwr;
-			elem* elwr2;
-			elem* eupr;
-			elem* eptr;
-			elem* einit;
-			int sz;
+			auto einit = resolveLengthVar(lengthVar, &e, t1);
+
+			int sz = cast(uint)t1.nextOf().size();
 
-			einit = resolveLengthVar(lengthVar, &e, t1);
-
-			sz = cast(uint)t1.nextOf().size();
+			auto elwr = lwr.toElem(irs);
+			auto eupr = upr.toElem(irs);
 
-			elwr = lwr.toElem(irs);
-			eupr = upr.toElem(irs);
-
-			elwr2 = el_same(&elwr);
+			auto elwr2 = el_same(&elwr);
 
 			// Create an array reference where:
 			// length is (upr - lwr)
 			// pointer is (ptr + lwr*sz)
 			// Combine as (length pair ptr)
 
-			if (global.params.useArrayBounds)
+			if (irs.arrayBoundsCheck())
 			{
 				// Checks (unsigned compares):
 				//	upr <= array.length
@@ -469,7 +465,7 @@
 				}
 			}
 
-			eptr = array_toPtr(e1.type, e);
+			auto eptr = array_toPtr(e1.type, e);
 
 			elem *elength = el_bin(OPmin, TYint, eupr, elwr2);
 			eptr = el_bin(OPadd, TYnptr, eptr, el_bin(OPmul, TYint, el_copytree(elwr2), el_long(TYint, sz)));
@@ -508,11 +504,11 @@
 		arguments.shift(this);
 	}
 
-	override Expression buildArrayLoop(Arguments fparams)
+	override Expression buildArrayLoop(Parameters fparams)
 	{
 		Identifier id = Identifier.generateId("p", fparams.dim);
-		Argument param = new Argument(STCconst, type, id, null);
-		fparams.shift(cast(void*)param);
+		auto param = new Parameter(STCconst, type, id, null);
+		fparams.shift(param);
 		Expression e = new IdentifierExp(Loc(0), id);
 		Expressions arguments = new Expressions();
 		Expression index = new IdentifierExp(Loc(0), Id.p);
--- a/dmd/Statement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/Statement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.Statement;
 
+import dmd.common;
 import dmd.TryCatchStatement;
 import dmd.GotoStatement;
 import dmd.AsmStatement;
@@ -119,9 +120,11 @@
 		assert(false);
 	}
 	
+	// TRUE if statement uses exception handling
+	
     bool usesEH()
 	{
-		assert(false);
+		return false;
 	}
 	
     BE blockExit()
--- a/dmd/StaticAssert.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/StaticAssert.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.StaticAssert;
 
+import dmd.common;
 import dmd.Dsymbol;
 import dmd.Expression;
 import dmd.OutBuffer;
@@ -67,12 +68,11 @@
 			else
 				error("(%s) is false", exp.toChars());
 
-			if(sc.tinst)
+			if (sc.tinst)
 				sc.tinst.printInstantiationTrace();
 
-			if (!global.gag) {
+			if (!global.gag)
 				fatal();
-			}
 		}
 		else if (!e.isBool(true))
 		{
--- a/dmd/StaticAssertStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/StaticAssertStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.StaticAssertStatement;
 
+import dmd.common;
 import dmd.Statement;
 import dmd.StaticAssert;
 import dmd.OutBuffer;
--- a/dmd/StaticCtorDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/StaticCtorDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.StaticCtorDeclaration;
 
+import dmd.common;
 import dmd.FuncDeclaration;
 import dmd.Loc;
 import dmd.Dsymbol;
@@ -65,14 +66,14 @@
 			v.storage_class = STCstatic;
 			Statements sa = new Statements();
 			Statement s = new DeclarationStatement(Loc(0), v);
-			sa.push(cast(void*)s);
+			sa.push(s);
 			Expression e = new IdentifierExp(Loc(0), id);
 			e = new AddAssignExp(Loc(0), e, new IntegerExp(1));
 			e = new EqualExp(TOKnotequal, Loc(0), e, new IntegerExp(1));
 			s = new IfStatement(Loc(0), null, e, new ReturnStatement(Loc(0), null), null);
-			sa.push(cast(void*)s);
+			sa.push(s);
 			if (fbody)
-				sa.push(cast(void*)fbody);
+				sa.push(fbody);
 			fbody = new CompoundStatement(Loc(0), sa);
 		}
 
--- a/dmd/StaticDtorDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/StaticDtorDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.StaticDtorDeclaration;
 
+import dmd.common;
 import dmd.FuncDeclaration;
 import dmd.VarDeclaration;
 import dmd.Dsymbol;
@@ -42,7 +43,7 @@
 	{
 		assert(!s);
 		StaticDtorDeclaration sdd = new StaticDtorDeclaration(loc, endloc);
-		return FuncDeclaration.syntaxCopy(sdd);
+		return super.syntaxCopy(sdd);
 	}
 	
 	override void semantic(Scope sc)
@@ -72,16 +73,16 @@
 			Identifier id = Lexer.idPool("__gate");
 			VarDeclaration v = new VarDeclaration(Loc(0), Type.tint32, id, null);
 			v.storage_class = STCstatic;
-			Statements sa = new Statements();
+			auto sa = new Statements();
 			Statement s = new DeclarationStatement(Loc(0), v);
-			sa.push(cast(void*)s);
+			sa.push(s);
 			Expression e = new IdentifierExp(Loc(0), id);
 			e = new AddAssignExp(Loc(0), e, new IntegerExp(-1));
 			e = new EqualExp(TOKnotequal, Loc(0), e, new IntegerExp(0));
 			s = new IfStatement(Loc(0), null, e, new ReturnStatement(Loc(0), null), null);
-			sa.push(cast(void*)s);
+			sa.push(s);
 			if (fbody)
-				sa.push(cast(void*)fbody);
+				sa.push(fbody);
 			fbody = new CompoundStatement(Loc(0), sa);
 			vgate = v;
 		}
--- a/dmd/StaticIfCondition.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/StaticIfCondition.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.StaticIfCondition;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.ScopeDsymbol;
 import dmd.OutBuffer;
--- a/dmd/StaticIfDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/StaticIfDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.StaticIfDeclaration;
 
+import dmd.common;
 import dmd.ConditionalDeclaration;
 import dmd.ScopeDsymbol;
 import dmd.AttribDeclaration;
--- a/dmd/StorageClassDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/StorageClassDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.StorageClassDeclaration;
 
+import dmd.common;
 import dmd.AttribDeclaration;
 import dmd.Array;
 import dmd.TOK;
@@ -9,12 +10,14 @@
 import dmd.OutBuffer;
 import dmd.HdrGenState;
 import dmd.STC;
+import dmd.Id;
+import dmd.Identifier;
 
 class StorageClassDeclaration: AttribDeclaration
 {
-    STC stc;
+    StorageClass stc;
 
-    this(STC stc, Dsymbols decl)
+    this(StorageClass stc, Dsymbols decl)
 	{
 		super(decl);
 		
@@ -34,7 +37,7 @@
 	{
 		if (decl)
 		{
-			STC scstc = sc.stc;
+			StorageClass scstc = sc.stc;
 
 			/* These sets of storage classes are mutually exclusive,
 			 * so choose the innermost or most recent one.
@@ -47,6 +50,8 @@
 				scstc &= ~(STC.STCconst | STC.STCimmutable | STC.STCmanifest);
 			if (stc & (STC.STCgshared | STC.STCshared | STC.STCtls))
 				scstc &= ~(STC.STCgshared | STC.STCshared | STC.STCtls);
+			if (stc & (STCsafe | STCtrusted | STCsystem))
+				scstc &= ~(STCsafe | STCtrusted | STCsystem);
 			scstc |= stc;
 
 			setScopeNewSc(sc, scstc, sc.linkage, sc.protection, sc.explicitProtection, sc.structalign);
@@ -57,7 +62,7 @@
 	{
 		if (decl)
 		{
-			STC scstc = sc.stc;
+			StorageClass scstc = sc.stc;
 
 			/* These sets of storage classes are mutually exclusive,
 			 * so choose the innermost or most recent one.
@@ -70,6 +75,8 @@
 				scstc &= ~(STC.STCconst | STC.STCimmutable | STC.STCmanifest);
 			if (stc & (STC.STCgshared | STC.STCshared | STC.STCtls))
 				scstc &= ~(STC.STCgshared | STC.STCshared | STC.STCtls);
+			if (stc & (STCsafe | STCtrusted | STCsystem))
+				scstc &= ~(STCsafe | STCtrusted | STCsystem);
 			scstc |= stc;
 
 			semanticNewSc(sc, scstc, sc.linkage, sc.protection, sc.explicitProtection, sc.structalign);
@@ -81,11 +88,11 @@
 		assert(false);
 	}
 
-    static void stcToCBuffer(OutBuffer buf, int stc)
+    static void stcToCBuffer(OutBuffer buf, StorageClass stc)
 	{
 		struct SCstring
 		{
-			int stc;
+			StorageClass stc;
 			TOK tok;
 		};
 
@@ -113,6 +120,9 @@
 ///			{ STCref,          TOKref },
 ///			{ STCtls,          TOKtls },
 ///			{ STCgshared,      TOKgshared },
+///			{ STCproperty,     TOKat },
+///			{ STCsafe,         TOKat },
+///			{ STCtrusted,      TOKat },
 ///		}
 		];
 
@@ -120,7 +130,22 @@
 		{
 			if (stc & table[i].stc)
 			{
-				buf.writestring(Token.toChars(table[i].tok));
+				enum TOK tok = table[i].tok;
+				if (tok == TOKat)
+				{	Identifier id;
+
+					if (stc & STCproperty)
+						id = Id.property;
+					else if (stc & STCsafe)
+						id = Id.safe;
+					else if (stc & STCtrusted)
+						id = Id.trusted;
+					else
+						assert(0);
+					buf.writestring(id.toChars());
+				}
+				else
+					buf.writestring(Token.toChars(tok));
 				buf.writeByte(' ');
 			}
 		}
--- a/dmd/String.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/String.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.String;
 
+import dmd.common;
 import dmd.Array;
 
 import core.stdc.string : strlen;
--- a/dmd/StringEntry.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/StringEntry.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.StringEntry;
 
+import dmd.common;
 import dmd.StringValue;
 import dmd.Dchar;
 import dmd.Lstring;
--- a/dmd/StringExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/StringExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.StringExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.backend.elem;
 import dmd.InterState;
@@ -107,7 +108,7 @@
 				case 'd':
 					for (u = 0; u < len;)
 					{
-						p = utf_decodeChar(cast(string)string_[0..len], &u, &c);
+						p = utf_decodeChar((cast(char*)string_)[0..len], &u, &c);
 						if (p !is null)
 						{	
 							error("%s", p);
@@ -131,7 +132,7 @@
 				case 'w':
 					for (u = 0; u < len;)
 					{
-						p = utf_decodeChar(cast(string)string_[0..len], &u, &c);
+						p = utf_decodeChar((cast(char*)string_)[0..len], &u, &c);
 						if (p !is null)
 						{	
 							error("%s", p);
@@ -190,7 +191,7 @@
 		case 1:
 			for (size_t u = 0; u < len;)
 			{
-				p = utf_decodeChar(cast(string)string_[0..len], &u, &c);
+				p = utf_decodeChar((cast(char*)string_)[0..len], &u, &c);
 				if (p)
 				{   
 					error("%s", p);
@@ -204,7 +205,7 @@
 		case 2:
 			for (size_t u = 0; u < len;)
 			{
-				p = utf_decodeWchar(cast(wstring)string_[0..len], &u, &c);
+				p = utf_decodeWchar((cast(wchar*)string_)[0..len], &u, &c);
 				if (p)
 				{   error("%s", p);
 					break;
@@ -445,7 +446,7 @@
 					for (size_t u = 0; u < len;)
 					{	
 						dchar c;
-						string p = utf_decodeChar(cast(string)se.string_[0..len], &u, &c);
+						string p = utf_decodeChar((cast(char*)se.string_)[0..len], &u, &c);
 						if (p !is null)
 							error("%s", p);
 						else
@@ -459,7 +460,7 @@
 					for (size_t u = 0; u < len;)
 					{	
 						dchar c;
-						string p = utf_decodeChar(cast(string)se.string_[0..len], &u, &c);
+						string p = utf_decodeChar((cast(char*)se.string_)[0..len], &u, &c);
 						if (p !is null)
 							error("%s", p);
 						buffer.write4(c);
@@ -472,7 +473,7 @@
 					for (size_t u = 0; u < len;)
 					{	
 						dchar c;
-						string p = utf_decodeWchar(cast(wstring)se.string_[0..len], &u, &c);
+						string p = utf_decodeWchar((cast(wchar*)se.string_)[0..len], &u, &c);
 						if (p)
 							error("%s", p);
 						else
@@ -486,7 +487,7 @@
 					for (size_t u = 0; u < len;)
 					{	
 						dchar c;
-						string p = utf_decodeWchar(cast(wstring)se.string_[0..len], &u, &c);
+						string p = utf_decodeWchar((cast(wchar*)se.string_)[0..len], &u, &c);
 						if (p)
 							error("%s", p);
 						buffer.write4(c);
@@ -732,7 +733,7 @@
 		    m = 'w';
 		    for (u = 0; u < len; )
 		    {
-			p = utf_decodeWchar(cast(wstring)string_[0..len], &u, &c);
+			p = utf_decodeWchar((cast(wchar*)string_)[0..len], &u, &c);
 			if (p)
 			    error("%s", p);
 			else
@@ -830,13 +831,12 @@
 		}
 		else if (tb.ty == TY.Tsarray)
 		{
-			Symbol *si;
 			dt_t *dt = null;
 
 			toDt(&dt);
 			dtnzeros(&dt, sz);		// leave terminating 0
 
-			si = symbol_generate(SC.SCstatic,type_allocn(TYM.TYarray, tschar));
+			Symbol* si = symbol_generate(SC.SCstatic,type_allocn(TYM.TYarray, tschar));
 			si.Sdt = dt;
 			si.Sfl = FL.FLdata;
 
@@ -846,6 +846,7 @@
 			outdata(si);
 
 			e = el_var(si);
+			e.Enumbytes = len * sz;
 		}
 		else if (tb.ty == TY.Tpointer)
 		{
--- a/dmd/StringTable.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/StringTable.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.StringTable;
 
+import dmd.common;
 import dmd.StringValue;
 import dmd.StringEntry;
 import dmd.Dchar;
--- a/dmd/StringValue.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/StringValue.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.StringValue;
 
+import dmd.common;
 import dmd.Lstring;
 import dmd.Dchar;
 
--- a/dmd/StructDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/StructDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.StructDeclaration;
 
+import dmd.common;
 import dmd.AggregateDeclaration;
 import dmd.FuncDeclaration;
 import dmd.DeclarationExp;
@@ -22,7 +23,7 @@
 import dmd.ThisExp;
 import dmd.ThisDeclaration;
 import dmd.TypeFunction;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.Id;
 import dmd.TY;
 import dmd.LINK;
@@ -52,6 +53,10 @@
 import dmd.NewDeclaration;
 import dmd.DeleteDeclaration;
 import dmd.Global;
+import dmd.MOD;
+import dmd.IntegerExp;
+import dmd.EqualExp;
+import dmd.AndAndExp;
 
 import dmd.backend.dt_t;
 import dmd.backend.Util;
@@ -60,6 +65,8 @@
 import dmd.backend.FL;
 import dmd.backend.glue;
 
+import std.stdio;
+
 class StructDeclaration : AggregateDeclaration
 {
     bool zeroInit;		// true if initialize with 0 fill
@@ -67,6 +74,7 @@
 version (DMDV2) {
     int hasIdentityAssign;	// !=0 if has identity opAssign
     FuncDeclaration cpctor;	// generated copy-constructor, if any
+    FuncDeclaration eq;	// bool opEquals(ref const T), if any
 
     FuncDeclarations postblits;	// Array of postblit functions
     FuncDeclaration postblit;	// aggregate postblit
@@ -98,17 +106,22 @@
 	{
 		Scope sc2;
 
-		//printf("+StructDeclaration.semantic(this=%p, '%s')\n", this, toChars());
+		//writef("+StructDeclaration.semantic(this=%p, '%s', sizeok = %d)\n", this, toChars(), sizeok);
 
-		//static int count; if (++count == 20) *(char*)0=0;
+		//static int count; if (++count == 20) halt();
 
 		assert(type);
 		if (!members)			// if forward reference
 		return;
 
-		if (symtab)
-		{   if (!scope_)
+		if (sizeok == 1 || symtab)
+		{
+			if (!scope_)
+			{
+				// writef("already completed\n");
+				scope_ = null;
 				return;             // semantic() already completed
+			}
 		}
 		else
 			symtab = new DsymbolTable();
@@ -199,28 +212,57 @@
 		sc2.protection = PROT.PROTpublic;
 		sc2.explicitProtection = 0;
 
-		int members_dim = members.dim;
+
+        /* Set scope so if there are forward references, we still might be able to
+         * resolve individual members like enums.
+         */
+        foreach (s; members)
+        {
+	        /* There are problems doing this in the general case because
+	         * Scope keeps track of things like 'offset'
+	         */
+	        if (s.isEnumDeclaration() || (s.isAggregateDeclaration() && s.ident))
+	        {
+	            //printf("setScope %s %s\n", s->kind(), s->toChars());
+	            s.setScope(sc2);
+	        }
+        }
+
 		foreach(Dsymbol s; members)
 		{
-		s.semantic(sc2);
-		if (isUnionDeclaration())
-			sc2.offset = 0;
+			s.semantic(sc2);
+			if (isUnionDeclaration())
+				sc2.offset = 0;
 static if (false) {
-		if (sizeok == 2)
-		{   //printf("forward reference\n");
-			break;
-		}
+			if (sizeok == 2)
+			{   //printf("forward reference\n");
+				break;
+			}
 }
-		Type t;
-		if (s.isDeclaration() &&
-			(t = s.isDeclaration().type) !is null &&
-			t.toBasetype().ty == TY.Tstruct)
-		{   StructDeclaration sd = cast(StructDeclaration)t.toDsymbol(sc);
-			if (sd.isnested)
-			error("inner struct %s cannot be a field", sd.toChars());
-		}
+			if (auto d = s.isDeclaration())
+			{   
+				if (auto t = d.type) {
+					if (t.toBasetype().ty == TY.Tstruct) {
+						auto ad = t.toDsymbol(sc).isThis();
+						/*
+						StructDeclaration sd = cast(StructDeclaration)foo;
+						if (foo && !sd) {
+							writeln(t.classin);
+							writeln(foo.classinfo.name);
+							assert(false);
+						}
+						*/
+						if (ad && ad.isnested)
+							error("inner struct %s cannot be a field", ad.toChars());
+					}
+				}
+			}
 		}
 
+version(DMDV1) {
+        /* This doesn't work for DMDV2 because (ref S) and (S) parameter
+         * lists will overload the same.
+         */
 		/* 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
@@ -230,22 +272,22 @@
 
 		TypeFunction tfeqptr;
 		{
-		Arguments arguments = new Arguments;
-		Argument arg = new Argument(STC.STCin, handle, Id.p, null);
+			auto arguments = new Parameters;
+			auto arg = new Parameter(STC.STCin, handle, Id.p, null);
 
-		arguments.push(cast(void*)arg);
-		tfeqptr = new TypeFunction(arguments, Type.tint32, 0, LINK.LINKd);
-		tfeqptr = cast(TypeFunction)tfeqptr.semantic(Loc(0), sc);
+			arguments.push(arg);
+			tfeqptr = new TypeFunction(arguments, Type.tint32, 0, LINK.LINKd);
+			tfeqptr = cast(TypeFunction)tfeqptr.semantic(Loc(0), sc);
 		}
 
 		TypeFunction tfeq;
 		{
-		Arguments arguments = new Arguments;
-		Argument arg = new Argument(STC.STCin, type, null, null);
+			auto arguments = new Parameters;
+			auto arg = new Parameter(STC.STCin, type, null, null);
 
-		arguments.push(cast(void*)arg);
-		tfeq = new TypeFunction(arguments, Type.tint32, 0, LINK.LINKd);
-		tfeq = cast(TypeFunction)tfeq.semantic(Loc(0), sc);
+			arguments.push(arg);
+			tfeq = new TypeFunction(arguments, Type.tint32, 0, LINK.LINKd);
+			tfeq = cast(TypeFunction)tfeq.semantic(Loc(0), sc);
 		}
 
 		Identifier id = Id.eq;
@@ -278,7 +320,39 @@
 
 			id = Id.cmp;
 		}
+}
 version (DMDV2) {
+        /* Try to find the opEquals function. Build it if necessary.
+         */
+        TypeFunction tfeqptr;
+        {   // bool opEquals(const T*) const;
+            auto parameters = new Parameters;
+version(STRUCTTHISREF) {
+            // bool opEquals(ref const T) const;
+            auto param = new Parameter(STC.STCref, type.constOf(), null, null);
+} else {
+            // bool opEquals(const T*) const;
+            auto param = new Parameter(STC.STCin, type.pointerTo(), null, null);
+}
+
+            parameters.push(param);
+            tfeqptr = new TypeFunction(parameters, Type.tbool, 0, LINK.LINKd);
+            tfeqptr.mod = MOD.MODconst;
+            tfeqptr = cast(TypeFunction)(tfeqptr.semantic(Loc(0), sc2));
+
+	        Dsymbol s = search_function(this, Id.eq);
+	        FuncDeclaration fdx = s ? s.isFuncDeclaration() : null;
+	        if (fdx)
+	        {
+	            eq = fdx.overloadExactMatch(tfeqptr);
+	            if (!eq)
+		            fdx.error("type signature should be %s not %s", tfeqptr.toChars(), fdx.type.toChars());
+	        }
+
+	        if (!eq)
+	            eq = buildOpEquals(sc2);
+        }
+
 		dtor = buildDtor(sc2);
 		postblit = buildPostBlit(sc2);
 		cpctor = buildCpCtor(sc2);
@@ -298,7 +372,7 @@
 		scope_ = scx ? scx : sc.clone();
 		scope_.setNoFree();
 		scope_.module_.addDeferredSemantic(this);
-		//printf("\tdeferring %s\n", toChars());
+		writef("\tdeferring %s\n", toChars());
 		return;
 		}
 
@@ -358,6 +432,22 @@
 		}
 	}
 	
+    Dsymbol search(Loc loc, Identifier ident, int flags)
+    {
+        //printf("%s.StructDeclaration::search('%s')\n", toChars(), ident->toChars());
+
+        if (scope_)
+    	    semantic(scope_);
+
+        if (!members || !symtab)
+        {
+    	    error("is forward referenced when looking for '%s'", ident.toChars());
+	        return null;
+        }
+
+        return ScopeDsymbol.search(loc, ident, flags);
+    }
+
     override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
 	{
 		assert(false);
@@ -373,7 +463,17 @@
 	{
 		assert(false);
 	}
-	
+
+version(DMDV1)
+{
+    Expression cloneMembers()
+	{
+		assert(false);
+	}
+}
+
+version(DMDV2)
+{
 	/*******************************************
 	 * We need an opAssign for the struct if
 	 * it has a destructor or a postblit.
@@ -423,6 +523,46 @@
 		return true;
 	}
 	
+	/*******************************************
+	* We need an opEquals for the struct if
+	* any fields has an opEquals.
+	* Generate one if a user-specified one does not exist.
+	*/
+	bool needOpEquals()
+	{
+		enum X = 0;
+static if (X) printf("StructDeclaration::needOpEquals() %s\n", toChars());
+
+		/* If any of the fields has an opEquals, then we
+		 * need it too.
+		 */
+		foreach (s; fields)
+		{
+		VarDeclaration v = s.isVarDeclaration();
+		assert(v && v.storage_class & STC.STCfield);
+		if (v.storage_class & STC.STCref)
+			continue;
+		Type tv = v.type.toBasetype();
+		while (tv.ty == Tsarray)
+		{   auto ta = cast(TypeSArray)tv;
+			tv = tv.nextOf().toBasetype();
+		}
+		if (tv.ty == Tstruct)
+		{   auto ts = cast(TypeStruct)tv;
+			StructDeclaration sd = ts.sym;
+			if (sd.eq)
+			goto Lneed;
+		}
+		}
+	Ldontneed:
+static if (X) printf("\tdontneed\n");
+		return false;
+
+	Lneed:
+static if (X) printf("\tneed\n");
+		return true;
+	}
+	
 	/******************************************
 	 * Build opAssign for struct.
 	 *	S* opAssign(S s) { ... }
@@ -436,9 +576,9 @@
 
 		FuncDeclaration fop = null;
 
-		Argument param = new Argument(STC.STCnodtor, type, Id.p, null);
-		Arguments fparams = new Arguments;
-		fparams.push(cast(void*)param);
+		auto param = new Parameter(STC.STCnodtor, type, Id.p, null);
+		auto fparams = new Parameters;
+		fparams.push(param);
 		Type ftype = new TypeFunction(fparams, handle, false, LINK.LINKd);
 version (STRUCTTHISREF) {
 		(cast(TypeFunction)ftype).isref = 1;
@@ -530,6 +670,72 @@
 		return fop;
 	}
 	
+	/******************************************
+	 * Build opEquals for struct.
+	 *	const bool opEquals(const ref S s) { ... }
+	 */
+	FuncDeclaration buildOpEquals(Scope sc)
+	{
+		if (!needOpEquals())
+		return null;
+		//printf("StructDeclaration::buildOpEquals() %s\n", toChars());
+		Loc loc = this.loc;
+
+		auto parameters = new Parameters;
+version (STRUCTTHISREF) {
+		// bool opEquals(ref const T) const;
+		auto param = new Parameter(STC.STCref, type.constOf(), Id.p, null);
+} else {
+		// bool opEquals(const T*) const;
+		auto param = new Parameter(STC.STCin, type.pointerTo(), Id.p, null);
+}
+
+		parameters.push(param);
+		auto ftype = new TypeFunction(parameters, Type.tbool, 0, LINKd);
+		ftype.mod = MOD.MODconst;
+		ftype = cast(TypeFunction)ftype.semantic(loc, sc);
+
+		auto fop = new FuncDeclaration(loc, Loc(0), Id.eq, STC.STCundefined, ftype);
+
+		Expression e = null;
+		/* Do memberwise compare
+		 */
+		//printf("\tmemberwise compare\n");
+		foreach (s; fields)
+		{
+		VarDeclaration v = s.isVarDeclaration();
+		assert(v && v.storage_class & STC.STCfield);
+		if (v.storage_class & STC.STCref)
+			assert(0);			// what should we do with this?
+		// this.v == s.v;
+		auto ec = new EqualExp(TOKequal, loc,
+			new DotVarExp(loc, new ThisExp(loc), v, 0),
+			new DotVarExp(loc, new IdentifierExp(loc, Id.p), v, 0));
+		if (e)
+			e = new AndAndExp(loc, e, ec);
+		else
+			e = ec;
+		}
+		if (!e)
+		e = new IntegerExp(loc, 1, Type.tbool);
+		fop.fbody = new ReturnStatement(loc, e);
+
+		members.push(fop);
+		fop.addMember(sc, this, 1);
+
+		sc = sc.push();
+		sc.stc = STCundefined;
+		sc.linkage = LINK.LINKd;
+
+		fop.semantic(sc);
+
+		sc.pop();
+
+		//printf("-StructDeclaration::buildOpEquals() %s\n", toChars());
+
+		return fop;
+	}
+
 	/*****************************************
 	 * Create inclusive postblit for struct by aggregating
 	 * all the postblits in postblits[] with the postblits for
@@ -649,46 +855,46 @@
 		 */
 		if (postblit)
 		{
-		//printf("generating cpctor\n");
+			//printf("generating cpctor\n");
 
-		Argument param = new Argument(STC.STCref, type, Id.p, null);
-		Arguments fparams = new Arguments;
-		fparams.push(cast(void*)param);
-		Type ftype = new TypeFunction(fparams, Type.tvoid, false, LINK.LINKd);
+		        auto param = new Parameter(STC.STCref, type, Id.p, null);
+		        auto fparams = new Parameters;
+			fparams.push(param);
+			Type ftype = new TypeFunction(fparams, Type.tvoid, false, LINK.LINKd);
 
-		fcp = new FuncDeclaration(Loc(0), Loc(0), Id.cpctor, STC.STCundefined, ftype);
+			fcp = new FuncDeclaration(Loc(0), Loc(0), Id.cpctor, STC.STCundefined, ftype);
 
-		// Build *this = p;
-		Expression e = new ThisExp(Loc(0));
+			// Build *this = p;
+			Expression e = new ThisExp(Loc(0));
 version (STRUCTTHISREF) {
 } else {
-		e = new PtrExp(Loc(0), e);
+			e = new PtrExp(Loc(0), e);
 }
-		AssignExp ea = new AssignExp(Loc(0), e, new IdentifierExp(Loc(0), Id.p));
-		ea.op = TOK.TOKblit;
-		Statement s = new ExpStatement(Loc(0), ea);
+			AssignExp ea = new AssignExp(Loc(0), e, new IdentifierExp(Loc(0), Id.p));
+			ea.op = TOK.TOKblit;
+			Statement s = new ExpStatement(Loc(0), ea);
 
-		// Build postBlit();
-		e = new VarExp(Loc(0), postblit, 0);
-		e = new CallExp(Loc(0), e);
+			// Build postBlit();
+			e = new VarExp(Loc(0), postblit, 0);
+			e = new CallExp(Loc(0), e);
 
-		s = new CompoundStatement(Loc(0), s, new ExpStatement(Loc(0), e));
-		fcp.fbody = s;
+			s = new CompoundStatement(Loc(0), s, new ExpStatement(Loc(0), e));
+			fcp.fbody = s;
 
-		members.push(fcp);
+			members.push(fcp);
 
-		sc = sc.push();
-		sc.stc = STC.STCundefined;
-		sc.linkage = LINK.LINKd;
+			sc = sc.push();
+			sc.stc = STC.STCundefined;
+			sc.linkage = LINK.LINKd;
 
-		fcp.semantic(sc);
+			fcp.semantic(sc);
 
-		sc.pop();
+			sc.pop();
 		}
 
 		return fcp;
 	}
-	
+}
     override void toDocBuffer(OutBuffer buf)
 	{
 		assert(false);
--- a/dmd/StructInitializer.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/StructInitializer.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.StructInitializer;
 
+import dmd.common;
 import dmd.Initializer;
 import dmd.TOK;
 import dmd.TypeSArray;
@@ -35,7 +36,7 @@
     Identifiers field;	// of Identifier *'s
     Initializers value;	// parallel array of Initializer *'s
 
-    Array vars;		// parallel array of VarDeclaration *'s
+    VarDeclarations vars;		// parallel array of VarDeclaration *'s
     AggregateDeclaration ad;	// which aggregate this is for
 
     this(Loc loc)
@@ -46,23 +47,23 @@
 		field = new Identifiers();
 		value = new Initializers();
 		
-		vars = new Array();
+		vars = new VarDeclarations();
 	}
 	
     override Initializer syntaxCopy()
 	{
-		StructInitializer ai = new StructInitializer(loc);
+		auto ai = new StructInitializer(loc);
 
 		assert(field.dim == value.dim);
 		ai.field.setDim(field.dim);
 		ai.value.setDim(value.dim);
 		for (int i = 0; i < field.dim; i++)
 		{    
-			ai.field.data[i] = field.data[i];
+			ai.field[i] = field[i];
 
-			Initializer init = cast(Initializer)value.data[i];
+			auto init = value[i];
 			init = init.syntaxCopy();
-			ai.value.data[i] = cast(void*)init;
+			ai.value[i] = init;
 		}
 
 		return ai;
@@ -71,13 +72,12 @@
     void addInit(Identifier field, Initializer value)
 	{
 		//printf("StructInitializer.addInit(field = %p, value = %p)\n", field, value);
-		this.field.push(cast(void*)field);
-		this.value.push(cast(void*)value);
+		this.field.push(field);
+		this.value.push(value);
 	}
 	
     override Initializer semantic(Scope sc, Type t)
 	{
-		TypeStruct ts;
 		int errors = 0;
 
 		//printf("StructInitializer.semantic(t = %s) %s\n", t.toChars(), toChars());
@@ -85,15 +85,17 @@
 		t = t.toBasetype();
 		if (t.ty == Tstruct)
 		{	
-			uint i;
 			uint fieldi = 0;
 
-			ts = cast(TypeStruct)t;
+			auto ts = cast(TypeStruct)t;
 			ad = ts.sym;
-			for (i = 0; i < field.dim; i++)
+	        if (ad.ctor)
+	            error("%s %s has constructors, cannot use { initializers }, use %s( initializers ) instead",
+		        ad.kind(), ad.toChars(), ad.toChars());
+			for (size_t i = 0; i < field.dim; i++)
 			{
-				Identifier id = cast(Identifier)field.data[i];
-				Initializer val = cast(Initializer)value.data[i];
+				Identifier id = field[i];
+				Initializer val = value[i];
 				Dsymbol s;
 				VarDeclaration v;
 
@@ -136,8 +138,8 @@
 				if (s && (v = s.isVarDeclaration()) !is null)
 				{
 					val = val.semantic(sc, v.type);
-					value.data[i] = cast(void*)val;
-					vars.data[i] = cast(void*)v;
+					value[i] = val;
+					vars[i] = v;
 				}
 				else
 				{
@@ -151,7 +153,7 @@
 		{	
 			/* Rewrite as empty delegate literal { }
 			 */
-			Arguments arguments = new Arguments;
+			auto arguments = new Parameters;
 			Type tf = new TypeFunction(arguments, null, 0, LINK.LINKd);
 			FuncLiteralDeclaration fd = new FuncLiteralDeclaration(loc, Loc(0), tf, TOK.TOKdelegate, null);
 			fd.fbody = new CompoundStatement(loc, new Statements());
@@ -194,9 +196,9 @@
 		Expressions elements = new Expressions();
 		for (size_t i = 0; i < value.dim; i++)
 		{
-			if (field.data[i])
+			if (field[i])
 				goto Lno;
-			Initializer iz = cast(Initializer)value.data[i];
+			Initializer iz = value[i];
 			if (!iz)
 				goto Lno;
 			Expression ex = iz.toExpression();
@@ -221,7 +223,7 @@
 
     override dt_t* toDt()
 	{
-		scope Array dts = new Array();
+		scope dts = new Vector!(dt_t*);
 		uint i;
 		uint j;
 		dt_t* dt;
@@ -235,8 +237,8 @@
 
 		for (i = 0; i < vars.dim; i++)
 		{
-			VarDeclaration v = cast(VarDeclaration)vars.data[i];
-			Initializer val = cast(Initializer)value.data[i];
+			VarDeclaration v = vars[i];
+			Initializer val = value[i];
 
 			//printf("vars[%d] = %s\n", i, v.toChars());
 
@@ -246,9 +248,9 @@
 				//printf(" adfield[%d] = %s\n", j, ((VarDeclaration *)ad.fields[j]).toChars());
 				if (cast(VarDeclaration)ad.fields[j] == v) // TODO: check if 'is' needs to be used here
 				{
-					if (dts.data[j])
+					if (dts[j])
 						error(loc, "field %s of %s already initialized", v.toChars(), ad.toChars());
-					dts.data[j] = cast(void*)val.toDt();
+					dts[j] = val.toDt();
 					break;
 				}
 			}
@@ -259,9 +261,9 @@
 		offset = 0;
 		for (j = 0; j < dts.dim; j++)
 		{
-			VarDeclaration v = cast(VarDeclaration)ad.fields[j];
+			VarDeclaration v = ad.fields[j];
 
-			d = cast(dt_t*)dts.data[j];
+			d = dts[j];
 			if (!d)
 			{   
 				// An instance specific initializer was not provided.
@@ -284,9 +286,9 @@
 							v.type.toDt(&d);
 							break;
 						}
-						VarDeclaration v2 = cast(VarDeclaration)ad.fields[k];
+						VarDeclaration v2 = ad.fields[k];
 
-						if (v2.offset < offset2 && dts.data[k])
+						if (v2.offset < offset2 && dts[k])
 							break;			// overlap
 					}
 				}
--- a/dmd/StructLiteralExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/StructLiteralExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,11 +1,14 @@
 module dmd.StructLiteralExp;
 
+import dmd.common;
 import dmd.Expression;
+import dmd.GlobalExpressions;
 import dmd.MOD;
 import dmd.TypeStruct;
 import dmd.TypeSArray;
 import dmd.expression.Util;
 import dmd.ErrorExp;
+import dmd.Array;
 import dmd.Dsymbol;
 import dmd.VarDeclaration;
 import dmd.StructDeclaration;
@@ -20,6 +23,7 @@
 import dmd.OutBuffer;
 import dmd.Loc;
 import dmd.Scope;
+import dmd.Initializer;
 import dmd.InlineCostState;
 import dmd.IRState;
 import dmd.InlineDoState;
@@ -61,7 +65,7 @@
 
 	override Expression syntaxCopy()
 	{
-		assert(false);
+		return new StructLiteralExp(loc, sd, arraySyntaxCopy(elements));
 	}
 
 	override Expression semantic(Scope sc)
@@ -138,12 +142,22 @@
 				{   
 					e = v.init.toExpression();
 					if (!e)
+					{
 						error("cannot make expression out of initializer for %s", v.toChars());
+						e = new ErrorExp();
+					}
+					else if (v.scope_)
+					{
+						// Do deferred semantic anaylsis
+						Initializer i2 = v.init.syntaxCopy();
+						i2 = i2.semantic(v.scope_, v.type);
+						e = i2.toExpression();
+						v.scope_ = null;
+					}
 				}
 				else
 				{	
-					e = v.type.defaultInit(Loc(0));
-					e.loc = loc;
+					e = v.type.defaultInitLiteral(loc);
 				}
 				offset = v.offset + cast(uint)v.type.size();
 			}
@@ -154,6 +168,10 @@
 		return this;
 	}
 
+	/**************************************
+	 * Gets expression at offset of type.
+	 * Returns null if not found.
+	 */
 	Expression getField(Type type, uint offset)
 	{
 		//printf("StructLiteralExp.getField(this = %s, type = %s, offset = %u)\n",
@@ -442,12 +460,163 @@
 
 	override Expression interpret(InterState istate)
 	{
-		assert(false);
+		Expressions expsx = null;
+
+version (LOG) {
+		printf("StructLiteralExp.interpret() %.*s\n", toChars());
+}
+		/* We don't know how to deal with overlapping fields
+		 */
+		if (sd.hasUnions)
+		{   
+			error("Unions with overlapping fields are not yet supported in CTFE");
+			return EXP_CANT_INTERPRET;
+		}
+
+		if (elements)
+		{
+			foreach (size_t i, Expression e; elements)
+			{   
+				if (!e)
+					continue;
+
+				Expression ex = e.interpret(istate);
+				if (ex is EXP_CANT_INTERPRET)
+				{   
+					delete expsx;
+					return EXP_CANT_INTERPRET;
+				}
+
+				/* If any changes, do Copy On Write
+				 */
+				if (ex != e)
+				{
+					if (!expsx)
+					{   
+						expsx = new Expressions();
+						expsx.setDim(elements.dim);
+						for (size_t j = 0; j < elements.dim; j++)
+						{
+							expsx[j] = elements[j];
+						}
+					}
+					expsx[i] = ex;
+				}
+			}
+		}
+		if (elements && expsx)
+		{
+			expandTuples(expsx);
+			if (expsx.dim != elements.dim)
+			{   
+				delete expsx;
+				return EXP_CANT_INTERPRET;
+			}
+			StructLiteralExp se = new StructLiteralExp(loc, sd, expsx);
+			se.type = type;
+			return se;
+		}
+		return this;
 	}
 
 	override dt_t** toDt(dt_t** pdt)
 	{
-		assert(false);
+		Array dts;
+		dt_t *dt;
+		dt_t *d;
+		uint offset;
+
+		//printf("StructLiteralExp.toDt() %s)\n", toChars());
+		dts.setDim(sd.fields.dim);
+		dts.zero();
+		assert(elements.dim <= sd.fields.dim);
+
+		foreach (uint i, Expression e; elements)
+		{
+			if (!e)
+				continue;
+
+			dt = null;
+			e.toDt(&dt);
+			dts.data[i] = dt;
+		}
+
+		offset = 0;
+		foreach (uint j, VarDeclaration v; sd.fields)
+		{
+			d = cast(dt_t*)dts.data[j];
+			if (!d)
+			{   // An instance specific initializer was not provided.
+				// Look to see if there's a default initializer from the
+				// struct definition
+				if (v.init)
+				{
+					d = v.init.toDt();
+				}
+				else if (v.offset >= offset)
+				{
+					uint k;
+					uint offset2 = v.offset + cast(uint)v.type.size();
+					// Make sure this field (v) does not overlap any explicitly
+					// initialized field.
+					for (k = j + 1; 1; k++)
+					{
+						if (k == dts.dim)		// didn't find any overlap
+						{
+							v.type.toDt(&d);
+							break;
+						}
+						VarDeclaration v2 = sd.fields[k];
+
+						if (v2.offset < offset2 && dts.data[k])
+							break;			// overlap
+					}
+				}
+			}
+			if (d)
+			{
+				if (v.offset < offset)
+					error("duplicate union initialization for %s", v.toChars());
+				else
+				{	
+					uint sz = dt_size(d);
+					uint vsz = cast(uint)v.type.size();
+					uint voffset = v.offset;
+					assert(sz <= vsz);
+
+					uint dim = 1;
+					for (Type vt = v.type.toBasetype(); vt.ty == Tsarray; vt = vt.nextOf().toBasetype())
+					{   
+						TypeSArray tsa = cast(TypeSArray)vt;
+						dim *= tsa.dim.toInteger();
+					}
+
+					for (size_t i = 0; i < dim; i++)
+					{
+						if (offset < voffset)
+							pdt = dtnzeros(pdt, voffset - offset);
+						if (!d)
+						{
+							if (v.init)
+								d = v.init.toDt();
+							else
+								v.type.toDt(&d);
+						}
+						pdt = dtcat(pdt, d);
+						d = null;
+						offset = voffset + sz;
+						voffset += vsz / dim;
+						if (sz == vsz)
+							break;
+					}
+				}
+			}
+		}
+		
+		if (offset < sd.structsize)
+			pdt = dtnzeros(pdt, sd.structsize - offset);
+
+		return pdt;
 	}
 
 version(DMDV2)
@@ -490,7 +659,7 @@
 					te = te.mutableOf();
 				else
 				{	
-					assert(t.mod == MODinvariant);
+					assert(t.mod == MODimmutable);
 					te = te.invariantOf();
 				}
 				MATCH m2 = e.implicitConvTo(te);
--- a/dmd/SuperExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/SuperExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.SuperExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.OutBuffer;
 import dmd.Loc;
--- a/dmd/SwitchErrorStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/SwitchErrorStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.SwitchErrorStatement;
 
+import dmd.common;
 import dmd.Statement;
 import dmd.OutBuffer;
 import dmd.Loc;
--- a/dmd/SwitchStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/SwitchStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.SwitchStatement;
 
+import dmd.common;
 import dmd.Statement;
 import dmd.Expression;
 import dmd.DefaultStatement;
@@ -166,10 +167,10 @@
 			}
 
 			a.reserve(4);
-			a.push(cast(void*)body_);
-			a.push(cast(void*)new BreakStatement(loc, null));
+			a.push(body_);
+			a.push(new BreakStatement(loc, null));
 			sc.sw.sdefault = new DefaultStatement(loc, s);
-			a.push(cast(void*)sc.sw.sdefault);
+			a.push(sc.sw.sdefault);
 			cs = new CompoundStatement(loc, a);
 			body_ = cs;
 		}
@@ -411,7 +412,7 @@
 		block_appendexp(mystate.switchBlock, econd);
 		block_next(blx,BCswitch,null);
 
-		/// 
+        // Corresponding free is in block_free
 		targ_llong* pu = cast(targ_llong*) malloc(targ_llong.sizeof * (numcases + 1));
 		mystate.switchBlock.Bswitch = pu;
 		/* First pair is the number of cases, and the default block
--- a/dmd/SymOffExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/SymOffExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.SymOffExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Declaration;
 import dmd.MATCH;
@@ -19,6 +20,7 @@
 import dmd.ErrorExp;
 import dmd.TY;
 import dmd.TOK;
+import dmd.STC;
 
 import dmd.backend.Symbol;
 import dmd.backend.Util;
@@ -57,8 +59,15 @@
 		VarDeclaration v = var.isVarDeclaration();
 		if (v)
 		{
-			if (!v.isDataseg())
-				error("escaping reference to local variable %s", v.toChars());
+			if (!v.isDataseg() && !(v.storage_class & (STC.STCref | STC.STCout)))
+			{   /* BUG: This should be allowed:
+				 *   void foo()
+				 *   { int a;
+				 *     int* bar() { return &a; }
+				 *   }
+				 */
+				error("escaping reference to local %s", v.toChars());
+			}
 		}
 	}
 
@@ -74,7 +83,7 @@
 
 	override bool isBool(bool result)
 	{
-		assert(false);
+		return result;
 	}
 
 	override Expression doInline(InlineDoState ids)
@@ -229,5 +238,13 @@
 		Symbol* s = var.toSymbol();
 		return dtxoff(pdt, s, offset, TYnptr);
 	}
+
+static if (false)
+{
+	override elem* toElem(IRState* irs)
+	{
+		assert(false); // this function is #if 0'ed out in dmd
+	}
+}
 }
 
--- a/dmd/SymbolDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/SymbolDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.SymbolDeclaration;
 
+import dmd.common;
 import dmd.Declaration;
 import dmd.StructDeclaration;
 import dmd.Loc;
--- a/dmd/SymbolExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/SymbolExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.SymbolExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Declaration;
 import dmd.Loc;
@@ -19,6 +20,7 @@
 import dmd.backend.Util;
 import dmd.codegen.Util;
 
+version(DMDV2)
 class SymbolExp : Expression
 {
 	Declaration var;
@@ -97,7 +99,7 @@
 
 				if (op == TOK.TOKvar)
 					e = el_una(OPER.OPind, TYM.TYnptr, e);
-				if ((var.isParameter() && tb.ty == TY.Tsarray) || var.isOut() || var.isRef())
+				if (ISREF(var, tb))
 					e = el_una(OPER.OPind, s.ty(), e);
 				else if (op == TOK.TOKsymoff && nrvo)
 				{   
@@ -122,7 +124,7 @@
 				e.Enumbytes = cast(uint)type.size();
 				el_setLoc(e, loc);
 			}
-			if ((var.isParameter() && tb.ty == TY.Tsarray) || var.isOut() || var.isRef())
+			if (ISREF(var, tb))
 			{   
 				e.Ety = TYM.TYnptr;
 				e = el_una(OPER.OPind, s.ty(), e);
@@ -150,7 +152,7 @@
 			e = el_var(var.toImport());
 			e = el_una(OPER.OPind,s.ty(),e);
 		}
-		else if ((var.isParameter() && tb.ty == TY.Tsarray) || var.isOut() || var.isRef())
+		else if (ISREF(var, tb))
 		{	
 			// Static arrays are really passed as pointers to the array
 			// Out parameters are really references
--- a/dmd/SynchronizedStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/SynchronizedStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.SynchronizedStatement;
 
+import dmd.common;
 import dmd.Statement;
 import dmd.IntegerExp;
 import dmd.TypeSArray;
@@ -87,19 +88,19 @@
 			VarDeclaration tmp = new VarDeclaration(loc, exp.type, id, ie);
 
 			Statements cs = new Statements();
-			cs.push(cast(void*)new DeclarationStatement(loc, new DeclarationExp(loc, tmp)));
+			cs.push(new DeclarationStatement(loc, new DeclarationExp(loc, tmp)));
 
 			FuncDeclaration fdenter = FuncDeclaration.genCfunc(Type.tvoid, Id.monitorenter);
 			Expression e = new CallExp(loc, new VarExp(loc, fdenter), new VarExp(loc, tmp));
 			e.type = Type.tvoid;			// do not run semantic on e
-			cs.push(cast(void*)new ExpStatement(loc, e));
+			cs.push(new ExpStatement(loc, e));
 
 			FuncDeclaration fdexit = FuncDeclaration.genCfunc(Type.tvoid, Id.monitorexit);
 			e = new CallExp(loc, new VarExp(loc, fdexit), new VarExp(loc, tmp));
 			e.type = Type.tvoid;			// do not run semantic on e
 			Statement s = new ExpStatement(loc, e);
 			s = new TryFinallyStatement(loc, body_, s);
-			cs.push(cast(void*)s);
+			cs.push(s);
 
 			s = new CompoundStatement(loc, cs);
 			return s.semantic(sc);
@@ -119,14 +120,14 @@
 			tmp.storage_class |= STCgshared | STCstatic;
 
 			Statements cs = new Statements();
-			cs.push(cast(void*)new DeclarationStatement(loc, new DeclarationExp(loc, tmp)));
+			cs.push(new DeclarationStatement(loc, new DeclarationExp(loc, tmp)));
 
 			FuncDeclaration fdenter = FuncDeclaration.genCfunc(Type.tvoid, Id.criticalenter);
 			Expression e = new DotIdExp(loc, new VarExp(loc, tmp), Id.ptr);
 			e = e.semantic(sc);
 			e = new CallExp(loc, new VarExp(loc, fdenter), e);
 			e.type = Type.tvoid;			// do not run semantic on e
-			cs.push(cast(void*)new ExpStatement(loc, e));
+			cs.push(new ExpStatement(loc, e));
 
 			FuncDeclaration fdexit = FuncDeclaration.genCfunc(Type.tvoid, Id.criticalexit);
 			e = new DotIdExp(loc, new VarExp(loc, tmp), Id.ptr);
@@ -135,7 +136,7 @@
 			e.type = Type.tvoid;			// do not run semantic on e
 			Statement s = new ExpStatement(loc, e);
 			s = new TryFinallyStatement(loc, body_, s);
-			cs.push(cast(void*)s);
+			cs.push(s);
 
 			s = new CompoundStatement(loc, cs);
 			return s.semantic(sc);
--- a/dmd/TOK.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TOK.d	Tue Sep 14 15:46:50 2010 +0200
@@ -126,6 +126,8 @@
 		TOKfile,
 		TOKshared,
 		TOKat,
+	    TOKpow,
+	    TOKpowass,
 
 		TOKMAX
 	}
@@ -249,5 +251,7 @@
 	}
 }
 
+alias TOK.TOKinout TOKwild;
+
 import dmd.EnumUtils;
 mixin(BringToCurrentScope!(TOK));
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmd/TRUST.d	Tue Sep 14 15:46:50 2010 +0200
@@ -0,0 +1,12 @@
+module dmd.TRUST;
+
+enum TRUST
+{
+    TRUSTdefault = 0,
+    TRUSTsystem = 1,	// @system (same as TRUSTdefault)
+    TRUSTtrusted = 2,	// @trusted
+    TRUSTsafe = 3,	// @safe
+};
+
+import dmd.EnumUtils;
+mixin(BringToCurrentScope!(TRUST));
\ No newline at end of file
--- a/dmd/TemplateAliasParameter.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TemplateAliasParameter.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TemplateAliasParameter;
 
+import dmd.common;
 import dmd.TemplateParameter;
 import dmd.Loc;
 import dmd.Identifier;
@@ -110,7 +111,7 @@
 		Dsymbol sa = isDsymbol(oded);
 		assert(sa);
 
-		printf("\tArgument alias: %s\n", sa.toChars());
+		printf("Parameter alias: %s\n", sa.toChars());
 	}
 
 	override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
@@ -171,14 +172,14 @@
 		//printf("TemplateAliasParameter.matchArg()\n");
 
 		if (i < tiargs.dim)
-			oarg = cast(Object)tiargs.data[i];
+			oarg = tiargs[i];
 		else
 		{	// Get default argument instead
 			oarg = defaultArg(loc, sc);
 			if (!oarg)
 			{   assert(i < dedtypes.dim);
 				// It might have already been deduced
-				oarg = cast(Object)dedtypes.data[i];
+				oarg = dedtypes[i];
 				if (!oarg)
 					goto Lnomatch;
 			}
@@ -219,14 +220,14 @@
 				if (sa != specAlias)
 					goto Lnomatch;
 			}
-			else if (dedtypes.data[i])
+			else if (dedtypes[i])
 			{   // Must match already deduced symbol
-				Object s_ = cast(Object)dedtypes.data[i];
+				Object s_ = dedtypes[i];
 
 				if (!sa || s_ != sa)
 					goto Lnomatch;
 			}
-			dedtypes.data[i] = cast(void*)sa;
+			dedtypes[i] = sa;
 
 			s = isDsymbol(sa);
 			if (s)
@@ -250,7 +251,7 @@
 			return MATCHnomatch;
 	}
 
-	override void* dummyArg()
+	override Object dummyArg()
 	{
 		Object s;
 
@@ -261,6 +262,6 @@
 				sdummy = new Dsymbol();
 			s = sdummy;
 		}
-		return cast(void*)s;
+		return s;
 	}
 }
--- a/dmd/TemplateDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TemplateDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TemplateDeclaration;
 
+import dmd.common;
 import dmd.Loc;
 import dmd.ScopeDsymbol;
 import dmd.ArrayTypes;
@@ -18,7 +19,7 @@
 import dmd.TypeSArray;
 import dmd.StringExp;
 import dmd.TOK;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.CtorDeclaration;
 import dmd.TypeFunction;
 import dmd.TY;
@@ -41,6 +42,7 @@
 import dmd.VarDeclaration;
 import dmd.TemplateParameter;
 import dmd.TemplateTypeParameter;
+import dmd.MOD;
 
 import dmd.expression.Util;
 
@@ -53,73 +55,73 @@
 TemplateTupleParameter isVariadic(TemplateParameters parameters)
 {   
 	size_t dim = parameters.dim;
-    TemplateTupleParameter tp = null;
+	TemplateTupleParameter tp = null;
 
-    if (dim)
-		tp = (cast(TemplateParameter)parameters.data[dim - 1]).isTemplateTupleParameter();
+	if (dim)
+		tp = parameters[dim - 1].isTemplateTupleParameter();
 
-    return tp;
+	return tp;
 }
 
 void ObjectToCBuffer(OutBuffer buf, HdrGenState* hgs, Object oarg)
 {
-    //printf("ObjectToCBuffer()\n");
-    Type t = isType(oarg);
-    Expression e = isExpression(oarg);
-    Dsymbol s = isDsymbol(oarg);
-    Tuple v = isTuple(oarg);
-    if (t)
-    {	
+	//printf("ObjectToCBuffer()\n");
+	Type t = isType(oarg);
+	Expression e = isExpression(oarg);
+	Dsymbol s = isDsymbol(oarg);
+	Tuple v = isTuple(oarg);
+	if (t)
+	{	
 		//printf("\tt: %s ty = %d\n", t.toChars(), t.ty);
 		t.toCBuffer(buf, null, hgs);
-    }
-    else if (e)
+	}
+	else if (e)
 		e.toCBuffer(buf, hgs);
-    else if (s)
-    {
+	else if (s)
+	{
 		string p = s.ident ? s.ident.toChars() : s.toChars();
 		buf.writestring(p);
-    }
-    else if (v)
-    {
+	}
+	else if (v)
+	{
 		Objects args = v.objects;
 		for (size_t i = 0; i < args.dim; i++)
 		{
 			if (i)
 				buf.writeByte(',');
-			Object o = cast(Object)args.data[i];
+			Object o = args[i];
 			ObjectToCBuffer(buf, hgs, o);
 		}
-    }
-    else if (!oarg)
-    {
+	}
+	else if (!oarg)
+	{
 		buf.writestring("null");
-    }
-    else
-    {
+	}
+	else
+	{
 		debug writef("bad Object = %p\n", oarg);
 		assert(0);
-    }
+	}
 }
 
 class TemplateDeclaration : ScopeDsymbol
 {
-    TemplateParameters parameters;	// array of TemplateParameter's
+	TemplateParameters parameters;	// array of TemplateParameter's
 
-    TemplateParameters origParameters;	// originals for Ddoc
-    Expression constraint;
-    Array instances;			// array of TemplateInstance's
+	TemplateParameters origParameters;	// originals for Ddoc
+	Expression constraint;
+	Vector!TemplateInstance instances;			// array of TemplateInstance's
 
-    TemplateDeclaration overnext;	// next overloaded TemplateDeclaration
-    TemplateDeclaration overroot;	// first in overnext list
+	TemplateDeclaration overnext;	// next overloaded TemplateDeclaration
+	TemplateDeclaration overroot;	// first in overnext list
 
-    int semanticRun;			// 1 semantic() run
+	int semanticRun;			// 1 semantic() run
 
-    Dsymbol onemember;		// if !=NULL then one member of this template
+	Dsymbol onemember;		// if !=NULL then one member of this template
 
-    int literal;		// this template declaration is a literal
+	int literal;		// this template declaration is a literal
 
-    this(Loc loc, Identifier id, TemplateParameters parameters, Expression constraint, Dsymbols decldefs)
+	this(Loc loc, Identifier id, TemplateParameters parameters, Expression constraint, Dsymbols decldefs)
 	{	
 		super(id);
 		
@@ -147,10 +149,10 @@
 		this.constraint = constraint;
 		this.members = decldefs;
 		
-		instances = new Array();
+		instances = new Vector!TemplateInstance();
 	}
 
-    override Dsymbol syntaxCopy(Dsymbol)
+	override Dsymbol syntaxCopy(Dsymbol)
 	{
 		//printf("TemplateDeclaration.syntaxCopy()\n");
 		TemplateDeclaration td;
@@ -164,8 +166,8 @@
 			p.setDim(parameters.dim);
 			for (int i = 0; i < p.dim; i++)
 			{   
-				TemplateParameter tp = cast(TemplateParameter)parameters.data[i];
-				p.data[i] = cast(void*)tp.syntaxCopy();
+				auto tp = parameters[i];
+				p[i] = tp.syntaxCopy();
 			}
 		}
 		
@@ -177,7 +179,7 @@
 		return td;
 	}
 
-    override void semantic(Scope sc)
+	override void semantic(Scope sc)
 	{
 	version (LOG) {
 		printf("TemplateDeclaration.semantic(this = %p, id = '%s')\n", this, ident.toChars());
@@ -227,23 +229,19 @@
 		{
 			origParameters = new TemplateParameters();
 			origParameters.setDim(parameters.dim);
-			for (int i = 0; i < parameters.dim; i++)
+			foreach (size_t i, TemplateParameter tp; parameters)
 			{
-				TemplateParameter tp = cast(TemplateParameter)parameters.data[i];
-				origParameters.data[i] = cast(void*)tp.syntaxCopy();
+				origParameters[i] = tp.syntaxCopy();
 			}
 		}
 
-		for (int i = 0; i < parameters.dim; i++)
+		foreach (tp; parameters)
 		{
-			TemplateParameter tp = cast(TemplateParameter)parameters.data[i];
 			tp.declareParameter(paramscope);
 		}
 
-		for (int i = 0; i < parameters.dim; i++)
+		foreach (size_t i, TemplateParameter tp; parameters)
 		{
-			TemplateParameter tp = cast(TemplateParameter)parameters.data[i];
-
 			tp.semantic(paramscope);
 			if (i + 1 != parameters.dim && tp.isTemplateTupleParameter())
 				error("template tuple parameter must be last one");
@@ -273,7 +271,7 @@
 	 * Overload existing TemplateDeclaration 'this' with the new one 's'.
 	 * Return !=0 if successful; i.e. no conflict.
 	 */
-    override bool overloadInsert(Dsymbol s)
+	override bool overloadInsert(Dsymbol s)
 	{
 		TemplateDeclaration *pf;
 		TemplateDeclaration f;
@@ -323,9 +321,48 @@
 		return true;
 	}
 
-    override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
+	override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
 	{
-		assert(false);
+static if (false) // Should handle template functions
+{
+		if (onemember && onemember.isFuncDeclaration())
+			buf.writestring("foo ");
+}
+		buf.writestring(kind());
+		buf.writeByte(' ');
+		buf.writestring(ident.toChars());
+		buf.writeByte('(');
+		foreach (size_t i, TemplateParameter tp; parameters)
+		{
+			if (hgs.ddoc)
+				tp = origParameters[i];
+			if (i)
+				buf.writeByte(',');
+			tp.toCBuffer(buf, hgs);
+		}
+		buf.writeByte(')');
+version(DMDV2)
+{
+		if (constraint)
+		{   buf.writestring(" if (");
+			constraint.toCBuffer(buf, hgs);
+			buf.writeByte(')');
+		}
+}
+
+		if (hgs.hdrgen)
+		{
+			hgs.tpltMember++;
+			buf.writenl();
+			buf.writebyte('{');
+			buf.writenl();
+			foreach (Dsymbol s; members)
+				s.toCBuffer(buf, hgs);
+
+			buf.writebyte('}');
+			buf.writenl();
+			hgs.tpltMember--;
+		}
 	}
 
 	override void toJsonBuffer(OutBuffer buf)
@@ -359,14 +396,14 @@
 		buf.writestring("}\n");
 	}
 
-    override string kind()
+	override string kind()
 	{
 		return (onemember && onemember.isAggregateDeclaration())
 			? onemember.kind()
 			: "template";
 	}
 
-    override string toChars()
+	override string toChars()
 	{
 		OutBuffer buf = new OutBuffer();
 		HdrGenState hgs;
@@ -374,9 +411,8 @@
 		/// memset(&hgs, 0, hgs.sizeof);
 		buf.writestring(ident.toChars());
 		buf.writeByte('(');
-		for (int i = 0; i < parameters.dim; i++)
+		foreach (size_t i, TemplateParameter tp; parameters)
 		{
-			TemplateParameter tp = cast(TemplateParameter)parameters.data[i];
 			if (i)
 				buf.writeByte(',');
 			tp.toCBuffer(buf, &hgs);
@@ -394,12 +430,12 @@
 		return buf.extractString();
 	}
 
-    override void emitComment(Scope sc)
+	override void emitComment(Scope sc)
 	{
 		assert(false);
 	}
 	
-//    void toDocBuffer(OutBuffer *buf);
+//	void toDocBuffer(OutBuffer *buf);
 
 	/***************************************
 	 * Given that ti is an instance of this TemplateDeclaration,
@@ -412,7 +448,7 @@
 	 *	dedtypes	deduced arguments
 	 * Return match level.
 	 */
-    MATCH matchWithInstance(TemplateInstance ti, Objects dedtypes, int flag)
+	MATCH matchWithInstance(TemplateInstance ti, Objects dedtypes, int flag)
 	{
 		MATCH m;
 		int dedtypes_dim = dedtypes.dim;
@@ -455,7 +491,7 @@
 		for (int i = 0; i < dedtypes_dim; i++)
 		{	
 			MATCH m2;
-			TemplateParameter tp = cast(TemplateParameter)parameters.data[i];
+			auto tp = parameters[i];
 			Declaration sparam;
 
 			//printf("\targument [%d]\n", i);
@@ -497,10 +533,10 @@
 			 */
 			for (int i = 0; i < dedtypes_dim; i++)
 			{
-				if (!dedtypes.data[i])
+				if (!dedtypes[i])
 				{
 					assert(i < ti.tiargs.dim);
-					dedtypes.data[i] = ti.tiargs.data[i];
+					dedtypes[i] = ti.tiargs[i];
 				}
 			}
 		}
@@ -509,6 +545,7 @@
 		if (m && constraint && !(flag & 1))
 		{	/* Check to see if constraint is satisfied.
 			 */
+            makeParamNamesVisibleInConstraint(paramscope);
 			Expression e = constraint.syntaxCopy();
 			paramscope.flags |= SCOPE.SCOPEstaticif;
 			e = e.semantic(paramscope);
@@ -574,9 +611,9 @@
 	 *	match	this is at least as specialized as td2
 	 *	0	td2 is more specialized than this
 	 */
-    MATCH leastAsSpecialized(TemplateDeclaration td2)
+	MATCH leastAsSpecialized(TemplateDeclaration td2)
 	{
-	    /* This works by taking the template parameters to this template
+		/* This works by taking the template parameters to this template
 		 * declaration and feeding them to td2 as if it were a template
 		 * instance.
 		 * If it works, then this template is at least as specialized
@@ -596,11 +633,11 @@
 		ti.tiargs.setDim(parameters.dim);
 		for (int i = 0; i < ti.tiargs.dim; i++)
 		{
-			TemplateParameter tp = cast(TemplateParameter)parameters.data[i];
+			auto tp = parameters[i];
 
-			void* p = tp.dummyArg();
+			auto p = tp.dummyArg();
 			if (p)
-				ti.tiargs.data[i] = p;
+				ti.tiargs[i] = p;
 			else
 				ti.tiargs.setDim(i);
 		}
@@ -643,7 +680,7 @@
 	 * Returns:
 	 *	match level
 	 */
-    MATCH deduceFunctionTemplateMatch(Loc loc, Objects targsi, Expression ethis, Expressions fargs, Objects dedargs)
+	MATCH deduceFunctionTemplateMatch(Loc loc, Objects targsi, Expression ethis, Expressions fargs, Objects dedargs)
 	{
 		size_t nfparams;
 		size_t nfargs;
@@ -652,7 +689,7 @@
 		int tuple_dim = 0;
 		MATCH match = MATCHexact;
 		FuncDeclaration fd = onemember.toAlias().isFuncDeclaration();
-		Arguments fparameters;		// function parameter list
+		Parameters fparameters;		// function parameter list
 		int fvarargs;			// function varargs
 		scope Objects dedtypes = new Objects();	// for T:T*, the dedargs is the T*, dedtypes is the T
 
@@ -682,6 +719,7 @@
 		Scope paramscope = scope_.push(paramsym);
 
 		TemplateTupleParameter tp = isVariadic();
+        int tp_is_declared = 0;
 
 	static if (false)
 	{
@@ -711,27 +749,28 @@
 				/* The extra initial template arguments
 				 * now form the tuple argument.
 				 */
-				Tuple t = new Tuple();
+				auto t = new Tuple();
 				assert(parameters.dim);
-				dedargs.data[parameters.dim - 1] = cast(void*)t;
+				dedargs[parameters.dim - 1] = t;
 
 				tuple_dim = nargsi - n;
 				t.objects.setDim(tuple_dim);
 				for (size_t i = 0; i < tuple_dim; i++)
 				{
-					t.objects.data[i] = cast(void*)targsi.data[n + i];
+					t.objects[i] = targsi[n + i];
 				}
 				declareParameter(paramscope, tp, t);
+                tp_is_declared = 1;
 			}
 			else
 				n = nargsi;
 
-			memcpy(dedargs.data, targsi.data, n * (*dedargs.data).sizeof);
+			memcpy(dedargs.ptr, targsi.ptr, n * (*dedargs.ptr).sizeof);
 
 			for (size_t i = 0; i < n; i++)
 			{   
 				assert(i < parameters.dim);
-				TemplateParameter tp2 = cast(TemplateParameter)parameters.data[i];
+				auto tp2 = parameters[i];
 				MATCH m;
 				Declaration sparam = null;
 
@@ -758,22 +797,8 @@
 		}
 	}
 
-		if (fd.type)
-		{
-			assert(fd.type.ty == Tfunction);
-			TypeFunction fdtype = cast(TypeFunction)fd.type;
-			fparameters = fdtype.parameters;
-			fvarargs = fdtype.varargs;
-		}
-		else
-		{	
-			CtorDeclaration fctor = fd.isCtorDeclaration();
-			assert(fctor);
-			fparameters = fctor.arguments;
-			fvarargs = fctor.varargs;
-		}
-
-		nfparams = Argument.dim(fparameters);	// number of function parameters
+		fparameters = fd.getParameters(&fvarargs);
+		nfparams = Parameter.dim(fparameters);	// number of function parameters
 		nfargs = fargs ? fargs.dim : 0;		// number of function arguments
 
 		/* Check for match of function arguments with variadic template
@@ -786,9 +811,11 @@
 		{
 			if (nfparams == 0 && nfargs != 0)		// if no function parameters
 			{
-				Tuple t = new Tuple();
+	            if (tp_is_declared)
+		            goto L2;
+				auto t = new Tuple();
 				//printf("t = %p\n", t);
-				dedargs.data[parameters.dim - 1] = cast(void*)t;
+				dedargs[parameters.dim - 1] = t;
 				declareParameter(paramscope, tp, t);
 				goto L2;
 			}
@@ -803,28 +830,31 @@
 				 */
 				for (fptupindex = 0; fptupindex < nfparams; fptupindex++)
 				{
-					Argument fparam = cast(Argument)fparameters.data[fptupindex];
+					auto fparam = fparameters[fptupindex];
 					if (fparam.type.ty != Tident)
 						continue;
-					TypeIdentifier tid = cast(TypeIdentifier)fparam.type;
+					auto tid = cast(TypeIdentifier)fparam.type;
 					if (!tp.ident.equals(tid.ident) || tid.idents.dim)
 						continue;
 
 					if (fvarargs)		// variadic function doesn't
 						goto Lnomatch;	// go with variadic template
 
+            		if (tp_is_declared)
+            		    goto L2;
+                    
 					/* The types of the function arguments
 					 * now form the tuple argument.
 					 */
-					Tuple t = new Tuple();
-					dedargs.data[parameters.dim - 1] = cast(void*)t;
+					auto t = new Tuple();
+					dedargs[parameters.dim - 1] = t;
 
 					tuple_dim = nfargs - (nfparams - 1);
 					t.objects.setDim(tuple_dim);
 					for (size_t i = 0; i < tuple_dim; i++)
 					{   
 						auto farg = fargs[fptupindex + i];
-						t.objects.data[i] = cast(void*)farg.type;
+						t.objects[i] = farg.type;
 					}
 					declareParameter(paramscope, tp, t);
 					goto L2;
@@ -849,7 +879,7 @@
 		{
 			for (size_t i = 0; i < parameters.dim; i++)
 			{   
-				TemplateParameter tp2 = cast(TemplateParameter)parameters.data[i];
+				auto tp2 = parameters[i];
 				TemplateThisParameter ttp = tp2.isTemplateThisParameter();
 				if (ttp)
 				{	
@@ -880,7 +910,7 @@
 				continue;
 			}
 
-			Argument fparam = Argument.getNth(fparameters, i);
+			auto fparam = Parameter.getNth(fparameters, i);
 
 			if (i >= nfargs)		// if not enough arguments
 			{
@@ -928,7 +958,7 @@
 					TypeDelegate td = cast(TypeDelegate)fparam.type.toBasetype();
 					TypeFunction tf = cast(TypeFunction)td.next;
 
-					if (!tf.varargs && Argument.dim(tf.parameters) == 0)
+					if (!tf.varargs && Parameter.dim(tf.parameters) == 0)
 					{
 						m = farg.type.deduceType(paramscope, tf.next, parameters, dedtypes);
 						if (!m && tf.next.toBasetype().ty == Tvoid)
@@ -1019,13 +1049,13 @@
 		 */
 		for (size_t i = nargsi; i < dedargs.dim; i++)
 		{
-			TemplateParameter tp2 = cast(TemplateParameter)parameters.data[i];
+			auto tp2 = parameters[i];
 			//printf("tp2[%d] = %s\n", i, tp2.ident.toChars());
 			/* For T:T*, the dedargs is the T*, dedtypes is the T
 			 * But for function templates, we really need them to match
 			 */
-			Object oarg = cast(Object)dedargs.data[i];
-			Object oded = cast(Object)dedtypes.data[i];
+			Object oarg = dedargs[i];
+			Object oded = dedtypes[i];
 			//printf("1dedargs[%d] = %p, dedtypes[%d] = %p\n", i, oarg, i, oded);
 			//if (oarg) printf("oarg: %s\n", oarg.toChars());
 			//if (oded) printf("oded: %s\n", oded.toChars());
@@ -1039,14 +1069,14 @@
 						 * the oded == oarg
 						 */
 						Declaration sparam;
-						dedargs.data[i] = cast(void*)oded;
+						dedargs[i] = oded;
 						MATCH m2 = tp2.matchArg(paramscope, dedargs, i, parameters, dedtypes, &sparam, 0);
 						//printf("m2 = %d\n", m2);
 						if (!m2)
 							goto Lnomatch;
 						if (m2 < match)
 							match = m2;		// pick worst match
-						if (dedtypes.data[i] !is cast(void*)oded)
+						if (dedtypes[i] !is oded)
 							error("specialization not allowed for deduced parameter %s", tp2.ident.toChars());
 					}
 				}
@@ -1057,7 +1087,7 @@
 						goto Lnomatch;
 				}
 				declareParameter(paramscope, tp2, oded);
-				dedargs.data[i] = cast(void*)oded;
+				dedargs[i] = oded;
 			}
 		}
 
@@ -1065,6 +1095,7 @@
 		if (constraint)
 		{	/* Check to see if constraint is satisfied.
 			 */
+            makeParamNamesVisibleInConstraint(paramscope);
 			Expression e = constraint.syntaxCopy();
 			paramscope.flags |= SCOPE.SCOPEstaticif;
 			e = e.semantic(paramscope);
@@ -1097,7 +1128,7 @@
 		//printf("\tnomatch\n");
 		return MATCHnomatch;
 	}
-    
+	
 	/*************************************************
 	 * Given function arguments, figure out which template function
 	 * to expand, and return that function.
@@ -1121,7 +1152,7 @@
 
 	static if (false) {
 		printf("TemplateDeclaration.deduceFunctionTemplate() %s\n", toChars());
-		printf("    targsi:\n");
+		printf("	targsi:\n");
 		if (targsi)
 		{	
 			for (int i = 0; i < targsi.dim; i++)
@@ -1130,7 +1161,7 @@
 				printf("\t%s\n", arg.toChars());
 			}
 		}
-		printf("    fargs:\n");
+		printf("	fargs:\n");
 		for (int i = 0; i < fargs.dim; i++)
 		{	
 			Expression arg = cast(Expression)fargs.data[i];
@@ -1193,7 +1224,7 @@
 			td_best = td;
 			m_best = m;
 			tdargs.setDim(dedargs.dim);
-			memcpy(tdargs.data, dedargs.data, tdargs.dim * (void*).sizeof);
+			memcpy(tdargs.ptr, dedargs.ptr, tdargs.dim * (void*).sizeof);
 			continue;
 		}
 		if (!td_best)
@@ -1213,7 +1244,7 @@
 		 */
 		assert(cast(size_t)cast(void*)td_best.scope_ > 0x10000);
 		ti = new TemplateInstance(loc, td_best, tdargs);
-		ti.semantic(sc);
+		ti.semantic(sc, fargs);
 		fd = ti.toAlias().isFuncDeclaration();
 		if (!fd)
 		goto Lerror;
@@ -1234,7 +1265,7 @@
 				{
 					if (i)
 						bufa.writeByte(',');
-					Object oarg = cast(Object)args.data[i];
+					Object oarg = args[i];
 					ObjectToCBuffer(bufa, &hgs, oarg);
 				}
 			}
@@ -1249,7 +1280,7 @@
 	/**************************************************
 	 * Declare template parameter tp with value o, and install it in the scope sc.
 	 */
-    void declareParameter(Scope sc, TemplateParameter tp, Object o)
+	void declareParameter(Scope sc, TemplateParameter tp, Object o)
 	{
 		//printf("TemplateDeclaration.declareParameter('%s', o = %p)\n", tp.ident.toChars(), o);
 
@@ -1317,9 +1348,9 @@
 		s.semantic(sc);
 	}
 	
-    override TemplateDeclaration isTemplateDeclaration() { return this; }
+	override TemplateDeclaration isTemplateDeclaration() { return this; }
 
-    TemplateTupleParameter isVariadic()
+	TemplateTupleParameter isVariadic()
 	{
 		return .isVariadic(parameters);
 	}
@@ -1327,8 +1358,51 @@
 	/***********************************
 	 * We can overload templates.
 	 */
-    override bool isOverloadable()
+	override bool isOverloadable()
 	{
-		return 1;
+		return true;
 	}
+    
+    /****************************
+     * Declare all the function parameters as variables
+     * and add them to the scope
+     */
+    void makeParamNamesVisibleInConstraint(Scope paramscope)
+    {
+        /* We do this ONLY if there is only one function in the template.
+         */	 
+        FuncDeclaration fd = onemember && onemember.toAlias() ?
+	    onemember.toAlias().isFuncDeclaration() : null;
+        if (fd)
+        {
+	        paramscope.parent = fd;
+	        int fvarargs;				// function varargs
+            Parameters fparameters = fd.getParameters(&fvarargs);
+	        size_t nfparams = Parameter.dim(fparameters); // Num function parameters
+	        for (int i = 0; i < nfparams; i++)
+	        {
+	            Parameter fparam = Parameter.getNth(fparameters, i).syntaxCopy();
+	            if (!fparam.ident)
+		            continue;			// don't add it, if it has no name
+	            Type vtype = fparam.type.syntaxCopy();
+	            // isPure will segfault if called on a ctor, because fd->type is null.
+	            if (fd.type && fd.isPure())
+		        vtype = vtype.addMod(MODconst);
+	            VarDeclaration v = new VarDeclaration(loc, vtype, fparam.ident, null);
+	            v.storage_class |= STCparameter;
+	            // Not sure if this condition is correct/necessary.
+	            //   It's from func.c
+	            if (//fd->type && fd->type->ty == Tfunction &&
+	                fvarargs == 2 && i + 1 == nfparams)
+		            v.storage_class |= STCvariadic;
+		
+	            v.storage_class |= fparam.storageClass & (STCin | STCout | STCref | STClazy | STCfinal | STC_TYPECTOR | STCnodtor);
+	            v.semantic(paramscope);
+	            if (!paramscope.insert(v))
+		            error("parameter %s.%s is already defined", toChars(), v.toChars());
+	            else
+		            v.parent = this;
+	        }
+        }
+    }
 }
--- a/dmd/TemplateExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TemplateExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TemplateExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.OutBuffer;
 import dmd.Loc;
--- a/dmd/TemplateInstance.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TemplateInstance.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TemplateInstance;
 
+import dmd.common;
 import dmd.ScopeDsymbol;
 import dmd.IntegerExp;
 import dmd.Identifier;
@@ -23,7 +24,7 @@
 import dmd.TOK;
 import dmd.TY;
 import dmd.TypeTuple;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.WANT;
 import dmd.ExpInitializer;
 import dmd.Array;
@@ -36,6 +37,10 @@
 import dmd.FuncExp;
 import dmd.Declaration;
 import dmd.MATCH;
+import dmd.TypeFunction;
+import dmd.TemplateTupleParameter;
+import dmd.FuncDeclaration;
+import dmd.OverloadSet;
 import dmd.templates.Util;
 
 import dmd.backend.glue;
@@ -144,7 +149,7 @@
 
 		for (size_t i = 0; i < v1.objects.dim; i++)
 		{
-			if (!match(cast(Object)v1.objects.data[i], cast(Object)v2.objects.data[i], tempdecl, sc))
+			if (!match(v1.objects[i], v2.objects[i], tempdecl, sc))
 				goto Lnomatch;
 		}
     }
@@ -236,7 +241,7 @@
 		a.setDim(objs.dim);
 		for (size_t i = 0; i < objs.dim; i++)
 		{
-		    a.data[i] = cast(void*)objectSyntaxCopy(cast(Object)objs.data[i]);
+		    a[i] = objectSyntaxCopy(objs[i]);
 		}
 	    }
 	    return a;
@@ -259,6 +264,11 @@
 
     override void semantic(Scope sc)
 	{
+        semantic(sc, null);
+    }
+
+    void semantic(Scope sc, Expressions fargs)
+    {
 	    if (global.errors)
 		{
 			if (!global.gag)
@@ -336,9 +346,8 @@
 		 * implements the typeargs. If so, just refer to that one instead.
 		 */
 
-		for (size_t i = 0; i < tempdecl.instances.dim; i++)
+		foreach (ti; tempdecl.instances)
 		{
-			TemplateInstance ti = cast(TemplateInstance)tempdecl.instances.data[i];
 		version (LOG) {
 			printf("\t%s: checking for match with instance %d (%p): '%s'\n", toChars(), i, ti, ti.toChars());
 		}
@@ -356,11 +365,39 @@
 		}
 			for (size_t j = 0; j < tdtypes.dim; j++)
 			{   
-				Object o1 = cast(Object)tdtypes.data[j];
-				Object o2 = cast(Object)ti.tdtypes.data[j];
+				Object o1 = tdtypes[j];
+				Object o2 = ti.tdtypes[j];
 				if (!match(o1, o2, tempdecl, sc))
 				{
 					goto L1;
+	            }
+	        }
+
+	        /* Template functions may have different instantiations based on
+	         * "auto ref" parameters.
+	         */
+	        if (fargs)
+	        {
+	            FuncDeclaration fd = ti.toAlias().isFuncDeclaration();
+	            if (fd)
+	            {
+		            auto fparameters = fd.getParameters(null);
+		            size_t nfparams = Parameter.dim(fparameters); // Num function parameters
+		            for (int i = 0; i < nfparams && i < fargs.dim; i++)
+		            {   auto fparam = Parameter.getNth(fparameters, i);
+		                auto farg = fargs[i];
+		                if (fparam.storageClass & STCauto)		// if "auto ref"
+		                {
+			                if (farg.isLvalue())
+			                {   if (!(fparam.storageClass & STC.STCref))
+				                goto L1;			// auto ref's don't match
+			                }
+			                else
+			                {   if (fparam.storageClass & STC.STCref)
+				                goto L1;			// auto ref's don't match
+			                }
+		                }
+		            }
 				}
 			}
 
@@ -384,7 +421,7 @@
 		uint errorsave = global.errors;
 		inst = this;
 		int tempdecl_instance_idx = tempdecl.instances.dim;
-		tempdecl.instances.push(cast(void*)this);
+		tempdecl.instances.push(this);
 		parent = tempdecl.parent;
 		//printf("parent = '%s'\n", parent.kind());
 
@@ -511,6 +548,22 @@
 				}
 			}
 		}
+        
+        /* If function template declaration
+         */
+        if (fargs && aliasdecl)
+        {
+	        FuncDeclaration fd = aliasdecl.toAlias().isFuncDeclaration();
+	        if (fd)
+	        {
+	            /* Transmit fargs to type so that TypeFunction::semantic() can
+	             * resolve any "auto ref" storage classes.
+	             */
+	            auto tf = cast(TypeFunction)fd.type;
+	            if (tf && tf.ty == TY.Tfunction)
+		        tf.fargs = fargs;
+	        }
+        }
 
 		// Do semantic() analysis on template instance members
 	version (LOG) {
@@ -607,10 +660,9 @@
 		if (global.errors != errorsave)
 		{
 			error("error instantiating");
-			if (tinst && !global.gag)
+			if (tinst)
 			{   
 				tinst.printInstantiationTrace();
-				fatal();
 			}
 			errors = 1;
 			if (global.gag)
@@ -708,7 +760,7 @@
 			{
 				if (i)
 					buf.writeByte(',');
-				Object oarg = cast(Object)args.data[i];
+				Object oarg = args[i];
 				ObjectToCBuffer(buf, hgs, oarg);
 			}
 			nest--;
@@ -750,7 +802,48 @@
 	    *ps = null;
 	    return true;
 	}
-	
+    
+    /*****************************************************
+     * Determine if template instance is really a template function,
+     * and that template function needs to infer types from the function
+     * arguments.
+     */
+
+    bool needsTypeInference(Scope sc)
+    {
+        //printf("TemplateInstance::needsTypeInference() %s\n", toChars());
+        if (!tempdecl)
+	        tempdecl = findTemplateDeclaration(sc);
+        for (TemplateDeclaration td = tempdecl; td; td = td.overnext)
+        {
+	    /* If any of the overloaded template declarations need inference,
+	     * then return TRUE
+	     */
+	    FuncDeclaration fd;
+	    if (!td.onemember ||
+	        (fd = td.onemember.toAlias().isFuncDeclaration()) is null ||
+	        fd.type.ty != TY.Tfunction)
+	    {
+	        /* Not a template function, therefore type inference is not possible.
+	         */
+	        //printf("false\n");
+	        return false;
+	    }
+
+	    /* Determine if the instance arguments, tiargs, are all that is necessary
+	     * to instantiate the template.
+	     */
+	    TemplateTupleParameter tp = td.isVariadic();
+	    //printf("tp = %p, td->parameters->dim = %d, tiargs->dim = %d\n", tp, td->parameters->dim, tiargs->dim);
+	    TypeFunction fdtype = cast(TypeFunction)fd.type;
+	    if (Parameter.dim(fdtype.parameters) &&
+	        (tp || tiargs.dim < td.parameters.dim))
+	        return true;
+        }
+        //printf("false\n");
+        return false;
+    }
+    
     override string toChars()
 	{
 		scope OutBuffer buf = new OutBuffer();
@@ -788,10 +881,82 @@
 	    return id;
 	}
 	
+    /**************************************
+     * Given an error instantiating the TemplateInstance,
+     * give the nested TemplateInstance instantiations that got
+     * us here. Those are a list threaded into the nested scopes.
+     */
     void printInstantiationTrace()
 	{
 	    if (global.gag)
-		return;
+		    return;
+/+
+        const int max_shown = 6;
+        const string format = "%s:        instantiated from here: %s\n";
+
+        // determine instantiation depth and number of recursive instantiations
+        int n_instantiations = 1;
+        int n_totalrecursions = 0;
+        for (TemplateInstance cur = this; cur; cur = cur.tinst)
+        {
+	        ++n_instantiations;
+	        // If two instantiations use the same declaration, they are recursive.
+	        // (this works even if they are instantiated from different places in the
+	        // same template).
+	        // In principle, we could also check for multiple-template recursion, but it's
+	        // probably not worthwhile.
+	        if (cur.tinst && cur.tempdecl && cur.tinst.tempdecl
+	            && cur.tempdecl.loc.equals(cur.tinst.tempdecl.loc))
+	            ++n_totalrecursions;
+        }
+
+        // show full trace only if it's short or verbose is on
+        if (n_instantiations <= max_shown || global.params.verbose)
+        {
+	        for (TemplateInstance cur = this; cur; cur = cur.tinst)
+	        {
+	            fprintf(stdmsg, format, cur.loc.toChars(), cur.toChars());
+	        }
+        }
+        else if (n_instantiations - n_totalrecursions <= max_shown)
+        {
+	        // By collapsing recursive instantiations into a single line,
+	        // we can stay under the limit.
+	        int recursionDepth=0;
+	        for (TemplateInstance cur = this; cur; cur = cur.tinst)
+	        {
+	            if (cur.tinst && cur.tempdecl && cur.tinst.tempdecl
+		            && cur.tempdecl.loc.equals(cur.tinst.tempdecl.loc))
+	            {
+    		        ++recursionDepth;
+	            }
+	            else
+	            {
+		            if (recursionDepth)
+		                fprintf(stdmsg, "%s:        %d recursive instantiations from here: %s\n", cur.loc.toChars(), recursionDepth+2, cur.toChars());
+		            else 
+		                fprintf(stdmsg,format, cur.loc.toChars(), cur.toChars());
+		            recursionDepth = 0;
+	            }
+	        }
+        }
+        else
+        {
+	        // Even after collapsing the recursions, the depth is too deep.
+	        // Just display the first few and last few instantiations.
+	        size_t i = 0;
+	        for (TemplateInstance cur = this; cur; cur = cur.tinst)
+	        {
+	            if (i == max_shown / 2)
+		        fprintf(stdmsg,"    ... (%d instantiations, -v to show) ...\n", n_instantiations - max_shown);
+
+	            if (i < max_shown / 2 ||
+		        i >= n_instantiations - max_shown + max_shown / 2)
+		        fprintf(stdmsg, format, cur.loc.toChars(), cur.toChars());
+	            ++i;
+	        }
+        }
++/
 	}
 
     override void toObjFile(int multiobj)			// compile to .obj file
@@ -825,7 +990,7 @@
 			return;
 		for (size_t j = 0; j < tiargs.dim; j++)
 		{
-			Object o = cast(Object)tiargs.data[j];
+			Object o = tiargs[j];
 			Type ta = isType(o);
 			Expression ea = isExpression(o);
 			Dsymbol sa = isDsymbol(o);
@@ -847,11 +1012,11 @@
 					if (ea.op != TOKvar || flags & 1)
 						ea = ea.optimize(WANTvalue | WANTinterpret);
 
-					tiargs.data[j] = cast(void*)ea;
+					tiargs[j] = ea;
 				}
 				else if (sa)
 				{	
-					tiargs.data[j] = cast(void*)sa;
+					tiargs[j] = sa;
 					TupleDeclaration d = sa.toAlias().isTupleDeclaration();
 					if (d)
 					{
@@ -867,7 +1032,7 @@
 					if (ta.ty == Ttuple)
 					{   
 						// Expand tuple
-						TypeTuple tt = cast(TypeTuple)ta;
+						auto tt = cast(TypeTuple)ta;
 						size_t dim = tt.arguments.dim;
 						tiargs.remove(j);
 						if (dim)
@@ -875,19 +1040,19 @@
 							tiargs.reserve(dim);
 							for (size_t i = 0; i < dim; i++)
 							{   
-								Argument arg = cast(Argument)tt.arguments.data[i];
-								tiargs.insert(j + i, cast(void*)arg.type);
+								auto arg = tt.arguments[i];
+								tiargs.insert(j + i, arg.type);
 							}
 						}
 						j--;
 					}
 					else
-						tiargs.data[j] = cast(void*)ta;
+						tiargs[j] = ta;
 				}
 				else
 				{
 					assert(global.errors);
-					tiargs.data[j] = cast(void*)Type.terror;
+					tiargs[j] = Type.terror;
 				}
 			}
 			else if (ea)
@@ -901,7 +1066,7 @@
 				ea = ea.semantic(sc);
 				if (ea.op != TOKvar || flags & 1)
 					ea = ea.optimize(WANTvalue | WANTinterpret);
-				tiargs.data[j] = cast(void*)ea;
+				tiargs[j] = ea;
 				if (ea.op == TOKtype)
 				{	
 					ta = ea.type;
@@ -917,7 +1082,7 @@
 					{   
 						tiargs.reserve(dim);
 						for (size_t i = 0; i < dim; i++)
-						tiargs.insert(j + i, cast(void*)te.exps.data[i]);
+						tiargs.insert(j + i, te.exps[i]);
 					}
 					j--;
 				}
@@ -980,9 +1145,32 @@
 			s = sc.search(loc, id, &scopesym);
 			if (!s)
 			{   
-				error("identifier '%s' is not defined", id.toChars());
+				error("template '%s' is not defined", id.toChars());
 				return null;
 			}
+
+	        /* If an OverloadSet, look for a unique member that is a template declaration
+	         */
+	        OverloadSet os = s.isOverloadSet();
+	        if (os)
+	        {
+                s = null;
+	            foreach (s2; os.a)
+	            {
+		            if (s2.isTemplateDeclaration())
+		            {
+		                if (s)
+			                error("ambiguous template declaration %s and %s", s.toPrettyChars(), s2.toPrettyChars());
+		                s = s2;
+		            }
+	            }
+	            if (!s)
+	            {
+                    error("template '%s' is not defined", id.toChars());
+		            return null;
+	            }
+	        }
+
 		version (LOG) {
 			printf("It's an instance of '%s' kind '%s'\n", s.toChars(), s.kind());
 			if (s.parent)
@@ -1153,7 +1341,7 @@
 			td_best = td;
 			m_best = m;
 			tdtypes.setDim(dedtypes.dim);
-			memcpy(tdtypes.data, dedtypes.data, tdtypes.dim * (void*).sizeof);
+			memcpy(tdtypes.ptr, dedtypes.ptr, tdtypes.dim * (void*).sizeof);
 			continue;
 		}
 
@@ -1212,9 +1400,9 @@
 		//printf("TemplateInstance.declareParameters()\n");
 		for (int i = 0; i < tdtypes.dim; i++)
 		{
-			TemplateParameter tp = cast(TemplateParameter)tempdecl.parameters.data[i];
+			auto tp = tempdecl.parameters[i];
 			//Object o = cast(Object)tiargs.data[i];
-			Object o = cast(Object)tdtypes.data[i];		// initializer for tp
+			Object o = tdtypes[i];		// initializer for tp
 
 			//printf("\ttdtypes[%d] = %p\n", i, o);
 			tempdecl.declareParameter(sc, tp, o);
@@ -1235,7 +1423,7 @@
 		 */
 		for (size_t i = 0; i < args.dim; i++)
 		{   
-			Object o = cast(Object)args.data[i];
+			Object o = args[i];
 			Expression ea = isExpression(o);
 			Dsymbol sa = isDsymbol(o);
 			Tuple va = isTuple(o);
@@ -1325,7 +1513,7 @@
 		Objects args = tiargs;
 		for (int i = 0; i < args.dim; i++)
 		{   
-			Object o = cast(Object)args.data[i];
+			Object o = args[i];
 			Type ta = isType(o);
 			Expression ea = isExpression(o);
 			Dsymbol sa = isDsymbol(o);
--- a/dmd/TemplateMixin.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TemplateMixin.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TemplateMixin;
 
+import dmd.common;
 import dmd.TemplateInstance;
 import dmd.Array;
 import dmd.Type;
@@ -212,12 +213,12 @@
 			if (tiargs.dim != tm.tiargs.dim)
 				continue;
 
-			for (int i = 0; i < tiargs.dim; i++)
-			{   Object o = cast(Object)tiargs.data[i];
+			foreach (size_t i, Object o; tiargs)
+			{
 				Type ta = isType(o);
 				Expression ea = isExpression(o);
 				Dsymbol sa = isDsymbol(o);
-				Object tmo = cast(Object)tm.tiargs.data[i];
+				Object tmo = tm.tiargs[i];
 				if (ta)
 				{
 					Type tmta = isType(tmo);
@@ -452,7 +453,7 @@
 			for (int i = 0; i < tiargs.dim; i++)
 			{   if (i)
 				buf.writebyte(',');
-				Object oarg = cast(Object)tiargs.data[i];
+				Object oarg = tiargs[i];
 				Type t = isType(oarg);
 				Expression e = isExpression(oarg);
 				Dsymbol s = isDsymbol(oarg);
--- a/dmd/TemplateParameter.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TemplateParameter.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TemplateParameter;
 
+import dmd.common;
 import dmd.Loc;
 import dmd.Identifier;
 import dmd.Declaration;
@@ -13,6 +14,7 @@
 import dmd.HdrGenState;
 import dmd.MATCH;
 import dmd.ArrayTypes;
+import dmd.Array;
 
 class TemplateParameter
 {
@@ -83,5 +85,5 @@
 
     /* Create dummy argument based on parameter.
      */
-    abstract void* dummyArg();
+    abstract Object dummyArg();
 }
\ No newline at end of file
--- a/dmd/TemplateThisParameter.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TemplateThisParameter.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TemplateThisParameter;
 
+import dmd.common;
 import dmd.TemplateTypeParameter;
 import dmd.Type;
 import dmd.Loc;
--- a/dmd/TemplateTupleParameter.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TemplateTupleParameter.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TemplateTupleParameter;
 
+import dmd.common;
 import dmd.TemplateParameter;
 import dmd.Loc;
 import dmd.Identifier;
@@ -66,7 +67,7 @@
 			if (i)
 				writef(", ");
 
-			Object o = cast(Object)v.objects.data[i];
+			Object o = v.objects[i];
 
 			Dsymbol sa = isDsymbol(o);
 			if (sa)
@@ -122,8 +123,8 @@
 		 */
 		assert(i + 1 == dedtypes.dim);	// must be the last one
 		Tuple ovar;
-		if (i + 1 == tiargs.dim && isTuple(cast(Object)tiargs.data[i]))
-			ovar = isTuple(cast(Object)tiargs.data[i]);
+		if (i + 1 == tiargs.dim && isTuple(tiargs[i]))
+			ovar = isTuple(tiargs[i]);
 		else
 		{
 			ovar = new Tuple();
@@ -133,16 +134,16 @@
 				//printf("i = %d, tiargs.dim = %d\n", i, tiargs.dim);
 				ovar.objects.setDim(tiargs.dim - i);
 				for (size_t j = 0; j < ovar.objects.dim; j++)
-					ovar.objects.data[j] = tiargs.data[i + j];
+					ovar.objects[j] = tiargs[i + j];
 			}
 		}
 		*psparam = new TupleDeclaration(loc, ident, ovar.objects);
-		dedtypes.data[i] = cast(void*)ovar;
+		dedtypes[i] = ovar;
 
 		return MATCH.MATCHexact;
 	}
 	
-    override void* dummyArg()
+    override Object dummyArg()
 	{
 		return null;
 	}
--- a/dmd/TemplateTypeParameter.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TemplateTypeParameter.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TemplateTypeParameter;
 
+import dmd.common;
 import dmd.TemplateParameter;
 import dmd.Type;
 import dmd.Loc;
@@ -132,7 +133,7 @@
 		Type ta;
 
 		if (i < tiargs.dim)
-			oarg = cast(Object)tiargs.data[i];
+			oarg = tiargs[i];
 		else
 		{	
 			// Get default argument instead
@@ -141,7 +142,7 @@
 			{   
 				assert(i < dedtypes.dim);
 				// It might have already been deduced
-				oarg = cast(Object)dedtypes.data[i];
+				oarg = dedtypes[i];
 				if (!oarg)
 				{
 					goto Lnomatch;
@@ -158,7 +159,7 @@
 		}
 		//printf("ta is %s\n", ta.toChars());
 
-		t = cast(Type)dedtypes.data[i];
+		t = cast(Type)dedtypes[i];
 
 		if (specType)
 		{
@@ -172,7 +173,7 @@
 
 			if (m2 < m)
 				m = m2;
-			t = cast(Type)dedtypes.data[i];
+			t = cast(Type)dedtypes[i];
 		}
 		else
 		{
@@ -199,7 +200,7 @@
 
 		if (!t)
 		{
-			dedtypes.data[i] = cast(void*)ta;
+			dedtypes[i] = ta;
 			t = ta;
 		}
 
@@ -213,7 +214,7 @@
 		return MATCHnomatch;
 	}
 	
-    override void* dummyArg()
+    override Object dummyArg()
 	{
 		Type t;
 
@@ -224,6 +225,6 @@
 			// Use this for alias-parameter's too (?)
 			t = new TypeIdentifier(loc, ident);
 		}
-		return cast(void *)t;
+		return t;
 	}
 }
--- a/dmd/TemplateValueParameter.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TemplateValueParameter.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TemplateValueParameter;
 
+import dmd.common;
 import dmd.TemplateParameter;
 import dmd.Scope;
 import dmd.Declaration;
@@ -137,11 +138,7 @@
 			e = e.syntaxCopy();
 			e = e.semantic(sc);
 version (DMDV2) {
-			if (e.op == TOKdefault)
-			{  
-				DefaultInitExp de = cast(DefaultInitExp)e;
-				e = de.resolve(loc, sc);
-			}
+            e = e.resolveLoc(loc, sc);
 }
 		}
 		return e;
@@ -179,7 +176,7 @@
 		Object oarg;
 
 		if (i < tiargs.dim)
-			oarg = cast(Object)tiargs.data[i];
+			oarg = tiargs[i];
 		else
 		{	
 			// Get default argument instead
@@ -188,7 +185,7 @@
 			{   
 				assert(i < dedtypes.dim);
 				// It might have already been deduced
-				oarg = cast(Object)dedtypes.data[i];
+				oarg = dedtypes[i];
 				if (!oarg)
 					goto Lnomatch;
 			}
@@ -227,9 +224,9 @@
 			if (!ei.equals(e))
 				goto Lnomatch;
 		}
-		else if (dedtypes.data[i])
+		else if (dedtypes[i])
 		{   // Must match already deduced value
-			Expression e = cast(Expression)dedtypes.data[i];
+			auto e = cast(Expression)dedtypes[i];
 
 			if (!ei || !ei.equals(e))
 				goto Lnomatch;
@@ -246,7 +243,7 @@
 			if (!m)
 				goto Lnomatch;
 		}
-		dedtypes.data[i] = cast(void*)ei;
+		dedtypes[i] = ei;
 
 		init = new ExpInitializer(loc, ei);
 		sparam = new VarDeclaration(loc, vt, ident, init);
@@ -260,7 +257,7 @@
 		return MATCHnomatch;
 	}
 
-    override void* dummyArg()
+    override Object dummyArg()
 	{
 		Expression e;
 
@@ -272,6 +269,6 @@
 				edummy = valType.defaultInit(Loc(0));
 			e = edummy;
 		}
-		return cast(void*)e;
+		return e;
 	}
 }
--- a/dmd/ThisDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/ThisDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.ThisDeclaration;
 
+import dmd.common;
 import dmd.VarDeclaration;
 import dmd.Dsymbol;
 import dmd.Loc;
--- a/dmd/ThisExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/ThisExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.ThisExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Declaration;
 import dmd.StructDeclaration;
@@ -130,7 +131,8 @@
 
 	override void scanForNestedRef(Scope sc)
 	{
-		assert(false);
+		assert(var);
+		var.isVarDeclaration().checkNestedReference(sc, Loc(0));
 	}
 
 	override int inlineCost(InlineCostState* ics)
--- a/dmd/ThrowStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/ThrowStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.ThrowStatement;
 
+import dmd.common;
 import dmd.Statement;
 import dmd.Expression;
 import dmd.Loc;
@@ -42,8 +43,11 @@
 		FuncDeclaration fd = sc.parent.isFuncDeclaration();
 		fd.hasReturnExp |= 2;
 
+version(DMDV1) {
+        // See bugzilla 3388. Should this be or not?
 		if (sc.incontract)
 			error("Throw statements cannot be in contracts");
+}
 		exp = exp.semantic(sc);
 		exp = resolveProperties(sc, exp);
 		if (!exp.type.toBasetype().isClassHandle())
--- a/dmd/Token.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/Token.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.Token;
 
+import dmd.common;
 import dmd.TOK;
 import dmd.Identifier;
 import dmd.OutBuffer;
--- a/dmd/TraitsExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TraitsExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TraitsExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Identifier;
 import dmd.ArrayTypes;
@@ -30,6 +31,7 @@
 import dmd.TemplateDeclaration;
 import dmd.TemplateInstance;
 import dmd.TypeClass;
+import dmd.Declaration;
 import dmd.Util;
 import dmd.expression.Util;
 
@@ -91,13 +93,14 @@
 			TemplateInstance.semanticTiargs(loc, sc, args, 1);
 		size_t dim = args ? args.dim : 0;
 		Object o;
+        Declaration d;
 		FuncDeclaration f;
 
 		string ISTYPE(string cond)
 		{
 			return `
 				for (size_t i = 0; i < dim; i++)
-				{   Type t = getType(cast(Object)args.data[i]);
+				{   Type t = getType(args[i]);
 					if (!t)
 						goto Lfalse;
 					if (!(`~cond~`))
@@ -112,7 +115,7 @@
 		string ISDSYMBOL(string cond)
 		{
 			return `for (size_t i = 0; i < dim; i++)
-			{   Dsymbol s = getDsymbol(cast(Object)args.data[i]);
+			{   Dsymbol s = getDsymbol(args[i]);
 				if (!s)
 					goto Lfalse;
 				if (!(`~cond~`))
@@ -171,14 +174,28 @@
 		{
 			mixin(ISDSYMBOL(q{(f = s.isFuncDeclaration()) !is null && f.isFinal()}));
 		}
+//version(DMDV2) {
+        else if (ident == Id.isRef)
+        {
+	        mixin(ISDSYMBOL(q{(d = s.isDeclaration()) !is null && d.isRef()}));
+        }
+        else if (ident == Id.isOut)
+        {
+            mixin(ISDSYMBOL(q{(d = s.isDeclaration()) !is null && d.isOut()}));
+        }
+        else if (ident == Id.isLazy)
+        {
+	        mixin(ISDSYMBOL(q{(d = s.isDeclaration()) !is null && d.storage_class & STClazy}));
+        }
+//}
 		else if (ident == Id.hasMember ||
 				ident == Id.getMember ||
 				ident == Id.getVirtualFunctions)
 		{
 			if (dim != 2)
 				goto Ldimerror;
-			Object o_ = cast(Object)args.data[0];
-			Expression e = isExpression(cast(Object)args.data[1]);
+			auto o_ = args[0];
+			Expression e = isExpression(args[1]);
 			if (!e)
 			{   error("expression expected as second argument of __traits %s", ident.toChars());
 				goto Lfalse;
@@ -188,7 +205,7 @@
 			{   error("string expected as second argument of __traits %s instead of %s", ident.toChars(), e.toChars());
 				goto Lfalse;
 			}
-			StringExp se = cast(StringExp)e;
+			auto se = cast(StringExp)e;
 			se = se.toUTF8(sc);
 			if (se.sz != 1)
 			{   error("string must be chars");
@@ -267,7 +284,7 @@
 		{
 			if (dim != 1)
 				goto Ldimerror;
-			Object o_ = cast(Object)args.data[0];
+			Object o_ = args[0];
 			Dsymbol s = getDsymbol(o_);
 			ClassDeclaration cd;
 			if (!s || (cd = s.isClassDeclaration()) is null)
@@ -281,7 +298,7 @@
 		{
 			if (dim != 1)
 				goto Ldimerror;
-			Object o_ = cast(Object)args.data[0];
+			Object o_ = args[0];
 			Dsymbol s = getDsymbol(o_);
 			ScopeDsymbol sd;
 			if (!s)
@@ -339,7 +356,7 @@
 				goto Lfalse;
 
 			for (size_t i = 0; i < dim; i++)
-			{   Object o_ = cast(Object)args.data[i];
+			{   Object o_ = args[i];
 				Expression e;
 
 				uint errors = global.errors;
@@ -375,8 +392,8 @@
 			if (dim != 2)
 				goto Ldimerror;
 			TemplateInstance.semanticTiargs(loc, sc, args, 0);
-			Object o1 = cast(Object)args.data[0];
-			Object o2 = cast(Object)args.data[1];
+			Object o1 = args[0];
+			Object o2 = args[1];
 			Dsymbol s1 = getDsymbol(o1);
 			Dsymbol s2 = getDsymbol(o2);
 
@@ -447,7 +464,7 @@
 			for (int i = 0; i < args.dim; i++)
 			{
 				buf.writeByte(',');
-				Object oarg = cast(Object)args.data[i];
+				Object oarg = args[i];
 				ObjectToCBuffer(buf, hgs, oarg);
 			}
 		}
--- a/dmd/TryCatchStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TryCatchStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TryCatchStatement;
 
+import dmd.common;
 import dmd.Statement;
 import dmd.Array;
 import dmd.Loc;
--- a/dmd/TryFinallyStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TryFinallyStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TryFinallyStatement;
 
+import dmd.common;
 import dmd.Statement;
 import dmd.Loc;
 import dmd.OutBuffer;
--- a/dmd/Tuple.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/Tuple.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.Tuple;
 
+import dmd.common;
 import dmd.ArrayTypes;
 import dmd.DYNCAST;
 
--- a/dmd/TupleDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TupleDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,7 +1,8 @@
 module dmd.TupleDeclaration;
 
+import dmd.common;
 import dmd.Declaration;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.ArrayTypes;
 import dmd.TypeTuple;
 import dmd.Loc;
@@ -53,10 +54,8 @@
 		{
 			/* It's only a type tuple if all the Object's are types
 			 */
-			for (size_t i = 0; i < objects.dim; i++)
+			foreach (o; objects)
 			{   
-				Object o = cast(Object)objects.data[i];
-
 				if (cast(Type)o is null)
 				{
 					//printf("\tnot[%d], %p, %d\n", i, o, o->dyncast());
@@ -66,12 +65,12 @@
 
 			/* We know it's a type tuple, so build the TypeTuple
 			 */
-			Arguments args = new Arguments();
+			auto args = new Parameters();
 			args.setDim(objects.dim);
 			OutBuffer buf = new OutBuffer();
 			bool hasdeco = 1;
 			for (size_t i = 0; i < objects.dim; i++)
-			{   Type t = cast(Type)objects.data[i];
+			{   Type t = cast(Type)objects[i];
 
 				//printf("type = %s\n", t->toChars());
 static if (false)
@@ -79,11 +78,11 @@
 					buf.printf("_%s_%d", ident.toChars(), i);
 					char *name = cast(char *)buf.extractData();
 					Identifier id = new Identifier(name, TOKidentifier);
-					Argument arg = new Argument(STCin, t, id, null);
+					auto arg = new Parameter(STCin, t, id, null);
 } else {
-					Argument arg = new Argument(STCundefined, t, null, null);
+					auto arg = new Parameter(STCundefined, t, null, null);
 }
-				args.data[i] = cast(void *)arg;
+				args[i] = arg;
 				if (!t.deco)
 					hasdeco = false;
 			}
@@ -101,7 +100,7 @@
 		//printf("TupleDeclaration::needThis(%s)\n", toChars());
 		for (size_t i = 0; i < objects.dim; i++)
 		{   
-			Object o = cast(Object)objects.data[i];
+			Object o = objects[i];
 			if (auto e = cast(Expression)o)
 			{
 				if (e.op == TOKdsymbol)
--- a/dmd/TupleExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TupleExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TupleExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.TupleDeclaration;
 import dmd.backend.elem;
@@ -88,9 +89,8 @@
 		type = null;
 
 		exps.reserve(tup.objects.dim);
-		for (size_t i = 0; i < tup.objects.dim; i++)
+		foreach (o; tup.objects)
 		{   
-			Object o = cast(Object)tup.objects.data[i];
 			if (auto e = cast(Expression)o)
 			{
 				e = e.syntaxCopy();
--- a/dmd/Type.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/Type.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,7 +1,8 @@
 module dmd.Type;
 
+import dmd.common;
 import dmd.TY;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.TOK;
 import dmd.STC;
 import dmd.TypeArray;
@@ -53,6 +54,15 @@
 import dmd.TypeSlice;
 import dmd.Global;
 import dmd.StringValue;
+import dmd.TRUST;
+import dmd.TemplateDeclaration;
+import dmd.DotIdExp;
+import dmd.AggregateDeclaration;
+import dmd.DotTemplateInstanceExp;
+import dmd.Token;
+import dmd.TypeInfoWildDeclaration;
+
+import dmd.expression.Util;
 
 import dmd.backend.Symbol;
 import dmd.backend.TYPE;
@@ -79,15 +89,15 @@
  * REALALIGNSIZE = alignment for reals
  */
 version (TARGET_OSX) {
-	int REALSIZE = 16;
+	extern(C++) int REALSIZE = 16;
 	int REALPAD = 6;
 	int REALALIGNSIZE = 16;
 } else version (POSIX) { /// TARGET_LINUX || TARGET_FREEBSD || TARGET_SOLARIS
-	int REALSIZE = 12;
+	extern(C++) int REALSIZE = 12;
 	int REALPAD = 2;
 	int REALALIGNSIZE = 4;
 } else {
-	int REALSIZE = 10;
+	extern(C++) int REALSIZE = 10;
 	int REALPAD = 0;
 	int REALALIGNSIZE = 2;
 }
@@ -99,10 +109,8 @@
 
 int templateIdentifierLookup(Identifier id, TemplateParameters parameters)
 {
-    for (size_t i = 0; i < parameters.dim; i++)
+    foreach (size_t i, TemplateParameter tp; parameters)
     {   
-		TemplateParameter tp = cast(TemplateParameter)parameters.data[i];
-
 		if (tp.ident.equals(id))
 			return i;
     }
@@ -121,6 +129,102 @@
     return -1;
 }
 
+/***************************
+ * Return !=0 if modfrom can be implicitly converted to modto
+ */
+int MODimplicitConv(MOD modfrom, MOD modto)
+{
+    if (modfrom == modto)
+	return 1;
+
+    //printf("MODimplicitConv(from = %x, to = %x)\n", modfrom, modto);
+	static uint X(MOD m, MOD n)
+	{
+		return (((m) << 4) | (n));
+	}
+    switch (X(modfrom, modto))
+    {
+	    case X(MOD.MODundefined, MOD.MODconst):
+	    case X(MOD.MODimmutable, MOD.MODconst):
+	    case X(MOD.MODwild,      MOD.MODconst):
+	    case X(MOD.MODimmutable, MOD.MODconst | MOD.MODshared):
+	    case X(MOD.MODshared,    MOD.MODconst | MOD.MODshared):
+	    case X(MOD.MODwild | MOD.MODshared,    MOD.MODconst | MOD.MODshared):
+	        return 1;
+
+	    default:
+	        return 0;
+    }
+}
+
+/*********************************
+ * Mangling for mod.
+ */
+void MODtoDecoBuffer(OutBuffer buf, MOD mod)
+{
+    switch (mod)
+    {
+        case MOD.MODundefined:
+	        break;
+	    case MOD.MODconst:
+	        buf.writeByte('x');
+	        break;
+	    case MOD.MODimmutable:
+	        buf.writeByte('y');
+	        break;
+	    case MOD.MODshared:
+	        buf.writeByte('O');
+	        break;
+	    case MOD.MODshared | MOD.MODconst:
+	        buf.writestring("Ox");
+	        break;
+	    case MOD.MODwild:
+	        buf.writestring("Ng");
+	        break;
+	    case MOD.MODshared | MOD.MODwild:
+	        buf.writestring("ONg");
+	        break;
+	    default:
+	        assert(0);
+    }
+}
+
+/*********************************
+ * Name for mod.
+ */
+void MODtoBuffer(OutBuffer buf, MOD mod)
+{
+    switch (mod)
+    {
+    case MOD.MODundefined:
+	    break;
+
+	case MOD.MODimmutable:
+	    buf.writestring(Token.tochars[TOK.TOKimmutable]);
+	    break;
+
+	case MOD.MODshared:
+	    buf.writestring(Token.tochars[TOK.TOKshared]);
+	    break;
+
+	case MOD.MODshared | MOD.MODconst:
+	    buf.writestring(Token.tochars[TOK.TOKshared]);
+	    buf.writeByte(' ');
+	case MOD.MODconst:
+	    buf.writestring(Token.tochars[TOK.TOKconst]);
+	    break;
+
+	case MOD.MODshared | MOD.MODwild:
+	    buf.writestring(Token.tochars[TOK.TOKshared]);
+	    buf.writeByte(' ');
+	case MOD.MODwild:
+	    buf.writestring(Token.tochars[TOKwild]);
+	    break;
+	default:
+	    assert(0);
+    }
+}
+
 class Type
 {
     TY ty;
@@ -137,12 +241,16 @@
      * They should not be referenced by anybody but mtype.c.
      * They can be null if not lazily evaluated yet.
      * Note that there is no "shared immutable", because that is just immutable
+     * Naked == no MOD bits
      */
 
-    Type cto;		// MODconst ? mutable version of this type : const version
-    Type ito;		// MODinvariant ? mutable version of this type : invariant version
-    Type sto;		// MODshared ? mutable version of this type : shared mutable version
-    Type scto;		// MODshared|MODconst ? mutable version of this type : shared const version
+    Type cto;		// MODconst ? naked version of this type : const version
+    Type ito;		// MODimmutable ? naked version of this type : immutable version
+    Type sto;		// MODshared ? naked version of this type : shared mutable version
+    Type scto;		// MODshared|MODconst ? naked version of this type : shared const version
+    Type wto;		// MODwild ? naked version of this type : wild version
+    Type swto;		// MODshared|MODwild ? naked version of this type : shared wild version
+
 
     Type pto;		// merged pointer to this type
     Type rto;		// reference to this type
@@ -167,6 +275,7 @@
     static ClassDeclaration typeinfoconst;
     static ClassDeclaration typeinfoinvariant;
     static ClassDeclaration typeinfoshared;
+    static ClassDeclaration typeinfowild;
 
     static Type basic[TY.TMAX];
     static ubyte mangleChar[TY.TMAX];
@@ -397,8 +506,8 @@
     DYNCAST dyncast() { return DYNCAST.DYNCAST_TYPE; } // kludge for template.isType()
 
 	/*******************************
-	 * Covariant means that 'this' can substitute for 't'.
-	 * Returns:
+     * Covariant means that 'this' can substitute for 't',
+     * i.e. a pure function is a match for an impure type.	 * Returns:
 	 *	0	types are distinct
 	 *	1	this is covariant with t
 	 *	2	arguments match as far as overloading goes,
@@ -434,14 +543,14 @@
 
 		if (t1.parameters && t2.parameters)
 		{
-			size_t dim = Argument.dim(t1.parameters);
-			if (dim != Argument.dim(t2.parameters))
+			size_t dim = Parameter.dim(t1.parameters);
+			if (dim != Parameter.dim(t2.parameters))
 				goto Ldistinct;
 
 			for (size_t i = 0; i < dim; i++)
 			{   
-				Argument arg1 = Argument.getNth(t1.parameters, i);
-				Argument arg2 = Argument.getNth(t2.parameters, i);
+				auto arg1 = Parameter.getNth(t1.parameters, i);
+				auto arg2 = Parameter.getNth(t2.parameters, i);
 
 				if (!arg1.type.equals(arg2.type))
 				{
@@ -453,7 +562,8 @@
 ///}
 					goto Ldistinct;
 				}
-				if ((arg1.storageClass & ~STC.STCscope) != (arg2.storageClass & ~STC.STCscope))
+                const StorageClass sc = STC.STCref | STC.STCin | STC.STCout | STC.STClazy;
+				if ((arg1.storageClass & sc) != (arg2.storageClass & sc))
 					inoutmismatch = 1;
 				// We can add scope, but not subtract it
 				if (!(arg1.storageClass & STC.STCscope) && (arg2.storageClass & STC.STCscope))
@@ -486,7 +596,7 @@
 			 * forward references.
 			 */
 			if ((cast(TypeClass)t1n).sym == (cast(TypeClass)t2n).sym &&
-				t2n.mod == MOD.MODconst)
+				MODimplicitConv(t1n.mod, t2n.mod))
 				goto Lcovariant;
 
 			// If t1n is forward referenced:
@@ -505,6 +615,9 @@
 	Lcovariant:
 		/* Can convert mutable to const
 		 */
+        if (!MODimplicitConv(t2.mod, t1.mod))
+	        goto Lnotcovariant;
+static if(false) {
 		if (t1.mod != t2.mod)
 		{
 			if (!(t1.mod & MOD.MODconst) && (t2.mod & MOD.MODconst))
@@ -512,7 +625,7 @@
 			if (!(t1.mod & MOD.MODshared) && (t2.mod & MOD.MODshared))
 				goto Lnotcovariant;
 		}
-
+}
 		/* Can convert pure to impure, and nothrow to throw
 		 */
 		if (!t1.ispure && t2.ispure)
@@ -522,6 +635,11 @@
 			goto Lnotcovariant;
 
 		if (t1.isref != t2.isref)
+	        goto Lnotcovariant;
+
+        /* Can convert safe/trusted to system
+         */
+        if (t1.trust <= TRUST.TRUSTsystem && t2.trust >= TRUST.TRUSTtrusted)
 			goto Lnotcovariant;
 
 		//printf("\tcovaraint: 1\n");
@@ -616,6 +734,7 @@
 		mangleChar[TY.Twchar] = 'u';
 		mangleChar[TY.Tdchar] = 'w';
 
+        // '@' shouldn't appear anywhere in the deco'd names
 		mangleChar[TY.Tbit] = '@';
 		mangleChar[TY.Tinstance] = '@';
 		mangleChar[TY.Terror] = '@';
@@ -724,16 +843,7 @@
 	{
 		if (flag != mod && flag != 0x100)
 		{
-			if (mod & MOD.MODshared)
-				buf.writeByte('O');
-
-			if (mod & MOD.MODconst)
-				buf.writeByte('x');
-			else if (mod & MOD.MODinvariant)
-				buf.writeByte('y');
-
-			// Cannot be both const and invariant
-			assert((mod & (MOD.MODconst | MOD.MODinvariant)) != (MOD.MODconst | MOD.MODinvariant));
+			MODtoDecoBuffer(buf, mod);
 		}
 		buf.writeByte(mangleChar[ty]);
 	}
@@ -820,40 +930,35 @@
 	{
 		if (mod != this.mod)
 		{
-			string p;
-
 			if (this.mod & MOD.MODshared)
-				buf.writestring("shared(");
+	        {
+	            MODtoBuffer(buf, this.mod & MOD.MODshared);
+	            buf.writeByte('(');
+	        }
 
-			switch (this.mod & (MOD.MODconst | MOD.MODinvariant))
-			{
-				case MOD.MODundefined:
-					toCBuffer2(buf, hgs, this.mod);
-					break;
-				case MOD.MODconst:
-					p = "const(";
-					goto L1;
-				case MOD.MODinvariant:
-					p = "immutable(";
-					L1:	buf.writestring(p);
-					toCBuffer2(buf, hgs, this.mod);
-					buf.writeByte(')');
-					break;
-			}
-
-			if (this.mod & MOD.MODshared)
-				buf.writeByte(')');
+	        if (this.mod & ~MOD.MODshared)
+	        {
+	            MODtoBuffer(buf, this.mod & ~MOD.MODshared);
+	            buf.writeByte('(');
+	            toCBuffer2(buf, hgs, this.mod);
+	            buf.writeByte(')');
+	        }
+	        else
+	            toCBuffer2(buf, hgs, this.mod);
+	        if (this.mod & MOD.MODshared)
+	        {
+	            buf.writeByte(')');
+	        }
 		}
 	}
 
     void modToBuffer(OutBuffer buf)
 	{
-		if (mod & MOD.MODshared)
-			buf.writestring(" shared");
-		if (mod & MOD.MODconst)
-			buf.writestring(" const");
-		if (mod & MOD.MODinvariant)
-			buf.writestring(" immutable");
+        if (mod)
+        {
+    	    buf.writeByte(' ');
+	        MODtoBuffer(buf, mod);
+        }
 	}
 
 version (CPP_MANGLE) {
@@ -936,13 +1041,20 @@
 
     bool isConst()	{ return (mod & MOD.MODconst) != 0; }
 
-	int isInvariant()	{ return mod & MOD.MODinvariant; }
+	int isImmutable()	{ return mod & MOD.MODimmutable; }
 
-	int isMutable()	{ return !(mod & (MOD.MODconst | MOD.MODinvariant)); }
+	int isMutable()	{ return !(mod & (MOD.MODconst | MOD.MODimmutable | MOD.MODwild)); }
 
 	int isShared()	{ return mod & MOD.MODshared; }
 
 	int isSharedConst()	{ return mod == (MOD.MODshared | MOD.MODconst); }
+            
+    int isWild()	{ return mod & MOD.MODwild; }
+
+    int isSharedWild()	{ return mod == (MOD.MODshared | MOD.MODwild); }
+
+    int isNaked()	{ return mod == 0; }
+
 
 	/********************************
 	 * Convert to 'const'.
@@ -970,13 +1082,13 @@
     Type invariantOf()
 	{	
 		//printf("Type.invariantOf() %p %s\n", this, toChars());
-		if (isInvariant())
+		if (isImmutable())
 		{
 			return this;
 		}
 		if (ito)
 		{
-			assert(ito.isInvariant());
+			assert(ito.isImmutable());
 			return ito;
 		}
 		Type t = makeInvariant();
@@ -995,51 +1107,29 @@
 			if (isShared())
 				t = sto;		// shared const => shared
 			else
-				t = cto;
+				t = cto;		// const => naked
 			assert(!t || t.isMutable());
 		}
-		else if (isInvariant())
+		else if (isImmutable())
 		{	
 			t = ito;
 			assert(!t || (t.isMutable() && !t.isShared()));
 		}
+        else if (isWild())
+        {
+	        if (isShared())
+	            t = sto;		// shared wild => shared
+	        else
+	            t = wto;		// wild => naked
+	        assert(!t || t.isMutable());
+        }
 		if (!t)
 		{
-			uint sz = this.classinfo.init.length;
-			t = cast(Type)GC.malloc(sz);
-			memcpy(cast(void*)t, cast(void*)this, sz);
-			t.mod = mod & MODshared;
-			t.deco = null;
-			t.arrayof = null;
-			t.pto = null;
-			t.rto = null;
-			t.cto = null;
-			t.ito = null;
-			t.sto = null;
-			t.scto = null;
-			t.vtinfo = null;
+            t = makeMutable();
 			t = t.merge();
-
 			t.fixTo(this);
-
-			switch (mod)
-			{
-				case MODconst:
-					t.cto = this;
-					break;
-
-				case MODinvariant:
-					t.ito = this;
-					break;
-
-				case MODshared | MODconst:
-					t.scto = this;
-					break;
-
-				default:
-					assert(0);
-			}
 		}
+            assert(t.isMutable());
 		return t;
 	}
 
@@ -1087,6 +1177,13 @@
 
 	/********************************
 	 * Make type unshared.
+     *	0            => 0
+     *	const        => const
+     *	immutable    => immutable
+     *	shared       => 0
+     *	shared const => const
+     *	wild         => wild
+     *	shared wild  => wild
 	 */
 	Type unSharedOf()
 	{
@@ -1097,6 +1194,8 @@
 		{
 			if (isConst())
 				t = cto;	// shared const => const
+	        else if (isWild())
+	            t = wto;	// shared wild => wild
 			else
 				t = sto;
 			assert(!t || !t.isShared());
@@ -1116,37 +1215,68 @@
 			t.ito = null;
 			t.sto = null;
 			t.scto = null;
+	        t.wto = null;
+	        t.swto = null;
 			t.vtinfo = null;
 			t = t.merge();
 	
 			t.fixTo(this);
-	
-			switch (mod)
-			{
-				case MODshared:
-				t.sto = this;
-				break;
-	
-				case MODshared | MODconst:
-				t.scto = this;
-				break;
-	
-				default:
-				assert(0);
-			}
 		}
 		assert(!t.isShared());
 		return t;
 	}
 
+            
+    /********************************
+     * Convert to 'wild'.
+     */
+
+    Type wildOf()
+    {
+        //printf("Type::wildOf() %p %s\n", this, toChars());
+        if (mod == MOD.MODwild)
+        {
+	        return this;
+        }
+        if (wto)
+        {
+    	    assert(wto.isWild());
+	        return wto;
+        }
+        Type t = makeWild();
+        t = t.merge();
+        t.fixTo(this);
+        //printf("\t%p %s\n", t, t->toChars());
+        return t;
+    }
+
+    Type sharedWildOf()
+    {
+        //printf("Type::sharedWildOf() %p, %s\n", this, toChars());
+        if (mod == (MOD.MODwild))
+        {
+    	    return this;
+        }
+        if (swto)
+        {
+	        assert(swto.mod == (MOD.MODshared | MOD.MODwild));
+	        return swto;
+        }
+        Type t = makeSharedWild();
+        t = t.merge();
+        t.fixTo(this);
+        //printf("\t%p\n", t);
+        return t;
+    }
+
 	static uint X(MOD m, MOD n)
 	{
-		return (((m) << 3) | (n));
+		return (((m) << 4) | (n));
 	}
 
 	/**********************************
 	 * For our new type 'this', which is type-constructed from t,
-	 * fill in the cto, ito, sto, scto shortcuts.
+	 * fill in the cto, ito, sto, scto, wto shortcuts.
 	 */
     void fixTo(Type t)
 	{
@@ -1169,7 +1299,7 @@
 			cto = t;
 			break;
 
-		case X(MOD.MODundefined, MOD.MODinvariant):
+		case X(MOD.MODundefined, MOD.MODimmutable):
 			ito = t;
 			break;
 
@@ -1181,12 +1311,20 @@
 			scto = t;
 			break;
 
+        case X(MOD.MODundefined, MODwild):
+    	    wto = t;
+	        break;
+
+	    case X(MOD.MODundefined, MODshared | MODwild):
+    	    swto = t;
+	        break;
+
 
 		case X(MOD.MODconst, MOD.MODundefined):
 			cto = null;
 			goto L2;
 
-		case X(MOD.MODconst, MOD.MODinvariant):
+		case X(MOD.MODconst, MOD.MODimmutable):
 			ito = t;
 			goto L2;
 
@@ -1196,30 +1334,48 @@
 
 		case X(MOD.MODconst, MOD.MODshared | MOD.MODconst):
 			scto = t;
+	        goto L2;
+
+	    case X(MOD.MODconst, MOD.MODwild):
+	        wto = t;
+	        goto L2;
+
+	    case X(MOD.MODconst, MOD.MODshared | MOD.MODwild):
+	        swto = t;
 		L2:
 			t.cto = this;
 			break;
 
 
-		case X(MOD.MODinvariant, MOD.MODundefined):
+		case X(MOD.MODimmutable, MOD.MODundefined):
 			ito = null;
 			goto L3;
 
-		case X(MOD.MODinvariant, MOD.MODconst):
+		case X(MOD.MODimmutable, MOD.MODconst):
 			cto = t;
 			goto L3;
 
-		case X(MOD.MODinvariant, MOD.MODshared):
+		case X(MOD.MODimmutable, MOD.MODshared):
 			sto = t;
 			goto L3;
 
-		case X(MOD.MODinvariant, MOD.MODshared | MOD.MODconst):
+		case X(MOD.MODimmutable, MOD.MODshared | MOD.MODconst):
 			scto = t;
+	        goto L3;
+
+	    case X(MOD.MODimmutable, MOD.MODwild):
+	        wto = t;
+	        goto L3;
+
+	    case X(MOD.MODimmutable, MOD.MODshared | MOD.MODwild):
+	        swto = t;
 		L3:
 			t.ito = this;
 			if (t.cto) t.cto.ito = this;
 			if (t.sto) t.sto.ito = this;
 			if (t.scto) t.scto.ito = this;
+	        if (t.wto) t.wto.ito = this;
+	        if (t.swto) t.swto.ito = this;
 			break;
 
 
@@ -1231,12 +1387,20 @@
 			cto = t;
 			goto L4;
 
-		case X(MOD.MODshared, MOD.MODinvariant):
+		case X(MOD.MODshared, MOD.MODimmutable):
 			ito = t;
 			goto L4;
 
 		case X(MOD.MODshared, MOD.MODshared | MOD.MODconst):
 			scto = t;
+	        goto L4;
+
+	    case X(MOD.MODshared, MOD.MODwild):
+	        wto = t;
+	        goto L4;
+
+	    case X(MOD.MODshared, MOD.MODshared | MOD.MODwild):
+	        swto = t;
 		L4:
 			t.sto = this;
 			break;
@@ -1244,21 +1408,82 @@
 
 		case X(MOD.MODshared | MOD.MODconst, MOD.MODundefined):
 			scto = null;
-			break;
+			goto L5;
 
 		case X(MOD.MODshared | MOD.MODconst, MOD.MODconst):
 			cto = t;
-			break;
+			goto L5;
 
-		case X(MOD.MODshared | MOD.MODconst, MOD.MODinvariant):
+		case X(MOD.MODshared | MOD.MODconst, MOD.MODimmutable):
 			ito = t;
-			break;
+	        goto L5;
+
+	    case X(MOD.MODshared | MOD.MODconst, MOD.MODwild):
+	        wto = t;
+	        goto L5;
 
 		case X(MOD.MODshared | MOD.MODconst, MOD.MODshared):
 			sto = t;
+	        goto L5;
+
+	    case X(MOD.MODshared | MOD.MODconst, MOD.MODshared | MOD.MODwild):
+	        swto = t;
 		L5:
 			t.scto = this;
 			break;
+            
+	    case X(MOD.MODwild, MOD.MODundefined):
+	        wto = null;
+	        goto L6;
+
+	    case X(MOD.MODwild, MOD.MODconst):
+	        cto = t;
+	        goto L6;
+
+	    case X(MOD.MODwild, MOD.MODimmutable):
+	        ito = t;
+	        goto L6;
+
+	    case X(MOD.MODwild, MOD.MODshared):
+	        sto = t;
+	        goto L6;
+
+	    case X(MOD.MODwild, MOD.MODshared | MOD.MODconst):
+	        scto = t;
+	        goto L6;
+
+	    case X(MOD.MODwild, MOD.MODshared | MOD.MODwild):
+	        swto = t;
+	    L6:
+	        t.wto = this;
+	        break;
+
+
+	    case X(MOD.MODshared | MOD.MODwild, MOD.MODundefined):
+	        swto = null;
+	        goto L7;
+
+	    case X(MOD.MODshared | MOD.MODwild, MOD.MODconst):
+	        cto = t;
+	        goto L7;
+
+	    case X(MOD.MODshared | MOD.MODwild, MOD.MODimmutable):
+	        ito = t;
+	        goto L7;
+
+	    case X(MOD.MODshared | MOD.MODwild, MOD.MODshared):
+	        sto = t;
+	        goto L7;
+
+	    case X(MOD.MODshared | MOD.MODwild, MOD.MODshared | MOD.MODconst):
+	        scto = t;
+	        goto L7;
+
+	    case X(MOD.MODshared | MOD.MODwild, MOD.MODwild):
+	        wto = t;
+	    L7:
+	        t.swto = this;
+	        break;
 		}
 
 		check();
@@ -1275,38 +1500,66 @@
 		{
 		case MOD.MODundefined:
 			if (cto) assert(cto.mod == MOD.MODconst);
-			if (ito) assert(ito.mod == MOD.MODinvariant);
+			if (ito) assert(ito.mod == MOD.MODimmutable);
 			if (sto) assert(sto.mod == MOD.MODshared);
 			if (scto) assert(scto.mod == (MOD.MODshared | MOD.MODconst));
+	        if (wto) assert(wto.mod == MOD.MODwild);
+	        if (swto) assert(swto.mod == (MOD.MODshared | MOD.MODwild));
 			break;
 
 		case MOD.MODconst:
 			if (cto) assert(cto.mod == MOD.MODundefined);
-			if (ito) assert(ito.mod == MOD.MODinvariant);
+			if (ito) assert(ito.mod == MOD.MODimmutable);
 			if (sto) assert(sto.mod == MOD.MODshared);
 			if (scto) assert(scto.mod == (MOD.MODshared | MOD.MODconst));
+	        if (wto) assert(wto.mod == MOD.MODwild);
+	        if (swto) assert(swto.mod == (MOD.MODshared | MOD.MODwild));
 			break;
 
-		case MOD.MODinvariant:
+		case MOD.MODimmutable:
 			if (cto) assert(cto.mod == MOD.MODconst);
 			if (ito) assert(ito.mod == MOD.MODundefined);
 			if (sto) assert(sto.mod == MOD.MODshared);
 			if (scto) assert(scto.mod == (MOD.MODshared | MOD.MODconst));
+	        if (wto) assert(wto.mod == MOD.MODwild);
+	        if (swto) assert(swto.mod == (MOD.MODshared | MOD.MODwild));
 			break;
 
 		case MOD.MODshared:
 			if (cto) assert(cto.mod == MOD.MODconst);
-			if (ito) assert(ito.mod == MOD.MODinvariant);
+			if (ito) assert(ito.mod == MOD.MODimmutable);
 			if (sto) assert(sto.mod == MOD.MODundefined);
 			if (scto) assert(scto.mod == (MOD.MODshared | MOD.MODconst));
+	        if (wto) assert(wto.mod == MOD.MODwild);
+	        if (swto) assert(swto.mod == (MOD.MODshared | MOD.MODwild));
 			break;
 
 		case MOD.MODshared | MOD.MODconst:
 			if (cto) assert(cto.mod == MOD.MODconst);
-			if (ito) assert(ito.mod == MOD.MODinvariant);
+			if (ito) assert(ito.mod == MOD.MODimmutable);
 			if (sto) assert(sto.mod == MOD.MODshared);
 			if (scto) assert(scto.mod == MOD.MODundefined);
+	        if (wto) assert(wto.mod == MOD.MODwild);
+	        if (swto) assert(swto.mod == (MOD.MODshared | MOD.MODwild));
 			break;
+            
+	    case MOD.MODwild:
+	        if (cto) assert(cto.mod == MOD.MODconst);
+	        if (ito) assert(ito.mod == MOD.MODimmutable);
+	        if (sto) assert(sto.mod == MOD.MODshared);
+	        if (scto) assert(scto.mod == (MOD.MODshared | MOD.MODconst));
+	        if (wto) assert(wto.mod == MOD.MODundefined);
+	        if (swto) assert(swto.mod == (MOD.MODshared | MOD.MODwild));
+	        break;
+
+	    case MOD.MODshared | MOD.MODwild:
+	        if (cto) assert(cto.mod == MOD.MODconst);
+	        if (ito) assert(ito.mod == MOD.MODimmutable);
+	        if (sto) assert(sto.mod == MOD.MODshared);
+	        if (scto) assert(scto.mod == (MOD.MODshared | MOD.MODconst));
+	        if (wto) assert(wto.mod == MOD.MODwild);
+	        if (swto) assert(swto.mod == MOD.MODundefined);
+	        break;
 		}
 
 		Type tn = nextOf();
@@ -1319,19 +1572,27 @@
 					break;
 
 				case MOD.MODconst:
-					assert(tn.mod & MOD.MODinvariant || tn.mod & MOD.MODconst);
+					assert(tn.mod & MOD.MODimmutable || tn.mod & MOD.MODconst);
 					break;
 
-				case MOD.MODinvariant:
-					assert(tn.mod == MOD.MODinvariant);
+				case MOD.MODimmutable:
+					assert(tn.mod == MOD.MODimmutable);
 					break;
 
 				case MOD.MODshared:
-					assert(tn.mod & MOD.MODinvariant || tn.mod & MOD.MODshared);
+					assert(tn.mod & MOD.MODimmutable || tn.mod & MOD.MODshared);
 					break;
 
 				case MOD.MODshared | MOD.MODconst:
-					assert(tn.mod & MOD.MODinvariant || tn.mod & (MOD.MODshared | MOD.MODconst));
+					assert(tn.mod & MOD.MODimmutable || tn.mod & (MOD.MODshared | MOD.MODconst));
+    		        break;
+
+	            case MOD.MODwild:
+	    	        assert(tn.mod);
+		            break;
+
+	            case MOD.MODshared | MOD.MODwild:
+		            assert(tn.mod == MOD.MODimmutable || tn.mod == (MOD.MODshared | MOD.MODconst) || tn.mod == (MOD.MODshared | MOD.MODwild));
 					break;
 			}
 			tn.check();
@@ -1348,23 +1609,31 @@
 		switch (mod)
 		{
 		case 0:
-			t = mutableOf();
+			t = unSharedOf().mutableOf();
 			break;
 
 		case MODconst:
-			t = constOf();
+			t = unSharedOf().constOf();
 			break;
 
-		case MODinvariant:
+		case MODimmutable:
 			t = invariantOf();
 			break;
 
 		case MODshared:
-			t = sharedOf();
+			t = mutableOf().sharedOf();
 			break;
 
 		case MODshared | MODconst:
 			t = sharedConstOf();
+	        break;
+
+	    case MODwild:
+	        t = unSharedOf().wildOf();
+	        break;
+
+	    case MODshared | MODwild:
+	        t = sharedWildOf();
 			break;
 
 		default:
@@ -1384,7 +1653,8 @@
 
 		/* Add anything to immutable, and it remains immutable
 		 */
-		if (!t.isInvariant())
+        //printf("addMod(%x) %s\n", mod, toChars());
+		if (!t.isImmutable())
 		{
 			switch (mod)
 			{
@@ -1398,13 +1668,15 @@
 						t = constOf();
 					break;
 
-				case MOD.MODinvariant:
+				case MOD.MODimmutable:
 					t = invariantOf();
 					break;
 
 				case MOD.MODshared:
 					if (isConst())
 						t = sharedConstOf();
+		            else if (isWild())
+		                t = sharedWildOf();
 					else
 						t = sharedOf();
 					break;
@@ -1412,25 +1684,40 @@
 				case MOD.MODshared | MOD.MODconst:
 					t = sharedConstOf();
 					break;
+                
+	            case MOD.MODwild:
+		            if (isConst())
+                    {}
+		            else if (isShared())
+		                t = sharedWildOf();
+		            else
+		                t = wildOf();
+		            break;
+
+	            case MOD.MODshared | MOD.MODwild:
+		            t = sharedWildOf();
+		            break;
 			}
 		}
 		return t;
 	}
 	
-    Type addStorageClass(STC stc)
+    Type addStorageClass(StorageClass stc)
 	{
 		/* Just translate to MOD bits and let addMod() do the work
 		 */
 		MOD mod = MOD.MODundefined;
 
 		if (stc & STC.STCimmutable)
-			mod = MOD.MODinvariant;
+			mod = MOD.MODimmutable;
 		else
 		{	
 			if (stc & (STC.STCconst | STC.STCin))
 				mod = MOD.MODconst;
 			if (stc & STC.STCshared)
 				mod |= MOD.MODshared;
+	        if (stc & STC.STCwild)
+	            mod |= MOD.MODwild;
 		}
 
 		return addMod(mod);
@@ -1502,6 +1789,8 @@
 		t.ito = null;
 		t.sto = null;
 		t.scto = null;
+        t.wto = null;
+        t.swto = null;
 		t.vtinfo = null;
 		
 		//printf("-Type.makeConst() %p, %s\n", t, toChars());
@@ -1515,7 +1804,7 @@
 		}
 
 		Type t = clone();
-		t.mod = MOD.MODinvariant;
+		t.mod = MOD.MODimmutable;
 
 		t.deco = null;
 		t.arrayof = null;
@@ -1525,6 +1814,8 @@
 		t.ito = null;
 		t.sto = null;
 		t.scto = null;
+        t.wto = null;
+        t.swto = null;
 		t.vtinfo = null;
 
 		return t;
@@ -1546,6 +1837,8 @@
 		t.ito = null;
 		t.sto = null;
 		t.scto = null;
+        t.wto = null;
+        t.swto = null;
 		t.vtinfo = null;
 
 		return t;
@@ -1567,11 +1860,73 @@
 		t.ito = null;
 		t.sto = null;
 		t.scto = null;
+        t.wto = null;
+        t.swto = null;
 		t.vtinfo = null;
 
 		return t;
 	}
 	
+    Type makeWild()
+    {
+        if (wto)
+	        return wto;
+        
+        Type t = clone();
+        t.mod = MOD.MODwild;
+        t.deco = null;
+        t.arrayof = null;
+        t.pto = null;
+        t.rto = null;
+        t.cto = null;
+        t.ito = null;
+        t.sto = null;
+        t.scto = null;
+        t.wto = null;
+        t.swto = null;
+        t.vtinfo = null;
+        return t;
+    }
+
+    Type makeSharedWild()
+    {
+        if (swto)
+	        return swto;
+        
+        Type t = clone();
+        t.mod = MOD.MODshared | MOD.MODwild;
+        t.deco = null;
+        t.arrayof = null;
+        t.pto = null;
+        t.rto = null;
+        t.cto = null;
+        t.ito = null;
+        t.sto = null;
+        t.scto = null;
+        t.wto = null;
+        t.swto = null;
+        t.vtinfo = null;
+        return t;
+    }
+
+    Type makeMutable()
+    {
+        Type t = clone();
+        t.mod =  mod & MOD.MODshared;
+        t.deco = null;
+        t.arrayof = null;
+        t.pto = null;
+        t.rto = null;
+        t.cto = null;
+        t.ito = null;
+        t.sto = null;
+        t.scto = null;
+        t.wto = null;
+        t.swto = null;
+        t.vtinfo = null;
+        return t;
+    }
+    
     Dsymbol toDsymbol(Scope sc)
 	{
 		return null;
@@ -1615,7 +1970,7 @@
 	{
 		if (equals(to))
 			return MATCH.MATCHexact;
-		if (ty == to.ty && to.mod == MOD.MODconst)
+		if (ty == to.ty && MODimplicitConv(mod, to.mod))
 			return MATCH.MATCHconst;
 		return MATCH.MATCHnomatch;
 	}
@@ -1765,11 +2120,11 @@
 			//		    if (!e.isConst())
 			//			error(loc, ".init cannot be evaluated at compile time");
 					}
-					return e;
+					goto Lreturn;
 				}
 }
-				Expression ex = defaultInit(e.loc);
-				return ex;
+				e = defaultInit(e.loc);
+	            goto Lreturn;
 			}
 		}
 		if (ident is Id.typeinfo_)
@@ -1777,19 +2132,89 @@
 			if (!global.params.useDeprecated)
 				error(e.loc, ".typeinfo deprecated, use typeid(type)");
 			e = getTypeInfo(sc);
-			return e;
 		}
-		if (ident is Id.stringof_)
+		else if (ident is Id.stringof_)
 		{		
 			string s = e.toChars();
 			e = new StringExp(e.loc, s, 'c');
-			scope Scope sc2 = new Scope(); ///
-			e = e.semantic(sc2);
-			return e;
 		}
-		return getProperty(e.loc, ident);
+        else
+    	    e = getProperty(e.loc, ident);
+        
+Lreturn:
+        e = e.semantic(sc);
+        return e;
 	}
 	
+    /***************************************
+     * Figures out what to do with an undefined member reference
+     * for classes and structs.
+     */
+    Expression noMember(Scope sc, Expression e, Identifier ident)
+    {
+        assert(ty == TY.Tstruct || ty == TY.Tclass);
+        AggregateDeclaration sym = toDsymbol(sc).isAggregateDeclaration();
+        assert(sym);
+
+        if (ident !is Id.__sizeof &&
+	    ident !is Id.alignof_ &&
+	    ident !is Id.init_ &&
+	    ident !is Id.mangleof_ &&
+	    ident !is Id.stringof_ &&
+	    ident !is Id.offsetof)
+        {
+	    /* See if we should forward to the alias this.
+	     */
+	    if (sym.aliasthis)
+	    {   /* Rewrite e.ident as:
+	         *	e.aliasthis.ident
+	         */
+	        e = new DotIdExp(e.loc, e, sym.aliasthis.ident);
+	        e = new DotIdExp(e.loc, e, ident);
+	        return e.semantic(sc);
+	    }
+
+	    /* Look for overloaded opDot() to see if we should forward request
+	     * to it.
+	     */
+	    Dsymbol fd = search_function(sym, Id.opDot);
+	    if (fd)
+	    {   /* Rewrite e.ident as:
+	         *	e.opDot().ident
+	         */
+	        e = build_overload(e.loc, sc, e, null, fd.ident);
+	        e = new DotIdExp(e.loc, e, ident);
+	        return e.semantic(sc);
+	    }
+
+	    /* Look for overloaded opDispatch to see if we should forward request
+	     * to it.
+	     */
+	    fd = search_function(sym, Id.opDispatch);
+	    if (fd)
+	    {
+	        /* Rewrite e.ident as:
+	         *	e.opDispatch!("ident")
+	         */
+	        TemplateDeclaration td = fd.isTemplateDeclaration();
+	        if (!td)
+	        {
+		    fd.error("must be a template opDispatch(string s), not a %s", fd.kind());
+		    return new ErrorExp();
+	        }
+	        auto se = new StringExp(e.loc, ident.toChars());
+	        auto tiargs = new Objects();
+	        tiargs.push(se);
+	        e = new DotTemplateInstanceExp(e.loc, e, Id.opDispatch, tiargs);
+	        (cast(DotTemplateInstanceExp)e).ti.tempdecl = td;
+	        return e;
+	        //return e.semantic(sc);
+	    }
+        }
+
+        return Type.dotExp(sc, e, ident);
+    }
+    
     uint memalign(uint salign)
 	{
 		return salign;
@@ -1801,6 +2226,18 @@
 		assert(false);
 	}
 	
+    /***************************************
+     * Use when we prefer the default initializer to be a literal,
+     * rather than a global immutable variable.
+     */
+    Expression defaultInitLiteral(Loc loc = Loc(0))
+    {
+version(LOGDEFAULTINIT) {
+        printf("Type::defaultInitLiteral() '%s'\n", toChars());
+}
+        return defaultInit(loc);
+    }
+
     ///bool isZeroInit(Loc loc = Loc(0))		// if initializer is 0
 	bool isZeroInit(Loc loc)		// if initializer is 0
 	{
@@ -1892,7 +2329,7 @@
 				Loc loc;
 				if (parameters.dim)
 				{
-					TemplateParameter tp = cast(TemplateParameter)parameters.data[0];
+					auto tp = parameters[0];
 					loc = tp.loc;
 				}
 
@@ -1904,46 +2341,58 @@
 				return deduceType(sc, tparam, parameters, dedtypes);
 			}
 
-			TemplateParameter tp = cast(TemplateParameter)parameters.data[i];
+			auto tp = parameters[i];
 
 			// Found the corresponding parameter tp
 			if (!tp.isTemplateTypeParameter())
 				goto Lnomatch;
 			Type tt = this;
-			Type at = cast(Type)dedtypes.data[i];
+			Type at = cast(Type)dedtypes[i];
 
 			// 5*5 == 25 cases
-			static pure int X(int U, int T) { return ((U << 3) | T); }
+			static pure int X(int U, int T) { return ((U << 4) | T); }
 			
 			switch (X(tparam.mod, mod))
 			{
 				case X(0, 0):
 				case X(0, MODconst):
-				case X(0, MODinvariant):
+				case X(0, MODimmutable):
 				case X(0, MODshared):
 				case X(0, MODconst | MODshared):
+	            case X(0, MODwild):
+	            case X(0, MODwild | MODshared):
 				// foo(U:U) T  							=> T
 				// foo(U:U) const(T)					=> const(T)
 				// foo(U:U) immutable(T)				=> immutable(T)
 				// foo(U:U) shared(T)					=> shared(T)
 				// foo(U:U) const(shared(T))			=> const(shared(T))
+		        // foo(U:U) wild(T)                        => wild(T)
+		        // foo(U:U) wild(shared(T))                => wild(shared(T))
 				if (!at)
-				{   dedtypes.data[i] = cast(void *)tt;
+				{   dedtypes[i] = tt;
 					goto Lexact;
 				}
 				break;
 
 				case X(MODconst, MODconst):
-				case X(MODinvariant, MODinvariant):
+				case X(MODimmutable, MODimmutable):
 				case X(MODshared, MODshared):
 				case X(MODconst | MODshared, MODconst | MODshared):
+	            case X(MODwild, MODwild):
+	            case X(MODwild | MODshared, MODwild | MODshared):
+	            case X(MODconst, MODwild):
+	            case X(MODconst, MODwild | MODshared):
 				// foo(U:const(U))			const(T)		=> T
 				// foo(U:immutable(U))		immutable(T)	=> T
 				// foo(U:shared(U))			shared(T)		=> T
 				// foo(U:const(shared(U))	const(shared(T))=> T
+		        // foo(U:wild(U))         wild(T)          => T
+		        // foo(U:wild(shared(U))  wild(shared(T)) => T
+        		// foo(U:const(U)) wild(shared(T))         => shared(T)
 				tt = mutableOf().unSharedOf();
 				if (!at)
-				{   dedtypes.data[i] = cast(void *)tt;
+				{
+					dedtypes[i] = tt;
 					goto Lexact;
 				}
 				break;
@@ -1952,13 +2401,15 @@
 				case X(MODconst, MODimmutable):
 				case X(MODconst, MODconst | MODshared):
 				case X(MODconst | MODshared, MODimmutable):
+        	    case X(MODshared, MODwild | MODshared):
 				// foo(U:const(U))			T					=> T
 				// foo(U:const(U))			immutable(T)		=> T
 				// foo(U:const(U))			const(shared(T))	=> shared(T)
 				// foo(U:const(shared(U))	immutable(T)		=> T
+        		// foo(U:shared(U)) wild(shared(T))        => wild(T)
 				tt = mutableOf();
 				if (!at)
-				{   dedtypes.data[i] = cast(void *)tt;
+				{   dedtypes[i] = tt;
 					goto Lconst;
 				}
 				break;
@@ -1969,7 +2420,7 @@
 				// foo(U:const(shared(U))	shared(T)			=> T
 				tt = unSharedOf();
 				if (!at)
-				{   dedtypes.data[i] = cast(void *)tt;
+				{   dedtypes[i] = tt;
 					goto Lconst;
 				}
 				break;
@@ -1984,6 +2435,23 @@
 				case X(MODshared,			MODimmutable):
 				case X(MODconst | MODshared, 0):
 				case X(MODconst | MODshared, MODconst):
+	            case X(MODimmutable,	 MODwild):
+	            case X(MODshared,		 MODwild):
+	            case X(MODconst | MODshared, MODwild):
+	            case X(MODwild,		 0):
+	            case X(MODwild,		 MODconst):
+	            case X(MODwild,		 MODimmutable):
+	            case X(MODwild,		 MODshared):
+	            case X(MODwild,		 MODconst | MODshared):
+	            case X(MODwild | MODshared,	 0):
+	            case X(MODwild | MODshared,	 MODconst):
+	            case X(MODwild | MODshared,  MODimmutable):
+	            case X(MODwild | MODshared,  MODshared):
+	            case X(MODwild | MODshared,  MODconst | MODshared):
+	            case X(MODwild | MODshared,  MODwild):
+	            case X(MODimmutable,	 MODwild | MODshared):
+	            case X(MODconst | MODshared, MODwild | MODshared):
+	            case X(MODwild,		 MODwild | MODshared):
 				// foo(U:immutable(U)) T				   => nomatch
 				// foo(U:immutable(U)) const(T)			=> nomatch
 				// foo(U:immutable(U)) shared(T)		   => nomatch
@@ -1994,6 +2462,23 @@
 				// foo(U:shared(U)) immutable(T)		   => nomatch
 				// foo(U:const(shared(U)) T				=> nomatch
 				// foo(U:const(shared(U)) const(T)		 => nomatch
+		        // foo(U:immutable(U)) wild(T)             => nomatch
+		        // foo(U:shared(U)) wild(T)                => nomatch
+		        // foo(U:const(shared(U)) wild(T)          => nomatch
+		        // foo(U:wild(U)) T                        => nomatch
+		        // foo(U:wild(U)) const(T)                 => nomatch
+		        // foo(U:wild(U)) immutable(T)             => nomatch
+		        // foo(U:wild(U)) shared(T)                => nomatch
+		        // foo(U:wild(U)) const(shared(T))         => nomatch
+		        // foo(U:wild(shared(U)) T 		   => nomatch
+		        // foo(U:wild(shared(U)) const(T)	   => nomatch
+		        // foo(U:wild(shared(U)) immutable(T)	   => nomatch
+		        // foo(U:wild(shared(U)) shared(T)         => nomatch
+		        // foo(U:wild(shared(U)) const(shared(T))  => nomatch
+		        // foo(U:wild(shared(U)) wild(T)	   => nomatch
+		        // foo(U:immutable(U)) wild(shared(T))     => nomatch
+		        // foo(U:const(shared(U))) wild(shared(T)) => nomatch
+		        // foo(U:wild(U)) wild(shared(T))          => nomatch
 				//if (!at)
 					goto Lnomatch;
 				break;
@@ -2121,8 +2606,11 @@
 				t.vtinfo = new TypeInfoSharedDeclaration(t);
 			else if (t.isConst())
 				t.vtinfo = new TypeInfoConstDeclaration(t);
-			else if (t.isInvariant())
+			else if (t.isImmutable())
 				t.vtinfo = new TypeInfoInvariantDeclaration(t);
+    	    else if (t.isWild())
+	            t.vtinfo = new TypeInfoWildDeclaration(t);
+
 			else
 				t.vtinfo = t.getTypeInfoDeclaration();
 } else {
@@ -2178,6 +2666,24 @@
 		return null;
 	}
 	
+    /***************************************
+     * Return !=0 if the type or any of its subtypes is wild.
+     */
+
+    int hasWild()
+    {
+        return mod & MOD.MODwild;
+    }
+
+    /***************************************
+     * Return MOD bits matching argument type (targ) to wild parameter type (this).
+     */
+
+    uint wildMatch(Type targ)
+    {
+        return 0;
+    }
+    
     Expression toExpression()
 	{
 		assert(false);
@@ -2319,14 +2825,16 @@
 		case MOD.MODundefined:
 			break;
 		case MOD.MODconst:
+	    case MOD.MODwild:
 			t |= mTY.mTYconst;
 			break;
-		case MOD.MODinvariant:
+		case MOD.MODimmutable:
 			t |= mTY.mTYimmutable;
 			break;
 		case MOD.MODshared:
 			t |= mTY.mTYshared;
 			break;
+        case MOD.MODshared | MOD.MODwild:
 		case MOD.MODshared | MOD.MODconst:
 			t |= mTY.mTYshared | mTY.mTYconst;
 			break;
--- a/dmd/TypeAArray.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeAArray.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TypeAArray;
 
+import dmd.common;
 import dmd.TypeArray;
 import dmd.MOD;
 import dmd.ArrayTypes;
@@ -115,7 +116,7 @@
 		else
 			index = index.semantic(loc,sc);
 
-		if (index.nextOf() && !index.nextOf().isInvariant())
+		if (index.nextOf() && !index.nextOf().isImmutable())
 		{
 			index = index.constOf().mutableOf();
 static if (false)
@@ -176,8 +177,8 @@
 				 */
 				TemplateInstance ti = new TemplateInstance(loc, Id.AssociativeArray);
 				Objects tiargs = new Objects();
-				tiargs.push(cast(void*)index);
-				tiargs.push(cast(void*)next);
+				tiargs.push(index);
+				tiargs.push(next);
 				ti.tiargs = tiargs;
 	
 				ti.semantic(sc);
@@ -329,9 +330,7 @@
 	version (LOGDEFAULTINIT) {
 		printf("TypeAArray.defaultInit() '%s'\n", toChars());
 	}
-		Expression e = new NullExp(loc);
-		e.type = this;
-		return e;
+		return new NullExp(loc, this);
 	}
 	
     override MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes)
@@ -356,12 +355,12 @@
 	
     override bool isZeroInit(Loc loc)
 	{
-		assert(false);
+		return true;
 	}
 	
     override bool checkBoolean()
 	{
-		assert(false);
+		return true;
 	}
 	
     override TypeInfoDeclaration getTypeInfoDeclaration()
@@ -384,10 +383,10 @@
 		{	
 			TypeAArray ta = cast(TypeAArray)to;
 
-			if (!(next.mod == ta.next.mod || ta.next.mod == MODconst))
+			if (!MODimplicitConv(next.mod, ta.next.mod))
 				return MATCHnomatch;	// not const-compatible
 
-			if (!(index.mod == ta.index.mod || ta.index.mod == MODconst))
+			if (!MODimplicitConv(index.mod, ta.index.mod))
 				return MATCHnomatch;	// not const-compatible
 
 			MATCH m = next.constConv(ta.next);
--- a/dmd/TypeArray.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeArray.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TypeArray;
 
+import dmd.common;
 import dmd.Type;
 import dmd.TypeNext;
 import dmd.Id;
@@ -121,6 +122,7 @@
 		{
 			e = Type.dotExp(sc, e, ident);
 		}
+        e = e.semantic(sc);
 		return e;
 	}
 	
--- a/dmd/TypeBasic.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeBasic.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TypeBasic;
 
+import dmd.common;
 import dmd.Type;
 import dmd.Id;
 import dmd.MOD;
@@ -307,6 +308,7 @@
 				case TY.Tcomplex80:
 				case TY.Timaginary80:
 				case TY.Tfloat80:	fvalue = real.min;		goto Lfvalue;
+                default:
 			}
 		}
 		else if (ident is Id.nan)
@@ -510,7 +512,8 @@
 					break;
 
 				default:
-					return Type.getProperty(e.loc, ident);
+		            e = Type.getProperty(e.loc, ident);
+		            break;
 			}
 		}
 		else if (ident is Id.im)
@@ -542,13 +545,15 @@
 					break;
 
 				default:
-					return Type.getProperty(e.loc, ident);
+		            e = Type.getProperty(e.loc, ident);
+		            break;
 			}
 		}
 		else
 		{
 			return Type.dotExp(sc, e, ident);
 		}
+        e = e.semantic(sc);
 		return e;
 	}
 	
--- a/dmd/TypeClass.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeClass.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TypeClass;
 
+import dmd.common;
 import dmd.Type;
 import dmd.ClassDeclaration;
 import dmd.TypeInstance;
@@ -199,7 +200,7 @@
 					 * at compile time.
 					 */
 					if (!sym.vclassinfo)
-						sym.vclassinfo = new ClassInfoDeclaration(sym);
+						sym.vclassinfo = new TypeInfoClassDeclaration(sym.type);
 
 					e = new VarExp(e.loc, sym.vclassinfo);
 					e = e.addressOf(sc);
@@ -272,41 +273,7 @@
 			}
 			else
 			{
-				if (ident !is Id.__sizeof	 &&
-					ident !is Id.alignof_ &&
-					ident !is Id.init_ &&
-					ident !is Id.mangleof_ &&
-					ident !is Id.stringof_ &&
-					ident !is Id.offsetof)
-				{
-					/* See if we should forward to the alias this.
-					 */
-					if (sym.aliasthis)
-					{   
-						/* Rewrite e.ident as:
-						 *	e.aliasthis.ident
-						 */
-						e = new DotIdExp(e.loc, e, sym.aliasthis.ident);
-						e = new DotIdExp(e.loc, e, ident);
-						return e.semantic(sc);
-					}
-
-					/* Look for overloaded opDot() to see if we should forward request
-					 * to it.
-					 */
-					Dsymbol fd = search_function(sym, Id.opDot);
-					if (fd)
-					{   
-						/* Rewrite e.ident as:
-						 *	e.opId().ident
-						 */
-						e = build_overload(e.loc, sc, e, null, fd.ident);
-						e = new DotIdExp(e.loc, e, ident);
-						return e.semantic(sc);
-					}
-				}
-
-				return Type.dotExp(sc, e, ident);
+				return noMember(sc, e, ident);
 			}
 		}
 
@@ -519,9 +486,7 @@
 version (LOGDEFAULTINIT) {
 		printf("TypeClass::defaultInit() '%s'\n", toChars());
 }
-		Expression e = new NullExp(loc);
-		e.type = this;
-		return e;
+		return new NullExp(loc, this);
 	}
 	
     override bool isZeroInit(Loc loc)
--- a/dmd/TypeDArray.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeDArray.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TypeDArray;
 
+import dmd.common;
 import dmd.TypeArray;
 import dmd.MOD;
 import dmd.Id;
@@ -194,7 +195,7 @@
 			/* Allow conversion to void*
 			 */
 			if (tp.next.ty == Tvoid &&
-				(next.mod == tp.next.mod || tp.next.mod == MODconst))
+				MODimplicitConv(next.mod, tp.next.mod))
 			{
 				return MATCHconvert;
 			}
@@ -207,7 +208,7 @@
 			int offset = 0;
 			TypeDArray ta = cast(TypeDArray)to;
 
-			if (!(next.mod == ta.next.mod || ta.next.mod == MODconst))
+			if (!MODimplicitConv(next.mod, ta.next.mod))
 				return MATCHnomatch;	// not const-compatible
 
 			/* Allow conversion to void[]
@@ -225,6 +226,7 @@
 				return m;
 			}
 
+static if(false) {
 			/* Allow conversions of T[][] to const(T)[][]
 			 */
 			if (mod == ta.mod && next.ty == Tarray && ta.next.ty == Tarray)
@@ -233,7 +235,7 @@
 				if (m == MATCHconst)
 				return m;
 			}
-
+}
 			/* Conversion of array of derived to array of base
 			 */
 			if (ta.next.isBaseOf(next, &offset) && offset == 0)
@@ -247,9 +249,7 @@
 	version (LOGDEFAULTINIT) {
 		printf("TypeDArray.defaultInit() '%s'\n", toChars());
 	}
-		Expression e = new NullExp(loc);
-		e.type = this;
-		return e;
+		return new NullExp(loc, this);
 	}
 	
     override bool builtinTypeInfo()
@@ -257,7 +257,7 @@
 	version (DMDV2) {
 		return !mod && (next.isTypeBasic() !is null && !next.mod ||
 			// strings are so common, make them builtin
-			next.ty == Tchar && next.mod == MODinvariant);
+			next.ty == Tchar && next.mod == MODimmutable);
 	} else {
 		return next.isTypeBasic() !is null;
 	}
--- a/dmd/TypeDelegate.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeDelegate.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TypeDelegate;
 
+import dmd.common;
 import dmd.Type;
 import dmd.TypeNext;
 import dmd.MOD;
@@ -15,7 +16,7 @@
 import dmd.Expression;
 import dmd.Identifier;
 import dmd.CppMangleState;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.Loc;
 import dmd.Scope;
 import dmd.TypeInfoDeclaration;
@@ -104,7 +105,7 @@
 
 		tf.next.toCBuffer2(buf, hgs, MODundefined);
 		buf.writestring(" delegate");
-		Argument.argsToCBuffer(buf, hgs, tf.parameters, tf.varargs);
+		Parameter.argsToCBuffer(buf, hgs, tf.parameters, tf.varargs);
 	}
 	
     override Expression defaultInit(Loc loc)
@@ -112,10 +113,7 @@
 	version (LOGDEFAULTINIT) {
 		printf("TypeDelegate.defaultInit() '%s'\n", toChars());
 	}
-		Expression e;
-		e = new NullExp(loc);
-		e.type = this;
-		return e;
+		return new NullExp(loc, this);
 	}
 	
     override bool isZeroInit(Loc loc)
--- a/dmd/TypeEnum.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeEnum.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TypeEnum;
 
+import dmd.common;
 import dmd.Type;
 import dmd.EnumDeclaration;
 import dmd.Scope;
@@ -188,11 +189,20 @@
 	
     override MATCH constConv(Type to)
 	{
-		assert(false);
+        if (equals(to))
+	        return MATCHexact;
+        if (ty == to.ty && sym == (cast(TypeEnum)to).sym &&
+	        MODimplicitConv(mod, to.mod))
+	        return MATCHconst;
+        return MATCHnomatch;
 	}
 	
     override Type toBasetype()
 	{
+        if (sym.scope_)
+        {
+    	    sym.semantic(null);	// attempt to resolve forward reference
+        }
 		if (!sym.memtype)
 		{
 			debug writef("2: ");
--- a/dmd/TypeExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,6 +1,9 @@
 module dmd.TypeExp;
 
+import dmd.common;
 import dmd.Expression;
+import dmd.backend.TYM;
+import dmd.backend.Util;
 import dmd.backend.elem;
 import dmd.Type;
 import dmd.OutBuffer;
@@ -41,7 +44,7 @@
 
 	override void rvalue()
 	{
-		assert(false);
+		error("type %s has no value", toChars());
 	}
 
 	override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
@@ -56,7 +59,11 @@
 
 	override elem* toElem(IRState* irs)
 	{
-		assert(false);
+		debug
+			writef("TypeExp.toElem()\n");
+
+		error("type %s is not an expression", toChars());
+		return el_long(TYint, 0);
 	}
 }
 
--- a/dmd/TypeFunction.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeFunction.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,8 +1,10 @@
 module dmd.TypeFunction;
 
+import dmd.common;
 import dmd.TypeNext;
 import dmd.TypeSArray;
 import dmd.TypeArray;
+import dmd.TemplateTupleParameter;
 import dmd.ArrayTypes;
 import dmd.LINK;
 import dmd.StructDeclaration;
@@ -11,6 +13,10 @@
 import dmd.STC;
 import dmd.MOD;
 import dmd.PROT;
+import dmd.TypeIdentifier;
+import dmd.TemplateParameter;
+import dmd.TypeInfoFunctionDeclaration;
+import dmd.Tuple;
 import dmd.Type;
 import dmd.Loc;
 import dmd.Scope;
@@ -20,11 +26,16 @@
 import dmd.CppMangleState;
 import dmd.TypeInfoDeclaration;
 import dmd.MATCH;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.Expression;
 import dmd.RET;
 import dmd.TY;
+import dmd.TRUST;
 import dmd.Util;
+import dmd.FuncDeclaration;
+import dmd.Dsymbol;
+import dmd.TypeTuple;
+import dmd.TemplateInstance : isTuple;
 
 import dmd.backend.TYPE;
 import dmd.backend.PARAM;
@@ -36,11 +47,13 @@
 import core.stdc.stdlib;
 import core.stdc.string;
 
+import std.stdio;
+
 class TypeFunction : TypeNext
 {
     // .next is the return type
 
-    Arguments parameters;	// function parameters
+    Parameters parameters;	// function parameters
     int varargs;	// 1: T t, ...) style for variable number of arguments
 			// 2: T t ...) style for variable number of arguments
     bool isnothrow;	// true: nothrow
@@ -48,10 +61,12 @@
     bool isproperty;	// can be called without parentheses
     bool isref;		// true: returns a reference
     LINK linkage;	// calling convention
+    TRUST trust;	// level of trust
+    Expressions fargs;	// function arguments
 
     int inuse;
 
-    this(Arguments parameters, Type treturn, int varargs, LINK linkage)
+    this(Parameters parameters, Type treturn, int varargs, LINK linkage)
 	{
 		super(TY.Tfunction, treturn);
 
@@ -61,18 +76,21 @@
 		this.parameters = parameters;
 		this.varargs = varargs;
 		this.linkage = linkage;
+        this.trust = TRUSTdefault;
 	}
 	
     override Type syntaxCopy()
 	{
 		Type treturn = next ? next.syntaxCopy() : null;
-		Arguments params = Argument.arraySyntaxCopy(parameters);
+		auto params = Parameter.arraySyntaxCopy(parameters);
 		TypeFunction t = new TypeFunction(params, treturn, varargs, linkage);
 		t.mod = mod;
 		t.isnothrow = isnothrow;
 		t.ispure = ispure;
 		t.isproperty = isproperty;
 		t.isref = isref;
+        t.trust = trust;
+        t.fargs = fargs;
 
 		return t;
 	}
@@ -97,11 +115,10 @@
 		if (parameters)
 		{
 			t.parameters = parameters.copy();
-			for (size_t i = 0; i < parameters.dim; i++)
+			foreach (arg; parameters)
 			{   
-				Argument arg = cast(Argument)parameters.data[i];
 				Argument cpy = arg.clone();
-				t.parameters.data[i] = cast(void*)cpy;
+				t.parameters[i] = cpy;
 			}
 		}
 
@@ -110,7 +127,7 @@
 
 	TypeFunction clone()
 	{
-		assert(this.classinfo == TypeFunction.classinfo);
+		assert(this.classinfo is TypeFunction.classinfo);
 		return cloneTo(new TypeFunction(null, next, varargs, linkage));
 	}
 }
@@ -122,14 +139,14 @@
 			return this;
 		}
 		//printf("TypeFunction.semantic() this = %p\n", this);
-		//printf("TypeFunction.semantic() %s, sc.stc = %x\n", toChars(), sc.stc);
+		//printf("TypeFunction::semantic() %s, sc->stc = %llx, fargs = %p\n", toChars(), sc->stc, fargs);
 
 		/* Copy in order to not mess up original.
 		 * This can produce redundant copies if inferring return type,
 		 * as semantic() will get called again on this.
 		 */
 
-		TypeFunction tf = cast(TypeFunction)clone();
+		TypeFunction tf = cloneThis(this);
 
 		if (sc.stc & STC.STCpure)
 			tf.ispure = true;
@@ -137,30 +154,61 @@
 			tf.isnothrow = true;
 		if (sc.stc & STC.STCref)
 			tf.isref = true;
+        if (sc.stc & STCsafe)
+    	    tf.trust = TRUST.TRUSTsafe;
+        if (sc.stc & STCtrusted)
+    	    tf.trust = TRUST.TRUSTtrusted;
+        if (sc.stc & STCproperty)
+	        tf.isproperty = true;
+        
+		tf.linkage = sc.linkage;
+        
+        /* If the parent is @safe, then this function defaults to safe
+         * too.
+         */
+        if (tf.trust == TRUST.TRUSTdefault)
+	        for (Dsymbol p = sc.func; p; p = p.toParent2())
+	        {   FuncDeclaration fd = p.isFuncDeclaration();
+	            if (fd)
+	            {
+    		        if (fd.isSafe())
+		                tf.trust = TRUST.TRUSTsafe;		// default to @safe
+		            break;
+	            }
+	        }
 
-		tf.linkage = sc.linkage;
+        bool wildreturn = false;
 		if (tf.next)
 		{
 			tf.next = tf.next.semantic(loc,sc);
 version(SARRAYVALUE) {} else
 {
 			if (tf.next.toBasetype().ty == TY.Tsarray)
-			{   error(loc, "functions cannot return static array %s", tf.next.toChars());
+			{   
+				error(loc, "functions cannot return static array %s", tf.next.toChars());
 				tf.next = Type.terror;
 			}
 }
 			if (tf.next.toBasetype().ty == TY.Tfunction)
-			{   error(loc, "functions cannot return a function");
+			{   
+				error(loc, "functions cannot return a function");
 				tf.next = Type.terror;
 			}
 			if (tf.next.toBasetype().ty == TY.Ttuple)
-			{   error(loc, "functions cannot return a tuple");
+			{   
+				error(loc, "functions cannot return a tuple");
 				tf.next = Type.terror;
 			}
 			if (tf.next.isauto() && !(sc.flags & SCOPE.SCOPEctor))
-			error(loc, "functions cannot return scope %s", tf.next.toChars());
-		}
+				error(loc, "functions cannot return scope %s", tf.next.toChars());
+	        if (tf.next.toBasetype().ty == TY.Tvoid)
+	            tf.isref = false;			// rewrite "ref void" as just "void"
+	        if (tf.next.isWild())
+	            wildreturn = true;
+        }
 
+        bool wildparams = false;
+        bool wildsubparams = false;
 		if (tf.parameters)
 		{	
 			/* Create a scope for evaluating the default arguments for the parameters
@@ -169,52 +217,100 @@
 			argsc.stc = STCundefined;			// don't inherit storage class
 			argsc.protection = PROT.PROTpublic;
 
-			size_t dim = Argument.dim(tf.parameters);
+			size_t dim = Parameter.dim(tf.parameters);
 
 			for (size_t i = 0; i < dim; i++)
-			{   Argument arg = Argument.getNth(tf.parameters, i);
+			{   auto fparam = Parameter.getNth(tf.parameters, i);
 
 				tf.inuse++;
-				arg.type = arg.type.semantic(loc, argsc);
+				fparam.type = fparam.type.semantic(loc, argsc);
 				if (tf.inuse == 1) tf.inuse--;
 
-				arg.type = arg.type.addStorageClass(arg.storageClass);
+				fparam.type = fparam.type.addStorageClass(fparam.storageClass);
 
-				if (arg.storageClass & (STC.STCauto | STC.STCalias | STC.STCstatic))
+				if (fparam.storageClass & (STC.STCauto | STC.STCalias | STC.STCstatic))
 				{
-					if (!arg.type)
+					if (!fparam.type)
 					continue;
 				}
 
-				Type t = arg.type.toBasetype();
+				Type t = fparam.type.toBasetype();
 
-				if (arg.storageClass & (STC.STCout | STC.STCref | STC.STClazy))
+				if (fparam.storageClass & (STC.STCout | STC.STCref | STC.STClazy))
 				{
 					//if (t.ty == TY.Tsarray)
 						//error(loc, "cannot have out or ref parameter of type %s", t.toChars());
-					if (arg.storageClass & STC.STCout && arg.type.mod & (STCconst | STCimmutable))
+					if (fparam.storageClass & STC.STCout && fparam.type.mod & (STCconst | STCimmutable))
 						error(loc, "cannot have const or immutabl out parameter of type %s", t.toChars());
 				}
-				if (!(arg.storageClass & STC.STClazy) && t.ty == TY.Tvoid)
-					error(loc, "cannot have parameter of type %s", arg.type.toChars());
+				if (!(fparam.storageClass & STC.STClazy) && t.ty == TY.Tvoid)
+					error(loc, "cannot have parameter of type %s", fparam.type.toChars());
 
-				if (arg.defaultArg)
-				{
-					arg.defaultArg = arg.defaultArg.semantic(argsc);
-					arg.defaultArg = resolveProperties(argsc, arg.defaultArg);
-					arg.defaultArg = arg.defaultArg.implicitCastTo(argsc, arg.type);
-				}
+	            if (t.isWild())
+	            {
+		            wildparams = true;
+		            if (tf.next && !wildreturn)
+		                error(loc, "inout on parameter means inout must be on return type as well (if from D1 code, replace with 'ref')");
+	            }
+	            else if (!wildsubparams && t.hasWild())
+		            wildsubparams = true;
 
-				/* If arg turns out to be a tuple, the number of parameters may
+	            if (fparam.defaultArg)
+	            {
+		            fparam.defaultArg = fparam.defaultArg.semantic(argsc);
+		            fparam.defaultArg = resolveProperties(argsc, fparam.defaultArg);
+		            fparam.defaultArg = fparam.defaultArg.implicitCastTo(argsc, fparam.type);
+	            }
+
+				/* If fparam turns out to be a tuple, the number of parameters may
 				 * change.
 				 */
 				if (t.ty == TY.Ttuple)
-				{	dim = Argument.dim(tf.parameters);
+	            {
+		        // Propagate storage class from tuple parameters to their element-parameters.
+		            auto tt = cast(TypeTuple)t;
+		            if (tt.arguments)
+		            {
+		                auto tdim = tt.arguments.dim;
+		                foreach (narg; tt.arguments)
+		                {
+			                narg.storageClass = fparam.storageClass;
+		                }
+		            }
+
+		            /* Reset number of parameters, and back up one to do this fparam again,
+		             * now that it is the first element of a tuple
+		             */
+		            dim = Parameter.dim(tf.parameters);
 					i--;
+                    continue;
 				}
+
+	            /* Resolve "auto ref" storage class to be either ref or value,
+	             * based on the argument matching the parameter
+	             */
+	            if (fparam.storageClass & STC.STCauto)
+	            {
+		            if (fargs && i < fargs.dim)
+		            {
+                        auto farg = fargs[i];
+		                if (farg.isLvalue())
+                            {}				// ref parameter
+		                else
+			                fparam.storageClass &= ~STC.STCref;	// value parameter
+		            }
+		            else
+		                error(loc, "auto can only be used for template function parameters");
+	            }
 			}
 			argsc.pop();
 		}
+
+        if (wildreturn && !wildparams)
+	    error(loc, "inout on return means inout must be on a parameter as well for %s", toChars());
+        if (wildsubparams && wildparams)
+	    error(loc, "inout must be all or none on top level for %s", toChars());
+
 		if (tf.next)
 		tf.deco = tf.merge().deco;
 
@@ -224,7 +320,10 @@
 			return terror;
 		}
 
-		if (tf.varargs == 1 && tf.linkage != LINK.LINKd && Argument.dim(tf.parameters) == 0)
+        if (tf.isproperty && (tf.varargs || Parameter.dim(tf.parameters) > 1))
+	    error(loc, "properties can only have zero or one parameter");
+
+		if (tf.varargs == 1 && tf.linkage != LINK.LINKd && Parameter.dim(tf.parameters) == 0)
 			error(loc, "variadic functions with non-D linkage must have at least one parameter");
 
 		/* Don't return merge(), because arg identifiers and default args
@@ -246,14 +345,7 @@
 			return;
 		}
 		inuse++;
-static if (true) {
-		if (mod & MOD.MODshared)
-			buf.writeByte('O');
-		if (mod & MOD.MODconst)
-			buf.writeByte('x');
-		else if (mod & MOD.MODinvariant)
-			buf.writeByte('y');
-}
+        MODtoDecoBuffer(buf, mod);
 		switch (linkage)
 		{
 			case LINK.LINKd:		mc = 'F';	break;
@@ -263,7 +355,7 @@
 			case LINK.LINKcpp:		mc = 'R';	break;
 		}
 		buf.writeByte(mc);
-		if (ispure || isnothrow || isproperty || isref)
+		if (ispure || isnothrow || isproperty || isref || trust)
 		{
 			if (ispure)
 				buf.writestring("Na");
@@ -273,9 +365,19 @@
 				buf.writestring("Nc");
 			if (isproperty)
 				buf.writestring("Nd");
+	        switch (trust)
+	        {
+	            case TRUST.TRUSTtrusted:
+		            buf.writestring("Ne");
+		            break;
+	            case TRUST.TRUSTsafe:
+		            buf.writestring("Nf");
+		            break;
+                default:
+	        }
 		}
 		// Write argument types
-		Argument.argsToDecoBuffer(buf, parameters);
+		Parameter.argsToDecoBuffer(buf, parameters);
 		//if (buf.data[buf.offset - 1] == '@') halt();
 		buf.writeByte('Z' - varargs);	// mark end of arg list
 		assert(next);
@@ -297,12 +399,11 @@
 
 		/* Use 'storage class' style for attributes
 		 */
-		if (mod & MODconst)
-			buf.writestring("const ");
-		if (mod & MODinvariant)
-			buf.writestring("immutable ");
-		if (mod & MODshared)
-			buf.writestring("shared ");
+	    if (mod)
+        {
+	        MODtoBuffer(buf, mod);
+	        buf.writeByte(' ');
+        }
 
 		if (ispure)
 			buf.writestring("pure ");
@@ -313,6 +414,17 @@
 		if (isref)
 			buf.writestring("ref ");
 
+        switch (trust)
+        {
+	    case TRUST.TRUSTtrusted:
+	        buf.writestring("@trusted ");
+	        break;
+
+	    case TRUST.TRUSTsafe:
+	        buf.writestring("@safe ");
+	        break;
+        }
+
 		if (next && (!ident || ident.toHChars2() == ident.toChars()))
 			next.toCBuffer2(buf, hgs, MODundefined);
 		if (hgs.ddoc != 1)
@@ -336,7 +448,7 @@
 			buf.writeByte(' ');
 			buf.writestring(ident.toHChars2());
 		}
-		Argument.argsToCBuffer(buf, hgs, parameters, varargs);
+		Parameter.argsToCBuffer(buf, hgs, parameters, varargs);
 		inuse--;
 	}
 	
@@ -371,7 +483,7 @@
 		if (!hgs.hdrgen && p)
 			buf.writestring(p);
 		buf.writestring(" function");
-		Argument.argsToCBuffer(buf, hgs, parameters, varargs);
+		Parameter.argsToCBuffer(buf, hgs, parameters, varargs);
 
 		/* Use postfix style for attributes
 		 */
@@ -389,32 +501,135 @@
 		if (isref)
 			buf.writestring(" ref");
 
+        switch (trust)
+        {
+	    case TRUSTtrusted:
+	        buf.writestring(" @trusted");
+	        break;
+
+	    case TRUSTsafe:
+	        buf.writestring(" @safe");
+	        break;
+
+		default:
+        }
 		inuse--;
 	}
 	
     override MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes)
 	{
-		assert(false);
+		//printf("TypeFunction.deduceType()\n");
+		//printf("\tthis   = %d, ", ty); print();
+		//printf("\ttparam = %d, ", tparam.ty); tparam.print();
+
+		// Extra check that function characteristics must match
+		if (tparam && tparam.ty == Tfunction)
+		{
+			TypeFunction tp = cast(TypeFunction)tparam;
+			if (varargs != tp.varargs ||
+				linkage != tp.linkage)
+				return MATCHnomatch;
+
+			size_t nfargs = Parameter.dim(this.parameters);
+			size_t nfparams = Parameter.dim(tp.parameters);
+
+			/* See if tuple match
+			 */
+			if (nfparams > 0 && nfargs >= nfparams - 1)
+			{
+				/* See if 'A' of the template parameter matches 'A'
+				 * of the type of the last function parameter.
+				 */
+				auto fparam = Parameter.getNth(tp.parameters, nfparams - 1);
+				assert(fparam);
+				assert(fparam.type);
+				if (fparam.type.ty != Tident)
+					goto L1;
+				TypeIdentifier tid = cast(TypeIdentifier)fparam.type;
+				if (tid.idents.dim)
+					goto L1;
+
+				/* Look through parameters to find tuple matching tid.ident
+				 */
+				size_t tupi = 0;
+				for (; 1; tupi++)
+				{	
+					if (tupi == parameters.dim)
+						goto L1;
+					TemplateParameter t = parameters[tupi];
+					TemplateTupleParameter tup = t.isTemplateTupleParameter();
+					if (tup && tup.ident.equals(tid.ident))
+						break;
+				}
+
+				/* The types of the function arguments [nfparams - 1 .. nfargs]
+				 * now form the tuple argument.
+				 */
+				int tuple_dim = nfargs - (nfparams - 1);
+
+				/* See if existing tuple, and whether it matches or not
+				 */
+				Object o = dedtypes[tupi];
+				if (o)
+				{	
+					// Existing deduced argument must be a tuple, and must match
+					Tuple t = isTuple(o);
+					if (!t || t.objects.dim != tuple_dim)
+						return MATCHnomatch;
+					for (size_t i = 0; i < tuple_dim; i++)
+					{   
+						auto arg = Parameter.getNth(this.parameters, nfparams - 1 + i);
+						if (!arg.type.equals(t.objects[i]))
+							return MATCHnomatch;
+					}
+				}
+				else
+				{	// Create new tuple
+					Tuple t = new Tuple();
+					t.objects.setDim(tuple_dim);
+					for (size_t i = 0; i < tuple_dim; i++)
+					{   
+						auto arg = Parameter.getNth(this.parameters, nfparams - 1 + i);
+						t.objects[i] = arg.type;
+					}
+					dedtypes[tupi] = t;
+				}
+				nfparams--;	// don't consider the last parameter for type deduction
+				goto L2;
+			}
+
+			L1:
+			if (nfargs != nfparams)
+				return MATCHnomatch;
+			L2:
+			for (size_t i = 0; i < nfparams; i++)
+			{
+				auto a = Parameter.getNth(this.parameters, i);
+				auto ap = Parameter.getNth(tp.parameters, i);
+				if (a.storageClass != ap.storageClass ||
+					!a.type.deduceType(sc, ap.type, parameters, dedtypes))
+				return MATCHnomatch;
+			}
+		}
+		return Type.deduceType(sc, tparam, parameters, dedtypes);
 	}
 	
     override TypeInfoDeclaration getTypeInfoDeclaration()
 	{
-		assert(false);
+		return new TypeInfoFunctionDeclaration(this);
 	}
 	
     override Type reliesOnTident()
 	{
-		if (parameters)
-		{
-			for (size_t i = 0; i < parameters.dim; i++)
-			{   
-				Argument arg = cast(Argument)parameters.data[i];
-				Type t = arg.type.reliesOnTident();
-				if (t)
-					return t;
-			}
-		}
-		return next.reliesOnTident();
+        size_t dim = Parameter.dim(parameters);
+        for (size_t i = 0; i < dim; i++)
+        {
+            auto fparam = Parameter.getNth(parameters, i);
+	        Type t = fparam.type.reliesOnTident();
+	        if (t)
+	            return t;
+        }
+        return next ? next.reliesOnTident() : null;
 	}
 
 version (CPP_MANGLE) {
@@ -428,7 +643,7 @@
 	 * Examine function signature for parameter p and see if
 	 * p can 'escape' the scope of the function.
 	 */
-    bool parameterEscapes(Argument p)
+    bool parameterEscapes(Parameter p)
 	{
 		/* Scope parameters do not escape.
 		 * Allow 'lazy' to imply 'scope' -
@@ -467,6 +682,8 @@
 	{
 		//printf("TypeFunction.callMatch() %s\n", toChars());
 		MATCH match = MATCH.MATCHexact;		// assume exact match
+        bool exactwildmatch = false;
+        bool wildmatch = false;
 
 		if (ethis)
 		{
@@ -476,14 +693,14 @@
 
 			if (t.mod != mod)
 			{
-				if (mod == MOD.MODconst)
+				if (MODimplicitConv(t.mod, mod))
 					match = MATCH.MATCHconst;
 				else
 					return MATCH.MATCHnomatch;
 			}
 		}
 
-		size_t nparams = Argument.dim(parameters);
+		size_t nparams = Parameter.dim(parameters);
 		size_t nargs = args ? args.dim : 0;
 		if (nparams == nargs) {
 			;
@@ -501,7 +718,7 @@
 
 			// BUG: what about out and ref?
 
-			Argument p = Argument.getNth(parameters, u);
+			auto p = Parameter.getNth(parameters, u);
 			assert(p);
 			if (u >= nargs)
 			{
@@ -512,7 +729,7 @@
 				goto Nomatch;		// not enough arguments
 			}
 
-			arg = cast(Expression)args.data[u];
+			arg = cast(Expression)args[u];
 			assert(arg);
 			// writef("arg: %s, type: %s\n", arg.toChars(), arg.type.toChars());
 
@@ -526,7 +743,7 @@
 			
 			if (p.storageClass & STCref)
 			{
-				/* Don't allow static arrays to be passed to mutable refereces
+				/* Don't allow static arrays to be passed to mutable references
 				 * to static arrays if the argument cannot be modified.
 				 */
 				Type targb = arg.type.toBasetype();
@@ -534,15 +751,36 @@
 				//writef("%s\n", targb.toChars());
 				//writef("%s\n", tparb.toChars());
 				if (targb.nextOf() && tparb.ty == Tsarray &&
-				    targb.nextOf().mod != tparb.nextOf().mod &&
-				    !tparb.nextOf().isConst())
+				   !MODimplicitConv(targb.nextOf().mod, tparb.nextOf().mod))
 					goto Nomatch;
 			}
 
 			if (p.storageClass & STC.STClazy && p.type.ty == TY.Tvoid && arg.type.ty != TY.Tvoid)
 				m = MATCH.MATCHconvert;
 			else
+            {
 				m = arg.implicitConvTo(p.type);
+	            if (p.type.isWild())
+	            {
+		            if (m == MATCHnomatch)
+		            {
+		                m = arg.implicitConvTo(p.type.constOf());
+		                if (m == MATCHnomatch)
+			            m = arg.implicitConvTo(p.type.sharedConstOf());
+		                if (m != MATCHnomatch)
+			            wildmatch = true;	// mod matched to wild
+		            }
+		            else
+		                exactwildmatch = true;	// wild matched to wild
+
+		            /* If both are allowed, then there could be more than one
+		             * binding of mod to wild, leaving a gaping type hole.
+		             */
+		            if (wildmatch && exactwildmatch)
+		                m = MATCHnomatch;
+	            }
+	        }
+
 			//printf("\tm = %d\n", m);
 			if (m == MATCH.MATCHnomatch)			// if no match
 			{
@@ -565,7 +803,7 @@
 							TypeArray ta = cast(TypeArray)tb;
 							for (; u < nargs; u++)
 							{
-								arg = cast(Expression)args.data[u];
+								arg = cast(Expression)args[u];
 								assert(arg);
 static if (true) {
 								/* If lazy array of delegates,
@@ -642,10 +880,10 @@
 			type* tp;
 
 			paramtypes = null;
-			size_t nparams = Argument.dim(parameters);
+			size_t nparams = Parameter.dim(parameters);
 			for (size_t i = 0; i < nparams; i++)
 			{   
-				Argument arg = Argument.getNth(parameters, i);
+				auto arg = Parameter.getNth(parameters, i);
 				tp = arg.type.toCtype();
 				if (arg.storageClass & (STC.STCout | STC.STCref))
 				{   
--- a/dmd/TypeIdentifier.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeIdentifier.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TypeIdentifier;
 
+import dmd.common;
 import dmd.TypeQualified;
 import dmd.MOD;
 import dmd.Identifier;
--- a/dmd/TypeInfoArrayDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeInfoArrayDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TypeInfoArrayDeclaration;
 
+import dmd.common;
 import dmd.Type;
 import dmd.TypeInfoDeclaration;
 import dmd.Type;
--- a/dmd/TypeInfoAssociativeArrayDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeInfoAssociativeArrayDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TypeInfoAssociativeArrayDeclaration;
 
+import dmd.common;
 import dmd.Type;
 import dmd.TypeAArray;
 import dmd.TY;
--- a/dmd/TypeInfoClassDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeInfoClassDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TypeInfoClassDeclaration;
 
+import dmd.common;
 import dmd.Type;
 import dmd.TypeInfoDeclaration;
 import dmd.ClassInfoDeclaration;
@@ -19,9 +20,19 @@
 	    type = Type.typeinfostruct.type;
 	}
 
+	override Symbol* toSymbol()
+	{
+	    //printf("TypeInfoClassDeclaration::toSymbol(%s), linkage = %d\n", toChars(), linkage);
+	    assert(tinfo.ty == TY.Tclass);
+	    auto tc = cast(TypeClass)tinfo;
+	    return tc.sym.toSymbol();
+	}
+	
 	override void toDt(dt_t** pdt)
 	{
 		//printf("TypeInfoClassDeclaration::toDt() %s\n", tinfo->toChars());
+        assert(0);
+static if(false) {
 		dtxoff(pdt, Type.typeinfoclass.toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoClass
 		dtdword(pdt, 0);			    // monitor
 
@@ -36,6 +47,7 @@
 		assert(s.Sxtrnnum == 0);
 
 		dtxoff(pdt, s, 0, TYnptr);		// ClassInfo for tinfo
+}
 	}
 }
 
--- a/dmd/TypeInfoConstDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeInfoConstDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TypeInfoConstDeclaration;
 
+import dmd.common;
 import dmd.Type;
 import dmd.TypeInfoDeclaration;
 import dmd.Type;
--- a/dmd/TypeInfoDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeInfoDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TypeInfoDeclaration;
 
+import dmd.common;
 import dmd.VarDeclaration;
 import dmd.Type;
 import dmd.Dsymbol;
@@ -24,9 +25,9 @@
 
 class TypeInfoDeclaration : VarDeclaration
 {
-    Type tinfo;
+	Type tinfo;
 
-    this(Type tinfo, int internal)
+	this(Type tinfo, int internal)
 	{
 		super(Loc(0), Type.typeinfo.type, tinfo.getTypeInfoIdent(internal), null);
 		this.tinfo = tinfo;
@@ -42,22 +43,22 @@
 		assert(false);
 	}
 }
-    override Dsymbol syntaxCopy(Dsymbol)
+	override Dsymbol syntaxCopy(Dsymbol)
 	{
-		assert(false);
+		assert(false);		  // should never be produced by syntax
+		return null;
 	}
 
-    override void semantic(Scope sc)
+	override void semantic(Scope sc)
 	{
-		assert(false);
+		assert(linkage == LINKc);
 	}
 
-    override void emitComment(Scope sc)
+	override void emitComment(Scope sc)
 	{
-		assert(false);
 	}
 
-    override Symbol* toSymbol()
+	override Symbol* toSymbol()
 	{
 		//printf("TypeInfoDeclaration::toSymbol(%s), linkage = %d\n", toChars(), linkage);
 		return VarDeclaration.toSymbol();
@@ -67,7 +68,7 @@
 	{
 	}
 
-    override void toObjFile(int multiobj)			// compile to .obj file
+	override void toObjFile(int multiobj)			// compile to .obj file
 	{
 		Symbol* s;
 		uint sz;
@@ -113,7 +114,7 @@
 			obj_export(s,0);
 	}
 
-    void toDt(dt_t** pdt)
+	void toDt(dt_t** pdt)
 	{
 		assert(false);
 	}
--- a/dmd/TypeInfoDelegateDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeInfoDelegateDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TypeInfoDelegateDeclaration;
 
+import dmd.common;
 import dmd.Type;
 import dmd.TypeInfoDeclaration;
 import dmd.TypeDelegate;
--- a/dmd/TypeInfoEnumDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeInfoEnumDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TypeInfoEnumDeclaration;
 
+import dmd.common;
 import dmd.TY;
 import dmd.Type;
 import dmd.Loc;
--- a/dmd/TypeInfoFunctionDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeInfoFunctionDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,20 +1,35 @@
-module dmd.TypeInfoFunctionDeclaration;
-
-import dmd.Type;
-import dmd.TypeInfoDeclaration;
-import dmd.backend.dt_t;
-
+module dmd.TypeInfoFunctionDeclaration;
+
+import dmd.common;
+import dmd.Type;
+import dmd.TypeInfoDeclaration;
+import dmd.TypeFunction;
+import dmd.TY;
+
+import dmd.backend.dt_t;
+import dmd.backend.Util;
+import dmd.backend.TYM;
+
 class TypeInfoFunctionDeclaration : TypeInfoDeclaration
 {
 	this(Type tinfo)
 	{
-		super(tinfo, 0);
-        type = Type.typeinfofunction.type;
+		super(tinfo, 0);
+        type = Type.typeinfofunction.type;
 	}
 
 	override void toDt(dt_t** pdt)
 	{
-		assert(false);
+		//printf("TypeInfoFunctionDeclaration.toDt()\n");
+		dtxoff(pdt, Type.typeinfofunction.toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Function
+		dtdword(pdt, 0);			    // monitor
+
+		assert(tinfo.ty == Tfunction);
+
+		TypeFunction tc = cast(TypeFunction)tinfo;
+
+		tc.next.getTypeInfo(null);
+		dtxoff(pdt, tc.next.vtinfo.toSymbol(), 0, TYnptr); // TypeInfo for function return value
 	}
 }
 
--- a/dmd/TypeInfoInterfaceDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeInfoInterfaceDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,10 +1,12 @@
 module dmd.TypeInfoInterfaceDeclaration;
 
+import dmd.common;
 import dmd.Type;
 import dmd.TypeInfoDeclaration;
 import dmd.ClassInfoDeclaration;
 import dmd.TypeClass;
 import dmd.TY;
+import dmd.TypeInfoClassDeclaration;
 
 import dmd.backend.dt_t;
 import dmd.backend.Symbol;
@@ -31,7 +33,7 @@
 		Symbol *s;
 
 		if (!tc.sym.vclassinfo)
-			tc.sym.vclassinfo = new ClassInfoDeclaration(tc.sym);
+			tc.sym.vclassinfo = new TypeInfoClassDeclaration(tc);
 		s = tc.sym.vclassinfo.toSymbol();
 		dtxoff(pdt, s, 0, TYnptr);		// ClassInfo for tinfo
 	}
--- a/dmd/TypeInfoInvariantDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeInfoInvariantDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TypeInfoInvariantDeclaration;
 
+import dmd.common;
 import dmd.Type;
 import dmd.TypeInfoDeclaration;
 import dmd.backend.dt_t;
--- a/dmd/TypeInfoPointerDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeInfoPointerDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TypeInfoPointerDeclaration;
 
+import dmd.common;
 import dmd.Type;
 import dmd.TypeInfoDeclaration;
 import dmd.TypePointer;
--- a/dmd/TypeInfoSharedDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeInfoSharedDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TypeInfoSharedDeclaration;
 
+import dmd.common;
 import dmd.Type;
 import dmd.TypeInfoDeclaration;
 import dmd.backend.dt_t;
--- a/dmd/TypeInfoStaticArrayDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeInfoStaticArrayDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TypeInfoStaticArrayDeclaration;
 
+import dmd.common;
 import dmd.Type;
 import dmd.TypeInfoDeclaration;
 import dmd.TypeSArray;
--- a/dmd/TypeInfoStructDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeInfoStructDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,10 +1,11 @@
 module dmd.TypeInfoStructDeclaration;
 
+import dmd.common;
 import dmd.Type;
 import dmd.TY;
 import dmd.MOD;
 import dmd.Loc;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.STC;
 import dmd.TypeStruct;
 import dmd.TypeFunction;
@@ -98,35 +99,52 @@
 		TypeFunction tfeqptr;
 		{	
 			// bool opEqual(const T*) const;
-			scope Scope sc = new Scope();
-			Arguments arguments = new Arguments;
+			scope sc = new Scope();
+			auto arguments = new Parameters;
 		version (STRUCTTHISREF) {
 			// arg type is ref const T
-			Argument arg = new Argument(STC.STCref, tc.constOf(), null, null);
+			auto arg = new Parameter(STC.STCref, tc.constOf(), null, null);
 		} else {
 			// arg type is const T*
-			Argument arg = new Argument(STC.STCin, tc.pointerTo(), null, null);
+			auto arg = new Parameter(STC.STCin, tc.pointerTo(), null, null);
 		}
 
-			arguments.push(cast(void*)arg);
+	        arguments.push(arg);
+	        tfeqptr = new TypeFunction(arguments, Type.tbool, 0, LINK.LINKd);
+	        tfeqptr.mod = MODconst;
+	        tfeqptr = cast(TypeFunction)tfeqptr.semantic(Loc(0), sc);
+        }
+
+        {
+	        scope sc = new Scope;
+	        auto arguments = new Parameters;
+version(STRUCTTHISREF) {
+	        // arg type is ref const T
+	        auto arg = new Parameter(STC.STCref, tc.constOf(), null, null);
+} else {
+	    // arg type is const T*
+	        auto arg = new Parameter(STC.STCin, tc.pointerTo(), null, null);
+}
+
+			arguments.push(arg);
 			tfeqptr = new TypeFunction(arguments, Type.tbool, 0, LINK.LINKd);
 			tfeqptr.mod = MOD.MODconst;
 			tfeqptr = cast(TypeFunction)tfeqptr.semantic(Loc(0), sc);
 		}
 
-		TypeFunction tfcmpptr;
+        TypeFunction tfcmpptr;
 		{
 			scope Scope sc = new Scope();
-			Arguments arguments = new Arguments;
+			auto arguments = new Parameters;
 		version (STRUCTTHISREF) {
 			// arg type is ref const T
-			Argument arg = new Argument(STC.STCref, tc.constOf(), null, null);
+			auto arg = new Parameter(STC.STCref, tc.constOf(), null, null);
 		} else {
 			// arg type is const T*
-			Argument arg = new Argument(STC.STCin, tc.pointerTo(), null, null);
+			auto arg = new Parameter(STC.STCin, tc.pointerTo(), null, null);
 		}
 
-			arguments.push(cast(void*)arg);
+			arguments.push(arg);
 			tfcmpptr = new TypeFunction(arguments, Type.tint32, 0, LINK.LINKd);
 			tfcmpptr.mod = MOD.MODconst;
 			tfcmpptr = cast(TypeFunction)tfcmpptr.semantic(Loc(0), sc);
@@ -146,23 +164,8 @@
 		else
 			dtdword(pdt, 0);
 
-		s = search_function(sd, Id.eq);
-		fdx = s ? s.isFuncDeclaration() : null;
-		if (fdx)
-		{
-			//printf("test1 %s, %s, %s\n", fdx.toChars(), fdx.type.toChars(), tfeqptr.toChars());
-			fd = fdx.overloadExactMatch(tfeqptr);
-			if (fd)
-				dtxoff(pdt, fd.toSymbol(), 0, TYM.TYnptr);
-			else
-			{   
-				fd = fdx.overloadExactMatch(tfcmpptr);
-				if (fd)
-					fdx.error("must return bool, not int");
-				//fdx.error("must be declared as extern (D) int %s(%s*)", fdx.toChars(), sd.toChars());
-				dtdword(pdt, 0);
-			}
-		}
+		if (sd.eq)
+	        dtxoff(pdt, sd.eq.toSymbol(), 0, TYnptr);
 		else
 			dtdword(pdt, 0);
 
--- a/dmd/TypeInfoTupleDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeInfoTupleDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,10 +1,11 @@
 module dmd.TypeInfoTupleDeclaration;
 
+import dmd.common;
 import dmd.Type;
 import dmd.TypeInfoDeclaration;
 import dmd.WANT;
 import dmd.TypeTuple;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.Expression;
 import dmd.TY;
 import dmd.backend.TYM;
@@ -29,7 +30,7 @@
 
 		assert(tinfo.ty == Ttuple);
 
-		TypeTuple tu = cast(TypeTuple)tinfo;
+		auto tu = cast(TypeTuple)tinfo;
 
 		size_t dim = tu.arguments.dim;
 		dtdword(pdt, dim);			    // elements.length
@@ -37,7 +38,7 @@
 		dt_t* d = null;
 		for (size_t i = 0; i < dim; i++)
 		{	
-			Argument arg = cast(Argument)tu.arguments.data[i];
+			auto arg = tu.arguments[i];
 			Expression e = arg.type.getTypeInfo(null);
 			e = e.optimize(WANTvalue);
 			e.toDt(&d);
--- a/dmd/TypeInfoTypedefDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeInfoTypedefDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TypeInfoTypedefDeclaration;
 
+import dmd.common;
 import dmd.Type;
 import dmd.TypeInfoDeclaration;
 import dmd.TypedefDeclaration;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmd/TypeInfoWildDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -0,0 +1,29 @@
+module dmd.TypeInfoWildDeclaration;
+
+import dmd.TY;
+import dmd.Type;
+import dmd.TypeInfoDeclaration;
+
+import dmd.backend.dt_t;
+import dmd.backend.Util;
+import dmd.backend.TYM;
+
+class TypeInfoWildDeclaration : TypeInfoDeclaration
+{
+    this(Type tinfo)
+    {
+        super(tinfo, 0);
+        type = Type.typeinfowild.type;
+    }
+
+    override void toDt(dt_t **pdt)
+    {
+        //printf("TypeInfoWildDeclaration::toDt() %s\n", toChars());
+        dtxoff(pdt, Type.typeinfowild.toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Wild
+        dtdword(pdt, 0);			    // monitor
+        Type tm = tinfo.mutableOf();
+        tm = tm.merge();
+        tm.getTypeInfo(null);
+        dtxoff(pdt, tm.vtinfo.toSymbol(), 0, TYnptr);
+    }
+};
--- a/dmd/TypeInstance.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeInstance.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TypeInstance;
 
+import dmd.common;
 import dmd.TypeQualified;
 import dmd.TemplateAliasParameter;
 import dmd.TemplateDeclaration;
@@ -197,7 +198,7 @@
 						}
 						goto Lnomatch;
 					}
-					TemplateParameter tpx = cast(TemplateParameter)parameters.data[i];
+					TemplateParameter tpx = parameters[i];
 					// This logic duplicates tpx->matchArg()
 					TemplateAliasParameter ta = tpx.isTemplateAliasParameter();
 					if (!ta)
@@ -207,14 +208,14 @@
 						goto Lnomatch;
 					if (ta.specAlias && sa != ta.specAlias)
 						goto Lnomatch;
-					if (dedtypes.data[i])
+					if (dedtypes[i])
 					{   // Must match already deduced symbol
-						Object s = cast(Object)dedtypes.data[i];
+						Object s = dedtypes[i];
 
 						if (s != sa)
 							goto Lnomatch;
 					}
-					dedtypes.data[i] = cast(void*)sa;
+					dedtypes[i] = sa;
 				}
 			}
 			else if (tempinst.tempdecl != tp.tempinst.tempdecl)
@@ -227,17 +228,17 @@
 				//printf("\ttest: tempinst->tiargs[%d]\n", i);
 				Object o1;
 				if (i < tempinst.tiargs.dim)
-					o1 = cast(Object)tempinst.tiargs.data[i];
+					o1 = tempinst.tiargs[i];
 				else if (i < tempinst.tdtypes.dim && i < tp.tempinst.tiargs.dim)
 					// Pick up default arg
-					o1 = cast(Object)tempinst.tdtypes.data[i];
+					o1 = tempinst.tdtypes[i];
 				else
 					break;
 
 				if (i >= tp.tempinst.tiargs.dim)
 					goto Lnomatch;
 
-				Object o2 = cast(Object)tp.tempinst.tiargs.data[i];
+				Object o2 = tp.tempinst.tiargs[i];
 
 				Type t1 = isType(o1);
 				Type t2 = isType(o2);
@@ -286,16 +287,16 @@
 					int vtdim = tempinst.tiargs.dim - i;
 					vt.objects.setDim(vtdim);
 					for (size_t k = 0; k < vtdim; k++)
-						vt.objects.data[k] = cast(void *)tempinst.tiargs.data[i + k];
+						vt.objects[k] = tempinst.tiargs[i + k];
 
-					Tuple v = cast(Tuple)dedtypes.data[j];
+					auto v = cast(Tuple)dedtypes[j];
 					if (v)
 					{
 						if (!match(v, vt, tempinst.tempdecl, sc))
 							goto Lnomatch;
 					}
 					else
-						dedtypes.data[j] = cast(void*)vt;
+						dedtypes[j] = vt;
 					break; //return MATCHexact;
 				}
 
@@ -324,12 +325,12 @@
 L1:
 					if (j == -1)
 						goto Lnomatch;
-					TemplateParameter tp_ = cast(TemplateParameter)parameters.data[j];
+					auto tp_ = parameters[j];
 					// BUG: use tp->matchArg() instead of the following
 					TemplateValueParameter tv = tp_.isTemplateValueParameter();
 					if (!tv)
 						goto Lnomatch;
-					Expression e = cast(Expression)dedtypes.data[j];
+					Expression e = cast(Expression)dedtypes[j];
 					if (e)
 					{
 						if (!e1.equals(e))
@@ -340,7 +341,7 @@
 						MATCH m = cast(MATCH)e1.implicitConvTo(vt);
 						if (!m)
 							goto Lnomatch;
-						dedtypes.data[j] = cast(void*)e1;
+						dedtypes[j] = e1;
 					}
 				}
 				else if (s1 && t2 && t2.ty == Tident)
@@ -348,12 +349,12 @@
 					j = templateParameterLookup(t2, parameters);
 					if (j == -1)
 						goto Lnomatch;
-					TemplateParameter tp_ = cast(TemplateParameter)parameters.data[j];
+					auto tp_ = parameters[j];
 					// BUG: use tp->matchArg() instead of the following
 					TemplateAliasParameter ta = tp_.isTemplateAliasParameter();
 					if (!ta)
 						goto Lnomatch;
-					Dsymbol s = cast(Dsymbol)dedtypes.data[j];
+					auto s = cast(Dsymbol)dedtypes[j];
 					if (s)
 					{
 						if (!s1.equals(s))
@@ -361,7 +362,7 @@
 					}
 					else
 					{
-						dedtypes.data[j] = cast(void*)s1;
+						dedtypes[j] = s1;
 					}
 				}
 				else if (s1 && s2)
--- a/dmd/TypeNewArray.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeNewArray.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TypeNewArray;
 
+import dmd.common;
 import dmd.HdrGenState;
 import dmd.MOD;
 import dmd.OutBuffer;
--- a/dmd/TypeNext.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeNext.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TypeNext;
 
+import dmd.common;
 import dmd.Type;
 import dmd.TypeAArray;
 import dmd.TY;
@@ -52,6 +53,35 @@
 		return next.reliesOnTident();
 	}
 	
+    override int hasWild()
+    {
+        return mod == MOD.MODwild || next.hasWild();
+    }
+
+    /***************************************
+     * Return MOD bits matching argument type (targ) to wild parameter type (this).
+     */
+
+    override uint wildMatch(Type targ)
+    {
+        uint mod;
+
+        Type tb = targ.nextOf();
+        if (!tb)
+	        return 0;
+        tb = tb.toBasetype();
+        if (tb.isMutable())
+	        mod = MOD.MODmutable;
+        else if (tb.isConst() || tb.isWild())
+	        return MOD.MODconst;
+        else if (tb.isImmutable())
+	        mod = MOD.MODimmutable;
+        else
+	        assert(0);
+        mod |= next.wildMatch(tb);
+        return mod;
+    }
+    
     override Type nextOf()
 	{
 		return next;
@@ -69,7 +99,7 @@
 		TypeNext t = cast(TypeNext)super.makeConst();
 		if (ty != TY.Tfunction && ty != TY.Tdelegate &&
 			(next.deco || next.ty == TY.Tfunction) &&
-			!next.isInvariant() && !next.isConst())
+			!next.isImmutable() && !next.isConst())
 		{
 			if (next.isShared())
 				t.next = next.sharedConstOf();
@@ -89,11 +119,11 @@
 		//printf("TypeNext::makeInvariant() %s\n", toChars());
 		if (ito)
 		{	
-			assert(ito.isInvariant());
+			assert(ito.isImmutable());
 			return ito;
 		}
 		TypeNext t = cast(TypeNext)Type.makeInvariant();
-		if (ty != TY.Tfunction && ty != TY.Tdelegate && (next.deco || next.ty == TY.Tfunction) && !next.isInvariant())
+		if (ty != TY.Tfunction && ty != TY.Tdelegate && (next.deco || next.ty == TY.Tfunction) && !next.isImmutable())
 		{	
 			t.next = next.invariantOf();
 		}
@@ -115,9 +145,9 @@
 		TypeNext t = cast(TypeNext)Type.makeShared();
 		if (ty != Tfunction && ty != Tdelegate &&
 			(next.deco || next.ty == Tfunction) &&
-			!next.isInvariant() && !next.isShared())
+			!next.isImmutable() && !next.isShared())
 		{
-			if (next.isConst())
+			if (next.isConst() || next.isWild())
 				t.next = next.sharedConstOf();
 			else
 				t.next = next.sharedOf();
@@ -141,7 +171,7 @@
 		TypeNext t = cast(TypeNext) Type.makeSharedConst();
 		if (ty != Tfunction && ty != Tdelegate &&
 		    (next.deco || next.ty == Tfunction) &&
-			!next.isInvariant() && !next.isSharedConst())
+			!next.isImmutable() && !next.isSharedConst())
 		{
 			t.next = next.sharedConstOf();
 		}
@@ -153,6 +183,73 @@
 		return t;
 	}
 	
+    override Type makeWild()
+    {
+        //printf("TypeNext::makeWild() %s\n", toChars());
+        if (wto)
+        {
+            assert(wto.mod == MODwild);
+	        return wto;
+        }    
+        auto t = cast(TypeNext)Type.makeWild();
+        if (ty != TY.Tfunction && ty != TY.Tdelegate &&
+	    (next.deco || next.ty == TY.Tfunction) &&
+            !next.isImmutable() && !next.isConst() && !next.isWild())
+        {
+	        if (next.isShared())
+	            t.next = next.sharedWildOf();
+	        else
+	            t.next = next.wildOf();
+        }
+        if (ty == TY.Taarray)
+        {
+    	    (cast(TypeAArray)t).impl = null;		// lazily recompute it
+        }
+        //printf("TypeNext::makeWild() returns %p, %s\n", t, t->toChars());
+        return t;
+    }
+
+    Type makeSharedWild()
+    {
+        //printf("TypeNext::makeSharedWild() %s\n", toChars());
+        if (swto)
+        {
+            assert(swto.isSharedWild());
+	        return swto;
+        }    
+        auto t = cast(TypeNext)Type.makeSharedWild();
+        if (ty != TY.Tfunction && ty != TY.Tdelegate &&
+	    (next.deco || next.ty == TY.Tfunction) &&
+            !next.isImmutable() && !next.isSharedConst())
+        {
+	        t.next = next.sharedWildOf();
+        }
+        if (ty == Taarray)
+        {
+	        (cast(TypeAArray)t).impl = null;		// lazily recompute it
+        }
+        //printf("TypeNext::makeSharedWild() returns %p, %s\n", t, t->toChars());
+        return t;
+    }
+
+    Type makeMutable()
+    {
+        //printf("TypeNext::makeMutable() %p, %s\n", this, toChars());
+        auto t = cast(TypeNext)Type.makeMutable();
+        if (ty != TY.Tfunction && ty != TY.Tdelegate &&
+	    (next.deco || next.ty == TY.Tfunction) &&
+            next.isWild())
+        {
+	        t.next = next.mutableOf();
+        }
+        if (ty == Taarray)
+        {
+	        (cast(TypeAArray)t).impl = null;		// lazily recompute it
+        }
+        //printf("TypeNext::makeMutable() returns %p, %s\n", t, t->toChars());
+        return t;
+    }
+    
 	override MATCH constConv(Type to)
 	{
 		MATCH m = Type.constConv(to);
--- a/dmd/TypePointer.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypePointer.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TypePointer;
 
+import dmd.common;
 import dmd.Type;
 import dmd.Loc;
 import dmd.Scope;
@@ -107,7 +108,7 @@
 			TypePointer tp = cast(TypePointer)to;
 			assert(tp.next);
 
-			if (!(next.mod == tp.next.mod || tp.next.mod == MOD.MODconst))
+			if (!MODimplicitConv(next.mod, tp.next.mod))
 				return MATCH.MATCHnomatch;        // not const-compatible
 
 			/* Alloc conversion to void[]
@@ -144,9 +145,7 @@
 	version (LOGDEFAULTINIT) {
 		printf("TypePointer::defaultInit() '%s'\n", toChars());
 	}
-		Expression e = new NullExp(loc);
-		e.type = this;
-		return e;
+		return new NullExp(loc, this);
 	}
 	
     override bool isZeroInit(Loc loc)
--- a/dmd/TypeQualified.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeQualified.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TypeQualified;
 
+import dmd.common;
 import dmd.Type;
 import dmd.Import;
 import dmd.DsymbolExp;
@@ -21,6 +22,7 @@
 import dmd.Dsymbol;
 import dmd.DYNCAST;
 import dmd.Expression;
+import dmd.FuncDeclaration;
 import dmd.Util;
 
 class TypeQualified : Type
@@ -99,6 +101,7 @@
     void resolveHelper(Loc loc, Scope sc, Dsymbol s, Dsymbol scopesym, Expression* pe, Type* pt, Dsymbol* ps)
 	{
 		VarDeclaration v;
+        FuncDeclaration fd;
 		EnumMember em;
 		TupleDeclaration td;
 		Expression e;
@@ -173,7 +176,7 @@
 						{
 							id = cast(Identifier)idents.data[i];
 							//printf("e: '%s', id: '%s', type = %p\n", e.toChars(), id.toChars(), e.type);
-							if (id == Id.offsetof)
+							if (id == Id.offsetof || !e.type)
 							{   e = new DotIdExp(e.loc, e, id);
 								e = e.semantic(sc);
 							}
@@ -194,32 +197,17 @@
 			v = s.isVarDeclaration();
 			if (v)
 			{
-///static if (false) {
-///				// It's not a type, it's an expression
-///				Expression *e = v.getConstInitializer();
-///				if (e)
-///				{
-///					*pe = e.copy();	// make copy so we can change loc
-///					(*pe).loc = loc;
-///				}
-///				else
-///}
-				{
-///static if (false) {
-///					WithScopeSymbol withsym;
-///					if (scopesym && (withsym = scopesym.isWithScopeSymbol()) !is null)
-///					{
-///						// Same as wthis.ident
-///						e = new VarExp(loc, withsym.withstate.wthis);
-///						e = new DotIdExp(loc, e, ident);
-///						//assert(0);	// BUG: should handle this
-///					}
-///					else
-///}
-						*pe = new VarExp(loc, v);
-				}
+				*pe = new VarExp(loc, v);
 				return;
 			}
+//#if 0
+//	fd = s->isFuncDeclaration();
+//	if (fd)
+//	{
+//	    *pe = new DsymbolExp(loc, fd, 1);
+//	    return;
+//	}
+//#endif
 			em = s.isEnumMember();
 			if (em)
 			{
--- a/dmd/TypeReference.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeReference.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TypeReference;
 
+import dmd.common;
 import dmd.Type;
 import dmd.MOD;
 import dmd.TypeNext;
@@ -9,6 +10,7 @@
 import dmd.HdrGenState;
 import dmd.Expression;
 import dmd.Identifier;
+import dmd.NullExp;
 import dmd.CppMangleState;
 import dmd.TY;
 
@@ -55,7 +57,10 @@
 	
     override Expression defaultInit(Loc loc)
 	{
-		assert(false);
+version(LOGDEFAULTINIT) {
+    printf("TypeReference::defaultInit() '%s'\n", toChars());
+}
+		return new NullExp(loc, this);
 	}
 	
     override bool isZeroInit(Loc loc)
--- a/dmd/TypeReturn.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeReturn.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TypeReturn;
 
+import dmd.common;
 import dmd.Loc;
 import dmd.MOD;
 import dmd.Type;
@@ -52,6 +53,11 @@
 			goto Lerr;
 		}
 		t = sc.func.type.nextOf();
+        if (!t)
+        {
+	        error(loc, "cannot use typeof(return) inside function %s with inferred return type", sc.func.toChars());
+	        goto Lerr;
+        }
 		t = t.addMod(mod);
 
 		if (idents.dim)
--- a/dmd/TypeSArray.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeSArray.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,10 +1,11 @@
 module dmd.TypeSArray;
 
+import dmd.common;
 import dmd.TypeArray;
 import dmd.TypeInfoStaticArrayDeclaration;
 import dmd.TypeAArray;
 import dmd.MOD;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.TypeIdentifier;
 import dmd.TemplateParameter;
 import dmd.TemplateValueParameter;
@@ -129,7 +130,7 @@
 			///}
 			///t = cast(Type)o;
 			
-			t = cast(Type)sd.objects.data[cast(size_t)d];
+			t = cast(Type)sd.objects[cast(size_t)d];
 			if (t is null) {
 				error(loc, "%s is not a type", toChars());
 				return Type.terror;
@@ -195,7 +196,7 @@
 			case TY.Ttuple:
 			{   // Index the tuple to get the type
 				assert(dim);
-				TypeTuple tt = cast(TypeTuple)tbn;
+				auto tt = cast(TypeTuple)tbn;
 				ulong d = dim.toUInteger();
 
 				if (d >= tt.arguments.dim)
@@ -203,7 +204,7 @@
 					error(loc, "tuple index %ju exceeds %u", d, tt.arguments.dim);
 					return Type.terror;
 				}
-				Argument arg = cast(Argument)tt.arguments.data[cast(size_t)d];
+				auto arg = tt.arguments[cast(size_t)d];
 				return arg.type;
 			}
 			case TY.Tstruct:
@@ -257,7 +258,7 @@
 					error(loc, "tuple index %ju exceeds %u", d, td.objects.dim);
 					goto Ldefault;
 				}
-				Object o = cast(Object)td.objects.data[cast(size_t)d];
+				Object o = td.objects[cast(size_t)d];
 				if ((*ps = isDsymbol(o)) !is null)	/// !
 				{
 					return;
@@ -272,11 +273,11 @@
 				 * Do it this way because TemplateInstance.semanticTiargs()
 				 * can handle unresolved Objects this way.
 				 */
-				Objects objects = new Objects;
+				auto objects = new Objects;
 				objects.setDim(1);
-				objects.data[0] = cast(void*)o;
+				objects[0] = o;
 
-				TupleDeclaration tds = new TupleDeclaration(loc, td.ident, objects);
+				auto tds = new TupleDeclaration(loc, td.ident, objects);
 				*ps = tds;
 			}
 			else
@@ -332,6 +333,7 @@
 		{
 			e = TypeArray.dotExp(sc, e, ident);
 		}
+        e = e.semantic(sc);
 		return e;
 	}
 	
@@ -365,7 +367,7 @@
 		{
 			TypePointer tp = cast(TypePointer)to;
 
-			if (next.mod != tp.next.mod && tp.next.mod != MODconst)
+			if (!MODimplicitConv(next.mod, tp.next.mod))
 				return MATCHnomatch;
 
 			if (tp.next.ty == Tvoid || next.constConv(tp.next) != MATCHnomatch)
@@ -379,11 +381,12 @@
 			int offset = 0;
 			TypeDArray ta = cast(TypeDArray)to;
 
-			if (next.mod != ta.next.mod && ta.next.mod != MODconst)
+			if (!MODimplicitConv(next.mod, ta.next.mod))
 				return MATCHnomatch;
 
 			if (next.equals(ta.next) ||
-				next.implicitConvTo(ta.next) >= MATCHconst ||
+//				next.implicitConvTo(ta.next) >= MATCHconst ||
+                next.constConv(ta.next) != MATCHnomatch ||
 				(ta.next.isBaseOf(next, &offset) && offset == 0) ||
 				ta.next.ty == Tvoid
 			)
@@ -507,11 +510,11 @@
 				// This code matches code in TypeInstance.deduceType()
 					if (i == -1)
 						goto Lnomatch;
-					TemplateParameter tp2 = cast(TemplateParameter)parameters.data[i];
+					auto tp2 = parameters[i];
 					TemplateValueParameter tvp = tp2.isTemplateValueParameter();
 					if (!tvp)
 						goto Lnomatch;
-					Expression e = cast(Expression)dedtypes.data[i];
+					Expression e = cast(Expression)dedtypes[i];
 					if (e)
 					{
 						if (!dim.equals(e))
@@ -523,7 +526,7 @@
 						MATCH m = cast(MATCH)dim.implicitConvTo(vt);
 						if (!m)
 							goto Lnomatch;
-						dedtypes.data[i] = cast(void*)dim;
+						dedtypes[i] = dim;
 					}
 				}
 				else if (dim.toInteger() != tp.dim.toInteger())
@@ -531,10 +534,10 @@
 			}
 			else if (tparam.ty == Taarray)
 			{
-				TypeAArray tp = cast(TypeAArray)tparam;
+				auto tp = cast(TypeAArray)tparam;
 				if (tp.index.ty == Tident)
 				{	
-					TypeIdentifier tident = cast(TypeIdentifier)tp.index;
+					auto tident = cast(TypeIdentifier)tp.index;
 
 					if (tident.idents.dim == 0)
 					{   
@@ -542,7 +545,7 @@
 
 						for (size_t i = 0; i < parameters.dim; i++)
 						{
-							TemplateParameter tp2 = cast(TemplateParameter)parameters.data[i];
+							auto tp2 = parameters[i];
 
 							if (tp2.ident.equals(id))
 							{   
@@ -551,13 +554,13 @@
 								if (!tvp || !tvp.valType.isintegral())
 								goto Lnomatch;
 
-								if (dedtypes.data[i])
+								if (dedtypes[i])
 								{
-									if (!dim.equals(cast(Object)dedtypes.data[i]))
+									if (!dim.equals(dedtypes[i]))
 										goto Lnomatch;
 								}
 								else
-								{	dedtypes.data[i] = cast(void*)dim;
+								{	dedtypes[i] = dim;
 								}
 								return next.deduceType(sc, tparam.nextOf(), parameters, dedtypes);
 							}
--- a/dmd/TypeSlice.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeSlice.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TypeSlice;
 
+import dmd.common;
 import dmd.Type;
 import dmd.TypeNext;
 import dmd.MOD;
@@ -13,7 +14,7 @@
 import dmd.TypeTuple;
 import dmd.WANT;
 import dmd.ArrayTypes;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.SliceExp;
 import dmd.TupleDeclaration;
 import dmd.ScopeDsymbol;
@@ -78,12 +79,12 @@
 			return Type.terror;
 		}
 
-		Arguments args = new Arguments;
+		auto args = new Parameters;
 		args.reserve(cast(size_t)(i2 - i1));
 		for (size_t i = cast(size_t)i1; i < cast(size_t)i2; i++)
 		{	
-			Argument arg = cast(Argument)tt.arguments.data[i];
-			args.push(cast(void*)arg);
+			auto arg = tt.arguments[i];
+			args.push(arg);
 		}
 
 		return new TypeTuple(args);
@@ -135,14 +136,14 @@
 				/* Create a new TupleDeclaration which
 				 * is a slice [i1..i2] out of the old one.
 				 */
-				Objects objects = new Objects;
+				auto objects = new Objects;
 				objects.setDim(cast(uint)(i2 - i1));
 				for (size_t i = 0; i < objects.dim; i++)
 				{
-					objects.data[i] = td.objects.data[cast(size_t)i1 + i];
+					objects[i] = td.objects[cast(size_t)i1 + i];
 				}
 
-				TupleDeclaration tds = new TupleDeclaration(loc, td.ident, objects);
+				auto tds = new TupleDeclaration(loc, td.ident, objects);
 				*ps = tds;
 			}
 			else
--- a/dmd/TypeStruct.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeStruct.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TypeStruct;
 
+import dmd.common;
 import dmd.Type;
 import dmd.TypeInstance;
 import dmd.StructDeclaration;
@@ -36,6 +37,7 @@
 import dmd.VarExp;
 import dmd.CommaExp;
 import dmd.ThisExp;
+import dmd.StructLiteralExp;
 import dmd.SymbolDeclaration;
 import dmd.TypeInfoDeclaration;
 import dmd.TypeInfoStructDeclaration;
@@ -217,41 +219,7 @@
 	L1:
 		if (!s)
 		{
-			if (ident !is Id.__sizeof &&
-				ident !is Id.alignof_ &&
-				ident !is Id.init_ &&
-				ident !is Id.mangleof_ &&
-				ident !is Id.stringof_ &&
-				ident !is Id.offsetof)
-			{
-				/* See if we should forward to the alias this.
-				 */
-				if (sym.aliasthis)
-				{	
-					/* Rewrite e.ident as:
-					 *	e.aliasthis.ident
-					 */
-					e = new DotIdExp(e.loc, e, sym.aliasthis.ident);
-					e = new DotIdExp(e.loc, e, ident);
-					return e.semantic(sc);
-				}
-
-				/* Look for overloaded opDot() to see if we should forward request
-				 * to it.
-				 */
-				Dsymbol fd = search_function(sym, Id.opDot);
-				if (fd)
-				{   
-					/* Rewrite e.ident as:
-					 *	e.opId().ident
-					 */
-					e = build_overload(e.loc, sc, e, null, fd.ident);
-					e = new DotIdExp(e.loc, e, ident);
-					return e.semantic(sc);
-				}
-			}
-
-			return Type.dotExp(sc, e, ident);
+	        return noMember(sc, e, ident);
 		}
 
 		if (!s.isFuncDeclaration())	// because of overloading
@@ -410,18 +378,44 @@
 	
     override Expression defaultInit(Loc loc)
 	{
-		Symbol* s;
-		Declaration d;
-
 	version (LOGDEFAULTINIT) {
 		printf("TypeStruct::defaultInit() '%s'\n", toChars());
 	}
-		s = sym.toInitializer();
-		d = new SymbolDeclaration(sym.loc, s, sym);
+		Symbol *s = sym.toInitializer();
+		Declaration d = new SymbolDeclaration(sym.loc, s, sym);
 		assert(d);
 		d.type = this;
 		return new VarExp(sym.loc, d);
 	}
+    
+    /***************************************
+     * Use when we prefer the default initializer to be a literal,
+     * rather than a global immutable variable.
+     */
+    Expression defaultInitLiteral(Loc loc)
+    {
+	version (LOGDEFAULTINIT) {
+        printf("TypeStruct::defaultInitLiteral() '%s'\n", toChars());
+    }
+        auto structelems = new Expressions();
+        structelems.setDim(sym.fields.dim);
+        for (size_t j = 0; j < structelems.dim; j++)
+        {
+	        auto vd = cast(VarDeclaration)(sym.fields[j]);
+	        Expression e;
+	        if (vd.init)
+	            e = vd.init.toExpression();
+	        else
+	            e = vd.type.defaultInitLiteral();
+	        structelems[j] = e;
+        }
+        auto structinit = new StructLiteralExp(loc, cast(StructDeclaration)sym, structelems);
+        // Why doesn't the StructLiteralExp constructor do this, when
+        // sym->type != NULL ?
+        structinit.type = sym.type;
+        return structinit;
+    }
+
 	
     override bool isZeroInit(Loc loc)
 	{
@@ -436,7 +430,7 @@
 		for (size_t i = 0; i < sym.fields.dim; i++)
 		{   
 			VarDeclaration v = cast(VarDeclaration)sym.fields[i];
-			if (v.isConst() || v.isInvariant())
+			if (v.isConst() || v.isImmutable())
 				return false;
 		}
 		return true;
@@ -513,6 +507,7 @@
 	
     override bool hasPointers()
 	{
+        // Probably should cache this information in sym rather than recompute
 		StructDeclaration s = sym;
 
 		sym.size(Loc(0));		// give error for forward references
@@ -536,7 +531,7 @@
 			m = MATCHexact;		// exact match
 			if (mod != to.mod)
 			{
-				if (to.mod == MODconst)
+				if (MODimplicitConv(mod, to.mod))
 					m = MATCHconst;
 				else
 				{	/* Check all the fields. If they can all be converted,
@@ -580,7 +575,8 @@
 	{
 		if (equals(to))
 			return MATCHexact;
-		if (ty == to.ty && sym == (cast(TypeStruct)to).sym && to.mod == MODconst)
+		if (ty == to.ty && sym == (cast(TypeStruct)to).sym &&
+            MODimplicitConv(mod, to.mod))
 			return MATCHconst;
 		return MATCHnomatch;
 	}
--- a/dmd/TypeTuple.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeTuple.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TypeTuple;
 
+import dmd.common;
 import dmd.Type;
 import dmd.ArrayTypes;
 import dmd.MOD;
@@ -14,26 +15,25 @@
 import dmd.TY;
 import dmd.Id;
 import dmd.STC;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.ErrorExp;
 import dmd.IntegerExp;
 
 class TypeTuple : Type
 {
-	Arguments arguments;	// types making up the tuple
+	Parameters arguments;	// types making up the tuple
 
-	this(Arguments arguments)
+	this(Parameters arguments)
 	{
 		super(TY.Ttuple);
 		//printf("TypeTuple(this = %p)\n", this);
 		this.arguments = arguments;
-		//printf("TypeTuple() %s\n", toChars());
+		//printf("TypeTuple() %p, %s\n", this, toChars());
 		debug {
 			if (arguments)
 			{
-				for (size_t i = 0; i < arguments.dim; i++)
+				foreach (arg; arguments)
 				{
-					Argument arg = cast(Argument)arguments.data[i];
 					assert(arg && arg.type);
 				}
 			}
@@ -55,25 +55,26 @@
 	this(Expressions exps)
 	{
 		super(TY.Ttuple);
-		Arguments arguments = new Arguments;
+		auto arguments = new Parameters;
 		if (exps)
 		{
 			arguments.setDim(exps.dim);
 			for (size_t i = 0; i < exps.dim; i++)
-			{   Expression e = cast(Expression)exps.data[i];
+			{   auto e = exps[i];
 				if (e.type.ty == Ttuple)
 					e.error("cannot form tuple of tuples");
-				Argument arg = new Argument(STCundefined, e.type, null, null);
-				arguments.data[i] = cast(void *)arg;
+				auto arg = new Parameter(STCundefined, e.type, null, null);
+				arguments[i] = arg;
 			}
 		}
 		this.arguments = arguments;
+        //printf("TypeTuple() %p, %s\n", this, toChars());
 	}
 
 	override Type syntaxCopy()
 	{
-		Arguments args = Argument.arraySyntaxCopy(arguments);
-		Type t = new TypeTuple(args);
+		auto args = Parameter.arraySyntaxCopy(arguments);
+		auto t = new TypeTuple(args);
 		t.mod = mod;
 		return t;
 	}
@@ -102,13 +103,13 @@
 			return 1;
 		}
 		if (t.ty == Ttuple)
-		{	TypeTuple tt = cast(TypeTuple)t;
+		{	auto tt = cast(TypeTuple)t;
 
 			if (arguments.dim == tt.arguments.dim)
 			{
 				for (size_t i = 0; i < tt.arguments.dim; i++)
-				{   Argument arg1 = cast(Argument)arguments.data[i];
-					Argument arg2 = cast(Argument)tt.arguments.data[i];
+				{   auto arg1 = arguments[i];
+					auto arg2 = tt.arguments[i];
 
 					if (!arg1.type.equals(arg2.type))
 						return 0;
@@ -123,10 +124,9 @@
 	{
 		if (arguments)
 		{
-			for (size_t i = 0; i < arguments.dim; i++)
+			foreach (arg; arguments)
 			{
-				Argument arg = cast(Argument)arguments.data[i];
-				Type t = arg.type.reliesOnTident();
+				auto t = arg.type.reliesOnTident();
 				if (t)
 					return t;
 			}
@@ -136,7 +136,7 @@
 
 	override void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod)
 	{
-		Argument.argsToCBuffer(buf, hgs, arguments, 0);
+		Parameter.argsToCBuffer(buf, hgs, arguments, 0);
 	}
 
 	override void toDecoBuffer(OutBuffer buf, int flag)
@@ -144,7 +144,7 @@
 		//printf("TypeTuple::toDecoBuffer() this = %p, %s\n", this, toChars());
 		Type.toDecoBuffer(buf, flag);
 		OutBuffer buf2 = new OutBuffer();
-		Argument.argsToDecoBuffer(buf2, arguments);
+		Parameter.argsToDecoBuffer(buf2, arguments);
 		uint len = buf2.offset;
 		//buf.printf("%d%.*s", len, len, cast(char *)buf2.extractData());
 		buf.printf("%d%s", len, buf2.extractString());
--- a/dmd/TypeTypedef.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeTypedef.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TypeTypedef;
 
+import dmd.common;
 import dmd.Type;
 import dmd.TypedefDeclaration;
 import dmd.MOD;
@@ -212,9 +213,6 @@
 	
     override Expression defaultInit(Loc loc)
 	{
-		Expression e;
-		Type bt;
-
 	version (LOGDEFAULTINIT) {
 		printf("TypeTypedef::defaultInit() '%s'\n", toChars());
 	}
@@ -223,8 +221,8 @@
 			//sym->init->toExpression()->print();
 			return sym.init.toExpression();
 		}
-		bt = sym.basetype;
-		e = bt.defaultInit(loc);
+		Type bt = sym.basetype;
+		Expression e = bt.defaultInit(loc);
 		e.type = this;
 		while (bt.ty == Tsarray)
 		{	
@@ -298,6 +296,11 @@
 		return toBasetype().hasPointers();
 	}
 	
+    override int hasWild()
+    {
+        return mod & MOD.MODwild || toBasetype().hasWild();
+    }
+    
     override Type toHeadMutable()
 	{
 		assert(false);
--- a/dmd/TypeTypeof.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeTypeof.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TypeTypeof;
 
+import dmd.common;
 import dmd.TypeFunction;
 import dmd.TypeQualified;
 import dmd.Expression;
@@ -131,6 +132,7 @@
 			if (exp.op == TOK.TOKtype)
 			{
 				error(loc, "argument %s to typeof is not an expression", exp.toChars());
+	            goto Lerr;
 			}
 			t = exp.type;
 			if (!t)
@@ -139,7 +141,10 @@
 				goto Lerr;
 			}
 			if (t.ty == TY.Ttypeof)
+            {
 				error(loc, "forward reference to %s", toChars());
+               	goto Lerr;
+            }
 
 			/* typeof should reflect the true type,
 			 * not what 'auto' would have gotten us.
--- a/dmd/TypedefDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypedefDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TypedefDeclaration;
 
+import dmd.common;
 import dmd.Declaration;
 import dmd.Initializer;
 import dmd.Type;
@@ -70,6 +71,9 @@
 			sem = 1;
 			basetype = basetype.semantic(loc, sc);
 			sem = 2;
+version(DMDV2) {
+    	    type = type.addStorageClass(storage_class);
+}
 			type = type.semantic(loc, sc);
 			if (sc.parent.isFuncDeclaration() && init)
 				semantic2(sc);
--- a/dmd/TypeidExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/TypeidExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TypeidExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Type;
 import dmd.OutBuffer;
@@ -7,15 +8,22 @@
 import dmd.Scope;
 import dmd.HdrGenState;
 import dmd.TOK;
+import dmd.Dsymbol;
+import dmd.TY;
+import dmd.Id;
+import dmd.ErrorExp;
+import dmd.DotIdExp;
+import dmd.CommaExp;
+import dmd.templates.Util;
 
 class TypeidExp : Expression
 {
-	Type typeidType;
+	Object obj;
 
-	this(Loc loc, Type typeidType)
+	this(Loc loc, Object o)
 	{
 		super(loc, TOK.TOKtypeid, TypeidExp.sizeof);
-		this.typeidType = typeidType;
+		this.obj = o;
 	}
 
 version (DumbClone) {
@@ -27,7 +35,7 @@
 }
 	override Expression syntaxCopy()
 	{
-		return new TypeidExp(loc, typeidType.syntaxCopy());
+		return new TypeidExp(loc, objectSyntaxCopy(obj));
 	}
 
 	override Expression semantic(Scope sc)
@@ -35,12 +43,53 @@
 		Expression e;
 
 	version (LOGSEMANTIC) {
-		printf("TypeidExp.semantic()\n");
+		printf("TypeidExp.semantic() %s\n", toChars());
 	}
-		typeidType = typeidType.semantic(loc, sc);
-		e = typeidType.getTypeInfo(sc);
-		if (e.loc.linnum == 0)
-			e.loc = loc;		// so there's at least some line number info
+		Type ta = isType(obj);
+		Expression ea = isExpression(obj);
+		Dsymbol sa = isDsymbol(obj);
+
+        //printf("ta %p ea %p sa %p\n", ta, ea, sa);
+
+		if (ta)
+		{
+			ta.resolve(loc, sc, &ea, &ta, &sa);
+		}
+        
+		if (ea)
+		{
+			ea = ea.semantic(sc);
+			ea = resolveProperties(sc, ea);
+			ta = ea.type;
+			if (ea.op == TOKtype)
+				ea = null;
+		}
+
+		if (!ta)
+		{	
+        	//printf("ta %p ea %p sa %p\n", ta, ea, sa);
+            error("no type for typeid(%s)", ea ? ea.toChars() : (sa ? sa.toChars() : ""));
+			return new ErrorExp();
+		}
+
+		if (ea && ta.toBasetype().ty == TY.Tclass)
+		{   /* Get the dynamic type, which is .classinfo
+		 */
+			e = new DotIdExp(ea.loc, ea, Id.classinfo_);
+			e = e.semantic(sc);
+		}
+		else
+		{	/* Get the static type
+		 */
+			e = ta.getTypeInfo(sc);
+			if (e.loc.linnum == 0)
+				e.loc = loc;		// so there's at least some line number info
+			if (ea)
+			{
+				e = new CommaExp(loc, ea, e);	// execute ea
+				e = e.semantic(sc);
+			}
+		}
 		return e;
 	}
 
--- a/dmd/UAddExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/UAddExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,11 +1,13 @@
 module dmd.UAddExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Identifier;
 import dmd.UnaExp;
 import dmd.Loc;
 import dmd.Scope;
 import dmd.TOK;
+import dmd.Id;
 
 class UAddExp : UnaExp
 {
@@ -34,6 +36,6 @@
 
 	override Identifier opId()
 	{
-		assert(false);
+		return Id.uadd;
 	}
 }
--- a/dmd/UnaExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/UnaExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.UnaExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.InterState;
 import dmd.TY;
@@ -85,6 +86,12 @@
 		return e1.canThrow();
 	}
 
+	Expression resolveLoc(Loc loc, Scope sc)
+	{
+		e1 = e1.resolveLoc(loc, sc);
+		return this;
+	}
+
 	override int inlineCost(InlineCostState* ics)
 	{
 		return 1 + e1.inlineCost(ics);
@@ -92,7 +99,7 @@
 
 	override Expression doInline(InlineDoState ids)
 	{
-		UnaExp ue = cast(UnaExp)copy();
+		auto ue = cast(UnaExp)copy();
 
 		ue.e1 = e1.doInline(ids);
 		return ue;
--- a/dmd/UnionDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/UnionDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.UnionDeclaration;
 
+import dmd.common;
 import dmd.StructDeclaration;
 import dmd.Loc;
 import dmd.Identifier;
--- a/dmd/UnitTestDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/UnitTestDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.UnitTestDeclaration;
 
+import dmd.common;
 import dmd.FuncDeclaration;
 import dmd.Loc;
 import dmd.Dsymbol;
--- a/dmd/UnrolledLoopStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/UnrolledLoopStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.UnrolledLoopStatement;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Statement;
 import dmd.InterState;
@@ -43,13 +44,11 @@
 		scd.sbreak = this;
 		scd.scontinue = this;
 
-		for (size_t i = 0; i < statements.dim; i++)
+		foreach(ref Statement s; statements)
 		{
-			Statement s = cast(Statement) statements.data[i];
 			if (s)
 			{
 				s = s.semantic(scd);
-				statements.data[i] = cast(void*)s;
 			}
 		}
 
@@ -76,9 +75,8 @@
 	override BE blockExit()
 	{
 		BE result = BEfallthru;
-		for (size_t i = 0; i < statements.dim; i++)
+		foreach (s; statements)
 		{	
-			Statement s = cast(Statement) statements.data[i];
 			if (s)
 			{
 				int r = s.blockExit();
@@ -105,7 +103,18 @@
 
 	override int inlineCost(InlineCostState* ics)
 	{
-		assert(false);
+		int cost = 0;
+
+		foreach (Statement s; statements)
+		{	
+			if (s)
+			{
+				cost += s.inlineCost(ics);
+				if (cost >= COST_MAX)
+					break;
+			}
+		}
+		return cost;
 	}
 
 	override Expression doInline(InlineDoState ids)
@@ -115,7 +124,12 @@
 
 	override Statement inlineScan(InlineScanState* iss)
 	{
-		assert(false);
+		foreach (ref Statement s; statements)
+		{	
+			if (s)
+				s = s.inlineScan(iss);
+		}
+		return this;
 	}
 
 	override void toIR(IRState* irs)
@@ -133,10 +147,8 @@
 
 		block* bdox;
 
-		size_t dim = statements.dim;
-		for (size_t i = 0 ; i < dim ; i++)
+		foreach (s; statements)
 		{
-			Statement s = cast(Statement)statements.data[i];
 			if (s !is null)
 			{
 				mystate.contBlock = block_calloc(blx);
--- a/dmd/UshrAssignExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/UshrAssignExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.UshrAssignExp;
 
+import dmd.common;
 import dmd.BinExp;
 import dmd.Loc;
 import dmd.Expression;
@@ -10,9 +11,13 @@
 import dmd.Id;
 import dmd.TOK;
 import dmd.Type;
+import dmd.ArrayLengthExp;
 import dmd.backend.elem;
+import dmd.expression.Ushr;
 import dmd.expression.Util;
 
+import dmd.backend.OPER;
+
 class UshrAssignExp : BinExp
 {
     this(Loc loc, Expression e1, Expression e2)
@@ -31,6 +36,13 @@
 		if (e)
 			return e;
 
+        if (e1.op == TOK.TOKarraylength)
+        {
+	        e = ArrayLengthExp.rewriteOpAssign(this);
+	        e = e.semantic(sc);
+	        return e;
+        }
+        
 		e1 = e1.modifiableLvalue(sc, e1);
 		e1.checkScalar();
 		e1.checkNoBool();
@@ -44,7 +56,7 @@
 	
     override Expression interpret(InterState istate)
 	{
-		assert(false);
+    	return interpretAssignCommon(istate, &Ushr);
 	}
 
     override Identifier opId()    /* For operator overloading */
@@ -54,6 +66,6 @@
 
     override elem* toElem(IRState* irs)
 	{
-		assert(false);
+		return toElemBin(irs, OPER.OPshrass);
 	}
 }
--- a/dmd/UshrExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/UshrExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.UshrExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Identifier;
 import dmd.InterState;
@@ -54,7 +55,7 @@
 
 	override Expression interpret(InterState istate)
 	{
-		assert(false);
+		return interpretCommon(istate, &Ushr);
 	}
 
 	override IntRange getIntRange()
@@ -74,12 +75,12 @@
 
 	override elem* toElem(IRState* irs)
 	{
-		elem *eleft  = e1.toElem(irs);
-		eleft.Ety = touns(eleft.Ety);
-		elem *eright = e2.toElem(irs);
-		elem *e = el_bin(OPshr, type.totym(), eleft, eright);
-		el_setLoc(e, loc);
-		return e;
+		//return toElemBin(irs, OPER.OPshr);
+        elem *eleft = e1.toElem(irs);
+        eleft.Ety = touns(eleft.Ety);
+        elem *eright = e2.toElem(irs);
+        elem *e = el_bin(OPER.OPshr, type.totym(), eleft, eright);
+        el_setLoc(e, loc);
+        return e;
 	}
-}
-
+}
\ No newline at end of file
--- a/dmd/Utf.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/Utf.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.Utf;
 
+import dmd.common;
 import dmd.Dchar;
 
 import std.utf;
--- a/dmd/Util.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/Util.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.Util;
 
+import dmd.common;
 import dmd.Loc;
 import dmd.Library;
 import dmd.File;
@@ -13,6 +14,9 @@
 import std.process : getenv;
 import std.c.string;
 import std.stdio : writef, writefln, write;
+
+import core.memory;
+
 version (Windows)
 {
     import std.c.process : spawnl, spawnlp;
@@ -74,7 +78,11 @@
 
 void warning(T...)(Loc loc, string format, T t)
 {
-	assert(false);
+	if (global.params.warnings && !global.gag)
+    {
+		write("warning - ");
+		error(loc, format, t);
+    }
 }
 
 void error(T...)(Loc loc, string format, T t)
@@ -94,6 +102,17 @@
     global.errors++;
 }
 
+T cloneThis(T)(T ptr)
+{
+	// similar code is used in Type.clone()
+	// TODO: move to Util or something...
+	size_t size = __traits(classInstanceSize, T);
+	void* mem = GC.malloc(size);
+	memcpy(mem, cast(void*)ptr, size);
+	
+	return cast(T)mem;
+}
+
 char* strupr(char* s)
 {
     char* t = s;
@@ -367,7 +386,7 @@
 						for ( ; *p2; p2++)
 						{   if (islower(*p2))
 								*p2 &= ~0x20;
-							else if (isspace(*p))
+							else if (isspace(*p2))
 								memmove(p2, p2 + 1, strlen(p2));
 							else if (*p2 == '=')
 							{
@@ -538,6 +557,7 @@
 "  -Llinkerflag   pass linkerflag to link\n"
 "  -lib           generate library rather than object files\n"
 "  -man           open web browser on manual page\n"
+"  -noboundscheck turns off array bounds checking for all functions\n"
 "  -nofloat       do not emit reference to floating point\n"
 "  -O             optimize\n"
 "  -o-            do not write object file\n"
@@ -548,7 +568,6 @@
 "  -quiet         suppress unnecessary messages\n"
 "  -release	 compile release version\n"
 "  -run srcfile args...   run resulting program, passing args\n"
-"  -safe          safe memory model\n"
 "  -unittest      compile in unit tests\n"
 "  -v             verbose\n"
 "  -version=level compile in version code >= level\n"
@@ -616,10 +635,13 @@
     precedence[TOK.TOKnew] = PREC.PREC_unary;
     precedence[TOK.TOKcast] = PREC.PREC_unary;
 
+    precedence[TOK.TOKpow] = PREC.PREC_pow;
+
     precedence[TOK.TOKmul] = PREC.PREC_mul;
     precedence[TOK.TOKdiv] = PREC.PREC_mul;
     precedence[TOK.TOKmod] = PREC.PREC_mul;
-
+    precedence[TOKpow]     = PREC.PREC_mul;
+	
     precedence[TOK.TOKadd] = PREC.PREC_add;
     precedence[TOK.TOKmin] = PREC.PREC_add;
     precedence[TOK.TOKcat] = PREC.PREC_add;
@@ -678,6 +700,7 @@
     precedence[TOK.TOKmulass] = PREC.PREC_assign;
     precedence[TOK.TOKdivass] = PREC.PREC_assign;
     precedence[TOK.TOKmodass] = PREC.PREC_assign;
+    precedence[TOK.TOKpowass]   = PREC.PREC_assign;
     precedence[TOK.TOKshlass] = PREC.PREC_assign;
     precedence[TOK.TOKshrass] = PREC.PREC_assign;
     precedence[TOK.TOKushrass] = PREC.PREC_assign;
@@ -690,7 +713,8 @@
 
 int runLINK()
 {
-version (_WIN32) {
+version (_WIN32)
+{
     string p;
     int i;
     int status;
@@ -1045,7 +1069,7 @@
     }
 
     status = executearg0(cmd, args);
-version (_WIN32) {
+version (Windows) {
     if (status == -1) {
 		auto cmdZ = toStringz(cmd);
 		auto argsZ = toStringz(args);
@@ -1057,7 +1081,7 @@
     if (status)
     {
 	if (status == -1)
-	    printf("Can't run '%s', check PATH\n", cmd);
+	    printf("Can't run '%.*s', check PATH\n", cmd);
 	else
 	    printf("--- errorlevel %d\n", status);
     }
@@ -1092,7 +1116,7 @@
 	auto fileZ = toStringz(file);
 	auto argsZ = toStringz(args);
     return spawnl(0, fileZ, fileZ, argsZ, null);
-} else version (XXX) { ///#elif linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4
+} else version (Posix) { ///#elif linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4
 	assert(false);
 	/+
     char *full;
--- a/dmd/VarDeclaration.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/VarDeclaration.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.VarDeclaration;
 
+import dmd.common;
 import dmd.Array;
 import dmd.Declaration;
 import dmd.SliceExp;
@@ -32,7 +33,7 @@
 import dmd.Initializer;
 import dmd.TypeStruct;
 import dmd.TypeTuple;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.ExpInitializer;
 import dmd.ArrayTypes;
 import dmd.Dsymbol;
@@ -197,10 +198,31 @@
 		if (!type)
 		{	
 			inuse++;
-			type = init.inferType(sc);
+			
+			ArrayInitializer ai = init.isArrayInitializer();
+			if (ai)
+			{
+				Expression e;
+				if (ai.isAssociativeArray())
+					e = ai.toAssocArrayLiteral();
+				else
+					e = init.toExpression();
+				init = new ExpInitializer(e.loc, e);
+				type = init.inferType(sc);
+				if (type.ty == TY.Tsarray)
+					type = type.nextOf().arrayOf();
+			}
+			else
+				type = init.inferType(sc);
+			
 			inuse--;
 			inferred = 1;
 
+			if (init.isArrayInitializer() && type.toBasetype().ty == TY.Tsarray)
+			{   // Prefer array literals to give a T[] type rather than a T[dim]
+				type = type.toBasetype().nextOf().arrayOf();
+			}
+			
 			/* This is a kludge to support the existing syntax for RAII
 			 * declarations.
 			 */
@@ -225,11 +247,18 @@
 		//printf("storage_class = x%x\n", storage_class);
 
 version (DMDV2) {
+static if (true) {
+		if (storage_class & STC.STCgshared && sc.func && sc.func.isSafe())
+		{
+		error("__gshared not allowed in safe functions; use shared");
+		}
+} else {
 		if (storage_class & STC.STCgshared && global.params.safe && !sc.module_.safe)
 		{
 		error("__gshared not allowed in safe mode; use shared");
 		}
 }
+}
 
 		Dsymbol parent = toParent();
 		FuncDeclaration fd = parent.isFuncDeclaration();
@@ -259,15 +288,15 @@
 			* and add those.
 			*/
 		TypeTuple tt = cast(TypeTuple)tb;
-		size_t nelems = Argument.dim(tt.arguments);
+		size_t nelems = Parameter.dim(tt.arguments);
 		Objects exps = new Objects();
 		exps.setDim(nelems);
 		Expression ie = init ? init.toExpression() : null;
 
 		for (size_t i = 0; i < nelems; i++)
-		{   Argument arg = Argument.getNth(tt.arguments, i);
+		{   auto arg = Parameter.getNth(tt.arguments, i);
 
-			OutBuffer buf = new OutBuffer();
+			auto buf = new OutBuffer();
 			///buf.printf("_%s_field_%zu", ident.toChars(), i);
 			buf.printf("_%s_field_%s", ident.toChars(), i);
 			buf.writeByte(0);
@@ -276,7 +305,7 @@
 
 			Expression einit = ie;
 			if (ie && ie.op == TOK.TOKtuple)
-			{	einit = cast(Expression)(cast(TupleExp)ie).exps.data[i];
+			{	einit = (cast(TupleExp)ie).exps[i];
 			}
 			Initializer ti = init;
 			if (einit)
@@ -293,10 +322,10 @@
 				sc.scopesym.members.push(v);
 			}
 
-			Expression e = new DsymbolExp(loc, v);
-			exps.data[i] = cast(void*)e;
+			auto e = new DsymbolExp(loc, v);
+			exps[i] = e;
 		}
-		TupleDeclaration v2 = new TupleDeclaration(loc, ident, exps);
+		auto v2 = new TupleDeclaration(loc, ident, exps);
 		v2.isexp = 1;
 		aliassym = v2;
 		return;
@@ -314,10 +343,12 @@
 		if (type.isShared())
 			storage_class |= STC.STCshared;
 		}
-		else if (type.isInvariant())
+		else if (type.isImmutable())
 		storage_class |= STC.STCimmutable;
 		else if (type.isShared())
 		storage_class |= STC.STCshared;
+        else if (type.isWild())
+	    storage_class |= STC.STCwild;
 
 		if (isSynchronized())
 		{
@@ -393,6 +424,13 @@
 		{
 			error("only parameters or foreach declarations can be ref");
 		}
+
+        if ((storage_class & (STCstatic | STCextern | STCtls | STCgshared | STCmanifest) ||
+	        isDataseg()) &&
+	        type.hasWild())
+        {
+	        error("only fields, parameters or stack based variables can be inout");
+        }
 }
 
 		if (type.isauto() && !noauto)
@@ -409,7 +447,7 @@
 			}
 		}
 
-		if ((isConst() || isInvariant()) && !init && !fd)
+		if ((isConst() || isImmutable()) && !init && !fd)
 		{
 			// Initialize by constructor only
 			storage_class |= STC.STCctorinit;
@@ -472,7 +510,8 @@
 		ArrayInitializer ai = init.isArrayInitializer();
 		if (ai && tb.ty == TY.Taarray)
 		{
-			init = ai.toAssocArrayInitializer();
+			Expression e = ai.toAssocArrayLiteral();
+			init = new ExpInitializer(e.loc, e);
 		}
 
 		StructInitializer si = init.isStructInitializer();
@@ -622,7 +661,7 @@
 			}
 		}
 		else if (storage_class & (STC.STCconst | STC.STCimmutable | STC.STCmanifest) ||
-			type.isConst() || type.isInvariant() ||
+			type.isConst() || type.isImmutable() ||
 			parent.isAggregateDeclaration())
 		{
 			/* Because we may need the results of a const declaration in a
@@ -765,7 +804,7 @@
 	{
 static if (false) {
 		printf("VarDeclaration.isDataseg(%p, '%s')\n", this, toChars());
-		printf("%x, %p, %p\n", storage_class & (STC.STCstatic | STC.STCconst), parent.isModule(), parent.isTemplateInstance());
+		printf("%llx, isModule: %p, isTemplateInstance: %p\n", storage_class & (STC.STCstatic | STC.STCconst), parent.isModule(), parent.isTemplateInstance());
 		printf("parent = '%s'\n", parent.toChars());
 }
 		if (storage_class & STC.STCmanifest)
@@ -800,6 +839,15 @@
 }
 	}
 	
+    /********************************************
+     * Can variable be read and written by CTFE?
+     */
+
+    int isCTFE()
+    {
+        return (storage_class & STCctfe) || !isDataseg();
+    }
+
     override bool hasPointers()
 	{
 		//printf("VarDeclaration.hasPointers() %s, ty = %d\n", toChars(), type.ty);
@@ -814,7 +862,7 @@
 		 *	const int x = 3;
 		 * are not stored and hence cannot have their address taken.
 		 */
-		if ((isConst() || isInvariant()) && (storage_class & STC.STCinit) && (!(storage_class & (STC.STCstatic | STC.STCextern)) || (storage_class & STC.STCfield)) &&
+		if ((isConst() || isImmutable()) && (storage_class & STC.STCinit) && (!(storage_class & (STC.STCstatic | STC.STCextern)) || (storage_class & STC.STCfield)) &&
 			(!parent || toParent().isModule() || toParent().isTemplateInstance()) && type.toBasetype().isTypeBasic())
 		{
 			return false;
@@ -962,7 +1010,7 @@
 	 */
     Expression getConstInitializer()
 	{
-		if ((isConst() || isInvariant() || storage_class & STC.STCmanifest) && storage_class & STC.STCinit)
+		if ((isConst() || isImmutable() || storage_class & STC.STCmanifest) && storage_class & STC.STCinit)
 		{
 			ExpInitializer ei = getExpInitializer();
 			if (ei)
--- a/dmd/VarExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/VarExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.VarExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Declaration;
 import dmd.InterState;
@@ -22,8 +23,7 @@
 import dmd.backend.dt_t;
 import dmd.expression.Util;
 
-// Variable
-
+//! Variable
 class VarExp : SymbolExp
 {
 	this(Loc loc, Declaration var, bool hasOverloads = false)
@@ -70,7 +70,7 @@
 		if (v)
 		{
 static if (false) {
-			if ((v.isConst() || v.isInvariant()) && type.toBasetype().ty != TY.Tsarray && v.init)
+			if ((v.isConst() || v.isImmutable()) && type.toBasetype().ty != TY.Tsarray && v.init)
 			{
 				ExpInitializer ei = v.init.isExpInitializer();
 				if (ei)
@@ -83,8 +83,22 @@
 			v.checkNestedReference(sc, loc);
 version (DMDV2) {
 	static if (true) {
-			if (sc.func)
+			if (sc.func && !sc.intypeof)
 			{
+				/* Given:
+				 * void f()
+				 * { int fx;
+				 *   pure void g()
+				 *   {  int gx;
+				 *      void h()
+				 *      {  int hx;
+				 *         void i() { }
+				 *      }
+				 *   }
+				 * }
+				 * i() can modify hx and gx but not fx
+				 */
+				
 				/* Determine if sc.func is pure or if any function that
 				 * encloses it is also pure.
 				 */
@@ -107,22 +121,28 @@
 				 * If it is pure, it cannot access any mutable variables other
 				 * than those inside itself
 				 */
-				if (hasPureParent && !sc.intypeof && v.isDataseg() && !v.isInvariant())
+				if (hasPureParent && v.isDataseg() && !v.isImmutable())
 				{
 					error("pure function '%s' cannot access mutable static data '%s'",
 						sc.func.toChars(), v.toChars());
 				}
-				else if (sc.func.isPure() && sc.parent != v.parent && !sc.intypeof && !v.isInvariant() && !(v.storage_class & STC.STCmanifest))
+				else if (sc.func.isPure() && sc.parent != v.parent && !v.isImmutable() && !(v.storage_class & STC.STCmanifest))
 				{
 					error("pure nested function '%s' cannot access mutable data '%s'", sc.func.toChars(), v.toChars());
 					if (v.isEnumDeclaration())
 						error("enum");
-				}	
+				}
+
+				/* Do not allow safe functions to access __gshared data
+				 */
+				if (sc.func.isSafe() && v.storage_class & STCgshared)
+				error("safe function '%s' cannot access __gshared data '%s'",
+					sc.func.toChars(), v.toChars());
 			}
 	} else {
 			if (sc.func && sc.func.isPure() && !sc.intypeof)
 			{
-				if (v.isDataseg() && !v.isInvariant())
+				if (v.isDataseg() && !v.isImmutable())
 					error("pure function '%s' cannot access mutable static data '%s'", sc.func.toChars(), v.toChars());
 			}
 	}
@@ -187,8 +207,19 @@
 			}
 		}
 	}
+    
+    override void checkEscapeRef()
+    {
+        VarDeclaration v = var.isVarDeclaration();
+        if (v)
+        {
+	    if (!v.isDataseg() && !(v.storage_class & (STCref | STCout)))
+	        error("escaping reference to local variable %s", v.toChars());
+        }
+    }
 
-version (DMDV2) {
+version (DMDV2)
+{
 	override int isLvalue()
 	{
 		if (var.storage_class & STClazy)
@@ -216,8 +247,8 @@
 	override Expression modifiableLvalue(Scope sc, Expression e)
 	{
 		//printf("VarExp::modifiableLvalue('%s')\n", var.toChars());
-		if (type && type.toBasetype().ty == TY.Tsarray)
-			error("cannot change reference to static array '%s'", var.toChars());
+		//if (type && type.toBasetype().ty == TY.Tsarray)
+		//	error("cannot change reference to static array '%s'", var.toChars());
 
 		var.checkModify(loc, sc, type);
 
@@ -230,6 +261,12 @@
 		assert(false);
 	}
 
+	version(DMDV1)
+	override elem* toElem(IRState* irs)
+	{
+		assert(false);
+	}
+
 	override void scanForNestedRef(Scope sc)
 	{
 		//printf("VarExp.scanForNestedRef(%s)\n", toChars());
--- a/dmd/VersionCondition.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/VersionCondition.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.VersionCondition;
 
+import dmd.common;
 import dmd.DVCondition;
 import dmd.Loc;
 import dmd.Module;
--- a/dmd/VersionSymbol.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/VersionSymbol.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.VersionSymbol;
 
+import dmd.common;
 import dmd.Dsymbol;
 import dmd.Loc;
 import dmd.Identifier;
@@ -12,14 +13,14 @@
 import dmd.String;
 import dmd.OutBuffer;
 
+/* VersionSymbol's happen for statements like:
+ *	version = identifier;
+ *	version = integer;
+ */
 class VersionSymbol : Dsymbol
 {
     uint level;
 
-	/* VersionSymbol's happen for statements like:
-	 *	version = identifier;
-	 *	version = integer;
-	 */
     this(Loc loc, Identifier ident)
 	{
 		super(ident);
@@ -36,7 +37,10 @@
 	
     override Dsymbol syntaxCopy(Dsymbol s)
 	{
-		assert(false);
+		assert(!s);
+		VersionSymbol ds = new VersionSymbol(loc, ident);
+		ds.level = level;
+		return ds;
 	}
 	
     override bool addMember(Scope sc, ScopeDsymbol s, bool memnum)
@@ -77,11 +81,17 @@
 	
     override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
 	{
-		assert(false);
+		buf.writestring("version = ");
+		if (ident)
+			buf.writestring(ident.toChars());
+		else
+			buf.printf("%u", level);
+		buf.writestring(";");
+		buf.writenl();
 	}
 	
     override string kind()
 	{
-		assert(false);
+		return "version";
 	}
 }
--- a/dmd/VoidInitializer.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/VoidInitializer.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.VoidInitializer;
 
+import dmd.common;
 import dmd.Initializer;
 import dmd.Type;
 import dmd.Loc;
--- a/dmd/VolatileStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/VolatileStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.VolatileStatement;
 
+import dmd.common;
 import dmd.Statement;
 import dmd.ArrayTypes;
 import dmd.Scope;
@@ -14,6 +15,9 @@
 import dmd.backend.Blockx;
 import dmd.backend.Util;
 import dmd.backend.BC;
+import dmd.backend.elem;
+import dmd.backend.OPER;
+import dmd.backend.mTY;
 //import dmd.backend.BFL;
 
 class VolatileStatement : Statement
@@ -43,12 +47,9 @@
 		Statements a = statement ? statement.flatten(sc) : null;
 		if (a)
 		{	
-			for (int i = 0; i < a.dim; i++)
+			foreach (ref Statement s; a)
 			{   
-				Statement s = cast(Statement)a.data[i];
-
 				s = new VolatileStatement(loc, s);
-				a.data[i] = cast(void*)s;
 			}
 		}
 
@@ -72,6 +73,23 @@
 		return this;
 	}
 
+    static void el_setVolatile(elem* e)
+	{
+		while (1)
+		{
+			e.Ety |= mTYvolatile;
+			if (OTunary(e.Eoper))
+				e = e.E1;
+			else if (OTbinary(e.Eoper))
+			{
+				el_setVolatile(e.E2);
+				e = e.E1;
+			}
+			else
+				break;
+		}
+	}
+
     override void toIR(IRState* irs)
 	{
 		block* b;
--- a/dmd/WhileStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/WhileStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.WhileStatement;
 
+import dmd.common;
 import dmd.Statement;
 import dmd.Expression;
 import dmd.Scope;
@@ -47,7 +48,7 @@
 	
     override bool hasContinue()
 	{
-		assert(false);
+		return true;
 	}
 	
     override bool usesEH()
@@ -67,7 +68,11 @@
 	
     override Expression interpret(InterState istate)
 	{
-		assert(false);
+version(LOG) {
+       printf("WhileStatement::interpret()\n");
+}
+        assert(false);			// rewritten to ForStatement
+        return null;
 	}
 	
     override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
--- a/dmd/WithScopeSymbol.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/WithScopeSymbol.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.WithScopeSymbol;
 
+import dmd.common;
 import dmd.ScopeDsymbol;
 import dmd.WithStatement;
 import dmd.Loc;
@@ -12,12 +13,13 @@
 
     this(WithStatement withstate)
 	{
-		assert(false);
+		this.withstate = withstate;
 	}
 	
     override Dsymbol search(Loc loc, Identifier ident, int flags)
 	{
-		assert(false);
+		// Acts as proxy to the with class declaration
+		return withstate.exp.type.toDsymbol(null).search(loc, ident, 0);
 	}
 
     override WithScopeSymbol isWithScopeSymbol() { return this; }
--- a/dmd/WithStatement.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/WithStatement.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,16 +1,34 @@
 module dmd.WithStatement;
 
+import dmd.common;
 import dmd.Statement;
 import dmd.Expression;
 import dmd.VarDeclaration;
 import dmd.Loc;
 import dmd.OutBuffer;
+import dmd.ScopeDsymbol;
+import dmd.TypeExp;
+import dmd.TOK;
+import dmd.Initializer;
+import dmd.ExpInitializer;
+import dmd.Id;
+import dmd.ScopeExp;
+import dmd.WithScopeSymbol;
+import dmd.TY;
+import dmd.Type;
 import dmd.HdrGenState;
 import dmd.InlineScanState;
 import dmd.IRState;
 import dmd.Scope;
 import dmd.BE;
 
+import dmd.backend.Symbol;
+import dmd.backend.block;
+import dmd.backend.Blockx;
+import dmd.backend.elem;
+import dmd.backend.Util;
+import dmd.backend.OPER;
+
 class WithStatement : Statement
 {
     Expression exp;
@@ -27,12 +45,74 @@
 	
     override Statement syntaxCopy()
 	{
-		assert(false);
+		WithStatement s = new WithStatement(loc, exp.syntaxCopy(), body_ ? body_.syntaxCopy() : null);
+		return s;
 	}
 	
     override Statement semantic(Scope sc)
 	{
-		assert(false);
+		ScopeDsymbol sym;
+		Initializer init;
+
+		//printf("WithStatement.semantic()\n");
+		exp = exp.semantic(sc);
+		exp = resolveProperties(sc, exp);
+		if (exp.op == TOKimport)
+		{	
+			ScopeExp es = cast(ScopeExp)exp;
+
+			sym = es.sds;
+		}
+		else if (exp.op == TOKtype)
+		{	
+			TypeExp es = cast(TypeExp)exp;
+
+			sym = es.type.toDsymbol(sc).isScopeDsymbol();
+			if (!sym)
+			{   
+				error("%s has no members", es.toChars());
+				body_ = body_.semantic(sc);
+				return this;
+			}
+		}
+		else
+		{	
+			Type t = exp.type;
+
+			assert(t);
+			t = t.toBasetype();
+			if (t.isClassHandle())
+			{
+				init = new ExpInitializer(loc, exp);
+				wthis = new VarDeclaration(loc, exp.type, Id.withSym, init);
+				wthis.semantic(sc);
+
+				sym = new WithScopeSymbol(this);
+				sym.parent = sc.scopesym;
+			}
+			else if (t.ty == Tstruct)
+			{
+				Expression e = exp.addressOf(sc);
+				init = new ExpInitializer(loc, e);
+				wthis = new VarDeclaration(loc, e.type, Id.withSym, init);
+				wthis.semantic(sc);
+				sym = new WithScopeSymbol(this);
+				sym.parent = sc.scopesym;
+			}
+			else
+			{   
+				error("with expressions must be class objects, not '%s'", exp.type.toChars());
+				return null;
+			}
+		}
+		sc = sc.push(sym);
+
+		if (body_)
+			body_ = body_.semantic(sc);
+
+		sc.pop();
+
+		return this;
 	}
 	
     override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
@@ -47,7 +127,14 @@
 	
     override BE blockExit()
 	{
-		assert(false);
+		BE result = BEnone;
+		if (exp.canThrow())
+			result = BEthrow;
+		if (body_)
+			result |= body_.blockExit();
+		else
+			result |= BEfallthru;
+		return result;
 	}
 
     override Statement inlineScan(InlineScanState* iss)
@@ -57,6 +144,34 @@
 
     override void toIR(IRState* irs)
 	{
-		assert(false);
+		Symbol* sp;
+		elem* e;
+		elem* ei;
+		ExpInitializer ie;
+		Blockx* blx = irs.blx;
+
+		//printf("WithStatement.toIR()\n");
+		if (exp.op == TOKimport || exp.op == TOKtype)
+		{
+		}
+		else
+		{
+			// Declare with handle
+			sp = wthis.toSymbol();
+			symbol_add(sp);
+
+			// Perform initialization of with handle
+			ie = wthis.init.isExpInitializer();
+			assert(ie);
+			ei = ie.exp.toElem(irs);
+			e = el_var(sp);
+			e = el_bin(OPeq,e.Ety, e, ei);
+			elem_setLoc(e, loc);
+			incUsage(irs, loc);
+			block_appendexp(blx.curblock,e);
+		}
+		// Execute with block
+		if (body_)
+			body_.toIR(irs);
 	}
 }
--- a/dmd/XorAssignExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/XorAssignExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,7 @@
 module dmd.XorAssignExp;
 
+import dmd.common;
+import dmd.expression.Xor;
 import dmd.BinExp;
 import dmd.Loc;
 import dmd.Expression;
@@ -28,7 +30,7 @@
 	
     override Expression interpret(InterState istate)
 	{
-		assert(false);
+    	return interpretAssignCommon(istate, &Xor);
 	}
 	
     override void buildArrayIdent(OutBuffer buf, Expressions arguments)
@@ -36,9 +38,9 @@
 		AssignExp_buildArrayIdent(buf, arguments, "Xor");
 	}
 	
-    override Expression buildArrayLoop(Arguments fparams)
+    override Expression buildArrayLoop(Parameters fparams)
 	{
-		assert(false);
+		return AssignExp_buildArrayLoop!(typeof(this))(fparams);
 	}
 
     override Identifier opId()    /* For operator overloading */
--- a/dmd/XorExp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/XorExp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.XorExp;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Identifier;
 import dmd.InterState;
@@ -47,11 +48,10 @@
 			else
 			{
 				typeCombine(sc);
-				if (e1.op != TOKslice && e2.op != TOKslice)
-				{
+				if (!e1.isArrayOperand())
 					e1.checkIntegral();
+				if (!e2.isArrayOperand())
 					e2.checkIntegral();
-				}
 			}
 		}
 		return this;
@@ -73,7 +73,7 @@
 
 	override Expression interpret(InterState istate)
 	{
-		assert(false);
+		return interpretCommon(istate, &Xor);
 	}
 
 	override void buildArrayIdent(OutBuffer buf, Expressions arguments)
@@ -81,14 +81,9 @@
 		Exp_buildArrayIdent(buf, arguments, "Xor");
 	}
 
-	override Expression buildArrayLoop(Arguments fparams)
+	override Expression buildArrayLoop(Parameters fparams)
 	{
-		/* Evaluate assign expressions left to right		
-		 */								
-		Expression ex1 = e1.buildArrayLoop(fparams);		
-		Expression ex2 = e2.buildArrayLoop(fparams);		
-		Expression e = new XorExp(Loc(0), ex1, ex2);			
-		return e;							
+		return Exp_buildArrayLoop!(typeof(this))(fparams);
 	}
 
 	override MATCH implicitConvTo(Type t)
--- a/dmd/backend/Blockx.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/backend/Blockx.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.backend.Blockx;
 
+import dmd.common;
 import dmd.Module;
 import dmd.Declaration;
 import dmd.ClassDeclaration;
--- a/dmd/backend/Classsym.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/backend/Classsym.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.backend.Classsym;
 
+import dmd.common;
 import dmd.backend.Symbol;
 
 alias Symbol Classsym;
\ No newline at end of file
--- a/dmd/backend/Config.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/backend/Config.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.backend.Config;
 
+import dmd.common;
 import dmd.backend.LINKAGE;
 import dmd.EnumUtils;
 
--- a/dmd/backend/Configv.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/backend/Configv.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.backend.Configv;
 
+import dmd.common;
 import dmd.backend.LANG;
 
 // Configuration that is not saved in precompiled header
@@ -15,5 +16,5 @@
     LANG language;		// message language
     int errmax;			// max error count
 }
-
+
 Configv configv;
\ No newline at end of file
--- a/dmd/backend/Cstate.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/backend/Cstate.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.backend.Cstate;
 
+import dmd.common;
 import dmd.backend.Symbol;
 import dmd.backend.LIST;
 import dmd.backend.symtab_t;
--- a/dmd/backend/DT.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/backend/DT.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.backend.DT;
 
+import dmd.common;
 import dmd.backend.dt_t;
 
 enum DT
--- a/dmd/backend/LIST.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/backend/LIST.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.backend.LIST;
 
+import dmd.common;
 import dmd.backend.Symbol;
 
 struct LIST
--- a/dmd/backend/OPER.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/backend/OPER.d	Tue Sep 14 15:46:50 2010 +0200
@@ -324,12 +324,17 @@
 #define _OTboolnop	1
 +/
 
-ubyte OTbinary(OPER op) {
+ubyte OTbinary(OPER op)
+{
 	return (optab1[op] & _OT._OTbinary);
 }
 
+ubyte OTunary(OPER op)
+{
+	return (optab1[op] & _OT._OTunary);
+}
+
 /+
-#define OTunary(op)	(optab1[op]&_OTunary)
 #define OTleaf(op)	(!(optab1[op]&(_OTunary|_OTbinary)))
 #define OTcommut(op)	(optab1[op]&_OTcommut)
 #define OTassoc(op)	(optab1[op]&_OTassoc)
--- a/dmd/backend/RTLSYM.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/backend/RTLSYM.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.backend.RTLSYM;
 
+import dmd.common;
 import dmd.backend.Symbol;
 
 enum RTLSYM
@@ -56,6 +57,8 @@
 	RTLSYM_ARRAYCATNT,
 	RTLSYM_ARRAYAPPENDT,
 	RTLSYM_ARRAYAPPENDCT,
+    RTLSYM_ARRAYAPPENDCD,
+    RTLSYM_ARRAYAPPENDWD,
 	RTLSYM_ARRAYSETLENGTHT,
 	RTLSYM_ARRAYSETLENGTHIT,
 	RTLSYM_ARRAYCOPY, 
--- a/dmd/backend/StringTab.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/backend/StringTab.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.backend.StringTab;
 
+import dmd.common;
 import dmd.Module;
 import dmd.backend.Symbol;
 
--- a/dmd/backend/Symbol.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/backend/Symbol.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.backend.Symbol;
 
+import dmd.common;
 import dmd.backend.dt_t;
 import dmd.backend.TYPE;
 import dmd.backend.LIST;
--- a/dmd/backend/TYFL.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/backend/TYFL.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.backend.TYFL;
 
+import dmd.common;
 import dmd.backend.Util;
 
 extern(C++) ubyte* get_tytab();
--- a/dmd/backend/TYPE.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/backend/TYPE.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.backend.TYPE;
 
+import dmd.common;
 import dmd.backend.Util;
 import dmd.backend.Srcpos;
 import dmd.backend.elem;
--- a/dmd/backend/Util.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/backend/Util.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.backend.Util;
 
+import dmd.common;
 import dmd.Array;
 import dmd.Loc;
 
@@ -166,7 +167,7 @@
 	elem_p el_copytree(elem_p);
 	int el_allbits(elem *e, int bit);
 	block* block_goto(Blockx* bctx, BC bc, block* bn);
-	block* block_calloc(Blockx* blx);
+//	block* block_calloc(Blockx* blx);
 	targ_size_t type_paramsize_i(type* t);
 	int os_critsecsize();
 	void el_setVolatile(elem* e);
@@ -174,6 +175,15 @@
 	elem* el_const(tym_t, eve*);
 	elem *el_params(void** args, int length);
 	
+	/****************************************
+	 * Allocate a new block, and set the tryblock.
+	 */
+	block *block_calloc(Blockx *blx)
+	{
+		block* b = block_calloc();
+		b.Btry = blx.tryblock;
+		return b;
+	}
 	
 	version (SEH) {
 		void nteh_declarvars(Blockx* bx);
--- a/dmd/backend/block.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/backend/block.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.backend.block;
 
+import dmd.common;
 import dmd.backend.elem;
 import dmd.backend.LIST;
 import dmd.backend.regm_t;
--- a/dmd/backend/code.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/backend/code.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.backend.code;
 
+import dmd.common;
 import dmd.backend.targ_types;
 import dmd.backend.Srcpos;
 import dmd.backend.elem;
--- a/dmd/backend/con_t.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/backend/con_t.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.backend.con_t;
 
+import dmd.common;
 import dmd.backend.cse_t;
 import dmd.backend.immed_t;
 import dmd.backend.regm_t;
--- a/dmd/backend/cse_t.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/backend/cse_t.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.backend.cse_t;
 
+import dmd.common;
 import dmd.backend.elem;
 import dmd.backend.regm_t;
 
--- a/dmd/backend/dt_t.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/backend/dt_t.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.backend.dt_t;
 
+import dmd.common;
 import dmd.backend.targ_types;
 import dmd.backend.Symbol;
 
--- a/dmd/backend/elem.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/backend/elem.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.backend.elem;
 
+import dmd.common;
 import dmd.Port;
 import dmd.Complex;
 
@@ -11,6 +12,7 @@
 import dmd.backend.TYPE;
 import dmd.backend.Util;
 import dmd.backend.Srcpos;
+import dmd.backend.OPER;
 
 /*********************************
  * Union of all data types. Storage allocated must be the right
@@ -91,8 +93,8 @@
     ushort	id;
 }
 
-    ubyte Eoper;	// operator (OPxxxx)
-    ubyte Ecount;	// # of parents of this elem - 1,
+    OPER	Eoper;	// operator (OPxxxx)
+    ubyte	Ecount;	// # of parents of this elem - 1,
 				// always 0 until CSE elimination is done
     eve EV;		// variants for each type of elem
 	
--- a/dmd/backend/enum_t.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/backend/enum_t.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.backend.enum_t;
 
+import dmd.common;
 import dmd.backend.SEN;
 import dmd.backend.Symbol;
 import dmd.backend.LIST;
--- a/dmd/backend/func_t.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/backend/func_t.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.backend.func_t;
 
+import dmd.common;
 import dmd.backend.LIST;
 import dmd.backend.block;
 import dmd.backend.symtab_t;
--- a/dmd/backend/glue.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/backend/glue.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.backend.glue;
 
+import dmd.common;
 import dmd.Array;
 import dmd.Dsymbol;
 import dmd.File;
@@ -19,12 +20,12 @@
 import core.stdc.string;
 
 __gshared Array obj_symbols_towrite;
+__gshared Outbuffer objbuf;
 
 version (Windows)
 {
 	extern (C++) extern
 	{
-		__gshared Outbuffer objbuf;
 		int go_flag(char* cp);
 		void util_set64();
 		void util_set386();
@@ -34,7 +35,6 @@
 {
 	extern (C++)
 	{
-		extern(C) extern __gshared Outbuffer objbuf;
 		int go_flag(char* cp);
 		void util_set64();
 		void util_set386();
--- a/dmd/backend/iasm.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/backend/iasm.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.backend.iasm;
 
+import dmd.common;
 import dmd.Dsymbol;
 import dmd.LabelDsymbol;
 import dmd.AsmStatement;
@@ -35,6 +36,7 @@
 import dmd.backend.Config;
 import dmd.backend.targ_types;
 import dmd.backend.elem;
+import dmd.backend.block;
 import dmd.Util;
 
 import std.stdio : writef, writefln;
@@ -3434,7 +3436,7 @@
 			error(asmstate.loc, "tuple index %u exceeds %u", index, tup.objects.dim);
 	    else
 	    {
-			Object o = cast(Object)tup.objects.data[index];
+			Object o = tup.objects[index];
 			if (auto d = cast(Dsymbol)o)
 			{   
 				o1.s = d;
@@ -4339,7 +4341,7 @@
 		}
 		if ((v.isConst()
 ///version (DMDV2) {
-			|| v.isInvariant() || v.storage_class & STCmanifest
+			|| v.isImmutable() || v.storage_class & STCmanifest
 ///}
 			) && !v.type.isfloating() && v.init)
 		{   
@@ -4465,3 +4467,22 @@
 		(szReg[1] == 't' || szReg[1] == 'T'));
 }
 }
+
+extern(C)
+{
+	// backward reference from backend
+	
+	extern int refparam;
+	
+	/**********************************
+	 * Return mask of registers used by block bp.
+	 */
+	regm_t iasm_regs(block *bp)
+	{
+		debug if (debuga)
+			printf("Block iasm regs = 0x%X\n", bp.usIasmregs);
+
+		refparam |= bp.bIasmrefparam;
+		return bp.usIasmregs;
+	}
+}
\ No newline at end of file
--- a/dmd/backend/immed_t.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/backend/immed_t.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.backend.immed_t;
 
+import dmd.common;
 import dmd.backend.targ_types;
 import dmd.backend.regm_t;
 import dmd.backend.REGMAX;
--- a/dmd/backend/rel.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/backend/rel.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.backend.rel;
 
+import dmd.common;
 import dmd.backend.OPER;
 
 extern (C++) extern
--- a/dmd/backend/struct_t.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/backend/struct_t.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.backend.struct_t;
 
+import dmd.common;
 import dmd.backend.targ_types;
 import dmd.backend.LIST;
 import dmd.backend.Symbol;
--- a/dmd/backend/symtab_t.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/backend/symtab_t.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.backend.symtab_t;
 
+import dmd.common;
 import dmd.backend.Symbol;
 import dmd.backend.Util;
 import dmd.backend.SYMIDX;
--- a/dmd/codegen/Util.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/codegen/Util.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,10 +1,12 @@
 module dmd.codegen.Util;
 
+import dmd.common;
 import dmd.Loc;
 import dmd.Id;
 import dmd.IRState;
 import dmd.Type;
 import dmd.Array;
+import dmd.Declaration;
 import dmd.Dsymbol;
 import dmd.FuncDeclaration;
 import dmd.Identifier;
@@ -12,7 +14,7 @@
 import dmd.TY;
 import dmd.LINK;
 import dmd.Expression;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.STC;
 import dmd.Global;
 import dmd.Module;
@@ -53,6 +55,7 @@
 import dmd.backend.RTLSYM;
 import dmd.backend.block;
 import dmd.backend.LIST;
+import dmd.backend.iasm : binary;
 
 import std.string;
 import core.stdc.string;
@@ -60,10 +63,21 @@
 
 import core.memory;
 
+
+/* If variable var of type typ is a reference
+ */
+version(SARRAYVALUE)
+{
+	bool ISREF(Declaration var, Type tb) {return var.isOut() || var.isRef();}
+}
+else
+	bool ISREF(Declaration var, Type tb) {return (var.isParameter() && tb.ty == TY.Tsarray) || var.isOut() || var.isRef();}
+
+
+
 /************************************
  * Call a function.
  */
-
 elem* callfunc(Loc loc, 
 	IRState* irs,
 	int directcall,		// 1: don't do virtual call
@@ -126,18 +140,16 @@
 		// j=1 if _arguments[] is first argument
 		int j = (tf.linkage == LINK.LINKd && tf.varargs == 1);
 
-		for (i = 0; i < arguments.dim ; i++)
+		foreach (size_t i, Expression arg; arguments)
 		{   
-			Expression arg;
 			elem* ea;
 
-			arg = cast(Expression)arguments.data[i];
-			//printf("\targ[%d]: %s\n", i, arg.toChars());
+			//writef("\targ[%d]: %s\n", i, arg.toChars());
 
-			size_t nparams = Argument.dim(tf.parameters);
+			size_t nparams = Parameter.dim(tf.parameters);
 			if (i - j < nparams && i >= j)
 			{
-				Argument p = Argument.getNth(tf.parameters, i - j);
+				auto p = Parameter.getNth(tf.parameters, i - j);
 
 				if (p.storageClass & (STC.STCout | STC.STCref))
 				{
@@ -150,11 +162,11 @@
 			}
 			ea = arg.toElem(irs);
 		L1:
-			if (tybasic(ea.Ety) == TYM.TYstruct)
+			if (tybasic(ea.Ety) == TYM.TYstruct || tybasic(ea.Ety) == TYarray)
 			{
 				ea = el_una(OPER.OPstrpar, TYM.TYstruct, ea);
 				ea.Enumbytes = ea.E1.Enumbytes;
-				assert(ea.Enumbytes);
+				//assert(ea.Enumbytes);
 			}
 			if (reverse)
 				ep = el_param(ep,ea);
@@ -170,10 +182,12 @@
 			// Don't have one, so create one
 			type* tt;
 
-			if (tf.next.toBasetype().ty == TY.Tstruct)
-				tt = tf.next.toCtype();
+			Type tret2 = tf.next; // in dmd tret is shadowed here, so -> tret2
+			if (tret2.toBasetype().ty == Tstruct ||
+				tret2.toBasetype().ty == Tsarray)
+				tt = tret2.toCtype();
 			else
-				tt = type_fake(tf.next.totym());
+				tt = type_fake(tret2.totym());
 
 			Symbol* stmp = symbol_genauto(tt);
 			ehidden = el_ptr(stmp);
@@ -284,9 +298,15 @@
 			e = el_una(op,tyret,ep);
     }
     else if (ep)
-		e = el_bin(tf.ispure ? OPER.OPcallns : OPER.OPcall, tyret, ec, ep);
+	    /* Do not do "no side effect" calls if a hidden parameter is passed,
+	     * as the return value is stored through the hidden parameter, which
+	     * is a side effect.
+	     */
+		e = el_bin((tf.ispure && tf.isnothrow && (retmethod != RET.RETstack)) ?
+		            OPcallns : OPcall, tyret, ec, ep);
     else
-		e = el_una(tf.ispure ? OPER.OPucallns : OPER.OPucall, tyret, ec);
+		e = el_una((tf.ispure && tf.isnothrow && (retmethod != RET.RETstack)) ?
+		            OPucallns : OPucall, tyret, ec);
 
     if (retmethod == RET.RETstack)
     {
@@ -633,13 +653,123 @@
  * Returns that operator, -1 if not an intrinsic function.
  */
 
-extern (C++) extern int intrinsic_op(char* name);
- 
+//extern (C++) extern int intrinsic_op(char* name);
+
 OPER intrinsic_oper(const(char)* name)
 {
-	int result = intrinsic_op(cast(char*)name);
-	if (result == -1) return OPER.OPMAX;
-	return cast(OPER)result;
+	version(DMDV1)
+	static const(char) *namearray[] =
+	[
+		"4math3cosFeZe",
+		"4math3sinFeZe",
+		"4math4fabsFeZe",
+		"4math4rintFeZe",
+		"4math4sqrtFdZd",
+		"4math4sqrtFeZe",
+		"4math4sqrtFfZf",
+		"4math4yl2xFeeZe",
+		"4math5ldexpFeiZe",
+		"4math6rndtolFeZl",
+		"4math6yl2xp1FeeZe",
+
+		"9intrinsic2btFPkkZi",
+		"9intrinsic3bsfFkZi",
+		"9intrinsic3bsrFkZi",
+		"9intrinsic3btcFPkkZi",
+		"9intrinsic3btrFPkkZi",
+		"9intrinsic3btsFPkkZi",
+		"9intrinsic3inpFkZh",
+		"9intrinsic4inplFkZk",
+		"9intrinsic4inpwFkZt",
+		"9intrinsic4outpFkhZh",
+		"9intrinsic5bswapFkZk",
+		"9intrinsic5outplFkkZk",
+		"9intrinsic5outpwFktZt",
+	];
+else
+	static const(char) *namearray[] =
+	[
+		/* The names are mangled differently because of the pure and
+		 * nothrow attributes.
+		 */
+		"4math3cosFNaNbNfeZe",
+		"4math3sinFNaNbNfeZe",
+		"4math4fabsFNaNbNfeZe",
+		"4math4rintFNaNbNfeZe",
+		"4math4sqrtFNaNbNfdZd",
+		"4math4sqrtFNaNbNfeZe",
+		"4math4sqrtFNaNbNffZf",
+		"4math4yl2xFNaNbNfeeZe",
+		"4math5ldexpFNaNbNfeiZe",
+		"4math6rndtolFNaNbNfeZl",
+		"4math6yl2xp1FNaNbNfeeZe",
+
+		"9intrinsic2btFNaNbxPkkZi",
+		"9intrinsic3bsfFNaNbkZi",
+		"9intrinsic3bsrFNaNbkZi",
+		"9intrinsic3btcFNbPkkZi",
+		"9intrinsic3btrFNbPkkZi",
+		"9intrinsic3btsFNbPkkZi",
+		"9intrinsic3inpFNbkZh",
+		"9intrinsic4inplFNbkZk",
+		"9intrinsic4inpwFNbkZt",
+		"9intrinsic4outpFNbkhZh",
+		"9intrinsic5bswapFNaNbkZk",
+		"9intrinsic5outplFNbkkZk",
+		"9intrinsic5outpwFNbktZt",
+	];
+
+	static const OPER ioptab[] =
+	[
+		OPcos,
+		OPsin,
+		OPabs,
+		OPrint,
+		OPsqrt,
+		OPsqrt,
+		OPsqrt,
+		OPyl2x,
+		OPscale,
+		OPrndtol,
+		OPyl2xp1,
+
+		OPbt,
+		OPbsf,
+		OPbsr,
+		OPbtc,
+		OPbtr,
+		OPbts,
+		OPinp,
+		OPinp,
+		OPinp,
+		OPoutp,
+		OPbswap,
+		OPoutp,
+		OPoutp,
+	];
+
+	debug 
+	{
+		assert(namearray.length == ioptab.length);
+		// assume sorted namearray
+		for (int i = 0; i < namearray.length - 1; i++)
+		{
+			if (strcmp(namearray[i], namearray[i + 1]) >= 0)
+			{
+				printf("namearray[%d] = '%s'\n", i, namearray[i]);
+				assert(0);
+			}
+		}
+	}
+
+	size_t length = strlen(name);
+	if (length < 11 || !(name[7] == 'm' || name[7] == 'i') || name[0..6] != "_D3std")
+		return OPMAX;
+
+	int p = binary(name + 6, namearray.ptr, namearray.length);
+	if(p == -1)
+		return OPMAX;
+	return ioptab[p];
 }
 
 /**************************************
@@ -716,13 +846,13 @@
     {
 		for (size_t i = 0; i < td.objects.dim; i++)
 		{   
-			auto o = cast(Object)td.objects.data[i];
+			auto o = td.objects[i];
 			///if (o.dyncast() == DYNCAST_EXPRESSION)
-			if (Expression eo = cast(Expression)o)
+			if (auto eo = cast(Expression)o)
 			{	
 				if (eo.op == TOK.TOKdsymbol)
 				{   
-					DsymbolExp se = cast(DsymbolExp)eo;
+					auto se = cast(DsymbolExp)eo;
 					e = el_combine(e, Dsymbol_toElem(se.s, irs));
 				}
 			}
@@ -771,13 +901,13 @@
 		{
 			elength = *pe;
 			*pe = el_same(&elength);
-			elength = el_una(OPER.OP64_32, TYM.TYuint, elength);
+			elength = el_una(OP64_32, TYM.TYuint, elength);
 
 		L3:
 			slength = lengthVar.toSymbol();
 			//symbol_add(slength);
 
-			einit = el_bin(OPER.OPeq, TYM.TYuint, el_var(slength), elength);
+			einit = el_bin(OPeq, TYM.TYuint, el_var(slength), elength);
 		}
     }
     return einit;
@@ -792,7 +922,6 @@
  *	edim	number of times to write evalue to eptr[]
  *	tb	type of evalue
  */
-
 elem* setArray(elem* eptr, elem* edim, Type tb, elem* evalue, IRState* irs, int op)
 {   
 	int r;
@@ -852,7 +981,7 @@
 		edim = el_bin(OPER.OPmul, TYM.TYuint, edim, el_long(TYM.TYuint, sz));
     }
 
-    if (tybasic(evalue.Ety) == TYM.TYstruct)
+    if (tybasic(evalue.Ety) == TYM.TYstruct || tybasic(evalue.Ety) == TYarray)
     {
 		evalue = el_una(OPER.OPstrpar, TYM.TYstruct, evalue);
 		evalue.Enumbytes = evalue.E1.Enumbytes;
@@ -987,7 +1116,7 @@
 			break;
 
 		case TY.Tsarray:
-			e = el_una(OPER.OPaddr, TYM.TYnptr, e);
+			e = addressElem(e, t);
 			dim = cast(uint)(cast(TypeSArray)t).dim.toInteger();
 			e = el_pair(TYM.TYullong, el_long(TYM.TYint, dim), e);
 			break;
@@ -1062,12 +1191,13 @@
     return el_combine(ef, e);
 }
 
+/************************************
+ */
 elem* sarray_toDarray(Loc loc, Type tfrom, Type tto, elem* e)
 {
     //printf("sarray_toDarray()\n");
     //elem_print(e);
 
-    elem* elen;
     uint dim = cast(uint)(cast(TypeSArray)tfrom).dim.toInteger();
 
     if (tto)
@@ -1084,8 +1214,8 @@
 	}
 
   L1:
-    elen = el_long(TYM.TYint, dim);
-    e = el_una(OPER.OPaddr, TYM.TYnptr, e);
+    elem* elen = el_long(TYM.TYint, dim);
+    e = addressElem(e, tfrom);
     e = el_pair(TYM.TYullong, elen, e);
     return e;
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmd/codegen/linkhelper.d	Tue Sep 14 15:46:50 2010 +0200
@@ -0,0 +1,32 @@
+module dmd.codegen.linkhelper;
+
+import dmd.Loc;
+import dmd.Util;
+
+import core.stdc.stdarg;
+import std.conv;
+
+// help resolve some linker dependencies from the backend back into the frontend
+
+extern(C++)
+{
+	// msc.c wants to access global from out_config_init(), but it should never be called
+	struct Global {}
+	Global global;
+
+	void error(const char *filename, uint linnum, const char *format, ...)
+	{
+		Loc loc;
+		loc.filename = to!string(filename);
+		loc.linnum = linnum;
+
+		va_list ap;
+		va_start(ap, format);
+		
+		char buf[1024];
+		vsprintf(buf.ptr, format, ap);
+		va_end( ap );
+		
+		dmd.Util.error(loc, to!string(buf));
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmd/common.d	Tue Sep 14 15:46:50 2010 +0200
@@ -0,0 +1,188 @@
+/**
+ * this module is imported in all modules in the dmd package
+ * and thus can be used for commonly used aliases etc.
+ */
+module dmd.common;
+
+// versions specified in a module are local to that module even if the module is imported by another one, see code at the bottom
+// until a solution is found, at least check the given versions for consistency
+
+pragma(msg, "checking predefined versions for consistency...");
+
+version(DMDV1)
+	version(DMDV2)
+		static assert(false, "DMDV1 and DMDV2 can't be set both");
+
+version(DMDV2)
+{
+	version(STRUCTTHISREF) {} else
+		static assert(false, "DMDV2 requires STRUCTTHISREF. 'this' for struct is a reference");
+	version(SNAN_DEFAULT_INIT) {} else
+		static assert(false, "DMDV2 requires SNAN_DEFAULT_INIT. floats are default initialized to signalling NaN");
+	version(SARRAYVALUE) {} else
+		static assert(false, "DMDV2 requires SARRAYVALUE. static arrays are value types");
+}
+
+version(DMDV2)
+	version(Posix) // TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS // TODO:
+		version(CPP_MANGLE) {} else
+			static assert(false, "CPP_MANGLE must be set if DMDV2 and a Posix target is specified. C++ mangling is done by the front end");
+
+version(Win32)
+{
+	version(_WIN32) {} else
+		static assert(false, "Set _WIN32 on Win32");
+	version(TARGET_WINDOS) {} else
+		static assert(false, "TARGET_WINDOS must be specified on Windows");
+	version(OMFOBJ) {} else
+		static assert(false, "OMFOBJ must be used on Windows");
+}
+else version(Win64)
+{
+	static assert(false, "now we need Win64 support");
+}
+
+version(Posix)
+	version(POSIX) {} else
+		static assert(false, "POSIX must be set on Posix");
+
+version(TARGET_LINUX)
+	version(ELFOBJ) {} else
+		static assert(false, "TARGET_LINUX requires ELFOBJ");
+version(TARGET_FREEBSD)
+	version(ELFOBJ) {} else
+		static assert(false, "TARGET_FREEBSD requires ELFOBJ");
+version(TARGET_SOLARIS)
+	version(ELFOBJ) {} else
+		static assert(false, "TARGET_SOLARIS requires ELFOBJ");
+
+version(TARGET_OSX)
+	version(MACHOBJ) {} else
+		static assert(false, "TARGET_OSX requires MACHOBJ");
+
+version(CCASTSYNTAX) {} else
+	static assert(false, `CCASTSYNTAX is needed for code like "(void*).sizeof"`);
+
+version(CARRAYDECL) {} else
+	static assert(false, "C array declarations are used in phobos so we still need CARRAYDECL");
+
+
+version(IN_GCC) // Changes for the GDC compiler by David Friedman
+{
+	static assert(false, "IN_GCC is not supported");
+}
+
+/+
+/*
+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
+	__FreeBSD__	FreeBSD
+	__sun&&__SVR4	Solaris, OpenSolaris (yes, both macros are necessary)
+
+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
+	TARGET_FREEBSD	Covers 32 and 64 bit FreeBSD
+	TARGET_SOLARIS	Covers 32 and 64 bit Solaris
+	TARGET_NET	Covers .Net
+
+    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, FreeBSD and Solaris
+	MACHOBJ		Mach-O Object Module Format, used on Mac OSX
+
+    There are currently no macros for byte endianness order.
+ */
+//version definitions from mars.h
+
+pragma(msg, "setting up versions...");
+
+// default to DMDV2
+version(DMDV1) {} else
+version = DMDV2; // Version 2.0 features
+version = BREAKABI;	// 0 if not ready to break the ABI just yet
+version(DMDV2)
+{
+	version = STRUCTTHISREF;	// if 'this' for struct is a reference, not a pointer
+	version = SNAN_DEFAULT_INIT;// if floats are default initialized to signalling NaN
+	version = SARRAYVALUE;		// static arrays are value types
+}
+
+// Set if C++ mangling is done by the front end
+version(DMDV2)
+{
+	version(Posix) // TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS
+		version = CPP_MANGLE;
+}
+
+/* Other targets are TARGET_LINUX, TARGET_OSX, TARGET_FREEBSD and
+ * TARGET_SOLARIS, which are
+ * set on the command line via the compiler makefile.
+ */
+
+version(Win32)
+{
+	version = _WIN32;
+	version = TARGET_WINDOS;		// Windows dmd generates Windows targets
+	version = OMFOBJ;
+}
+else version(Win64)
+{
+	static assert(false, "now we need Win64 support");
+}
+
+version(Posix)
+	version = POSIX;
+
+version(TARGET_LINUX)
+	version = ELFOBJ;
+version(TARGET_FREEBSD)
+	version = ELFOBJ;
+version(TARGET_SOLARIS)
+	version = ELFOBJ;
+
+
+version(TARGET_OSX)
+	version = MACHOBJ;
+
+/* TODO:
+//Modify OutBuffer::writewchar to write the correct size of wchar
+#if _WIN32
+#define writewchar writeword
+#else
+//This needs a configuration test...
+#define writewchar write4
+#endif
+
+#define INTERFACE_OFFSET	0	// if 1, put classinfo as first entry
+//in interface vtbl[]'s
+#define INTERFACE_VIRTUAL	0	// 1 means if an interface appears
+//in the inheritance graph multiple
+//times, only one is used
+*/
++/
\ No newline at end of file
--- a/dmd/condition/util/findCondition.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/condition/util/findCondition.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,18 +1,19 @@
 module dmd.condition.util.findCondition;
 
+import dmd.common;
 import dmd.String;
 import dmd.Array;
 import dmd.Identifier;
 
-bool findCondition(Array ids, Identifier ident)
+bool findCondition(Vector!string ids, Identifier ident)
 {
     if (ids)
     {
 		for (int i = 0; i < ids.dim; i++)
 		{
-			String id = cast(String)ids.data[i];
+			string id = ids[i];
 
-			if (id.str == ident.toChars()) {
+			if (id == ident.toChars()) {
 				return true;
 			}
 		}
--- a/dmd/ddoc/Sections.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/ddoc/Sections.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.ddoc.Sections;
 
+import dmd.common;
 import dmd.ddoc.DocComment;
 import dmd.Array;
 import dmd.Scope;
@@ -12,10 +13,10 @@
 //!
 class Section
 {
-	string name;
-	string body_;
+    string name;
+    string body_;
 
-	int nooutput;
+    int nooutput;
 
 	void write(DocComment dc, Scope sc, Dsymbol s, OutBuffer buf)
 	{
@@ -26,7 +27,7 @@
 					"DEPRECATED", "EXAMPLES", "HISTORY", "LICENSE",
 					"RETURNS", "SEE_ALSO", "STANDARDS", "THROWS",
 					"VERSION" };
-
+     
 			for (int i = 0; i < table.length; i++)
 			{
 				if (icmp(table[i], name, namelen) == 0)
--- a/dmd/declaration/Match.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/declaration/Match.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,14 +1,15 @@
 module dmd.declaration.Match;
 
+import dmd.common;
 import dmd.FuncDeclaration;
 import dmd.MATCH;
 
-struct Match
-{
+struct Match
+{
 	int count;			// number of matches found
     MATCH last;			// match level of lastf
     FuncDeclaration lastf;	// last matching function we found
     FuncDeclaration nextf;	// current matching function
-    FuncDeclaration anyf;	// pick a func, any func, to use for error recovery
-}
-
+    FuncDeclaration anyf;	// pick a func, any func, to use for error recovery
+}
+
--- a/dmd/expression/Add.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/expression/Add.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.expression.Add;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Type;
 import dmd.Loc;
--- a/dmd/expression/And.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/expression/And.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.expression.And;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Type;
 import dmd.IntegerExp;
--- a/dmd/expression/ArrayLength.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/expression/ArrayLength.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.expression.ArrayLength;
 
+import dmd.common;
 import dmd.Type;
 import dmd.Expression;
 import dmd.StringExp;
@@ -9,6 +10,17 @@
 import dmd.TOK;
 import dmd.AssocArrayLiteralExp;
 import dmd.GlobalExpressions;
+import dmd.XorExp;
+import dmd.UshrExp;
+import dmd.ShrExp;
+import dmd.ShlExp;
+import dmd.OrExp;
+import dmd.MulExp;
+import dmd.ModExp;
+import dmd.MinExp;
+import dmd.AddExp;
+import dmd.DivExp;
+import dmd.AndExp;
 
 Expression ArrayLength(Type type, Expression e1)
 {
@@ -36,4 +48,26 @@
 		e = EXP_CANT_INTERPRET;
 
     return e;
+}
+
+Expression opAssignToOp(Loc loc, TOK op, Expression e1, Expression e2)
+{   
+	Expression e;
+
+    switch (op)
+    {
+		case TOK.TOKaddass:   e = new AddExp(loc, e1, e2);	break;
+		case TOK.TOKminass:   e = new MinExp(loc, e1, e2);	break;
+		case TOK.TOKmulass:   e = new MulExp(loc, e1, e2);	break;
+		case TOK.TOKdivass:   e = new DivExp(loc, e1, e2);	break;
+		case TOK.TOKmodass:   e = new ModExp(loc, e1, e2);	break;
+		case TOK.TOKandass:   e = new AndExp(loc, e1, e2);	break;
+		case TOK.TOKorass:    e = new OrExp (loc, e1, e2);	break;
+		case TOK.TOKxorass:   e = new XorExp(loc, e1, e2);	break;
+		case TOK.TOKshlass:   e = new ShlExp(loc, e1, e2);	break;
+		case TOK.TOKshrass:   e = new ShrExp(loc, e1, e2);	break;
+		case TOK.TOKushrass:  e = new UshrExp(loc, e1, e2);	break;
+		default:	assert(0);
+    }
+    return e;
 }
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmd/expression/Bool.d	Tue Sep 14 15:46:50 2010 +0200
@@ -0,0 +1,11 @@
+module dmd.expression.Bool;
+
+import dmd.IntegerExp;
+import dmd.Loc;
+import dmd.Type;
+import dmd.Expression;
+
+Expression Bool(Type type, Expression e1)
+{
+	return new IntegerExp(e1.loc, e1.isBool(1), type);
+}
\ No newline at end of file
--- a/dmd/expression/Cat.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/expression/Cat.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.expression.Cat;
 
+import dmd.common;
 import dmd.Type;
 import dmd.Expression;
 import dmd.Loc;
--- a/dmd/expression/Cmp.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/expression/Cmp.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.expression.Cmp;
 
+import dmd.common;
 import dmd.IntegerExp;
 import dmd.Loc;
 import dmd.TOK;
--- a/dmd/expression/Com.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/expression/Com.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.expression.Com;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Type;
 import dmd.IntegerExp;
--- a/dmd/expression/Div.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/expression/Div.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.expression.Div;
 
+import dmd.common;
 import dmd.Type;
 import dmd.Expression;
 import dmd.Loc;
--- a/dmd/expression/Equal.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/expression/Equal.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.expression.Equal;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Type;
 import dmd.TOK;
--- a/dmd/expression/Identity.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/expression/Identity.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.expression.Identity;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Type;
 import dmd.TOK;
--- a/dmd/expression/Index.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/expression/Index.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.expression.Index;
 
+import dmd.common;
 import dmd.Type;
 import dmd.Loc;
 import dmd.StringExp;
--- a/dmd/expression/Min.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/expression/Min.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.expression.Min;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Type;
 import dmd.Loc;
--- a/dmd/expression/Mod.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/expression/Mod.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.expression.Mod;
 
+import dmd.common;
 import dmd.Loc;
 import dmd.Type;
 import dmd.Expression;
--- a/dmd/expression/Mul.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/expression/Mul.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.expression.Mul;
 
+import dmd.common;
 import dmd.Type;
 import dmd.Expression;
 import dmd.RealExp;
@@ -32,7 +33,7 @@
 		}
 		else if (e2.type.isreal())
 		{
-			r = e2.toReal();
+			r = e2.toReal();
 			c = e1.toComplex();
 			c = Complex!(real)(r * c.re, r * c.im);
 		}
--- a/dmd/expression/Neg.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/expression/Neg.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.expression.Neg;
 
+import dmd.common;
 import dmd.Type;
 import dmd.Loc;
 import dmd.RealExp;
--- a/dmd/expression/Not.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/expression/Not.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.expression.Not;
 
+import dmd.common;
 import dmd.Type;
 import dmd.Expression;
 import dmd.IntegerExp;
--- a/dmd/expression/Or.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/expression/Or.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.expression.Or;
 
+import dmd.common;
 import dmd.Type;
 import dmd.Expression;
 import dmd.IntegerExp;
--- a/dmd/expression/Ptr.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/expression/Ptr.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.expression.Ptr;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Type;
 import dmd.TOK;
--- a/dmd/expression/Shl.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/expression/Shl.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.expression.Shl;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Type;
 import dmd.IntegerExp;
--- a/dmd/expression/Shr.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/expression/Shr.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.expression.Shr;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Type;
 import dmd.Loc;
--- a/dmd/expression/Slice.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/expression/Slice.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.expression.Slice;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Type;
 import dmd.Loc;
--- a/dmd/expression/Ushr.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/expression/Ushr.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.expression.Ushr;
 
+import dmd.common;
 import dmd.Type;
 import dmd.Expression;
 import dmd.Loc;
--- a/dmd/expression/Util.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/expression/Util.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.expression.Util;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.Loc;
 import dmd.RealExp;
@@ -23,7 +24,8 @@
 import dmd.IndexExp;
 import dmd.AssignExp;
 import dmd.CommaExp;
-import dmd.Argument;
+import dmd.CondExp;
+import dmd.Parameter;
 import dmd.DefaultInitExp;
 import dmd.Identifier;
 import dmd.Dsymbol;
@@ -62,9 +64,13 @@
 import dmd.Util;
 import dmd.TypeAArray;
 import dmd.Id;
+import dmd.PtrExp;
+import dmd.ErrorExp;
 
 import std.stdio : writef;
 
+import core.stdc.math;
+import core.stdc.string;
 
 /***********************************
  * Utility to build a function call out of this reference and argument.
@@ -184,17 +190,30 @@
 struct Param2
 {
     Match* m;
+version(DMDV2) {
     Expression ethis;
+    int property;	// 0: unintialized
+			// 1: seen @property
+			// 2: not @property
+}
     Expressions arguments;
 	
-	int fp2(void*, FuncDeclaration f)
-	{   
+	int fp2(void* param, FuncDeclaration f)
+	{
+        auto p = cast(Param2*)param;
 		MATCH match;
 
 		if (f != m.lastf)		// skip duplicates
 		{
 			m.anyf = f;
 			TypeFunction tf = cast(TypeFunction)f.type;
+
+	        int property = (tf.isproperty) ? 1 : 2;
+	        if (p.property == 0)
+	            p.property = property;
+	        else if (p.property != property)
+	            error(f.loc, "cannot overload both property and non-property functions");
+
 			match = tf.callMatch(f.needThis() ? ethis : null, arguments);
 			//printf("test: match = %d\n", match);
 			if (match != MATCH.MATCHnomatch)
@@ -212,6 +231,7 @@
 				else if (f.overrides(m.lastf))
 					goto LfIsBetter;
 
+version(DMDV2) {
 				/* Try to disambiguate using template-style partial ordering rules.
 				 * In essence, if f() and g() are ambiguous, if f() can call g(),
 				 * but g() cannot call f(), then pick f().
@@ -226,6 +246,7 @@
 					if (c1 < c2)
 						goto LlastIsBetter;
 				}
+}
 
 			Lambiguous:
 				m.nextf = f;
@@ -260,9 +281,10 @@
 		}
 
 	version (DMDV2) {
-		/* Allow covariant matches, if it's just a const conversion
-		 * of the return type
-		 */
+        /* Allow covariant matches, as long as the return type
+         * is just a const conversion.
+         * This allows things like pure functions to match with an impure function type.
+         */
 		if (t.ty == Tfunction)
 		{   
 			TypeFunction tf = cast(TypeFunction)f.type;
@@ -283,6 +305,7 @@
     Param2 p;
     p.m = m;
     p.ethis = ethis;
+    p.property = 0;
     p.arguments = arguments;
     overloadApply(fstart, &p.fp2, &p);
 }
@@ -324,11 +347,108 @@
     }
 }
 
+Expressions arrayExpressionToCommonType(Scope sc, Expressions exps, Type *pt)
+{
+//version(DMDV1) {
+//    /* The first element sets the type
+//     */
+//    Type *t0 = NULL;
+//    for (size_t i = 0; i < exps->dim; i++)
+//    {	Expression *e = (Expression *)exps->data[i];
+//
+//	if (!e->type)
+//	{   error("%s has no value", e->toChars());
+//	    e = new ErrorExp();
+//	}
+//	e = resolveProperties(sc, e);
+//
+//	if (!t0)
+//	    t0 = e->type;
+//	else
+//	    e = e->implicitCastTo(sc, t0);
+//	exps->data[i] = (void *)e;
+//    }
+//
+//    if (!t0)
+//	t0 = Type::tvoid;
+//    if (pt)
+//	*pt = t0;
+//
+//    // Eventually, we want to make this copy-on-write
+//    return exps;
+//}
+version(DMDV2) {
+    /* The type is determined by applying ?: to each pair.
+     */
+    /* Still have a problem with:
+     *	ubyte[][] = [ cast(ubyte[])"hello", [1]];
+     * which works if the array literal is initialized top down with the ubyte[][]
+     * type, but fails with this function doing bottom up typing.
+     */
+    //printf("arrayExpressionToCommonType()\n");
+    scope integerexp = new IntegerExp(0);
+    scope condexp = new CondExp(Loc(0), integerexp, null, null);
+
+    Type t0;
+    Expression e0;
+    int j0;
+    foreach (size_t i, Expression e; exps)
+    {
+		e = resolveProperties(sc, e);
+		if (!e.type)
+		{   error("%s has no value", e.toChars());
+		    e = new ErrorExp();
+		}
+
+		if (t0)
+		{ 
+			if (t0 != e.type)
+		    {
+				/* This applies ?: to merge the types. It's backwards;
+				* ?: should call this function to merge types.
+				*/
+				condexp.type = null;
+				condexp.e1 = e0;
+				condexp.e2 = e;
+				condexp.semantic(sc);
+				exps[j0] = condexp.e1;
+				e = condexp.e2;
+				j0 = i;
+				e0 = e;
+				t0 = e0.type;
+			}
+		}
+		else
+		{
+			j0 = i;
+			e0 = e;
+			t0 = e.type;
+		}
+		exps[i] = e;
+    }
+
+    if (t0)
+    {
+		foreach (ref Expression e; exps)
+		{
+			e = e.implicitCastTo(sc, t0);
+		}
+    }
+    else
+		t0 = Type.tvoid;		// [] is typed as void[]
+    if (pt)
+		*pt = t0;
+
+    // Eventually, we want to make this copy-on-write
+    return exps;
+}
+}
+
 /****************************************
  * Preprocess arguments to function.
  */
 
-void preFunctionArguments(Loc loc, Scope sc, Expressions exps)
+void preFunctionParameters(Loc loc, Scope sc, Expressions exps)
 {
     if (exps)
     {
@@ -474,22 +594,24 @@
  *	3. do default promotions on arguments corresponding to ...
  *	4. add hidden _arguments[] argument
  *	5. call copy constructor for struct value arguments
+ * Returns:
+ *	return type from function
  */
 
-void functionArguments(Loc loc, Scope sc, TypeFunction tf, Expressions arguments)
+Type functionParameters(Loc loc, Scope sc, TypeFunction tf, Expressions arguments)
 {
-	uint n;
-
-    //printf("functionArguments()\n");
+    //printf("functionParameters()\n");
     assert(arguments);
     size_t nargs = arguments ? arguments.dim : 0;
-    size_t nparams = Argument.dim(tf.parameters);
+    size_t nparams = Parameter.dim(tf.parameters);
 
     if (nargs > nparams && tf.varargs == 0)
 	error(loc, "expected %zu arguments, not %zu for non-variadic function type %s", nparams, nargs, tf.toChars());
 
-    n = (nargs > nparams) ? nargs : nparams;	// n = max(nargs, nparams)
+    uint n = (nargs > nparams) ? nargs : nparams;	// n = max(nargs, nparams)
 
+    uint wildmatch = 0;
+    
     int done = 0;
     for (size_t i = 0; i < n; i++)
     {
@@ -504,7 +626,7 @@
 
 		if (i < nparams)
 		{
-			auto p = Argument.getNth(tf.parameters, i);
+			auto p = Parameter.getNth(tf.parameters, i);
 
 			if (!arg)
 			{
@@ -514,21 +636,13 @@
 						goto L2;
 
 					error(loc, "expected %d function arguments, not %d", nparams, nargs);
-					break;
+					return tf.next;
 				}
 				arg = p.defaultArg;
-version (DMDV2) {
-				if (arg.op == TOK.TOKdefault)
-				{   
-					DefaultInitExp de = cast(DefaultInitExp)arg;
-					arg = de.resolve(loc, sc);
-				}
-				else
-				{
-					arg = arg.copy();
-				}
-} else {
 				arg = arg.copy();
+version (DMDV2)
+{
+				arg = arg.resolveLoc(loc, sc);		// __FILE__ and __LINE__
 }
 				arguments.push(arg);
 				nargs++;
@@ -540,7 +654,10 @@
 				if (arg.implicitConvTo(p.type))
 				{
 					if (nargs != nparams)
+					{
 						error(loc, "expected %zu function arguments, not %zu", nparams, nargs);
+						return tf.next;
+					}
 					goto L1;
 				}
 				 L2:
@@ -565,6 +682,7 @@
 						Type t = new TypeSArray((cast(TypeArray)tb).next, new IntegerExp(nargs - i));
 						t = t.semantic(loc, sc);
 						VarDeclaration v = new VarDeclaration(loc, t, id, new VoidInitializer(loc));
+			            v.storage_class |= STCctfe;
 						v.semantic(sc);
 						v.parent = sc.parent;
 						//sc.insert(v);
@@ -614,7 +732,7 @@
 						if (!arg)
 						{   
 							error(loc, "not enough arguments");
-							return;
+							return tf.next;
 						}
 						break;
 				}
@@ -631,7 +749,27 @@
 				if (p.type != arg.type)
 				{
 					//printf("arg.type = %s, p.type = %s\n", arg.type.toChars(), p.type.toChars());
-					arg = arg.implicitCastTo(sc, p.type);
+					if (arg.op == TOKtype)
+						arg.error("cannot pass type %s as function argument", arg.toChars());
+		            if (p.type.isWild() && tf.next.isWild())
+		            {	
+                        Type t = p.type;
+			            MATCH m = arg.implicitConvTo(t);
+			            if (m == MATCH.MATCHnomatch)
+			            {
+                            t = t.constOf();
+			                m = arg.implicitConvTo(t);
+			                if (m == MATCHnomatch)
+			                {
+                                t = t.sharedConstOf();
+				                m = arg.implicitConvTo(t);
+			                }
+			                wildmatch |= p.type.wildMatch(arg.type);
+			            }
+			            arg = arg.implicitCastTo(sc, t);
+		            }
+		            else
+    					arg = arg.implicitCastTo(sc, p.type);
 					arg = arg.optimize(WANT.WANTvalue);
 				}
 			}
@@ -644,12 +782,15 @@
 				arg = arg.modifiableLvalue(sc, arg);
 			}
 
+			tb = arg.type.toBasetype();
+version(SARRAYVALUE) {} else
+{
 			// Convert static arrays to pointers
-			tb = arg.type.toBasetype();
 			if (tb.ty == TY.Tsarray)
 			{
 				arg = arg.checkToPointer();
 			}
+}
 version (DMDV2) {
 			if (tb.ty == TY.Tstruct && !(p.storageClass & (STC.STCref | STC.STCout)))
 			{
@@ -728,14 +869,9 @@
 				TypeSArray ts = cast(TypeSArray)tb;
 				Type ta = ts.next.arrayOf();
 				if (ts.size(arg.loc) == 0)
-				{   
-					arg = new NullExp(arg.loc);
-					arg.type = ta;
-				}
+					arg = new NullExp(arg.loc, ta);
 				else
-				{
 					arg = arg.castTo(sc, ta);
-				}
 			}
 version (DMDV2) {
 			if (tb.ty == Tstruct)
@@ -769,9 +905,28 @@
     // If D linkage and variadic, add _arguments[] as first argument
     if (tf.linkage == LINK.LINKd && tf.varargs == 1)
     {
+		assert(arguments.dim >= nparams);
 		auto e = createTypeInfoArray(sc, &arguments[nparams], arguments.dim - nparams);
 		arguments.insert(0, e);
     }
+    
+    Type tret = tf.next;
+    if (wildmatch)
+    {	/* Adjust function return type based on wildmatch
+	 */
+	    //printf("wildmatch = x%x\n", wildmatch);
+	    assert(tret.isWild());
+	    if (wildmatch & MOD.MODconst || wildmatch & (wildmatch - 1))
+	        tret = tret.constOf();
+	    else if (wildmatch & MOD.MODimmutable)
+	        tret = tret.invariantOf();
+	    else
+	    {
+            assert(wildmatch & MOD.MODmutable);
+	        tret = tret.mutableOf();
+	    }
+    }
+    return tret;
 }
 
 /******************************
@@ -945,12 +1100,12 @@
 
 	/* Create the TypeTuple corresponding to the types of args[]
 	 */
-	Arguments args = new Arguments;
+	auto args = new Parameters;
 	args.setDim(dim);
 	for (size_t i = 0; i < dim; i++)
 	{	
-		Argument arg = new Argument(STCin, exps[i].type, null, null);
-		args.data[i] = cast(void*)arg;
+		auto arg = new Parameter(STCin, exps[i].type, null, null);
+		args[i] = arg;
 	}
 	TypeTuple tup = new TypeTuple(args);
 	Expression e = tup.getTypeInfo(sc);
@@ -1135,7 +1290,7 @@
     if (!v)
 		return e;
 
-    if (v.isConst() || v.isInvariant() || v.storage_class & STC.STCmanifest)
+    if (v.isConst() || v.isImmutable() || v.storage_class & STC.STCmanifest)
     {
 		if (!v.type)
 		{
@@ -1265,7 +1420,7 @@
  * them from the aggregate type.
  */
 
-void inferApplyArgTypes(TOK op, Arguments arguments, Expression aggr)
+void inferApplyArgTypes(TOK op, Parameters arguments, Expression aggr)
 {
     if (!arguments || !arguments.dim)
 		return;
@@ -1277,14 +1432,15 @@
 		if (u == arguments.dim)
 			return;
 
-		Argument arg = cast(Argument)arguments.data[u];
+		auto arg = arguments[u];
 		if (!arg.type)
 			break;
     }
 
+    Dsymbol s;
     AggregateDeclaration ad;
 
-    Argument arg = cast(Argument)arguments.data[0];
+    auto arg = arguments[0];
     Type taggr = aggr.type;
     if (!taggr)
 		return;
@@ -1298,7 +1454,7 @@
 			{
 				if (!arg.type)
 					arg.type = Type.tsize_t;	// key type
-				arg = cast(Argument)arguments.data[1];
+				arg = arguments[1];
 			}
 			if (!arg.type && tab.ty != TY.Ttuple)
 				arg.type = tab.nextOf();	// value type
@@ -1306,13 +1462,13 @@
 
 		case TY.Taarray:
 		{   
-			TypeAArray taa = cast(TypeAArray)tab;
+			auto taa = cast(TypeAArray)tab;
 
 			if (arguments.dim == 2)
 			{
 				if (!arg.type)
 					arg.type = taa.index;	// key type
-				arg = cast(Argument)arguments.data[1];
+				arg = arguments[1];
 			}
 			if (!arg.type)
 				arg.type = taa.next;		// value type
@@ -1328,6 +1484,10 @@
 			goto Laggr;
 
 		Laggr:
+	        s = search_function(ad, (op == TOKforeach_reverse) ? Id.applyReverse : Id.apply);
+	        if (s)
+		        goto Lapply;			// prefer opApply
+
 			if (arguments.dim == 1)
 			{
 				if (!arg.type)
@@ -1335,11 +1495,11 @@
 					/* Look for a head() or rear() overload
 					 */
 					Identifier id = (op == TOK.TOKforeach) ? Id.Fhead : Id.Ftoe;
-					Dsymbol s = search_function(ad, id);
-					FuncDeclaration fd = s ? s.isFuncDeclaration() : null;
+					Dsymbol s1 = search_function(ad, id);
+					FuncDeclaration fd = s1 ? s1.isFuncDeclaration() : null;
 					if (!fd)
 					{	
-						if (s && s.isTemplateDeclaration())
+						if (s1 && s1.isTemplateDeclaration())
 							break;
 						goto Lapply;
 					}
@@ -1353,7 +1513,6 @@
 			 *	int opApply(int delegate(ref Type [, ...]) dg);
 			 * overload
 			 */
-			Dsymbol s = search_function(ad, (op == TOK.TOKforeach_reverse) ? Id.applyReverse : Id.apply);
 			if (s)
 			{
 				FuncDeclaration fd = s.isFuncDeclaration();
@@ -1405,7 +1564,7 @@
 
 	int fp3(void*, FuncDeclaration f)
 	{
-		TypeFunction tf = cast(TypeFunction)f.type;
+		auto tf = cast(TypeFunction)f.type;
 		if (inferApplyArgTypesY(tf, arguments) == 1)
 			return 0;
 
@@ -1415,10 +1574,10 @@
 		return 0;
 	}
 	
-	Arguments arguments;
+	Parameters arguments;
 }
 
-void inferApplyArgTypesX(FuncDeclaration fstart, Arguments arguments)
+void inferApplyArgTypesX(FuncDeclaration fstart, Parameters arguments)
 {
 	Param3 p3;
 	p3.arguments = arguments;
@@ -1432,15 +1591,15 @@
  *	1 no match for this function
  */
 
-int inferApplyArgTypesY(TypeFunction tf, Arguments arguments)
+int inferApplyArgTypesY(TypeFunction tf, Parameters arguments)
 {   
 	size_t nparams;
-    Argument p;
+    Parameter p;
 
-    if (Argument.dim(tf.parameters) != 1)
+    if (Parameter.dim(tf.parameters) != 1)
 		goto Lnomatch;
 
-    p = Argument.getNth(tf.parameters, 0);
+    p = Parameter.getNth(tf.parameters, 0);
     if (p.type.ty != TY.Tdelegate)
 		goto Lnomatch;
 
@@ -1450,7 +1609,7 @@
     /* We now have tf, the type of the delegate. Match it against
      * the arguments, filling in missing argument types.
      */
-    nparams = Argument.dim(tf.parameters);
+    nparams = Parameter.dim(tf.parameters);
     if (nparams == 0 || tf.varargs)
 		goto Lnomatch;		// not enough parameters
     if (arguments.dim != nparams)
@@ -1458,8 +1617,8 @@
 
     for (size_t u = 0; u < nparams; u++)
     {
-		Argument arg = cast(Argument)arguments.data[u];
-		Argument param = Argument.getNth(tf.parameters, u);
+		auto arg = arguments[u];
+		auto param = Parameter.getNth(tf.parameters, u);
 		if (arg.type)
 		{   
 			if (!arg.type.equals(param.type))
@@ -1551,4 +1710,64 @@
 			}
 		}
     }
-}
\ No newline at end of file
+}
+
+void realToMangleBuffer(OutBuffer buf, real value)
+{
+    /* Rely on %A to get portable mangling.
+     * Must munge result to get only identifier characters.
+     *
+     * Possible values from %A	=> mangled result
+     * NAN			=> NAN
+     * -INF			=> NINF
+     * INF			=> INF
+     * -0X1.1BC18BA997B95P+79	=> N11BC18BA997B95P79
+     * 0X1.9P+2			=> 19P2
+     */
+
+    if (isnan(value))
+		buf.writestring("NAN");	// no -NAN bugs
+    else
+    {
+		char buffer[32];
+		int n = sprintf(buffer.ptr, "%LA", value);
+		assert(n > 0 && n < buffer.sizeof);
+		for (int i = 0; i < n; i++)
+		{   char c = buffer[i];
+
+			switch (c)
+			{
+			case '-':
+				buf.writeByte('N');
+				break;
+
+			case '+':
+			case 'X':
+			case '.':
+				break;
+
+			case '0':
+				if (i < 2)
+				break;		// skip leading 0X
+			default:
+				buf.writeByte(c);
+				break;
+			}
+		}
+    }
+}
+
+/********************************
+ * Test to see if two reals are the same.
+ * Regard NaN's as equivalent.
+ * Regard +0 and -0 as different.
+ */
+
+int RealEquals(real x1, real x2)
+{
+    return (isnan(x1) && isnan(x2)) || 
+		/* In some cases, the REALPAD bytes get garbage in them,
+		 * so be sure and ignore them.
+		 */
+		memcmp(&x1, &x2, REALSIZE - REALPAD) == 0;
+}
--- a/dmd/expression/Xor.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/expression/Xor.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.expression.Xor;
 
+import dmd.common;
 import dmd.Type;
 import dmd.Expression;
 import dmd.IntegerExp;
--- a/dmd/expression/shift_optimize.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/expression/shift_optimize.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.expression.shift_optimize;
 
+import dmd.common;
 import dmd.Expression;
 import dmd.BinExp;
 import dmd.Type;
--- a/dmd/expression/util/arrayTypeCompatible.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/expression/util/arrayTypeCompatible.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.expression.util.arrayTypeCompatible;
 
+import dmd.common;
 import dmd.Loc;
 import dmd.Type;
 import dmd.TY;
--- a/dmd/interpret/Util.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/interpret/Util.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,7 +1,9 @@
 module dmd.interpret.Util;
 
+import dmd.common;
 import dmd.StructDeclaration;
 import dmd.Expression;
+import dmd.FuncDeclaration;
 import dmd.InterState;
 import dmd.ArrayTypes;
 import dmd.GlobalExpressions;
@@ -13,76 +15,132 @@
 import dmd.Loc;
 import dmd.ArrayLiteralExp;
 import dmd.TypeAArray;
+import dmd.TypeFunction;
 import dmd.TypeSArray;
+import dmd.TY;
 import dmd.STC;
 import dmd.SymbolDeclaration;
 import dmd.StructLiteralExp;
 import dmd.VarDeclaration;
 import dmd.Util;
 
+version(DMDV1)
+{
 Expression interpret_aaLen(InterState istate, Expressions arguments)
 {
-    if (!arguments || arguments.dim != 1)
+	if (!arguments || arguments.dim != 1)
 		return null;
-    auto earg = arguments[0];
-    earg = earg.interpret(istate);
-    if (earg is EXP_CANT_INTERPRET)
+	auto earg = arguments[0];
+	earg = earg.interpret(istate);
+	if (earg is EXP_CANT_INTERPRET)
 		return null;
-    if (earg.op != TOKassocarrayliteral)
+	if (earg.op != TOKassocarrayliteral)
 		return null;
-    auto aae = cast(AssocArrayLiteralExp)earg;
-    auto e = new IntegerExp(aae.loc, aae.keys.dim, Type.tsize_t);
-    return e;
+	auto aae = cast(AssocArrayLiteralExp)earg;
+	auto e = new IntegerExp(aae.loc, aae.keys.dim, Type.tsize_t);
+	return e;
 }
 
 Expression interpret_aaKeys(InterState istate, Expressions arguments)
 {
 version (LOG) {
-    printf("interpret_aaKeys()\n");
+	writef("interpret_aaKeys()\n");
 }
-    if (!arguments || arguments.dim != 2)
+	if (!arguments || arguments.dim != 2)
 		return null;
-    auto earg = arguments[0];
-    earg = earg.interpret(istate);
-    if (earg is EXP_CANT_INTERPRET)
+	auto earg = arguments[0];
+	earg = earg.interpret(istate);
+	if (earg is EXP_CANT_INTERPRET)
 		return null;
-    if (earg.op != TOKassocarrayliteral)
+	if (earg.op != TOKassocarrayliteral)
 		return null;
-    auto aae = cast(AssocArrayLiteralExp)earg;
-    auto e = new ArrayLiteralExp(aae.loc, aae.keys);
-    Type elemType = (cast(TypeAArray)aae.type).index;
-    e.type = new TypeSArray(elemType, new IntegerExp(arguments ? arguments.dim : 0));
-    return e;
+	auto aae = cast(AssocArrayLiteralExp)earg;
+	auto e = new ArrayLiteralExp(aae.loc, aae.keys);
+	Type elemType = (cast(TypeAArray)aae.type).index;
+	e.type = new TypeSArray(elemType, new IntegerExp(arguments ? arguments.dim : 0));
+	return e;
 }
 
 Expression interpret_aaValues(InterState istate, Expressions arguments)
 {
-    //printf("interpret_aaValues()\n");
-    if (!arguments || arguments.dim != 3)
+	//writef("interpret_aaValues()\n");
+	if (!arguments || arguments.dim != 3)
+		return null;
+	auto earg = arguments[0];
+	earg = earg.interpret(istate);
+	if (earg is EXP_CANT_INTERPRET)
+		return null;
+	if (earg.op != TOKassocarrayliteral)
 		return null;
-    auto earg = arguments[0];
-    earg = earg.interpret(istate);
-    if (earg is EXP_CANT_INTERPRET)
+	auto aae = cast(AssocArrayLiteralExp)earg;
+	auto e = new ArrayLiteralExp(aae.loc, aae.values);
+	Type elemType = (cast(TypeAArray)aae.type).next;
+	e.type = new TypeSArray(elemType, new IntegerExp(arguments ? arguments.dim : 0));
+	//writef("result is %s\n", e.toChars());
+	return e;
+}
+}
+else version(DMDV2)
+{
+Expression interpret_length(InterState istate, Expression earg)
+{
+//	writef("interpret_length()\n");
+	earg = earg.interpret(istate);
+	if (earg == EXP_CANT_INTERPRET)
+		return null;
+	if (earg.op != TOKassocarrayliteral)
 		return null;
-    if (earg.op != TOKassocarrayliteral)
+	AssocArrayLiteralExp aae = cast(AssocArrayLiteralExp)earg;
+	Expression e = new IntegerExp(aae.loc, aae.keys.dim, Type.tsize_t);
+	return e;
+}
+
+Expression interpret_keys(InterState istate, Expression earg, FuncDeclaration fd)
+{
+version(LOG)
+	writef("interpret_keys()\n");
+
+	earg = earg.interpret(istate);
+	if (earg == EXP_CANT_INTERPRET)
+	return null;
+	if (earg.op != TOKassocarrayliteral)
+	return null;
+	AssocArrayLiteralExp aae = cast(AssocArrayLiteralExp)earg;
+	Expression e = new ArrayLiteralExp(aae.loc, aae.keys);
+	assert(fd.type.ty == Tfunction);
+	assert(fd.type.nextOf().ty == Tarray);
+	Type elemType = (cast(TypeFunction)fd.type).nextOf().nextOf();
+	e.type = new TypeSArray(elemType, new IntegerExp(aae.keys.dim));
+	return e;
+}
+Expression interpret_values(InterState istate, Expression earg, FuncDeclaration fd)
+{
+	//writef("interpret_values()\n");
+	earg = earg.interpret(istate);
+	if (earg == EXP_CANT_INTERPRET)
 		return null;
-    auto aae = cast(AssocArrayLiteralExp)earg;
-    auto e = new ArrayLiteralExp(aae.loc, aae.values);
-    Type elemType = (cast(TypeAArray)aae.type).next;
-    e.type = new TypeSArray(elemType, new IntegerExp(arguments ? arguments.dim : 0));
-    //printf("result is %s\n", e.toChars());
-    return e;
+	if (earg.op != TOKassocarrayliteral)
+		return null;
+	AssocArrayLiteralExp aae = cast(AssocArrayLiteralExp)earg;
+	Expression e = new ArrayLiteralExp(aae.loc, aae.values);
+	assert(fd.type.ty == Tfunction);
+	assert(fd.type.nextOf().ty == Tarray);
+	Type elemType = (cast(TypeFunction)fd.type).nextOf().nextOf();
+	e.type = new TypeSArray(elemType, new IntegerExp(aae.values.dim));
+	//writef("result is %s\n", e.toChars());
+	return e;
+}
 }
 
 Expression getVarExp(Loc loc, InterState istate, Declaration d)
 {
-    Expression e = EXP_CANT_INTERPRET;
-    VarDeclaration v = d.isVarDeclaration();
-    SymbolDeclaration s = d.isSymbolDeclaration();
-    if (v)
-    {
+	Expression e = EXP_CANT_INTERPRET;
+	VarDeclaration v = d.isVarDeclaration();
+	SymbolDeclaration s = d.isSymbolDeclaration();
+	if (v)
+	{
 ///version (DMDV2) {
-		if ((v.isConst() || v.isInvariant() || v.storage_class & STCmanifest) && v.init && !v.value)
+		if ((v.isConst() || v.isImmutable() || v.storage_class & STCmanifest) && v.init && !v.value)
 ///} else {
 ///	if (v.isConst() && v.init)
 ///}
@@ -94,7 +152,7 @@
 		else
 		{   
 			e = v.value;
-			if (v.isDataseg())
+			if (v.isCTFE())
 			{	
 				error(loc, "static variable %s cannot be read at compile time", v.toChars());
 				e = EXP_CANT_INTERPRET;
@@ -106,17 +164,17 @@
 		}
 		if (!e)
 			e = EXP_CANT_INTERPRET;
-    }
-    else if (s)
-    {
+	}
+	else if (s)
+	{
 		if (s.dsym.toInitializer() == s.sym)
 		{   
 			Expressions exps = new Expressions();
 			e = new StructLiteralExp(Loc(0), s.dsym, exps);
 			e = e.semantic(null);
 		}
-    }
-    return e;
+	}
+	return e;
 }
 
 /* Helper functions for BinExp.interpretAssignCommon
@@ -127,16 +185,16 @@
  */
 Expressions changeOneElement(Expressions oldelems, size_t indexToChange, Expression newelem)
 {
-    auto expsx = new Expressions();
-    expsx.setDim(oldelems.dim);
-    for (size_t j = 0; j < expsx.dim; j++)
-    {
+	auto expsx = new Expressions();
+	expsx.setDim(oldelems.dim);
+	for (size_t j = 0; j < expsx.dim; j++)
+	{
 		if (j == indexToChange)
 			expsx[j] = newelem;
 		else
 			expsx[j] = oldelems[j];
-    }
-    return expsx;
+	}
+	return expsx;
 }
 
 /***************************************
@@ -144,16 +202,16 @@
  */
 Expressions spliceElements(Expressions oldelems, Expressions newelems, size_t insertpoint)
 {
-    auto expsx = new Expressions();
-    expsx.setDim(oldelems.dim);
-    for (size_t j = 0; j < expsx.dim; j++)
-    {
+	auto expsx = new Expressions();
+	expsx.setDim(oldelems.dim);
+	for (size_t j = 0; j < expsx.dim; j++)
+	{
 		if (j >= insertpoint && j < insertpoint + newelems.dim)
 			expsx[j] = newelems[j - insertpoint];
 		else
 			expsx[j] = oldelems[j];
-    }
-    return expsx;
+	}
+	return expsx;
 }
 
 /******************************
@@ -161,53 +219,35 @@
  */
 ArrayLiteralExp createBlockDuplicatedArrayLiteral(Type type, Expression elem, size_t dim)
 {
-    auto elements = new Expressions();
-    elements.setDim(dim);
-    for (size_t i = 0; i < dim; i++) {
+	auto elements = new Expressions();
+	elements.setDim(dim);
+	for (size_t i = 0; i < dim; i++) {
 		elements[i] = elem;
 	}
 	
-    auto ae = new ArrayLiteralExp(Loc(0), elements);
-    ae.type = type;
-    return ae;
+	auto ae = new ArrayLiteralExp(Loc(0), elements);
+	ae.type = type;
+	return ae;
 }
 
 
 /********************************
- * Necessary because defaultInit() for a struct is a VarExp, not a StructLiteralExp.
- */
-StructLiteralExp createDefaultInitStructLiteral(Loc loc, StructDeclaration sym)
-{
-    Expressions structelems = new Expressions();
-    structelems.setDim(sym.fields.dim);
-    for (size_t j = 0; j < structelems.dim; j++)
-    {
-		structelems[j] = sym.fields[j].type.defaultInit(Loc(0));
-    }
-    StructLiteralExp structinit = new StructLiteralExp(loc, sym, structelems);
-    // Why doesn't the StructLiteralExp constructor do this, when
-    // sym.type != null ?
-    structinit.type = sym.type;
-    return structinit;
-}
-
-/********************************
  *  Add v to the istate list, unless it already exists there.
  */
 void addVarToInterstate(InterState istate, VarDeclaration v)
 {
-    if (!v.isParameter())
-    {
+	if (!v.isParameter())
+	{
 		for (size_t i = 0; 1; i++)
 		{
 			if (i == istate.vars.dim)
 			{   
 				istate.vars.push(v);
-				//printf("\tadding %s to istate\n", v.toChars());
+				//writef("\tadding %s to istate\n", v.toChars());
 				break;
 			}
 			if (v == cast(VarDeclaration)istate.vars[i])
 				break;
 		}
-    }
+	}
 }
\ No newline at end of file
--- a/dmd/templates/Util.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/templates/Util.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.templates.Util;
 
+import dmd.common;
 import dmd.Dsymbol;
 import dmd.Type;
 import dmd.Expression;
--- a/dmd/type/Util.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/dmd/type/Util.d	Tue Sep 14 15:46:50 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.type.Util;
 
+import dmd.common;
 import dmd.TY;
 import dmd.Expression;
 import dmd.Scope;
--- a/dmd2035.patch	Tue Aug 31 18:02:48 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-# HG changeset patch
-# User trass3r
-# Date 1283163123 -7200
-# Node ID 1ca9dcaadc045a9856c1c554fb2f871081df12a0
-# Parent  e5248fb387cb8381af2c9ec786bd08a86d90a3a7
-fix
-
-diff -r e5248fb387cb -r 1ca9dcaadc04 class.c
---- a/class.c	Sat Aug 28 17:24:54 2010 +0200
-+++ b/class.c	Mon Aug 30 12:12:03 2010 +0200
-@@ -61,7 +61,7 @@
-     if (id)
-     {	// Look for special class names
- 
--	if (id == Id::__sizeof || id == Id::alignof || id == Id::mangleof)
-+	if (id == Id::__sizeof || id == Id::__xalignof || id == Id::mangleof)
- 	    error("illegal class name");
- 
- 	// BUG: What if this is the wrong TypeInfo, i.e. it is nested?
-diff -r e5248fb387cb -r 1ca9dcaadc04 dsymbol.c
---- a/dsymbol.c	Sat Aug 28 17:24:54 2010 +0200
-+++ b/dsymbol.c	Mon Aug 30 12:12:03 2010 +0200
-@@ -488,7 +488,7 @@
- 	}
- 	if (sd->isAggregateDeclaration() || sd->isEnumDeclaration())
- 	{
--	    if (ident == Id::__sizeof || ident == Id::alignof || ident == Id::mangleof)
-+	    if (ident == Id::__sizeof || ident == Id::__xalignof || ident == Id::mangleof)
- 		error(".%s property cannot be redefined", ident->toChars());
- 	}
- 	return 1;
-diff -r e5248fb387cb -r 1ca9dcaadc04 expression.c
---- a/expression.c	Sat Aug 28 17:24:54 2010 +0200
-+++ b/expression.c	Mon Aug 30 12:12:03 2010 +0200
-@@ -5714,7 +5714,7 @@
-     }
-     else if (t1b->ty == Tpointer &&
- 	     ident != Id::init && ident != Id::__sizeof &&
--	     ident != Id::alignof && ident != Id::offsetof &&
-+	     ident != Id::__xalignof && ident != Id::offsetof &&
- 	     ident != Id::mangleof && ident != Id::stringof)
-     {	/* Rewrite:
-          *   p.ident
-diff -r e5248fb387cb -r 1ca9dcaadc04 idgen.c
---- a/idgen.c	Sat Aug 28 17:24:54 2010 +0200
-+++ b/idgen.c	Mon Aug 30 12:12:03 2010 +0200
-@@ -45,7 +45,7 @@
-     { "init" },
-     { "size" },
-     { "__sizeof", "sizeof" },
--    { "alignof" },
-+    { "__xalignof", "alignof" },
-     { "mangleof" },
-     { "stringof" },
-     { "tupleof" },
-diff -r e5248fb387cb -r 1ca9dcaadc04 mtype.c
---- a/mtype.c	Sat Aug 28 17:24:54 2010 +0200
-+++ b/mtype.c	Mon Aug 30 12:12:03 2010 +0200
-@@ -1303,7 +1303,7 @@
- 	error(loc, ".size property should be replaced with .sizeof");
- 	e = new ErrorExp();
-     }
--    else if (ident == Id::alignof)
-+    else if (ident == Id::__xalignof)
-     {
- 	e = new IntegerExp(loc, alignsize(), Type::tsize_t);
-     }
-@@ -5807,7 +5807,7 @@
-     if (!s)
-     {
- 	if (ident != Id::__sizeof &&
--	    ident != Id::alignof &&
-+	    ident != Id::__xalignof &&
- 	    ident != Id::init &&
- 	    ident != Id::mangleof &&
- 	    ident != Id::stringof &&
-@@ -6298,7 +6298,7 @@
- 	{
- 
- 	    if (ident != Id::__sizeof &&
--		ident != Id::alignof &&
-+		ident != Id::__xalignof &&
- 		ident != Id::init &&
- 		ident != Id::mangleof &&
- 		ident != Id::stringof &&
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmd2036.patch	Tue Sep 14 15:46:50 2010 +0200
@@ -0,0 +1,98 @@
+# HG changeset patch
+# User trass3r
+# Date 1283292718 -7200
+# Node ID e6e22eceb1e7da03f765df9369851a6491d1b2ad
+# Parent  a5c1086667193606d10002efa031b316a5727450
+2.036 patch
+
+diff -r a5c108666719 -r e6e22eceb1e7 src/dmd/class.c
+--- a/src/dmd/class.c	Mon Aug 30 20:49:59 2010 +0200
++++ b/src/dmd/class.c	Wed Sep 01 00:11:58 2010 +0200
+@@ -61,7 +61,7 @@
+     if (id)
+     {	// Look for special class names
+ 
+-	if (id == Id::__sizeof || id == Id::alignof || id == Id::mangleof)
++	if (id == Id::__sizeof || id == Id::_alignof || id == Id::mangleof)
+ 	    error("illegal class name");
+ 
+ 	// BUG: What if this is the wrong TypeInfo, i.e. it is nested?
+diff -r a5c108666719 -r e6e22eceb1e7 src/dmd/dsymbol.c
+--- a/src/dmd/dsymbol.c	Mon Aug 30 20:49:59 2010 +0200
++++ b/src/dmd/dsymbol.c	Wed Sep 01 00:11:58 2010 +0200
+@@ -488,7 +488,7 @@
+ 	}
+ 	if (sd->isAggregateDeclaration() || sd->isEnumDeclaration())
+ 	{
+-	    if (ident == Id::__sizeof || ident == Id::alignof || ident == Id::mangleof)
++	    if (ident == Id::__sizeof || ident == Id::_alignof || ident == Id::mangleof)
+ 		error(".%s property cannot be redefined", ident->toChars());
+ 	}
+ 	return 1;
+diff -r a5c108666719 -r e6e22eceb1e7 src/dmd/expression.c
+--- a/src/dmd/expression.c	Mon Aug 30 20:49:59 2010 +0200
++++ b/src/dmd/expression.c	Wed Sep 01 00:11:58 2010 +0200
+@@ -5747,7 +5747,7 @@
+     }
+     else if (t1b->ty == Tpointer &&
+ 	     ident != Id::init && ident != Id::__sizeof &&
+-	     ident != Id::alignof && ident != Id::offsetof &&
++	     ident != Id::_alignof && ident != Id::offsetof &&
+ 	     ident != Id::mangleof && ident != Id::stringof)
+     {	/* Rewrite:
+          *   p.ident
+diff -r a5c108666719 -r e6e22eceb1e7 src/dmd/idgen.c
+--- a/src/dmd/idgen.c	Mon Aug 30 20:49:59 2010 +0200
++++ b/src/dmd/idgen.c	Wed Sep 01 00:11:58 2010 +0200
+@@ -45,7 +45,7 @@
+     { "init" },
+     { "size" },
+     { "__sizeof", "sizeof" },
+-    { "alignof" },
++    { "_alignof", "alignof" },
+     { "mangleof" },
+     { "stringof" },
+     { "tupleof" },
+diff -r a5c108666719 -r e6e22eceb1e7 src/dmd/mtype.c
+--- a/src/dmd/mtype.c	Mon Aug 30 20:49:59 2010 +0200
++++ b/src/dmd/mtype.c	Wed Sep 01 00:11:58 2010 +0200
+@@ -1266,7 +1266,7 @@
+ 	error(loc, ".size property should be replaced with .sizeof");
+ 	e = new ErrorExp();
+     }
+-    else if (ident == Id::alignof)
++    else if (ident == Id::_alignof)
+     {
+ 	e = new IntegerExp(loc, alignsize(), Type::tsize_t);
+     }
+@@ -5895,7 +5895,7 @@
+     if (!s)
+     {
+ 	if (ident != Id::__sizeof &&
+-	    ident != Id::alignof &&
++	    ident != Id::_alignof &&
+ 	    ident != Id::init &&
+ 	    ident != Id::mangleof &&
+ 	    ident != Id::stringof &&
+@@ -6386,7 +6386,7 @@
+ 	{
+ 
+ 	    if (ident != Id::__sizeof &&
+-		ident != Id::alignof &&
++		ident != Id::_alignof &&
+ 		ident != Id::init &&
+ 		ident != Id::mangleof &&
+ 		ident != Id::stringof &&
+diff -r a5c108666719 -r e6e22eceb1e7 src/druntime/src/compiler/dmd/win32.mak
+--- a/src/druntime/src/compiler/dmd/win32.mak	Mon Aug 30 20:49:59 2010 +0200
++++ b/src/druntime/src/compiler/dmd/win32.mak	Wed Sep 01 00:11:58 2010 +0200
+@@ -163,8 +163,8 @@
+ 
+ # Patterns - asm
+ 
+-minit.obj : minit.asm
+-	$(CC) -c $**
++#minit.obj : minit.asm
++#	$(CC) -c $**
+ 
+ # Rulez
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmdpatch.patch	Tue Sep 14 15:46:50 2010 +0200
@@ -0,0 +1,183 @@
+# HG changeset patch
+# User trass3r
+# Date 1284418540 -7200
+# Node ID a4ec24e030fdda493d8d1249ef966e0beed13e1e
+# Parent  0ebf1721e4d32cfb38376c6688a767627aa63758
+t
+
+diff -r 0ebf1721e4d3 -r a4ec24e030fd src/dmd/class.c
+--- a/src/dmd/class.c	Mon Sep 13 15:46:31 2010 +0200
++++ b/src/dmd/class.c	Tue Sep 14 00:55:40 2010 +0200
+@@ -61,7 +61,7 @@
+     if (id)
+     {	// Look for special class names
+ 
+-	if (id == Id::__sizeof || id == Id::alignof || id == Id::mangleof)
++	if (id == Id::__sizeof || id == Id::__alignof || id == Id::mangleof)
+ 	    error("illegal class name");
+ 
+ 	// BUG: What if this is the wrong TypeInfo, i.e. it is nested?
+diff -r 0ebf1721e4d3 -r a4ec24e030fd src/dmd/dsymbol.c
+--- a/src/dmd/dsymbol.c	Mon Sep 13 15:46:31 2010 +0200
++++ b/src/dmd/dsymbol.c	Tue Sep 14 00:55:40 2010 +0200
+@@ -488,7 +488,7 @@
+ 	}
+ 	if (sd->isAggregateDeclaration() || sd->isEnumDeclaration())
+ 	{
+-	    if (ident == Id::__sizeof || ident == Id::alignof || ident == Id::mangleof)
++	    if (ident == Id::__sizeof || ident == Id::__alignof || ident == Id::mangleof)
+ 		error(".%s property cannot be redefined", ident->toChars());
+ 	}
+ 	return 1;
+diff -r 0ebf1721e4d3 -r a4ec24e030fd src/dmd/expression.c
+--- a/src/dmd/expression.c	Mon Sep 13 15:46:31 2010 +0200
++++ b/src/dmd/expression.c	Tue Sep 14 00:55:40 2010 +0200
+@@ -5953,7 +5953,7 @@
+     }
+     else if (t1b->ty == Tpointer &&
+ 	     ident != Id::init && ident != Id::__sizeof &&
+-	     ident != Id::alignof && ident != Id::offsetof &&
++	     ident != Id::__alignof && ident != Id::offsetof &&
+ 	     ident != Id::mangleof && ident != Id::stringof)
+     {	/* Rewrite:
+          *   p.ident
+diff -r 0ebf1721e4d3 -r a4ec24e030fd src/dmd/idgen.c
+--- a/src/dmd/idgen.c	Mon Sep 13 15:46:31 2010 +0200
++++ b/src/dmd/idgen.c	Tue Sep 14 00:55:40 2010 +0200
+@@ -44,7 +44,7 @@
+     { "init" },
+     { "size" },
+     { "__sizeof", "sizeof" },
+-    { "alignof" },
++    { "__alignof", "alignof" },
+     { "mangleof" },
+     { "stringof" },
+     { "tupleof" },
+diff -r 0ebf1721e4d3 -r a4ec24e030fd src/dmd/mtype.c
+--- a/src/dmd/mtype.c	Mon Sep 13 15:46:31 2010 +0200
++++ b/src/dmd/mtype.c	Tue Sep 14 00:55:40 2010 +0200
+@@ -1610,7 +1610,7 @@
+ 	error(loc, ".size property should be replaced with .sizeof");
+ 	e = new ErrorExp();
+     }
+-    else if (ident == Id::alignof)
++    else if (ident == Id::__alignof)
+     {
+ 	e = new IntegerExp(loc, alignsize(), Type::tsize_t);
+     }
+@@ -1749,7 +1749,7 @@
+     assert(sym);
+ 
+     if (ident != Id::__sizeof &&
+-	ident != Id::alignof &&
++	ident != Id::__alignof &&
+ 	ident != Id::init &&
+ 	ident != Id::mangleof &&
+ 	ident != Id::stringof &&
+diff -r 0ebf1721e4d3 -r a4ec24e030fd src/dmd/win32.mak
+--- a/src/dmd/win32.mak	Mon Sep 13 15:46:31 2010 +0200
++++ b/src/dmd/win32.mak	Tue Sep 14 00:55:40 2010 +0200
+@@ -8,7 +8,8 @@
+ DMDSVN=\svnproj\dmd\trunk\src
+ SCROOT=$D\dm
+ INCLUDE=$(SCROOT)\include
+-CC=\dm\bin\dmc
++CC=$(SCROOT)\bin\dmc
++LIB=$(SCROOT)\bin\lib
+ LIBNT=$(SCROOT)\lib
+ SNN=$(SCROOT)\lib\snn
+ DIR=\dmd2
+@@ -24,7 +25,7 @@
+ XFLG=
+ MODEL=n
+ OPT=
+-DEBUG=-gl -D
++DEBUG=-g -D
+ #PREC=-H -HItotal.h -HO
+ PREC=
+ LFLAGS=
+@@ -59,11 +60,17 @@
+ 	$(MAKE) OPT=-o "DEBUG=" LFLAGS=-L/delexe dmd.exe
+ #	$(MAKE) OPT=-o "DEBUG=" LFLAGS=-L/ma/co/delexe dmd.exe
+ 
++lib:
++	$(MAKE) OPT=-o "DEBUG=" dmd.lib
++
+ ################ NT COMMAND LINE DEBUG #########################
+ 
+ debdmd:
+ 	$(MAKE) OPT= "DEBUG=-D -g" LFLAGS=-L/ma/co dmd.exe
+ 
++deblib:
++	$(MAKE) OPT= "DEBUG=-D -g" dmd.lib
++
+ #########################################
+ 
+ # D front end
+@@ -155,8 +162,11 @@
+ #########################################
+ 
+ $(TARGET).exe : $(OBJS) win32.mak
+-	dmc -o$(TARGET).exe $(OBJS) -cpp -mn -Ar $(LFLAGS)
++	$(CC) -o$(TARGET).exe $(OBJS) -cpp -mn -Ar $(LFLAGS)
+ 
++$(TARGET).lib : $(OBJS) win32.mak
++	$(LIB) -c -p128 $(TARGET).lib $(OBJ8) $(ROOTOBJS) msc.obj tk.obj util.obj entity.obj ph.obj eh.obj
++	$(LIB) -d $(TARGET).lib iasm.obj
+ 
+ ##################### INCLUDE MACROS #####################
+ 
+@@ -171,11 +181,11 @@
+ 	msgsx
+ 
+ msgsx.exe : msgsx.c
+-	dmc msgsx -mn -D$(TARGET) $(DEFINES) $(WINLIBS)
++	$(CC) msgsx -mn -D$(TARGET) $(DEFINES) $(WINLIBS)
+ 
+ elxxx.c cdxxx.c optab.c debtab.c fltables.c tytab.c : \
+ 	$C\cdef.h $C\cc.h $C\oper.h $C\ty.h $C\optabgen.c
+-	dmc -cpp -ooptabgen.exe $C\optabgen -DMARS -I$(TK) $(WINLIBS) #-L$(LINKS)
++	$(CC) -cpp -ooptabgen.exe $C\optabgen -DMARS -I$(TK) $(WINLIBS) #-L$(LINKS)
+ 	optabgen
+ 
+ impcnvtab.c : impcnvgen.c
+@@ -183,7 +193,7 @@
+ 	impcnvgen
+ 
+ id.h id.c : idgen.c
+-	dmc -cpp idgen
++	$(CC) -cpp idgen
+ 	idgen
+ 
+ ##################### SPECIAL BUILDS #####################
+diff -r 0ebf1721e4d3 -r a4ec24e030fd src/druntime/win32.mak
+--- a/src/druntime/win32.mak	Mon Sep 13 15:46:31 2010 +0200
++++ b/src/druntime/win32.mak	Tue Sep 14 00:55:40 2010 +0200
+@@ -1,5 +1,5 @@
+ 
+-DMD=dmd
++DMD=..\..\windows\bin\dmd
+ 
+ CC=dmc
+ 
+@@ -300,7 +300,7 @@
+ # NOTE: a pre-compiled minit.obj has been provided in dmd for Win32 and
+ #       minit.asm is not used by dmd for Linux
+ 
+-OBJS= errno_c.obj complex.obj critical.obj deh.obj monitor.obj src\rt\minit.obj
++OBJS= errno_c.obj complex.obj critical.obj deh.obj monitor.obj minit.obj
+ OBJS_TO_DELETE= errno_c.obj complex.obj critical.obj deh.obj monitor.obj
+ 
+ DOCS=\
+diff -r 0ebf1721e4d3 -r a4ec24e030fd src/phobos/win32.mak
+--- a/src/phobos/win32.mak	Mon Sep 13 15:46:31 2010 +0200
++++ b/src/phobos/win32.mak	Tue Sep 14 00:55:40 2010 +0200
+@@ -51,7 +51,7 @@
+ 
+ DMD=$(DIR)\bin\dmd
+ #DMD=..\dmd
+-DMD=dmd
++DMD=..\..\windows\bin\dmd
+ 
+ ## Location of where to write the html documentation files
+ 
--- a/main.d	Tue Aug 31 18:02:48 2010 +0200
+++ b/main.d	Tue Sep 14 15:46:50 2010 +0200
@@ -214,6 +214,7 @@
     int status = ExitCode.EXIT_SUCCESS;
     int argcstart = args.length;
     int setdebuglib = 0;
+    byte noboundscheck = 0;
 	
 	global = new Global();
 
@@ -229,7 +230,7 @@
     global.params.useInvariants = 1;
     global.params.useIn = 1;
     global.params.useOut = 1;
-    global.params.useArrayBounds = 1;
+    global.params.useArrayBounds = 2;	// default to all functions
     global.params.useSwitchError = 1;
     global.params.useInline = 0;
     global.params.obj = 1;
@@ -290,12 +291,17 @@
 }
     VersionCondition.addPredefinedGlobalIdent("all");
 
-version (_WIN32) {
-    inifile(args[0], "sc.ini");
-} else version (POSIX) {///linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4
-    inifile(args[0], "dmd.conf");
-} else {
-        static assert (false, "fix this");
+version (Windows)
+{
+	inifile(args[0], "sc.ini");
+}
+ else version (Posix) ///linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4
+{
+	inifile(args[0], "dmd.conf");
+}
+else
+{
+	static assert (false, "fix this");
 }
     args = getenv_setargv("DFLAGS", args);
 
@@ -472,8 +478,8 @@
             else if (arg == "release")
                 global.params.release = 1;
 ///version (DMDV2) {
-            else if (arg == "safe")
-                global.params.safe = 1;
+	        else if (arg == "noboundscheck")
+		        noboundscheck = 1;
 ///}
             else if (arg == "unittest")
                 global.params.useUnitTests = 1;
@@ -578,7 +584,7 @@
             }
             else if (memcmp(p + 1, "man".ptr, 3) == 0)
             {
-version (_WIN32) {
+version (Windows) {
 version (DMDV1) {
                 browse("http://www.digitalmars.com/d/1.0/dmd-windows.html");
 } else {
@@ -664,14 +670,18 @@
 }
 
     if (global.params.release)
-    {        global.params.useInvariants = 0;
+    {
+        global.params.useInvariants = 0;
         global.params.useIn = 0;
         global.params.useOut = 0;
         global.params.useAssert = 0;
         global.params.useArrayBounds = 0;
         global.params.useSwitchError = 0;
     }
-
+    
+    if (noboundscheck)
+	    global.params.useArrayBounds = 0;
+    
     if (global.params.run)
         global.params.quiet = 1;
 
@@ -800,7 +810,7 @@
 		String s = cast(String) files.data[i];
         string mp = s.str;
 
-version (_WIN32) {
+version (Windows) {
 		char[] copy = null;
         // Convert / to \ so linker will work
         foreach (j, c; mp)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test.d	Tue Sep 14 15:46:50 2010 +0200
@@ -0,0 +1,253 @@
+import std.stdio;
+import std.utf;
+import std.file;
+import std.path;
+import std.algorithm;
+import std.string;
+import std.process;
+import core.stdc.ctype;
+import std.c.windows.windows;
+
+string compiler = "dmd";
+
+class Test
+{
+	enum EXTRA_SOURCES = "EXTRA_SOURCES";
+	enum COMPILE_SEPARATELY = "COMPILE_SEPARATELY";
+	enum PERMUTE_ARGS = "PERMUTE_ARGS";
+	enum REQUIRED_ARGS = "REQUIRED_ARGS";
+	enum POST_SCRIPT = "POST_SCRIPT";
+	enum EXECUTE_ARGS = "EXECUTE_ARGS";
+	
+	this(string path, string outputDir)
+	{
+		this.outputDir = outputDir;
+		this.baseDir = dirname(path);
+		
+		this.baseName = getBaseName(path);
+		this.name = getName(baseName);
+		
+		this.fileNames ~= baseName;
+		
+		auto file = File(path);
+		while (true) {
+			auto line = file.readln();
+			if (!line.startsWith("// ")) {
+				break;
+			}
+			
+			line = trim(line[3..$]);
+			if (line.startsWith(EXTRA_SOURCES)) {
+				fileNames ~= split(line[EXTRA_SOURCES.length + 2..$], " ");
+			} else if (line.startsWith(COMPILE_SEPARATELY)) {
+				compileSeparately = true;
+			} else if (line.startsWith(EXECUTE_ARGS)) {
+				executeArgs = line[EXECUTE_ARGS.length + 2..$];
+			} else if (line.startsWith(PERMUTE_ARGS)) {
+				// ignore for now
+			} else if (line.startsWith(REQUIRED_ARGS)) {
+				requiredArgs = line[REQUIRED_ARGS.length + 2..$];
+			} else if (line.startsWith(POST_SCRIPT)) {
+				// ignore for now
+			} else {
+				continue;
+			}
+		}
+	}
+	
+	private string prefix()
+	{
+		return std.string.format(compiler ~ " -od%s -I%s %s", outputDir, baseDir, requiredArgs);
+	}
+	
+	private string csuffix(string fileName)
+	{
+		// output to console
+		return ""; //std.string.format(" > %s\\%s.clog", outputDir, getBaseName(fileName));
+	}
+	
+	private string lsuffix(string fileName)
+	{
+		return std.string.format(" > %s\\%s.llog", outputDir, getBaseName(fileName));
+	}
+	
+	private string output()
+	{
+		return std.string.format(" -of%s\\%s.exe", outputDir, name);
+	}
+	
+	private void execute(string command)
+	{
+		system(command);
+	}
+	
+	void compile()
+	{
+		if (compileSeparately) {
+			string link_command = compiler ~ output();
+			foreach (fileName; fileNames) {
+				string compile_command = prefix();
+				
+				compile_command ~= std.string.format(" %s\\%s -c", baseDir, fileName);
+				compile_command ~= csuffix(fileName);
+				
+				execute(compile_command);
+				link_command ~= std.string.format(" %s\\%s.obj", outputDir, getName(getBaseName(fileName)));
+			}
+			
+			link_command ~= lsuffix(baseName);
+			
+			execute(link_command);			
+		} else {
+			string compile_command = prefix();
+			foreach (fileName; fileNames) {
+				compile_command ~= std.string.format(" %s\\%s", baseDir, fileName);
+			}
+			
+			compile_command ~= output();
+			compile_command ~= csuffix(baseName);
+			
+			execute(compile_command);
+		}
+	}
+	
+	private string[] fileNames;
+	
+	private string name;
+	private string baseName;
+	private string outputDir;
+	private string baseDir;
+	private string requiredArgs;
+	private string executeArgs;
+	
+	private bool compileSeparately = false;
+}
+
+class RunnableTest : Test
+{
+	this(string path, string outputDir)
+	{
+		super(path, outputDir);
+	}
+	
+	void run()
+	{
+		string run_command = std.string.format("%s\\%s.exe %s > %s\\%s.exe.rlog", outputDir, name, executeArgs, outputDir, name);
+		execute(run_command);
+	}
+}
+
+int main(string[] args)
+{
+	auto runnable_tests = wildcard("runnable/*.d"/*, "runnable/*.html", "runnable/*.sh"*/);
+	auto runnable_test_results = map!q{"result/" ~ a ~ ".out"}(runnable_tests);
+
+	auto outputDir = "result";
+	
+	if (args.length >= 2) {
+		compiler = args[1];
+	} else {
+		// compiler = "dmd"; // value by default
+	}
+
+	foreach (fileName; runnable_tests) {
+		//fileName = "runnable\\a18.d";
+		writeln("testing ", fileName);
+		auto test = new RunnableTest(fileName, outputDir);
+		test.compile();
+//		test.run();
+//		break;
+	}
+	
+	return 0;
+}
+
+string[] wildcard(string[] paths...)
+{
+	string[] fileNames;
+	
+	foreach (path; paths) {
+		filter(path, (string fileName) { fileNames ~= fileName; return true; });
+	}
+	
+	return fileNames;
+}
+
+string trimLeft(string s)
+{
+	for (int i = 0; i < s.length; ++i) {
+		if (!isspace(s[i])) {
+			return s[i..$];
+		}
+	}
+	
+	return null;
+}
+
+string trimRight(string s)
+{
+	for (int i = s.length - 1; i >= 0; --i) {
+		if (!isspace(s[i])) {
+			return s[0..i + 1];
+		}
+	}
+	
+	return null;
+}
+
+string trim(string s)
+{
+	return trimLeft(trimRight(s));
+}
+
+version(Windows) void filter(string pattern, bool delegate(string fileName) callback)
+{
+	WIN32_FIND_DATAW fileinfo;
+
+	auto h = FindFirstFileW(std.utf.toUTF16z(pattern), &fileinfo);
+	if (h == INVALID_HANDLE_VALUE)
+		return;
+
+	auto path = dirname(pattern);
+
+	do
+	{
+		// Skip "." and ".."
+		auto name = fileinfo.cFileName.ptr;
+		if (name[0] == '.' && (name[1] == 0 || name[1] == '.'))
+			continue;
+
+		size_t clength = std.string.wcslen(fileinfo.cFileName.ptr);
+        auto fileName = std.path.join(path, std.utf.toUTF8(fileinfo.cFileName[0 .. clength]));
+		
+		if (!callback(fileName)) {
+			break;
+		}
+	} while (FindNextFileW(h, &fileinfo) != FALSE);
+	
+	FindClose(h);
+}
+
+string getBaseName(string fullname, string extension = null)
+{
+    auto i = fullname.length;
+    for (; i > 0; i--)
+    {
+        version(Windows)
+        {
+            if (fullname[i - 1] == ':' || fullname[i - 1] == '\\' || fullname[i - 1] == '/')
+                break;
+        }
+        else version(Posix)
+        {
+            if (fullname[i - 1] == '/')
+                break;
+        }
+        else
+        {
+            static assert(0);
+        }
+    }
+    return chomp(fullname[i .. fullname.length],
+            extension.length ? extension : "");
+}
\ No newline at end of file
--- a/win32_lib.mak	Tue Aug 31 18:02:48 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,518 +0,0 @@
-#_ win32_lib.mak
-# Copyright (C) 1999-2009 by Digital Mars, http://www.digitalmars.com
-# Written by Walter Bright
-# All Rights Reserved
-# Build dmd with Digital Mars C++ compiler
-
-D=
-DMDSVN=\svnproj\dmd\trunk\src
-SCROOT=$D\dm
-INCLUDE=$(SCROOT)\include
-CC=\dm\bin\dmc
-LIBNT=$(SCROOT)\lib
-SNN=$(SCROOT)\lib\snn
-DIR=\dmd2
-CP=cp
-
-C=backend
-TK=tk
-ROOT=root
-
-MAKE=make -fwin32_lib.mak C=$C TK=$(TK) ROOT=$(ROOT)
-
-TARGET=dmd
-XFLG=
-MODEL=n
-OPT=
-DEBUG=-gl -D
-#PREC=-H -HItotal.h -HO
-PREC=
-LFLAGS=
-
-LINKN=$(SCROOT)\bin\link /de
-
-CFLAGS=-I$(ROOT);$(INCLUDE) $(XFLG) $(OPT) $(DEBUG) -cpp -D_DH
-MFLAGS=-I$C;$(TK) -DMARS -cpp $(DEBUG) -e -wx -D_DH
-
-# Makerules:
-.c.obj:
-	$(CC) -c $(CFLAGS) $(PREC) $*
-
-.asm.obj:
-	$(CC) -c $(CFLAGS) $*
-
-defaulttarget: debdmd
-
-################ RELEASES #########################
-
-release:
-	$(MAKE) clean
-	$(MAKE) dmd
-	$(MAKE) clean
-
-################ NT COMMAND LINE RELEASE #########################
-
-trace:
-	$(MAKE) OPT=-o "DEBUG=-gt -Nc" LFLAGS=-L/ma/co/delexe dmd.lib
-
-dmd:
-	$(MAKE) OPT=-o "DEBUG=" LFLAGS=-L/delexe dmd.lib
-#	$(MAKE) OPT=-o "DEBUG=" LFLAGS=-L/ma/co/delexe dmd.exe
-
-################ NT COMMAND LINE DEBUG #########################
-
-debdmd:
-	$(MAKE) OPT= "DEBUG=-D -g" LFLAGS=-L/ma/co dmd.lib
-
-#########################################
-
-# D front end
-
-OBJ1= mars2.obj enum.obj struct.obj dsymbol.obj import.obj id.obj \
-	staticassert.obj identifier.obj mtype.obj expression.obj \
-	optimize.obj template.obj lexer.obj declaration.obj cast.obj \
-	init.obj func.obj utf.obj unialpha.obj parse.obj statement.obj \
-	constfold.obj version.obj inifile.obj typinf.obj \
-	module.obj scope.obj dump.obj cond.obj inline.obj opover.obj \
-	entity.obj class.obj mangle.obj attrib.obj impcnvtab.obj \
-	link.obj access.obj doc.obj macro.obj hdrgen.obj delegatize.obj \
-	interpret.obj traits.obj aliasthis.obj \
-	builtin.obj clone.obj libomf.obj arrayop.obj irstate.obj \
-	glue.obj msc.obj ph.obj tk.obj s2ir.obj todt.obj e2ir.obj tocsym.obj \
-	util.obj bit.obj eh.obj toobj.obj toctype.obj tocvdebug.obj toir.obj \
-	json.obj
-
-# from C/C++ compiler optimizer and back end
-
-OBJ8= go.obj gdag.obj gother.obj gflow.obj gloop.obj var.obj el.obj \
-	newman.obj glocal.obj os.obj nteh.obj evalu8.obj cgcs.obj \
-	rtlsym.obj html.obj cgelem.obj cgen.obj cgreg.obj out.obj \
-	blockopt.obj cgobj.obj cg.obj cgcv.obj type.obj dt.obj \
-	debug.obj code.obj cg87.obj cgsched.obj ee.obj csymbol.obj \
-	cgcod.obj cod1.obj cod2.obj cod3.obj cod4.obj cod5.obj outbuf.obj \
-	bcomplex.obj iasm.obj ptrntab.obj aa.obj ti_achar.obj md5.obj
-
-# from ROOT
-
-ROOTOBJS= lstring.obj array.obj gnuc.obj man.obj rmem.obj port.obj root.obj \
-	stringtable.obj dchar.obj response.obj async.obj
-
-OBJS= $(OBJ1) $(OBJ8) $(ROOTOBJS)
-
-SRCS= mars2.c enum.c struct.c dsymbol.c import.c idgen.c impcnvgen.c utf.h \
-	utf.c entity.c identifier.c mtype.c expression.c optimize.c \
-	template.h template.c lexer.c declaration.c cast.c \
-	cond.h cond.c link.c aggregate.h staticassert.h parse.c statement.c \
-	constfold.c version.h version.c inifile.c iasm.c staticassert.c \
-	module.c scope.c dump.c init.h init.c attrib.h attrib.c opover.c \
-	eh.c toctype.c class.c mangle.c bit.c tocsym.c func.c inline.c \
-	access.c complex_t.h unialpha.c irstate.h irstate.c glue.c msc.c \
-	ph.c tk.c s2ir.c todt.c e2ir.c util.c toobj.c cppmangle.c \
-	identifier.h parse.h objfile.h scope.h enum.h import.h \
-	typinf.c tocvdebug.c toelfdebug.c mars.h module.h mtype.h dsymbol.h \
-	declaration.h lexer.h expression.h statement.h doc.h doc.c \
-	macro.h macro.c hdrgen.h hdrgen.c arraytypes.h \
-	delegatize.c toir.h toir.c interpret.c traits.c builtin.c \
-	clone.c lib.h libomf.c libelf.c libmach.c arrayop.c \
-	aliasthis.h aliasthis.c json.h json.c
-
-# From C++ compiler
-
-BACKSRC= $C\cdef.h $C\cc.h $C\oper.h $C\ty.h $C\optabgen.c \
-	$C\global.h $C\parser.h $C\code.h $C\type.h $C\dt.h $C\cgcv.h \
-	$C\el.h $C\iasm.h $C\rtlsym.h $C\html.h \
-	$C\bcomplex.c $C\blockopt.c $C\cg.c $C\cg87.c \
-	$C\cgcod.c $C\cgcs.c $C\cgcv.c $C\cgelem.c $C\cgen.c $C\cgobj.c \
-	$C\cgreg.c $C\var.c \
-	$C\cgsched.c $C\cod1.c $C\cod2.c $C\cod3.c $C\cod4.c $C\cod5.c \
-	$C\code.c $C\symbol.c $C\debug.c $C\dt.c $C\ee.c $C\el.c \
-	$C\evalu8.c $C\go.c $C\gflow.c $C\gdag.c \
-	$C\gother.c $C\glocal.c $C\gloop.c $C\html.c $C\newman.c \
-	$C\nteh.c $C\os.c $C\out.c $C\outbuf.c $C\ptrntab.c $C\rtlsym.c \
-	$C\type.c $C\melf.h $C\mach.h $C\bcomplex.h \
-	$C\cdeflnx.h $C\outbuf.h $C\token.h $C\tassert.h \
-	$C\elfobj.c $C\cv4.h $C\dwarf2.h $C\cpp.h $C\exh.h $C\go.h \
-	$C\dwarf.c $C\dwarf.h $C\cppman.c $C\machobj.c \
-	$C\strtold.c $C\aa.h $C\aa.c $C\tinfo.h $C\ti_achar.c \
-	$C\md5.h $C\md5.c
-
-# From TK
-
-TKSRC= $(TK)\filespec.h $(TK)\mem.h $(TK)\list.h $(TK)\vec.h \
-	$(TK)\filespec.c $(TK)\mem.c $(TK)\vec.c $(TK)\list.c
-
-# From root
-
-ROOTSRC= $(ROOT)\dchar.h $(ROOT)\dchar.c $(ROOT)\lstring.h \
-	$(ROOT)\lstring.c $(ROOT)\root.h $(ROOT)\root.c $(ROOT)\array.c \
-	$(ROOT)\rmem.h $(ROOT)\rmem.c $(ROOT)\port.h \
-	$(ROOT)\stringtable.h $(ROOT)\stringtable.c \
-	$(ROOT)\gnuc.h $(ROOT)\gnuc.c $(ROOT)\man.c $(ROOT)\port.c \
-	$(ROOT)\response.c $(ROOT)\async.h $(ROOT)\async.c
-
-MAKEFILES=win32.mak win32_lib.mak linux.mak osx.mak freebsd.mak solaris.mak
-
-#########################################
-
-$(TARGET).lib : $(OBJS) win32_lib.mak
-	lib -c -p128 $(TARGET).lib $(OBJS)
-
-##################### INCLUDE MACROS #####################
-
-CCH=
-#TOTALH=$(CCH) total.sym
-TOTALH=$(CCH) id.h
-CH= $C\cc.h $C\global.h $C\parser.h $C\oper.h $C\code.h $C\type.h $C\dt.h $C\cgcv.h $C\el.h $C\iasm.h
-
-##################### GENERATED SOURCE #####################
-
-msgs.h msgs.c sj1041.msg sj1036.msg sj1031.msg : msgsx.exe
-	msgsx
-
-msgsx.exe : msgsx.c
-	dmc msgsx -mn -D$(TARGET) $(DEFINES) $(WINLIBS)
-
-elxxx.c cdxxx.c optab.c debtab.c fltables.c tytab.c : \
-	$C\cdef.h $C\cc.h $C\oper.h $C\ty.h $C\optabgen.c
-	dmc -cpp -ooptabgen.exe $C\optabgen -DMARS -I$(TK) $(WINLIBS) #-L$(LINKS)
-	optabgen
-
-impcnvtab.c : impcnvgen.c
-	$(CC) -I$(ROOT) -cpp impcnvgen
-	impcnvgen
-
-id.h id.c : idgen.c
-	dmc -cpp idgen
-	idgen
-
-##################### SPECIAL BUILDS #####################
-
-total.sym : $(ROOT)\root.h mars.h lexer.h parse.h enum.h dsymbol.h \
-	mtype.h expression.h attrib.h init.h cond.h version.h \
-	declaration.h statement.h scope.h import.h module.h id.h \
-	template.h aggregate.h arraytypes.h lib.h total.h
-	$(CC) -c $(CFLAGS) -HFtotal.sym total.h
-
-impcnvtab.obj : mtype.h impcnvtab.c
-	$(CC) -c -I$(ROOT) -cpp impcnvtab
-
-iasm.obj : $(CH) $(TOTALH) $C\iasm.h iasm.c
-	$(CC) -c $(MFLAGS) -I$(ROOT) iasm
-
-bcomplex.obj : $C\bcomplex.c
-	$(CC) -c $(MFLAGS) $C\bcomplex
-
-aa.obj : $C\tinfo.h $C\aa.h $C\aa.c
-	$(CC) -c $(MFLAGS) -I. $C\aa
-
-bit.obj : expression.h bit.c
-	$(CC) -c -I$(ROOT) $(MFLAGS) bit
-
-blockopt.obj : $C\blockopt.c
-	$(CC) -c $(MFLAGS) $C\blockopt
-
-cg.obj : $C\cg.c
-	$(CC) -c $(MFLAGS) -I. $C\cg
-
-cg87.obj : $C\cg87.c
-	$(CC) -c $(MFLAGS) $C\cg87
-
-cgcod.obj : $C\cgcod.c
-	$(CC) -c $(MFLAGS) -I. $C\cgcod
-
-cgcs.obj : $C\cgcs.c
-	$(CC) -c $(MFLAGS) $C\cgcs
-
-cgcv.obj : $C\cgcv.c
-	$(CC) -c $(MFLAGS) $C\cgcv
-
-cgelem.obj : $C\rtlsym.h $C\cgelem.c
-	$(CC) -c $(MFLAGS) -I. $C\cgelem
-
-cgen.obj : $C\rtlsym.h $C\cgen.c
-	$(CC) -c $(MFLAGS) $C\cgen
-
-cgobj.obj : $C\md5.h $C\cgobj.c
-	$(CC) -c $(MFLAGS) $C\cgobj
-
-cgreg.obj : $C\cgreg.c
-	$(CC) -c $(MFLAGS) $C\cgreg
-
-cgsched.obj : $C\rtlsym.h $C\cgsched.c
-	$(CC) -c $(MFLAGS) $C\cgsched
-
-cod1.obj : $C\rtlsym.h $C\cod1.c
-	$(CC) -c $(MFLAGS) $C\cod1
-
-cod2.obj : $C\rtlsym.h $C\cod2.c
-	$(CC) -c $(MFLAGS) $C\cod2
-
-cod3.obj : $C\rtlsym.h $C\cod3.c
-	$(CC) -c $(MFLAGS) $C\cod3
-
-cod4.obj : $C\cod4.c
-	$(CC) -c $(MFLAGS) $C\cod4
-
-cod5.obj : $C\cod5.c
-	$(CC) -c $(MFLAGS) $C\cod5
-
-code.obj : $C\code.c
-	$(CC) -c $(MFLAGS) $C\code
-
-irstate.obj : irstate.h irstate.c
-	$(CC) -c $(MFLAGS) irstate
-
-csymbol.obj : $C\symbol.c
-	$(CC) -c $(MFLAGS) $C\symbol -ocsymbol.obj
-
-debug.obj : $C\debug.c
-	$(CC) -c $(MFLAGS) -I. $C\debug
-
-dt.obj : $C\dt.h $C\dt.c
-	$(CC) -c $(MFLAGS) $C\dt
-
-ee.obj : $C\ee.c
-	$(CC) -c $(MFLAGS) $C\ee
-
-eh.obj : $C\cc.h $C\code.h $C\type.h $C\dt.h eh.c
-	$(CC) -c $(MFLAGS) eh
-
-el.obj : $C\rtlsym.h $C\el.h $C\el.c
-	$(CC) -c $(MFLAGS) $C\el
-
-evalu8.obj : $C\evalu8.c
-	$(CC) -c $(MFLAGS) $C\evalu8
-
-go.obj : $C\go.c
-	$(CC) -c $(MFLAGS) $C\go
-
-gflow.obj : $C\gflow.c
-	$(CC) -c $(MFLAGS) $C\gflow
-
-gdag.obj : $C\gdag.c
-	$(CC) -c $(MFLAGS) $C\gdag
-
-gother.obj : $C\gother.c
-	$(CC) -c $(MFLAGS) $C\gother
-
-glocal.obj : $C\rtlsym.h $C\glocal.c
-	$(CC) -c $(MFLAGS) $C\glocal
-
-gloop.obj : $C\gloop.c
-	$(CC) -c $(MFLAGS) $C\gloop
-
-glue.obj : $(CH) $(TOTALH) $C\rtlsym.h mars.h module.h glue.c
-	$(CC) -c $(MFLAGS) -I$(ROOT) glue
-
-html.obj : $(CH) $(TOTALH) $C\html.h $C\html.c
-	$(CC) -c -I$(ROOT) $(MFLAGS) $C\html
-
-mars2.obj : $(TOTALH) module.h mars.h mars2.c
-	$(CC) -c $(CFLAGS) $(PREC) $* -Ae
-
-md5.obj : $C\md5.h $C\md5.c
-	$(CC) -c $(MFLAGS) $C\md5
-
-module.obj : $(TOTALH) $C\html.h module.c
-	$(CC) -c $(CFLAGS) -I$C $(PREC) module.c
-
-msc.obj : $(CH) mars.h msc.c
-	$(CC) -c $(MFLAGS) msc
-
-newman.obj : $(CH) $C\newman.c
-	$(CC) -c $(MFLAGS) $C\newman
-
-nteh.obj : $C\rtlsym.h $C\nteh.c
-	$(CC) -c $(MFLAGS) $C\nteh
-
-os.obj : $C\os.c
-	$(CC) -c $(MFLAGS) $C\os
-
-out.obj : $C\out.c
-	$(CC) -c $(MFLAGS) $C\out
-
-outbuf.obj : $C\outbuf.h $C\outbuf.c
-	$(CC) -c $(MFLAGS) $C\outbuf
-
-ph.obj : ph.c
-	$(CC) -c $(MFLAGS) ph
-
-ptrntab.obj : $C\iasm.h $C\ptrntab.c
-	$(CC) -c $(MFLAGS) $C\ptrntab
-
-rtlsym.obj : $C\rtlsym.h $C\rtlsym.c
-	$(CC) -c $(MFLAGS) $C\rtlsym
-
-ti_achar.obj : $C\tinfo.h $C\ti_achar.c
-	$(CC) -c $(MFLAGS) -I. $C\ti_achar
-
-toctype.obj : $(CH) $(TOTALH) $C\rtlsym.h mars.h module.h toctype.c
-	$(CC) -c $(MFLAGS) -I$(ROOT) toctype
-
-tocvdebug.obj : $(CH) $(TOTALH) $C\rtlsym.h mars.h module.h tocvdebug.c
-	$(CC) -c $(MFLAGS) -I$(ROOT) tocvdebug
-
-toobj.obj : $(CH) $(TOTALH) mars.h module.h toobj.c
-	$(CC) -c $(MFLAGS) -I$(ROOT) toobj
-
-type.obj : $C\type.c
-	$(CC) -c $(MFLAGS) $C\type
-
-typinf.obj : $(CH) $(TOTALH) $C\rtlsym.h mars.h module.h typinf.c
-	$(CC) -c $(MFLAGS) -I$(ROOT) typinf
-
-todt.obj : mtype.h expression.h $C\dt.h todt.c
-	$(CC) -c -I$(ROOT) $(MFLAGS) todt
-
-s2ir.obj : $C\rtlsym.h statement.h s2ir.c
-	$(CC) -c -I$(ROOT) $(MFLAGS) s2ir
-
-e2ir.obj : $C\rtlsym.h expression.h toir.h e2ir.c
-	$(CC) -c -I$(ROOT) $(MFLAGS) e2ir
-
-toir.obj : $C\rtlsym.h expression.h toir.h toir.c
-	$(CC) -c -I$(ROOT) $(MFLAGS) toir
-
-tocsym.obj : $(CH) $(TOTALH) mars.h module.h tocsym.c
-	$(CC) -c $(MFLAGS) -I$(ROOT) tocsym
-
-util.obj : util.c
-	$(CC) -c $(MFLAGS) util
-
-var.obj : $C\var.c optab.c
-	$(CC) -c $(MFLAGS) -I. $C\var
-
-
-tk.obj : tk.c
-	$(CC) -c $(MFLAGS) tk.c
-
-# ROOT
-
-array.obj : $(ROOT)\array.c
-	$(CC) -c $(CFLAGS) $(ROOT)\array.c
-
-async.obj : $(ROOT)\async.h $(ROOT)\async.c
-	$(CC) -c $(CFLAGS) $(ROOT)\async.c
-
-dchar.obj : $(ROOT)\dchar.c
-	$(CC) -c $(CFLAGS) $(ROOT)\dchar.c
-
-gnuc.obj : $(ROOT)\gnuc.c
-	$(CC) -c $(CFLAGS) $(ROOT)\gnuc.c
-
-lstring.obj : $(ROOT)\lstring.c
-	$(CC) -c $(CFLAGS) $(ROOT)\lstring.c
-
-man.obj : $(ROOT)\man.c
-	$(CC) -c $(CFLAGS) $(ROOT)\man.c
-
-rmem.obj : $(ROOT)\rmem.c
-	$(CC) -c $(CFLAGS) $(ROOT)\rmem.c
-
-port.obj : $(ROOT)\port.c
-	$(CC) -c $(CFLAGS) $(ROOT)\port.c
-
-root.obj : $(ROOT)\root.c
-	$(CC) -c $(CFLAGS) $(ROOT)\root.c
-
-response.obj : $(ROOT)\response.c
-	$(CC) -c $(CFLAGS) $(ROOT)\response.c
-
-stringtable.obj : $(ROOT)\stringtable.c
-	$(CC) -c $(CFLAGS) $(ROOT)\stringtable.c
-
-
-################# Source file dependencies ###############
-
-access.obj : $(TOTALH) enum.h aggregate.h init.h attrib.h access.c
-aliasthis.obj : $(TOTALH) aliasthis.h aliasthis.c
-arrayop.obj : $(TOTALH) identifier.h declaration.h arrayop.c
-attrib.obj : $(TOTALH) identifier.h declaration.h attrib.h attrib.c
-builtin.obj : $(TOTALH) builtin.c
-cast.obj : $(TOTALH) expression.h mtype.h cast.c
-class.obj : $(TOTALH) enum.h class.c
-clone.obj : $(TOTALH) clone.c
-constfold.obj : $(TOTALH) expression.h constfold.c
-cond.obj : $(TOTALH) identifier.h declaration.h cond.h cond.c
-declaration.obj : $(TOTALH) identifier.h attrib.h declaration.h declaration.c
-delegatize.obj : $(TOTALH) delegatize.c
-doc.obj : $(TOTALH) doc.h doc.c
-enum.obj : $(TOTALH) identifier.h enum.h enum.c
-expression.obj : $(TOTALH) expression.h expression.c
-func.obj : $(TOTALH) identifier.h attrib.h declaration.h func.c
-hdrgen.obj : $(TOTALH) hdrgen.h hdrgen.c
-id.obj : $(TOTALH) id.h id.c
-identifier.obj : $(TOTALH) identifier.h identifier.c
-import.obj : $(TOTALH) dsymbol.h import.h import.c
-inifile.obj : $(TOTALH) inifile.c
-init.obj : $(TOTALH) init.h init.c
-inline.obj : $(TOTALH) inline.c
-interpret.obj : $(TOTALH) interpret.c
-json.obj : $(TOTALH) json.h json.c
-lexer.obj : $(TOTALH) lexer.c
-libomf.obj : $(TOTALH) lib.h libomf.c
-link.obj : $(TOTALH) link.c
-macro.obj : $(TOTALH) macro.h macro.c
-mangle.obj : $(TOTALH) dsymbol.h declaration.h mangle.c
-#module.obj : $(TOTALH) mars.h $C\html.h module.h module.c
-opover.obj : $(TOTALH) expression.h opover.c
-optimize.obj : $(TOTALH) expression.h optimize.c
-parse.obj : $(TOTALH) attrib.h lexer.h parse.h parse.c
-scope.obj : $(TOTALH) scope.h scope.c
-statement.obj : $(TOTALH) statement.h statement.c
-staticassert.obj : $(TOTALH) staticassert.h staticassert.c
-struct.obj : $(TOTALH) identifier.h enum.h struct.c
-traits.obj : $(TOTALH) traits.c
-dsymbol.obj : $(TOTALH) identifier.h dsymbol.h dsymbol.c
-mtype.obj : $(TOTALH) mtype.h mtype.c
-#typinf.obj : $(TOTALH) mtype.h typinf.c
-utf.obj : utf.h utf.c
-template.obj : $(TOTALH) template.h template.c
-version.obj : $(TOTALH) identifier.h dsymbol.h cond.h version.h version.c
-
-################### Utilities ################
-
-clean:
-	del *.obj
-	del total.sym
-	del msgs.h msgs.c
-	del elxxx.c cdxxx.c optab.c debtab.c fltables.c tytab.c
-	del impcnvtab.c
-
-zip : $(MAKEFILES)
-	del dmdsrc.zip
-	zip32 dmdsrc $(MAKEFILES)
-	zip32 dmdsrc $(SRCS)
-	zip32 dmdsrc $(BACKSRC)
-	zip32 dmdsrc $(TKSRC)
-	zip32 dmdsrc $(ROOTSRC)
-
-################### Install ################
-
-install:
-	copy dmd.exe $(DIR)\windows\bin\ 
-	copy phobos\phobos.lib $(DIR)\windows\lib 
-	$(CP) $(SRCS) $(DIR)\src\dmd\ 
-	$(CP) $(ROOTSRC) $(DIR)\src\dmd\root\ 
-	$(CP) $(TKSRC) $(DIR)\src\dmd\tk\  
-	$(CP) $(BACKSRC) $(DIR)\src\dmd\backend\  
-	$(CP) $(MAKEFILES) $(DIR)\src\dmd\  
-	copy gpl.txt $(DIR)\src\dmd\ 
-	copy readme.txt $(DIR)\src\dmd\ 
-	copy artistic.txt $(DIR)\src\dmd\ 
-	copy backendlicense.txt $(DIR)\src\dmd\ 
-
-################### Write to SVN ################
-
-svn:
-	$(CP) $(SRCS) $(DMDSVN)\ 
-	$(CP) $(ROOTSRC) $(DMDSVN)\root\ 
-	$(CP) $(TKSRC) $(DMDSVN)\tk\  
-	$(CP) $(BACKSRC) $(DMDSVN)\backend\  
-	$(CP) $(MAKEFILES) $(DMDSVN)\  
-	copy gpl.txt $(DMDSVN)\ 
-	copy readme.txt $(DMDSVN)\ 
-	copy artistic.txt $(DMDSVN)\ 
-	copy backendlicense.txt $(DMDSVN)\ 
-
-###################################