mirror of
https://github.com/dlang/dmd.git
synced 2025-04-25 20:50:41 +03:00
Moved the _isZeroInit function out from dstruct.d into dsymbolsem.d (#21172)
This commit is contained in:
parent
b2926b6b2a
commit
a52d7f0e36
3 changed files with 92 additions and 91 deletions
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue