Index: trunk/abdev/BasicCompiler_Common/src/Class.cpp
===================================================================
--- trunk/abdev/BasicCompiler_Common/src/ClassImpl.cpp	(revision 204)
+++ trunk/abdev/BasicCompiler_Common/src/Class.cpp	(revision 206)
@@ -1,9 +1,10 @@
+#include "stdafx.h"
+
 #include <jenga/include/smoothie/Smoothie.h>
-#include <jenga/include/smoothie/Class.h>
 #include <jenga/include/smoothie/Source.h>
 #include <jenga/include/smoothie/SmoothieException.h>
 #include <jenga/include/smoothie/LexicalAnalysis.h>
 
-#include <ClassImpl.h>
+#include <Class.h>
 #include <Compiler.h>
 #include <NamespaceSupporter.h>
@@ -15,6 +16,4 @@
 #include "../../BasicCompiler32/opcode.h"
 #endif
-
-
 
 
@@ -77,14 +76,103 @@
 
 
-bool ClassImpl::IsEqualSymbol( const NamespaceScopes &namespaceScopes, const string &name ) const
-{
-	if( GetName() != name ){
+bool CClass::IsClass() const
+{
+	return classType == CClass::Class;
+}
+bool CClass::IsInterface() const
+{
+	return classType == CClass::Interface;
+}
+bool CClass::IsEnum() const
+{
+	return classType == CClass::Enum;
+}
+bool CClass::IsDelegate() const
+{
+	return classType == CClass::Delegate;
+}
+bool CClass::IsStructure() const
+{
+	return classType == CClass::Structure;
+}
+
+
+// コンストラクタのコンパイルを開始
+void CClass::NotifyStartConstructorCompile() const
+{
+	isCompilingConstructor = true;
+}
+
+//コンストラクタのコンパイルを終了
+void CClass::NotifyFinishConstructorCompile() const
+{
+	isCompilingConstructor = false;
+}
+
+//コンストラクタをコンパイル中かどうかを判別
+bool CClass::IsCompilingConstructor() const
+{
+	return isCompilingConstructor;
+}
+
+//デストラクタのコンパイルを開始
+void CClass::NotifyStartDestructorCompile() const{
+	isCompilingDestructor = true;
+}
+
+//デストラクタのコンパイルを終了
+void CClass::NotifyFinishDestructorCompile() const{
+	isCompilingDestructor = false;
+}
+
+//デストラクタをコンパイル中かどうかを判別
+bool CClass::IsCompilingDestructor() const
+{
+	return isCompilingDestructor;
+}
+
+//自身の派生クラスかどうかを確認
+bool CClass::IsSubClass( const CClass *pClass ) const
+{
+	if( !pClass->HasSuperClass() )
+	{
 		return false;
 	}
 
-	return compiler.GetNamespaceSupporter().IsSameAreaNamespace( GetNamespaceScopes(), namespaceScopes );
-}
-
-bool ClassImpl::Inherits( const char *inheritNames, int nowLine ){
+	const CClass *pTempClass = &pClass->GetSuperClass();
+	while( pTempClass ){
+		if( this == pTempClass ) return true;
+		pTempClass = &pTempClass->GetSuperClass();
+	}
+	return false;
+}
+
+//自身と等しいまたは派生クラスかどうかを確認
+bool CClass::IsEqualsOrSubClass( const CClass *pClass ) const
+{
+	if( IsEquals( pClass ) ) return true;
+	return IsSubClass( pClass );
+}
+
+// 自身と等しいまたは派生クラス、基底クラスかどうかを確認
+bool CClass::IsEqualsOrSubClassOrSuperClass( const CClass &objClass ) const
+{
+	if( IsEquals( &objClass ) ) return true;
+	if( IsSubClass( &objClass ) ) return true;
+	if( objClass.IsSubClass( this ) ) return true;
+	return false;
+}
+
+bool CClass::IsInheritsInterface( const CClass *pInterfaceClass ) const
+{
+	BOOST_FOREACH( const InheritedInterface &objInterface, interfaces ){
+		if( pInterfaceClass == &objInterface.GetInterfaceClass() ){
+			return true;
+		}
+	}
+	return false;
+}
+
+bool CClass::Inherits( const char *inheritNames, int nowLine ){
 	int i = 0;
 	bool isInheritsClass = false;
@@ -183,5 +271,5 @@
 	return true;
 }
-bool ClassImpl::InheritsClass( const CClass &inheritsClass, int nowLine ){
+bool CClass::InheritsClass( const CClass &inheritsClass, int nowLine ){
 
 	//ループ継承でないかをチェック
@@ -245,5 +333,5 @@
 	return true;
 }
-bool ClassImpl::InheritsInterface( const CClass &inheritsInterface, int nowLine ){
+bool CClass::InheritsInterface( const CClass &inheritsInterface, int nowLine ){
 
 	//ループ継承でないかをチェック
@@ -291,5 +379,5 @@
 	return true;
 }
-CMember *ClassImpl::CreateMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine )
+CMember *CClass::CreateMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine )
 {
 	extern int cp;
@@ -299,7 +387,7 @@
 	char initBuffer[VN_SIZE];
 	char lpszConstructParameter[VN_SIZE];
-	int SubScripts[MAX_ARRAYDIM];
+	Subscripts subscripts;
 	Type type;
-	GetDimentionFormat(buffer,VarName,SubScripts,type,initBuffer,lpszConstructParameter);
+	GetDimentionFormat(buffer,VarName,subscripts,type,initBuffer,lpszConstructParameter);
 
 	//重複チェック
@@ -308,15 +396,14 @@
 	}
 
-	CMember *pMember = new CMember( accessibility, VarName, type, isConst, initBuffer, lpszConstructParameter );
+	CMember *pMember = new CMember( accessibility, VarName, type, isConst, subscripts, initBuffer, lpszConstructParameter );
 	pMember->source_code_address = nowLine;
-	memcpy( pMember->SubScripts, SubScripts, MAX_ARRAYDIM * sizeof(int) );
 	return pMember;
 }
-void ClassImpl::AddMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ){
+void CClass::AddMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ){
 	dynamicMembers.push_back(
 		CreateMember( accessibility, isConst, isRef, buffer, nowLine )
 	);
 }
-void ClassImpl::AddStaticMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ){
+void CClass::AddStaticMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ){
 	staticMembers.push_back(
 		CreateMember( accessibility, isConst, isRef, buffer, nowLine )
@@ -324,5 +411,5 @@
 }
 
-void ClassImpl::AddMethod(CClass *pobj_c, Prototype::Accessibility accessibility, BOOL bStatic, bool isConst, bool isAbstract,
+void CClass::AddMethod(CClass *pobj_c, Prototype::Accessibility accessibility, BOOL bStatic, bool isConst, bool isAbstract,
 						 bool isVirtual, bool isOverride, char *buffer, int nowLine){
 	int i,i2;
@@ -340,6 +427,5 @@
 
 	//関数ハッシュへ登録
-	GlobalProc *pUserProc;
-	pUserProc=AddSubData( NamespaceScopes(), NamespaceScopesCollection(), buffer,nowLine,isVirtual,pobj_c, (bStatic!=0) );
+	UserProc *pUserProc = compiler.GetMeta().GetUserProcs().Add( NamespaceScopes(), NamespaceScopesCollection(), buffer,nowLine,isVirtual,pobj_c, (bStatic!=0) );
 	if(!pUserProc) return;
 
@@ -394,6 +480,6 @@
 		if( pMethod->GetInheritsClassPtr() ) continue;
 
-		if( pMethod->pUserProc->GetName() == temporary ){
-			if( pMethod->pUserProc->Params().Equals( pUserProc->Params() ) ){
+		if( pMethod->GetUserProc().GetName() == temporary ){
+			if( pMethod->GetUserProc().Params().Equals( pUserProc->Params() ) ){
 				//関数名、パラメータ属性が合致したとき
 				SetError(15,pUserProc->GetName().c_str(),nowLine);
@@ -408,10 +494,10 @@
 	//メソッドのオーバーライド
 	BOOST_FOREACH( CMethod *pMethod, pobj_c->GetMethods() ){
-		if( pMethod->pUserProc->GetName() == temporary ){
-			if( pMethod->pUserProc->Params().Equals( pUserProc->Params() ) ){
+		if( pMethod->GetUserProc().GetName() == temporary ){
+			if( pMethod->GetUserProc().Params().Equals( pUserProc->Params() ) ){
 
 				if(pMethod->IsVirtual()){
 					//メンバ関数を上書き
-					pMethod->pUserProc=pUserProc;
+					pMethod->SetUserProcPtr( pUserProc );
 					pMethod->Override();
 
@@ -446,5 +532,153 @@
 }
 
-LONG_PTR ClassImpl::GetVtblGlobalOffset(void) const
+bool CClass::DupliCheckAll(const char *name){
+	//重複チェック
+
+	//メンバ
+	if(DupliCheckMember(name)) return 1;
+
+	//メソッド
+	BOOST_FOREACH( const CMethod *pMethod, methods ){
+		if( lstrcmp( name, pMethod->GetUserProc().GetName().c_str() ) == 0 ){
+			return 1;
+		}
+	}
+
+	return 0;
+}
+bool CClass::DupliCheckMember(const char *name){
+	//重複チェック
+
+	// 動的メンバ
+	BOOST_FOREACH( CMember *pMember, dynamicMembers ){
+		if( GetName() == pMember->GetName() ){
+			return 1;
+		}
+	}
+
+	// 静的メンバ
+	BOOST_FOREACH( CMember *pMember, staticMembers ){
+		if( GetName() == pMember->GetName() ){
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+//サイズを取得
+int CClass::GetSize() const
+{
+	return GetMemberOffset( NULL, NULL );
+}
+
+//メンバのオフセットを取得
+int CClass::GetMemberOffset( const char *memberName, int *pMemberNum ) const
+{
+	int i2;
+
+	//仮想関数が存在する場合は関数リストへのポインタのサイズを追加
+	int offset = IsExistVirtualFunctions() ? PTR_SIZE : 0;
+
+	int alignment;
+	if(iAlign) alignment=iAlign;
+	else alignment=1;
+
+	int iMaxAlign=0;
+	int i = -1;
+	BOOST_FOREACH( CMember *pMember, dynamicMembers ){
+		i++;
+
+		i2 = pMember->GetType().GetSize();
+
+		//アラインメントを算出
+		int member_size;
+		if( pMember->GetType().IsStruct() ){
+			//メンバクラスのアラインメントを取得
+			member_size=pMember->GetType().GetClass().GetAlignment();
+		}
+		else{
+			//メンバサイズを取得
+			member_size=i2;
+		}
+		if(iMaxAlign<member_size) iMaxAlign=member_size;
+
+		//アラインメントを考慮
+		if(iAlign&&iAlign<member_size){
+			if(offset%alignment) offset+=alignment-(offset%alignment);
+		}
+		else{
+			if(alignment<member_size) alignment=member_size;
+
+			if(member_size==0){
+				//メンバを持たないクラス
+				//※何もしない（オフセットの計算をしない）
+			}
+			else{
+				if(offset%member_size) offset+=member_size-(offset%member_size);
+			}
+		}
+
+		if(memberName){
+			//メンバ指定がある場合は、オフセットを返す
+			if( pMember->GetName() == memberName ){
+				if(pMemberNum) *pMemberNum=i;
+				return offset;
+			}
+		}
+
+		//配列を考慮したメンバサイズを取得
+		member_size = i2 * Variable::GetSubScriptCounts( pMember->GetSubscripts() );
+
+		//メンバサイズを加算
+		offset+= member_size;
+	}
+
+	if(iMaxAlign<alignment) alignment=iMaxAlign;
+
+	//アラインメントを考慮
+	if(alignment){
+		if(offset%alignment) offset+=alignment-(offset%alignment);
+	}
+
+	if(pMemberNum) *pMemberNum=i;
+	return offset;
+}
+int CClass::GetAlignment() const
+{
+	//仮想関数が存在する場合は関数リストへのポインタのサイズを追加
+	int alignment = IsExistVirtualFunctions() ? PTR_SIZE : 0;
+
+	BOOST_FOREACH( CMember *pMember, dynamicMembers ){
+		int member_size;
+		if(pMember->GetType().IsStruct()){
+			//メンバクラスのアラインメントを取得
+			member_size=pMember->GetType().GetClass().GetAlignment();
+		}
+		else{
+			//メンバサイズを取得
+			member_size = pMember->GetType().GetSize();
+		}
+
+		//アラインメントをセット
+		if(alignment<member_size) alignment=member_size;
+	}
+
+	if(alignment==0) return 0;
+
+	if(iAlign) alignment=iAlign;
+
+	return alignment;
+}
+int CClass::GetFuncNumInVtbl( const UserProc *pUserProc ) const
+{
+	int n = 0;
+	BOOST_FOREACH( const CMethod *pMethod, methods ){
+		if( &pMethod->GetUserProc() == pUserProc ) break;
+		if( pMethod->IsVirtual() ) n++;
+	}
+	return n;
+}
+LONG_PTR CClass::GetVtblGlobalOffset(void) const
 {
 
@@ -458,6 +692,6 @@
 	//////////////////////////////////////
 
-	UserProc **ppsi;
-	ppsi=(UserProc **)malloc(GetVtblNum()*sizeof(UserProc *));
+	const UserProc **ppsi;
+	ppsi=(const UserProc **)malloc(GetVtblNum()*sizeof(UserProc *));
 
 	//関数テーブルに値をセット
@@ -465,5 +699,5 @@
 	BOOST_FOREACH( const CMethod *pMethod, methods ){
 		if(pMethod->IsVirtual()){
-			pMethod->pUserProc->Using();
+			pMethod->GetUserProc().Using();
 
 			if(pMethod->IsAbstract()){
@@ -474,5 +708,5 @@
 			}
 			else{
-				ppsi[i2]=pMethod->pUserProc;
+				ppsi[i2]=&pMethod->GetUserProc();
 			}
 			i2++;
@@ -490,5 +724,5 @@
 	return vtbl_offset;
 }
-void ClassImpl::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){
+void CClass::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){
 	if(vtbl_offset==-1) return;
 
@@ -501,13 +735,93 @@
 		pUserProc=(UserProc *)pVtbl[i];
 		if(!pUserProc) continue;
-		pVtbl[i]=pUserProc->beginOpAddress+ImageBase+MemPos_CodeSection;
-	}
-}
-
-CClass *ClassesImpl::Create( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name){
-	return new ClassImpl(namespaceScopes, importedNamespaces, name);
-}
-
-void ClassesImpl::CollectClassesForNameOnly( const BasicSource &source )
+		pVtbl[i]=pUserProc->GetBeginOpAddress()+ImageBase+MemPos_CodeSection;
+	}
+}
+bool CClass::IsAbstract() const
+{
+	// 未実装(abstract)の仮想関数を持つ場合はtrueを返す
+
+	BOOST_FOREACH( const CMethod *pMethod, methods ){
+		if(pMethod->IsVirtual()){
+			if(pMethod->IsAbstract()){
+				return true;
+			}
+		}
+	}
+
+	return false;
+}
+
+
+int Classes::GetHashCode(const char *name) const
+{
+	int key;
+
+	for(key=0;*name!='\0';name++){
+		key=((key<<8)+ *name )%MAX_CLASS_HASH;
+	}
+
+	return key;
+}
+
+CClass *Classes::Create( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name){
+	return new CClass(namespaceScopes, importedNamespaces, name);
+}
+bool Classes::Insert( CClass *pClass )
+{
+	// キャッシュしておくクラス
+	if( pClass->GetName() == "String" )
+	{
+		pStringClass=pClass;
+	}
+	else if( pClass->GetName() == "Object" )
+	{
+		pObjectClass = pClass;
+	}
+
+	/////////////////////////////////
+	// ハッシュデータに追加
+	/////////////////////////////////
+
+	int key;
+	key=GetHashCode( pClass->GetName().c_str() );
+
+	if(pobj_ClassHash[key]){
+		CClass *pobj_c2;
+		pobj_c2=pobj_ClassHash[key];
+		while(1){
+			if( ((const Prototype *)pobj_c2)->IsEqualSymbol( *(const Prototype *)pClass ) ){
+				//名前空間及びクラス名が重複した場合
+				SmoothieException::Throw(15,pClass->GetName());
+				return false;
+			}
+
+			if(pobj_c2->pobj_NextClass==0) break;
+			pobj_c2=pobj_c2->pobj_NextClass;
+		}
+		pobj_c2->pobj_NextClass=pClass;
+	}
+	else{
+		pobj_ClassHash[key]=pClass;
+	}
+	return true;
+}
+CClass *Classes::Add( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name,int nowLine){
+	//////////////////////////////////////////////////////////////////////////
+	// クラスを追加
+	// ※名前のみを登録。その他の情報はSetClassメソッドで！
+	//////////////////////////////////////////////////////////////////////////
+
+	CClass *pClass = Create(namespaceScopes, importedNamespaces, name);
+
+	if( !Insert( pClass ) )
+	{
+		return NULL;
+	}
+
+	return pClass;	
+}
+
+void Classes::CollectClassesForNameOnly( const BasicSource &source )
 {
 	int i, i2;
@@ -641,5 +955,22 @@
 }
 
-void ClassesImpl::InitStaticMember(){
+void Classes::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){
+	int i;
+	for(i=0;i<MAX_CLASS_HASH;i++){
+		if(pobj_ClassHash[i]){
+			CClass *pobj_c;
+			pobj_c=pobj_ClassHash[i];
+			while(1){
+				pobj_c->ActionVtblSchedule(ImageBase,MemPos_CodeSection);
+
+				if(pobj_c->pobj_NextClass==0) break;
+				pobj_c=pobj_c->pobj_NextClass;
+			}
+		}
+	}
+}
+
+
+void Classes::InitStaticMember(){
 	//静的メンバをグローバル領域に作成
 
@@ -662,5 +993,5 @@
 			dim(
 				temporary,
-				member->SubScripts,
+				member->GetSubscripts(),
 				member->GetType(),
 				member->GetInitializeExpression().c_str(),
@@ -679,5 +1010,5 @@
 	cp=back_cp;
 }
-bool ClassesImpl::MemberVar_LoopRefCheck(const CClass &objClass){
+bool Classes::MemberVar_LoopRefCheck(const CClass &objClass){
 	bool result = true;
 	BOOST_FOREACH( CMember *pMember, objClass.GetDynamicMembers() ){
@@ -704,5 +1035,5 @@
 	return result;
 }
-void ClassesImpl::GetClass_recur(const char *lpszInheritsClass){
+void Classes::GetClass_recur(const char *lpszInheritsClass){
 	extern char *basbuf;
 	int i,i2,i3,sub_address,top_pos;
@@ -1156,5 +1487,5 @@
 	compiler.GetNamespaceSupporter().GetLivingNamespaceScopes() = backupNamespaceScopes;
 }
-void ClassesImpl::GetAllClassInfo(void){
+void Classes::GetAllClassInfo(void){
 	//ループ継承チェック用のクラス
 	pobj_LoopRefCheck=new CLoopRefCheck();
@@ -1169,5 +1500,5 @@
 	this->Iterator_Init();
 }
-void ClassesImpl::Compile_System_InitializeUserTypes(){
+void Classes::Compile_System_InitializeUserTypes(){
 	char temporary[VN_SIZE];
 
@@ -1296,5 +1627,5 @@
 }
 
-const CClass *ClassesImpl::Find( const NamespaceScopes &namespaceScopes, const string &name ) const
+const CClass *Classes::Find( const NamespaceScopes &namespaceScopes, const string &name ) const
 {
 	int key;
@@ -1333,2 +1664,93 @@
 	return NULL;
 }
+const CClass *Classes::Find( const string &fullName ) const
+{
+	char AreaName[VN_SIZE] = "";		//オブジェクト変数
+	char NestName[VN_SIZE] = "";		//入れ子メンバ
+	bool isNest = SplitMemberName( fullName.c_str(), AreaName, NestName );
+
+	return Find( NamespaceScopes( AreaName ), NestName );
+}
+void Classes::StartCompile( const UserProc *pUserProc ){
+	const CClass *pParentClass = pUserProc->GetParentClassPtr();
+	if( pParentClass ){
+		pParentClass->Using();
+
+		pCompilingMethod = pParentClass->GetMethods().GetMethodPtr( pUserProc );
+		if( !pCompilingMethod ){
+			pCompilingMethod = pParentClass->GetStaticMethods().GetMethodPtr( pUserProc );
+			if( !pCompilingMethod ){
+				SmoothieException::Throw(300);
+			}
+		}
+	}
+	else{
+		pCompilingMethod = NULL;
+	}
+}
+
+CClass *Classes::GetStringClassPtr() const
+{
+	if( !pStringClass ){
+		SmoothieException::Throw();
+		return NULL;
+	}
+	return pStringClass;
+}
+CClass *Classes::GetObjectClassPtr() const
+{
+	if( !pObjectClass ){
+		SmoothieException::Throw();
+		return NULL;
+	}
+	return pObjectClass;
+}
+
+
+//////////////////////
+// イテレータ
+//////////////////////
+
+void Classes::Iterator_Init() const
+{
+	if(ppobj_IteClass) free(ppobj_IteClass);
+
+	iIteMaxNum=0;
+	iIteNextNum=0;
+	ppobj_IteClass=(CClass **)malloc(1);
+
+	int i;
+	for(i=0;i<MAX_CLASS_HASH;i++){
+		if(pobj_ClassHash[i]){
+			CClass *pobj_c;
+			pobj_c=pobj_ClassHash[i];
+			while(1){
+				ppobj_IteClass=(CClass **)realloc(ppobj_IteClass,(iIteMaxNum+1)*sizeof(CClass *));
+				ppobj_IteClass[iIteMaxNum]=pobj_c;
+				iIteMaxNum++;
+
+				if(pobj_c->pobj_NextClass==0) break;
+				pobj_c=pobj_c->pobj_NextClass;
+			}
+		}
+	}
+}
+void Classes::Iterator_Reset() const
+{
+	iIteNextNum = 0;
+}
+BOOL Classes::Iterator_HasNext() const
+{
+	if(iIteNextNum<iIteMaxNum) return 1;
+	return 0;
+}
+CClass *Classes::Iterator_GetNext() const
+{
+	CClass *pobj_c = ppobj_IteClass[iIteNextNum];
+	iIteNextNum++;
+	return pobj_c;
+}
+int Classes::Iterator_GetMaxCount() const
+{
+	return iIteMaxNum;
+}
