Merge branch 'master' of https://github.com/ZDoom/gzdoom
This commit is contained in:
commit
74a27be3fd
114 changed files with 3366 additions and 1677 deletions
|
|
@ -291,23 +291,21 @@ bool AreCompatiblePointerTypes(PType *dest, PType *source, bool forcompare)
|
|||
if (!forcompare && fromtype->IsConst && !totype->IsConst) return false;
|
||||
// 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->isObjectPointer() && dest->isObjectPointer())
|
||||
{
|
||||
{ // Pointers to different types are only compatible if both point to an object and the source type is a child of the destination type.
|
||||
auto fromcls = static_cast<PObjectPointer*>(source)->PointedClass();
|
||||
auto tocls = static_cast<PObjectPointer*>(dest)->PointedClass();
|
||||
if (forcompare && tocls->IsDescendantOf(fromcls)) return true;
|
||||
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->isClassPointer() && dest->isClassPointer())
|
||||
{
|
||||
else if (source->isClassPointer() && dest->isClassPointer())
|
||||
{ // The same rules apply to class pointers. A child type can be assigned to a variable of a parent type.
|
||||
auto fromcls = static_cast<PClassPointer*>(source)->ClassRestriction;
|
||||
auto tocls = static_cast<PClassPointer*>(dest)->ClassRestriction;
|
||||
if (forcompare && tocls->IsDescendantOf(fromcls)) return true;
|
||||
return (fromcls->IsDescendantOf(tocls));
|
||||
}
|
||||
if(source->isFunctionPointer() && dest->isFunctionPointer())
|
||||
else if(source->isFunctionPointer() && dest->isFunctionPointer())
|
||||
{
|
||||
auto from = static_cast<PFunctionPointer*>(source);
|
||||
auto to = static_cast<PFunctionPointer*>(dest);
|
||||
|
|
@ -315,6 +313,10 @@ bool AreCompatiblePointerTypes(PType *dest, PType *source, bool forcompare)
|
|||
|
||||
return to->PointedType == TypeVoid || (AreCompatibleFnPtrTypes((PPrototype *)to->PointedType, (PPrototype *)from->PointedType) && from->ArgFlags == to->ArgFlags && FScopeBarrier::CheckSidesForFunctionPointer(from->Scope, to->Scope));
|
||||
}
|
||||
else if(source->isRealPointer() && dest->isRealPointer())
|
||||
{
|
||||
return fromtype->PointedType == totype->PointedType;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1940,6 +1942,12 @@ FxExpression *FxTypeCast::Resolve(FCompileContext &ctx)
|
|||
{
|
||||
bool writable;
|
||||
basex->RequestAddress(ctx, &writable);
|
||||
|
||||
if(!writable && !ValueType->toPointer()->IsConst && ctx.Version >= MakeVersion(4, 12))
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR, "Trying to assign readonly value to writable type.");
|
||||
}
|
||||
|
||||
basex->ValueType = ValueType;
|
||||
auto x = basex;
|
||||
basex = nullptr;
|
||||
|
|
@ -8739,6 +8747,12 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
|
|||
if (Self->ValueType->isRealPointer())
|
||||
{
|
||||
auto pointedType = Self->ValueType->toPointer()->PointedType;
|
||||
|
||||
if(pointedType && pointedType->isStruct() && Self->ValueType->toPointer()->IsConst && ctx.Version >= MakeVersion(4, 12))
|
||||
{
|
||||
isreadonly = true;
|
||||
}
|
||||
|
||||
if (pointedType && (pointedType->isDynArray() || pointedType->isMap() || pointedType->isMapIterator()))
|
||||
{
|
||||
Self = new FxOutVarDereference(Self, Self->ScriptPosition);
|
||||
|
|
@ -9268,7 +9282,7 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
|
|||
return nullptr;
|
||||
}
|
||||
}
|
||||
else if (Self->ValueType->isStruct())
|
||||
else if (Self->ValueType->isStruct() && !isreadonly)
|
||||
{
|
||||
bool writable;
|
||||
|
||||
|
|
|
|||
|
|
@ -2764,7 +2764,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
|||
// [ZZ] unspecified virtual function inherits old scope. virtual function scope can't be changed.
|
||||
sym->Variants[0].Implementation->VarFlags = sym->Variants[0].Flags;
|
||||
}
|
||||
|
||||
|
||||
bool exactReturnType = mVersion < MakeVersion(4, 4);
|
||||
PClass *clstype = forclass? static_cast<PClassType *>(c->Type())->Descriptor : nullptr;
|
||||
if (varflags & VARF_Virtual)
|
||||
|
|
@ -2785,7 +2785,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
|||
|
||||
auto parentfunc = clstype->ParentClass? dyn_cast<PFunction>(clstype->ParentClass->VMType->Symbols.FindSymbol(sym->SymbolName, true)) : nullptr;
|
||||
|
||||
int virtindex = clstype->FindVirtualIndex(sym->SymbolName, &sym->Variants[0], parentfunc, exactReturnType);
|
||||
int virtindex = clstype->FindVirtualIndex(sym->SymbolName, &sym->Variants[0], parentfunc, exactReturnType, sym->SymbolName == FName("SpecialBounceHit") && mVersion < MakeVersion(4, 12));
|
||||
// specifying 'override' is necessary to prevent one of the biggest problem spots with virtual inheritance: Mismatching argument types.
|
||||
if (varflags & VARF_Override)
|
||||
{
|
||||
|
|
@ -2867,7 +2867,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
|||
}
|
||||
else if (forclass)
|
||||
{
|
||||
int virtindex = clstype->FindVirtualIndex(sym->SymbolName, &sym->Variants[0], nullptr, exactReturnType);
|
||||
int virtindex = clstype->FindVirtualIndex(sym->SymbolName, &sym->Variants[0], nullptr, exactReturnType, sym->SymbolName == FName("SpecialBounceHit") && mVersion < MakeVersion(4, 12));
|
||||
if (virtindex != -1)
|
||||
{
|
||||
Error(f, "Function %s attempts to override parent function without 'override' qualifier", FName(f->Name).GetChars());
|
||||
|
|
|
|||
|
|
@ -71,9 +71,16 @@ static FString ResolveIncludePath(const FString &path,const FString &lumpname){
|
|||
{
|
||||
relativePath = relativePath.Mid(3);
|
||||
auto slash_index = fullPath.LastIndexOf("/");
|
||||
if (slash_index != -1) {
|
||||
if (slash_index != -1)
|
||||
{
|
||||
fullPath = fullPath.Mid(0, slash_index);
|
||||
} else {
|
||||
}
|
||||
else if (fullPath.IsNotEmpty())
|
||||
{
|
||||
fullPath = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
pathOk = false;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue