[206] | 1 | #include "stdafx.h" |
---|
| 2 | |
---|
[52] | 3 | #ifdef _AMD64_ |
---|
[485] | 4 | #include "../compiler_x64/opcode.h" |
---|
[52] | 5 | #else |
---|
[484] | 6 | #include "../compiler_x86/opcode.h" |
---|
[52] | 7 | #endif |
---|
| 8 | |
---|
[78] | 9 | #define OVERLOAD_MIN_LEVEL 0 |
---|
[111] | 10 | #define OVERLOAD_MAX_LEVEL 6 |
---|
[78] | 11 | #define OVERLOAD_LEVEL0 0 // 型調整なし。厳密に等しい |
---|
[90] | 12 | #define OVERLOAD_LEVEL1 1 // 型調整なし。レベル1以上はオブジェクトの場合は派生関係を考慮 |
---|
[111] | 13 | #define OVERLOAD_LEVEL2 2 // 型調整なし。整数型/実数型レベルでの同一性チェック(サイズ照合あり) |
---|
| 14 | #define OVERLOAD_LEVEL3 3 // 型調整なし。整数型/実数型レベルでの同一性チェック |
---|
| 15 | #define OVERLOAD_LEVEL4 4 // 型調整あり。厳密に等しい |
---|
| 16 | #define OVERLOAD_LEVEL5 5 // 型調整あり。整数型/実数型レベルでの同一性チェック |
---|
| 17 | #define OVERLOAD_LEVEL6 6 // 型調整あり。数値型/クラス型レベルでの同一性チェック |
---|
[78] | 18 | |
---|
[75] | 19 | ParamImpl::ParamImpl(const char *buffer): |
---|
| 20 | returnType() |
---|
| 21 | { |
---|
[52] | 22 | /////////////////////////// |
---|
| 23 | // パラメータ文字列を整理 |
---|
| 24 | /////////////////////////// |
---|
| 25 | |
---|
| 26 | extern HANDLE hHeap; |
---|
| 27 | int i,i2,i3; |
---|
| 28 | char temporary[VN_SIZE]; |
---|
| 29 | |
---|
| 30 | i=0; |
---|
| 31 | ParmsNum=0; |
---|
| 32 | while(1){ |
---|
| 33 | if(buffer[i]=='\0') break; |
---|
| 34 | |
---|
| 35 | for(i2=0;;i2++,i++){ |
---|
| 36 | if(buffer[i]=='\"'){ |
---|
| 37 | temporary[i2]=buffer[i]; |
---|
| 38 | for(i++,i2++;;i++,i2++){ |
---|
| 39 | temporary[i2]=buffer[i]; |
---|
[319] | 40 | if( buffer[i] == '\0' ) |
---|
| 41 | { |
---|
[465] | 42 | compiler.errorMessenger.OutputFatalError(); |
---|
[319] | 43 | break; |
---|
| 44 | } |
---|
[52] | 45 | if(buffer[i]=='\"') break; |
---|
| 46 | } |
---|
| 47 | continue; |
---|
| 48 | } |
---|
| 49 | |
---|
| 50 | if(buffer[i]=='('){ |
---|
| 51 | i3=GetStringInPare(temporary+i2,buffer+i); |
---|
| 52 | i2+=i3-1; |
---|
| 53 | i+=i3-1; |
---|
| 54 | continue; |
---|
| 55 | } |
---|
| 56 | if(buffer[i]=='['){ |
---|
| 57 | i3=GetStringInBracket(temporary+i2,buffer+i); |
---|
| 58 | i2+=i3-1; |
---|
| 59 | i+=i3-1; |
---|
| 60 | continue; |
---|
| 61 | } |
---|
| 62 | |
---|
| 63 | if(buffer[i]==','||buffer[i]=='\0'){ |
---|
| 64 | temporary[i2]=0; |
---|
| 65 | break; |
---|
| 66 | } |
---|
| 67 | temporary[i2]=buffer[i]; |
---|
| 68 | } |
---|
| 69 | |
---|
| 70 | Parms[ParmsNum]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1); |
---|
| 71 | lstrcpy(Parms[ParmsNum],temporary); |
---|
| 72 | ParmsNum++; |
---|
| 73 | |
---|
[75] | 74 | types.push_back( Type() ); |
---|
| 75 | |
---|
[52] | 76 | if(buffer[i]==',') i++; |
---|
| 77 | } |
---|
| 78 | } |
---|
[75] | 79 | ParamImpl::ParamImpl(const Parameters ¶ms): |
---|
| 80 | returnType() |
---|
| 81 | { |
---|
| 82 | ParmsNum = 0; |
---|
[182] | 83 | BOOST_FOREACH( Parameter *pParam, params ){ |
---|
[75] | 84 | Parms[ParmsNum]=0; |
---|
| 85 | ParmsNum++; |
---|
[52] | 86 | |
---|
[75] | 87 | types.push_back( *pParam ); |
---|
[73] | 88 | } |
---|
| 89 | } |
---|
[71] | 90 | ParamImpl::~ParamImpl(){ |
---|
[52] | 91 | int i2; |
---|
| 92 | |
---|
| 93 | //パラメータ文字列を解放 |
---|
| 94 | for(i2=0;i2<ParmsNum;i2++){ |
---|
| 95 | if(Parms[i2]==(char *)-1) continue; |
---|
| 96 | |
---|
| 97 | if(Parms[i2]) HeapDefaultFree(Parms[i2]); |
---|
| 98 | } |
---|
| 99 | } |
---|
| 100 | |
---|
[75] | 101 | void ParamImpl::SetReturnType( const Type &returnType ){ |
---|
| 102 | this->returnType = returnType; |
---|
[52] | 103 | } |
---|
| 104 | |
---|
[424] | 105 | bool ParamImpl::EvaluateOverloadScore( int level, const Parameters &targetParms, const Type &targetResultType, const Type &leftType, const UserProc &userProc, bool &isErrored ){ |
---|
[52] | 106 | //パラメータを識別してオーバーロードを解決 |
---|
| 107 | |
---|
[364] | 108 | isErrored = false; |
---|
| 109 | |
---|
[52] | 110 | //パラメータの個数が不一致の場合 |
---|
[75] | 111 | int max = (int)targetParms.size(); |
---|
[77] | 112 | |
---|
| 113 | if( ParmsNum > max ){ |
---|
| 114 | // 実引数が駆り引数より多いとき |
---|
| 115 | // ※無条件で不一致 |
---|
[75] | 116 | return false; |
---|
| 117 | } |
---|
[52] | 118 | |
---|
[73] | 119 | Type argType; |
---|
| 120 | for(int i=0;i<max;i++){ |
---|
[75] | 121 | Parameter ¶m = *targetParms[i]; |
---|
[73] | 122 | |
---|
[424] | 123 | Type paramType( param ); |
---|
| 124 | ResolveFormalGenericTypeParameter( paramType, leftType, &userProc ); |
---|
| 125 | |
---|
[77] | 126 | if( i >= ParmsNum ){ |
---|
| 127 | // 引数が多いとき |
---|
| 128 | if( param.GetInitValue().size() > 0 ){ |
---|
| 129 | // 初期値が指定されているパラメータを考慮 |
---|
| 130 | return true; |
---|
| 131 | } |
---|
| 132 | else{ |
---|
| 133 | return false; |
---|
| 134 | } |
---|
| 135 | } |
---|
| 136 | |
---|
[52] | 137 | if(Parms[i]){ |
---|
[73] | 138 | Type nullParam( DEF_NON ); |
---|
| 139 | |
---|
[364] | 140 | if( !NumOpe_GetType(Parms[i], |
---|
[424] | 141 | ( level <= OVERLOAD_LEVEL3 )? nullParam : paramType, |
---|
[364] | 142 | argType) ) |
---|
| 143 | { |
---|
| 144 | isErrored = true; |
---|
| 145 | return false; |
---|
| 146 | } |
---|
[52] | 147 | } |
---|
| 148 | else{ |
---|
[75] | 149 | argType = types[i]; |
---|
[52] | 150 | } |
---|
| 151 | |
---|
[424] | 152 | if( ( argType.IsObject() && paramType.IsObject() ) || argType.GetBasicType() == paramType.GetBasicType() ) |
---|
| 153 | { |
---|
| 154 | if( argType.IsStruct() ){ |
---|
| 155 | if(argType.GetIndex()!=paramType.GetIndex()){ |
---|
| 156 | return false; |
---|
| 157 | } |
---|
| 158 | } |
---|
| 159 | else if( argType.IsObject() ){ |
---|
| 160 | if( level == OVERLOAD_LEVEL0 ){ |
---|
| 161 | if( !paramType.GetClass().IsEquals( &argType.GetClass() ) ){ |
---|
| 162 | return false; |
---|
| 163 | } |
---|
| 164 | } |
---|
| 165 | else{ |
---|
| 166 | if( !paramType.GetClass().IsEqualsOrSubClass( &argType.GetClass() ) ){ |
---|
| 167 | return false; |
---|
| 168 | } |
---|
| 169 | } |
---|
| 170 | } |
---|
| 171 | } |
---|
| 172 | else |
---|
| 173 | { |
---|
[111] | 174 | if( level == OVERLOAD_LEVEL0 || level == OVERLOAD_LEVEL1 || level==OVERLOAD_LEVEL4 ){ |
---|
[75] | 175 | return false; |
---|
[52] | 176 | } |
---|
[111] | 177 | else if( level == OVERLOAD_LEVEL2 ){ |
---|
[424] | 178 | if( !(argType.IsWhole() && paramType.IsWhole() && argType.GetBasicSize() == paramType.GetBasicSize() ) ){ |
---|
[111] | 179 | // サイズ違い |
---|
| 180 | return false; |
---|
| 181 | } |
---|
| 182 | } |
---|
| 183 | else if( level == OVERLOAD_LEVEL3 || level==OVERLOAD_LEVEL5){ |
---|
[52] | 184 | if(!( |
---|
[424] | 185 | argType.IsWhole()&¶mType.IsWhole()|| |
---|
| 186 | argType.IsReal()&¶mType.IsReal() |
---|
[75] | 187 | )){ |
---|
| 188 | return false; |
---|
| 189 | } |
---|
[424] | 190 | if( argType.IsPointer() || paramType.IsPointer() ) |
---|
[140] | 191 | { |
---|
| 192 | // ポインタ型の不整合は認めない |
---|
| 193 | return false; |
---|
| 194 | } |
---|
[52] | 195 | } |
---|
[111] | 196 | else if(level==OVERLOAD_LEVEL6){ |
---|
[424] | 197 | if(argType.IsObject()||paramType.IsObject()) return false; |
---|
[52] | 198 | } |
---|
| 199 | } |
---|
| 200 | } |
---|
| 201 | |
---|
[75] | 202 | if( !targetResultType.IsNull() ){ |
---|
[52] | 203 | //戻り値も比較対象にする |
---|
[673] | 204 | |
---|
| 205 | Type temp( targetResultType ); |
---|
| 206 | ResolveFormalGenericTypeParameter( temp, leftType, &userProc ); |
---|
| 207 | |
---|
| 208 | if( !returnType.Equals( temp ) ){ |
---|
[75] | 209 | return false; |
---|
[52] | 210 | } |
---|
| 211 | } |
---|
| 212 | |
---|
[75] | 213 | return true; |
---|
[52] | 214 | } |
---|
| 215 | |
---|
[424] | 216 | const UserProc *ParamImpl::_OverloadSolution( const char *name, std::vector<const UserProc *> &subs, const Type &leftType, bool isEnabledReturnType ){ |
---|
[353] | 217 | const UserProc *pUserProc = NULL; |
---|
[52] | 218 | |
---|
[364] | 219 | for( int level=OVERLOAD_MIN_LEVEL; level<=OVERLOAD_MAX_LEVEL; level++ ) |
---|
| 220 | { |
---|
| 221 | BOOST_FOREACH( const UserProc *pTempUserProc, subs ) |
---|
| 222 | { |
---|
| 223 | bool isErrored = false; |
---|
| 224 | bool isHit = false; |
---|
[424] | 225 | isHit = EvaluateOverloadScore( level, pTempUserProc->Params(), isEnabledReturnType?pTempUserProc->ReturnType():Type(), leftType, *pTempUserProc, isErrored ); |
---|
[364] | 226 | if( isErrored ) |
---|
| 227 | { |
---|
| 228 | // 照合中にエラーが起きた場合 |
---|
| 229 | return NULL; |
---|
| 230 | } |
---|
[140] | 231 | |
---|
[364] | 232 | if( isHit ) |
---|
| 233 | { |
---|
[353] | 234 | trace_for_overload( "レベル" << level << " ○適合..." << pTempUserProc->_paramStr ); |
---|
[140] | 235 | |
---|
[353] | 236 | if( pUserProc ){ |
---|
[140] | 237 | if( isEnabledReturnType ){ |
---|
[465] | 238 | compiler.errorMessenger.Output(52,name,cp); |
---|
[364] | 239 | return NULL; |
---|
[140] | 240 | } |
---|
| 241 | else{ |
---|
| 242 | // 戻り値も比較するモードにして再びオーバーロード解決を試みる |
---|
[52] | 243 | |
---|
[167] | 244 | trace_for_overload( "戻り値も比較するモードに切り替えてオーバーロード解決を試みる" ); |
---|
[52] | 245 | |
---|
[424] | 246 | return OverloadSolution( name, subs, leftType, true); |
---|
[140] | 247 | } |
---|
[52] | 248 | } |
---|
[64] | 249 | |
---|
[75] | 250 | pUserProc = pTempUserProc; |
---|
[52] | 251 | } |
---|
[140] | 252 | else |
---|
| 253 | { |
---|
[353] | 254 | trace_for_overload( "レベル" << level << " ×不適合..." << pTempUserProc->_paramStr ); |
---|
[140] | 255 | } |
---|
[52] | 256 | } |
---|
| 257 | |
---|
[353] | 258 | if( pUserProc ) break; |
---|
[52] | 259 | } |
---|
| 260 | |
---|
[353] | 261 | if( !pUserProc ){ |
---|
[364] | 262 | BOOST_FOREACH( const UserProc *pTempUserProc, subs ) |
---|
| 263 | { |
---|
[52] | 264 | //エラーチェック |
---|
[364] | 265 | if(pTempUserProc->Params().size()==this->ParmsNum) |
---|
| 266 | { |
---|
| 267 | if( pUserProc ) |
---|
| 268 | { |
---|
[465] | 269 | compiler.errorMessenger.Output(52,name,cp); |
---|
[364] | 270 | return NULL; |
---|
[52] | 271 | } |
---|
| 272 | |
---|
[75] | 273 | pUserProc=pTempUserProc; |
---|
[52] | 274 | } |
---|
| 275 | } |
---|
| 276 | } |
---|
| 277 | |
---|
[353] | 278 | if( !pUserProc ) |
---|
| 279 | { |
---|
[465] | 280 | compiler.errorMessenger.OutputFatalError(); |
---|
[52] | 281 | } |
---|
| 282 | |
---|
[75] | 283 | return pUserProc; |
---|
[52] | 284 | } |
---|
[424] | 285 | const UserProc *ParamImpl::OverloadSolution( const char *name, std::vector<const UserProc *> &subs, const Type &leftType, bool isEnabledReturnType ){ |
---|
[167] | 286 | trace_for_overload( "" ); |
---|
| 287 | trace_for_overload( "■■■■■■■■■■■■■■■■■■" ); |
---|
| 288 | trace_for_overload( "■■■ オーバーロード解決(" << name << ")" ); |
---|
[52] | 289 | |
---|
[424] | 290 | const UserProc *result = _OverloadSolution( name, subs, leftType, isEnabledReturnType ); |
---|
[140] | 291 | |
---|
[167] | 292 | trace_for_overload( "■■■ ここまで" ); |
---|
| 293 | trace_for_overload( "■■■■■■■■■■■■■■■■■■" ); |
---|
| 294 | trace_for_overload( "" ); |
---|
[140] | 295 | |
---|
| 296 | return result; |
---|
| 297 | } |
---|
| 298 | |
---|
[77] | 299 | void ParamImpl::ApplyDefaultParameters( const Parameters ¶ms ){ |
---|
| 300 | if( ParmsNum == (int)params.size() ){ |
---|
| 301 | // デフォルト引数の適用が不必要なとき |
---|
| 302 | return; |
---|
| 303 | } |
---|
| 304 | |
---|
| 305 | while( ParmsNum < (int)params.size() ){ |
---|
| 306 | Parameter ¶m = *params[ParmsNum]; |
---|
| 307 | |
---|
| 308 | Parms[ParmsNum]=(char *)HeapAlloc(hHeap,0,param.GetInitValue().size() + 1 ); |
---|
| 309 | lstrcpy(Parms[ParmsNum],param.GetInitValue().c_str() ); |
---|
| 310 | ParmsNum++; |
---|
| 311 | } |
---|
| 312 | } |
---|
| 313 | |
---|
[523] | 314 | bool ParamImpl::ErrorCheck( const std::string &procName, const Parameters ¶ms, int SecondParmNum ){ |
---|
[75] | 315 | if( SecondParmNum == -1 ) SecondParmNum = (int)params.size(); |
---|
[52] | 316 | |
---|
[284] | 317 | if(ParmsNum>(int)params.size()){ |
---|
| 318 | if( params.size() == 0 || params[params.size()-1]->GetBasicType()!=DEF_ELLIPSE ){ |
---|
[73] | 319 | //パラメータが多すぎるとき |
---|
[465] | 320 | compiler.errorMessenger.Output(10,procName,cp); |
---|
[73] | 321 | return false; |
---|
| 322 | } |
---|
| 323 | } |
---|
| 324 | else if(ParmsNum<(int)params.size()){ |
---|
| 325 | if(ParmsNum<SecondParmNum){ |
---|
| 326 | if(params[ParmsNum]->GetBasicType()==DEF_ELLIPSE){ |
---|
| 327 | return true; |
---|
| 328 | } |
---|
[52] | 329 | |
---|
[73] | 330 | //パラメータが少なすぎるとき |
---|
[465] | 331 | compiler.errorMessenger.Output(10,procName,cp); |
---|
[73] | 332 | return false; |
---|
| 333 | } |
---|
| 334 | |
---|
| 335 | //省略パラメータに "0" を指定する |
---|
| 336 | for(;ParmsNum < (int)params.size();ParmsNum++){ |
---|
| 337 | extern HANDLE hHeap; |
---|
| 338 | char temporary[64]; |
---|
| 339 | if(params[ParmsNum]->IsRef() == false) lstrcpy(temporary,"0"); |
---|
| 340 | else sprintf(temporary,"%c%c0",1,ESC_BYVAL); |
---|
| 341 | Parms[ParmsNum]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1); |
---|
| 342 | lstrcpy(Parms[ParmsNum],temporary); |
---|
| 343 | } |
---|
| 344 | } |
---|
| 345 | |
---|
| 346 | return true; |
---|
| 347 | } |
---|
| 348 | |
---|
| 349 | void ParamImpl::MacroParameterSupport( const Parameters ¶ms ){ |
---|
| 350 | for(int i=0;i<ParmsNum;i++){ |
---|
| 351 | if(Parms[i][0]=='\0'){ |
---|
| 352 | extern HANDLE hHeap; |
---|
| 353 | char temporary[64]; |
---|
| 354 | if( params[i]->IsRef() == false ) lstrcpy(temporary,"0"); |
---|
| 355 | else sprintf(temporary,"%c%c0",1,ESC_BYVAL); |
---|
| 356 | HeapDefaultFree(Parms[i]); |
---|
| 357 | Parms[i]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1); |
---|
| 358 | lstrcpy(Parms[i],temporary); |
---|
| 359 | } |
---|
| 360 | } |
---|
| 361 | } |
---|