============ idCompiler::LookupDef ============ */
| 1185 | ============ |
| 1186 | */ |
| 1187 | idVarDef *idCompiler::LookupDef( const char *name, const idVarDef *baseobj ) { |
| 1188 | idVarDef *def; |
| 1189 | idVarDef *field; |
| 1190 | etype_t type_b; |
| 1191 | etype_t type_c; |
| 1192 | const opcode_t *op; |
| 1193 | |
| 1194 | // check if we're accessing a field |
| 1195 | if ( baseobj && ( baseobj->Type() == ev_object ) ) { |
| 1196 | const idVarDef *tdef; |
| 1197 | |
| 1198 | def = NULL; |
| 1199 | for( tdef = baseobj; tdef != &def_object; tdef = tdef->TypeDef()->SuperClass()->def ) { |
| 1200 | def = gameLocal.program.GetDef( NULL, name, tdef ); |
| 1201 | if ( def ) { |
| 1202 | break; |
| 1203 | } |
| 1204 | } |
| 1205 | } else { |
| 1206 | // first look through the defs in our scope |
| 1207 | def = gameLocal.program.GetDef( NULL, name, scope ); |
| 1208 | if ( !def ) { |
| 1209 | // if we're in a member function, check types local to the object |
| 1210 | if ( ( scope->Type() != ev_namespace ) && ( scope->scope->Type() == ev_object ) ) { |
| 1211 | // get the local object pointer |
| 1212 | idVarDef *thisdef = gameLocal.program.GetDef( scope->scope->TypeDef(), "self", scope ); |
| 1213 | |
| 1214 | field = LookupDef( name, scope->scope->TypeDef()->def ); |
| 1215 | if ( !field ) { |
| 1216 | Error( "Unknown value \"%s\"", name ); |
| 1217 | } |
| 1218 | |
| 1219 | // type check |
| 1220 | type_b = field->Type(); |
| 1221 | if ( field->Type() == ev_function ) { |
| 1222 | type_c = field->TypeDef()->ReturnType()->Type(); |
| 1223 | } else { |
| 1224 | type_c = field->TypeDef()->FieldType()->Type(); // field access gets type from field |
| 1225 | if ( CheckToken( "++" ) ) { |
| 1226 | if ( type_c != ev_float ) { |
| 1227 | Error( "Invalid type for ++" ); |
| 1228 | } |
| 1229 | def = EmitOpcode( OP_UINCP_F, thisdef, field ); |
| 1230 | return def; |
| 1231 | } else if ( CheckToken( "--" ) ) { |
| 1232 | if ( type_c != ev_float ) { |
| 1233 | Error( "Invalid type for --" ); |
| 1234 | } |
| 1235 | def = EmitOpcode( OP_UDECP_F, thisdef, field ); |
| 1236 | return def; |
| 1237 | } |
| 1238 | } |
| 1239 | |
| 1240 | op = &opcodes[ OP_INDIRECT_F ]; |
| 1241 | while( ( op->type_a->Type() != ev_object ) |
| 1242 | || ( type_b != op->type_b->Type() ) || ( type_c != op->type_c->Type() ) ) { |
| 1243 | if ( ( op->priority == FUNCTION_PRIORITY ) && ( op->type_a->Type() == ev_object ) && ( op->type_c->Type() == ev_void ) && |
| 1244 | ( type_c != op->type_c->Type() ) ) { |
nothing calls this directly
no test coverage detected