#include "common.h" #ifdef _AMD64_ #include "../BasicCompiler64/opcode.h" #else #include "../BasicCompiler32/opcode.h" #endif CDBClass *pobj_DBClass; CClass *pobj_CompilingClass; CClass *pobj_StringClass; CMember *pCompilingMethod; int AddDataTable(char *buffer,int length); CMember::CMember( CClass *pobj_c, DWORD access, bool isConst, char *buffer, int NowLine ){ extern int cp; //構文を解析 char VarName[VN_SIZE]; char init_buf[VN_SIZE]; char constract_parameter[VN_SIZE]; if(!GetDimentionFormat(buffer,VarName,SubScripts,&TypeInfo,init_buf,constract_parameter)) return; //重複チェック if(pobj_c->DupliCheckAll(VarName)){ SetError(15,VarName,cp); return; } if(TypeInfo.type==DEF_OBJECT){ if(TypeInfo.u.pobj_Class->IsHoldAbstractFunction()){ //抽象クラスだったとき SetError(125,TypeInfo.u.pobj_Class->name,cp); } } //メンバ名 name=(char *)HeapAlloc(hHeap,0,lstrlen(VarName)+1); lstrcpy(name,VarName); //アクセス権 dwAccess=access; //定数扱いかどうか this->isConst = isConst; //初期データ InitBuf=(char *)HeapAlloc(hHeap,0,lstrlen(init_buf)+1); lstrcpy(InitBuf,init_buf); //コンストラクタ用のパラメータ ConstractParameter=(char *)HeapAlloc(hHeap,0,lstrlen(constract_parameter)+1); lstrcpy(ConstractParameter,constract_parameter); //ソースコードの位置 source_code_address=NowLine; } CMember::CMember(CMember *pobj){ //コピーコンストラクタ memset(this,0,sizeof(CMember)); //name name=(char *)HeapAlloc(hHeap,0,lstrlen(pobj->name)+1); lstrcpy(name,pobj->name); //定数扱いかどうか isConst = pobj->isConst; //SubScripts memcpy(SubScripts,pobj->SubScripts,MAX_ARRAYDIM*sizeof(int)); //TypeInfo TypeInfo=pobj->TypeInfo; //ソースコードの位置 source_code_address=pobj->source_code_address; } CMember::CMember(){ memset(this,0,sizeof(CMember)); } CMember::~CMember(){ HeapDefaultFree(name); if(InitBuf) HeapDefaultFree(InitBuf); if(ConstractParameter) HeapDefaultFree(ConstractParameter); } bool CMember::IsConst(){ return isConst; } void CMember::InitStaticMember(void){ //静的メンバをグローバル領域に作成 //イテレータをリセット extern CDBClass *pobj_DBClass; pobj_DBClass->Iterator_Reset(); int back_cp=cp; while(pobj_DBClass->Iterator_HasNext()){ CClass *pobj_c; pobj_c=pobj_DBClass->Iterator_GetNext(); int i; char temporary[VN_SIZE]; for(i=0;iiStaticMemberNum;i++){ sprintf(temporary,"%s.%s",pobj_c->name,pobj_c->ppobj_StaticMember[i]->name); AddGlobalVariable( temporary, pobj_c->ppobj_StaticMember[i]->SubScripts, &pobj_c->ppobj_StaticMember[i]->TypeInfo, GetTypeSize(pobj_c->ppobj_StaticMember[i]->TypeInfo.type,pobj_c->ppobj_StaticMember[i]->TypeInfo.u.lpIndex), pobj_c->ppobj_StaticMember[i]->InitBuf, pobj_c->ppobj_StaticMember[i]->ConstractParameter, 0); if(pobj_c->ppobj_StaticMember[i]->TypeInfo.type==DEF_OBJECT){ //エラー用 cp=pobj_c->ppobj_StaticMember[i]->source_code_address; CallConstractor(temporary, pobj_c->ppobj_StaticMember[i]->SubScripts, pobj_c->ppobj_StaticMember[i]->TypeInfo, pobj_c->ppobj_StaticMember[i]->ConstractParameter); } //ネイティブコードバッファの再確保 extern int obp_AllocSize; if(obp_AllocSizepsi; bAbstract=pobj->bAbstract; bVirtual=pobj->bVirtual; } CMethod::CMethod(){ memset(this,0,sizeof(CMethod)); } CMethod::~CMethod(){ } CClass::CClass(char *name){ memset(this,0,sizeof(CClass)); vtbl_offset=-1; this->name=(char *)HeapAlloc(hHeap,0,lstrlen(name)+1); lstrcpy(this->name,name); isCompilingConstructor = false; isCompilingDestructor = false; } CClass::~CClass(){ int i; //クラス名 HeapDefaultFree(name); if(ppobj_Member){ //メンバ for(i=0;ipsi = psi; ppobj_Method[iMethodNum]->dwAccess = dwAccess; ppobj_Method[iMethodNum]->isConst = isConst; ppobj_Method[iMethodNum]->bAbstract = bAbstract; ppobj_Method[iMethodNum]->bVirtual = bVirtual; ppobj_Method[iMethodNum]->pobj_InheritsClass = 0; iMethodNum++; } void CClass::AddStaticMethod(SUBINFO *psi,DWORD dwAccess){ ppobj_StaticMethod=(CMethod **)HeapReAlloc(hHeap,0,ppobj_StaticMethod,(iStaticMethodNum+1)*sizeof(CMethod *)); ppobj_StaticMethod[iStaticMethodNum]=new CMethod(); ppobj_StaticMethod[iStaticMethodNum]->psi=psi; ppobj_StaticMethod[iStaticMethodNum]->dwAccess=dwAccess; ppobj_StaticMethod[iStaticMethodNum]->bAbstract=0; ppobj_StaticMethod[iStaticMethodNum]->bVirtual=0; ppobj_StaticMethod[iStaticMethodNum]->pobj_InheritsClass=0; iStaticMethodNum++; } BOOL CClass::DupliCheckAll(char *name){ //重複チェック int i; //メンバ if(DupliCheckMember(name)) return 1; //メソッド for(i=0;ipsi->name)==0){ return 1; } } return 0; } BOOL CClass::DupliCheckMember(char *name){ //重複チェック int i; //メンバ for(i=0;iname)==0){ return 1; } } //静的メンバ for(i=0;iname)==0){ return 1; } } return 0; } CMethod *CClass::GetMethodInfo( SUBINFO *psi ){ int i; for( i=0; ipsi ) break; } if( i == iMethodNum ){ return NULL; } return ppobj_Method[i]; } CMethod *CClass::GetStaticMethodInfo( SUBINFO *psi ){ int i; for( i=0; ipsi ) break; } if( i == iMethodNum ){ return NULL; } return ppobj_StaticMethod[i]; } LONG_PTR CClass::AddVtblDataTable(SUBINFO **ppsi,int length){ return AddDataTable((char *)ppsi,length); } LONG_PTR CClass::GetVtblGlobalOffset(void){ if(vtbl_offset!=-1) return vtbl_offset; SUBINFO **ppsi; ppsi=(SUBINFO **)HeapAlloc(hHeap,0,vtbl_num*sizeof(SUBINFO *)); //関数テーブルに値をセット int i,i2,i3=0; for(i=0;i < iMethodNum;i++){ if(ppobj_Method[i]->bVirtual){ for(i2=iMethodNum-1; i2>=i; i2--){ if(lstrcmp(ppobj_Method[i]->psi->name,ppobj_Method[i2]->psi->name)==0){ pobj_CompilingClass->ppobj_Method[i2]->psi->bUse=1; if(ppobj_Method[i2]->bAbstract){ extern int cp; SetError(300,NULL,cp); ppsi[i3]=0; } else ppsi[i3]=pobj_CompilingClass->ppobj_Method[i2]->psi; i3++; break; } } } } vtbl_offset=AddDataTable((char *)ppsi,vtbl_num*sizeof(LONG_PTR)); for(i=0;iAddSchedule_DataSection(vtbl_offset+i*sizeof(LONG_PTR)); } HeapDefaultFree(ppsi); return vtbl_offset; } void CClass::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){ if(vtbl_offset==-1) return; extern char *DataTable; LONG_PTR *pVtbl; pVtbl=(LONG_PTR *)(DataTable+vtbl_offset); int i; for(i=0;iCompileAddress+ImageBase+MemPos_CodeSection; } } BOOL CClass::IsHoldAbstractFunction(void){ //未実装の仮想関数を持つ場合は1を返す int i,i2,i3=0; for(i=0;i < iMethodNum;i++){ if(ppobj_Method[i]->bVirtual){ for(i2=iMethodNum-1; i2>=i; i2--){ if(lstrcmp(ppobj_Method[i]->psi->name,ppobj_Method[i2]->psi->name)==0){ if(ppobj_Method[i2]->bAbstract){ return 1; } break; } } } } //コンポジションの関係にあるメンバも検査する for(i=0;i < iMemberNum;i++){ if(ppobj_Member[i]->TypeInfo.type==DEF_OBJECT){ if(ppobj_Member[i]->TypeInfo.u.pobj_Class->IsHoldAbstractFunction()) return 1; } } return 0; } SUBINFO **CClass::GetOperatorSubInfo(BYTE idCalc,int &num){ //格納のための構造体配列を用意 SUBINFO **ppArray_si; ppArray_si=(SUBINFO **)HeapAlloc(hHeap,0,sizeof(SUBINFO *)*1024); num=0; int i; for(i=0;ipsi->name; if(temp[0]==1&&temp[1]==ESC_OPERATOR){ if((BYTE)temp[2]==idCalc){ ppArray_si[num]=ppobj_Method[i]->psi; num++; } } } return ppArray_si; } // コンストラクタのコンパイルを開始 void CClass::NotifyStartConstructorCompile(){ isCompilingConstructor = true; } //コンストラクタのコンパイルを終了 void CClass::NotifyFinishConstructorCompile(){ isCompilingConstructor = false; } //コンストラクタをコンパイル中かどうかを判別 bool CClass::IsCompilingConstructor(){ return isCompilingConstructor; } //デストラクタのコンパイルを開始 void CClass::NotifyStartDestructorCompile(){ isCompilingDestructor = true; } //デストラクタのコンパイルを終了 void CClass::NotifyFinishDestructorCompile(){ isCompilingDestructor = false; } //デストラクタをコンパイル中かどうかを判別 bool CClass::IsCompilingDestructor(){ return isCompilingDestructor; } int CDBClass::hash(char *name){ int key; for(key=0;*name!='\0';name++){ key=((key<<8)+ *name )%MAX_CLASS_HASH; } return key; } void CDBClass::DestroyClass(CClass *pobj_c){ if(pobj_c->pobj_NextClass){ DestroyClass(pobj_c->pobj_NextClass); } delete pobj_c; } CDBClass::CDBClass(){ memset(this,0,sizeof(CDBClass)); } CDBClass::~CDBClass(){ int i; for(i=0;iActionVtblSchedule(ImageBase,MemPos_CodeSection); if(pobj_c->pobj_NextClass==0) break; pobj_c=pobj_c->pobj_NextClass; } } } } CClass *CDBClass::check(char *name){ int key; key=hash(name); if(pobj_ClassHash[key]){ CClass *pobj_c; pobj_c=pobj_ClassHash[key]; while(1){ if(lstrcmp(name,pobj_c->name)==0){ //重複した場合 return pobj_c; } if(pobj_c->pobj_NextClass==0) break; pobj_c=pobj_c->pobj_NextClass; } } return 0; } CClass *CDBClass::AddClass(char *name,int NowLine){ ////////////////////////////////////////////////////////////////////////// // クラスを追加 // ※名前のみを登録。その他の情報はSetClassメソッドで! ////////////////////////////////////////////////////////////////////////// CClass *pobj_c; pobj_c=new CClass(name); if(lstrcmp(name,"String")==0){ //Stringクラス pobj_StringClass=pobj_c; } ///////////////////////////////// // ハッシュデータに追加 ///////////////////////////////// int key; key=hash(name); if(pobj_ClassHash[key]){ CClass *pobj_c2; pobj_c2=pobj_ClassHash[key]; while(1){ if(lstrcmp(name,pobj_c2->name)==0){ //重複した場合 SetError(15,name,NowLine); return 0; } if(pobj_c2->pobj_NextClass==0) break; pobj_c2=pobj_c2->pobj_NextClass; } pobj_c2->pobj_NextClass=pobj_c; } else{ pobj_ClassHash[key]=pobj_c; } return pobj_c; } void CDBClass::InitNames(void){ extern char *basbuf; int i; for(i=0;;i++){ if(basbuf[i]=='\0') break; if(basbuf[i]==1&&( basbuf[i+1]==ESC_CLASS|| basbuf[i+1]==ESC_TYPE|| basbuf[i+1]==ESC_INTERFACE )){ int NowLine; NowLine=i; i+=2; //アラインメント修飾子 if(_memicmp(basbuf+i,"Align(",6)==0){ i+=6; i=JumpStringInPare(basbuf,i)+1; } int i2; char temporary[VN_SIZE]; for(i2=0;;i++,i2++){ if(!IsVariableChar(basbuf[i])){ temporary[i2]=0; break; } temporary[i2]=basbuf[i]; } //クラスを追加 pobj_DBClass->AddClass(temporary,NowLine); } } } void CDBClass::AddMethod(CClass *pobj_c, DWORD dwAccess, BOOL bStatic, bool isConst, BOOL bAbstract, BOOL bVirtual, BOOL bOverride, char *buffer, int NowLine){ int i,i2; char temporary[VN_SIZE]; i=2; for(i2=0;;i++,i2++){ if(buffer[i]=='('||buffer[i]=='\0'){ temporary[i2]=0; break; } temporary[i2]=buffer[i]; } //関数ハッシュへ登録 SUBINFO *psi; psi=AddSubData(buffer,NowLine,bVirtual,pobj_c,bStatic); if(!psi) return; //////////////////////////////////////////////////////////// // コンストラクタ、デストラクタの場合の処理 //////////////////////////////////////////////////////////// BOOL fConstructor=0,bDestructor=0; if(lstrcmp(temporary,pobj_c->name)==0){ //コンストラクタの場合 //標準コンストラクタ(引数なし) if(psi->ParmNum==1) fConstructor=1; //コピーコンストラクタ if(psi->ParmNum==2){ if(psi->pParmInfo[1].type==DEF_OBJECT&& psi->pParmInfo[1].u.pobj_c==pobj_c) fConstructor=2; } //強制的にConst修飾子をつける isConst = true; } else if(temporary[0]=='~'){ //デストラクタの場合はその名前が正しいかチェックを行う if(lstrcmp(temporary+1,pobj_c->name)!=0) SetError(117,NULL,NowLine); else bDestructor=1; } if(fConstructor||bDestructor){ // コンストラクタ、デストラクタのアクセシビリティをチェック if(dwAccess!=ACCESS_PUBLIC){ SetError(116,NULL,NowLine); dwAccess=ACCESS_PUBLIC; } //強制的にConst修飾子をつける isConst = true; } if( fConstructor == 1 ) pobj_c->ConstructorMemberSubIndex = pobj_c->iMethodNum; else if( fConstructor == 2 ) pobj_c->CopyConstructorMemberSubIndex = pobj_c->iMethodNum; else if( bDestructor ) pobj_c->DestructorMemberSubIndex = pobj_c->iMethodNum; ////////////////// // 重複チェック ////////////////// if(pobj_c->DupliCheckMember(temporary)){ SetError(15,temporary,NowLine); return; } //メンバ関数 for(i=0;iiMethodNum;i++){ //スーパークラスと重複する場合はオーバーライドを行う if(pobj_c->ppobj_Method[i]->pobj_InheritsClass) continue; if(lstrcmp(temporary,pobj_c->ppobj_Method[i]->psi->name)==0){ if(CompareParameter( pobj_c->ppobj_Method[i]->psi->pParmInfo,pobj_c->ppobj_Method[i]->psi->ParmNum, psi->pParmInfo,psi->ParmNum )==0){ //関数名、パラメータ属性が合致したとき SetError(15,psi->name,NowLine); return; } } } //仮想関数の場合 if(bAbstract) psi->bCompile=1; for(i=0;iiMethodNum;i++){ if(lstrcmp(temporary,pobj_c->ppobj_Method[i]->psi->name)==0){ if(CompareParameter( pobj_c->ppobj_Method[i]->psi->pParmInfo,pobj_c->ppobj_Method[i]->psi->ParmNum, psi->pParmInfo,psi->ParmNum )==0){ if(pobj_c->ppobj_Method[i]->psi->bVirtual){ //メンバ関数を上書き pobj_c->ppobj_Method[i]->psi=psi; pobj_c->ppobj_Method[i]->bAbstract=0; if(!bOverride){ SetError(127,NULL,NowLine); } if(pobj_c->ppobj_Method[i]->dwAccess!=dwAccess){ SetError(128,NULL,NowLine); } return; } } } } if(psi->bVirtual){ pobj_c->vtbl_num++; } if(bOverride){ SetError(12,"Override",NowLine); } if(bStatic){ pobj_c->AddStaticMethod(psi,dwAccess); } else{ pobj_c->AddMethod(psi, dwAccess, isConst, bAbstract, bVirtual); } } BOOL CDBClass::MemberVar_LoopRefCheck(CClass *pobj_c){ int i,i2,bRet=1; for(i=0;iiMemberNum;i++){ if(pobj_c->ppobj_Member[i]->TypeInfo.type==DEF_OBJECT){ //循環参照でないかをチェック if(pobj_LoopRefCheck->check(pobj_c->ppobj_Member[i]->TypeInfo.u.pobj_Class->name)){ extern int cp; SetError(123,pobj_c->ppobj_Member[i]->TypeInfo.u.pobj_Class->name,cp); return 0; } pobj_LoopRefCheck->add(pobj_c->name); i2=MemberVar_LoopRefCheck(pobj_c->ppobj_Member[i]->TypeInfo.u.pobj_Class); if(bRet==1) bRet=i2; pobj_LoopRefCheck->del(pobj_c->name); } } return bRet; } void CDBClass::GetClass_recur(char *lpszInheritsClass){ extern char *basbuf; int i,i2,i3,sub_address,top_pos; DWORD dwClassType; DWORD dwAccess; char temporary[8192]; for(i=0;;i++){ if(basbuf[i]=='\0') break; CClass *pobj_c; if(basbuf[i]==1&&basbuf[i+1]==ESC_INTERFACE){ ////////////////////////// // インターフェイス ////////////////////////// top_pos=i; i+=2; //インターフェイス名を取得 GetIdentifierToken( temporary, basbuf, i ); pobj_c=pobj_DBClass->check(temporary); if(!pobj_c) continue; if(lpszInheritsClass){ if(lstrcmp(lpszInheritsClass,pobj_c->name)!=0){ //継承先先読み用 continue; } } if(pobj_c->ppobj_Member){ //既に先読みされているとき continue; } //メンバ用メモリを初期化 pobj_c->ppobj_Member=(CMember **)HeapAlloc(hHeap,0,1); pobj_c->iMemberNum=0; pobj_c->ppobj_StaticMember=(CMember **)HeapAlloc(hHeap,0,1); pobj_c->iStaticMemberNum=0; pobj_c->ppobj_Method=(CMethod **)HeapAlloc(hHeap,0,1); pobj_c->iMethodNum=0; pobj_c->ppobj_StaticMethod=(CMethod **)HeapAlloc(hHeap,0,1); pobj_c->iStaticMethodNum=0; pobj_c->ConstructorMemberSubIndex=-1; pobj_c->CopyConstructorMemberSubIndex=-1; pobj_c->DestructorMemberSubIndex=-1; if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS){ //継承を行う場合 for(i+=3,i2=0;;i++,i2++){ if(IsCommandDelimitation(basbuf[i])){ temporary[i2]=0; break; } temporary[i2]=basbuf[i]; } if(lstrcmpi(temporary,pobj_c->name)==0){ SetError(105,temporary,i); goto Interface_InheritsError; } //継承元クラスを取得 pobj_c->pobj_InheritsClass=check(temporary); if(!pobj_c->pobj_InheritsClass){ SetError(106,temporary,i); goto Interface_InheritsError; } //ループ継承でないかをチェック if(pobj_LoopRefCheck->check(temporary)){ SetError(123,temporary,i); goto Interface_InheritsError; } if(pobj_c->pobj_InheritsClass->ppobj_Member==0){ //継承先が読み取られていないとき pobj_LoopRefCheck->add(pobj_c->name); GetClass_recur(temporary); pobj_LoopRefCheck->del(pobj_c->name); } //メンバ変数をコピー pobj_c->ppobj_Member=(CMember **)HeapReAlloc( hHeap, 0, pobj_c->ppobj_Member, pobj_c->pobj_InheritsClass->iMemberNum*sizeof(CMember *)); pobj_c->iMemberNum=pobj_c->pobj_InheritsClass->iMemberNum; for(i3=0;i3pobj_InheritsClass->iMemberNum;i3++){ pobj_c->ppobj_Member[i3]=new CMember(pobj_c->pobj_InheritsClass->ppobj_Member[i3]); //dwAccess if(pobj_c->pobj_InheritsClass->ppobj_Member[i3]->dwAccess==ACCESS_PRIVATE) pobj_c->ppobj_Member[i3]->dwAccess=ACCESS_NON; else pobj_c->ppobj_Member[i3]->dwAccess=pobj_c->pobj_InheritsClass->ppobj_Member[i3]->dwAccess; } //メンバ関数をコピー pobj_c->ppobj_Method=(CMethod **)HeapReAlloc( hHeap, 0, pobj_c->ppobj_Method, pobj_c->pobj_InheritsClass->iMethodNum*sizeof(CMethod *)); pobj_c->iMethodNum=pobj_c->pobj_InheritsClass->iMethodNum; for(i3=0;i3pobj_InheritsClass->iMethodNum;i3++){ pobj_c->ppobj_Method[i3]=new CMethod(pobj_c->pobj_InheritsClass->ppobj_Method[i3]); //dwAccess if(pobj_c->pobj_InheritsClass->ppobj_Method[i3]->dwAccess==ACCESS_PRIVATE) pobj_c->ppobj_Method[i3]->dwAccess=ACCESS_NON; else pobj_c->ppobj_Method[i3]->dwAccess=pobj_c->pobj_InheritsClass->ppobj_Method[i3]->dwAccess; //pobj_Inherits // ※継承元のClassIndexをセット(入れ子継承を考慮する) if(pobj_c->pobj_InheritsClass->ppobj_Method[i3]->pobj_InheritsClass==0) pobj_c->ppobj_Method[i3]->pobj_InheritsClass=pobj_c->pobj_InheritsClass; else pobj_c->ppobj_Method[i3]->pobj_InheritsClass= pobj_c->pobj_InheritsClass->ppobj_Method[i3]->pobj_InheritsClass; } //仮想関数の数 pobj_c->vtbl_num=pobj_c->pobj_InheritsClass->vtbl_num; } else{ //継承無し pobj_c->pobj_InheritsClass=0; //仮想関数の数を初期化 pobj_c->vtbl_num=0; } Interface_InheritsError: //メンバ変数、関数を取得 while(1){ i++; //エラー if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE||basbuf[i+1]==ESC_INTERFACE)){ SetError(22,"Interface",i); i--; break; } if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){ SetError(111,NULL,i); break; } sub_address=i; for(i2=0;;i++,i2++){ if(IsCommandDelimitation(basbuf[i])){ temporary[i2]=0; break; } temporary[i2]=basbuf[i]; } if(temporary[0]=='\0'){ if(basbuf[i]=='\0'){ i--; SetError(22,"Interface",top_pos); break; } continue; } //End Interface記述の場合 if(temporary[0]==1&&temporary[1]==ESC_ENDINTERFACE) break; if(!(temporary[0]==1&&( temporary[1]==ESC_SUB||temporary[1]==ESC_FUNCTION ))){ SetError(1,NULL,i); break; } //メンバ関数を追加 AddMethod(pobj_c, ACCESS_PUBLIC, //Publicアクセス権 0, //Static指定なし false, //Constではない 1, //Abstract 1, //Virtual 0, temporary, sub_address ); } } if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){ ////////////////////////// // クラス ////////////////////////// top_pos=i; dwClassType=basbuf[i+1]; i+=2; //アラインメント修飾子 int iAlign=0; if(_memicmp(basbuf+i,"Align(",6)==0){ i+=6; i+=GetStringInPare_RemovePare(temporary,basbuf+i)+1; iAlign=atoi(temporary); if(!(iAlign==1||iAlign==2||iAlign==4||iAlign==8||iAlign==16)) SetError(51,NULL,i); } //クラス名を取得 GetIdentifierToken( temporary, basbuf, i ); pobj_c=pobj_DBClass->check(temporary); if(!pobj_c) continue; if(lpszInheritsClass){ if(lstrcmp(lpszInheritsClass,pobj_c->name)!=0){ //継承先先読み用 continue; } } if(pobj_c->ppobj_Member){ //既に先読みされているとき continue; } pobj_c->iAlign=iAlign; //メンバ用メモリを初期化 pobj_c->ppobj_Member=(CMember **)HeapAlloc(hHeap,0,1); pobj_c->iMemberNum=0; pobj_c->ppobj_StaticMember=(CMember **)HeapAlloc(hHeap,0,1); pobj_c->iStaticMemberNum=0; pobj_c->ppobj_Method=(CMethod **)HeapAlloc(hHeap,0,1); pobj_c->iMethodNum=0; pobj_c->ppobj_StaticMethod=(CMethod **)HeapAlloc(hHeap,0,1); pobj_c->iStaticMethodNum=0; pobj_c->ConstructorMemberSubIndex=-1; pobj_c->CopyConstructorMemberSubIndex=-1; pobj_c->DestructorMemberSubIndex=-1; //アクセス制限の初期値をセット if(dwClassType==ESC_CLASS) dwAccess=ACCESS_PRIVATE; else dwAccess=ACCESS_PUBLIC; if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS){ //継承を行う場合 for(i+=3,i2=0;;i++,i2++){ if(IsCommandDelimitation(basbuf[i])){ temporary[i2]=0; break; } temporary[i2]=basbuf[i]; } if(lstrcmpi(temporary,pobj_c->name)==0){ SetError(105,temporary,i); goto InheritsError; } //継承元クラスを取得 pobj_c->pobj_InheritsClass=check(temporary); if(!pobj_c->pobj_InheritsClass){ SetError(106,temporary,i); goto InheritsError; } //ループ継承でないかをチェック if(pobj_LoopRefCheck->check(temporary)){ SetError(123,temporary,i); goto InheritsError; } if(pobj_c->pobj_InheritsClass->ppobj_Member==0){ //継承先が読み取られていないとき pobj_LoopRefCheck->add(pobj_c->name); GetClass_recur(temporary); pobj_LoopRefCheck->del(pobj_c->name); } //メンバをコピー pobj_c->ppobj_Member=(CMember **)HeapReAlloc( hHeap, 0, pobj_c->ppobj_Member, pobj_c->pobj_InheritsClass->iMemberNum*sizeof(CMember *)); pobj_c->iMemberNum=pobj_c->pobj_InheritsClass->iMemberNum; for(i3=0;i3pobj_InheritsClass->iMemberNum;i3++){ pobj_c->ppobj_Member[i3]=new CMember(pobj_c->pobj_InheritsClass->ppobj_Member[i3]); //dwAccess if(pobj_c->pobj_InheritsClass->ppobj_Member[i3]->dwAccess==ACCESS_PRIVATE) pobj_c->ppobj_Member[i3]->dwAccess=ACCESS_NON; else pobj_c->ppobj_Member[i3]->dwAccess=pobj_c->pobj_InheritsClass->ppobj_Member[i3]->dwAccess; } //メソッドをコピー pobj_c->ppobj_Method=(CMethod **)HeapReAlloc( hHeap, 0, pobj_c->ppobj_Method, pobj_c->pobj_InheritsClass->iMethodNum*sizeof(CMethod *)); pobj_c->iMethodNum=pobj_c->pobj_InheritsClass->iMethodNum; for(i3=0;i3pobj_InheritsClass->iMethodNum;i3++){ pobj_c->ppobj_Method[i3]=new CMethod(pobj_c->pobj_InheritsClass->ppobj_Method[i3]); //dwAccess if(pobj_c->pobj_InheritsClass->ppobj_Method[i3]->dwAccess==ACCESS_PRIVATE) pobj_c->ppobj_Method[i3]->dwAccess=ACCESS_NON; else pobj_c->ppobj_Method[i3]->dwAccess=pobj_c->pobj_InheritsClass->ppobj_Method[i3]->dwAccess; //pobj_Inherits // ※継承元のClassIndexをセット(入れ子継承を考慮する) if(pobj_c->pobj_InheritsClass->ppobj_Method[i3]->pobj_InheritsClass==0) pobj_c->ppobj_Method[i3]->pobj_InheritsClass=pobj_c->pobj_InheritsClass; else pobj_c->ppobj_Method[i3]->pobj_InheritsClass= pobj_c->pobj_InheritsClass->ppobj_Method[i3]->pobj_InheritsClass; } //仮想関数の数 pobj_c->vtbl_num=pobj_c->pobj_InheritsClass->vtbl_num; } else{ //継承無し pobj_c->pobj_InheritsClass=0; //仮想関数の数を初期化 pobj_c->vtbl_num=0; } InheritsError: //メンバとメソッドを取得 while(1){ i++; //エラー if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){ SetError(22,"Class",i); i--; break; } if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){ SetError(111,NULL,i); break; } //Static修飾子 BOOL bStatic; if(basbuf[i]==1&&basbuf[i+1]==ESC_STATIC){ bStatic=1; i+=2; } else bStatic=0; //Const修飾子 bool isConst = false; if( basbuf[i] == 1 && basbuf[i + 1] == ESC_CONST ){ isConst = true; i += 2; } if(basbuf[i]==1&&( basbuf[i+1]==ESC_ABSTRACT||basbuf[i+1]==ESC_VIRTUAL||basbuf[i+1]==ESC_OVERRIDE|| basbuf[i+1]==ESC_SUB||basbuf[i+1]==ESC_FUNCTION )){ i3=basbuf[i+1]; sub_address=i; } else i3=0; BOOL bVirtual=0,bAbstract=0,bOverride=0; if(i3==ESC_ABSTRACT){ bAbstract=1; bVirtual=1; i+=2; i3=basbuf[i+1]; } else if(i3==ESC_VIRTUAL){ bAbstract=0; bVirtual=1; i+=2; i3=basbuf[i+1]; } else if(i3==ESC_OVERRIDE){ bOverride=1; bVirtual=1; i+=2; i3=basbuf[i+1]; } for(i2=0;;i++,i2++){ if(IsCommandDelimitation(basbuf[i])){ temporary[i2]=0; break; } temporary[i2]=basbuf[i]; } if(temporary[0]=='\0'){ if(basbuf[i]=='\0'){ if(dwClassType==ESC_CLASS) SetError(22,"Class",top_pos); else SetError(22,"Type",top_pos); i--; break; } continue; } //End Class記述の場合 if(temporary[0]==1&&temporary[1]==ESC_ENDCLASS&&dwClassType==ESC_CLASS) break; if(temporary[0]==1&&temporary[1]==ESC_ENDTYPE&&dwClassType==ESC_TYPE) break; //アクセスを変更 if(lstrcmpi(temporary,"Private")==0){ dwAccess=ACCESS_PRIVATE; continue; } if(lstrcmpi(temporary,"Public")==0){ dwAccess=ACCESS_PUBLIC; continue; } if(lstrcmpi(temporary,"Protected")==0){ dwAccess=ACCESS_PROTECTED; continue; } extern int cp; if(i3==0){ if(bStatic){ //静的メンバを追加 cp=i; //エラー用 pobj_c->AddStaticMember( dwAccess, isConst, temporary, i); } else{ //メンバを追加 cp=i; //エラー用 pobj_c->AddMember( dwAccess, isConst, temporary ); if(pobj_c->ppobj_Member[pobj_c->iMemberNum-1]->TypeInfo.type==DEF_OBJECT){ if(pobj_c->ppobj_Member[pobj_c->iMemberNum-1]->TypeInfo.u.pobj_Class->ppobj_Member==0){ //参照先が読み取られていないとき GetClass_recur(pobj_c->ppobj_Member[pobj_c->iMemberNum-1]->TypeInfo.u.pobj_Class->name); } } if(pobj_c->ppobj_Member[pobj_c->iMemberNum-1]->TypeInfo.type==DEF_OBJECT){ //循環参照のチェック pobj_LoopRefCheck->add(pobj_c->name); if(!MemberVar_LoopRefCheck(pobj_c->ppobj_Member[pobj_c->iMemberNum-1]->TypeInfo.u.pobj_Class)){ //エラー回避 pobj_c->ppobj_Member[pobj_c->iMemberNum-1]->TypeInfo.type=DEF_PTR_VOID; } pobj_LoopRefCheck->del(pobj_c->name); } } } else{ //メソッドを追加 cp=i; //エラー用 AddMethod(pobj_c, dwAccess, bStatic, isConst, bAbstract, bVirtual, bOverride, temporary, sub_address); if(bAbstract) continue; for(;;i++){ if(basbuf[i]=='\0'){ i--; break; } if(basbuf[i-1]!='*'&& basbuf[i]==1&&( basbuf[i+1]==ESC_SUB|| basbuf[i+1]==ESC_FUNCTION|| basbuf[i+1]==ESC_MACRO|| basbuf[i+1]==ESC_TYPE|| basbuf[i+1]==ESC_CLASS|| basbuf[i+1]==ESC_INTERFACE|| basbuf[i+1]==ESC_ENUM)){ GetDefaultNameFromES(i3,temporary); SetError(22,temporary,i); } if(basbuf[i]==1&&basbuf[i+1]==GetEndXXXCommand((char)i3)){ i+=2; break; } } } } } } } void CDBClass::GetObjectClassInfo(void){ //ループ継承チェック用のクラス pobj_LoopRefCheck=new CLoopRefCheck(); //クラスを取得 GetClass_recur(0); delete pobj_LoopRefCheck; pobj_LoopRefCheck=0; } void CDBClass::StartCompile( SUBINFO *psi ){ pCompilingClass = psi->pobj_ParentClass; if( pCompilingClass ){ pCompilingMethod = pCompilingClass->GetMethodInfo( psi ); if( !pCompilingMethod ){ pCompilingMethod = pCompilingClass->GetStaticMethodInfo( psi ); if( !pCompilingMethod ){ SetError(300,NULL,cp); } } } else{ pCompilingMethod = NULL; } } CClass *CDBClass::GetNowCompilingClass(){ return pCompilingClass; } CMethod *CDBClass::GetNowCompilingMethodInfo(){ return pCompilingMethod; } ////////////////////// // イテレータ ////////////////////// void CDBClass::Iterator_Reset(void){ if(ppobj_IteClass) HeapDefaultFree(ppobj_IteClass); iIteMaxNum=0; iIteNextNum=0; ppobj_IteClass=(CClass **)HeapAlloc(hHeap,0,1); int i; for(i=0;ipobj_NextClass==0) break; pobj_c=pobj_c->pobj_NextClass; } } } } BOOL CDBClass::Iterator_HasNext(void){ if(iIteNextNum