Index: trunk/abdev/BasicCompiler64/Compile_Func.cpp
===================================================================
--- trunk/abdev/BasicCompiler64/Compile_Func.cpp	(revision 331)
+++ trunk/abdev/BasicCompiler64/Compile_Func.cpp	(revision 339)
@@ -70,36 +70,9 @@
 	return;
 }
-void Opcode_Func_AddressOf( const char *name, const Type &baseType ){
-	extern int cp;
-	const UserProc *pUserProc;
-
-	if( baseType.IsProcPtr() )
-	{
-		//左辺の型にのっとり、オーバーロードを解決
-
-		std::vector<const UserProc *> subs;
-		GetOverloadSubHash( name, subs );
-		if( subs.size() == 0 ){
-			SetError(27,name,cp);
-			return;
-		}
-
-		//オーバーロードを解決
-		pUserProc=OverloadSolution(name,subs,compiler.GetObjectModule().meta.GetProcPointers()[baseType.GetIndex()]->Params(), Type() );
-
-		if(!pUserProc){
-			SetError(27,name,cp);
-			return;
-		}
-	}
-	else{
-		pUserProc=GetSubHash(name);
-		if(!pUserProc){
-			SetError(27,name,cp);
-			return;
-		}
-	}
-
-	if( pUserProc->IsVirtual() ){
+
+void _Opcode_Func_AddressOf( const char *methodInstanceName, const UserProc &userProc )
+{
+	if( userProc.IsVirtual() )
+	{
 		///////////////////////////////
 		// 仮想関数の場合
@@ -111,5 +84,5 @@
 		char ObjectName[VN_SIZE];
 		ReferenceKind referenceKind;
-		SplitObjectName(name,ObjectName, referenceKind );
+		SplitObjectName(methodInstanceName,ObjectName, referenceKind );
 
 		if(ObjectName[0]){
@@ -151,5 +124,5 @@
 		compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_R11,REG_RCX,0,MOD_BASE);
 
-		int i2 = pobj_c->GetFuncNumInVtbl( pUserProc );
+		int i2 = pobj_c->GetFuncNumInVtbl( &userProc );
 
 		//mov rax,qword ptr[r11+func_index]
@@ -165,8 +138,164 @@
 
 		//mov rax,ProcAddr
-		compiler.codeGenerator.op_addressof( REG_RAX, pUserProc );
-	}
-
-	pUserProc->Using();
+		compiler.codeGenerator.op_addressof( REG_RAX, &userProc );
+	}
+
+	userProc.Using();
+}
+void Opcode_CreateDelegate( const CClass &dgClass, const char *methodInstanceName, const UserProc &userProc )
+{
+	/////////////////////////////////////////////////////////////////
+	// 関数ポインタをpush
+	/////////////////////////////////////////////////////////////////
+
+	//mov rax,AddressOf
+	_Opcode_Func_AddressOf( methodInstanceName, userProc );
+
+
+	if( userProc.GetMethod().IsDynamic() )
+	{
+		//mov rdx,rax
+		compiler.codeGenerator.op_mov_RR( REG_RDX, REG_RAX );
+
+		pobj_BlockReg->lock( REG_RDX );
+
+
+		/////////////////////////////////////////////////////////////////
+		// オブジェクト ポインタをpush
+		/////////////////////////////////////////////////////////////////
+
+		// オブジェクト名を取得
+		char objectName[VN_SIZE];
+		char memberName[VN_SIZE];
+		char *thisPtrName = "This";
+		Type type;
+		if( SplitMemberName( methodInstanceName, objectName, memberName ) )
+		{
+			if( GetVarType( objectName, type, false ) )
+			{
+				thisPtrName = objectName;
+			}
+		}
+
+		// オブジェクト ポインタを取得
+		RELATIVE_VAR relativeVar;
+		GetVarOffsetReadOnly( thisPtrName, &relativeVar, type );
+		if( !type.IsObject() )
+		{
+			extern int cp;
+			SetError(1,NULL,cp);
+			return;
+		}
+
+		SetVarPtrToReg( REG_RAX, &relativeVar );
+
+		//mov rcx,dword ptr[rax]
+		compiler.codeGenerator.op_mov_RM( sizeof(_int64), REG_RCX, REG_RAX, 0, MOD_BASE );
+
+		pobj_BlockReg->unlock( REG_RDX );
+	}
+	else
+	{
+		//mov rcx,rax
+		compiler.codeGenerator.op_mov_RR( REG_RCX, REG_RAX );
+	}
+
+
+	/////////////////////////////////////////////////////////////////
+	// call _CreateDynamicDelegate/_CreateStaticDelegate
+	/////////////////////////////////////////////////////////////////
+
+	std::vector<const UserProc *> subs;
+	if( userProc.GetMethod().IsDynamic() )
+	{
+		dgClass.GetStaticMethods().Enum( "_CreateDynamicDelegate", subs );
+	}
+	else
+	{
+		dgClass.GetStaticMethods().Enum( "_CreateStaticDelegate", subs );
+	}
+
+	// call _CreateDynamicDelegate
+	compiler.codeGenerator.op_call( subs[0] );
+}
+void Opcode_Func_AddressOf( const char *name, const Type &baseType, bool isCallOn, Type &resultType )
+{
+	extern int cp;
+	const UserProc *pUserProc;
+
+	const Parameters *pBaseParams = NULL;
+	if( baseType.IsProcPtr() )
+	{
+		// 左辺で関数ポインタを要求されているとき
+		pBaseParams = &compiler.GetObjectModule().meta.GetProcPointers()[baseType.GetIndex()]->Params();
+	}
+	else if( baseType.IsDelegate() )
+	{
+		// 左辺でデリゲートを要求されているとき
+		pBaseParams = &baseType.GetClass().GetDelegate().Params();
+	}
+
+	if( pBaseParams )
+	{
+		//左辺の型にのっとり、オーバーロードを解決
+
+		std::vector<const UserProc *> subs;
+		GetOverloadSubHash( name, subs );
+		if( subs.size() == 0 ){
+			SetError(27,name,cp);
+			return;
+		}
+
+		//オーバーロードを解決
+		pUserProc=OverloadSolution( name, subs, *pBaseParams, Type() );
+
+		if( isCallOn && baseType.IsDelegate() )
+		{
+			// コード生成を伴う場合はエラーチェックを行う
+			if( !pUserProc->Params().Equals( *pBaseParams )
+				|| !pUserProc->ReturnType().Equals( baseType.GetClass().GetDelegate().ReturnType() ) )
+			{
+				if( baseType.IsDelegate() )
+				{
+					SetError(67, name, cp );
+				}
+				else
+				{
+					SetError(66, name, cp );
+				}
+			}
+		}
+
+		if(!pUserProc){
+			SetError(27,name,cp);
+			return;
+		}
+	}
+	else{
+		pUserProc=GetSubHash(name);
+		if(!pUserProc){
+			SetError(27,name,cp);
+			return;
+		}
+	}
+
+	if( baseType.IsDelegate() )
+	{
+		if( isCallOn )
+		{
+			// デリゲートのとき
+			Opcode_CreateDelegate( baseType.GetClass(), name, *pUserProc );
+		}
+		resultType = baseType;
+	}
+	else
+	{
+		if( isCallOn )
+		{
+			// 関数ポインタのとき
+			_Opcode_Func_AddressOf( name, *pUserProc );
+		}
+		resultType.SetBasicType( DEF_PTR_VOID );
+	}
 }
 void Opcode_Func_SizeOf( const string &typeName ){
@@ -262,5 +391,5 @@
 		i = GetOneParameter( paramsStr, i, methodPtrParamStr );
 
-		char objPtrValueStr[VN_SIZE];
+		char objPtrValueStr[VN_SIZE] = "";
 		if( isDynamicCall )
 		{
@@ -307,6 +436,5 @@
 			break;
 		case FUNC_ADDRESSOF:
-			if( isCallOn ) Opcode_Func_AddressOf( Parameter, baseType );
-			resultType.SetBasicType( DEF_PTR_VOID );
+			Opcode_Func_AddressOf( Parameter, baseType, isCallOn, resultType );
 			break;
 		case FUNC_SIZEOF:
