- removed all RTTI checks for the types.

This commit is contained in:
Christoph Oelckers 2017-04-13 15:13:14 +02:00
parent b2d944974e
commit aeb455d705
11 changed files with 133 additions and 100 deletions

View file

@ -219,7 +219,7 @@ static PClass *FindClassType(FName name, FCompileContext &ctx)
if (sym && sym->IsKindOf(RUNTIME_CLASS(PSymbolType)))
{
auto type = static_cast<PSymbolType*>(sym);
auto ctype = dyn_cast<PClassType>(type->Type);
auto ctype = PType::toClass(type->Type);
if (ctype) return ctype->Descriptor;
}
return nullptr;
@ -227,7 +227,7 @@ static PClass *FindClassType(FName name, FCompileContext &ctx)
bool isActor(PContainerType *type)
{
auto cls = dyn_cast<PClassType>(type);
auto cls = PType::toClass(type);
return cls ? cls->Descriptor->IsDescendantOf(RUNTIME_CLASS(AActor)) : false;
}
@ -303,7 +303,7 @@ static bool AreCompatiblePointerTypes(PType *dest, PType *source, bool forcompar
// A type is always compatible to itself.
if (fromtype == totype) return true;
// Pointers to different types are only compatible if both point to an object and the source type is a child of the destination type.
if (source->IsA(RUNTIME_CLASS(PObjectPointer)) && dest->IsA(RUNTIME_CLASS(PObjectPointer)))
if (source->isObjectPointer() && dest->isObjectPointer())
{
auto fromcls = static_cast<PObjectPointer*>(source)->PointedClass();
auto tocls = static_cast<PObjectPointer*>(dest)->PointedClass();
@ -311,7 +311,7 @@ static bool AreCompatiblePointerTypes(PType *dest, PType *source, bool forcompar
return (fromcls->IsDescendantOf(tocls));
}
// The same rules apply to class pointers. A child type can be assigned to a variable of a parent type.
if (source->IsA(RUNTIME_CLASS(PClassPointer)) && dest->IsA(RUNTIME_CLASS(PClassPointer)))
if (source->isClassPointer() && dest->isClassPointer())
{
auto fromcls = static_cast<PClassPointer*>(source)->ClassRestriction;
auto tocls = static_cast<PClassPointer*>(dest)->ClassRestriction;
@ -1158,7 +1158,7 @@ FxExpression *FxNameCast::Resolve(FCompileContext &ctx)
CHECKRESOLVED();
SAFE_RESOLVE(basex, ctx);
if (mExplicit && basex->ValueType->IsKindOf(RUNTIME_CLASS(PClassPointer)))
if (mExplicit && basex->ValueType->isClassPointer())
{
if (basex->isConstant())
{
@ -1750,7 +1750,7 @@ FxExpression *FxTypeCast::Resolve(FCompileContext &ctx)
}
}
}
else if (ValueType->IsKindOf(RUNTIME_CLASS(PClassPointer)))
else if (ValueType->isClassPointer())
{
FxExpression *x = new FxClassTypeCast(static_cast<PClassPointer*>(ValueType), basex, Explicit);
x = x->Resolve(ctx);
@ -1758,14 +1758,14 @@ FxExpression *FxTypeCast::Resolve(FCompileContext &ctx)
delete this;
return x;
}
/* else if (ValueType->IsKindOf(RUNTIME_CLASS(PEnum)))
/* else if (ValueType->isEnum())
{
// this is not yet ready and does not get assigned to actual values.
}
*/
else if (ValueType->IsKindOf(RUNTIME_CLASS(PClassType))) // this should never happen because the VM doesn't handle plain class types - just pointers
else if (ValueType->isClass()) // this should never happen because the VM doesn't handle plain class types - just pointers
{
if (basex->ValueType->IsKindOf(RUNTIME_CLASS(PClassType)))
if (basex->ValueType->isClass())
{
// class types are only compatible if the base type is a descendant of the result type.
auto fromtype = static_cast<PClassType *>(basex->ValueType)->Descriptor;
@ -2480,13 +2480,13 @@ FxExpression *FxAssign::Resolve(FCompileContext &ctx)
}
else if (Base->ValueType == Right->ValueType)
{
if (Base->ValueType->IsKindOf(RUNTIME_CLASS(PArray)))
if (Base->ValueType->isArray())
{
ScriptPosition.Message(MSG_ERROR, "Cannot assign arrays");
delete this;
return nullptr;
}
if (!Base->IsVector() && Base->ValueType->IsKindOf(RUNTIME_CLASS(PStruct)))
if (!Base->IsVector() && Base->ValueType->isStruct())
{
ScriptPosition.Message(MSG_ERROR, "Struct assignment not implemented yet");
delete this;
@ -3611,7 +3611,7 @@ FxExpression *FxCompareEq::Resolve(FCompileContext& ctx)
// Special cases: Compare strings and names with names, sounds, colors, state labels and class types.
// These are all types a string can be implicitly cast into, so for convenience, so they should when doing a comparison.
if ((left->ValueType == TypeString || left->ValueType == TypeName) &&
(right->ValueType == TypeName || right->ValueType == TypeSound || right->ValueType == TypeColor || right->ValueType->IsKindOf(RUNTIME_CLASS(PClassPointer)) || right->ValueType == TypeStateLabel))
(right->ValueType == TypeName || right->ValueType == TypeSound || right->ValueType == TypeColor || right->ValueType->isClassPointer() || right->ValueType == TypeStateLabel))
{
left = new FxTypeCast(left, right->ValueType, false, true);
left = left->Resolve(ctx);
@ -3619,7 +3619,7 @@ FxExpression *FxCompareEq::Resolve(FCompileContext& ctx)
ValueType = right->ValueType;
}
else if ((right->ValueType == TypeString || right->ValueType == TypeName) &&
(left->ValueType == TypeName || left->ValueType == TypeSound || left->ValueType == TypeColor || left->ValueType->IsKindOf(RUNTIME_CLASS(PClassPointer)) || left->ValueType == TypeStateLabel))
(left->ValueType == TypeName || left->ValueType == TypeSound || left->ValueType == TypeColor || left->ValueType->isClassPointer() || left->ValueType == TypeStateLabel))
{
right = new FxTypeCast(right, left->ValueType, false, true);
right = right->Resolve(ctx);
@ -4596,7 +4596,7 @@ FxExpression *FxTypeCheck::Resolve(FCompileContext& ctx)
RESOLVE(right, ctx);
ABORT(right && left);
if (left->ValueType->IsKindOf(RUNTIME_CLASS(PClassPointer)))
if (left->ValueType->isClassPointer())
{
left = new FxClassTypeCast(NewClassPointer(RUNTIME_CLASS(DObject)), left, false);
ClassCheck = true;
@ -5140,7 +5140,7 @@ FxExpression *FxNew::Resolve(FCompileContext &ctx)
SAFE_RESOLVE(val, ctx);
CallingFunction = ctx.Function;
if (!val->ValueType->IsKindOf(RUNTIME_CLASS(PClassPointer)))
if (!val->ValueType->isClassPointer())
{
ScriptPosition.Message(MSG_ERROR, "Class type expected");
delete this;
@ -6126,7 +6126,7 @@ FxExpression *FxIdentifier::ResolveMember(FCompileContext &ctx, PContainerType *
{
PSymbol *sym;
PSymbolTable *symtbl;
bool isclass = objtype->IsKindOf(RUNTIME_CLASS(PClassType));
bool isclass = objtype->isClass();
if (Identifier == NAME_Default)
{
@ -6180,8 +6180,8 @@ FxExpression *FxIdentifier::ResolveMember(FCompileContext &ctx, PContainerType *
object = nullptr;
return nullptr;
}
auto cls_ctx = dyn_cast<PClassType>(classctx);
auto cls_target = dyn_cast<PClassType>(objtype);
auto cls_ctx = PType::toClass(classctx);
auto cls_target = PType::toClass(objtype);
// [ZZ] neither PSymbol, PField or PSymbolTable have the necessary information. so we need to do the more complex check here.
if (vsym->Flags & VARF_Protected)
{
@ -6403,7 +6403,7 @@ FxExpression *FxMemberIdentifier::Resolve(FCompileContext& ctx)
return ret;
}
}
else if (Object->ValueType->IsKindOf(RUNTIME_CLASS(PStruct)))
else if (Object->ValueType->isStruct())
{
auto ret = ResolveMember(ctx, ctx.Class, Object, static_cast<PStruct *>(Object->ValueType));
delete this;
@ -6972,7 +6972,7 @@ FxExpression *FxStructMember::Resolve(FCompileContext &ctx)
if (membervar->SymbolName == NAME_Default)
{
if (!classx->ValueType->IsKindOf(RUNTIME_CLASS(PObjectPointer))
if (!classx->ValueType->isObjectPointer()
|| !static_cast<PObjectPointer *>(classx->ValueType)->PointedClass()->IsDescendantOf(RUNTIME_CLASS(AActor)))
{
ScriptPosition.Message(MSG_ERROR, "'Default' requires an actor type");
@ -7028,7 +7028,7 @@ FxExpression *FxStructMember::Resolve(FCompileContext &ctx)
return nullptr;
}
}
else if (classx->ValueType->IsKindOf(RUNTIME_CLASS(PStruct)))
else if (classx->ValueType->isStruct())
{
// if this is a struct within a class or another struct we can simplify the expression by creating a new PField with a cumulative offset.
if (classx->ExprType == EFX_ClassMember || classx->ExprType == EFX_StructMember || classx->ExprType == EFX_GlobalVariable || classx->ExprType == EFX_StackVariable)
@ -7237,12 +7237,11 @@ FxExpression *FxArrayElement::Resolve(FCompileContext &ctx)
}
else
{
arraytype = dyn_cast<PArray>(Array->ValueType);
if (arraytype == nullptr)
if (!Array->ValueType->isArray())
{
// Check if we got a pointer to an array. Some native data structures (like the line list in sectors) use this.
PPointer *ptype = Array->ValueType->toPointer();
if (ptype == nullptr || !ptype->PointedType->IsKindOf(RUNTIME_CLASS(PArray)))
if (ptype == nullptr || !ptype->PointedType->isArray())
{
ScriptPosition.Message(MSG_ERROR, "'[]' can only be used with arrays.");
delete this;
@ -7251,10 +7250,14 @@ FxExpression *FxArrayElement::Resolve(FCompileContext &ctx)
arraytype = static_cast<PArray*>(ptype->PointedType);
arrayispointer = true;
}
else
{
arraytype = static_cast<PArray*>(Array->ValueType);
}
elementtype = arraytype->ElementType;
}
if (Array->IsResizableArray())
if (Array->isStaticArray())
{
// if this is an array within a class or another struct we can simplify the expression by creating a new PField with a cumulative offset.
if (Array->ExprType == EFX_ClassMember || Array->ExprType == EFX_StructMember || Array->ExprType == EFX_GlobalVariable || Array->ExprType == EFX_StackVariable)
@ -7498,8 +7501,8 @@ static bool CheckFunctionCompatiblity(FScriptPosition &ScriptPosition, PFunction
bool match = (callingself == calledself);
if (!match)
{
auto callingselfcls = dyn_cast<PClassType>(caller->Variants[0].SelfClass);
auto calledselfcls = dyn_cast<PClassType>(callee->Variants[0].SelfClass);
auto callingselfcls = PType::toClass(caller->Variants[0].SelfClass);
auto calledselfcls = PType::toClass(callee->Variants[0].SelfClass);
match = callingselfcls != nullptr && calledselfcls != nullptr && callingselfcls->Descriptor->IsDescendantOf(calledselfcls->Descriptor);
}
@ -7860,7 +7863,7 @@ FxExpression *FxFunctionCall::Resolve(FCompileContext& ctx)
if (CheckArgSize(MethodName, ArgList, 0, 1, ScriptPosition))
{
// [ZZ] allow implicit new() call to mean "create current class instance"
if (!ArgList.Size() && !ctx.Class->IsKindOf(RUNTIME_CLASS(PClassType)))
if (!ArgList.Size() && !ctx.Class->isClass())
{
ScriptPosition.Message(MSG_ERROR, "Cannot use implicit new() in a struct");
delete this;
@ -7969,7 +7972,7 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
{
cls = ccls;
staticonly = true;
if (ccls->IsKindOf(RUNTIME_CLASS(PClassType)))
if (ccls->isClass())
{
if (ctx.Function == nullptr)
{
@ -7977,7 +7980,7 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
delete this;
return nullptr;
}
auto clstype = dyn_cast<PClassType>(ctx.Function->Variants[0].SelfClass);
auto clstype = PType::toClass(ctx.Function->Variants[0].SelfClass);
if (clstype != nullptr)
{
novirtual = clstype->Descriptor->IsDescendantOf(static_cast<PClassType*>(ccls)->Descriptor);
@ -8009,7 +8012,7 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
delete this;
return nullptr;
}
auto clstype = dyn_cast<PClassType>(ctx.Function->Variants[0].SelfClass);
auto clstype = PType::toClass(ctx.Function->Variants[0].SelfClass);
if (clstype != nullptr)
{
// give the node the proper value type now that we know it's properly used.
@ -8175,7 +8178,7 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
delete this;
return nullptr;
}
if (!Self->IsResizableArray())
if (!Self->isStaticArray())
{
auto atype = Self->ValueType;
if (Self->ValueType->isPointer()) atype = ValueType->toPointer()->PointedType;
@ -8210,7 +8213,7 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
if (MethodName == NAME_GetParentClass &&
(Self->IsObject() || Self->ValueType->IsKindOf(RUNTIME_CLASS(PClassPointer))))
(Self->IsObject() || Self->ValueType->isClassPointer()))
{
if (ArgList.Size() > 0)
{
@ -8228,7 +8231,7 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
cls = ptype->toContainer();
if (cls != nullptr)
{
if (ptype->IsKindOf(RUNTIME_CLASS(PClassType)) && MethodName == NAME_GetClass)
if (ptype->isClass() && MethodName == NAME_GetClass)
{
if (ArgList.Size() > 0)
{
@ -8247,7 +8250,7 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
return nullptr;
}
}
else if (Self->ValueType->IsKindOf(RUNTIME_CLASS(PStruct)))
else if (Self->ValueType->isStruct())
{
bool writable;
@ -8328,8 +8331,8 @@ isresolved:
{
if (!novirtual || !(afd->Variants[0].Flags & VARF_Virtual))
{
auto clstype = dyn_cast<PClassType>(ctx.Class);
auto ccls = dyn_cast<PClassType>(cls);
auto clstype = PType::toClass(ctx.Class);
auto ccls = PType::toClass(cls);
if (clstype == nullptr || ccls == nullptr || !clstype->Descriptor->IsDescendantOf(ccls->Descriptor))
{
ScriptPosition.Message(MSG_ERROR, "Cannot call non-static function %s::%s from here", cls->TypeName.GetChars(), MethodName.GetChars());
@ -8820,7 +8823,7 @@ FxExpression *FxVMFunctionCall::Resolve(FCompileContext& ctx)
ArgList[i] = ArgList[i]->Resolve(ctx); // nust be resolved before the address is requested.
if (ArgList[i] != nullptr && ArgList[i]->ValueType != TypeNullPtr)
{
if (type == ArgList[i]->ValueType && type->isRealPointer() && type->toPointer()->PointedType->IsA(RUNTIME_CLASS(PStruct)))
if (type == ArgList[i]->ValueType && type->isRealPointer() && type->toPointer()->PointedType->isStruct())
{
// trying to pass a struct reference as a struct reference. This must preserve the type.
}
@ -9331,7 +9334,7 @@ FxExpression *FxGetParentClass::Resolve(FCompileContext &ctx)
{
SAFE_RESOLVE(Self, ctx);
if (!Self->ValueType->IsKindOf(RUNTIME_CLASS(PClassPointer)) && !Self->IsObject())
if (!Self->ValueType->isClassPointer() && !Self->IsObject())
{
ScriptPosition.Message(MSG_ERROR, "GetClass() requires an object");
delete this;
@ -9402,7 +9405,7 @@ FxExpression *FxGetDefaultByType::Resolve(FCompileContext &ctx)
}
else
{
auto cp = dyn_cast<PClassPointer>(Self->ValueType);
auto cp = PType::toClassPointer(Self->ValueType);
if (cp == nullptr || !cp->ClassRestriction->IsDescendantOf(RUNTIME_CLASS(AActor)))
{
ScriptPosition.Message(MSG_ERROR, "GetDefaultByType() requires an actor class type");
@ -10601,7 +10604,7 @@ FxExpression *FxClassTypeCast::Resolve(FCompileContext &ctx)
return x;
}
auto to = static_cast<PClassPointer *>(ValueType);
if (basex->ValueType->GetClass() == RUNTIME_CLASS(PClassPointer))
if (basex->ValueType->isClassPointer())
{
auto from = static_cast<PClassPointer *>(basex->ValueType);
if (from->ClassRestriction->IsDescendantOf(to->ClassRestriction))
@ -10769,7 +10772,7 @@ FxExpression *FxClassPtrCast::Resolve(FCompileContext &ctx)
return x;
}
auto to = static_cast<PClassPointer *>(ValueType);
if (basex->ValueType->GetClass() == RUNTIME_CLASS(PClassPointer))
if (basex->ValueType->isClassPointer())
{
auto from = static_cast<PClassPointer *>(basex->ValueType);
// Downcast is always ok.
@ -10846,7 +10849,7 @@ FxExpression *FxStateByIndex::Resolve(FCompileContext &ctx)
{
CHECKRESOLVED();
ABORT(ctx.Class);
auto vclass = dyn_cast<PClassType>(ctx.Class);
auto vclass = PType::toClass(ctx.Class);
assert(vclass != nullptr);
auto aclass = ValidateActor(vclass->Descriptor);
@ -10925,7 +10928,7 @@ FxExpression *FxRuntimeStateIndex::Resolve(FCompileContext &ctx)
SAFE_RESOLVE(Index, ctx);
}
auto vclass = dyn_cast<PClassType>(ctx.Class);
auto vclass = PType::toClass(ctx.Class);
assert(vclass != nullptr);
auto aclass = ValidateActor(vclass->Descriptor);
assert(aclass != nullptr && aclass->GetStateCount() > 0);
@ -10985,7 +10988,7 @@ FxExpression *FxMultiNameState::Resolve(FCompileContext &ctx)
ABORT(ctx.Class);
int symlabel;
auto vclass = dyn_cast<PClassType>(ctx.Class);
auto vclass = PType::toClass(ctx.Class);
assert(vclass != nullptr);
auto clstype = ValidateActor(vclass->Descriptor);
@ -11201,7 +11204,7 @@ ExpEmit FxLocalVariableDeclaration::Emit(VMFunctionBuilder *build)
else
{
// Init arrays and structs.
if (ValueType->IsA(RUNTIME_CLASS(PStruct)))
if (ValueType->isStruct())
{
auto pstr = static_cast<PStruct*>(ValueType);
if (pstr->mConstructor != nullptr)
@ -11227,7 +11230,7 @@ void FxLocalVariableDeclaration::Release(VMFunctionBuilder *build)
}
else
{
if (ValueType->IsA(RUNTIME_CLASS(PStruct)))
if (ValueType->isStruct())
{
auto pstr = static_cast<PStruct*>(ValueType);
if (pstr->mDestructor != nullptr)