mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 13:10:12 +03:00
Check array types with new isStaticOrDynamicArray
function (#20795)
* Check array types with new `isStaticOrDynamicArray` function * Make isStaticOrDynamicArray extern (D)
This commit is contained in:
parent
84c7b040b0
commit
acaa88abee
16 changed files with 84 additions and 91 deletions
|
@ -38,7 +38,7 @@ TypeTuple toArgTypes_aarch64(Type t)
|
|||
return null;
|
||||
|
||||
Type tb = t.toBasetype();
|
||||
const isAggregate = tb.ty == Tstruct || tb.ty == Tsarray || tb.ty == Tarray || tb.ty == Tdelegate || tb.isComplex();
|
||||
const isAggregate = tb.ty == Tstruct || tb.isStaticOrDynamicArray() || tb.ty == Tdelegate || tb.isComplex();
|
||||
if (!isAggregate)
|
||||
return new TypeTuple(t);
|
||||
|
||||
|
|
|
@ -44,12 +44,12 @@ bool isArrayOpValid(Expression e)
|
|||
if (e.op == EXP.arrayLiteral)
|
||||
{
|
||||
Type t = e.type.toBasetype();
|
||||
while (t.ty == Tarray || t.ty == Tsarray)
|
||||
while (t.isStaticOrDynamicArray())
|
||||
t = t.nextOf().toBasetype();
|
||||
return (t.ty != Tvoid);
|
||||
}
|
||||
Type tb = e.type.toBasetype();
|
||||
if (tb.ty == Tarray || tb.ty == Tsarray)
|
||||
if (tb.isStaticOrDynamicArray())
|
||||
{
|
||||
if (isUnaArrayOp(e.op))
|
||||
{
|
||||
|
@ -80,7 +80,7 @@ bool isNonAssignmentArrayOp(Expression e)
|
|||
return isNonAssignmentArrayOp(e.isSliceExp().e1);
|
||||
|
||||
Type tb = e.type.toBasetype();
|
||||
if (tb.ty == Tarray || tb.ty == Tsarray)
|
||||
if (tb.isStaticOrDynamicArray())
|
||||
{
|
||||
return (isUnaArrayOp(e.op) || isBinArrayOp(e.op));
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ Expression arrayOp(BinExp e, Scope* sc)
|
|||
{
|
||||
//printf("BinExp.arrayOp() %s\n", e.toChars());
|
||||
Type tb = e.type.toBasetype();
|
||||
assert(tb.ty == Tarray || tb.ty == Tsarray);
|
||||
assert(tb.isStaticOrDynamicArray());
|
||||
Type tbn = tb.nextOf().toBasetype();
|
||||
if (tbn.ty == Tvoid)
|
||||
{
|
||||
|
@ -346,7 +346,7 @@ bool isArrayOpOperand(Expression e)
|
|||
if (e.op == EXP.arrayLiteral)
|
||||
{
|
||||
Type t = e.type.toBasetype();
|
||||
while (t.ty == Tarray || t.ty == Tsarray)
|
||||
while (t.isStaticOrDynamicArray())
|
||||
t = t.nextOf().toBasetype();
|
||||
return (t.ty != Tvoid);
|
||||
}
|
||||
|
|
|
@ -2990,7 +2990,7 @@ final class CParser(AST) : Parser!AST
|
|||
if (isStatic || mod)
|
||||
error("static or type qualifier used outside of function prototype");
|
||||
}
|
||||
if (ts.isTypeSArray() || ts.isTypeDArray())
|
||||
if (ts.isStaticOrDynamicArray())
|
||||
{
|
||||
/* C11 6.7.6.2-1: type qualifiers and 'static' shall only appear
|
||||
* in the outermost array type derivation.
|
||||
|
|
|
@ -688,7 +688,7 @@ Expression getAggregateFromPointer(Expression e, dinteger_t* ofs)
|
|||
if (auto ie = e.isIndexExp())
|
||||
{
|
||||
// Note that each AA element is part of its own memory block
|
||||
if ((ie.e1.type.ty == Tarray || ie.e1.type.ty == Tsarray || ie.e1.op == EXP.string_ || ie.e1.op == EXP.arrayLiteral) && ie.e2.op == EXP.int64)
|
||||
if ((ie.e1.type.isStaticOrDynamicArray() || ie.e1.op == EXP.string_ || ie.e1.op == EXP.arrayLiteral) && ie.e2.op == EXP.int64)
|
||||
{
|
||||
*ofs = ie.e2.toInteger();
|
||||
return ie.e1;
|
||||
|
@ -697,7 +697,7 @@ Expression getAggregateFromPointer(Expression e, dinteger_t* ofs)
|
|||
if (auto se = e.isSliceExp())
|
||||
{
|
||||
if (se && e.type.toBasetype().ty == Tsarray &&
|
||||
(se.e1.type.ty == Tarray || se.e1.type.ty == Tsarray || se.e1.op == EXP.string_ || se.e1.op == EXP.arrayLiteral) && se.lwr.op == EXP.int64)
|
||||
(se.e1.type.isStaticOrDynamicArray() || se.e1.op == EXP.string_ || se.e1.op == EXP.arrayLiteral) && se.lwr.op == EXP.int64)
|
||||
{
|
||||
*ofs = se.lwr.toInteger();
|
||||
return se.e1;
|
||||
|
@ -1841,7 +1841,7 @@ bool isCtfeValueValid(Expression newval)
|
|||
const SliceExp se = newval.isSliceExp();
|
||||
assert(se.lwr && se.lwr.op == EXP.int64);
|
||||
assert(se.upr && se.upr.op == EXP.int64);
|
||||
return (tb.ty == Tarray || tb.ty == Tsarray) && (se.e1.op == EXP.string_ || se.e1.op == EXP.arrayLiteral);
|
||||
return tb.isStaticOrDynamicArray() && (se.e1.op == EXP.string_ || se.e1.op == EXP.arrayLiteral);
|
||||
}
|
||||
|
||||
case EXP.void_:
|
||||
|
|
|
@ -626,7 +626,7 @@ MATCH implicitConvTo(Expression e, Type t)
|
|||
if (!e.committed && t.ty == Tpointer && t.nextOf().ty == Tvoid)
|
||||
return MATCH.nomatch;
|
||||
|
||||
if (!(e.type.ty == Tsarray || e.type.ty == Tarray || e.type.ty == Tpointer))
|
||||
if (!(e.type.isStaticOrDynamicArray() || e.type.ty == Tpointer))
|
||||
return visit(e);
|
||||
|
||||
TY tyn = e.type.nextOf().ty;
|
||||
|
@ -758,8 +758,7 @@ MATCH implicitConvTo(Expression e, Type t)
|
|||
Type typeb = e.type.toBasetype();
|
||||
|
||||
auto result = MATCH.nomatch;
|
||||
if ((tb.ty == Tarray || tb.ty == Tsarray) &&
|
||||
(typeb.ty == Tarray || typeb.ty == Tsarray))
|
||||
if (tb.isStaticOrDynamicArray() && typeb.isStaticOrDynamicArray())
|
||||
{
|
||||
result = MATCH.exact;
|
||||
Type typen = typeb.nextOf().toBasetype();
|
||||
|
@ -802,7 +801,7 @@ MATCH implicitConvTo(Expression e, Type t)
|
|||
|
||||
return result;
|
||||
}
|
||||
else if (tb.ty == Tvector && (typeb.ty == Tarray || typeb.ty == Tsarray || typeb.ty == Tpointer))
|
||||
else if (tb.ty == Tvector && (typeb.isStaticOrDynamicArray() || typeb.ty == Tpointer))
|
||||
{ // Tpointer because ImportC eagerly converts Tsarray to Tpointer
|
||||
result = MATCH.exact;
|
||||
// Convert array literal to vector type
|
||||
|
@ -2724,8 +2723,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null)
|
|||
}
|
||||
Type typeb = e.type.toBasetype();
|
||||
|
||||
if ((tb.ty == Tarray || tb.ty == Tsarray) &&
|
||||
(typeb.ty == Tarray || typeb.ty == Tsarray))
|
||||
if (tb.isStaticOrDynamicArray() && typeb.isStaticOrDynamicArray())
|
||||
{
|
||||
if (tb.nextOf().toBasetype().ty == Tvoid && typeb.nextOf().toBasetype().ty != Tvoid)
|
||||
{
|
||||
|
@ -2768,7 +2766,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null)
|
|||
ae.type = tp;
|
||||
}
|
||||
}
|
||||
else if (tb.ty == Tvector && (typeb.ty == Tarray || typeb.ty == Tsarray || typeb.ty == Tpointer))
|
||||
else if (tb.ty == Tvector && (typeb.isStaticOrDynamicArray() || typeb.ty == Tpointer))
|
||||
{
|
||||
// Convert array literal to vector type
|
||||
// The Tpointer case comes from C eagerly converting Tsarray to Tpointer
|
||||
|
@ -3140,7 +3138,7 @@ Expression inferType(Expression e, Type t, int flag = 0)
|
|||
Expression visitAle(ArrayLiteralExp ale)
|
||||
{
|
||||
Type tb = t.toBasetype();
|
||||
if (tb.ty == Tarray || tb.ty == Tsarray)
|
||||
if (tb.isStaticOrDynamicArray())
|
||||
{
|
||||
Type tn = tb.nextOf();
|
||||
if (ale.basis)
|
||||
|
@ -3284,7 +3282,7 @@ private bool isVoidArrayLiteral(Expression e, Type other)
|
|||
{
|
||||
auto ale = e.isArrayLiteralExp();
|
||||
e = ale[0];
|
||||
if (other.ty == Tsarray || other.ty == Tarray)
|
||||
if (other.isStaticOrDynamicArray())
|
||||
other = other.nextOf();
|
||||
else
|
||||
return false;
|
||||
|
@ -3550,7 +3548,7 @@ Lagain:
|
|||
return null;
|
||||
}
|
||||
|
||||
if ((t1.ty == Tsarray || t1.ty == Tarray) && (e2.op == EXP.null_ && t2.ty == Tpointer && t2.nextOf().ty == Tvoid || e2.op == EXP.arrayLiteral && t2.ty == Tsarray && t2.nextOf().ty == Tvoid && t2.isTypeSArray().dim.toInteger() == 0 || isVoidArrayLiteral(e2, t1)))
|
||||
if (t1.isStaticOrDynamicArray() && (e2.op == EXP.null_ && t2.ty == Tpointer && t2.nextOf().ty == Tvoid || e2.op == EXP.arrayLiteral && t2.ty == Tsarray && t2.nextOf().ty == Tvoid && t2.isTypeSArray().dim.toInteger() == 0 || isVoidArrayLiteral(e2, t1)))
|
||||
{
|
||||
/* (T[n] op void*) => T[]
|
||||
* (T[] op void*) => T[]
|
||||
|
@ -3562,7 +3560,9 @@ Lagain:
|
|||
return coerce(t1.nextOf().arrayOf());
|
||||
}
|
||||
|
||||
if ((t2.ty == Tsarray || t2.ty == Tarray) && (e1.op == EXP.null_ && t1.ty == Tpointer && t1.nextOf().ty == Tvoid || e1.op == EXP.arrayLiteral && t1.ty == Tsarray && t1.nextOf().ty == Tvoid && t1.isTypeSArray().dim.toInteger() == 0 || isVoidArrayLiteral(e1, t2)))
|
||||
if (t2.isStaticOrDynamicArray() &&
|
||||
(e1.op == EXP.null_ && t1.ty == Tpointer && t1.nextOf().ty == Tvoid || e1.op == EXP.arrayLiteral
|
||||
&& t1.ty == Tsarray && t1.nextOf().ty == Tvoid && t1.isTypeSArray().dim.toInteger() == 0 || isVoidArrayLiteral(e1, t2)))
|
||||
{
|
||||
/* (void* op T[n]) => T[]
|
||||
* (void* op T[]) => T[]
|
||||
|
@ -3574,7 +3574,7 @@ Lagain:
|
|||
return coerce(t2.nextOf().arrayOf());
|
||||
}
|
||||
|
||||
if ((t1.ty == Tsarray || t1.ty == Tarray) && (m = t1.implicitConvTo(t2)) != MATCH.nomatch)
|
||||
if (t1.isStaticOrDynamicArray() && (m = t1.implicitConvTo(t2)) != MATCH.nomatch)
|
||||
{
|
||||
// https://issues.dlang.org/show_bug.cgi?id=7285
|
||||
// Tsarray op [x, y, ...] should to be Tsarray
|
||||
|
@ -3590,7 +3590,7 @@ Lagain:
|
|||
return convert(e1, t2);
|
||||
}
|
||||
|
||||
if ((t2.ty == Tsarray || t2.ty == Tarray) && t2.implicitConvTo(t1))
|
||||
if (t2.isStaticOrDynamicArray() && t2.implicitConvTo(t1))
|
||||
{
|
||||
// https://issues.dlang.org/show_bug.cgi?id=7285
|
||||
// https://issues.dlang.org/show_bug.cgi?id=14737
|
||||
|
@ -3599,7 +3599,8 @@ Lagain:
|
|||
return convert(e2, t1);
|
||||
}
|
||||
|
||||
if ((t1.ty == Tsarray || t1.ty == Tarray || t1.ty == Tpointer) && (t2.ty == Tsarray || t2.ty == Tarray || t2.ty == Tpointer) && t1.nextOf().mod != t2.nextOf().mod)
|
||||
if ((t1.isStaticOrDynamicArray() || t1.ty == Tpointer) && (t2.isStaticOrDynamicArray() || t2.ty == Tpointer)
|
||||
&& t1.nextOf().mod != t2.nextOf().mod)
|
||||
{
|
||||
/* If one is mutable and the other immutable, then retry
|
||||
* with both of them as const
|
||||
|
@ -4240,7 +4241,7 @@ extern (D) bool arrayTypeCompatibleWithoutCasting(Type t1, Type t2)
|
|||
t1 = t1.toBasetype();
|
||||
t2 = t2.toBasetype();
|
||||
|
||||
if ((t1.ty == Tarray || t1.ty == Tsarray || t1.ty == Tpointer) && t2.ty == t1.ty)
|
||||
if ((t1.isStaticOrDynamicArray() || t1.ty == Tpointer) && t2.ty == t1.ty)
|
||||
{
|
||||
if (t1.nextOf().implicitConvTo(t2.nextOf()) >= MATCH.constant || t2.nextOf().implicitConvTo(t1.nextOf()) >= MATCH.constant)
|
||||
return true;
|
||||
|
|
|
@ -1885,7 +1885,7 @@ public:
|
|||
// Check for taking an address of a shared variable.
|
||||
// If the shared variable is an array, the offset might not be zero.
|
||||
Type fromType = null;
|
||||
if (e.var.type.ty == Tarray || e.var.type.ty == Tsarray)
|
||||
if (e.var.type.isStaticOrDynamicArray())
|
||||
{
|
||||
fromType = (cast(TypeArray)e.var.type).next;
|
||||
}
|
||||
|
@ -1900,7 +1900,7 @@ public:
|
|||
Expression val = getVarExp(e.loc, istate, e.var, goal);
|
||||
if (exceptionOrCant(val))
|
||||
return;
|
||||
if (val.type.ty == Tarray || val.type.ty == Tsarray)
|
||||
if (val.type.isStaticOrDynamicArray())
|
||||
{
|
||||
// Check for unsupported type painting operations
|
||||
Type elemtype = (cast(TypeArray)val.type).next;
|
||||
|
@ -3354,7 +3354,7 @@ public:
|
|||
// a[] = e can have const e. So we compare the naked types.
|
||||
Type tdst = e1.type.toBasetype();
|
||||
Type tsrc = e.e2.type.toBasetype();
|
||||
while (tdst.ty == Tsarray || tdst.ty == Tarray)
|
||||
while (tdst.isStaticOrDynamicArray())
|
||||
{
|
||||
tdst = (cast(TypeArray)tdst).next.toBasetype();
|
||||
if (tsrc.equivalent(tdst))
|
||||
|
@ -4302,7 +4302,7 @@ public:
|
|||
Expression assignTo(ArrayLiteralExp ae, size_t lwr, size_t upr)
|
||||
{
|
||||
Expressions* w = ae.elements;
|
||||
assert(ae.type.ty == Tsarray || ae.type.ty == Tarray || ae.type.ty == Tpointer);
|
||||
assert(ae.type.isStaticOrDynamicArray() || ae.type.ty == Tpointer);
|
||||
bool directblk = (cast(TypeNext)ae.type).next.equivalent(newval.type);
|
||||
for (size_t k = lwr; k < upr; k++)
|
||||
{
|
||||
|
@ -5804,8 +5804,7 @@ public:
|
|||
auto expTb = exp.type.toBasetype();
|
||||
|
||||
if (exp.type.implicitConvTo(tbNext) >= MATCH.convert &&
|
||||
(tb.ty == Tarray || tb.ty == Tsarray) &&
|
||||
(expTb.ty == Tarray || expTb.ty == Tsarray))
|
||||
tb.isStaticOrDynamicArray() && expTb.isStaticOrDynamicArray())
|
||||
return new ArrayLiteralExp(exp.loc, e.type, exp);
|
||||
return exp;
|
||||
}
|
||||
|
@ -5921,7 +5920,7 @@ public:
|
|||
|
||||
bool castToSarrayPointer = false;
|
||||
bool castBackFromVoid = false;
|
||||
if (e1.type.ty == Tarray || e1.type.ty == Tsarray || e1.type.ty == Tpointer)
|
||||
if (e1.type.isStaticOrDynamicArray() || e1.type.ty == Tpointer)
|
||||
{
|
||||
// Check for unsupported type painting operations
|
||||
// For slices, we need the type being sliced,
|
||||
|
@ -6101,7 +6100,7 @@ public:
|
|||
|
||||
// Disallow array type painting, except for conversions between built-in
|
||||
// types of identical size.
|
||||
if ((e.to.ty == Tsarray || e.to.ty == Tarray) && (e1.type.ty == Tsarray || e1.type.ty == Tarray) && !isSafePointerCast(e1.type.nextOf(), e.to.nextOf()))
|
||||
if (e.to.isStaticOrDynamicArray() && e1.type.isStaticOrDynamicArray() && !isSafePointerCast(e1.type.nextOf(), e.to.nextOf()))
|
||||
{
|
||||
auto se = e1.isStringExp();
|
||||
// Allow casting a hex string literal to short[], int[] or long[]
|
||||
|
|
|
@ -1625,8 +1625,7 @@ elem* toElem(Expression e, ref IRState irs)
|
|||
Type tb1 = be.e1.type.toBasetype();
|
||||
Type tb2 = be.e2.type.toBasetype();
|
||||
|
||||
assert(!((tb1.ty == Tarray || tb1.ty == Tsarray ||
|
||||
tb2.ty == Tarray || tb2.ty == Tsarray) &&
|
||||
assert(!((tb1.isStaticOrDynamicArray() || tb2.isStaticOrDynamicArray()) &&
|
||||
tb2.ty != Tvoid &&
|
||||
op != OPeq && op != OPandand && op != OPoror));
|
||||
|
||||
|
@ -1648,8 +1647,7 @@ elem* toElem(Expression e, ref IRState irs)
|
|||
Type tb1 = be.e1.type.toBasetype();
|
||||
Type tb2 = be.e2.type.toBasetype();
|
||||
|
||||
assert(!((tb1.ty == Tarray || tb1.ty == Tsarray ||
|
||||
tb2.ty == Tarray || tb2.ty == Tsarray) &&
|
||||
assert(!((tb1.isStaticOrDynamicArray() || tb2.isStaticOrDynamicArray()) &&
|
||||
tb2.ty != Tvoid &&
|
||||
op != OPeq && op != OPandand && op != OPoror));
|
||||
|
||||
|
@ -1822,9 +1820,7 @@ elem* toElem(Expression e, ref IRState irs)
|
|||
// Should have already been lowered
|
||||
assert(0);
|
||||
}
|
||||
else if (cast(int)eop > 1 &&
|
||||
(t1.ty == Tarray || t1.ty == Tsarray) &&
|
||||
(t2.ty == Tarray || t2.ty == Tsarray))
|
||||
else if (cast(int)eop > 1 && t1.isStaticOrDynamicArray() && t2.isStaticOrDynamicArray())
|
||||
{
|
||||
// This codepath was replaced by lowering during semantic
|
||||
// to object.__cmp in druntime.
|
||||
|
@ -1975,8 +1971,7 @@ elem* toElem(Expression e, ref IRState irs)
|
|||
// Rewritten to IdentityExp or memberwise-compare
|
||||
assert(0);
|
||||
}
|
||||
else if ((t1.ty == Tarray || t1.ty == Tsarray) &&
|
||||
(t2.ty == Tarray || t2.ty == Tsarray))
|
||||
else if (t1.isStaticOrDynamicArray() && t2.isStaticOrDynamicArray())
|
||||
{
|
||||
Type telement = t1.nextOf().toBasetype();
|
||||
Type telement2 = t2.nextOf().toBasetype();
|
||||
|
@ -2142,8 +2137,7 @@ elem* toElem(Expression e, ref IRState irs)
|
|||
e = el_bin(eop, TYint, e, el_long(TYint, 0));
|
||||
elem_setLoc(e, ie.loc);
|
||||
}
|
||||
else if ((t1.ty == Tarray || t1.ty == Tsarray) &&
|
||||
(t2.ty == Tarray || t2.ty == Tsarray))
|
||||
else if (t1.isStaticOrDynamicArray() && t2.isStaticOrDynamicArray())
|
||||
{
|
||||
|
||||
elem *ea1 = toElem(ie.e1, irs);
|
||||
|
@ -3765,7 +3759,7 @@ elem* toElem(Expression e, ref IRState irs)
|
|||
{
|
||||
//printf("SliceExp.toElem() se = %s %s\n", se.type.toChars(), se.toChars());
|
||||
Type tb = se.type.toBasetype();
|
||||
assert(tb.ty == Tarray || tb.ty == Tsarray);
|
||||
assert(tb.isStaticOrDynamicArray());
|
||||
Type t1 = se.e1.type.toBasetype();
|
||||
elem *e = toElem(se.e1, irs);
|
||||
if (se.lwr)
|
||||
|
|
|
@ -1607,7 +1607,7 @@ void escapeExp(Expression e, ref scope EscapeByResults er, int deref)
|
|||
void visitArrayLiteral(ArrayLiteralExp e)
|
||||
{
|
||||
Type tb = e.type.toBasetype();
|
||||
if (tb.isTypeSArray() || tb.isTypeDArray())
|
||||
if (tb.isStaticOrDynamicArray())
|
||||
{
|
||||
if (e.basis)
|
||||
escapeExp(e.basis, er, deref);
|
||||
|
@ -2245,7 +2245,7 @@ private bool isTypesafeVariadicArray(VarDeclaration v)
|
|||
if (v.storage_class & STC.variadic)
|
||||
{
|
||||
Type tb = v.type.toBasetype();
|
||||
if (tb.ty == Tarray || tb.ty == Tsarray)
|
||||
if (tb.isStaticOrDynamicArray())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -1207,7 +1207,7 @@ private Expression resolveUFCS(Scope* sc, CallExp ce)
|
|||
eleft = die.e1;
|
||||
|
||||
Type t = eleft.type.toBasetype();
|
||||
if (t.ty == Tarray || t.ty == Tsarray || t.ty == Tnull || (t.isTypeBasic() && t.ty != Tvoid))
|
||||
if (t.isStaticOrDynamicArray() || t.ty == Tnull || (t.isTypeBasic() && t.ty != Tvoid))
|
||||
{
|
||||
/* Built-in types and arrays have no callable properties, so do shortcut.
|
||||
* It is necessary in: e.init()
|
||||
|
@ -7554,7 +7554,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
result = e;
|
||||
return;
|
||||
}
|
||||
if (exp.e1.op == EXP.slice || exp.e1.type.ty == Tarray || exp.e1.type.ty == Tsarray)
|
||||
if (exp.e1.op == EXP.slice || exp.e1.type.isStaticOrDynamicArray())
|
||||
{
|
||||
if (checkNonAssignmentArrayOp(exp.e1))
|
||||
return setError();
|
||||
|
@ -8846,7 +8846,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
fix16997(sc, exp);
|
||||
exp.type = exp.e1.type;
|
||||
Type tb = exp.type.toBasetype();
|
||||
if (tb.ty == Tarray || tb.ty == Tsarray)
|
||||
if (tb.isStaticOrDynamicArray())
|
||||
{
|
||||
if (!isArrayOpValid(exp.e1))
|
||||
{
|
||||
|
@ -8911,7 +8911,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
fix16997(sc, exp);
|
||||
exp.type = exp.e1.type;
|
||||
Type tb = exp.type.toBasetype();
|
||||
if (tb.ty == Tarray || tb.ty == Tsarray)
|
||||
if (tb.isStaticOrDynamicArray())
|
||||
{
|
||||
if (!isArrayOpValid(exp.e1))
|
||||
{
|
||||
|
@ -9193,7 +9193,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
}
|
||||
}
|
||||
|
||||
if (!t1b.equals(tob) && (t1b.ty == Tarray || t1b.ty == Tsarray))
|
||||
if (!t1b.equals(tob) && t1b.isStaticOrDynamicArray())
|
||||
{
|
||||
if (checkNonAssignmentArrayOp(exp.e1))
|
||||
return setError();
|
||||
|
@ -9513,7 +9513,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
/* Run semantic on lwr and upr.
|
||||
*/
|
||||
Scope* scx = sc;
|
||||
if (t1b.ty == Tsarray || t1b.ty == Tarray || t1b.ty == Ttuple)
|
||||
if (t1b.isStaticOrDynamicArray() || t1b.ty == Ttuple)
|
||||
{
|
||||
// Create scope for 'length' variable
|
||||
ScopeDsymbol sym = new ArrayScopeSymbol(sc, exp);
|
||||
|
@ -9620,7 +9620,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
IntRange lwrRange = getIntRange(exp.lwr);
|
||||
IntRange uprRange = getIntRange(exp.upr);
|
||||
|
||||
if (t1b.ty == Tsarray || t1b.ty == Tarray)
|
||||
if (t1b.isStaticOrDynamicArray())
|
||||
{
|
||||
Expression el = new ArrayLengthExp(exp.loc, exp.e1);
|
||||
el = el.expressionSemantic(sc);
|
||||
|
@ -9941,7 +9941,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
t1b = t1b.castMod(tv1.mod);
|
||||
exp.e1 = exp.e1.castTo(sc, t1b);
|
||||
}
|
||||
if (t1b.ty == Tsarray || t1b.ty == Tarray)
|
||||
if (t1b.isStaticOrDynamicArray())
|
||||
{
|
||||
if (!checkAddressable(exp, sc))
|
||||
return setError();
|
||||
|
@ -9950,7 +9950,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
/* Run semantic on e2
|
||||
*/
|
||||
Scope* scx = sc;
|
||||
if (t1b.ty == Tsarray || t1b.ty == Tarray || t1b.ty == Ttuple)
|
||||
if (t1b.isStaticOrDynamicArray() || t1b.ty == Ttuple)
|
||||
{
|
||||
// Create scope for 'length' variable
|
||||
ScopeDsymbol sym = new ArrayScopeSymbol(sc, exp);
|
||||
|
@ -10086,7 +10086,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
// We might know $ now
|
||||
setLengthVarIfKnown(exp.lengthVar, t1b);
|
||||
|
||||
if (t1b.ty == Tsarray || t1b.ty == Tarray)
|
||||
if (t1b.isStaticOrDynamicArray())
|
||||
{
|
||||
Expression el = new ArrayLengthExp(exp.loc, exp.e1);
|
||||
el = el.expressionSemantic(sc);
|
||||
|
@ -11352,7 +11352,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
return setError();
|
||||
}
|
||||
else if (exp.e1.op == EXP.slice &&
|
||||
(t2.ty == Tarray || t2.ty == Tsarray) &&
|
||||
t2.isStaticOrDynamicArray() &&
|
||||
t2.nextOf().implicitConvTo(t1.nextOf()))
|
||||
{
|
||||
// Check element-wise assignment.
|
||||
|
@ -11461,7 +11461,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
}
|
||||
|
||||
if (exp.e1.op == EXP.slice &&
|
||||
(t1.ty == Tarray || t1.ty == Tsarray) &&
|
||||
t1.isStaticOrDynamicArray() &&
|
||||
t1.nextOf().toBasetype().ty == Tvoid)
|
||||
{
|
||||
if (t2.nextOf().implicitConvTo(t1.nextOf()))
|
||||
|
@ -11496,7 +11496,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
|
||||
/* Look for array operations
|
||||
*/
|
||||
if ((t2.ty == Tarray || t2.ty == Tsarray) && isArrayOpValid(exp.e2))
|
||||
if (t2.isStaticOrDynamicArray() && isArrayOpValid(exp.e2))
|
||||
{
|
||||
// Look for valid array operations
|
||||
if (exp.memset != MemorySet.blockAssign &&
|
||||
|
@ -11673,7 +11673,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
return ae;
|
||||
|
||||
const isArrayAssign = (ae.e1.isSliceExp() || ae.e1.type.ty == Tsarray) &&
|
||||
(ae.e2.type.ty == Tsarray || ae.e2.type.ty == Tarray) &&
|
||||
(ae.e2.type.isStaticOrDynamicArray()) &&
|
||||
(ae.e1.type.nextOf() && ae.e2.type.nextOf() && ae.e1.type.nextOf.mutableOf.equals(ae.e2.type.nextOf.mutableOf()));
|
||||
|
||||
const isArraySetAssign = (ae.e1.isSliceExp() || ae.e1.type.ty == Tsarray) &&
|
||||
|
@ -11749,7 +11749,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
return setError();
|
||||
|
||||
assert(exp.e1.type && exp.e2.type);
|
||||
if (exp.e1.op == EXP.slice || exp.e1.type.ty == Tarray || exp.e1.type.ty == Tsarray)
|
||||
if (exp.e1.op == EXP.slice || exp.e1.type.isStaticOrDynamicArray())
|
||||
{
|
||||
if (checkNonAssignmentArrayOp(exp.e1))
|
||||
return setError();
|
||||
|
@ -11769,7 +11769,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
// Check element types are arithmetic
|
||||
Type tb1 = exp.e1.type.nextOf().toBasetype();
|
||||
Type tb2 = exp.e2.type.toBasetype();
|
||||
if (tb2.ty == Tarray || tb2.ty == Tsarray)
|
||||
if (tb2.isStaticOrDynamicArray())
|
||||
tb2 = tb2.nextOf().toBasetype();
|
||||
if ((tb1.isIntegral() || tb1.isFloating()) && (tb2.isIntegral() || tb2.isFloating()))
|
||||
{
|
||||
|
@ -11858,7 +11858,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
* EXP.concatenateDcharAssign: appending dchar to T[]
|
||||
*/
|
||||
if ((tb1.ty == Tarray) &&
|
||||
(tb2.ty == Tarray || tb2.ty == Tsarray) &&
|
||||
tb2.isStaticOrDynamicArray() &&
|
||||
(exp.e2.implicitConvTo(exp.e1.type) ||
|
||||
(tb2.nextOf().implicitConvTo(tb1next) &&
|
||||
// Do not strip const(void)[]
|
||||
|
@ -12116,7 +12116,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
}
|
||||
|
||||
Type tb = exp.type.toBasetype();
|
||||
if (tb.ty == Tarray || tb.ty == Tsarray)
|
||||
if (tb.isStaticOrDynamicArray())
|
||||
{
|
||||
if (!isArrayOpValid(exp))
|
||||
{
|
||||
|
@ -12269,7 +12269,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
}
|
||||
|
||||
Type tb = exp.type.toBasetype();
|
||||
if (tb.ty == Tarray || tb.ty == Tsarray)
|
||||
if (tb.isStaticOrDynamicArray())
|
||||
{
|
||||
if (!isArrayOpValid(exp))
|
||||
{
|
||||
|
@ -12451,7 +12451,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
}
|
||||
|
||||
// Check for: array ~ element
|
||||
if ((tb1.ty == Tsarray || tb1.ty == Tarray) && tb2.ty != Tvoid)
|
||||
if (tb1.isStaticOrDynamicArray() && tb2.ty != Tvoid)
|
||||
{
|
||||
if (exp.e1.op == EXP.arrayLiteral)
|
||||
{
|
||||
|
@ -12490,7 +12490,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
}
|
||||
}
|
||||
// Check for: element ~ array
|
||||
if ((tb2.ty == Tsarray || tb2.ty == Tarray) && tb1.ty != Tvoid)
|
||||
if (tb2.isStaticOrDynamicArray() && tb1.ty != Tvoid)
|
||||
{
|
||||
if (exp.e2.op == EXP.arrayLiteral)
|
||||
{
|
||||
|
@ -12525,7 +12525,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
}
|
||||
|
||||
Lpeer:
|
||||
if ((tb1.ty == Tsarray || tb1.ty == Tarray) && (tb2.ty == Tsarray || tb2.ty == Tarray) && (tb1next.mod || tb2next.mod) && (tb1next.mod != tb2next.mod))
|
||||
if (tb1.isStaticOrDynamicArray() && tb2.isStaticOrDynamicArray() &&
|
||||
(tb1next.mod || tb2next.mod) && (tb1next.mod != tb2next.mod))
|
||||
{
|
||||
Type t1 = tb1next.mutableOf().constOf().arrayOf();
|
||||
Type t2 = tb2next.mutableOf().constOf().arrayOf();
|
||||
|
@ -12564,8 +12565,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
Type t1 = exp.e1.type.toBasetype();
|
||||
Type t2 = exp.e2.type.toBasetype();
|
||||
Expression e;
|
||||
if ((t1.ty == Tarray || t1.ty == Tsarray) &&
|
||||
(t2.ty == Tarray || t2.ty == Tsarray))
|
||||
if (t1.isStaticOrDynamicArray() && t2.isStaticOrDynamicArray())
|
||||
{
|
||||
// Normalize to ArrayLiteralExp or StringExp as far as possible
|
||||
e = exp.optimize(WANTvalue);
|
||||
|
@ -12596,7 +12596,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
}
|
||||
|
||||
Type tb = exp.type.toBasetype();
|
||||
if (tb.ty == Tarray || tb.ty == Tsarray)
|
||||
if (tb.isStaticOrDynamicArray())
|
||||
{
|
||||
if (!isArrayOpValid(exp))
|
||||
{
|
||||
|
@ -12876,7 +12876,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
}
|
||||
|
||||
Type tb = exp.type.toBasetype();
|
||||
if (tb.ty == Tarray || tb.ty == Tsarray)
|
||||
if (tb.isStaticOrDynamicArray())
|
||||
{
|
||||
if (!isArrayOpValid(exp))
|
||||
{
|
||||
|
@ -13038,7 +13038,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
Expression arrayLowering = null;
|
||||
t1 = exp.e1.type.toBasetype();
|
||||
t2 = exp.e2.type.toBasetype();
|
||||
if ((t1.ty == Tarray || t1.ty == Tsarray || t1.ty == Tpointer) && (t2.ty == Tarray || t2.ty == Tsarray || t2.ty == Tpointer))
|
||||
if ((t1.isStaticOrDynamicArray() || t1.ty == Tpointer) && (t2.isStaticOrDynamicArray() || t2.ty == Tpointer))
|
||||
{
|
||||
Type t1next = t1.nextOf();
|
||||
Type t2next = t2.nextOf();
|
||||
|
@ -13048,8 +13048,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
return setError();
|
||||
}
|
||||
|
||||
if ((t1.ty == Tarray || t1.ty == Tsarray) &&
|
||||
(t2.ty == Tarray || t2.ty == Tsarray))
|
||||
if (t1.isStaticOrDynamicArray() && t2.isStaticOrDynamicArray())
|
||||
{
|
||||
if (!verifyHookExist(exp.loc, *sc, Id.__cmp, "comparing arrays"))
|
||||
return setError();
|
||||
|
@ -13288,8 +13287,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
return;
|
||||
}
|
||||
|
||||
const isArrayComparison = (t1.ty == Tarray || t1.ty == Tsarray) &&
|
||||
(t2.ty == Tarray || t2.ty == Tsarray);
|
||||
const isArrayComparison = t1.isStaticOrDynamicArray() && t2.isStaticOrDynamicArray();
|
||||
const needsArrayLowering = isArrayComparison && needsDirectEq(t1, t2, sc);
|
||||
|
||||
if (!needsArrayLowering)
|
||||
|
@ -14401,7 +14399,7 @@ Expression dotTemplateSemanticProp(DotTemplateInstanceExp exp, Scope* sc, bool g
|
|||
{
|
||||
exp.e1 = die.e1; // take back
|
||||
Type t1b = exp.e1.type.toBasetype();
|
||||
if (t1b.ty == Tarray || t1b.ty == Tsarray || t1b.ty == Taarray || t1b.ty == Tnull || (t1b.isTypeBasic() && t1b.ty != Tvoid))
|
||||
if (t1b.isStaticOrDynamicArray() || t1b.ty == Taarray || t1b.ty == Tnull || (t1b.isTypeBasic() && t1b.ty != Tvoid))
|
||||
{
|
||||
/* No built-in type has templatized properties, so do shortcut.
|
||||
* It is necessary in: 1024.max!"a < b"
|
||||
|
@ -16281,7 +16279,7 @@ private bool fit(StructDeclaration sd, const ref Loc loc, Scope* sc, Expressions
|
|||
Type typeb = se.type.toBasetype();
|
||||
TY tynto = tb.nextOf().ty;
|
||||
if (!se.committed &&
|
||||
(typeb.ty == Tarray || typeb.ty == Tsarray) && tynto.isSomeChar &&
|
||||
typeb.isStaticOrDynamicArray() && tynto.isSomeChar &&
|
||||
se.numberOfCodeUnits(tynto) < (cast(TypeSArray)tb).dim.toInteger())
|
||||
{
|
||||
e = se.castTo(sc, t);
|
||||
|
|
|
@ -166,7 +166,7 @@ Expression carraySemantic(ArrayExp ae, Scope* sc)
|
|||
* So, rewrite as an IndexExp if we can.
|
||||
*/
|
||||
auto t1 = e1.type.toBasetype();
|
||||
if (t1.isTypeDArray() || t1.isTypeSArray())
|
||||
if (t1.isStaticOrDynamicArray())
|
||||
{
|
||||
e2 = e2.expressionSemantic(sc).arrayFuncConv(sc);
|
||||
// C doesn't do array bounds checking, so `true` turns it off
|
||||
|
@ -176,7 +176,7 @@ Expression carraySemantic(ArrayExp ae, Scope* sc)
|
|||
e1 = e1.arrayFuncConv(sc); // e1 might still be a function call
|
||||
e2 = e2.expressionSemantic(sc);
|
||||
auto t2 = e2.type.toBasetype();
|
||||
if (t2.isTypeDArray() || t2.isTypeSArray())
|
||||
if (t2.isStaticOrDynamicArray())
|
||||
{
|
||||
return new IndexExp(ae.loc, e2, e1, true).expressionSemantic(sc); // swap operands
|
||||
}
|
||||
|
|
|
@ -439,7 +439,7 @@ Initializer initializerSemantic(Initializer init, Scope* sc, ref Type tx, NeedIn
|
|||
Type typeb = se.type.toBasetype();
|
||||
TY tynto = tb.nextOf().ty;
|
||||
if (!se.committed &&
|
||||
(typeb.ty == Tarray || typeb.ty == Tsarray) && tynto.isSomeChar &&
|
||||
typeb.isStaticOrDynamicArray() && tynto.isSomeChar &&
|
||||
se.numberOfCodeUnits(tynto) < tb.isTypeSArray().dim.toInteger())
|
||||
{
|
||||
i.exp = se.castTo(sc, t);
|
||||
|
|
|
@ -822,7 +822,7 @@ public:
|
|||
visit(cast(BinExp)e);
|
||||
|
||||
Type t1 = e.e1.type.toBasetype();
|
||||
if (t1.ty == Tarray || t1.ty == Tsarray)
|
||||
if (t1.isStaticOrDynamicArray())
|
||||
{
|
||||
Type t = t1.nextOf().toBasetype();
|
||||
while (t.toBasetype().nextOf())
|
||||
|
|
|
@ -1521,6 +1521,8 @@ extern (C++) abstract class Type : ASTNode
|
|||
inout(TypeTraits) isTypeTraits() { return ty == Ttraits ? cast(typeof(return))this : null; }
|
||||
inout(TypeNoreturn) isTypeNoreturn() { return ty == Tnoreturn ? cast(typeof(return))this : null; }
|
||||
inout(TypeTag) isTypeTag() { return ty == Ttag ? cast(typeof(return))this : null; }
|
||||
|
||||
extern (D) bool isStaticOrDynamicArray() const { return ty == Tarray || ty == Tsarray; }
|
||||
}
|
||||
|
||||
override void accept(Visitor v)
|
||||
|
@ -3947,7 +3949,7 @@ extern (C++) final class Parameter : ASTNode
|
|||
Type isLazyArray()
|
||||
{
|
||||
Type tb = type.toBasetype();
|
||||
if (tb.ty == Tsarray || tb.ty == Tarray)
|
||||
if (tb.isStaticOrDynamicArray())
|
||||
{
|
||||
Type tel = (cast(TypeArray)tb).next.toBasetype();
|
||||
if (auto td = tel.isTypeDelegate())
|
||||
|
@ -4334,7 +4336,7 @@ AggregateDeclaration isAggregate(Type t)
|
|||
bool isIndexableNonAggregate(Type t)
|
||||
{
|
||||
t = t.toBasetype();
|
||||
return (t.ty == Tpointer || t.ty == Tsarray || t.ty == Tarray || t.ty == Taarray ||
|
||||
return (t.ty == Tpointer || t.isStaticOrDynamicArray() || t.ty == Taarray ||
|
||||
t.ty == Ttuple || t.ty == Tvector);
|
||||
}
|
||||
|
||||
|
|
|
@ -1683,7 +1683,7 @@ void genKill(ref ObState obstate, ObNode* ob)
|
|||
override void visit(ArrayLiteralExp e)
|
||||
{
|
||||
Type tb = e.type.toBasetype();
|
||||
if (tb.ty == Tsarray || tb.ty == Tarray)
|
||||
if (tb.isStaticOrDynamicArray())
|
||||
{
|
||||
if (e.basis)
|
||||
e.basis.accept(this);
|
||||
|
@ -2424,7 +2424,7 @@ void checkObErrors(ref ObState obstate)
|
|||
override void visit(ArrayLiteralExp e)
|
||||
{
|
||||
Type tb = e.type.toBasetype();
|
||||
if (tb.ty == Tsarray || tb.ty == Tarray)
|
||||
if (tb.isStaticOrDynamicArray())
|
||||
{
|
||||
if (e.basis)
|
||||
e.basis.accept(this);
|
||||
|
|
|
@ -658,8 +658,7 @@ Expression opOverloadEqual(EqualExp e, Scope* sc, Type[2] aliasThisStop)
|
|||
* lowering to object.__equals(), which takes care of overloaded
|
||||
* operators for the element types.
|
||||
*/
|
||||
if ((t1.isTypeDArray() || t1.isTypeSArray()) &&
|
||||
(t2.isTypeDArray() || t2.isTypeSArray()))
|
||||
if (t1.isStaticOrDynamicArray() && t2.isStaticOrDynamicArray())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -1080,7 +1080,7 @@ private void toDtElem(TypeSArray tsa, ref DtBuilder dtb, Expression e, bool isCt
|
|||
Type tnext = tsa.next;
|
||||
Type tbn = tnext.toBasetype();
|
||||
Type ten = e ? e.type : null;
|
||||
if (ten && (ten.ty == Tsarray || ten.ty == Tarray))
|
||||
if (ten && ten.isStaticOrDynamicArray())
|
||||
ten = ten.nextOf();
|
||||
while (tbn.ty == Tsarray && (!e || !tbn.equivalent(ten)))
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue