Browse Source

Further embedded Type changes.

woollybah 8 years ago
parent
commit
71e95e987d
3 changed files with 3644 additions and 3617 deletions
  1. 5 3
      ctranslator.bmx
  2. 3634 3613
      decl.bmx
  3. 5 1
      expr.bmx

+ 5 - 3
ctranslator.bmx

@@ -4393,10 +4393,12 @@ End Rem
 		Local classid$=classDecl.munged
 		Local superid$=classDecl.superClass.actual.munged
 
-		Local newDecls:TFuncDeclList = TFuncDeclList(classdecl.FindDeclList("new", SCOPE_CLASS_LOCAL))
+		Local newDecls:TFuncDeclList = TFuncDeclList(classdecl.FindDeclList("new", True,,,True))
 		
 		For Local fdecl:TFuncDecl = EachIn newDecls
 		
+			MungDecl fdecl
+		
 			If fdecl.scope <> classDecl Then
 				fdecl.Clear()
 				EmitClassDeclNew(classDecl, fdecl)
@@ -4417,7 +4419,7 @@ End Rem
 		Local classid$=classDecl.munged
 		'Local superid$=classDecl.superClass.actual.munged
 
-		Local newDecls:TFuncDeclList = TFuncDeclList(classdecl.FindDeclList("new", SCOPE_CLASS_LOCAL))
+		Local newDecls:TFuncDeclList = TFuncDeclList(classdecl.FindDeclList("new", True,,,True))
 		
 		For Local fdecl:TFuncDecl = EachIn newDecls
 		
@@ -4447,7 +4449,7 @@ End Rem
 		If Not classDecl.IsStruct() Then
 			t :+ "_"
 		End If
-		
+
 		t :+ funcMunged + "_ObjectNew"
 
 		'Find decl we override

+ 3634 - 3613
decl.bmx

@@ -1,3615 +1,3636 @@
-' Copyright (c) 2013-2017 Bruce A Henderson
-'
-' Based on the public domain Monkey "trans" by Mark Sibly
-'
-' This software is provided 'as-is', without any express or implied
-' warranty. In no event will the authors be held liable for any damages
-' arising from the use of this software.
-'
-' Permission is granted to anyone to use this software for any purpose,
-' including commercial applications, and to alter it and redistribute it
-' freely, subject to the following restrictions:
-'
-'    1. The origin of this software must not be misrepresented; you must not
-'    claim that you wrote the original software. If you use this software
-'    in a product, an acknowledgment in the product documentation would be
-'    appreciated but is not required.
-'
-'    2. Altered source versions must be plainly marked as such, and must not be
-'    misrepresented as being the original software.
-'
-'    3. This notice may not be removed or altered from any source
-'    distribution.
-'
-
-Const DECL_EXTERN:Int=        $010000
-Const DECL_PRIVATE:Int=       $020000
-Const DECL_ABSTRACT:Int=      $040000
-Const DECL_FINAL:Int=         $080000
-
-Const DECL_SEMANTED:Int=      $100000
-Const DECL_SEMANTING:Int=     $200000
-Const DECL_CYCLIC:Int=       $8000000
-
-Const DECL_POINTER:Int=       $400000
-
-Const DECL_ARG:Int=           $800000
-Const DECL_INITONLY:Int=     $1000000
-
-Const DECL_NODEBUG:Int=      $2000000
-Const DECL_PROTECTED:Int=    $4000000
-
-Const DECL_API_CDECL:Int=   $00000000
-Const DECL_API_STDCALL:Int= $10000000
-Const DECL_API_DEFAULT:Int=DECL_API_CDECL
-
-Const DECL_NESTED:Int=      $20000000
-
-Const CLASS_INTERFACE:Int=    $002000
-Const CLASS_THROWABLE:Int=    $004000
-Const CLASS_STRUCT:Int=       $008000
-Const CLASS_GENERIC:Int=      $001000
-
-Const SCOPE_FUNC:Int = 0
-Const SCOPE_CLASS_LOCAL:Int = 1
-Const SCOPE_CLASS_HEIRARCHY:Int = 2
-Const SCOPE_MODULE:Int = 3
-Const SCOPE_ALL:Int = 4
-
-'Const CALL_CONV_CDECL:Int = 0
-'Const CALL_CONV_STDCALL:Int = 1
-'Const CALL_CONV_DEFAULT:Int = CALL_CONV_CDECL
-
-Global _env:TScopeDecl
-Global _envStack:TList=New TList
-
-Global _appInstance:TAppDecl
-
-Global _loopnest:Int
-
-Function PushEnv( env:TScopeDecl )
-	If _env _envStack.AddLast( _env )
-	_env=env
-End Function
-
-Function PopEnv()
-	_env=TScopeDecl( _envStack.RemoveLast() )
-End Function
-
-Type TFuncDeclList Extends TList
-	Field ident:String
-	Field _identLower:String
-	
-	Method IdentLower:String()
-		If Not _identLower Then
-			_identLower = ident.ToLower()
-		End If
-		Return _identLower
-	End Method
-End Type
-
-Type TMetadata
-
-	Field metadataString:String
-
-	' key/value pairs
-	Field meta:TMap
-
-	Method InsertMeta(key:String, value:String)
-		If Not meta Then
-			meta = New TMap
-		End If
-		
-		meta.Insert(key, value)
-	End Method
-
-	Method HasMeta:Int(key:String)
-		Return meta And meta.Contains(key.ToLower())
-	End Method
-	
-End Type
-
-Type TDecl
-	Field ident$
-	Field munged$
-	Field errInfo$
-	Field actual:TDecl
-	Field scope:TScopeDecl
-	Field attrs:Int
-	Field metadata:TMetadata = New TMetadata
-	
-	Field declImported:Int = False
-	Field generated:Int
-	
-	Field _identLower:String
-	
-	Method New()
-		errInfo=_errInfo
-		actual=Self
-	End Method
-	
-	Method OnCopy:TDecl(deep:Int = True) Abstract
-	
-	Method IdentLower:String()
-		If Not _identLower Then
-			_identLower = ident.ToLower()
-		End If
-		Return _identLower
-	End Method
-	
-	Method ToString$()
-		If TClassDecl( scope ) Return scope.ToString()+"."+ident
-		Return ident
-	End Method
-	
-	Method ToTypeString:String()
-	End Method
-	
-	Method IsExtern:Int()
-		Return (attrs & DECL_EXTERN)<>0
-	End Method
-	
-	Method IsFinal:Int()
-		Return (attrs & DECL_FINAL)<>0
-	End Method
-
-	Method IsPrivate:Int()
-		Return (attrs & DECL_PRIVATE)<>0
-	End Method
-
-	Method IsProtected:Int()
-		Return (attrs & DECL_PROTECTED)<>0
-	End Method
-	
-	Method IsPublic:Int()
-		Return Not (IsPrivate() Or IsProtected())
-	End Method
-	
-	Method IsAbstract:Int()
-		Return (attrs & DECL_ABSTRACT)<>0
-	End Method
-	
-	Method IsSemanted:Int()
-		Return (attrs & DECL_SEMANTED)<>0
-	End Method
-	
-	Method IsSemanting:Int()
-		Return (attrs & DECL_SEMANTING)<>0
-	End Method
-	
-	Method IsNoDebug:Int()
-		Return (attrs & DECL_NODEBUG)<>0
-	End Method
-	
-	Method FuncScope:TFuncDecl()
-		If TFuncDecl( Self ) Return TFuncDecl( Self )
-		If scope Return scope.FuncScope()
-	End Method
-
-	Method ClassScope:TClassDecl()
-		If TClassDecl( Self ) Return TClassDecl( Self )
-		If scope Return scope.ClassScope()
-	End Method
-	
-	Method ModuleScope:TModuleDecl()
-		If TModuleDecl( Self ) Return TModuleDecl( Self )
-		' "app" is a module container
-		If TAppDecl( Self ) Return TAppDecl( Self).mainModule
-		If scope Return scope.ModuleScope()
-	End Method
-	
-	Method AppScope:TAppDecl()
-		If TAppDecl( Self ) Return TAppDecl( Self )
-		If scope Return scope.AppScope()
-	End Method
-	
-	' find an owning scope of function, class or module
-	Method ParentScope:TScopeDecl()
-		If scope Then
-			' func scope
-			If TFuncDecl( scope ) Return TFuncDecl( scope )
-			' class scope
-			If TClassDecl( scope ) Return TClassDecl( scope )
-			' module scope
-			If TModuleDecl( scope ) Return TModuleDecl( scope )
-
-			Return scope.ParentScope()
-		End If
-	End Method
-	
-	Method CheckAccess:Int()
-		If IsPrivate() And ModuleScope()<>_env.ModuleScope() Return False
-		Return True
-	End Method
-	
-	Method AssertAccess()
-If ident="abc" DebugStop
-		If Not CheckAccess()
-			If IsPrivate() Then
-				Err ToString() +" is private."
-			Else
-				Err ToString() +" is protected."
-			End If
-		EndIf
-	End Method
-
-	Method Copy:TDecl(deep:Int = True)
-		Local t:TDecl=OnCopy(deep)
-		t.munged=munged
-		t.errInfo=errInfo
-		Return t
-	End Method
-
-	Method Semant()
-
-		If IsSemanted() Return
-
-		If IsSemanting() Then
-			If attrs & DECL_CYCLIC Then
-				Return
-			End If
-			Err "Cyclic declaration of '"+ident+"'."
-		End If
-		
-		If actual<>Self
-			actual.Semant
-		EndIf
-
-		PushErr errInfo
-		
-		If scope
-			PushEnv scope
-		EndIf
-		
-		attrs:|DECL_SEMANTING
-
-		'If ident And ClassScope() Print "Semanting "+ToString()
-
-		OnSemant
-		
-		attrs:&~DECL_SEMANTING
-
-		attrs:|DECL_SEMANTED
-
-		If scope 
-			'If Not IsExtern()
-			If TFuncDecl(Self) And attrs & FUNC_PTR
-				'DebugLog "**** " + ident
-			Else
-			
-				' a nested function/class needs to be scoped to another function, class or module.
-				If attrs & FUNC_NESTED Or attrs & DECL_NESTED Then
-					Local sc:TScopeDecl = ParentScope()
-					
-					' if our scope isn't one of the above, let it be so.
-					If sc <> scope Then
-						scope = Null
-						sc.InsertDecl(Self)
-					End If
-				End If
-
-				scope._semanted.AddLast Self
-				
-				If TGlobalDecl( Self )
-					' FIXME
-					If AppScope() Then
-						AppScope().semantedGlobals.AddLast TGlobalDecl( Self )
-					End If
-				EndIf
-				
-				If TModuleDecl( scope )
-					' FIXME
-					Local app:TAppDecl = AppScope()
-					If app Then
-						app._semanted.AddLast Self
-					End If
-				EndIf
-			
-			EndIf
-			
-			If TValDecl(Self) And TValDecl(Self).deferInit Then
-				TValDecl(Self).SemantInit
-			End If
-
-			PopEnv
-		Else
-			If TValDecl(Self) And TValDecl(Self).deferInit Then
-				TValDecl(Self).SemantInit
-			End If
-		EndIf
-		
-		
-		PopErr
-	End Method
-	
-	Method InitInstance:TDecl( decl:TDecl )
-		decl.ident=ident
-		decl.munged=munged
-		decl.errInfo=errInfo
-		decl.actual=actual
-		decl.scope=Null
-		decl.attrs=attrs & ~(DECL_SEMANTED|DECL_SEMANTING)
-		Return decl
-	End Method
-	
-	Method GenInstance:TDecl()
-		InternalErr
-	End Method
-	
-	Method OnSemant() Abstract
-	
-	Method Clear()
-	End Method
-
-End Type
-
-Type TValDecl Extends TDecl
-	'pre-semant
-	Field declTy:TType
-	Field declInit:TExpr
-	'post-semant
-	Field ty:TType
-	Field init:TExpr
-	
-	Field deferInit:Int = False
-	
-	Method ToString$()
-		Local t$=Super.ToString()
-		If ty Return t+":"+ty.ToString()
-		If declTy Return t+":"+declTy.ToString()
-		Return t+":?"
-	End Method
-
-	Method ToTypeString:String()
-		If ty Return ty.ToString()
-		If declTy Return declTy.ToString()
-	End Method
-
-	Method CopyInit:TExpr()
-		If init Return init.Copy()
-	End Method
-	
-	Method OnSemant()
-'DebugStop	
-		If declTy
-
-			Local at:TType = TArrayType(declTy)
-			
-			While TArrayType(at)
-				at = TArrayType(at).elemType
-			Wend
-		
-			' ensure to set the scope for a function pointer array before semanting
-			If TFunctionPtrType(at) Then
-				If Not TFunctionPtrType(at).func.scope Then
-					If scope Then
-						TFunctionPtrType(at).func.scope = scope
-					Else
-						TFunctionPtrType(at).func.scope = _env
-					End If
-				End If
-			End If
-
-			' pass the scope into the function ptr
-			If TFunctionPtrType(declTy) Then
-				If Not TFunctionPtrType(declTy).func.scope Then
-					If scope Then
-						TFunctionPtrType(declTy).func.scope = scope
-					Else
-						TFunctionPtrType(declTy).func.scope = _env
-					End If
-				End If
-			End If
-			
-			ty=declTy.Semant()
-
-			If Not deferInit Then
-				SemantInit()
-			End If
-			
-		Else If declInit
-			If Not deferInit Then
-				SemantInit()
-			End If
-		Else
-			InternalErr
-		EndIf
-		
-	End Method
-	
-	Method SemantInit()
-		' for field initialisation, create a stub New() method to use as current scope
-		' since fields are initialised in New(). Otherwise the scope would be "class", which is
-		' incorrect for processing field inits.
-		If TFieldDecl(Self) And declInit Then
-			Local newScope:TFuncDecl = New TFuncDecl.CreateF( "new", Null,Null,FUNC_METHOD )
-			newScope.scope = _env
-			PushEnv(newScope)
-		End If
-	
-		If declTy
-			If declInit Then
-				If TFunctionPtrType(ty) Then
-					
-					Local expr:TExpr
-					
-					If TInvokeExpr(declInit) Then
-						expr = declInit.Copy()
-					Else If TConstExpr(declInit) Then
-						expr = declInit.Copy().Semant()
-					Else If TFuncCallExpr(declInit) Then
-						expr=declInit.Copy().Semant()
-					Else If TNullExpr(declInit) Then
-						expr = declInit
-					Else
-						' declInit can only be an expression, never a statement
-						' this means that any function call in there is required to have parentheses, and will
-						' thus appear in the form of a TFuncCallExpr
-						' as such, trying SemantFunc in the Else branch seems pointless and will in fact wrongly
-						' interpret function pointers (as TIdentExpr, TIndexExpr, possibly others?) as calls
-						Rem
-						Local argExpr:TExpr[] = New TExpr[0]
-
-						For Local arg:TArgDecl = EachIn TFunctionPtrType(ty).func.argDecls
-							Local ldecl:TLocalDecl = New TLocalDecl.Create(arg.ident, arg.declTy, Null, 0)
-							ldecl.Semant()
-							Local aexp:TVarExpr = New TVarExpr.Create(ldecl)
-							'Local aexp:TIdentTypeExpr = New TIdentTypeExpr.Create(arg.declTy)
-							aexp.Semant()
-							argExpr :+ [aexp]
-						Next
-
-						expr=declInit.Copy().SemantFunc(argExpr, False, False)
-						If Not expr Then
-							expr = declInit.Copy().Semant()
-						End If
-						End Rem
-						
-						expr = declInit.Copy().Semant()
-					End If
-					
-					If expr.exprType.EqualsType( ty ) Then
-						init = expr
-					Else
-						init = New TCastExpr.Create( ty,expr,CAST_EXPLICIT ).Semant()
-					End If
-					
-					
-				Else
-					If TArrayExpr(declInit) And TArrayType(ty) And TNumericType(TArrayType(ty).elemType) Then
-						TArrayExpr(declInit).toType = TArrayType(ty).elemType
-					End If
-				
-					init=declInit.Copy().SemantAndCast(ty)
-					
-					' check if struct has been initialised
-					If TObjectType(ty) And TObjectType(ty).classDecl.IsStruct() Then
-					
-						' new not used
-						If TConstExpr(init) And Not TConstExpr(init).value Then
-							
-							Local found:Int = False
-							' struct contains any objects?
-							For Local fld:TFieldDecl = EachIn TObjectType(ty).classDecl._decls
-								If Not fld.IsSemanted() Then
-									fld.Semant()
-								End If
-							
-								If TObjectType(fld.ty) Or TStringType(fld.ty) Or TArrayType(fld.ty) Then
-									found = True
-									Exit
-								End If
-							Next
-						
-							' we need to initialise object fields, so we'll call the default constructor
-							If found Then
-								init = New TNewObjectExpr.Create(ty, Null).Semant()
-							End If
-						End If
-					End If
-				End If
-			End If
-		Else If declInit
-			init=declInit.Copy().Semant()
-			ty=init.exprType
-		End If
-		
-		If init Then
-			If TVarExpr(init) And TVarExpr(init).decl = Self Then
-				Err "Identifier '" + TVarExpr(init).decl.ident + "' not found."
-			End If
-			
-			If TNewObjectExpr(init) And TVarExpr(TNewObjectExpr(init).instanceExpr) And TVarExpr(TNewObjectExpr(init).instanceExpr).decl = Self Then
-				Err "Identifier '" + Self.ident + "' not found."
-			End If
-		End If
-		
-		' remove the temporary scope
-		If TFieldDecl(Self) And declInit Then
-			PopEnv()
-		End If
-	End Method
-	
-	Method Clear()
-	End Method
-	
-End Type
-
-Type TConstDecl Extends TValDecl
-	Field value$
-	
-	Method Create:TConstDecl( ident$,ty:TType,init:TExpr,attrs:Int )
-		Self.ident=ident
-		Self.munged=ident
-		Self.declTy=ty
-		Self.declInit=init
-		Self.attrs=attrs
-		Return Self
-	End Method
-
-	Method GenInstance:TDecl()
-		Local inst:TConstDecl = New TConstDecl
-		InitInstance inst
-		inst.declTy=declTy
-		inst.declInit=declInit
-		Return inst
-	End Method
-
-	Method OnCopy:TDecl(deep:Int = True)
-		Return New TConstDecl.Create( ident,ty,CopyInit(), attrs )
-	End Method
-	
-	Method OnSemant()
-		Super.OnSemant()
-		'If Not IsExtern() value=init.Eval()
-		If init Then
-			value=init.Eval()
-			If TStringType(ty) And Not _appInstance.hasStringConst(value) Then
-				_appInstance.mapStringConsts(value)
-			End If
-		End If
-	End Method
-	
-	Method ToString$()
-		Return "Const "+Super.ToString()
-	End Method
-
-End Type
-
-Type TVarDecl Extends TValDecl
-
-End Type
-
-Type TLocalDecl Extends TVarDecl
-
-	Field done:Int
-	Field volatile:Int = True
-
-	Method Create:TLocalDecl( ident$,ty:TType,init:TExpr,attrs:Int=0, generated:Int = False, volatile:Int = True )
-		Self.ident=ident
-		Self.declTy=ty
-		Self.declInit=init
-		Self.attrs=attrs
-		Self.generated=generated
-		Self.volatile=volatile
-		Return Self
-	End Method
-	
-	Method OnCopy:TDecl(deep:Int = True)
-		Local decl:TLocalDecl = New TLocalDecl.Create( ident,declTy,declInit,attrs &~ DECL_SEMANTED, generated, volatile )
-		decl.scope = scope
-		decl.ty = ty
-		decl.init = init
-		Return decl
-	End Method
-
-	Method GetDeclPrefix:String()
-		Return "Local "
-	End Method
-	
-	Method ToString$()
-		Return GetDeclPrefix() + Super.ToString()
-	End Method
-
-	Method Clear()
-		done = False
-	End Method
-
-End Type
-
-Type TArgDecl Extends TLocalDecl
-
-	Field castTo:String
-	
-	Method Create:TArgDecl( ident$,ty:TType,init:TExpr,attrs:Int=0, generated:Int = False, volatile:Int = True )
-		Self.ident=ident
-		Self.declTy=ty
-		Self.declInit=init
-		Self.attrs=attrs
-		Self.generated=generated
-		Self.volatile=volatile
-		Return Self
-	End Method
-	
-	Method GenInstance:TDecl()
-		Local inst:TArgDecl=New TArgDecl
-		InitInstance inst
-		inst.declTy=declTy
-		inst.declInit=declInit
-		Return inst
-	End Method
-	
-	Method OnCopy:TDecl(deep:Int = True)
-		Local d:TArgDecl = New TArgDecl.Create( ident,declTy,declInit,attrs,generated,volatile )
-		d.ty = ty
-		d.init = init
-		Return d
-	End Method
-
-	Method GetDeclPrefix:String()
-		Return ""
-	End Method
-	
-	Method ToString$()
-		Return Super.ToString()
-	End Method
-	
-End Type
-
-Type TGlobalDecl Extends TVarDecl
-
-	Field inited:Int
-	Field funcGlobal:Int
-	
-	Method Create:TGlobalDecl( ident$,ty:TType,init:TExpr,attrs:Int=0,funcGlobal:Int=False )
-		Self.deferInit = True
-		Self.ident=ident
-		Self.declTy=ty
-		Self.declInit=init
-		Self.attrs=attrs
-		Self.funcGlobal=funcGlobal
-		Return Self
-	End Method
-
-	Method OnCopy:TDecl(deep:Int = True)
-		Local g:TGlobalDecl = New TGlobalDecl.Create( ident,declTy,declInit,attrs,funcGlobal )
-		g.ty = ty
-		g.init = init
-		Return g
-	End Method
-	
-	Method ToString$()
-		Return "Global "+Super.ToString()
-	End Method
-
-	Method GenInstance:TDecl()
-'		PushErr errInfo
-'		Err "Global variables cannot be used inside generic classes."
-		Local inst:TGlobalDecl=New TGlobalDecl
-		InitInstance inst
-		inst.declTy=declTy
-		inst.declInit=declInit
-		Return inst
-	End Method
-
-	Method CheckAccess:Int()
-		Local cd:TClassDecl = ClassScope()
-		If cd Then
-			If IsPrivate() And cd<>_env.ClassScope() Return False
-			If IsProtected() Then
-				Local ec:TClassDecl = _env.ClassScope()
-				If Not ec Return False
-				If Not ec.ExtendsClass(cd) Return False
-			End If
-			Return True
-		End If
-		Return Super.CheckAccess()
-	End Method
-
-End Type
-
-Type TFieldDecl Extends TVarDecl
-
-	' location offset in object variable data
-	Field offset:Int
-
-	Method Create:TFieldDecl( ident$,ty:TType,init:TExpr,attrs:Int=0 )
-		Self.ident=ident
-		Self.declTy=ty
-		Self.declInit=init
-		Self.attrs=attrs
-		Return Self
-	End Method
-
-	Method OnCopy:TDecl(deep:Int = True)
-		Local f:TFieldDecl = New TFieldDecl.Create( ident,declTy,declInit,attrs )
-		f.ty = ty
-		f.init = init
-		f.metadata = metadata
-		Return f
-	End Method
-	
-	Method ToString$()
-		Return "Field "+Super.ToString()
-	End Method
-	
-	Method GenInstance:TDecl()
-		Local inst:TFieldDecl=New TFieldDecl
-		InitInstance inst
-		inst.declTy=declTy
-		inst.declInit=declInit
-		Return inst
-	End Method
-
-	Method CheckAccess:Int()
-
-		Local cs:TClassDecl = ClassScope()
-
-		If IsPrivate() And cs Then
-			Local ec:TClassDecl = _env.ClassScope()
-
-			While ec
-
-				If cs = ec Then
-					Return True
-				End If
-				
+' Copyright (c) 2013-2017 Bruce A Henderson
+'
+' Based on the public domain Monkey "trans" by Mark Sibly
+'
+' This software is provided 'as-is', without any express or implied
+' warranty. In no event will the authors be held liable for any damages
+' arising from the use of this software.
+'
+' Permission is granted to anyone to use this software for any purpose,
+' including commercial applications, and to alter it and redistribute it
+' freely, subject to the following restrictions:
+'
+'    1. The origin of this software must not be misrepresented; you must not
+'    claim that you wrote the original software. If you use this software
+'    in a product, an acknowledgment in the product documentation would be
+'    appreciated but is not required.
+'
+'    2. Altered source versions must be plainly marked as such, and must not be
+'    misrepresented as being the original software.
+'
+'    3. This notice may not be removed or altered from any source
+'    distribution.
+'
+
+Const DECL_EXTERN:Int=        $010000
+Const DECL_PRIVATE:Int=       $020000
+Const DECL_ABSTRACT:Int=      $040000
+Const DECL_FINAL:Int=         $080000
+
+Const DECL_SEMANTED:Int=      $100000
+Const DECL_SEMANTING:Int=     $200000
+Const DECL_CYCLIC:Int=       $8000000
+
+Const DECL_POINTER:Int=       $400000
+
+Const DECL_ARG:Int=           $800000
+Const DECL_INITONLY:Int=     $1000000
+
+Const DECL_NODEBUG:Int=      $2000000
+Const DECL_PROTECTED:Int=    $4000000
+
+Const DECL_API_CDECL:Int=   $00000000
+Const DECL_API_STDCALL:Int= $10000000
+Const DECL_API_DEFAULT:Int=DECL_API_CDECL
+
+Const DECL_NESTED:Int=      $20000000
+
+Const CLASS_INTERFACE:Int=    $002000
+Const CLASS_THROWABLE:Int=    $004000
+Const CLASS_STRUCT:Int=       $008000
+Const CLASS_GENERIC:Int=      $001000
+
+Const SCOPE_FUNC:Int = 0
+Const SCOPE_CLASS_LOCAL:Int = 1
+Const SCOPE_CLASS_HEIRARCHY:Int = 2
+Const SCOPE_MODULE:Int = 3
+Const SCOPE_ALL:Int = 4
+
+'Const CALL_CONV_CDECL:Int = 0
+'Const CALL_CONV_STDCALL:Int = 1
+'Const CALL_CONV_DEFAULT:Int = CALL_CONV_CDECL
+
+Global _env:TScopeDecl
+Global _envStack:TList=New TList
+
+Global _appInstance:TAppDecl
+
+Global _loopnest:Int
+
+Function PushEnv( env:TScopeDecl )
+	If _env _envStack.AddLast( _env )
+	_env=env
+End Function
+
+Function PopEnv()
+	_env=TScopeDecl( _envStack.RemoveLast() )
+End Function
+
+Type TFuncDeclList Extends TList
+	Field ident:String
+	Field _identLower:String
+	
+	Method IdentLower:String()
+		If Not _identLower Then
+			_identLower = ident.ToLower()
+		End If
+		Return _identLower
+	End Method
+End Type
+
+Type TMetadata
+
+	Field metadataString:String
+
+	' key/value pairs
+	Field meta:TMap
+
+	Method InsertMeta(key:String, value:String)
+		If Not meta Then
+			meta = New TMap
+		End If
+		
+		meta.Insert(key, value)
+	End Method
+
+	Method HasMeta:Int(key:String)
+		Return meta And meta.Contains(key.ToLower())
+	End Method
+	
+End Type
+
+Type TDecl
+	Field ident$
+	Field munged$
+	Field errInfo$
+	Field actual:TDecl
+	Field scope:TScopeDecl
+	Field attrs:Int
+	Field metadata:TMetadata = New TMetadata
+	
+	Field declImported:Int = False
+	Field generated:Int
+	
+	Field _identLower:String
+	
+	Method New()
+		errInfo=_errInfo
+		actual=Self
+	End Method
+	
+	Method OnCopy:TDecl(deep:Int = True) Abstract
+	
+	Method IdentLower:String()
+		If Not _identLower Then
+			_identLower = ident.ToLower()
+		End If
+		Return _identLower
+	End Method
+	
+	Method ToString$()
+		If TClassDecl( scope ) Return scope.ToString()+"."+ident
+		Return ident
+	End Method
+	
+	Method ToTypeString:String()
+	End Method
+	
+	Method IsExtern:Int()
+		Return (attrs & DECL_EXTERN)<>0
+	End Method
+	
+	Method IsFinal:Int()
+		Return (attrs & DECL_FINAL)<>0
+	End Method
+
+	Method IsPrivate:Int()
+		Return (attrs & DECL_PRIVATE)<>0
+	End Method
+
+	Method IsProtected:Int()
+		Return (attrs & DECL_PROTECTED)<>0
+	End Method
+	
+	Method IsPublic:Int()
+		Return Not (IsPrivate() Or IsProtected())
+	End Method
+	
+	Method IsAbstract:Int()
+		Return (attrs & DECL_ABSTRACT)<>0
+	End Method
+	
+	Method IsSemanted:Int()
+		Return (attrs & DECL_SEMANTED)<>0
+	End Method
+	
+	Method IsSemanting:Int()
+		Return (attrs & DECL_SEMANTING)<>0
+	End Method
+	
+	Method IsNoDebug:Int()
+		Return (attrs & DECL_NODEBUG)<>0
+	End Method
+	
+	Method FuncScope:TFuncDecl()
+		If TFuncDecl( Self ) Return TFuncDecl( Self )
+		If scope Return scope.FuncScope()
+	End Method
+
+	Method ClassScope:TClassDecl()
+		If TClassDecl( Self ) Return TClassDecl( Self )
+		If scope Return scope.ClassScope()
+	End Method
+	
+	Method ModuleScope:TModuleDecl()
+		If TModuleDecl( Self ) Return TModuleDecl( Self )
+		' "app" is a module container
+		If TAppDecl( Self ) Return TAppDecl( Self).mainModule
+		If scope Return scope.ModuleScope()
+	End Method
+	
+	Method AppScope:TAppDecl()
+		If TAppDecl( Self ) Return TAppDecl( Self )
+		If scope Return scope.AppScope()
+	End Method
+	
+	' find an owning scope of function, class or module
+	Method ParentScope:TScopeDecl()
+		If scope Then
+			' func scope
+			If TFuncDecl( scope ) Return TFuncDecl( scope )
+			' class scope
+			If TClassDecl( scope ) Return TClassDecl( scope )
+			' module scope
+			If TModuleDecl( scope ) Return TModuleDecl( scope )
+
+			Return scope.ParentScope()
+		End If
+	End Method
+	
+	Method CheckAccess:Int()
+		If IsPrivate() And ModuleScope()<>_env.ModuleScope() Return False
+		Return True
+	End Method
+	
+	Method AssertAccess()
+If ident="abc" DebugStop
+		If Not CheckAccess()
+			If IsPrivate() Then
+				Err ToString() +" is private."
+			Else
+				Err ToString() +" is protected."
+			End If
+		EndIf
+	End Method
+
+	Method Copy:TDecl(deep:Int = True)
+		Local t:TDecl=OnCopy(deep)
+		t.munged=munged
+		t.errInfo=errInfo
+		Return t
+	End Method
+
+	Method Semant()
+
+		If IsSemanted() Return
+
+		If IsSemanting() Then
+			If attrs & DECL_CYCLIC Then
+				Return
+			End If
+			Err "Cyclic declaration of '"+ident+"'."
+		End If
+		
+		If actual<>Self
+			actual.Semant
+		EndIf
+
+		PushErr errInfo
+		
+		If scope
+			PushEnv scope
+		EndIf
+		
+		attrs:|DECL_SEMANTING
+
+		'If ident And ClassScope() Print "Semanting "+ToString()
+
+		OnSemant
+		
+		attrs:&~DECL_SEMANTING
+
+		attrs:|DECL_SEMANTED
+
+		If scope 
+			'If Not IsExtern()
+			If TFuncDecl(Self) And attrs & FUNC_PTR
+				'DebugLog "**** " + ident
+			Else
+			
+				' a nested function/class needs to be scoped to another function, class or module.
+				If attrs & FUNC_NESTED Or attrs & DECL_NESTED Then
+					Local sc:TScopeDecl = ParentScope()
+					
+					' if our scope isn't one of the above, let it be so.
+					If sc <> scope Then
+						scope = Null
+						sc.InsertDecl(Self)
+					End If
+				End If
+
+				scope._semanted.AddLast Self
+				
+				If TGlobalDecl( Self )
+					' FIXME
+					If AppScope() Then
+						AppScope().semantedGlobals.AddLast TGlobalDecl( Self )
+					End If
+				EndIf
+				
+				If TModuleDecl( scope )
+					' FIXME
+					Local app:TAppDecl = AppScope()
+					If app Then
+						app._semanted.AddLast Self
+					End If
+				EndIf
+			
+			EndIf
+			
+			If TValDecl(Self) And TValDecl(Self).deferInit Then
+				TValDecl(Self).SemantInit
+			End If
+
+			PopEnv
+		Else
+			If TValDecl(Self) And TValDecl(Self).deferInit Then
+				TValDecl(Self).SemantInit
+			End If
+		EndIf
+		
+		
+		PopErr
+	End Method
+	
+	Method InitInstance:TDecl( decl:TDecl )
+		decl.ident=ident
+		decl.munged=munged
+		decl.errInfo=errInfo
+		decl.actual=actual
+		decl.scope=Null
+		decl.attrs=attrs & ~(DECL_SEMANTED|DECL_SEMANTING)
+		Return decl
+	End Method
+	
+	Method GenInstance:TDecl()
+		InternalErr
+	End Method
+	
+	Method OnSemant() Abstract
+	
+	Method Clear()
+	End Method
+
+End Type
+
+Type TValDecl Extends TDecl
+	'pre-semant
+	Field declTy:TType
+	Field declInit:TExpr
+	'post-semant
+	Field ty:TType
+	Field init:TExpr
+	
+	Field deferInit:Int = False
+	
+	Method ToString$()
+		Local t$=Super.ToString()
+		If ty Return t+":"+ty.ToString()
+		If declTy Return t+":"+declTy.ToString()
+		Return t+":?"
+	End Method
+
+	Method ToTypeString:String()
+		If ty Return ty.ToString()
+		If declTy Return declTy.ToString()
+	End Method
+
+	Method CopyInit:TExpr()
+		If init Return init.Copy()
+	End Method
+	
+	Method OnSemant()
+'DebugStop	
+		If declTy
+
+			Local at:TType = TArrayType(declTy)
+			
+			While TArrayType(at)
+				at = TArrayType(at).elemType
+			Wend
+		
+			' ensure to set the scope for a function pointer array before semanting
+			If TFunctionPtrType(at) Then
+				If Not TFunctionPtrType(at).func.scope Then
+					If scope Then
+						TFunctionPtrType(at).func.scope = scope
+					Else
+						TFunctionPtrType(at).func.scope = _env
+					End If
+				End If
+			End If
+
+			' pass the scope into the function ptr
+			If TFunctionPtrType(declTy) Then
+				If Not TFunctionPtrType(declTy).func.scope Then
+					If scope Then
+						TFunctionPtrType(declTy).func.scope = scope
+					Else
+						TFunctionPtrType(declTy).func.scope = _env
+					End If
+				End If
+			End If
+			
+			ty=declTy.Semant()
+
+			If Not deferInit Then
+				SemantInit()
+			End If
+			
+		Else If declInit
+			If Not deferInit Then
+				SemantInit()
+			End If
+		Else
+			InternalErr
+		EndIf
+		
+	End Method
+	
+	Method SemantInit()
+		' for field initialisation, create a stub New() method to use as current scope
+		' since fields are initialised in New(). Otherwise the scope would be "class", which is
+		' incorrect for processing field inits.
+		If TFieldDecl(Self) And declInit Then
+			Local newScope:TFuncDecl = New TFuncDecl.CreateF( "new", Null,Null,FUNC_METHOD )
+			newScope.scope = _env
+			PushEnv(newScope)
+		End If
+	
+		If declTy
+			If declInit Then
+				If TFunctionPtrType(ty) Then
+					
+					Local expr:TExpr
+					
+					If TInvokeExpr(declInit) Then
+						expr = declInit.Copy()
+					Else If TConstExpr(declInit) Then
+						expr = declInit.Copy().Semant()
+					Else If TFuncCallExpr(declInit) Then
+						expr=declInit.Copy().Semant()
+					Else If TNullExpr(declInit) Then
+						expr = declInit
+					Else
+						' declInit can only be an expression, never a statement
+						' this means that any function call in there is required to have parentheses, and will
+						' thus appear in the form of a TFuncCallExpr
+						' as such, trying SemantFunc in the Else branch seems pointless and will in fact wrongly
+						' interpret function pointers (as TIdentExpr, TIndexExpr, possibly others?) as calls
+						Rem
+						Local argExpr:TExpr[] = New TExpr[0]
+
+						For Local arg:TArgDecl = EachIn TFunctionPtrType(ty).func.argDecls
+							Local ldecl:TLocalDecl = New TLocalDecl.Create(arg.ident, arg.declTy, Null, 0)
+							ldecl.Semant()
+							Local aexp:TVarExpr = New TVarExpr.Create(ldecl)
+							'Local aexp:TIdentTypeExpr = New TIdentTypeExpr.Create(arg.declTy)
+							aexp.Semant()
+							argExpr :+ [aexp]
+						Next
+
+						expr=declInit.Copy().SemantFunc(argExpr, False, False)
+						If Not expr Then
+							expr = declInit.Copy().Semant()
+						End If
+						End Rem
+						
+						expr = declInit.Copy().Semant()
+					End If
+					
+					If expr.exprType.EqualsType( ty ) Then
+						init = expr
+					Else
+						init = New TCastExpr.Create( ty,expr,CAST_EXPLICIT ).Semant()
+					End If
+					
+					
+				Else
+					If TArrayExpr(declInit) And TArrayType(ty) And TNumericType(TArrayType(ty).elemType) Then
+						TArrayExpr(declInit).toType = TArrayType(ty).elemType
+					End If
+				
+					init=declInit.Copy().SemantAndCast(ty)
+					
+					' check if struct has been initialised
+					If TObjectType(ty) And TObjectType(ty).classDecl.IsStruct() Then
+					
+						' new not used
+						If TConstExpr(init) And Not TConstExpr(init).value Then
+							
+							Local found:Int = False
+							' struct contains any objects?
+							For Local fld:TFieldDecl = EachIn TObjectType(ty).classDecl._decls
+								If Not fld.IsSemanted() Then
+									fld.Semant()
+								End If
+							
+								If TObjectType(fld.ty) Or TStringType(fld.ty) Or TArrayType(fld.ty) Then
+									found = True
+									Exit
+								End If
+							Next
+						
+							' we need to initialise object fields, so we'll call the default constructor
+							If found Then
+								init = New TNewObjectExpr.Create(ty, Null).Semant()
+							End If
+						End If
+					End If
+				End If
+			End If
+		Else If declInit
+			init=declInit.Copy().Semant()
+			ty=init.exprType
+		End If
+		
+		If init Then
+			If TVarExpr(init) And TVarExpr(init).decl = Self Then
+				Err "Identifier '" + TVarExpr(init).decl.ident + "' not found."
+			End If
+			
+			If TNewObjectExpr(init) And TVarExpr(TNewObjectExpr(init).instanceExpr) And TVarExpr(TNewObjectExpr(init).instanceExpr).decl = Self Then
+				Err "Identifier '" + Self.ident + "' not found."
+			End If
+		End If
+		
+		' remove the temporary scope
+		If TFieldDecl(Self) And declInit Then
+			PopEnv()
+		End If
+	End Method
+	
+	Method Clear()
+	End Method
+	
+End Type
+
+Type TConstDecl Extends TValDecl
+	Field value$
+	
+	Method Create:TConstDecl( ident$,ty:TType,init:TExpr,attrs:Int )
+		Self.ident=ident
+		Self.munged=ident
+		Self.declTy=ty
+		Self.declInit=init
+		Self.attrs=attrs
+		Return Self
+	End Method
+
+	Method GenInstance:TDecl()
+		Local inst:TConstDecl = New TConstDecl
+		InitInstance inst
+		inst.declTy=declTy
+		inst.declInit=declInit
+		Return inst
+	End Method
+
+	Method OnCopy:TDecl(deep:Int = True)
+		Return New TConstDecl.Create( ident,ty,CopyInit(), attrs )
+	End Method
+	
+	Method OnSemant()
+		Super.OnSemant()
+		'If Not IsExtern() value=init.Eval()
+		If init Then
+			value=init.Eval()
+			If TStringType(ty) And Not _appInstance.hasStringConst(value) Then
+				_appInstance.mapStringConsts(value)
+			End If
+		End If
+	End Method
+	
+	Method ToString$()
+		Return "Const "+Super.ToString()
+	End Method
+
+End Type
+
+Type TVarDecl Extends TValDecl
+
+End Type
+
+Type TLocalDecl Extends TVarDecl
+
+	Field done:Int
+	Field volatile:Int = True
+
+	Method Create:TLocalDecl( ident$,ty:TType,init:TExpr,attrs:Int=0, generated:Int = False, volatile:Int = True )
+		Self.ident=ident
+		Self.declTy=ty
+		Self.declInit=init
+		Self.attrs=attrs
+		Self.generated=generated
+		Self.volatile=volatile
+		Return Self
+	End Method
+	
+	Method OnCopy:TDecl(deep:Int = True)
+		Local decl:TLocalDecl = New TLocalDecl.Create( ident,declTy,declInit,attrs &~ DECL_SEMANTED, generated, volatile )
+		decl.scope = scope
+		decl.ty = ty
+		decl.init = init
+		Return decl
+	End Method
+
+	Method GetDeclPrefix:String()
+		Return "Local "
+	End Method
+	
+	Method ToString$()
+		Return GetDeclPrefix() + Super.ToString()
+	End Method
+
+	Method Clear()
+		done = False
+	End Method
+
+End Type
+
+Type TArgDecl Extends TLocalDecl
+
+	Field castTo:String
+	
+	Method Create:TArgDecl( ident$,ty:TType,init:TExpr,attrs:Int=0, generated:Int = False, volatile:Int = True )
+		Self.ident=ident
+		Self.declTy=ty
+		Self.declInit=init
+		Self.attrs=attrs
+		Self.generated=generated
+		Self.volatile=volatile
+		Return Self
+	End Method
+	
+	Method GenInstance:TDecl()
+		Local inst:TArgDecl=New TArgDecl
+		InitInstance inst
+		inst.declTy=declTy
+		inst.declInit=declInit
+		Return inst
+	End Method
+	
+	Method OnCopy:TDecl(deep:Int = True)
+		Local d:TArgDecl = New TArgDecl.Create( ident,declTy,declInit,attrs,generated,volatile )
+		d.ty = ty
+		d.init = init
+		Return d
+	End Method
+
+	Method GetDeclPrefix:String()
+		Return ""
+	End Method
+	
+	Method ToString$()
+		Return Super.ToString()
+	End Method
+	
+End Type
+
+Type TGlobalDecl Extends TVarDecl
+
+	Field inited:Int
+	Field funcGlobal:Int
+	
+	Method Create:TGlobalDecl( ident$,ty:TType,init:TExpr,attrs:Int=0,funcGlobal:Int=False )
+		Self.deferInit = True
+		Self.ident=ident
+		Self.declTy=ty
+		Self.declInit=init
+		Self.attrs=attrs
+		Self.funcGlobal=funcGlobal
+		Return Self
+	End Method
+
+	Method OnCopy:TDecl(deep:Int = True)
+		Local g:TGlobalDecl = New TGlobalDecl.Create( ident,declTy,declInit,attrs,funcGlobal )
+		g.ty = ty
+		g.init = init
+		Return g
+	End Method
+	
+	Method ToString$()
+		Return "Global "+Super.ToString()
+	End Method
+
+	Method GenInstance:TDecl()
+'		PushErr errInfo
+'		Err "Global variables cannot be used inside generic classes."
+		Local inst:TGlobalDecl=New TGlobalDecl
+		InitInstance inst
+		inst.declTy=declTy
+		inst.declInit=declInit
+		Return inst
+	End Method
+
+	Method CheckAccess:Int()
+		Local cd:TClassDecl = ClassScope()
+		If cd Then
+			If IsPrivate() And cd<>_env.ClassScope() Return False
+			If IsProtected() Then
+				Local ec:TClassDecl = _env.ClassScope()
+				If Not ec Return False
+				If Not ec.ExtendsClass(cd) Return False
+			End If
+			Return True
+		End If
+		Return Super.CheckAccess()
+	End Method
+
+End Type
+
+Type TFieldDecl Extends TVarDecl
+
+	' location offset in object variable data
+	Field offset:Int
+
+	Method Create:TFieldDecl( ident$,ty:TType,init:TExpr,attrs:Int=0 )
+		Self.ident=ident
+		Self.declTy=ty
+		Self.declInit=init
+		Self.attrs=attrs
+		Return Self
+	End Method
+
+	Method OnCopy:TDecl(deep:Int = True)
+		Local f:TFieldDecl = New TFieldDecl.Create( ident,declTy,declInit,attrs )
+		f.ty = ty
+		f.init = init
+		f.metadata = metadata
+		Return f
+	End Method
+	
+	Method ToString$()
+		Return "Field "+Super.ToString()
+	End Method
+	
+	Method GenInstance:TDecl()
+		Local inst:TFieldDecl=New TFieldDecl
+		InitInstance inst
+		inst.declTy=declTy
+		inst.declInit=declInit
+		Return inst
+	End Method
+
+	Method CheckAccess:Int()
+
+		Local cs:TClassDecl = ClassScope()
+
+		If IsPrivate() And cs Then
+			Local ec:TClassDecl = _env.ClassScope()
+
+			While ec
+
+				If cs = ec Then
+					Return True
+				End If
+				
 				ec = ec.scope.ClassScope()
-			Wend
-			
-			If Not ec Then
-				Return False
-			End If
-		End If
-		If IsProtected() And cs Then
-			Local ec:TClassDecl = _env.ClassScope()
-			
-			While ec
-				If ec.ExtendsClass(cs) Then
-					Return True
-				End If
-				
+			Wend
+			
+			If Not ec Then
+				Return False
+			End If
+		End If
+		If IsProtected() And cs Then
+			Local ec:TClassDecl = _env.ClassScope()
+			
+			While ec
+				If ec.ExtendsClass(cs) Then
+					Return True
+				End If
+				
 				ec = ec.scope.ClassScope()
-			Wend
-			
-			If Not ec Then
-				Return False
-			End If
-		End If
-		Return True
-	End Method
-
-End Type
-
-Type TAliasDecl Extends TDecl
-
-	Field decl:Object
-	
-	Method Create:TAliasDecl( ident$,decl:Object,attrs:Int=0 )
-		Self.ident=ident
-		Self.decl=decl
-		Self.attrs=attrs
-		Return Self
-	End Method
-	
-	Method OnCopy:TDecl(deep:Int = True)
-		Return New TAliasDecl.Create( ident,decl,attrs )
-	End Method
-	
-	Method OnSemant()
-	End Method
-	
-	Method Clear()
-	End Method
-	
-End Type
-
-Type TScopeDecl Extends TDecl
-
-'Private
-
-	Field _decls:TList=New TList'<TDecl>
-	Field _semanted:TList=New TList'<TDecl>
-
-	Field declsMap:TMap=New TMap'<Object>
-
-'Public
-
-	Method OnCopy:TDecl(deep:Int = True)
-		InternalErr
-	End Method
-
-	Method Decls:TList()
-		Return _decls
-	End Method
-	
-	Method Semanted:TList()
-		Return _semanted
-	End Method
-	
-	Method FuncDecls:TList( id$="" )
-		Local fdecls:TList=New TList
-		For Local decl:TDecl=EachIn _decls
-			If id And decl.ident<>id Continue
-			Local fdecl:TFuncDecl=TFuncDecl( decl )
-			If fdecl fdecls.AddLast fdecl
-		Next
-		Return fdecls
-	End Method
-	
-	Method MethodDecls:TList( id$="" )
-		Local fdecls:TList=New TList
-		For Local decl:TDecl=EachIn _decls
-			If id And decl.ident<>id Continue
-			Local fdecl:TFuncDecl=TFuncDecl( decl )
-			If fdecl And fdecl.IsMethod() fdecls.AddLast fdecl
-		Next
-		Return fdecls
-	End Method
-	
-	Method SemantedFuncs:TList( id$="" )
-		Local fdecls:TList=New TList
-		For Local decl:TDecl=EachIn _semanted
-			If id And decl.ident<>id Continue
-			Local fdecl:TFuncDecl=TFuncDecl( decl )
-			If fdecl fdecls.AddLast fdecl
-		Next
-		Return fdecls
-	End Method
-	
-	Method SemantedMethods:TList( id$="" )
-		Local fdecls:TList=New TList
-		For Local decl:TDecl=EachIn _decls
-			If id And decl.ident<>id Continue
-			Local fdecl:TFuncDecl=TFuncDecl( decl )
-			If fdecl And fdecl.IsMethod()
-				If Not fdecl.IsSemanted() Then
-					fdecl.Semant()
-				End If
-				fdecls.AddLast fdecl
-			End If
-		Next
-		Return fdecls
-	End Method
-	
-	Method InsertDecl( decl:TDecl, isCopy:Int = False )
-
-		If decl.scope And Not (decl.attrs & DECL_INITONLY) And Not isCopy InternalErr
-		
-		'Local ident$=decl.ident
-		If Not decl.ident Return
-		
-		If Not decl.scope Or isCopy Then
-			decl.scope=Self
-		End If
-		_decls.AddLast decl
-
-		'Local _decls:TMap
-		Local tdecl_:Object=declsMap.ValueForKey( decl.IdentLower() )
-		
-		If TFuncDecl( decl )
-			Local funcs:TFuncDeclList=TFuncDeclList( tdecl_ )
-			If funcs Or Not tdecl_
-				If Not funcs
-					funcs=New TFuncDeclList
-					funcs.ident = decl.IdentLower()
-					declsMap.Insert decl.IdentLower(),funcs
-				EndIf
-
-				funcs.AddLast TFuncDecl( decl )
-				Return
-			Else
-				Err "Duplicate identifier '"+decl.ident+"'."
-			EndIf
-		Else If Not tdecl_
-			declsMap.Insert decl.IdentLower(),decl
-		Else
-			Err "Duplicate identifier '"+decl.ident+"'."
-		EndIf
-
-	End Method
-
-	Method InsertDecls( _decls:TList )
-		For Local decl:TDecl=EachIn _decls
-			InsertDecl decl
-		Next
-	End Method
-	
-	'This is overridden by TClassDecl and TModuleDecl
-	Method GetDecl:Object( ident$ )
-'DebugLog "GetDecl (" + Self.ident + ") : " + ident
-		Local decl:Object=Object(declsMap.ValueForKey( ident ))
-
-		If Not decl Then
-			If Self.IdentLower() = ident Then
-				' name matches but we are a "module", but not a *real* module..
-				' .. so we can't be looking for ourself
-				If TModuleDecl(Self) And Self.ident.Find(".") = - 1 Then
-					decl = Null
-				Else
-					decl = Self
-				End If
-			End If
-		End If
-		
-		If Not decl Return Null
-		
-		Local adecl:TAliasDecl=TAliasDecl( decl )
-		If Not adecl Return decl
-		
-		If adecl.CheckAccess() Return adecl.decl
-	End Method
-	
-
-	Method FindDecl:Object( ident$, override:Int = False )
-	
-		If Not override And _env<>Self Return GetDecl( ident )
-		
-		Local tscope:TScopeDecl=Self
-		While tscope
-			Local decl:Object=tscope.GetDecl( ident )
-			If decl Return decl
-			tscope=tscope.scope
-		Wend
-	End Method
-	
-	Method GetDeclList:Object( ident$, declList:TFuncDeclList = Null, maxSearchDepth:Int )
-
-		If Not declList Then
-			declList = New TFuncDeclList
-		End If
-
-		Local decl:Object=Object(declsMap.ValueForKey( ident ))
-
-		If Not decl Return Null
-
-		If TFuncDeclList(decl) Then
-			For Local fdecl:TFuncDecl = EachIn TFuncDeclList(decl)
-
-				If Not fdecl.IsSemanted() And Not fdecl.IsSemanting() Then
-					fdecl.Semant
-				End If
-				
-				Local found:Int
-				For Local func:TFuncDecl = EachIn declList
-					If func.equalsFunc(fdecl) Then
-						found = True
-						Exit
-'Else
-'Print func.ToString() + "  didn't match  " + fdecl.ToString()
-					End If
-				Next
-				
-				If Not found Then
-					declList.AddLast(fdecl)
-				End If
-			Next
-			
-			Return declList
-		End If		
-		
-		Return decl
-		
-	End Method
-	
-	' returns a list of all matching named decls in scope
-	Method FindDeclList:Object(ident:String, override:Int = False, declList:TFuncDeclList = Null, maxSearchDepth:Int = SCOPE_ALL )
-	
-		If Not declList Then
-			declList = New TFuncDeclList
-		End If
-	
-		If Not override And _env<>Self Return GetDeclList( ident, declList, maxSearchDepth )
-		
-		Local tscope:TScopeDecl=Self
-		While tscope
-			Local decl:Object=tscope.GetDeclList( ident, declList, maxSearchDepth )
-			'If decl And (Not TFuncDeclList(decl) And declList.IsEmpty()) Return decl
-			If decl Then
-				If TFuncDeclList(decl) Then
-					If TFuncDeclList(decl) <> declList Then
-						For Local d:TDecl = EachIn TFuncDeclList(decl)
-							declList.AddLast(d)
-						Next
-					End If
-				Else
-					declList.AddLast(decl)
-				End If
-			End If
-
-			' if scope is an interface, also check implemented/extended interfaces?
-			If TClassDecl(tscope) Then'And TClassDecl(tscope).IsInterface() Then
-				If TClassDecl(tscope).implments Then
-					For Local idecl:TScopeDecl = EachIn TClassDecl(tscope).implments
-						Local decl:Object=idecl.GetDeclList( ident, declList, maxSearchDepth )
-						If decl Then
-							If TFuncDeclList(decl) Then
-								If TFuncDeclList(decl) <> declList Then
-									For Local d:TDecl = EachIn TFuncDeclList(decl)
-										declList.AddLast(d)
-									Next
-								End If
-							Else
-								declList.AddLast(decl)
-							End If
-						End If
-					Next
-				End If 
-			End If
-			
-			tscope=tscope.scope
-			
-			If TClassDecl(tscope) And maxSearchDepth < SCOPE_CLASS_HEIRARCHY Then
-				Exit
-			Else If TModuleDecl(tscope) And maxSearchDepth < SCOPE_ALL Then
-				Exit
-			End If
-		Wend
-		
-		Return declList
-	End Method
-
-	
-
-'	Method FindDecl:Object( ident$, static:Int = False )
-'		Local decl:Object=GetDecl( ident )
-'		
-'		If Not static Or Not decl Then
-'			If decl Return decl
-'		Else
-'			If Not TFieldDecl(decl) And Not (TFuncDecl(decl) And TFuncDecl(decl).IsMethod()) Then
-'				Return decl
-'			End If
-'		End If
-'		If scope Return scope.FindDecl( ident, static )
-'	End Method
-	
-	Method FindValDecl:TValDecl( ident$, static:Int = False )
-		Local decl:TValDecl=TValDecl( FindDecl( ident ) )
-		
-		' we found a field but we don't have access to it?
-		If TFieldDecl(decl) And static Then
-			' see if there's another decl with the same name elsewhere that we may...
-			' field's scope.scope will be a module.
-			If decl.scope And decl.scope.scope Then
-				Local vDecl:TValDecl = TValDecl( decl.scope.scope.FindDecl( ident, True ) )
-				If vDecl Then
-					decl = vDecl
-				End If
-			End If
-		End If
-		
-		If Not decl Then
-			' try scope search
-			decl = TValDecl( FindDecl( ident, True ) )
-			
-			If Not decl Then
-				' didn't find it? Maybe it is in module local scope?
-				' issue arises when a global initialises with a local variable in the module scope.
-				Local fdecl:Object = FindDecl("__localmain", True)
-				If fdecl Then
-					If TFuncDecl(fdecl) Then
-						decl = TValDecl( TFuncDecl(fdecl).FindDecl( ident ) )
-					Else If TFuncDeclList(fdecl) Then
-						For Local func:TFuncDecl = EachIn TFuncDeclList(fdecl)
-							func.Semant()
-							decl = TValDecl( func.FindDecl( ident ) )
-							If decl Then
-								Exit
-							End If
-						Next
-					End If
-					
-					' a local variable from module local scope can't be seen outside of module local scope...
-					If TLocalDecl(decl) And static Then
-						decl = Null
-					End If
-				End If
-			End If
-		End If
-		If Not decl Return Null
-		decl.AssertAccess
-		decl.Semant
-		Return decl
-	End Method
-
-	Method FindType:TType( ident$,args:TType[] )
-'DebugLog Self.ident + "::FindType::" + ident
-		Local decl:Object=(GetDecl( ident ))
-		If decl Then
-			If TModuleDecl(decl) Then
-				decl = TModuleDecl(decl).GetDecl(ident)
-			End If
-			Local ty:TType=TType(decl)
-			If ty
-				If args.Length Err "Wrong number of type arguments"
-				Return ty
-			EndIf
-			Local cdecl:TClassDecl=TClassDecl( decl )
-			If cdecl
-				cdecl.AssertAccess
-				If Not cdecl.instanceof Then
-					cdecl=cdecl.GenClassInstance( args )
-					cdecl.Semant
-				End If
-				Return cdecl.objectType
-			EndIf
-		EndIf
-		If scope Return scope.FindType( ident,args )
-	End Method
-	
-	Method FindScopeDecl:TScopeDecl( ident$ )
-		Local decl:TScopeDecl=TScopeDecl( FindDecl( ident ) )
-		If Not decl Return Null
-		decl.AssertAccess
-		decl.Semant
-		Return decl
-	End Method
-Rem	
-	Method FindClassDecl:TClassDecl( ident$,args:TClassDecl[] = Null )
-		Local decl:TClassDecl=TClassDecl( GetDecl( ident ) )
-		If Not args Then
-			args = New TClassDecl[0]
-		End If
-		If Not decl
-			If scope Return scope.FindClassDecl( ident,args )
-			Return Null
-		EndIf
-		decl.AssertAccess
-		decl.Semant
-		Return decl.GenClassInstance( args )
-	End Method
-End Rem	
-	Method FindModuleDecl:TModuleDecl( ident$ )
-'DebugStop
-		Local decl:TModuleDecl=TModuleDecl( GetDecl( ident ) )
-		If Not decl
-			If scope Return scope.FindModuleDecl( ident )
-			Return Null
-		EndIf
-		decl.AssertAccess
-		
-		' only semant on "real" module
-		If Not decl.declImported Then
-			decl.Semant
-		End If
-		Return decl
-	End Method
-	
-	Method FindBestMatchForArgs:TFuncDecl(argExprs:TExpr[], matches:TList)
-
-		Local bestMatch:TFuncDecl = Null
-		Local totals:Int[] = New Int[matches.count()]
-		Local index:Int
-		
-		For Local func:TFuncDecl = EachIn matches
-
-			Local argDecls:TArgDecl[]=func.argDecls
-			
-			For Local i:Int=0 Until argDecls.Length
-	
-				If i<argExprs.Length And argExprs[i]
-				
-					Local declTy:TType=argDecls[i].ty
-					Local exprTy:TType=argExprs[i].exprType
-
-					If TFunctionPtrType(declTy) And TInvokeExpr(argExprs[i]) Then
-						If TFunctionPtrType(declTy).equalsDecl(TInvokeExpr(argExprs[i]).decl) Then
-							Continue
-						End If
-					End If
-
-					' not ideal - since the arg is configured as a Byte Ptr, we can't check that the function is of the correct type.
-					If IsPointerType(declTy, TType.T_BYTE) And TInvokeExpr(argExprs[i]) And TInvokeExpr(argExprs[i]).invokedWithBraces = 0 Then
-						Continue
-					End If
-					
-					If TFunctionPtrType(declTy) And IsPointerType(exprTy, TType.T_BYTE) Then
-						Continue
-					End If
-					
-					If exprTy.EqualsType( declTy ) Continue
-					
-					' not an exact match. increase distance...
-					totals[index] :+ exprTy.DistanceToType(declTy)
-					
-				End If
-				
-			Next
-			
-			index :+ 1
-
-		Next
-		
-		Local tot:Int = -1
-		index = 0
-		Local i:Int
-		For Local func:TFuncDecl = EachIn matches
-			If tot = -1 Or totals[i] < tot Then
-				tot = totals[i]
-				bestMatch = func
-			Else If tot = totals[i] Then
-				If bestMatch.IsMethod() And Not func.IsMethod() Then
-					' 
-				Else If Not bestMatch.IsMethod() And func.IsMethod() Then
-					bestMatch = func
-				Else If (bestMatch.scope <> func.scope) And (TClassDecl(bestMatch.scope).ExtendsClass(TClassDecl(func.scope))) Then
-					' match is in different level of class hierarchy
-					Exit
-				Else
-					' a tie?
-					Err "Unable to determine overload to use: "+ bestMatch.ToString()+" or "+func.ToString()+"."
-				End If
-			End If
-			i :+ 1
-		Next
-		
-		Return bestMatch
-		
-	End Method
-	
-	Method FindFuncDecl:TFuncDecl( ident$,argExprs:TExpr[] = Null,explicit:Int=False, isArg:Int = False, isIdentExpr:Int = False, throwOnNotMatched:Int = False, maxSearchDepth:Int )
-'DebugLog "FindFuncDecl : " + ident
-'If ident = "new" Then DebugStop
-		Local foundIdentMatch:Int
-		Local funcs:TFuncDeclList
-
-		' does ident exist?
-		Local f:Object = FindDeclList(ident, True,,maxSearchDepth)
-		If Not f Then Return Null
-		
-		funcs = TFuncDeclList( f )
-		Local fp:TFuncDecl
-		
-		' not a function list, test for a function ptr var
-		If Not funcs Or funcs.IsEmpty() Then
-
-			' we found a funcdecl
-			If TFuncDecl(f) Then
-				funcs = New TFuncDeclList
-				funcs.AddLast(f)
-			End If
-			
-			If TVarDecl(f) Then
-				If Not TVarDecl(f).IsSemanted() Then
-					TVarDecl(f).Semant()
-				End If
-				If TFunctionPtrType(TVarDecl(f).ty) Then
-					funcs = New TFuncDeclList
-					fp = TFunctionPtrType(TVarDecl(f).ty).func
-					If Not fp.scope Then
-						fp.scope = TVarDecl(f).scope
-					End If
-					If Not fp.ident Then
-						fp.ident = TVarDecl(f).ident
-					End If
-					funcs.AddLast fp
-				End If
-			End If
-		End If
-		' was neither... lets bug out
-		If Not funcs Return Null
-		
-'		If Not funcs Then Return Null
-		
-		For Local func:TDecl = EachIn funcs
-			If Not func.IsSemanting() Then
-				func.Semant()
-			End If
-		Next
-		
-		'Local f:TDecl = TDecl(findDecl(ident))
-		'If Not f Then Return Null
-		
-				
-			'Local func:TFuncDecl = TFuncDecl(f)
-'			If Not func Then
-'				If TVarDecl(f) Then
-'					If Not f.IsSemanted() Then
-'						f.Semant()
-'					End If
-'					If TFunctionPtrType(TVarDecl(f).ty) Then
-'						func = TFunctionPtrType(TVarDecl(f).ty).func
-'						If Not func.scope Then
-'							func.scope = f.scope
-'						End If
-'						If Not func.ident Then
-'							func.ident = f.ident
-'						End If
-'					End If
-'				End If
-'			End If
-'			If Not func Return Null
-	
-		If Not argExprs
-			argExprs = New TExpr[0]
-		End If
-	
-		'func.Semant()
-		
-		Local match:TFuncDecl,isexact:Int
-		Local _err$
-		Local errorDetails:String
-		Local matches:TList = New TList
-
-		Local noExtendString:Int = True
-		Local generateWarnings:Int = False
-
-		' double test for matches.
-		' * first time through we don't allow up-casting args to String
-		'    if we get a match on the first pass, we'll take it.
-		' * second iteration we allow up-casting numerics to string
-		' * third iteration is valid if opt_warnover is enabled
-		'    this will allow down-casting of numerics (eg. double->float)
-		'    warnings will be generated if this produces valid results.
-		' if after all that, there's no match, then we can fail it.
-		For Local n:Int = 0 Until 3
-		
-			If n > 1 Then
-				If Not opt_warnover Then
-					Continue
-				Else
-					generateWarnings = True
-				End If
-			End If
-		
-			errorDetails = ""
-		
-			If n Then
-				noExtendString = False
-			End If
-
-			For Local iDecl:TDecl = EachIn funcs
-			
-				Local func:TFuncDecl = TFuncDecl(iDecl)
-				
-				If Not func Then
-					If TVarDecl(iDecl) Then
-'						If Not TVarDecl(iDecl).IsSemanted() Then
-'							TVarDecl(f).Semant()
-'						End If
-						If TFunctionPtrType(TVarDecl(iDecl).ty) Then
-							'funcs = New TFuncDeclList
-							fp = TFunctionPtrType(TVarDecl(iDecl).ty).func
-							If Not fp.scope Then
-								fp.scope = TVarDecl(iDecl).scope
-							End If
-							If Not fp.ident Then
-								fp.ident = TVarDecl(iDecl).ident
-							End If
-							'funcs.AddLast fp
-							func = fp
-						End If
-					End If
-					
-					If Not func Then
-						Continue
-					End If
-				End If
-				
-	
-			'While True
-				If Not func.CheckAccess() Continue
-				
-				Local argDecls:TArgDecl[]=func.argDecls
-				
-				Local exact:Int=True
-				Local possible:Int=True
-				
-				foundIdentMatch = True
-
-				' we found a matching name - this is probably the one we mean...
-				If isArg Then
-					'match=func
-					matches.AddLast(func)
-					Exit
-				End If
-
-				If argExprs.Length>argDecls.Length
-					exact = False
-					Continue
-				End If
-
-				For Local i:Int=0 Until argDecls.Length
-	
-					If i<argExprs.Length And argExprs[i]
-					
-						Local arg:TExpr = argExprs[i]
-					
-						Local declTy:TType=argDecls[i].ty
-						Local exprTy:TType=arg.exprType
-						
-						Local widensTest:Int = True
-						
-						' for numeric constants, allow them to be auto-cast unless
-						If TConstExpr(arg) And IsNumericType(exprTy) And Not TConstExpr(arg).typeSpecific And TConstExpr(arg).CompatibleWithType(declTy) Then
-							widensTest = False
-						End If
-	
-						If TFunctionPtrType(declTy) And TInvokeExpr(arg) Then
-							If TFunctionPtrType(declTy).equalsDecl(TInvokeExpr(arg).decl) Continue
-						End If
-	
-						' not ideal - since the arg is configured as a Byte Ptr, we can't check that the function is of the correct type.
-						If IsPointerType(declTy, TType.T_BYTE) And TInvokeExpr(arg) And TInvokeExpr(arg).invokedWithBraces = 0 Then
-							Continue
-						End If
-						
-						If TFunctionPtrType(declTy) And IsPointerType(exprTy, TType.T_BYTE) Then
-							Continue
-						End If
-						
-						If exprTy.EqualsType( declTy ) Continue
-						
-						exact=False
-						
-						If Not generateWarnings Then
-							If Not explicit And exprTy.ExtendsType( declTy, noExtendString, widensTest ) Continue
-						Else
-							If Not explicit Then
-								' fails widen test
-								If Not exprTy.ExtendsType( declTy, noExtendString, True ) Then
-									' but passes non-widen test
-									If exprTy.ExtendsType( declTy, noExtendString, False ) Then
-										' generate a warning, and accept it
-										Warn "In call to " + func.ToString()+ ". Argument #"+(i+1)+" is ~q" + exprTy.ToString()+"~q but declaration is ~q"+declTy.ToString()+"~q. "
-										Continue
-									End If
-								Else
-									Continue
-								End If
-							End If
-						End If
-	
-						' make a more helpful error message
-						errorDetails :+ "Argument #"+(i+1)+" is ~q" + exprTy.ToString()+"~q but declaration is ~q"+declTy.ToString()+"~q. "
-
-					Else If Not argDecls[i].init
-	
-						If (func.attrs & FUNC_PTR) Or isIdentExpr Then
-							exact=False
-							Exit
-						End If
-	
-						' if this argument is missing and there isn't a default...
-						errorDetails :+  "Missing function parameter '" + argDecls[i].ident + "'"
-	
-					Else ' for case of argdecls having default args
-						exact=False
-						If Not explicit Exit
-					EndIf
-				
-					possible=False
-					Exit
-				Next
-				
-				If Not possible Continue
-				
-				If exact
-					If isexact
-						Err "Unable to determine overload to use: "+match.ToString()+" or "+func.ToString()+"."
-					Else
-						_err=""
-						'match=func
-						matches.AddLast(func)
-						isexact=True
-						Exit
-					EndIf
-				Else
-					If Not isexact
-						'If match 
-						'	_err="Unable to determine overload to use: "+match.ToString()+" or "+func.ToString()+"."
-						'Else
-							'match=func
-							matches.AddLast(func)
-						'EndIf
-					EndIf
-				EndIf
-				'Exit
-			Next
-			
-			If Not matches.IsEmpty() Then
-				Exit
-			End If
-			
-		Next
-		
-		If matches.Count() = 1 Then
-			match = TFuncDecl(matches.First())
-		Else
-			' find best match
-			match = FindBestMatchForArgs(argExprs, matches)
-		End If
-		
-		If Not isexact
-			If _err Err _err
-			If explicit Return Null
-		EndIf
-
-		' last try... maybe we are trying to use it as a function pointer? (no args)
-		If Not match Then
-			If argExprs Then
-				'match = func
-'				match.maybeFunctionPtr = True
-			End If
-		Else If Not argExprs Then
-			' if there are no args, the actual function may have none either... so we may still be trying to use it as a function pointer
-			match.maybeFunctionPtr = True
-		End If
-		
-		If Not match
-			Local t$
-			For Local i:Int=0 Until argExprs.Length
-				If t t:+","
-				If argExprs[i] t:+argExprs[i].exprType.ToString()
-			Next
-			If foundIdentMatch Then
-				If throwOnNotMatched Then
-					Throw "Unable to find overload for "+ident+"("+t+"). " + errorDetails
-				Else
-					Err "Unable to find overload for "+ident+"("+t+"). " + errorDetails
-				End If
-			Else
-				If throwOnNotMatched Then
-					Throw "Identifier '" + ident + "' not found."
-				Else
-					Err "Identifier '" + ident + "' not found."
-				End If
-			End If
-		EndIf
-		
-		match.AssertAccess
-
-		Return match
-	End Method
-
-	Method FindLoop:TStmt(ident:String = Null)
-
-		If TBlockDecl(Self) And TBlockDecl(Self).extra Then
-			Local loop:TLoopStmt = TLoopStmt(TBlockDecl(Self).extra)
-			If ident Then
-				If loop.loopLabel And loop.loopLabel.IdentLower() = ident Then
-					Return loop
-				End If
-			Else
-				Return loop
-			End If
-		End If
-
-		If TFuncDecl(scope) Or TModuleDecl(scope)
-			Return Null
-		End If
-		
-		If scope Return scope.FindLoop( ident )
-	End Method
-	
-	Method OnSemant()
-	End Method
-	
-	Method Clear()
-	End Method
-
-End Type
-
-Type TBlockDecl Extends TScopeDecl
-	Field stmts:TList=New TList
-	Field extra:Object
-	
-	Method Create:TBlockDecl( scope:TScopeDecl, generated:Int = False )
-		Self.scope=scope
-		Self.generated = generated
-		
-		attrs :| (scope.attrs & DECL_NODEBUG)
-		
-		Return Self
-	End Method
-	
-	Method AddStmt( stmt:TStmt )
-		stmts.AddLast stmt
-	End Method
-	
-	Method OnCopy:TDecl(deep:Int = True)
-		Local t:TBlockDecl=New TBlockDecl
-		t.scope = scope
-		If deep Then
-			For Local stmt:TStmt=EachIn stmts
-				t.AddStmt stmt.Copy( t )
-			Next
-		End If
-		t.extra = extra
-		t.generated = generated
-		Return t
-	End Method
-
-	Method OnSemant()
-		PushEnv Self
-		
-		' any nested functions?
-		For Local fdecl:TFuncDecl = EachIn _decls
-			fdecl.Semant
-		Next
-
-		' any nested classes?
-		For Local cdecl:TClassDecl = EachIn _decls
-			cdecl.Semant
-		Next
-		
-		For Local stmt:TStmt=EachIn stmts
-			stmt.Semant
-		Next
-		PopEnv
-	End Method
-
-	Method CopyBlock:TBlockDecl( scope:TScopeDecl )
-		Local t:TBlockDecl=TBlockDecl( Copy() )
-		t.scope=scope
-		Return t
-	End Method
-
-	Method Clear()
-		For Local stmt:TStmt=EachIn stmts
-			stmt.Clear
-		Next
-	End Method
-
-End Type
-
-Const FUNC_METHOD:Int=   $0001			'mutually exclusive with ctor
-Const FUNC_CTOR:Int=     $0002
-Const FUNC_PROPERTY:Int= $0004
-Const FUNC_DTOR:Int=     $0008
-Const FUNC_BUILTIN:Int = $0080
-Const FUNC_PTR:Int=      $0100
-Const FUNC_INIT:Int =    $0200
-Const FUNC_NESTED:Int =  $0400
-Const FUNC_OPERATOR:Int= $0800
-Const FUNC_FIELD:Int=    $1000
-
-'Fix! A func is NOT a block/scope!
-'
-Type TFuncDecl Extends TBlockDecl
-
-	Field retType:TType
-	Field retTypeExpr:TType
-	Field argDecls:TArgDecl[]
-
-	Field overrides:TFuncDecl
-	Field superCtor:TInvokeSuperExpr
-	
-	Field castTo:String
-	Field noCastGen:Int
-	
-	Field maybeFunctionPtr:Int
-	
-	Field returnTypeSubclassed:Int
-	
-	Field mangled:String
-	Field noMangle:Int
-	
-	Field equalsBuiltIn:Int = -1
-	
-	Method CreateF:TFuncDecl( ident$,ty:TType,argDecls:TArgDecl[],attrs:Int )
-		Self.ident=ident
-		Self.retTypeExpr=ty
-		If argDecls
-			Self.argDecls=argDecls
-		Else
-			Self.argDecls = New TArgDecl[0]
-		End If
-		Self.attrs=attrs
-		Return Self
-	End Method
-	
-	Method OnCopy:TDecl(deep:Int = True)
-		Local args:TArgDecl[]=argDecls[..]
-		For Local i:Int=0 Until args.Length
-			args[i]=TArgDecl( args[i].Copy() )
-		Next
-		Local t:TFuncDecl=New TFuncDecl.CreateF( ident,retType,args,attrs)
-		If deep Then
-			For Local stmt:TStmt=EachIn stmts
-				t.AddStmt stmt.Copy( t )
-			Next
-		End If
-		t.retType = retType
-		t.retTypeExpr = retTypeExpr
-		t.scope = scope
-		t.overrides = overrides
-		t.superCtor = superCtor
-		t.castTo = castTo
-		t.noCastGen = noCastGen
-		t.munged = munged
-		t.metadata = metadata
-		t.mangled = mangled
-		t.noMangle = noMangle
-		Return  t
-	End Method
-
-	Method GenInstance:TDecl()
-		Local inst:TFuncDecl=New TFuncDecl
-		InitInstance inst
-		inst.retTypeExpr=retTypeExpr
-		inst.argDecls=argDecls[..]
-		For Local i:Int=0 Until argDecls.Length
-			inst.argDecls[i]=TArgDecl( argDecls[i].GenInstance() )
-		Next
-		Return inst
-	End Method
-	
-	Method ToString$()
-		Local t$
-		For Local decl:TArgDecl=EachIn argDecls
-			If t t:+","
-			t:+decl.ToString()
-		Next
-		Local q$
-		If IsCtor()
-			q="Method "+Super.ToString()
-		Else
-			If IsMethod() q="Method " Else q="Function "
-			q:+Super.ToString()
-			If retType
-				If Not TVoidType(retType) Then
-					q:+":"+retType.ToString()
-				End If
-			Else If retTypeExpr 
-				q:+":"+retTypeExpr.ToString()
-			'Else
-			'	q:+":"+"?"
-			EndIf
-		EndIf
-		Return q+"("+t+")"
-	End Method
-
-	Method ToTypeString:String()
-		Local t$
-		For Local decl:TArgDecl=EachIn argDecls
-			If t t:+","
-			t:+decl.ToTypeString()
-		Next
-		Local q$
-		If Not IsCtor() Then
-			If retType
-				If Not TVoidType(retType) Then
-					q:+retType.ToString()
-				End If
-			Else If retTypeExpr 
-				q:+retTypeExpr.ToString()
-			EndIf
-		End If
-		Return q+"("+t+")"
-	End Method
-
-	Method IsBuiltIn:Int()
-		Return (attrs & FUNC_BUILTIN)<>0
-	End Method
-	
-	Method IsCtor:Int()
-		Return (attrs & FUNC_CTOR)<>0
-	End Method
-
-	Method IsDtor:Int()
-		Return (attrs & FUNC_DTOR)<>0
-	End Method
-
-	Method IsMethod:Int()
-		Return (attrs & FUNC_METHOD)<>0
-	End Method
-	
-	Method IsAnyMethod:Int()
-		Return IsMethod() Or IsCtor() Or IsDtor() 
-	End Method
-	
-	Method IsStatic:Int()
-		Return (attrs & (FUNC_METHOD|FUNC_CTOR))=0
-	End Method
-	
-	Method IsProperty:Int()
-		Return (attrs & FUNC_PROPERTY)<>0
-	End Method
-
-	Method IsField:Int()
-		Return (attrs & FUNC_FIELD)<>0
-	End Method
-		
-	Method EqualsArgs:Int( decl:TFuncDecl ) ' careful, this is not commutative!
-		If argDecls.Length<>decl.argDecls.Length Return False
-		For Local i:Int=0 Until argDecls.Length
-			' objects can be subclasses as well as the same.
-			If TObjectType(decl.argDecls[i].ty) Then
-				If Not decl.argDecls[i].ty.EqualsType( argDecls[i].ty ) And Not decl.argDecls[i].ty.ExtendsType( argDecls[i].ty ) Return False
-			Else
-				If Not decl.argDecls[i].ty.EqualsType( argDecls[i].ty ) Return False
-			End If
-		Next
-		Return True
-	End Method
-
-	Method EqualsFunc:Int( decl:TFuncDecl ) ' careful, this is not commutative!
-		If IsCtor() Then
-			Return EqualsArgs( decl )
-		Else
-			' matching args?
-			If EqualsArgs( decl ) Then
-				' matching return type?
-				If TObjectType(retType) Or TArrayType(retType) Or TStringType(retType) Then
-					Return retType.EqualsType( decl.retType ) Or retType.ExtendsType( decl.retType )' Or decl.retType.EqualsType( retType )) And EqualsArgs( decl )
-				Else
-					Return retType.EqualsType( decl.retType )
-				End If
-			End If
-		End If
-		Return False
-	End Method
-
-	Method OnSemant()
-
-		Local strictVoidToInt:Int = False
-
-		If isCtor() Or isDtor() Then
-			If ClassScope() And ClassScope().IsInterface() Then
-				Err ident + "() cannot be declared in an Interface."
-			End If
-		End If
-
-		'semant ret type
-		If Not retTypeExpr Then
-			If Not retType Then ' may have previously been set (if this is a function pointer)
-				retType = TType.voidType
-			Else If TIdentType(retType)
-				retType = retType.Semant()
-			Else
-				' for Strict code, a void return type becomes Int
-				If TVoidType(retType) And Not ModuleScope().IsSuperStrict() Then
-					strictVoidToInt = True
-					retType = New TIntType
-				End If
-			End If
-		Else
-			' pass the scope into the function ptr
-			Local retTypeExpr_:TType = retTypeExpr
-			While TArrayType(retTypeExpr_) ' look into array types, since the element type might be function ptr
-				retTypeExpr_ = TArrayType(retTypeExpr_).elemType
-			Wend
-			If TFunctionPtrType(retTypeExpr_) Then
-				If Not TFunctionPtrType(retTypeExpr_).func.scope Then
-					If scope Then
-						TFunctionPtrType(retTypeExpr_).func.scope = scope
-					Else
-						TFunctionPtrType(retTypeExpr_).func.scope = _env
-					End If
-				End If
-			End If
-		
-			retType=retTypeExpr.Semant()
-			
-			' for Strict code, a void return type becomes Int
-			If TVoidType(retType) And Not ModuleScope().IsSuperStrict() And Not IsDTor() Then
-				strictVoidToInt = True
-				retType = New TIntType
-			End If
-		End If
-		
-		If TArrayType( retType ) And Not retType.EqualsType( retType.ActualType() )
-'			Err "Return type cannot be an array of generic objects."
-		EndIf
-		
-		'semant args
-		For Local arg:TArgDecl=EachIn argDecls
-			InsertDecl arg
-			arg.Semant
-		Next
-
-		' if we are a function pointer declaration, we just want to semant the args here.
-		If attrs & FUNC_PTR Return
-
-		If actual<>Self Return
-		
-		'check for duplicate decl
-		If ident Then
-			For Local decl:TFuncDecl=EachIn scope.SemantedFuncs( ident )
-				If decl<>Self And EqualsArgs( decl ) And Not decl.IsCTOR()
-					Err "Duplicate declaration "+ToString()
-				EndIf
-				If noMangle Then
-					If decl<>Self Then
-						If decl.argDecls.Length = 0 Then
-							Err "You cannot apply NoMangle to the function, as another function with no arguments exists."
-						Else If decl.NoMangle Then
-							Err "Another function is already declared with NoMangle."
-						End If
-					End If
-				End If
-			Next
-		End If
-		
-		' any nested functions?
-		For Local fdecl:TFuncDecl = EachIn _decls
-			fdecl.Semant
-		Next
-		
-		'get cdecl, sclasss
-		Local cdecl:TClassDecl=ClassScope(),sclass:TClassDecl
-		If cdecl sclass=TClassDecl( cdecl.superClass )
-		
-		'prefix call to super ctor if necessary
-'		If IsCtor() And superCtor=Null And sclass
-'			If sclass.FindFuncDecl( "new", Null )
-'				superCtor=New TInvokeSuperExpr.Create( "new" )
-'				stmts.AddFirst New TExprStmt.Create( superCtor )
-'			EndIf
-'		EndIf
-		
-		'check we exactly match an override
-		If sclass 'And IsMethod()
-
-			While sclass
-				Local errorDetails:String = ""
-
-				Local found:Int
-				For Local decl:TFuncDecl=EachIn sclass.FuncDecls( )
-					
-					If decl.IdentLower() = IdentLower() Then
-
-						If IdentLower() = "new" Continue
-						If IdentLower() = "delete" Continue
-
-						found=True
-
-						If Not decl.IsSemanted() Then
-							decl.Semant
-						End If
-
-						' check void return type strictness, and fail if appropriate.
-						Local voidReturnTypeFail:Int = False
-						' super has void return type... so it is superstrict (or inherited from)
-						If TVoidType(decl.retType) And TIntType(retType) Then
-							' if we are only strict, we may fail on type mismatch
-							If Not ModuleScope().IsSuperStrict() Then
-								' we have the option of upgrading our return type to match superstrict parent
-								If opt_strictupgrade And strictVoidToInt Then
-									retType = TType.voidType
-								Else
-									' otherwise...
-									voidReturnTypeFail = True
-								End If
-							End If
-						End If
-
-						If EqualsFunc( decl ) And Not voidReturnTypeFail
-
-							' check we aren't attempting to assign weaker access modifiers
-							If (IsProtected() And decl.IsPublic()) Or (IsPrivate() And (decl.IsProtected() Or decl.IsPublic())) Then
-							
-								Err PrivilegeError(Self, decl)
-							
-							End If
-						
-							If (TObjectType(retType) And TObjectType(decl.retType )) Or (TArrayType(retType) And TArrayType(decl.retType)) Then
-								If Not retType.EqualsType( decl.retType ) And retType.ExtendsType( decl.retType ) Then
-									returnTypeSubclassed = True
-								End If
-							End If
-							
-							overrides=TFuncDecl( decl.actual )
-						Else
-							' method overloading?
-							If Not EqualsArgs(decl) Then
-								found = False
-								Continue
-							End If
-							
-							'prepare a more detailed error message
-							If (Not retType.EqualsType( decl.retType ) Or Not retType.ExtendsType( decl.retType )) Or (decl.retType And Not decl.retType.EqualsType( retType )) Or voidReturnTypeFail
-								errorDetails :+ "Return type is ~q"+retType.ToString()+"~q, expected ~q"+decl.retType.ToString()+"~q. "
-								If voidReturnTypeFail Then
-									errorDetails :+ "You may have Strict type overriding SuperStrict type. "
-								End If
-							Else
-								found = False
-								Continue
-							End If
-
-							Local argCount:Int = Min(argDecls.Length, decl.argDecls.Length)
-							If argCount > 0
-								For Local i:Int=0 Until argCount
-									If Not argDecls[i].ty.EqualsType( decl.argDecls[i].ty )
-										errorDetails :+ "Argument #"+(i+1)+" is ~q" + argDecls[i].ty.ToString()+"~q, expected ~q"+decl.argDecls[i].ty.ToString()+"~q. "
-									End If
-								Next
-							EndIf
-							'remove last space
-							errorDetails = errorDetails.Trim()
-						EndIf
-					End If
-				Next
-				If found
-					If Not overrides Err "Overriding method does not match any overridden method. (Detail: " + errorDetails+")"
-					If overrides.IsFinal() Err "Final methods cannot be overridden."
-					' for overrides, make the ident match that of the superclass
-					ident = overrides.ident
-					
-					Exit
-				EndIf
-				sclass=sclass.superClass
-			Wend
-		EndIf
-
-		'append a return statement if necessary
-		If Not IsExtern() And Not TVoidType( retType ) And Not TReturnStmt( stmts.Last() )
-			If Not isCtor() And Not isDtor()
-				Local stmt:TReturnStmt
-
-				stmt=New TReturnStmt.Create( New TConstExpr.Create( retType,"" ) )
-				stmt.generated = True
-
-				stmt.errInfo=errInfo
-				stmts.AddLast stmt
-			End If
-		EndIf
-
-		attrs:|DECL_SEMANTED
-		
-		Super.OnSemant()
-	End Method
-
-	Method CheckAccess:Int()
-		Local cd:TClassDecl = ClassScope()
-		If cd Then
-			If IsPrivate() And cd<>_env.ClassScope() Return False
-			If IsProtected() Then
-				Local ec:TClassDecl = _env.ClassScope()
-				If Not ec Return False
-				If Not ec.ExtendsClass(cd) Return False
-			End If
-			Return True
-		End If
-		Return Super.CheckAccess()
-	End Method
-
-	Function PrivilegeError:String(decl:TFuncDecl, decl2:TFuncDecl)
-		Local p:String
-		If decl.IsProtected() Then
-			p = "Protected"
-		Else
-			p = "Private"
-		End If
-		
-		Local dp:String
-		If decl2.IsPublic() Then
-			dp = "Public"
-		Else
-			dp = "Protected"
-		End If
-	
-		Return decl.ToString() + " clashes with " + decl2.ToString() + ". Attempt to assign weaker access privileges ('" + p + "'), was '" + dp + "'."
-	End Function
-	
-End Type
-
-Type TNewDecl Extends TFuncDecl
-
-	Field chainedCtor:TNewExpr
-	
-	Method OnCopy:TDecl(deep:Int = True)
-		Local args:TArgDecl[]=argDecls[..]
-		For Local i:Int=0 Until args.Length
-			args[i]=TArgDecl( args[i].Copy() )
-		Next
-		Local t:TNewDecl = TNewDecl(New TNewDecl.CreateF( ident,retType,args,attrs &~DECL_SEMANTED ))
-		If deep Then
-			For Local stmt:TStmt=EachIn stmts
-				t.AddStmt stmt.Copy(t)
-			Next
-		End If
-		t.retType = retType
-		t.scope = scope
-		t.overrides = overrides
-		t.superCtor = superCtor
-		t.castTo = castTo
-		t.noCastGen = noCastGen
-		t.munged = munged
-		t.metadata = metadata
-		t.mangled = mangled
-		t.noMangle = noMangle
-		t.chainedCtor = chainedCtor
-
-		Return  t
-	End Method
-
-
-End Type
-
-
-'Const CLASS_INTERFACE:Int=1
-'Const CLASS_TEMPLATEARG:Int=2
-'Const CLASS_TEMPLATEINST:Int=4
-'Const CLASS_INSTANCED:Int=8		'class used in New?
-Const CLASS_INSTANCED:Int=1
-Const CLASS_EXTENDSOBJECT:Int=2
-Const CLASS_FINALIZED:Int=4
-
-Type TNullDecl Extends TClassDecl
-
-End Type
-
-Type TClassDecl Extends TScopeDecl
-
-	Field lastOffset:Int
-
-	Field args:TTemplateArg[]
-	Field superTy:TIdentType
-	Field impltys:TIdentType[]
-
-	Field superClass:TClassDecl
-	
-	Field implments:TClassDecl[]			'interfaces immediately implemented
-	Field implmentsAll:TClassDecl[]		'all interfaces implemented
-	
-	Field instanceof:TClassDecl			'for instances
-	Field instances:TList		'for actual (non-arg, non-instance)
-	Field instArgs:TType[]
-
-	Field objectType:TObjectType '"canned" objectType
-	Field globInit:Int
-	Field templateSource:TTemplateRecord
-
-	'Global nullObjectClass:TClassDecl=New TNullDecl.Create( "{NULL}",Null,Null,Null,DECL_ABSTRACT|DECL_EXTERN )
-	
-	Method Create:TClassDecl( ident$,args:TTemplateArg[],superTy:TIdentType,impls:TIdentType[],attrs:Int )
-		Self.ident=ident
-		Self.args=args
-		Self.superTy=superTy
-		Self.impltys=impls
-		Self.attrs=attrs
-		Self.objectType=New TObjectType.Create( Self )
-		If args
-			instances=New TList
-		EndIf
-		Return Self
-	End Method
-	
-	Method OnCopy:TDecl(deep:Int = True)
-		InternalErr
-	End Method
-	
-	Method ToString$()
-		Local t$
-
-		If args Then
-			For Local i:Int=0 Until args.Length
-				If i Then
-					t :+ ","
-				End If
-				t:+args[i].ToString()
-			Next
-		ElseIf instargs
-			For Local i:Int=0 Until instargs.Length
-				If i Then
-					t :+ ","
-				End If
-				t :+ instargs[i].ToString()
-			Next
-		End If
-		If t t="<"+t+">"
-		Return ident+t
-	End Method
-
-	Method ToTypeString:String()
-		Return ToString()
-	End Method
-Rem
-	Method GenClassInstance:TClassDecl( instArgs:TClassDecl[] )
-		If Not IsSemanted() InternalErr
-		
-		'no args
-		If Not instArgs
-			If Not args Return Self
-			If instanceof Return Self
-			For Local inst:TClassDecl=EachIn instances
-				If _env.ClassScope()=inst Return inst
-			Next
-		EndIf
-		
-		'If Not instanceof And Not instArgs Return Self
-		
-		'check number of args
-		If instanceof Or args.Length<>instArgs.Length
-			Err "Wrong number of class arguments for "+ToString()
-		EndIf
-		
-		'look for existing instance
-		For Local inst:TClassDecl=EachIn instances
-			Local equal:Int=True
-			For Local i:Int=0 Until args.Length
-				If inst.args[i]=instArgs[i] Continue
-				equal=False
-				Exit
-			Next
-			If equal Return inst
-		Next
-		
-		Local inst:TClassDecl=New TClassDecl
-
-		InitInstance inst
-
-		inst.scope=scope
-		inst.attrs:|CLASS_TEMPLATEINST
-		inst.args=instArgs
-		inst.superTy=superTy
-		inst.instanceof=Self
-		instances.AddLast inst
-		
-		For Local i:Int=0 Until args.Length
-			inst.InsertDecl New TAliasDecl.Create( args[i].ident,instArgs[i] )
-		Next
-		
-		For Local decl:TDecl=EachIn _decls
-			If TClassDecl( decl ) Continue
-			inst.InsertDecl decl.GenInstance()
-		Next
-
-		'inst.Semant
-		'A bit cheeky...
-		inst.OnSemant
-		inst.attrs:|DECL_SEMANTED
-		
-		Return inst
-	End Method
-End Rem
-	Method GenClassInstance:TClassDecl( instArgs:TType[], declImported:Int = False )
-
-		If instanceof InternalErr
-		
-		'no args
-		If Not instArgs
-			If Not args Return Self
-			For Local inst:TClassDecl=EachIn instances
-				If _env.ClassScope()=inst Return inst
-			Next
-		EndIf
-		
-		'check number of args
-		If args.Length<>instArgs.Length
-			Err "Wrong number of type arguments for class "+ToString()
-		EndIf
-		
-		'look for existing instance
-		For Local inst:TClassDecl=EachIn instances
-			Local equal:Int=True
-			For Local i:Int=0 Until args.Length
-				If Not inst.instArgs[i].EqualsType( instArgs[i] )
-					equal=False
-					Exit
-				EndIf
-			Next
-			If equal Return inst
-		Next
-
-		Local inst:TClassDecl=New TClassDecl.Create( ident,Null,superTy,impltys, attrs )
-
-		inst.attrs:&~DECL_SEMANTED
-
-		inst.munged=munged
-		inst.errInfo=errInfo
-		inst.scope=scope
-		inst.instanceof=Self
-		inst.instArgs=instArgs
-		inst.templateSource = templateSource
-		instances.AddLast inst
-		
-		inst.declImported = declImported
-
-		For Local i:Int=0 Until args.Length
-		
-			' ensure parameter types are compatible
-			If args[i].superTy Then
-				args[i].superTy = args[i].superTy.Semant()
-				If Not instArgs[i].EqualsType(args[i].superTy) And Not instArgs[i].ExtendsType(args[i].superTy) Then
-					Err "Type parameter '" + instArgs[i].ToString() + "' is not within its bound; should extend '" + args[i].superTy.ToString() + "'"
-				End If
-			End If
-		
-			inst.InsertDecl New TAliasDecl.Create( args[i].ident,instArgs[i],0 )
-		Next
-
-		For Local decl:TDecl=EachIn _decls
-			inst.InsertDecl decl.Copy(), True
-		Next
-
-		If Not declImported Then
-			inst.scope = _env.ModuleScope()
-		End If
-
-		Return inst
-	End Method
-
-	Method IsInterface:Int()
-		Return (attrs & CLASS_INTERFACE)<>0
-	End Method
-
-	Method IsThrowable:Int()
-		Return (attrs & CLASS_THROWABLE)<>0
-	End Method
-
-	Method IsFinalized:Int()
-		Return (attrs & CLASS_FINALIZED)<>0
-	End Method
-	
-	Method IsStruct:Int()
-		Return (attrs & CLASS_STRUCT)<>0
-	End Method
-
-	Method ExtendsObject:Int()
-		Return (attrs & CLASS_EXTENDSOBJECT)<>0
-	End Method
-	
-	Method IsInstanced:Int()
-		Return (attrs & CLASS_INSTANCED)<>0
-	End Method
-	
-	Method GetDecl:Object( ident$ )
-	
-		Local cdecl:TClassDecl=Self
-		While cdecl
-			Local decl:Object=cdecl.GetDecl2( ident )
-			If decl Return decl
-			
-			cdecl=cdecl.superClass
-		Wend
-
-	End Method
-	
-	'needs this 'coz you can't go blah.Super.GetDecl()...
-	Method GetDecl2:Object( ident$ )
-		Return Super.GetDecl( ident )
-	End Method
-
-	Method GetDeclList:Object( ident$, declList:TFuncDeclList = Null, maxSearchDepth:Int )
-	
-		If Not declList Then
-			declList = New TFuncDeclList
-		End If
-	
-		Local cdecl:TClassDecl=Self
-		While cdecl
-			Local decl:Object=cdecl.GetDeclList2( ident, declList, maxSearchDepth )
-			'If decl And (Not TFuncDeclList(decl) And declList.IsEmpty()) Return decl
-			If decl Then
-				declList.AddLast(decl)
-			End If
-
-			cdecl=cdecl.superClass
-			
-			If maxSearchDepth < SCOPE_CLASS_HEIRARCHY Then
-				Exit
-			End If
-		Wend
-
-		Return declList
-	End Method
-	
-	'needs this 'coz you can't go blah.Super.GetDecl()...
-	Method GetDeclList2:Object( ident$, declList:TFuncDeclList = Null, maxSearchDepth:Int )
-		Return Super.GetDeclList( ident, declList, maxSearchDepth )
-	End Method
-	
-	Method FindFuncDecl:TFuncDecl( ident$,args:TExpr[] = Null ,explicit:Int=False, isArg:Int = False, isIdentExpr:Int = False, throwOnNotMatched:Int = False, maxSearchDepth:Int )
-	
-		' try the super first...
-		Local funcDecl:TFuncDecl = Super.FindFuncDecl(ident, args, explicit, isArg, isIdentExpr, throwOnNotMatched, maxSearchDepth)
-		If funcDecl Then
-			Return funcDecl
-		End If
-	
-	
-		If args = Null Then
-			args = New TExpr[0]
-		End If
-	
-		If Not IsInterface()
-			' try getdecl first&
-			Local decl:TFuncDecl = TFuncDecl(GetDecl(ident))
-			If decl Then
-				Return decl
-			End If
-			Return FindFuncDecl2( ident,args,explicit,isIdentExpr )
-		EndIf
-		
-		Local fdecl:TFuncDecl=FindFuncDecl2( ident,args,True )
-		
-		For Local iface:TClassDecl=EachIn implmentsAll
-			Local decl:TFuncDecl=iface.FindFuncDecl2( ident,args,True )
-			If Not decl Continue
-			
-			If fdecl
-				If fdecl.EqualsFunc( decl ) Continue
-				Err "Unable to determine overload to use: "+fdecl.ToString()+" or "+decl.ToString()+"."
-			EndIf
-			fdecl=decl
-		Next
-		
-		If fdecl Or explicit Return fdecl
-		
-		fdecl=FindFuncDecl2( ident,args,False )
-		
-		For Local iface:TClassDecl=EachIn implmentsAll
-			Local decl:TFuncDecl=iface.FindFuncDecl2( ident,args,False )
-			If Not decl Continue
-			
-			If fdecl
-				If fdecl.EqualsFunc( decl ) Continue
-				Err "Unable to determine overload to use: "+fdecl.ToString()+" or "+decl.ToString()+"."
-			EndIf
-			fdecl=decl
-		Next
-		
-		Return fdecl
-	End Method
-	
-	Method FindFuncDecl2:TFuncDecl( ident$,args:TExpr[],explicit:Int, isIdentExpr:Int = False )
-		Return Super.FindFuncDecl( ident,args,explicit,,isIdentExpr,0,0 )
-	End Method
-	
-	Method GetAllFuncDecls:TFuncDecl[](funcs:TFuncDecl[] = Null, includeSuper:Int = True)
-
-		If Not funcs Then
-			funcs = New TFuncDecl[0]
-		End If
-		
-		If superClass And includeSuper Then
-			funcs = superClass.GetAllFuncDecls(funcs)
-		End If
-
-		' interface methods
-		For Local iface:TClassDecl=EachIn implmentsAll
-			funcs = iface.GetAllFuncDecls(funcs)
-		Next
-		
-		For Local func:TFuncDecl = EachIn _decls
-		
-			Local matched:Int = False
-			
-			For Local i:Int = 0 Until funcs.length
-				' found a match - we are overriding it
-				If func.IdentLower() = funcs[i].IdentLower() And func.EqualsArgs(funcs[i]) Then
-					matched = True
-					' but don't override if we are an interface and the function is implemented
-					If IsInterface() And Not funcs[i].ClassScope().IsInterface() Then
-						Exit
-					End If
-					' set this to our own func
-					funcs[i] = func
-					Exit
-				End If
-			Next
-			
-			If Not matched Then
-				funcs :+ [func]
-			End If
-		
-		Next
-		
-		Return funcs
-	End Method
-
-	' returns a list of original function decls (i.e. decls in the scope of their original declarations).
-	' this is useful for generating vtables for extern types
-	Method GetAllOriginalFuncDecls:TFuncDecl[](funcs:TFuncDecl[] = Null, includeSuper:Int = True)
-		If Not funcs Then
-			funcs = New TFuncDecl[0]
-		End If
-		
-		If superClass And includeSuper Then
-			funcs = superClass.GetAllOriginalFuncDecls(funcs, True)
-		End If
-
-		' interface methods
-		For Local iface:TClassDecl=EachIn implmentsAll
-			For Local func:TFuncDecl=EachIn iface._decls
-				Local matched:Int = False
-
-'				For Local i:Int = 0 Until funcs.length
-'					' found a match - we are overriding it
-'					If func.IdentLower() = funcs[i].IdentLower() Then
-'						matched = True
-'						Exit
-'					End If
-'				Next
-				
-				If Not matched Then
-					funcs :+ [func]
-				End If
-			Next
-		Next
-
-		
-		For Local func:TFuncDecl = EachIn _decls
-		
-			Local matched:Int = False
-			
-			' dont count any that are already in the funcs list
-			For Local i:Int = 0 Until funcs.length
-				' found a match - we are overriding it
-				If func.IdentLower() = funcs[i].IdentLower() And func.EqualsArgs(funcs[i]) Then
-					matched = True
-					' set this to our own func
-					'funcs[i] = func
-					Exit
-				End If
-			Next
-			
-			If Not matched Then
-				funcs :+ [func]
-			End If
-		
-		Next
-		
-		Return funcs
-	End Method
-
-	Method GetOriginalFuncDecl:TFuncDecl(fdecl:TFuncDecl)
-		If Not TClassDecl(Self) Then
-			Return fdecl
-		End If
-		
-		If superClass Then
-			Local decl:TFuncDecl = superClass.GetOriginalFuncDecl(fdecl)
-			If decl <> fdecl Then
-				Return decl
-			End If
-		End If
-		
-		For Local func:TFuncDecl = EachIn _decls
-		
-			If func.IdentLower() = fdecl.IdentLower() And func.EqualsArgs(fdecl) Then
-				Return func
-			End If
-		
-		Next
-		
-		Return fdecl
-	End Method
-
-	Method GetLatestFuncDecl:TFuncDecl(fdecl:TFuncDecl)
-		If Not TClassDecl(Self) Then
-			Return fdecl
-		End If
-		
-		For Local func:TFuncDecl = EachIn _decls
-		
-			If func.IdentLower() = fdecl.IdentLower() And func.EqualsArgs(fdecl) Then
-				Return func
-			End If
-		
-		Next
-		
-		If superClass Then
-			Local decl:TFuncDecl = superClass.GetLatestFuncDecl(fdecl)
-			If decl <> fdecl Then
-				Return decl
-			End If
-		End If
-		
-
-		Return fdecl
-	End Method
-	
-	Method ExtendsClass:Int( cdecl:TClassDecl )
-		'If Self=nullObjectClass Return True
-		
-'		If cdecl.IsTemplateArg()
-'			cdecl=TType.objectType.FindClass()
-'		EndIf
-		
-		Local tdecl_:TClassDecl=Self
-		While tdecl_
-			If tdecl_=cdecl Return True
-			If cdecl.IsInterface()
-				For Local iface:TClassDecl=EachIn tdecl_.implmentsAll
-					If iface=cdecl Return True
-				Next
-			EndIf
-			tdecl_=tdecl_.superClass
-		Wend
-		
-		Return False
-	End Method
-	
-	Method OnSemant()
-	
-		If args Then
-			Return
-		End If
-
-		PushEnv Self
-
-		'If Not IsTemplateInst()
-		'	For Local i:Int=0 Until args.Length
-		'		InsertDecl args[i]
-		'		args[i].Semant
-		'	Next
-		'EndIf
-
-		'Semant superclass		
-		If superTy
-			'superClass=superTy.FindClass()
-			superClass=superTy.SemantClass()
-			If superClass.IsInterface() Then
-				If Not IsExtern() Or Not superClass.IsExtern() Err superClass.ToString()+" is an interface, not a class."
-				If (IsExtern() And Not superClass.IsExtern()) Or (superClass.IsExtern() And Not IsExtern()) Err "Extern and non extern types cannot be mixed."
-			End If
-			If superClass.IsFinal() Err "Final types cannot be extended."
-		EndIf
-		
-		'Semant implemented interfaces
-		Local impls:TClassDecl[]=New TClassDecl[impltys.Length]
-		Local implsall:TStack=New TStack
-		For Local i:Int=0 Until impltys.Length
-			attrs :| DECL_CYCLIC
-			Local cdecl:TClassDecl=impltys[i].SemantClass()
-			attrs :~ DECL_CYCLIC
-			If Not cdecl.IsInterface()
-				Err cdecl.ToString()+" is a type, not an interface."
-			EndIf
-			For Local j:Int=0 Until i
-				If impls[j]=cdecl
-					Err "Duplicate interface "+cdecl.ToString()+"."
-				EndIf
-			Next
-			impls[i]=cdecl
-			implsall.Push cdecl
-			For Local tdecl_:TDecl=EachIn cdecl.implmentsAll
-				implsall.Push tdecl_
-			Next
-		Next
-		Local length:Int = implsall.Length()
-		implmentsAll=New TClassDecl[length]
-		For Local i:Int=0 Until length
-			implmentsAll[i]=TClassDecl(implsall.Get(length - i - 1))
-		Next
-		implments=impls
-
-		Rem
-		If IsInterface()
-			'add implemented methods to our methods
-			For Local iface:=EachIn implmentsAll
-				For Local decl:=EachIn iface.FuncDecls
-					InsertAlias decl.ident,decl
-				Next
-			Next
-		EndIf
-		EndRem
-				
-'		attrs|=DECL_SEMANTED
-		
-		PopEnv
-		
-		'If IsTemplateArg()
-		'	actual=TType.objectType.FindClass()
-		'	Return
-		'EndIf
-		
-		'If IsTemplateInst()
-		'	Return
-		'EndIf
-		
-		'Are we abstract?
-		If Not IsAbstract()
-			For Local decl:TDecl=EachIn _decls
-				Local fdecl:TFuncDecl=TFuncDecl( decl )
-				If fdecl And fdecl.IsAbstract()
-					attrs:|DECL_ABSTRACT
-					Exit
-				EndIf
-			Next
-		EndIf
-		
-		If Not lastOffset And superClass Then
-			lastOffset = superClass.LastOffset
-		End If
-
-		For Local decl:TFieldDecl=EachIn _decls
-			GetFieldOffset(decl)
-		Next
-
-		If Not IsExtern() And Not IsInterface()
-			Local fdecl:TFuncDecl
-			For Local decl:TFuncDecl=EachIn FuncDecls()
-				If Not decl.IsCtor() Continue
-				Local nargs:Int
-				For Local arg:TArgDecl=EachIn decl.argDecls
-					If Not arg.init nargs:+1
-				Next
-				If nargs Continue
-				fdecl=decl
-				Exit
-			Next
-			
-			
-			' Don't need default new?
-			'If Not fdecl
-			'	fdecl=New TFuncDecl.CreateF( "new",New TObjectType.Create( Self ),Null,FUNC_CTOR )
-			'	fdecl.AddStmt New TReturnStmt.Create( Null )
-			'	InsertDecl fdecl
-			'EndIf
-		EndIf
-
-		'NOTE: do this AFTER super semant so UpdateAttrs order is cool.
-
-		If AppScope() Then
-			AppScope().semantedClasses.AddLast Self
-		End If
-	End Method
-	
-	Method SemantParts()
-'		If IsSemanted() Return
-		
-'		Super.Semant()
-		If args Then
-			Return
-		End If
-		
-		For Local decl:TConstDecl = EachIn Decls()
-			decl.Semant()
-		Next
-
-		For Local decl:TGlobalDecl = EachIn Decls()
-			decl.Semant()
-		Next
-
-		' NOTE : we can't semant functions here as they cause cyclic errors.
-		For Local decl:TFuncDecl = EachIn Decls()
-			decl.Semant()
-		Next
-
-		For Local decl:TFieldDecl = EachIn Decls()
-			decl.Semant()
-		Next
-
-		' nested classes
-		For Local decl:TClassDecl = EachIn Decls()
-			decl.Semant()
-		Next
-
-	End Method
-	
-	'Ok, this dodgy looking beast 'resurrects' methods that may not currently be alive, but override methods that ARE.
-	Method UpdateLiveMethods:Int()
-	
-		If IsInterface() Return 0
-
-		If Not superClass Return 0
-
-		Local n:Int
-		For Local decl:TFuncDecl=EachIn MethodDecls()
-			If decl.IsSemanted() Continue
-			
-			Local live:Int
-			Local unsem:TList=New TList'<TFuncDecl>
-			
-			unsem.AddLast decl
-			
-			Local sclass:TClassDecl=superClass
-			While sclass
-				For Local decl2:TFuncDecl=EachIn sclass.MethodDecls( decl.ident )
-					If decl2.IsSemanted()
-						live=True
-					Else
-						unsem.AddLast decl2
-						If decl2.IsExtern() live=True
-						If decl2.actual.IsSemanted() live=True
-					EndIf
-				Next
-				sclass=sclass.superClass
-			Wend
-			
-			If Not live
-				Local cdecl:TClassDecl=Self
-				While cdecl
-					For Local iface:TClassDecl=EachIn cdecl.implmentsAll
-						For Local decl2:TFuncDecl=EachIn iface.MethodDecls( decl.ident )
-							If decl2.IsSemanted()
-								live=True
-							Else
-								unsem.AddLast decl2
-								If decl2.IsExtern() live=True
-								If decl2.actual.IsSemanted() live=True
-							EndIf
-						Next
-					Next
-					cdecl=cdecl.superClass
-				Wend
-			EndIf
-			
-			If Not live Continue
-			
-			For Local decl:TDecl=EachIn unsem
-				decl.Semant
-				n:+1
-			Next
-		Next
-		
-		Return n
-	End Method
-	
-	Method FinalizeClass()
-	
-		SemantParts()
-
-		PushErr errInfo
-		
-		If Not IsInterface()
-			'
-			'check for duplicate fields! - BlitzMax supports fields with the same name in subclasses..
-			'
-			'For Local decl:TDecl=EachIn Semanted()
-			'	Local fdecl:TFieldDecl=TFieldDecl( decl )
-			'	If Not fdecl Continue
-			'	Local cdecl:TClassDecl=superClass
-			'	While cdecl
-			'		For Local decl:TDecl=EachIn cdecl.Semanted()
-			'			If decl.ident=fdecl.ident Err "Field '"+fdecl.ident+"' in class "+ToString()+" overrides existing declaration in class "+cdecl.ToString()
-			'		Next
-			'		cdecl=cdecl.superClass
-			'	Wend
-			'Next
-			'
-			'Check we implement all abstract methods!
-			'
-			If IsInstanced()
-				Local cdecl:TClassDecl=Self
-				Local impls:TList=New TList'<TFuncDecl>
-				While cdecl
-					For Local decl:TFuncDecl=EachIn cdecl.SemantedMethods()
-						If decl.IsAbstract()
-							Local found:Int
-							For Local decl2:TFuncDecl=EachIn impls
-								If decl.IdentLower() = decl2.IdentLower() And decl2.EqualsFunc( decl )
-									found=True
-									Exit
-								EndIf
-							Next
-							If Not found
-								Err "Can't create instance of type "+ToString()+" due to abstract method "+decl.ToString()+"."
-							EndIf
-						Else
-							impls.AddLast decl
-						EndIf
-					Next
-					cdecl=cdecl.superClass
-				Wend
-			EndIf
-			'
-			'Check we implement all interface methods!
-			'
-			If Not IsAbstract() Then
-
-				Local ints:TMap = GetInterfaces()
-
-				For Local iface:TClassDecl=EachIn ints.Values()
-				
-					If (Not IsExtern() And iface.IsExtern()) Or (IsExtern() And Not iface.IsExtern()) Then
-						Err "Cannot mix Extern and non Extern Types and Interfaces."
-					End If
-				
-					For Local decl:TFuncDecl=EachIn iface.SemantedMethods()
-						Local found:Int
-
-						Local cdecl:TClassDecl=Self
-						
-						While cdecl And Not found
-							For Local decl2:TFuncDecl=EachIn cdecl.SemantedMethods( decl.ident )
-								' equals (or extends - for object types)
-								If decl2.EqualsFunc( decl )
-									If Not decl2.IsPublic() Then
-										' error on function decl
-										PushErr decl2.errInfo
-										Err TFuncDecl.PrivilegeError(decl2, decl)
-									End If
-									found=True
-									Exit
-								EndIf
-							Next
-						
-							cdecl = cdecl.superClass
-						Wend
-
-						If Not found
-							Err decl.ToString() + " must be implemented by type " + ToString()
-						EndIf
-					Next
-				Next
-			End If
-		Else
-			' check for compatible overloads, etc.
-
-			Local impls:TList=New TList
-
-			CheckInterface(Self, impls)
-			
-		EndIf
-		
-		PopErr
-		
-	End Method
-	
-	Method CheckInterface(cdecl:TClassDecl, impls:TList)
-		While cdecl
-			For Local decl:TFuncDecl=EachIn cdecl.SemantedMethods()
-				Local found:Int
-				For Local decl2:TFuncDecl=EachIn impls
-					If decl.IdentLower() = decl2.IdentLower()
-						If decl2.argDecls.Length = decl.argDecls.Length And Not decl2.EqualsFunc( decl )
-						'	Err "Cannot mix incompatible method signatures." + decl2.ToString() + " vs " + decl.ToString() + "."
-						Else
-							found = True
-						End If
-					EndIf
-				Next
-				If Not found Then
-					impls.AddLast decl
-				End If
-				'EndIf
-			Next
-			
-			For Local idecl:TClassDecl = EachIn cdecl.implments
-				CheckInterface(idecl, impls)
-			Next
-
-			cdecl=cdecl.superClass
-		Wend
-	End Method
-	
-	Method GetFieldOffset(decl:TFieldDecl)
-		
-		Local ty:TType = decl.declTy
-		
-		Local modifier:Int = POINTER_SIZE
-		
-		If TIntType(ty) Or TFloatType(ty) Or TUIntType(ty) Then
-			modifier = 4
-		Else If TShortType(ty) Then
-			modifier = 2
-		Else If TLongType(ty) Or TDoubleType(ty) Or TULongType(ty) Then
-			modifier = 8
-		Else If TByteType(ty) Then
-			modifier = 1
-		Else If TSizeTType(ty) Then
-			modifier = WORD_SIZE
-		End If
-
-		If modifier > 1 And lastOffset Mod modifier Then
-			lastOffset :+ modifier - (lastOffset Mod modifier)
-		End If
-		
-		decl.offset = lastOffset
-		
-		lastOffset :+ modifier
-	End Method
-	
-	Method ImplementsInterface:Int(ident:String)
-		ident = ident.ToLower()
-		For Local iface:TClassDecl = EachIn implmentsAll
-			If iface.IdentLower() = ident Then
-				Return True
-			End If
-		Next
-		Return False
-	End Method
-	
-	' returns a map of all interfaces implemented in this hierarchy
-	Method GetInterfaces:TMap(map:TMap = Null)
-		If Not map Then
-			map = New TMap
-		End If
-
-		For Local iface:TClassDecl=EachIn implmentsAll
-		
-			If iface.IsInterface() Then
-			
-				Local cdecl:TClassDecl = iface
-				While cdecl
-				
-					If cdecl.IsInterface() Then
-						If Not map.Contains(cdecl) Then
-							map.Insert(cdecl, cdecl)
-						End If
-					End If
-
-
-					cdecl=cdecl.superClass
-				Wend
-			
-			End If
-		Next
-
-		
-		If superClass Then
-			map = superClass.GetInterfaces(map)
-		End If
-		
-		Return map
-	End Method
-	
-	Method GetImplementedFuncs:TList(list:TList = Null)
-		If Not list Then
-			list = New TList
-		End If
-		
-		For Local idecl:TClassDecl = EachIn implmentsAll
-			idecl.GetImplementedFuncs(list)
-		Next
-		
-		For Local decl:TFuncDecl = EachIn SemantedMethods()
-			list.AddLast(decl)
-		Next
-
-		Return list
-	End Method
-	
-End Type
-
-Type TLoopLabelDecl Extends TDecl
-
-	Field realIdent:String
-
-	Method Create:TLoopLabelDecl( ident$, attrs:Int=0 )
-		Self.ident="#" + ident
-		Self.realIdent = ident
-		Self.attrs=attrs
-		Return Self
-	End Method
-	
-	Method OnCopy:TDecl(deep:Int = True)
-		Return New TLoopLabelDecl.Create( realIdent,attrs )
-	End Method
-	
-	Method OnSemant()
-	End Method
-	
-End Type
-
-Type TDataLabelDecl Extends TDecl
-
-	Field realIdent:String
-	Field index:Int
-
-	Method Create:TDataLabelDecl( ident$, attrs:Int=0 )
-		Self.ident="#" + ident
-		Self.realIdent = ident
-		Self.attrs=attrs
-		Return Self
-	End Method
-	
-	Method OnCopy:TDecl(deep:Int = True)
-		Return New TDataLabelDecl.Create( realIdent,attrs )
-	End Method
-	
-	Method OnSemant()
-	End Method
-	
-End Type
-
-Type TDefDataDecl Extends TDecl
-
-	Global count:Int
-
-	Field label:TDataLabelDecl
-	Field data:TExpr[]
-
-	Method Create:TDefDataDecl(data:TExpr[], label:TDataLabelDecl = Null, attrs:Int=0 )
-		Self.data=data
-		Self.label=label
-		Self.attrs=attrs
-		Return Self
-	End Method
-	
-	Method OnCopy:TDecl(deep:Int = True)
-		Return New TDefDataDecl.Create(TExpr.CopyArgs(data),TDataLabelDecl(label.Copy()),attrs)
-	End Method
-
-	Method OnSemant()
-		If data Then
-			If label Then
-				label.index = count
-			End If
-		
-			For Local i:Int = 0 Until data.length
-				data[i] = data[i].Semant()
-				If Not TConstExpr(data[i]) Then
-					Err "Data items must be numeric or strings"
-				Else
-					' todo : more type tests?
-				End If
-				count :+ 1
-			Next
-		Else
-			' err?
-		End If
-	End Method
-	
-End Type
-
-Const MODULE_STRICT:Int=1
-Const MODULE_SUPERSTRICT:Int=2
-Const MODULE_ACTUALMOD:Int=4
-
-Type TNamespaceDecl Extends TScopeDecl
-
-'	Field mods:TMap = New TMap
-
-	Method Create:TNamespaceDecl( ident$,munged$ )
-		Self.ident=ident
-		Self.munged=munged
-		Return Self
-	End Method
-
-'	Method GetDecl:Object( ident$ )
-'		Return mods.ValueForKey(ident.ToLower())
-'	End Method
-	
-End Type
-
-Type TModuleDecl Extends TScopeDecl
-
-	Field filepath$
-	Field relpath$
-	Field imported:TUnorderedMap=New TUnorderedMap'<TModuleDecl>		'Maps filepath to modules
-	Field pubImported:TUnorderedMap =New TUnorderedMap'<TModuleDecl>	'Ditto for publicly imported modules
-
-	Field pmod:TModuleDecl
-
-	Field fileImports:TList=New TList'StringList
-	
-	' cache of ModuleInfo lines
-	Field modInfo:TList = New TList
-
-	Field _getDeclTreeCache:TList
-	
-	Field _getDeclCache:TMap = New TMap
-	Field _getDeclListCache:TMap = New TMap
-
-	Method ToString$()
-		Return "Module "+munged
-	End Method
-	
-	Method Create:TModuleDecl( ident$,munged$,filepath$,attrs:Int )
-		Self.ident=ident
-		Self.munged=munged
-		Self.filepath=filepath
-		Self.attrs=attrs
-
-		If ident.Find(".") <> -1 And ident.find("/") = -1 And ident.find("\") = -1 Then
-			Local m:String = ident[..ident.Find(".")]
-			Local ns:TNamespaceDecl = TNamespaceDecl(_appInstance.GetDecl(m.ToLower()))
-			If Not ns Then
-				ns = New TNamespaceDecl.Create(m, m)
-				If _appInstance.mainModule Then
-					_appInstance.mainModule.InsertDecl(ns)
-				Else
-					' this must be the main module...
-					InsertDecl(ns)
-				End If
-			End If
-			ns.InsertDecl(Self)
-		End If
-
-		Return Self
-	End Method
-
-	Method UpdateFilePath(fp:String)
-		filepath = fp
-	End Method
-	
-	Method AddImport(imp:String, obj:Object)
-		imported.Insert(imp, obj)
-		FlushCaches()
-	End Method
-	
-	Method FlushCaches()
-		_getDeclTreeCache = Null
-		If TModuleDecl(pmod) Then
-			TModuleDecl(pmod).FlushCaches()
-		End If
-	End Method
-	
-	Method IsStrict:Int()
-		Return (attrs & MODULE_STRICT)<>0
-	End Method
-
-	Method IsSuperStrict:Int()
-		Return (attrs & MODULE_SUPERSTRICT)<>0
-	End Method
-	
-	Method IsActualModule:Int()
-		Return (attrs & MODULE_ACTUALMOD)<>0
-	End Method
-	
-	Method GetDecl:Object( ident$ )
-		' if we previously found it, return it from the cache
-		Local decl:Object = _getDeclCache.ValueForKey(ident)
-
-		If decl Then
-			Return decl
-		End If
-		
-		If _getDeclTreeCache Then
-		
-			Local declmod$
-		
-			For Local mdecl:TModuleDecl = EachIn _getDeclTreeCache
-
-				If ident = mdecl.ident
-					_getDeclCache.Insert(ident, mdecl)
-					Return mdecl
-				End If
-			
-				Local tdecl_:Object=mdecl.GetDecl2( ident )
-			
-				If tdecl_ And tdecl_<>decl
-					If mdecl=Self
-						_getDeclCache.Insert(ident, tdecl_)
-						Return tdecl_
-					End If
-					If decl
-						Err "Duplicate identifier '"+ident+"' found in module '"+declmod+"' and module '"+mdecl.ident+"'."
-					EndIf
-					decl=tdecl_
-					declmod=mdecl.ident
-				EndIf
-			Next
-		
-		Else
-		
-			_getDeclTreeCache = New TList
-	
-			Local todo:TList=New TList'<TModuleDecl>
-			'Local done:TIntMap=New TIntMap'<TModuleDecl>
-			Local done:TMap = New TMap
-			
-			todo.AddLast Self
-			'done.Insert _filePathId,Self
-			done.Insert filePath,Self
-			
-			Local declmod$
-			
-			While Not todo.IsEmpty()
-		
-				Local mdecl:TModuleDecl=TModuleDecl(todo.RemoveLast())
-				
-				_getDeclTreeCache.AddLast(mdecl)
-				
-				Local imps:TUnorderedMap=mdecl.imported
-	
-				For Local mdecl2:TModuleDecl=EachIn imps.Values()
-	
-					'If Not done.Contains( mdecl2._filePathId )
-					If Not done.Contains( mdecl2.filePath )
-						todo.AddLast mdecl2
-						'done.Insert mdecl2._filePathId,mdecl2
-						done.Insert mdecl2.filePath,mdecl2
-					EndIf
-					
-				Next
-	
-			Wend
-	
-			Return GetDecl(ident)
-	
-		End If
-			
-		' cache it for next time
-		_getDeclCache.Insert(ident, decl)
-		
-		Return decl
-	End Method
-	
-	Method GetDecl2:Object( ident$ )
-		Return Super.GetDecl( ident )
-	End Method
-
-
-	Method GetDeclList:Object( ident$, declList:TFuncDeclList = Null, maxSearchDepth:Int )
-
-		If Not declList Then
-			declList = New TFuncDeclList
-		End If
-
-		Local decl:Object,declmod$
-
-		If _getDeclTreeCache Then
-		
-'			Print "   Using Cache"
-			
-			Local declmod$
-		
-			For Local mdecl:TModuleDecl = EachIn _getDeclTreeCache
-			
-				If ident = mdecl.ident
-					'_getDeclCache.Insert(identId, mdecl)
-					Return mdecl
-				End If
-			
-				Local tdecl_:Object=mdecl.GetDeclList2( ident, declList, maxSearchDepth )
-			
-				If tdecl_ And tdecl_<>decl
-					If mdecl=Self
-						_getDeclCache.Insert(ident, tdecl_)
-						Return tdecl_
-					End If
-					If decl
-						Err "Duplicate identifier '"+ident+"' found in module '"+declmod+"' and module '"+mdecl.ident+"'."
-					EndIf
-					decl=tdecl_
-					declmod=mdecl.ident
-				EndIf
-			Next
-		
-		Else
-
-			_getDeclTreeCache = New TList
-	
-			Local todo:TList=New TList'<TModuleDecl>
-			Local done:TMap=New TMap'<TModuleDecl>
-			
-			todo.AddLast Self
-			done.Insert filepath,Self
-			
-			'Local decl:Object,declmod$
-			
-			While Not todo.IsEmpty()
-		
-				Local mdecl:TModuleDecl=TModuleDecl(todo.RemoveLast())
-				_getDeclTreeCache.AddLast(mdecl)
-				
-				Local imps:TUnorderedMap=mdecl.imported
-	
-				For Local mdecl2:TModuleDecl=EachIn imps.Values()
-					If Not done.Contains( mdecl2.filepath )
-						todo.AddLast mdecl2
-						done.Insert mdecl2.filepath,mdecl2
-					EndIf
-					
-				Next
-	
-			Wend
-		
-			Return GetDeclList( ident, declList, maxSearchDepth )
-		
-		End If
-		
-		Return decl
-	End Method
-	
-	Method GetDeclList2:Object( ident$, declList:TFuncDeclList = Null, maxSearchDepth:Int )
-		Return Super.GetDeclList( ident, declList, maxSearchDepth )
-	End Method
-
-	Method OnSemant()
-		Local decl:TFuncDecl = FindFuncDecl( "__localmain", ,,,,,SCOPE_MODULE )
-		If decl Then
-			decl.Semant
-		End If
-	
-		For Local gdecl:TGlobalDecl=EachIn _decls
-			gdecl.Semant
-		Next
-
-		For Local cdecl:TClassDecl=EachIn _decls
-			If cdecl.args Then
-				For Local inst:TClassDecl = EachIn cdecl.instances
-					For Local idecl:TDecl = EachIn inst.Decls()
-						If TAliasDecl( idecl ) Continue
-						idecl.Semant()
-					Next
-				Next
-			Else
-				cdecl.Semant
-			End If
-		Next
-
-		For Local fdecl:TFuncDecl=EachIn _decls
-			fdecl.Semant
-		Next
-
-		For Local cdecl:TConstDecl=EachIn _decls
-			cdecl.Semant
-		Next
-	End Method
-
-End Type
-
-Type TAppDecl Extends TScopeDecl
-
-	Field imported:TUnorderedMap=New TUnorderedMap'<TModuleDecl>			'maps modpath->mdecl
-	
-	Field globalImports:TUnorderedMap = New TUnorderedMap
-	
-	Field mainModule:TModuleDecl
-	Field mainFunc:TFuncDecl	
-		
-	Field semantedClasses:TList=New TList'<TClassDecl>			'in-order (ie: base before derived) list of _semanted classes
-	Field semantedGlobals:TList=New TList'<TGlobalDecl>			'in-order (ie: dependancy sorted) list of _semanted globals
-
-	Field fileImports:TList=New TList'StringList
-	Field headers:TList = New TList
-	
-	Field stringConsts:TMap = New TMap
-	Field stringConstCount:Int
-	
-	Field incbins:TList = New TList
-	Field genIncBinHeader:Int = False
-	
-	Field dataDefs:TList = New TList
-	Field scopeDefs:TMap = New TMap
-	
-	Method GetPathPrefix:String()
-		If opt_buildtype = BUILDTYPE_MODULE Then
-			Local prefix:String
-			Local path:String[] = mainModule.filepath.split("/")
-			Local c:Int = 0
-			For Local dir:String = EachIn path
-				If c Then
-					prefix :+ dir.Replace(".mod", "") + "_"
-					c:- 1
-				End If
-				If dir = "mod" Then
-					c = 2
-				End If
-			Next
-		Else
-			Return "bb_"
-		End If
-	End Method
-	
-	Method InsertModule( mdecl:TModuleDecl )
-		mdecl.scope=Self
-		imported.Insert mdecl.filepath,mdecl
-		If Not mainModule
-			mainModule=mdecl
-		EndIf
-	End Method
-	
-	Method IsImported:Int(modpath:String)
-		Return globalImports.Contains(modpath)
-	End Method
-	
-	Method GetDecl:Object( ident$ )
-		Local obj:Object = Super.GetDecl(ident)
-		If Not obj And mainModule Then
-			Return mainModule.GetDecl(ident)
-		End If
-		Return obj
-	End Method
-
-	Method OnSemant()
-'DebugStop		
-		_env=Null
-		pushenv Self
-		
-		SemantDataDefs()	
-
-		mainModule.Semant
-
-		mainFunc=mainModule.FindFuncDecl( "__localmain",,,,,,SCOPE_MODULE )
-		
-		
-		' FIXME
-		If Not mainFunc Err "Function 'Main' not found."
-	
-		SemantDecls()
-
-		Repeat
-			Local more:Int
-			For Local cdecl:TClassDecl=EachIn semantedClasses
-				more:+cdecl.UpdateLiveMethods()
-			Next
-			If Not more Exit
-		Forever
-		
-		For Local cdecl:TClassDecl=EachIn semantedClasses
-			cdecl.FinalizeClass
-		Next
-	End Method
-	
-	Method SemantDataDefs()
-		TDefDataDecl.count = 0
-		
-		For Local decl:TDecl = EachIn dataDefs
-			decl.Semant
-		Next
-	End Method
-	
-	Method SemantDecls()
-		For Local decl:TDecl=EachIn mainModule._decls
-
-			decl.Semant
-			
-			' consts
-			Local cdecl:TConstDecl=TConstDecl( decl )
-			If cdecl
-				cdecl.Semant()
-				Continue
-			End If
-
-			' classes
-			Local tdecl:TClassDecl=TClassDecl( decl )
-			If tdecl
-				tdecl.Semant()
-				tdecl.SemantParts()
-				Continue
-			EndIf
-
-			' functions
-			Local fdecl:TFuncDecl=TFuncDecl( decl )
-			If fdecl And fdecl <> _appInstance.mainFunc Then
-				fdecl.Semant()
-				Continue
-			End If
-
-			' globals
-			Local gdecl:TGlobalDecl=TGlobalDecl( decl )
-			If gdecl
-				gdecl.Semant()
-				Continue
-			End If
-		Next
-
-	End Method
-	
-	Method hasStringConst:Int(value:String)
-		Return stringConsts.ValueForKey(value) <> Null
-	End Method
-	
-	Method mapStringConsts(value:String)
-		Local sc:TStringConst = TStringConst(stringConsts.ValueForKey(value))
-		
-		If Not sc Then
-			Local sc:TStringConst = New TStringConst
-			sc.count = 1
-		
-			If value Then
-				sc.id = "_s" + stringConstCount
-			Else
-				sc.id = "bbEmptyString"
-			End If
-
-			stringConsts.Insert(value, sc)
-
-			If value Then
-				stringConstCount:+ 1
-			End If
-		Else
-			sc.count :+ 1
-		End If
-	End Method
-	
-	Method removeStringConst(value:String)
-		If value Then
-			Local sc:TStringConst = TStringConst(stringConsts.ValueForKey(value))
-			If sc Then
-				If sc.count > 0 Then
-					sc.count :- 1
-					'stringConsts.Remove(value)
-				End If
-			End If
-		End If
-	End Method
-	
-	Method FindDataLabel:TDecl(ident:String)
-		For Local dd:TDefDataDecl = EachIn dataDefs
-			If dd.label And dd.label.ident.ToLower() = ident.ToLower() Then
-				Return dd
-			End If
-		Next
-	End Method
-	
-End Type
-
-Type TStringConst
-
-	Field id:String
-	Field count:Int
-
-End Type
+			Wend
+			
+			If Not ec Then
+				Return False
+			End If
+		End If
+		Return True
+	End Method
+
+End Type
+
+Type TAliasDecl Extends TDecl
+
+	Field decl:Object
+	
+	Method Create:TAliasDecl( ident$,decl:Object,attrs:Int=0 )
+		Self.ident=ident
+		Self.decl=decl
+		Self.attrs=attrs
+		Return Self
+	End Method
+	
+	Method OnCopy:TDecl(deep:Int = True)
+		Return New TAliasDecl.Create( ident,decl,attrs )
+	End Method
+	
+	Method OnSemant()
+	End Method
+	
+	Method Clear()
+	End Method
+	
+End Type
+
+Type TScopeDecl Extends TDecl
+
+'Private
+
+	Field _decls:TList=New TList'<TDecl>
+	Field _semanted:TList=New TList'<TDecl>
+
+	Field declsMap:TMap=New TMap'<Object>
+
+'Public
+
+	Method OnCopy:TDecl(deep:Int = True)
+		InternalErr
+	End Method
+
+	Method Decls:TList()
+		Return _decls
+	End Method
+	
+	Method Semanted:TList()
+		Return _semanted
+	End Method
+	
+	Method FuncDecls:TList( id$="" )
+		Local fdecls:TList=New TList
+		For Local decl:TDecl=EachIn _decls
+			If id And decl.ident<>id Continue
+			Local fdecl:TFuncDecl=TFuncDecl( decl )
+			If fdecl fdecls.AddLast fdecl
+		Next
+		Return fdecls
+	End Method
+	
+	Method MethodDecls:TList( id$="" )
+		Local fdecls:TList=New TList
+		For Local decl:TDecl=EachIn _decls
+			If id And decl.ident<>id Continue
+			Local fdecl:TFuncDecl=TFuncDecl( decl )
+			If fdecl And fdecl.IsMethod() fdecls.AddLast fdecl
+		Next
+		Return fdecls
+	End Method
+	
+	Method SemantedFuncs:TList( id$="" )
+		Local fdecls:TList=New TList
+		For Local decl:TDecl=EachIn _semanted
+			If id And decl.ident<>id Continue
+			Local fdecl:TFuncDecl=TFuncDecl( decl )
+			If fdecl fdecls.AddLast fdecl
+		Next
+		Return fdecls
+	End Method
+	
+	Method SemantedMethods:TList( id$="" )
+		Local fdecls:TList=New TList
+		For Local decl:TDecl=EachIn _decls
+			If id And decl.ident<>id Continue
+			Local fdecl:TFuncDecl=TFuncDecl( decl )
+			If fdecl And fdecl.IsMethod()
+				If Not fdecl.IsSemanted() Then
+					fdecl.Semant()
+				End If
+				fdecls.AddLast fdecl
+			End If
+		Next
+		Return fdecls
+	End Method
+	
+	Method InsertDecl( decl:TDecl, isCopy:Int = False )
+
+		If decl.scope And Not (decl.attrs & DECL_INITONLY) And Not isCopy InternalErr
+		
+		'Local ident$=decl.ident
+		If Not decl.ident Return
+		
+		If Not decl.scope Or isCopy Then
+			decl.scope=Self
+		End If
+		_decls.AddLast decl
+
+		'Local _decls:TMap
+		Local tdecl_:Object=declsMap.ValueForKey( decl.IdentLower() )
+		
+		If TFuncDecl( decl )
+			Local funcs:TFuncDeclList=TFuncDeclList( tdecl_ )
+			If funcs Or Not tdecl_
+				If Not funcs
+					funcs=New TFuncDeclList
+					funcs.ident = decl.IdentLower()
+					declsMap.Insert decl.IdentLower(),funcs
+				EndIf
+
+				funcs.AddLast TFuncDecl( decl )
+				Return
+			Else
+				Err "Duplicate identifier '"+decl.ident+"'."
+			EndIf
+		Else If Not tdecl_
+			declsMap.Insert decl.IdentLower(),decl
+		Else
+			Err "Duplicate identifier '"+decl.ident+"'."
+		EndIf
+
+	End Method
+
+	Method InsertDecls( _decls:TList )
+		For Local decl:TDecl=EachIn _decls
+			InsertDecl decl
+		Next
+	End Method
+	
+	'This is overridden by TClassDecl and TModuleDecl
+	Method GetDecl:Object( ident$ )
+'DebugLog "GetDecl (" + Self.ident + ") : " + ident
+		Local decl:Object=Object(declsMap.ValueForKey( ident ))
+
+		If Not decl Then
+			If Self.IdentLower() = ident Then
+				' name matches but we are a "module", but not a *real* module..
+				' .. so we can't be looking for ourself
+				If TModuleDecl(Self) And Self.ident.Find(".") = - 1 Then
+					decl = Null
+				Else
+					decl = Self
+				End If
+			End If
+		End If
+		
+		If Not decl Return Null
+		
+		Local adecl:TAliasDecl=TAliasDecl( decl )
+		If Not adecl Return decl
+		
+		If adecl.CheckAccess() Return adecl.decl
+	End Method
+	
+
+	Method FindDecl:Object( ident$, override:Int = False )
+	
+		If Not override And _env<>Self Return GetDecl( ident )
+		
+		Local tscope:TScopeDecl=Self
+		While tscope
+			Local decl:Object=tscope.GetDecl( ident )
+			If decl Return decl
+			tscope=tscope.scope
+		Wend
+	End Method
+	
+	Method GetDeclList:Object( ident$, declList:TFuncDeclList = Null, maxSearchDepth:Int )
+
+		If Not declList Then
+			declList = New TFuncDeclList
+		End If
+
+		Local decl:Object=Object(declsMap.ValueForKey( ident ))
+
+		If Not decl Return Null
+
+		If TFuncDeclList(decl) Then
+			For Local fdecl:TFuncDecl = EachIn TFuncDeclList(decl)
+
+				If Not fdecl.IsSemanted() And Not fdecl.IsSemanting() Then
+					fdecl.Semant
+				End If
+				
+				Local found:Int
+				For Local func:TFuncDecl = EachIn declList
+					If func.equalsFunc(fdecl) Then
+						found = True
+						Exit
+'Else
+'Print func.ToString() + "  didn't match  " + fdecl.ToString()
+					End If
+				Next
+				
+				If Not found Then
+					declList.AddLast(fdecl)
+				End If
+			Next
+			
+			Return declList
+		End If		
+		
+		Return decl
+		
+	End Method
+	
+	' returns a list of all matching named decls in scope
+	Method FindDeclList:Object(ident:String, override:Int = False, declList:TFuncDeclList = Null, maxSearchDepth:Int = SCOPE_ALL, skipMultipleClassScopes:Int = False )
+
+		If Not declList Then
+			declList = New TFuncDeclList
+		End If
+	
+		If Not override And _env<>Self Return GetDeclList( ident, declList, maxSearchDepth )
+		
+		Local hadClassScope:Int
+		Local tscope:TScopeDecl=Self
+		While tscope
+			If TClassDecl(tscope) Then
+			
+				If skipMultipleClassScopes And hadClassScope Then
+					tscope=tscope.scope
+					Continue
+				End If
+			
+				hadClassScope = True
+			End If
+		
+			Local decl:Object=tscope.GetDeclList( ident, declList, maxSearchDepth )
+			'If decl And (Not TFuncDeclList(decl) And declList.IsEmpty()) Return decl
+			If decl Then
+				If TFuncDeclList(decl) Then
+					If TFuncDeclList(decl) <> declList Then
+						For Local d:TDecl = EachIn TFuncDeclList(decl)
+							declList.AddLast(d)
+						Next
+					End If
+				Else
+					declList.AddLast(decl)
+				End If
+			End If
+
+			' if scope is an interface, also check implemented/extended interfaces?
+			If TClassDecl(tscope) Then'And TClassDecl(tscope).IsInterface() Then
+				If TClassDecl(tscope).implments Then
+					For Local idecl:TScopeDecl = EachIn TClassDecl(tscope).implments
+						Local decl:Object=idecl.GetDeclList( ident, declList, maxSearchDepth )
+						If decl Then
+							If TFuncDeclList(decl) Then
+								If TFuncDeclList(decl) <> declList Then
+									For Local d:TDecl = EachIn TFuncDeclList(decl)
+										declList.AddLast(d)
+									Next
+								End If
+							Else
+								declList.AddLast(decl)
+							End If
+						End If
+					Next
+				End If 
+			End If
+			
+			tscope=tscope.scope
+			
+			If TClassDecl(tscope) And maxSearchDepth < SCOPE_CLASS_HEIRARCHY Then
+				Exit
+			Else If TModuleDecl(tscope) And maxSearchDepth < SCOPE_ALL Then
+				Exit
+			End If
+		Wend
+		
+		Return declList
+	End Method
+
+	
+
+'	Method FindDecl:Object( ident$, static:Int = False )
+'		Local decl:Object=GetDecl( ident )
+'		
+'		If Not static Or Not decl Then
+'			If decl Return decl
+'		Else
+'			If Not TFieldDecl(decl) And Not (TFuncDecl(decl) And TFuncDecl(decl).IsMethod()) Then
+'				Return decl
+'			End If
+'		End If
+'		If scope Return scope.FindDecl( ident, static )
+'	End Method
+	
+	Method FindValDecl:TValDecl( ident$, static:Int = False )
+		Local decl:TValDecl=TValDecl( FindDecl( ident ) )
+		
+		' we found a field but we don't have access to it?
+		If TFieldDecl(decl) And static Then
+			' see if there's another decl with the same name elsewhere that we may...
+			' field's scope.scope will be a module.
+			If decl.scope And decl.scope.scope Then
+				Local vDecl:TValDecl = TValDecl( decl.scope.scope.FindDecl( ident, True ) )
+				If vDecl Then
+					decl = vDecl
+				End If
+			End If
+		End If
+		
+		If Not decl Then
+			' try scope search
+			decl = TValDecl( FindDecl( ident, True ) )
+			
+			If Not decl Then
+				' didn't find it? Maybe it is in module local scope?
+				' issue arises when a global initialises with a local variable in the module scope.
+				Local fdecl:Object = FindDecl("__localmain", True)
+				If fdecl Then
+					If TFuncDecl(fdecl) Then
+						decl = TValDecl( TFuncDecl(fdecl).FindDecl( ident ) )
+					Else If TFuncDeclList(fdecl) Then
+						For Local func:TFuncDecl = EachIn TFuncDeclList(fdecl)
+							func.Semant()
+							decl = TValDecl( func.FindDecl( ident ) )
+							If decl Then
+								Exit
+							End If
+						Next
+					End If
+					
+					' a local variable from module local scope can't be seen outside of module local scope...
+					If TLocalDecl(decl) And static Then
+						decl = Null
+					End If
+				End If
+			End If
+		End If
+		If Not decl Return Null
+		decl.AssertAccess
+		decl.Semant
+		Return decl
+	End Method
+
+	Method FindType:TType( ident$,args:TType[] )
+'DebugLog Self.ident + "::FindType::" + ident
+		Local decl:Object=(GetDecl( ident ))
+		If decl Then
+			If TModuleDecl(decl) Then
+				decl = TModuleDecl(decl).GetDecl(ident)
+			End If
+			Local ty:TType=TType(decl)
+			If ty
+				If args.Length Err "Wrong number of type arguments"
+				Return ty
+			EndIf
+			Local cdecl:TClassDecl=TClassDecl( decl )
+			If cdecl
+				cdecl.AssertAccess
+				If Not cdecl.instanceof Then
+					cdecl=cdecl.GenClassInstance( args )
+					cdecl.Semant
+				End If
+				Return cdecl.objectType
+			EndIf
+		EndIf
+		If scope Return scope.FindType( ident,args )
+	End Method
+	
+	Method FindScopeDecl:TScopeDecl( ident$ )
+		Local decl:TScopeDecl=TScopeDecl( FindDecl( ident ) )
+		If Not decl Return Null
+		decl.AssertAccess
+		decl.Semant
+		Return decl
+	End Method
+Rem	
+	Method FindClassDecl:TClassDecl( ident$,args:TClassDecl[] = Null )
+		Local decl:TClassDecl=TClassDecl( GetDecl( ident ) )
+		If Not args Then
+			args = New TClassDecl[0]
+		End If
+		If Not decl
+			If scope Return scope.FindClassDecl( ident,args )
+			Return Null
+		EndIf
+		decl.AssertAccess
+		decl.Semant
+		Return decl.GenClassInstance( args )
+	End Method
+End Rem	
+	Method FindModuleDecl:TModuleDecl( ident$ )
+'DebugStop
+		Local decl:TModuleDecl=TModuleDecl( GetDecl( ident ) )
+		If Not decl
+			If scope Return scope.FindModuleDecl( ident )
+			Return Null
+		EndIf
+		decl.AssertAccess
+		
+		' only semant on "real" module
+		If Not decl.declImported Then
+			decl.Semant
+		End If
+		Return decl
+	End Method
+	
+	Method FindBestMatchForArgs:TFuncDecl(argExprs:TExpr[], matches:TList)
+
+		Local bestMatch:TFuncDecl = Null
+		Local totals:Int[] = New Int[matches.count()]
+		Local index:Int
+		
+		For Local func:TFuncDecl = EachIn matches
+
+			Local argDecls:TArgDecl[]=func.argDecls
+			
+			For Local i:Int=0 Until argDecls.Length
+	
+				If i<argExprs.Length And argExprs[i]
+				
+					Local declTy:TType=argDecls[i].ty
+					Local exprTy:TType=argExprs[i].exprType
+
+					If TFunctionPtrType(declTy) And TInvokeExpr(argExprs[i]) Then
+						If TFunctionPtrType(declTy).equalsDecl(TInvokeExpr(argExprs[i]).decl) Then
+							Continue
+						End If
+					End If
+
+					' not ideal - since the arg is configured as a Byte Ptr, we can't check that the function is of the correct type.
+					If IsPointerType(declTy, TType.T_BYTE) And TInvokeExpr(argExprs[i]) And TInvokeExpr(argExprs[i]).invokedWithBraces = 0 Then
+						Continue
+					End If
+					
+					If TFunctionPtrType(declTy) And IsPointerType(exprTy, TType.T_BYTE) Then
+						Continue
+					End If
+					
+					If exprTy.EqualsType( declTy ) Continue
+					
+					' not an exact match. increase distance...
+					totals[index] :+ exprTy.DistanceToType(declTy)
+					
+				End If
+				
+			Next
+			
+			index :+ 1
+
+		Next
+		
+		Local tot:Int = -1
+		index = 0
+		Local i:Int
+		For Local func:TFuncDecl = EachIn matches
+			If tot = -1 Or totals[i] < tot Then
+				tot = totals[i]
+				bestMatch = func
+			Else If tot = totals[i] Then
+				If bestMatch.IsMethod() And Not func.IsMethod() Then
+					' 
+				Else If Not bestMatch.IsMethod() And func.IsMethod() Then
+					bestMatch = func
+				Else If (bestMatch.scope <> func.scope) And (TClassDecl(bestMatch.scope).ExtendsClass(TClassDecl(func.scope))) Then
+					' match is in different level of class hierarchy
+					Exit
+				Else
+					' a tie?
+					Err "Unable to determine overload to use: "+ bestMatch.ToString()+" or "+func.ToString()+"."
+				End If
+			End If
+			i :+ 1
+		Next
+		
+		Return bestMatch
+		
+	End Method
+	
+	Method FindFuncDecl:TFuncDecl( ident$,argExprs:TExpr[] = Null,explicit:Int=False, isArg:Int = False, isIdentExpr:Int = False, throwOnNotMatched:Int = False, maxSearchDepth:Int )
+'DebugLog "FindFuncDecl : " + ident
+'If ident = "new" Then DebugStop
+		Local foundIdentMatch:Int
+		Local funcs:TFuncDeclList
+
+		' does ident exist?
+		Local f:Object = FindDeclList(ident, True,,maxSearchDepth)
+		If Not f Then Return Null
+		
+		funcs = TFuncDeclList( f )
+		Local fp:TFuncDecl
+		
+		' not a function list, test for a function ptr var
+		If Not funcs Or funcs.IsEmpty() Then
+
+			' we found a funcdecl
+			If TFuncDecl(f) Then
+				funcs = New TFuncDeclList
+				funcs.AddLast(f)
+			End If
+			
+			If TVarDecl(f) Then
+				If Not TVarDecl(f).IsSemanted() Then
+					TVarDecl(f).Semant()
+				End If
+				If TFunctionPtrType(TVarDecl(f).ty) Then
+					funcs = New TFuncDeclList
+					fp = TFunctionPtrType(TVarDecl(f).ty).func
+					If Not fp.scope Then
+						fp.scope = TVarDecl(f).scope
+					End If
+					If Not fp.ident Then
+						fp.ident = TVarDecl(f).ident
+					End If
+					funcs.AddLast fp
+				End If
+			End If
+		End If
+		' was neither... lets bug out
+		If Not funcs Return Null
+		
+'		If Not funcs Then Return Null
+		
+		For Local func:TDecl = EachIn funcs
+			If Not func.IsSemanting() Then
+				func.Semant()
+			End If
+		Next
+		
+		'Local f:TDecl = TDecl(findDecl(ident))
+		'If Not f Then Return Null
+		
+				
+			'Local func:TFuncDecl = TFuncDecl(f)
+'			If Not func Then
+'				If TVarDecl(f) Then
+'					If Not f.IsSemanted() Then
+'						f.Semant()
+'					End If
+'					If TFunctionPtrType(TVarDecl(f).ty) Then
+'						func = TFunctionPtrType(TVarDecl(f).ty).func
+'						If Not func.scope Then
+'							func.scope = f.scope
+'						End If
+'						If Not func.ident Then
+'							func.ident = f.ident
+'						End If
+'					End If
+'				End If
+'			End If
+'			If Not func Return Null
+	
+		If Not argExprs
+			argExprs = New TExpr[0]
+		End If
+	
+		'func.Semant()
+		
+		Local match:TFuncDecl,isexact:Int
+		Local _err$
+		Local errorDetails:String
+		Local matches:TList = New TList
+
+		Local noExtendString:Int = True
+		Local generateWarnings:Int = False
+
+		' double test for matches.
+		' * first time through we don't allow up-casting args to String
+		'    if we get a match on the first pass, we'll take it.
+		' * second iteration we allow up-casting numerics to string
+		' * third iteration is valid if opt_warnover is enabled
+		'    this will allow down-casting of numerics (eg. double->float)
+		'    warnings will be generated if this produces valid results.
+		' if after all that, there's no match, then we can fail it.
+		For Local n:Int = 0 Until 3
+		
+			If n > 1 Then
+				If Not opt_warnover Then
+					Continue
+				Else
+					generateWarnings = True
+				End If
+			End If
+		
+			errorDetails = ""
+		
+			If n Then
+				noExtendString = False
+			End If
+
+			For Local iDecl:TDecl = EachIn funcs
+			
+				Local func:TFuncDecl = TFuncDecl(iDecl)
+				
+				If Not func Then
+					If TVarDecl(iDecl) Then
+'						If Not TVarDecl(iDecl).IsSemanted() Then
+'							TVarDecl(f).Semant()
+'						End If
+						If TFunctionPtrType(TVarDecl(iDecl).ty) Then
+							'funcs = New TFuncDeclList
+							fp = TFunctionPtrType(TVarDecl(iDecl).ty).func
+							If Not fp.scope Then
+								fp.scope = TVarDecl(iDecl).scope
+							End If
+							If Not fp.ident Then
+								fp.ident = TVarDecl(iDecl).ident
+							End If
+							'funcs.AddLast fp
+							func = fp
+						End If
+					End If
+					
+					If Not func Then
+						Continue
+					End If
+				End If
+				
+	
+			'While True
+				If Not func.CheckAccess() Continue
+				
+				Local argDecls:TArgDecl[]=func.argDecls
+				
+				Local exact:Int=True
+				Local possible:Int=True
+				
+				foundIdentMatch = True
+
+				' we found a matching name - this is probably the one we mean...
+				If isArg Then
+					'match=func
+					matches.AddLast(func)
+					Exit
+				End If
+
+				If argExprs.Length>argDecls.Length
+					exact = False
+					Continue
+				End If
+
+				For Local i:Int=0 Until argDecls.Length
+	
+					If i<argExprs.Length And argExprs[i]
+					
+						Local arg:TExpr = argExprs[i]
+					
+						Local declTy:TType=argDecls[i].ty
+						Local exprTy:TType=arg.exprType
+						
+						Local widensTest:Int = True
+						
+						' for numeric constants, allow them to be auto-cast unless
+						If TConstExpr(arg) And IsNumericType(exprTy) And Not TConstExpr(arg).typeSpecific And TConstExpr(arg).CompatibleWithType(declTy) Then
+							widensTest = False
+						End If
+	
+						If TFunctionPtrType(declTy) And TInvokeExpr(arg) Then
+							If TFunctionPtrType(declTy).equalsDecl(TInvokeExpr(arg).decl) Continue
+						End If
+	
+						' not ideal - since the arg is configured as a Byte Ptr, we can't check that the function is of the correct type.
+						If IsPointerType(declTy, TType.T_BYTE) And TInvokeExpr(arg) And TInvokeExpr(arg).invokedWithBraces = 0 Then
+							Continue
+						End If
+						
+						If TFunctionPtrType(declTy) And IsPointerType(exprTy, TType.T_BYTE) Then
+							Continue
+						End If
+						
+						If exprTy.EqualsType( declTy ) Continue
+						
+						exact=False
+						
+						If Not generateWarnings Then
+							If Not explicit And exprTy.ExtendsType( declTy, noExtendString, widensTest ) Continue
+						Else
+							If Not explicit Then
+								' fails widen test
+								If Not exprTy.ExtendsType( declTy, noExtendString, True ) Then
+									' but passes non-widen test
+									If exprTy.ExtendsType( declTy, noExtendString, False ) Then
+										' generate a warning, and accept it
+										Warn "In call to " + func.ToString()+ ". Argument #"+(i+1)+" is ~q" + exprTy.ToString()+"~q but declaration is ~q"+declTy.ToString()+"~q. "
+										Continue
+									End If
+								Else
+									Continue
+								End If
+							End If
+						End If
+	
+						' make a more helpful error message
+						errorDetails :+ "Argument #"+(i+1)+" is ~q" + exprTy.ToString()+"~q but declaration is ~q"+declTy.ToString()+"~q. "
+
+					Else If Not argDecls[i].init
+	
+						If (func.attrs & FUNC_PTR) Or isIdentExpr Then
+							exact=False
+							Exit
+						End If
+	
+						' if this argument is missing and there isn't a default...
+						errorDetails :+  "Missing function parameter '" + argDecls[i].ident + "'"
+	
+					Else ' for case of argdecls having default args
+						exact=False
+						If Not explicit Exit
+					EndIf
+				
+					possible=False
+					Exit
+				Next
+				
+				If Not possible Continue
+				
+				If exact
+					If isexact
+						Err "Unable to determine overload to use: "+match.ToString()+" or "+func.ToString()+"."
+					Else
+						_err=""
+						'match=func
+						matches.AddLast(func)
+						isexact=True
+						Exit
+					EndIf
+				Else
+					If Not isexact
+						'If match 
+						'	_err="Unable to determine overload to use: "+match.ToString()+" or "+func.ToString()+"."
+						'Else
+							'match=func
+							matches.AddLast(func)
+						'EndIf
+					EndIf
+				EndIf
+				'Exit
+			Next
+			
+			If Not matches.IsEmpty() Then
+				Exit
+			End If
+			
+		Next
+		
+		If matches.Count() = 1 Then
+			match = TFuncDecl(matches.First())
+		Else
+			' find best match
+			match = FindBestMatchForArgs(argExprs, matches)
+		End If
+		
+		If Not isexact
+			If _err Err _err
+			If explicit Return Null
+		EndIf
+
+		' last try... maybe we are trying to use it as a function pointer? (no args)
+		If Not match Then
+			If argExprs Then
+				'match = func
+'				match.maybeFunctionPtr = True
+			End If
+		Else If Not argExprs Then
+			' if there are no args, the actual function may have none either... so we may still be trying to use it as a function pointer
+			match.maybeFunctionPtr = True
+		End If
+		
+		If Not match
+			Local t$
+			For Local i:Int=0 Until argExprs.Length
+				If t t:+","
+				If argExprs[i] t:+argExprs[i].exprType.ToString()
+			Next
+			If foundIdentMatch Then
+				If throwOnNotMatched Then
+					Throw "Unable to find overload for "+ident+"("+t+"). " + errorDetails
+				Else
+					Err "Unable to find overload for "+ident+"("+t+"). " + errorDetails
+				End If
+			Else
+				If throwOnNotMatched Then
+					Throw "Identifier '" + ident + "' not found."
+				Else
+					Err "Identifier '" + ident + "' not found."
+				End If
+			End If
+		EndIf
+		
+		match.AssertAccess
+
+		Return match
+	End Method
+
+	Method FindLoop:TStmt(ident:String = Null)
+
+		If TBlockDecl(Self) And TBlockDecl(Self).extra Then
+			Local loop:TLoopStmt = TLoopStmt(TBlockDecl(Self).extra)
+			If ident Then
+				If loop.loopLabel And loop.loopLabel.IdentLower() = ident Then
+					Return loop
+				End If
+			Else
+				Return loop
+			End If
+		End If
+
+		If TFuncDecl(scope) Or TModuleDecl(scope)
+			Return Null
+		End If
+		
+		If scope Return scope.FindLoop( ident )
+	End Method
+	
+	Method OnSemant()
+	End Method
+	
+	Method Clear()
+	End Method
+
+End Type
+
+Type TBlockDecl Extends TScopeDecl
+	Field stmts:TList=New TList
+	Field extra:Object
+	
+	Method Create:TBlockDecl( scope:TScopeDecl, generated:Int = False )
+		Self.scope=scope
+		Self.generated = generated
+		
+		attrs :| (scope.attrs & DECL_NODEBUG)
+		
+		Return Self
+	End Method
+	
+	Method AddStmt( stmt:TStmt )
+		stmts.AddLast stmt
+	End Method
+	
+	Method OnCopy:TDecl(deep:Int = True)
+		Local t:TBlockDecl=New TBlockDecl
+		t.scope = scope
+		If deep Then
+			For Local stmt:TStmt=EachIn stmts
+				t.AddStmt stmt.Copy( t )
+			Next
+		End If
+		t.extra = extra
+		t.generated = generated
+		Return t
+	End Method
+
+	Method OnSemant()
+		PushEnv Self
+		
+		' any nested functions?
+		For Local fdecl:TFuncDecl = EachIn _decls
+			fdecl.Semant
+		Next
+
+		' any nested classes?
+		For Local cdecl:TClassDecl = EachIn _decls
+			cdecl.Semant
+		Next
+		
+		For Local stmt:TStmt=EachIn stmts
+			stmt.Semant
+		Next
+		PopEnv
+	End Method
+
+	Method CopyBlock:TBlockDecl( scope:TScopeDecl )
+		Local t:TBlockDecl=TBlockDecl( Copy() )
+		t.scope=scope
+		Return t
+	End Method
+
+	Method Clear()
+		For Local stmt:TStmt=EachIn stmts
+			stmt.Clear
+		Next
+	End Method
+
+End Type
+
+Const FUNC_METHOD:Int=   $0001			'mutually exclusive with ctor
+Const FUNC_CTOR:Int=     $0002
+Const FUNC_PROPERTY:Int= $0004
+Const FUNC_DTOR:Int=     $0008
+Const FUNC_BUILTIN:Int = $0080
+Const FUNC_PTR:Int=      $0100
+Const FUNC_INIT:Int =    $0200
+Const FUNC_NESTED:Int =  $0400
+Const FUNC_OPERATOR:Int= $0800
+Const FUNC_FIELD:Int=    $1000
+
+'Fix! A func is NOT a block/scope!
+'
+Type TFuncDecl Extends TBlockDecl
+
+	Field retType:TType
+	Field retTypeExpr:TType
+	Field argDecls:TArgDecl[]
+
+	Field overrides:TFuncDecl
+	Field superCtor:TInvokeSuperExpr
+	
+	Field castTo:String
+	Field noCastGen:Int
+	
+	Field maybeFunctionPtr:Int
+	
+	Field returnTypeSubclassed:Int
+	
+	Field mangled:String
+	Field noMangle:Int
+	
+	Field equalsBuiltIn:Int = -1
+	
+	Method CreateF:TFuncDecl( ident$,ty:TType,argDecls:TArgDecl[],attrs:Int )
+		Self.ident=ident
+		Self.retTypeExpr=ty
+		If argDecls
+			Self.argDecls=argDecls
+		Else
+			Self.argDecls = New TArgDecl[0]
+		End If
+		Self.attrs=attrs
+		Return Self
+	End Method
+	
+	Method OnCopy:TDecl(deep:Int = True)
+		Local args:TArgDecl[]=argDecls[..]
+		For Local i:Int=0 Until args.Length
+			args[i]=TArgDecl( args[i].Copy() )
+		Next
+		Local t:TFuncDecl=New TFuncDecl.CreateF( ident,retType,args,attrs)
+		If deep Then
+			For Local stmt:TStmt=EachIn stmts
+				t.AddStmt stmt.Copy( t )
+			Next
+		End If
+		t.retType = retType
+		t.retTypeExpr = retTypeExpr
+		t.scope = scope
+		t.overrides = overrides
+		t.superCtor = superCtor
+		t.castTo = castTo
+		t.noCastGen = noCastGen
+		t.munged = munged
+		t.metadata = metadata
+		t.mangled = mangled
+		t.noMangle = noMangle
+		Return  t
+	End Method
+
+	Method GenInstance:TDecl()
+		Local inst:TFuncDecl=New TFuncDecl
+		InitInstance inst
+		inst.retTypeExpr=retTypeExpr
+		inst.argDecls=argDecls[..]
+		For Local i:Int=0 Until argDecls.Length
+			inst.argDecls[i]=TArgDecl( argDecls[i].GenInstance() )
+		Next
+		Return inst
+	End Method
+	
+	Method ToString$()
+		Local t$
+		For Local decl:TArgDecl=EachIn argDecls
+			If t t:+","
+			t:+decl.ToString()
+		Next
+		Local q$
+		If IsCtor()
+			q="Method "+Super.ToString()
+		Else
+			If IsMethod() q="Method " Else q="Function "
+			q:+Super.ToString()
+			If retType
+				If Not TVoidType(retType) Then
+					q:+":"+retType.ToString()
+				End If
+			Else If retTypeExpr 
+				q:+":"+retTypeExpr.ToString()
+			'Else
+			'	q:+":"+"?"
+			EndIf
+		EndIf
+		Return q+"("+t+")"
+	End Method
+
+	Method ToTypeString:String()
+		Local t$
+		For Local decl:TArgDecl=EachIn argDecls
+			If t t:+","
+			t:+decl.ToTypeString()
+		Next
+		Local q$
+		If Not IsCtor() Then
+			If retType
+				If Not TVoidType(retType) Then
+					q:+retType.ToString()
+				End If
+			Else If retTypeExpr 
+				q:+retTypeExpr.ToString()
+			EndIf
+		End If
+		Return q+"("+t+")"
+	End Method
+
+	Method IsBuiltIn:Int()
+		Return (attrs & FUNC_BUILTIN)<>0
+	End Method
+	
+	Method IsCtor:Int()
+		Return (attrs & FUNC_CTOR)<>0
+	End Method
+
+	Method IsDtor:Int()
+		Return (attrs & FUNC_DTOR)<>0
+	End Method
+
+	Method IsMethod:Int()
+		Return (attrs & FUNC_METHOD)<>0
+	End Method
+	
+	Method IsAnyMethod:Int()
+		Return IsMethod() Or IsCtor() Or IsDtor() 
+	End Method
+	
+	Method IsStatic:Int()
+		Return (attrs & (FUNC_METHOD|FUNC_CTOR))=0
+	End Method
+	
+	Method IsProperty:Int()
+		Return (attrs & FUNC_PROPERTY)<>0
+	End Method
+
+	Method IsField:Int()
+		Return (attrs & FUNC_FIELD)<>0
+	End Method
+		
+	Method EqualsArgs:Int( decl:TFuncDecl ) ' careful, this is not commutative!
+		If argDecls.Length<>decl.argDecls.Length Return False
+		For Local i:Int=0 Until argDecls.Length
+			' objects can be subclasses as well as the same.
+			If TObjectType(decl.argDecls[i].ty) Then
+				If Not decl.argDecls[i].ty.EqualsType( argDecls[i].ty ) And Not decl.argDecls[i].ty.ExtendsType( argDecls[i].ty ) Return False
+			Else
+				If Not decl.argDecls[i].ty.EqualsType( argDecls[i].ty ) Return False
+			End If
+		Next
+		Return True
+	End Method
+
+	Method EqualsFunc:Int( decl:TFuncDecl ) ' careful, this is not commutative!
+		If IsCtor() Then
+			Return EqualsArgs( decl )
+		Else
+			' matching args?
+			If EqualsArgs( decl ) Then
+				' matching return type?
+				If TObjectType(retType) Or TArrayType(retType) Or TStringType(retType) Then
+					Return retType.EqualsType( decl.retType ) Or retType.ExtendsType( decl.retType )' Or decl.retType.EqualsType( retType )) And EqualsArgs( decl )
+				Else
+					Return retType.EqualsType( decl.retType )
+				End If
+			End If
+		End If
+		Return False
+	End Method
+
+	Method OnSemant()
+
+		Local strictVoidToInt:Int = False
+
+		If isCtor() Or isDtor() Then
+			If ClassScope() And ClassScope().IsInterface() Then
+				Err ident + "() cannot be declared in an Interface."
+			End If
+		End If
+
+		'semant ret type
+		If Not retTypeExpr Then
+			If Not retType Then ' may have previously been set (if this is a function pointer)
+				retType = TType.voidType
+			Else If TIdentType(retType)
+				retType = retType.Semant()
+			Else
+				' for Strict code, a void return type becomes Int
+				If TVoidType(retType) And Not ModuleScope().IsSuperStrict() Then
+					strictVoidToInt = True
+					retType = New TIntType
+				End If
+			End If
+		Else
+			' pass the scope into the function ptr
+			Local retTypeExpr_:TType = retTypeExpr
+			While TArrayType(retTypeExpr_) ' look into array types, since the element type might be function ptr
+				retTypeExpr_ = TArrayType(retTypeExpr_).elemType
+			Wend
+			If TFunctionPtrType(retTypeExpr_) Then
+				If Not TFunctionPtrType(retTypeExpr_).func.scope Then
+					If scope Then
+						TFunctionPtrType(retTypeExpr_).func.scope = scope
+					Else
+						TFunctionPtrType(retTypeExpr_).func.scope = _env
+					End If
+				End If
+			End If
+		
+			retType=retTypeExpr.Semant()
+			
+			' for Strict code, a void return type becomes Int
+			If TVoidType(retType) And Not ModuleScope().IsSuperStrict() And Not IsDTor() Then
+				strictVoidToInt = True
+				retType = New TIntType
+			End If
+		End If
+		
+		If TArrayType( retType ) And Not retType.EqualsType( retType.ActualType() )
+'			Err "Return type cannot be an array of generic objects."
+		EndIf
+		
+		'semant args
+		For Local arg:TArgDecl=EachIn argDecls
+			InsertDecl arg
+			arg.Semant
+		Next
+
+		' if we are a function pointer declaration, we just want to semant the args here.
+		If attrs & FUNC_PTR Return
+
+		If actual<>Self Return
+		
+		'check for duplicate decl
+		If ident Then
+			For Local decl:TFuncDecl=EachIn scope.SemantedFuncs( ident )
+				If decl<>Self And EqualsArgs( decl ) And Not decl.IsCTOR()
+					Err "Duplicate declaration "+ToString()
+				EndIf
+				If noMangle Then
+					If decl<>Self Then
+						If decl.argDecls.Length = 0 Then
+							Err "You cannot apply NoMangle to the function, as another function with no arguments exists."
+						Else If decl.NoMangle Then
+							Err "Another function is already declared with NoMangle."
+						End If
+					End If
+				End If
+			Next
+		End If
+		
+		' any nested functions?
+		For Local fdecl:TFuncDecl = EachIn _decls
+			fdecl.Semant
+		Next
+		
+		'get cdecl, sclasss
+		Local cdecl:TClassDecl=ClassScope(),sclass:TClassDecl
+		If cdecl sclass=TClassDecl( cdecl.superClass )
+		
+		'prefix call to super ctor if necessary
+'		If IsCtor() And superCtor=Null And sclass
+'			If sclass.FindFuncDecl( "new", Null )
+'				superCtor=New TInvokeSuperExpr.Create( "new" )
+'				stmts.AddFirst New TExprStmt.Create( superCtor )
+'			EndIf
+'		EndIf
+		
+		'check we exactly match an override
+		If sclass 'And IsMethod()
+
+			While sclass
+				Local errorDetails:String = ""
+
+				Local found:Int
+				For Local decl:TFuncDecl=EachIn sclass.FuncDecls( )
+					
+					If decl.IdentLower() = IdentLower() Then
+
+						If IdentLower() = "new" Continue
+						If IdentLower() = "delete" Continue
+
+						found=True
+
+						If Not decl.IsSemanted() Then
+							decl.Semant
+						End If
+
+						' check void return type strictness, and fail if appropriate.
+						Local voidReturnTypeFail:Int = False
+						' super has void return type... so it is superstrict (or inherited from)
+						If TVoidType(decl.retType) And TIntType(retType) Then
+							' if we are only strict, we may fail on type mismatch
+							If Not ModuleScope().IsSuperStrict() Then
+								' we have the option of upgrading our return type to match superstrict parent
+								If opt_strictupgrade And strictVoidToInt Then
+									retType = TType.voidType
+								Else
+									' otherwise...
+									voidReturnTypeFail = True
+								End If
+							End If
+						End If
+
+						If EqualsFunc( decl ) And Not voidReturnTypeFail
+
+							' check we aren't attempting to assign weaker access modifiers
+							If (IsProtected() And decl.IsPublic()) Or (IsPrivate() And (decl.IsProtected() Or decl.IsPublic())) Then
+							
+								Err PrivilegeError(Self, decl)
+							
+							End If
+						
+							If (TObjectType(retType) And TObjectType(decl.retType )) Or (TArrayType(retType) And TArrayType(decl.retType)) Then
+								If Not retType.EqualsType( decl.retType ) And retType.ExtendsType( decl.retType ) Then
+									returnTypeSubclassed = True
+								End If
+							End If
+							
+							overrides=TFuncDecl( decl.actual )
+						Else
+							' method overloading?
+							If Not EqualsArgs(decl) Then
+								found = False
+								Continue
+							End If
+							
+							'prepare a more detailed error message
+							If (Not retType.EqualsType( decl.retType ) Or Not retType.ExtendsType( decl.retType )) Or (decl.retType And Not decl.retType.EqualsType( retType )) Or voidReturnTypeFail
+								errorDetails :+ "Return type is ~q"+retType.ToString()+"~q, expected ~q"+decl.retType.ToString()+"~q. "
+								If voidReturnTypeFail Then
+									errorDetails :+ "You may have Strict type overriding SuperStrict type. "
+								End If
+							Else
+								found = False
+								Continue
+							End If
+
+							Local argCount:Int = Min(argDecls.Length, decl.argDecls.Length)
+							If argCount > 0
+								For Local i:Int=0 Until argCount
+									If Not argDecls[i].ty.EqualsType( decl.argDecls[i].ty )
+										errorDetails :+ "Argument #"+(i+1)+" is ~q" + argDecls[i].ty.ToString()+"~q, expected ~q"+decl.argDecls[i].ty.ToString()+"~q. "
+									End If
+								Next
+							EndIf
+							'remove last space
+							errorDetails = errorDetails.Trim()
+						EndIf
+					End If
+				Next
+				If found
+					If Not overrides Err "Overriding method does not match any overridden method. (Detail: " + errorDetails+")"
+					If overrides.IsFinal() Err "Final methods cannot be overridden."
+					' for overrides, make the ident match that of the superclass
+					ident = overrides.ident
+					
+					Exit
+				EndIf
+				sclass=sclass.superClass
+			Wend
+		EndIf
+
+		'append a return statement if necessary
+		If Not IsExtern() And Not TVoidType( retType ) And Not TReturnStmt( stmts.Last() )
+			If Not isCtor() And Not isDtor()
+				Local stmt:TReturnStmt
+
+				stmt=New TReturnStmt.Create( New TConstExpr.Create( retType,"" ) )
+				stmt.generated = True
+
+				stmt.errInfo=errInfo
+				stmts.AddLast stmt
+			End If
+		EndIf
+
+		attrs:|DECL_SEMANTED
+		
+		Super.OnSemant()
+	End Method
+
+	Method CheckAccess:Int()
+		Local cd:TClassDecl = ClassScope()
+		If cd Then
+			If IsPrivate() And cd<>_env.ClassScope() Return False
+			If IsProtected() Then
+				Local ec:TClassDecl = _env.ClassScope()
+				If Not ec Return False
+				If Not ec.ExtendsClass(cd) Return False
+			End If
+			Return True
+		End If
+		Return Super.CheckAccess()
+	End Method
+
+	Function PrivilegeError:String(decl:TFuncDecl, decl2:TFuncDecl)
+		Local p:String
+		If decl.IsProtected() Then
+			p = "Protected"
+		Else
+			p = "Private"
+		End If
+		
+		Local dp:String
+		If decl2.IsPublic() Then
+			dp = "Public"
+		Else
+			dp = "Protected"
+		End If
+	
+		Return decl.ToString() + " clashes with " + decl2.ToString() + ". Attempt to assign weaker access privileges ('" + p + "'), was '" + dp + "'."
+	End Function
+	
+End Type
+
+Type TNewDecl Extends TFuncDecl
+
+	Field chainedCtor:TNewExpr
+	
+	Method OnCopy:TDecl(deep:Int = True)
+		Local args:TArgDecl[]=argDecls[..]
+		For Local i:Int=0 Until args.Length
+			args[i]=TArgDecl( args[i].Copy() )
+		Next
+		Local t:TNewDecl = TNewDecl(New TNewDecl.CreateF( ident,retType,args,attrs &~DECL_SEMANTED ))
+		If deep Then
+			For Local stmt:TStmt=EachIn stmts
+				t.AddStmt stmt.Copy(t)
+			Next
+		End If
+		t.retType = retType
+		t.scope = scope
+		t.overrides = overrides
+		t.superCtor = superCtor
+		t.castTo = castTo
+		t.noCastGen = noCastGen
+		t.munged = munged
+		t.metadata = metadata
+		t.mangled = mangled
+		t.noMangle = noMangle
+		t.chainedCtor = chainedCtor
+
+		Return  t
+	End Method
+
+
+End Type
+
+
+'Const CLASS_INTERFACE:Int=1
+'Const CLASS_TEMPLATEARG:Int=2
+'Const CLASS_TEMPLATEINST:Int=4
+'Const CLASS_INSTANCED:Int=8		'class used in New?
+Const CLASS_INSTANCED:Int=1
+Const CLASS_EXTENDSOBJECT:Int=2
+Const CLASS_FINALIZED:Int=4
+
+Type TNullDecl Extends TClassDecl
+
+End Type
+
+Type TClassDecl Extends TScopeDecl
+
+	Field lastOffset:Int
+
+	Field args:TTemplateArg[]
+	Field superTy:TIdentType
+	Field impltys:TIdentType[]
+
+	Field superClass:TClassDecl
+	
+	Field implments:TClassDecl[]			'interfaces immediately implemented
+	Field implmentsAll:TClassDecl[]		'all interfaces implemented
+	
+	Field instanceof:TClassDecl			'for instances
+	Field instances:TList		'for actual (non-arg, non-instance)
+	Field instArgs:TType[]
+
+	Field objectType:TObjectType '"canned" objectType
+	Field globInit:Int
+	Field templateSource:TTemplateRecord
+
+	'Global nullObjectClass:TClassDecl=New TNullDecl.Create( "{NULL}",Null,Null,Null,DECL_ABSTRACT|DECL_EXTERN )
+	
+	Method Create:TClassDecl( ident$,args:TTemplateArg[],superTy:TIdentType,impls:TIdentType[],attrs:Int )
+		Self.ident=ident
+		Self.args=args
+		Self.superTy=superTy
+		Self.impltys=impls
+		Self.attrs=attrs
+		Self.objectType=New TObjectType.Create( Self )
+		If args
+			instances=New TList
+		EndIf
+		Return Self
+	End Method
+	
+	Method OnCopy:TDecl(deep:Int = True)
+		InternalErr
+	End Method
+	
+	Method ToString$()
+		Local t$
+
+		If args Then
+			For Local i:Int=0 Until args.Length
+				If i Then
+					t :+ ","
+				End If
+				t:+args[i].ToString()
+			Next
+		ElseIf instargs
+			For Local i:Int=0 Until instargs.Length
+				If i Then
+					t :+ ","
+				End If
+				t :+ instargs[i].ToString()
+			Next
+		End If
+		If t t="<"+t+">"
+		Return ident+t
+	End Method
+
+	Method ToTypeString:String()
+		Return ToString()
+	End Method
+Rem
+	Method GenClassInstance:TClassDecl( instArgs:TClassDecl[] )
+		If Not IsSemanted() InternalErr
+		
+		'no args
+		If Not instArgs
+			If Not args Return Self
+			If instanceof Return Self
+			For Local inst:TClassDecl=EachIn instances
+				If _env.ClassScope()=inst Return inst
+			Next
+		EndIf
+		
+		'If Not instanceof And Not instArgs Return Self
+		
+		'check number of args
+		If instanceof Or args.Length<>instArgs.Length
+			Err "Wrong number of class arguments for "+ToString()
+		EndIf
+		
+		'look for existing instance
+		For Local inst:TClassDecl=EachIn instances
+			Local equal:Int=True
+			For Local i:Int=0 Until args.Length
+				If inst.args[i]=instArgs[i] Continue
+				equal=False
+				Exit
+			Next
+			If equal Return inst
+		Next
+		
+		Local inst:TClassDecl=New TClassDecl
+
+		InitInstance inst
+
+		inst.scope=scope
+		inst.attrs:|CLASS_TEMPLATEINST
+		inst.args=instArgs
+		inst.superTy=superTy
+		inst.instanceof=Self
+		instances.AddLast inst
+		
+		For Local i:Int=0 Until args.Length
+			inst.InsertDecl New TAliasDecl.Create( args[i].ident,instArgs[i] )
+		Next
+		
+		For Local decl:TDecl=EachIn _decls
+			If TClassDecl( decl ) Continue
+			inst.InsertDecl decl.GenInstance()
+		Next
+
+		'inst.Semant
+		'A bit cheeky...
+		inst.OnSemant
+		inst.attrs:|DECL_SEMANTED
+		
+		Return inst
+	End Method
+End Rem
+	Method GenClassInstance:TClassDecl( instArgs:TType[], declImported:Int = False )
+
+		If instanceof InternalErr
+		
+		'no args
+		If Not instArgs
+			If Not args Return Self
+			For Local inst:TClassDecl=EachIn instances
+				If _env.ClassScope()=inst Return inst
+			Next
+		EndIf
+		
+		'check number of args
+		If args.Length<>instArgs.Length
+			Err "Wrong number of type arguments for class "+ToString()
+		EndIf
+		
+		'look for existing instance
+		For Local inst:TClassDecl=EachIn instances
+			Local equal:Int=True
+			For Local i:Int=0 Until args.Length
+				If Not inst.instArgs[i].EqualsType( instArgs[i] )
+					equal=False
+					Exit
+				EndIf
+			Next
+			If equal Return inst
+		Next
+
+		Local inst:TClassDecl=New TClassDecl.Create( ident,Null,superTy,impltys, attrs )
+
+		inst.attrs:&~DECL_SEMANTED
+
+		inst.munged=munged
+		inst.errInfo=errInfo
+		inst.scope=scope
+		inst.instanceof=Self
+		inst.instArgs=instArgs
+		inst.templateSource = templateSource
+		instances.AddLast inst
+		
+		inst.declImported = declImported
+
+		For Local i:Int=0 Until args.Length
+		
+			' ensure parameter types are compatible
+			If args[i].superTy Then
+				args[i].superTy = args[i].superTy.Semant()
+				If Not instArgs[i].EqualsType(args[i].superTy) And Not instArgs[i].ExtendsType(args[i].superTy) Then
+					Err "Type parameter '" + instArgs[i].ToString() + "' is not within its bound; should extend '" + args[i].superTy.ToString() + "'"
+				End If
+			End If
+		
+			inst.InsertDecl New TAliasDecl.Create( args[i].ident,instArgs[i],0 )
+		Next
+
+		For Local decl:TDecl=EachIn _decls
+			If TClassDecl(decl) Then
+				inst.InsertDecl TClassDecl(decl).GenClassInstance(instArgs, declImported), True
+			Else
+				inst.InsertDecl decl.Copy(), True
+			End If
+		Next
+
+		If Not declImported Then
+			inst.scope = _env.ModuleScope()
+		End If
+
+		Return inst
+	End Method
+
+	Method IsInterface:Int()
+		Return (attrs & CLASS_INTERFACE)<>0
+	End Method
+
+	Method IsThrowable:Int()
+		Return (attrs & CLASS_THROWABLE)<>0
+	End Method
+
+	Method IsFinalized:Int()
+		Return (attrs & CLASS_FINALIZED)<>0
+	End Method
+	
+	Method IsStruct:Int()
+		Return (attrs & CLASS_STRUCT)<>0
+	End Method
+
+	Method ExtendsObject:Int()
+		Return (attrs & CLASS_EXTENDSOBJECT)<>0
+	End Method
+	
+	Method IsInstanced:Int()
+		Return (attrs & CLASS_INSTANCED)<>0
+	End Method
+	
+	Method GetDecl:Object( ident$ )
+	
+		Local cdecl:TClassDecl=Self
+		While cdecl
+			Local decl:Object=cdecl.GetDecl2( ident )
+			If decl Return decl
+			
+			cdecl=cdecl.superClass
+		Wend
+
+	End Method
+	
+	'needs this 'coz you can't go blah.Super.GetDecl()...
+	Method GetDecl2:Object( ident$ )
+		Return Super.GetDecl( ident )
+	End Method
+
+	Method GetDeclList:Object( ident$, declList:TFuncDeclList = Null, maxSearchDepth:Int )
+	
+		If Not declList Then
+			declList = New TFuncDeclList
+		End If
+	
+		Local cdecl:TClassDecl=Self
+		While cdecl
+			Local decl:Object=cdecl.GetDeclList2( ident, declList, maxSearchDepth )
+			'If decl And (Not TFuncDeclList(decl) And declList.IsEmpty()) Return decl
+			If decl Then
+				declList.AddLast(decl)
+			End If
+
+			cdecl=cdecl.superClass
+			
+			If maxSearchDepth < SCOPE_CLASS_HEIRARCHY Then
+				Exit
+			End If
+		Wend
+
+		Return declList
+	End Method
+	
+	'needs this 'coz you can't go blah.Super.GetDecl()...
+	Method GetDeclList2:Object( ident$, declList:TFuncDeclList = Null, maxSearchDepth:Int )
+		Return Super.GetDeclList( ident, declList, maxSearchDepth )
+	End Method
+	
+	Method FindFuncDecl:TFuncDecl( ident$,args:TExpr[] = Null ,explicit:Int=False, isArg:Int = False, isIdentExpr:Int = False, throwOnNotMatched:Int = False, maxSearchDepth:Int )
+	
+		' try the super first...
+		Local funcDecl:TFuncDecl = Super.FindFuncDecl(ident, args, explicit, isArg, isIdentExpr, throwOnNotMatched, maxSearchDepth)
+		If funcDecl Then
+			Return funcDecl
+		End If
+	
+	
+		If args = Null Then
+			args = New TExpr[0]
+		End If
+	
+		If Not IsInterface()
+			' try getdecl first&
+			Local decl:TFuncDecl = TFuncDecl(GetDecl(ident))
+			If decl Then
+				Return decl
+			End If
+			Return FindFuncDecl2( ident,args,explicit,isIdentExpr )
+		EndIf
+		
+		Local fdecl:TFuncDecl=FindFuncDecl2( ident,args,True )
+		
+		For Local iface:TClassDecl=EachIn implmentsAll
+			Local decl:TFuncDecl=iface.FindFuncDecl2( ident,args,True )
+			If Not decl Continue
+			
+			If fdecl
+				If fdecl.EqualsFunc( decl ) Continue
+				Err "Unable to determine overload to use: "+fdecl.ToString()+" or "+decl.ToString()+"."
+			EndIf
+			fdecl=decl
+		Next
+		
+		If fdecl Or explicit Return fdecl
+		
+		fdecl=FindFuncDecl2( ident,args,False )
+		
+		For Local iface:TClassDecl=EachIn implmentsAll
+			Local decl:TFuncDecl=iface.FindFuncDecl2( ident,args,False )
+			If Not decl Continue
+			
+			If fdecl
+				If fdecl.EqualsFunc( decl ) Continue
+				Err "Unable to determine overload to use: "+fdecl.ToString()+" or "+decl.ToString()+"."
+			EndIf
+			fdecl=decl
+		Next
+		
+		Return fdecl
+	End Method
+	
+	Method FindFuncDecl2:TFuncDecl( ident$,args:TExpr[],explicit:Int, isIdentExpr:Int = False )
+		Return Super.FindFuncDecl( ident,args,explicit,,isIdentExpr,0,0 )
+	End Method
+	
+	Method GetAllFuncDecls:TFuncDecl[](funcs:TFuncDecl[] = Null, includeSuper:Int = True)
+
+		If Not funcs Then
+			funcs = New TFuncDecl[0]
+		End If
+		
+		If superClass And includeSuper Then
+			funcs = superClass.GetAllFuncDecls(funcs)
+		End If
+
+		' interface methods
+		For Local iface:TClassDecl=EachIn implmentsAll
+			funcs = iface.GetAllFuncDecls(funcs)
+		Next
+		
+		For Local func:TFuncDecl = EachIn _decls
+		
+			Local matched:Int = False
+			
+			For Local i:Int = 0 Until funcs.length
+				' found a match - we are overriding it
+				If func.IdentLower() = funcs[i].IdentLower() And func.EqualsArgs(funcs[i]) Then
+					matched = True
+					' but don't override if we are an interface and the function is implemented
+					If IsInterface() And Not funcs[i].ClassScope().IsInterface() Then
+						Exit
+					End If
+					' set this to our own func
+					funcs[i] = func
+					Exit
+				End If
+			Next
+			
+			If Not matched Then
+				funcs :+ [func]
+			End If
+		
+		Next
+		
+		Return funcs
+	End Method
+
+	' returns a list of original function decls (i.e. decls in the scope of their original declarations).
+	' this is useful for generating vtables for extern types
+	Method GetAllOriginalFuncDecls:TFuncDecl[](funcs:TFuncDecl[] = Null, includeSuper:Int = True)
+		If Not funcs Then
+			funcs = New TFuncDecl[0]
+		End If
+		
+		If superClass And includeSuper Then
+			funcs = superClass.GetAllOriginalFuncDecls(funcs, True)
+		End If
+
+		' interface methods
+		For Local iface:TClassDecl=EachIn implmentsAll
+			For Local func:TFuncDecl=EachIn iface._decls
+				Local matched:Int = False
+
+'				For Local i:Int = 0 Until funcs.length
+'					' found a match - we are overriding it
+'					If func.IdentLower() = funcs[i].IdentLower() Then
+'						matched = True
+'						Exit
+'					End If
+'				Next
+				
+				If Not matched Then
+					funcs :+ [func]
+				End If
+			Next
+		Next
+
+		
+		For Local func:TFuncDecl = EachIn _decls
+		
+			Local matched:Int = False
+			
+			' dont count any that are already in the funcs list
+			For Local i:Int = 0 Until funcs.length
+				' found a match - we are overriding it
+				If func.IdentLower() = funcs[i].IdentLower() And func.EqualsArgs(funcs[i]) Then
+					matched = True
+					' set this to our own func
+					'funcs[i] = func
+					Exit
+				End If
+			Next
+			
+			If Not matched Then
+				funcs :+ [func]
+			End If
+		
+		Next
+		
+		Return funcs
+	End Method
+
+	Method GetOriginalFuncDecl:TFuncDecl(fdecl:TFuncDecl)
+		If Not TClassDecl(Self) Then
+			Return fdecl
+		End If
+		
+		If superClass Then
+			Local decl:TFuncDecl = superClass.GetOriginalFuncDecl(fdecl)
+			If decl <> fdecl Then
+				Return decl
+			End If
+		End If
+		
+		For Local func:TFuncDecl = EachIn _decls
+		
+			If func.IdentLower() = fdecl.IdentLower() And func.EqualsArgs(fdecl) Then
+				Return func
+			End If
+		
+		Next
+		
+		Return fdecl
+	End Method
+
+	Method GetLatestFuncDecl:TFuncDecl(fdecl:TFuncDecl)
+		If Not TClassDecl(Self) Then
+			Return fdecl
+		End If
+		
+		For Local func:TFuncDecl = EachIn _decls
+		
+			If func.IdentLower() = fdecl.IdentLower() And func.EqualsArgs(fdecl) Then
+				Return func
+			End If
+		
+		Next
+		
+		If superClass Then
+			Local decl:TFuncDecl = superClass.GetLatestFuncDecl(fdecl)
+			If decl <> fdecl Then
+				Return decl
+			End If
+		End If
+		
+
+		Return fdecl
+	End Method
+	
+	Method ExtendsClass:Int( cdecl:TClassDecl )
+		'If Self=nullObjectClass Return True
+		
+'		If cdecl.IsTemplateArg()
+'			cdecl=TType.objectType.FindClass()
+'		EndIf
+		
+		Local tdecl_:TClassDecl=Self
+		While tdecl_
+			If tdecl_=cdecl Return True
+			If cdecl.IsInterface()
+				For Local iface:TClassDecl=EachIn tdecl_.implmentsAll
+					If iface=cdecl Return True
+				Next
+			EndIf
+			tdecl_=tdecl_.superClass
+		Wend
+		
+		Return False
+	End Method
+	
+	Method OnSemant()
+
+		If args Then
+			Return
+		End If
+
+		PushEnv Self
+
+		'If Not IsTemplateInst()
+		'	For Local i:Int=0 Until args.Length
+		'		InsertDecl args[i]
+		'		args[i].Semant
+		'	Next
+		'EndIf
+
+		'Semant superclass		
+		If superTy
+			'superClass=superTy.FindClass()
+			superClass=superTy.SemantClass()
+			If superClass.IsInterface() Then
+				If Not IsExtern() Or Not superClass.IsExtern() Err superClass.ToString()+" is an interface, not a class."
+				If (IsExtern() And Not superClass.IsExtern()) Or (superClass.IsExtern() And Not IsExtern()) Err "Extern and non extern types cannot be mixed."
+			End If
+			If superClass.IsFinal() Err "Final types cannot be extended."
+		EndIf
+
+		'Semant implemented interfaces
+		Local impls:TClassDecl[]=New TClassDecl[impltys.Length]
+		Local implsall:TStack=New TStack
+		For Local i:Int=0 Until impltys.Length
+			attrs :| DECL_CYCLIC
+			Local cdecl:TClassDecl=impltys[i].SemantClass()
+			attrs :~ DECL_CYCLIC
+			If Not cdecl.IsInterface()
+				Err cdecl.ToString()+" is a type, not an interface."
+			EndIf
+			For Local j:Int=0 Until i
+				If impls[j]=cdecl
+					Err "Duplicate interface "+cdecl.ToString()+"."
+				EndIf
+			Next
+			impls[i]=cdecl
+			implsall.Push cdecl
+			For Local tdecl_:TDecl=EachIn cdecl.implmentsAll
+				implsall.Push tdecl_
+			Next
+		Next
+		Local length:Int = implsall.Length()
+		implmentsAll=New TClassDecl[length]
+		For Local i:Int=0 Until length
+			implmentsAll[i]=TClassDecl(implsall.Get(length - i - 1))
+		Next
+		implments=impls
+
+		Rem
+		If IsInterface()
+			'add implemented methods to our methods
+			For Local iface:=EachIn implmentsAll
+				For Local decl:=EachIn iface.FuncDecls
+					InsertAlias decl.ident,decl
+				Next
+			Next
+		EndIf
+		EndRem
+				
+'		attrs|=DECL_SEMANTED
+		
+		PopEnv
+		
+		'If IsTemplateArg()
+		'	actual=TType.objectType.FindClass()
+		'	Return
+		'EndIf
+		
+		'If IsTemplateInst()
+		'	Return
+		'EndIf
+		
+		'Are we abstract?
+		If Not IsAbstract()
+			For Local decl:TDecl=EachIn _decls
+				Local fdecl:TFuncDecl=TFuncDecl( decl )
+				If fdecl And fdecl.IsAbstract()
+					attrs:|DECL_ABSTRACT
+					Exit
+				EndIf
+			Next
+		EndIf
+		
+		If Not lastOffset And superClass Then
+			lastOffset = superClass.LastOffset
+		End If
+
+		For Local decl:TFieldDecl=EachIn _decls
+			GetFieldOffset(decl)
+		Next
+
+		If Not IsExtern() And Not IsInterface()
+			Local fdecl:TFuncDecl
+			For Local decl:TFuncDecl=EachIn FuncDecls()
+				If Not decl.IsCtor() Continue
+				Local nargs:Int
+				For Local arg:TArgDecl=EachIn decl.argDecls
+					If Not arg.init nargs:+1
+				Next
+				If nargs Continue
+				fdecl=decl
+				Exit
+			Next
+			
+			
+			' Don't need default new?
+			'If Not fdecl
+			'	fdecl=New TFuncDecl.CreateF( "new",New TObjectType.Create( Self ),Null,FUNC_CTOR )
+			'	fdecl.AddStmt New TReturnStmt.Create( Null )
+			'	InsertDecl fdecl
+			'EndIf
+		EndIf
+
+		For Local decl:TDecl=EachIn _decls
+			If TClassDecl(decl) Then
+				TClassDecl(decl).Semant
+			End If
+		Next
+
+		'NOTE: do this AFTER super semant so UpdateAttrs order is cool.
+
+		If AppScope() Then
+			AppScope().semantedClasses.AddLast Self
+		End If
+	End Method
+	
+	Method SemantParts()
+'		If IsSemanted() Return
+		
+'		Super.Semant()
+		If args Then
+			Return
+		End If
+		
+		For Local decl:TConstDecl = EachIn Decls()
+			decl.Semant()
+		Next
+
+		For Local decl:TGlobalDecl = EachIn Decls()
+			decl.Semant()
+		Next
+
+		' NOTE : we can't semant functions here as they cause cyclic errors.
+		For Local decl:TFuncDecl = EachIn Decls()
+			decl.Semant()
+		Next
+
+		For Local decl:TFieldDecl = EachIn Decls()
+			decl.Semant()
+		Next
+
+		' nested classes
+		For Local decl:TClassDecl = EachIn Decls()
+			decl.Semant()
+		Next
+
+	End Method
+	
+	'Ok, this dodgy looking beast 'resurrects' methods that may not currently be alive, but override methods that ARE.
+	Method UpdateLiveMethods:Int()
+	
+		If IsInterface() Return 0
+
+		If Not superClass Return 0
+
+		Local n:Int
+		For Local decl:TFuncDecl=EachIn MethodDecls()
+			If decl.IsSemanted() Continue
+			
+			Local live:Int
+			Local unsem:TList=New TList'<TFuncDecl>
+			
+			unsem.AddLast decl
+			
+			Local sclass:TClassDecl=superClass
+			While sclass
+				For Local decl2:TFuncDecl=EachIn sclass.MethodDecls( decl.ident )
+					If decl2.IsSemanted()
+						live=True
+					Else
+						unsem.AddLast decl2
+						If decl2.IsExtern() live=True
+						If decl2.actual.IsSemanted() live=True
+					EndIf
+				Next
+				sclass=sclass.superClass
+			Wend
+			
+			If Not live
+				Local cdecl:TClassDecl=Self
+				While cdecl
+					For Local iface:TClassDecl=EachIn cdecl.implmentsAll
+						For Local decl2:TFuncDecl=EachIn iface.MethodDecls( decl.ident )
+							If decl2.IsSemanted()
+								live=True
+							Else
+								unsem.AddLast decl2
+								If decl2.IsExtern() live=True
+								If decl2.actual.IsSemanted() live=True
+							EndIf
+						Next
+					Next
+					cdecl=cdecl.superClass
+				Wend
+			EndIf
+			
+			If Not live Continue
+			
+			For Local decl:TDecl=EachIn unsem
+				decl.Semant
+				n:+1
+			Next
+		Next
+		
+		Return n
+	End Method
+	
+	Method FinalizeClass()
+	
+		SemantParts()
+
+		PushErr errInfo
+		
+		If Not IsInterface()
+			'
+			'check for duplicate fields! - BlitzMax supports fields with the same name in subclasses..
+			'
+			'For Local decl:TDecl=EachIn Semanted()
+			'	Local fdecl:TFieldDecl=TFieldDecl( decl )
+			'	If Not fdecl Continue
+			'	Local cdecl:TClassDecl=superClass
+			'	While cdecl
+			'		For Local decl:TDecl=EachIn cdecl.Semanted()
+			'			If decl.ident=fdecl.ident Err "Field '"+fdecl.ident+"' in class "+ToString()+" overrides existing declaration in class "+cdecl.ToString()
+			'		Next
+			'		cdecl=cdecl.superClass
+			'	Wend
+			'Next
+			'
+			'Check we implement all abstract methods!
+			'
+			If IsInstanced()
+				Local cdecl:TClassDecl=Self
+				Local impls:TList=New TList'<TFuncDecl>
+				While cdecl
+					For Local decl:TFuncDecl=EachIn cdecl.SemantedMethods()
+						If decl.IsAbstract()
+							Local found:Int
+							For Local decl2:TFuncDecl=EachIn impls
+								If decl.IdentLower() = decl2.IdentLower() And decl2.EqualsFunc( decl )
+									found=True
+									Exit
+								EndIf
+							Next
+							If Not found
+								Err "Can't create instance of type "+ToString()+" due to abstract method "+decl.ToString()+"."
+							EndIf
+						Else
+							impls.AddLast decl
+						EndIf
+					Next
+					cdecl=cdecl.superClass
+				Wend
+			EndIf
+			'
+			'Check we implement all interface methods!
+			'
+			If Not IsAbstract() Then
+
+				Local ints:TMap = GetInterfaces()
+
+				For Local iface:TClassDecl=EachIn ints.Values()
+				
+					If (Not IsExtern() And iface.IsExtern()) Or (IsExtern() And Not iface.IsExtern()) Then
+						Err "Cannot mix Extern and non Extern Types and Interfaces."
+					End If
+				
+					For Local decl:TFuncDecl=EachIn iface.SemantedMethods()
+						Local found:Int
+
+						Local cdecl:TClassDecl=Self
+						
+						While cdecl And Not found
+							For Local decl2:TFuncDecl=EachIn cdecl.SemantedMethods( decl.ident )
+								' equals (or extends - for object types)
+								If decl2.EqualsFunc( decl )
+									If Not decl2.IsPublic() Then
+										' error on function decl
+										PushErr decl2.errInfo
+										Err TFuncDecl.PrivilegeError(decl2, decl)
+									End If
+									found=True
+									Exit
+								EndIf
+							Next
+						
+							cdecl = cdecl.superClass
+						Wend
+
+						If Not found
+							Err decl.ToString() + " must be implemented by type " + ToString()
+						EndIf
+					Next
+				Next
+			End If
+		Else
+			' check for compatible overloads, etc.
+
+			Local impls:TList=New TList
+
+			CheckInterface(Self, impls)
+			
+		EndIf
+		
+		PopErr
+		
+	End Method
+	
+	Method CheckInterface(cdecl:TClassDecl, impls:TList)
+		While cdecl
+			For Local decl:TFuncDecl=EachIn cdecl.SemantedMethods()
+				Local found:Int
+				For Local decl2:TFuncDecl=EachIn impls
+					If decl.IdentLower() = decl2.IdentLower()
+						If decl2.argDecls.Length = decl.argDecls.Length And Not decl2.EqualsFunc( decl )
+						'	Err "Cannot mix incompatible method signatures." + decl2.ToString() + " vs " + decl.ToString() + "."
+						Else
+							found = True
+						End If
+					EndIf
+				Next
+				If Not found Then
+					impls.AddLast decl
+				End If
+				'EndIf
+			Next
+			
+			For Local idecl:TClassDecl = EachIn cdecl.implments
+				CheckInterface(idecl, impls)
+			Next
+
+			cdecl=cdecl.superClass
+		Wend
+	End Method
+	
+	Method GetFieldOffset(decl:TFieldDecl)
+		
+		Local ty:TType = decl.declTy
+		
+		Local modifier:Int = POINTER_SIZE
+		
+		If TIntType(ty) Or TFloatType(ty) Or TUIntType(ty) Then
+			modifier = 4
+		Else If TShortType(ty) Then
+			modifier = 2
+		Else If TLongType(ty) Or TDoubleType(ty) Or TULongType(ty) Then
+			modifier = 8
+		Else If TByteType(ty) Then
+			modifier = 1
+		Else If TSizeTType(ty) Then
+			modifier = WORD_SIZE
+		End If
+
+		If modifier > 1 And lastOffset Mod modifier Then
+			lastOffset :+ modifier - (lastOffset Mod modifier)
+		End If
+		
+		decl.offset = lastOffset
+		
+		lastOffset :+ modifier
+	End Method
+	
+	Method ImplementsInterface:Int(ident:String)
+		ident = ident.ToLower()
+		For Local iface:TClassDecl = EachIn implmentsAll
+			If iface.IdentLower() = ident Then
+				Return True
+			End If
+		Next
+		Return False
+	End Method
+	
+	' returns a map of all interfaces implemented in this hierarchy
+	Method GetInterfaces:TMap(map:TMap = Null)
+		If Not map Then
+			map = New TMap
+		End If
+
+		For Local iface:TClassDecl=EachIn implmentsAll
+		
+			If iface.IsInterface() Then
+			
+				Local cdecl:TClassDecl = iface
+				While cdecl
+				
+					If cdecl.IsInterface() Then
+						If Not map.Contains(cdecl) Then
+							map.Insert(cdecl, cdecl)
+						End If
+					End If
+
+
+					cdecl=cdecl.superClass
+				Wend
+			
+			End If
+		Next
+
+		
+		If superClass Then
+			map = superClass.GetInterfaces(map)
+		End If
+		
+		Return map
+	End Method
+	
+	Method GetImplementedFuncs:TList(list:TList = Null)
+		If Not list Then
+			list = New TList
+		End If
+		
+		For Local idecl:TClassDecl = EachIn implmentsAll
+			idecl.GetImplementedFuncs(list)
+		Next
+		
+		For Local decl:TFuncDecl = EachIn SemantedMethods()
+			list.AddLast(decl)
+		Next
+
+		Return list
+	End Method
+	
+End Type
+
+Type TLoopLabelDecl Extends TDecl
+
+	Field realIdent:String
+
+	Method Create:TLoopLabelDecl( ident$, attrs:Int=0 )
+		Self.ident="#" + ident
+		Self.realIdent = ident
+		Self.attrs=attrs
+		Return Self
+	End Method
+	
+	Method OnCopy:TDecl(deep:Int = True)
+		Return New TLoopLabelDecl.Create( realIdent,attrs )
+	End Method
+	
+	Method OnSemant()
+	End Method
+	
+End Type
+
+Type TDataLabelDecl Extends TDecl
+
+	Field realIdent:String
+	Field index:Int
+
+	Method Create:TDataLabelDecl( ident$, attrs:Int=0 )
+		Self.ident="#" + ident
+		Self.realIdent = ident
+		Self.attrs=attrs
+		Return Self
+	End Method
+	
+	Method OnCopy:TDecl(deep:Int = True)
+		Return New TDataLabelDecl.Create( realIdent,attrs )
+	End Method
+	
+	Method OnSemant()
+	End Method
+	
+End Type
+
+Type TDefDataDecl Extends TDecl
+
+	Global count:Int
+
+	Field label:TDataLabelDecl
+	Field data:TExpr[]
+
+	Method Create:TDefDataDecl(data:TExpr[], label:TDataLabelDecl = Null, attrs:Int=0 )
+		Self.data=data
+		Self.label=label
+		Self.attrs=attrs
+		Return Self
+	End Method
+	
+	Method OnCopy:TDecl(deep:Int = True)
+		Return New TDefDataDecl.Create(TExpr.CopyArgs(data),TDataLabelDecl(label.Copy()),attrs)
+	End Method
+
+	Method OnSemant()
+		If data Then
+			If label Then
+				label.index = count
+			End If
+		
+			For Local i:Int = 0 Until data.length
+				data[i] = data[i].Semant()
+				If Not TConstExpr(data[i]) Then
+					Err "Data items must be numeric or strings"
+				Else
+					' todo : more type tests?
+				End If
+				count :+ 1
+			Next
+		Else
+			' err?
+		End If
+	End Method
+	
+End Type
+
+Const MODULE_STRICT:Int=1
+Const MODULE_SUPERSTRICT:Int=2
+Const MODULE_ACTUALMOD:Int=4
+
+Type TNamespaceDecl Extends TScopeDecl
+
+'	Field mods:TMap = New TMap
+
+	Method Create:TNamespaceDecl( ident$,munged$ )
+		Self.ident=ident
+		Self.munged=munged
+		Return Self
+	End Method
+
+'	Method GetDecl:Object( ident$ )
+'		Return mods.ValueForKey(ident.ToLower())
+'	End Method
+	
+End Type
+
+Type TModuleDecl Extends TScopeDecl
+
+	Field filepath$
+	Field relpath$
+	Field imported:TUnorderedMap=New TUnorderedMap'<TModuleDecl>		'Maps filepath to modules
+	Field pubImported:TUnorderedMap =New TUnorderedMap'<TModuleDecl>	'Ditto for publicly imported modules
+
+	Field pmod:TModuleDecl
+
+	Field fileImports:TList=New TList'StringList
+	
+	' cache of ModuleInfo lines
+	Field modInfo:TList = New TList
+
+	Field _getDeclTreeCache:TList
+	
+	Field _getDeclCache:TMap = New TMap
+	Field _getDeclListCache:TMap = New TMap
+
+	Method ToString$()
+		Return "Module "+munged
+	End Method
+	
+	Method Create:TModuleDecl( ident$,munged$,filepath$,attrs:Int )
+		Self.ident=ident
+		Self.munged=munged
+		Self.filepath=filepath
+		Self.attrs=attrs
+
+		If ident.Find(".") <> -1 And ident.find("/") = -1 And ident.find("\") = -1 Then
+			Local m:String = ident[..ident.Find(".")]
+			Local ns:TNamespaceDecl = TNamespaceDecl(_appInstance.GetDecl(m.ToLower()))
+			If Not ns Then
+				ns = New TNamespaceDecl.Create(m, m)
+				If _appInstance.mainModule Then
+					_appInstance.mainModule.InsertDecl(ns)
+				Else
+					' this must be the main module...
+					InsertDecl(ns)
+				End If
+			End If
+			ns.InsertDecl(Self)
+		End If
+
+		Return Self
+	End Method
+
+	Method UpdateFilePath(fp:String)
+		filepath = fp
+	End Method
+	
+	Method AddImport(imp:String, obj:Object)
+		imported.Insert(imp, obj)
+		FlushCaches()
+	End Method
+	
+	Method FlushCaches()
+		_getDeclTreeCache = Null
+		If TModuleDecl(pmod) Then
+			TModuleDecl(pmod).FlushCaches()
+		End If
+	End Method
+	
+	Method IsStrict:Int()
+		Return (attrs & MODULE_STRICT)<>0
+	End Method
+
+	Method IsSuperStrict:Int()
+		Return (attrs & MODULE_SUPERSTRICT)<>0
+	End Method
+	
+	Method IsActualModule:Int()
+		Return (attrs & MODULE_ACTUALMOD)<>0
+	End Method
+	
+	Method GetDecl:Object( ident$ )
+		' if we previously found it, return it from the cache
+		Local decl:Object = _getDeclCache.ValueForKey(ident)
+
+		If decl Then
+			Return decl
+		End If
+		
+		If _getDeclTreeCache Then
+		
+			Local declmod$
+		
+			For Local mdecl:TModuleDecl = EachIn _getDeclTreeCache
+
+				If ident = mdecl.ident
+					_getDeclCache.Insert(ident, mdecl)
+					Return mdecl
+				End If
+			
+				Local tdecl_:Object=mdecl.GetDecl2( ident )
+			
+				If tdecl_ And tdecl_<>decl
+					If mdecl=Self
+						_getDeclCache.Insert(ident, tdecl_)
+						Return tdecl_
+					End If
+					If decl
+						Err "Duplicate identifier '"+ident+"' found in module '"+declmod+"' and module '"+mdecl.ident+"'."
+					EndIf
+					decl=tdecl_
+					declmod=mdecl.ident
+				EndIf
+			Next
+		
+		Else
+		
+			_getDeclTreeCache = New TList
+	
+			Local todo:TList=New TList'<TModuleDecl>
+			'Local done:TIntMap=New TIntMap'<TModuleDecl>
+			Local done:TMap = New TMap
+			
+			todo.AddLast Self
+			'done.Insert _filePathId,Self
+			done.Insert filePath,Self
+			
+			Local declmod$
+			
+			While Not todo.IsEmpty()
+		
+				Local mdecl:TModuleDecl=TModuleDecl(todo.RemoveLast())
+				
+				_getDeclTreeCache.AddLast(mdecl)
+				
+				Local imps:TUnorderedMap=mdecl.imported
+	
+				For Local mdecl2:TModuleDecl=EachIn imps.Values()
+	
+					'If Not done.Contains( mdecl2._filePathId )
+					If Not done.Contains( mdecl2.filePath )
+						todo.AddLast mdecl2
+						'done.Insert mdecl2._filePathId,mdecl2
+						done.Insert mdecl2.filePath,mdecl2
+					EndIf
+					
+				Next
+	
+			Wend
+	
+			Return GetDecl(ident)
+	
+		End If
+			
+		' cache it for next time
+		_getDeclCache.Insert(ident, decl)
+		
+		Return decl
+	End Method
+	
+	Method GetDecl2:Object( ident$ )
+		Return Super.GetDecl( ident )
+	End Method
+
+
+	Method GetDeclList:Object( ident$, declList:TFuncDeclList = Null, maxSearchDepth:Int )
+
+		If Not declList Then
+			declList = New TFuncDeclList
+		End If
+
+		Local decl:Object,declmod$
+
+		If _getDeclTreeCache Then
+		
+'			Print "   Using Cache"
+			
+			Local declmod$
+		
+			For Local mdecl:TModuleDecl = EachIn _getDeclTreeCache
+			
+				If ident = mdecl.ident
+					'_getDeclCache.Insert(identId, mdecl)
+					Return mdecl
+				End If
+			
+				Local tdecl_:Object=mdecl.GetDeclList2( ident, declList, maxSearchDepth )
+			
+				If tdecl_ And tdecl_<>decl
+					If mdecl=Self
+						_getDeclCache.Insert(ident, tdecl_)
+						Return tdecl_
+					End If
+					If decl
+						Err "Duplicate identifier '"+ident+"' found in module '"+declmod+"' and module '"+mdecl.ident+"'."
+					EndIf
+					decl=tdecl_
+					declmod=mdecl.ident
+				EndIf
+			Next
+		
+		Else
+
+			_getDeclTreeCache = New TList
+	
+			Local todo:TList=New TList'<TModuleDecl>
+			Local done:TMap=New TMap'<TModuleDecl>
+			
+			todo.AddLast Self
+			done.Insert filepath,Self
+			
+			'Local decl:Object,declmod$
+			
+			While Not todo.IsEmpty()
+		
+				Local mdecl:TModuleDecl=TModuleDecl(todo.RemoveLast())
+				_getDeclTreeCache.AddLast(mdecl)
+				
+				Local imps:TUnorderedMap=mdecl.imported
+	
+				For Local mdecl2:TModuleDecl=EachIn imps.Values()
+					If Not done.Contains( mdecl2.filepath )
+						todo.AddLast mdecl2
+						done.Insert mdecl2.filepath,mdecl2
+					EndIf
+					
+				Next
+	
+			Wend
+		
+			Return GetDeclList( ident, declList, maxSearchDepth )
+		
+		End If
+		
+		Return decl
+	End Method
+	
+	Method GetDeclList2:Object( ident$, declList:TFuncDeclList = Null, maxSearchDepth:Int )
+		Return Super.GetDeclList( ident, declList, maxSearchDepth )
+	End Method
+
+	Method OnSemant()
+		Local decl:TFuncDecl = FindFuncDecl( "__localmain", ,,,,,SCOPE_MODULE )
+		If decl Then
+			decl.Semant
+		End If
+	
+		For Local gdecl:TGlobalDecl=EachIn _decls
+			gdecl.Semant
+		Next
+
+		For Local cdecl:TClassDecl=EachIn _decls
+			If cdecl.args Then
+				For Local inst:TClassDecl = EachIn cdecl.instances
+					For Local idecl:TDecl = EachIn inst.Decls()
+						If TAliasDecl( idecl ) Continue
+						idecl.Semant()
+					Next
+				Next
+			Else
+				cdecl.Semant
+			End If
+		Next
+
+		For Local fdecl:TFuncDecl=EachIn _decls
+			fdecl.Semant
+		Next
+
+		For Local cdecl:TConstDecl=EachIn _decls
+			cdecl.Semant
+		Next
+	End Method
+
+End Type
+
+Type TAppDecl Extends TScopeDecl
+
+	Field imported:TUnorderedMap=New TUnorderedMap'<TModuleDecl>			'maps modpath->mdecl
+	
+	Field globalImports:TUnorderedMap = New TUnorderedMap
+	
+	Field mainModule:TModuleDecl
+	Field mainFunc:TFuncDecl	
+		
+	Field semantedClasses:TList=New TList'<TClassDecl>			'in-order (ie: base before derived) list of _semanted classes
+	Field semantedGlobals:TList=New TList'<TGlobalDecl>			'in-order (ie: dependancy sorted) list of _semanted globals
+
+	Field fileImports:TList=New TList'StringList
+	Field headers:TList = New TList
+	
+	Field stringConsts:TMap = New TMap
+	Field stringConstCount:Int
+	
+	Field incbins:TList = New TList
+	Field genIncBinHeader:Int = False
+	
+	Field dataDefs:TList = New TList
+	Field scopeDefs:TMap = New TMap
+	
+	Method GetPathPrefix:String()
+		If opt_buildtype = BUILDTYPE_MODULE Then
+			Local prefix:String
+			Local path:String[] = mainModule.filepath.split("/")
+			Local c:Int = 0
+			For Local dir:String = EachIn path
+				If c Then
+					prefix :+ dir.Replace(".mod", "") + "_"
+					c:- 1
+				End If
+				If dir = "mod" Then
+					c = 2
+				End If
+			Next
+		Else
+			Return "bb_"
+		End If
+	End Method
+	
+	Method InsertModule( mdecl:TModuleDecl )
+		mdecl.scope=Self
+		imported.Insert mdecl.filepath,mdecl
+		If Not mainModule
+			mainModule=mdecl
+		EndIf
+	End Method
+	
+	Method IsImported:Int(modpath:String)
+		Return globalImports.Contains(modpath)
+	End Method
+	
+	Method GetDecl:Object( ident$ )
+		Local obj:Object = Super.GetDecl(ident)
+		If Not obj And mainModule Then
+			Return mainModule.GetDecl(ident)
+		End If
+		Return obj
+	End Method
+
+	Method OnSemant()
+'DebugStop		
+		_env=Null
+		pushenv Self
+		
+		SemantDataDefs()	
+
+		mainModule.Semant
+
+		mainFunc=mainModule.FindFuncDecl( "__localmain",,,,,,SCOPE_MODULE )
+		
+		
+		' FIXME
+		If Not mainFunc Err "Function 'Main' not found."
+	
+		SemantDecls()
+
+		Repeat
+			Local more:Int
+			For Local cdecl:TClassDecl=EachIn semantedClasses
+				more:+cdecl.UpdateLiveMethods()
+			Next
+			If Not more Exit
+		Forever
+		
+		For Local cdecl:TClassDecl=EachIn semantedClasses
+			cdecl.FinalizeClass
+		Next
+	End Method
+	
+	Method SemantDataDefs()
+		TDefDataDecl.count = 0
+		
+		For Local decl:TDecl = EachIn dataDefs
+			decl.Semant
+		Next
+	End Method
+	
+	Method SemantDecls()
+		For Local decl:TDecl=EachIn mainModule._decls
+
+			decl.Semant
+			
+			' consts
+			Local cdecl:TConstDecl=TConstDecl( decl )
+			If cdecl
+				cdecl.Semant()
+				Continue
+			End If
+
+			' classes
+			Local tdecl:TClassDecl=TClassDecl( decl )
+			If tdecl
+				tdecl.Semant()
+				tdecl.SemantParts()
+				Continue
+			EndIf
+
+			' functions
+			Local fdecl:TFuncDecl=TFuncDecl( decl )
+			If fdecl And fdecl <> _appInstance.mainFunc Then
+				fdecl.Semant()
+				Continue
+			End If
+
+			' globals
+			Local gdecl:TGlobalDecl=TGlobalDecl( decl )
+			If gdecl
+				gdecl.Semant()
+				Continue
+			End If
+		Next
+
+	End Method
+	
+	Method hasStringConst:Int(value:String)
+		Return stringConsts.ValueForKey(value) <> Null
+	End Method
+	
+	Method mapStringConsts(value:String)
+		Local sc:TStringConst = TStringConst(stringConsts.ValueForKey(value))
+		
+		If Not sc Then
+			Local sc:TStringConst = New TStringConst
+			sc.count = 1
+		
+			If value Then
+				sc.id = "_s" + stringConstCount
+			Else
+				sc.id = "bbEmptyString"
+			End If
+
+			stringConsts.Insert(value, sc)
+
+			If value Then
+				stringConstCount:+ 1
+			End If
+		Else
+			sc.count :+ 1
+		End If
+	End Method
+	
+	Method removeStringConst(value:String)
+		If value Then
+			Local sc:TStringConst = TStringConst(stringConsts.ValueForKey(value))
+			If sc Then
+				If sc.count > 0 Then
+					sc.count :- 1
+					'stringConsts.Remove(value)
+				End If
+			End If
+		End If
+	End Method
+	
+	Method FindDataLabel:TDecl(ident:String)
+		For Local dd:TDefDataDecl = EachIn dataDefs
+			If dd.label And dd.label.ident.ToLower() = ident.ToLower() Then
+				Return dd
+			End If
+		Next
+	End Method
+	
+End Type
+
+Type TStringConst
+
+	Field id:String
+	Field count:Int
+
+End Type

+ 5 - 1
expr.bmx

@@ -833,6 +833,10 @@ Type TNewObjectExpr Extends TExpr
 			Err "Expression is not a class."
 		EndIf
 		
+		If objTy And Not objTy.classDecl.Semanted() Then
+			objTy.classDecl.Semant()
+		End If
+		
 		' 
 		If clsTy And clsTy.instance Then
 			instanceExpr = New TSelfExpr.Semant()
@@ -1154,7 +1158,7 @@ Type TCastExpr Extends TExpr
 		expr=expr.Semant()
 
 		Local src:TType=expr.exprType
-		
+
 		'equal?
 		If src.EqualsType( ty ) Return expr