Moved the _isZeroInit function out from dstruct.d into dsymbolsem.d (#21172)

This commit is contained in:
Nayaab Zameer 2025-04-08 05:04:52 +05:30 committed by GitHub
parent b2926b6b2a
commit a52d7f0e36
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 92 additions and 91 deletions

View file

@ -318,96 +318,6 @@ extern (C++) class StructDeclaration : AggregateDeclaration
}
}
/**********************************
* Determine if exp is all binary zeros.
* Params:
* exp = expression to check
* Returns:
* true if it's all binary 0
*/
bool _isZeroInit(Expression exp)
{
switch (exp.op)
{
case EXP.int64:
return exp.toInteger() == 0;
case EXP.null_:
return true;
case EXP.structLiteral:
{
auto sle = exp.isStructLiteralExp();
if (sle.sd.isNested())
return false;
const isCstruct = sle.sd.isCsymbol(); // C structs are default initialized to all zeros
foreach (i; 0 .. sle.sd.fields.length)
{
auto field = sle.sd.fields[i];
if (field.type.size(field.loc))
{
auto e = sle.elements && i < sle.elements.length ? (*sle.elements)[i] : null;
if (e ? !_isZeroInit(e)
: !isCstruct && !field.type.isZeroInit(field.loc))
return false;
}
}
return true;
}
case EXP.arrayLiteral:
{
auto ale = cast(ArrayLiteralExp)exp;
const dim = ale.elements ? ale.elements.length : 0;
if (ale.type.toBasetype().ty == Tarray) // if initializing a dynamic array
return dim == 0;
foreach (i; 0 .. dim)
{
if (!_isZeroInit(ale[i]))
return false;
}
/* Note that true is returned for all T[0]
*/
return true;
}
case EXP.string_:
{
auto se = cast(StringExp)exp;
if (se.type.toBasetype().ty == Tarray) // if initializing a dynamic array
return se.len == 0;
foreach (i; 0 .. se.len)
{
if (se.getIndex(i) != 0)
return false;
}
return true;
}
case EXP.vector:
{
auto ve = cast(VectorExp) exp;
return _isZeroInit(ve.e1);
}
case EXP.float64:
case EXP.complex80:
{
import dmd.root.ctfloat : CTFloat;
return (exp.toReal() is CTFloat.zero) &&
(exp.toImaginary() is CTFloat.zero);
}
default:
return false;
}
}
/***********************************************************
* Unions are a variation on structs.

View file

@ -8315,6 +8315,97 @@ void finalizeSize(AggregateDeclaration ad)
ad.accept(v);
}
/**********************************
* Determine if exp is all binary zeros.
* Params:
* exp = expression to check
* Returns:
* true if it's all binary 0
*/
bool _isZeroInit(Expression exp)
{
switch (exp.op)
{
case EXP.int64:
return exp.toInteger() == 0;
case EXP.null_:
return true;
case EXP.structLiteral:
{
auto sle = exp.isStructLiteralExp();
if (sle.sd.isNested())
return false;
const isCstruct = sle.sd.isCsymbol(); // C structs are default initialized to all zeros
foreach (i; 0 .. sle.sd.fields.length)
{
auto field = sle.sd.fields[i];
if (field.type.size(field.loc))
{
auto e = sle.elements && i < sle.elements.length ? (*sle.elements)[i] : null;
if (e ? !_isZeroInit(e)
: !isCstruct && !field.type.isZeroInit(field.loc))
return false;
}
}
return true;
}
case EXP.arrayLiteral:
{
auto ale = cast(ArrayLiteralExp)exp;
const dim = ale.elements ? ale.elements.length : 0;
if (ale.type.toBasetype().ty == Tarray) // if initializing a dynamic array
return dim == 0;
foreach (i; 0 .. dim)
{
if (!_isZeroInit(ale[i]))
return false;
}
/* Note that true is returned for all T[0]
*/
return true;
}
case EXP.string_:
{
auto se = cast(StringExp)exp;
if (se.type.toBasetype().ty == Tarray) // if initializing a dynamic array
return se.len == 0;
foreach (i; 0 .. se.len)
{
if (se.getIndex(i) != 0)
return false;
}
return true;
}
case EXP.vector:
{
auto ve = cast(VectorExp) exp;
return _isZeroInit(ve.e1);
}
case EXP.float64:
case EXP.complex80:
{
import dmd.root.ctfloat : CTFloat;
return (exp.toReal() is CTFloat.zero) &&
(exp.toImaginary() is CTFloat.zero);
}
default:
return false;
}
}
private extern(C++) class FinalizeSizeVisitor : Visitor
{
alias visit = Visitor.visit;

View file

@ -37,7 +37,7 @@ import dmd.dmodule;
import dmd.dscope;
import dmd.dstruct;
import dmd.dsymbol;
import dmd.dsymbolsem : include;
import dmd.dsymbolsem : include, _isZeroInit;
import dmd.dtemplate;
import dmd.expression;
import dmd.expressionsem : fill;