can_elide_copy_p (Expression *exp)
{
/* Explicit `__rvalue(exp)'. */
- if (exp->rvalue)
+ if (exp->rvalue ())
return true;
/* Look for variable expression. */
break;
case OPT_fdebug:
- global.params.debuglevel = value ? 1 : 0;
+ global.params.debugEnabled = value ? true : false;
break;
case OPT_fdebug_:
-b7e3b3b61711bf6c6cad27c7b5b73df0e570c215
+d29e3eca45edaeef63b31f78c9846fc6e2870c49
The first line of this file holds the git revision number of the last
merge done from the dlang/dmd repository.
/****************************************
* Determine if scope sc has protected level access to cd.
*/
-private bool hasProtectedAccess(Scope *sc, Dsymbol s)
+private bool hasProtectedAccess(Scope* sc, Dsymbol s)
{
if (auto cd = s.isClassMember()) // also includes interfaces
{
* s = symbol to check for visibility
* Returns: true if s is visible by origin
*/
-bool symbolIsVisible(Scope *sc, Dsymbol s)
+bool symbolIsVisible(Scope* sc, Dsymbol s)
{
s = mostVisibleOverload(s);
return checkSymbolAccess(sc, s);
* s = symbol to check for visibility
* Returns: true if s is visible by origin
*/
-bool checkSymbolAccess(Scope *sc, Dsymbol s)
+bool checkSymbolAccess(Scope* sc, Dsymbol s)
{
final switch (s.visible().kind)
{
s.isTemplateDeclaration() ||
s.isOverloadSet()))
{
- .error(s.loc, "%s `%s` is not a constructor; identifiers starting with `__` are reserved for the implementation", s.kind(), s.toPrettyChars());
+ error(s.loc, "%s name `__ctor` is not allowed", s.kind);
+ errorSupplemental(s.loc, "identifiers starting with `__` are reserved for internal use");
errors = true;
s = null;
}
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))
{
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));
}
{
//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)
{
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);
}
return new LinkDeclaration(loc, linkage, Dsymbol.arraySyntaxCopy(decl));
}
-
- override const(char)* toChars() const
- {
- return toString().ptr;
- }
-
- extern(D) override const(char)[] toString() const
- {
- return "extern ()";
- }
-
override void accept(Visitor v)
{
v.visit(this);
return new CPPMangleDeclaration(loc, cppmangle, Dsymbol.arraySyntaxCopy(decl));
}
- override const(char)* toChars() const
- {
- return toString().ptr;
- }
-
- extern(D) override const(char)[] toString() const
- {
- return "extern ()";
- }
-
override void accept(Visitor v)
{
v.visit(this);
this.loc, this.ident, this.exp, Dsymbol.arraySyntaxCopy(this.decl), this.cppnamespace);
}
- override const(char)* toChars() const
- {
- return toString().ptr;
- }
-
- extern(D) override const(char)[] toString() const
- {
- return "extern (C++, `namespace`)";
- }
-
override void accept(Visitor v)
{
v.visit(this);
static LinkDeclaration *create(const Loc &loc, LINK p, Dsymbols *decl);
LinkDeclaration *syntaxCopy(Dsymbol *s) override;
- const char *toChars() const override;
void accept(Visitor *v) override { v->visit(this); }
};
CPPMANGLE cppmangle;
CPPMangleDeclaration *syntaxCopy(Dsymbol *s) override;
- const char *toChars() const override;
void accept(Visitor *v) override { v->visit(this); }
};
Expression *exp;
CPPNamespaceDeclaration *syntaxCopy(Dsymbol *s) override;
- const char *toChars() const override;
void accept(Visitor *v) override { v->visit(this); }
};
return;
}
- Expressions *es;
+ Expressions* es;
if (auto ale = aggr.isArrayLiteralExp())
{
// Directly use the elements of the array for the TupleExp creation
*/
extern (C++) class DVCondition : Condition
{
- uint level;
Identifier ident;
Module mod;
- extern (D) this(const ref Loc loc, Module mod, uint level, Identifier ident) @safe
+ extern (D) this(const ref Loc loc, Module mod, Identifier ident) @safe
{
super(loc);
this.mod = mod;
- this.level = level;
this.ident = ident;
}
*
* Params:
* mod = Module this node belongs to
- * level = Minimum global level this condition needs to pass.
- * Only used if `ident` is `null`.
* ident = Identifier required for this condition to pass.
* If `null`, this conditiion will use an integer level.
* loc = Location in the source file
*/
- extern (D) this(const ref Loc loc, Module mod, uint level, Identifier ident) @safe
+ extern (D) this(const ref Loc loc, Module mod, Identifier ident) @safe
{
- super(loc, mod, level, ident);
+ super(loc, mod, ident);
}
override int include(Scope* sc)
mod.debugidsNot.push(ident);
}
}
- else if (level <= global.params.debuglevel || level <= mod.debuglevel)
+ else if (global.params.debugEnabled)
inc = Include.yes;
+
if (!definedInModule)
printDepsConditional(sc, this, "depsDebug ");
return (inc == Include.yes);
{
v.visit(this);
}
-
- override const(char)* toChars() const
- {
- return ident ? ident.toChars() : "debug".ptr;
- }
}
/**
*
* Params:
* mod = Module this node belongs to
- * level = Minimum global level this condition needs to pass.
- * Only used if `ident` is `null`.
* ident = Identifier required for this condition to pass.
* If `null`, this conditiion will use an integer level.
* loc = Location in the source file
*/
- extern (D) this(const ref Loc loc, Module mod, uint level, Identifier ident) @safe
+ extern (D) this(const ref Loc loc, Module mod, Identifier ident) @safe
{
- super(loc, mod, level, ident);
+ super(loc, mod, ident);
}
override int include(Scope* sc)
mod.versionidsNot.push(ident);
}
}
- else if (level <= global.params.versionlevel || level <= mod.versionlevel)
- inc = Include.yes;
if (!definedInModule &&
(!ident || (!isReserved(ident.toString()) && ident != Id._unittest && ident != Id._assert)))
{
{
v.visit(this);
}
-
- override const(char)* toChars() const
- {
- return ident ? ident.toChars() : "version".ptr;
- }
}
/***********************************************************
{
return this;
}
-
- override const(char)* toChars() const
- {
- return exp ? exp.toChars() : "static if".ptr;
- }
}
ob.writestring(") : ");
if (condition.ident)
ob.writestring(condition.ident.toString());
- else
- ob.print(condition.level);
ob.writeByte('\n');
}
class DVCondition : public Condition
{
public:
- unsigned level;
Identifier *ident;
Module *mod;
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.
{
public:
ClassReferenceExp *thrown; // the thing being tossed
- const char *toChars() const override;
void accept(Visitor *v) override { v->visit(this); }
};
class CTFEExp final : public Expression
{
-public:
- const char *toChars() const override;
};
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;
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;
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_:
/***********************************************************
* iasm.d
*/
-Statement asmSemantic(AsmStatement s, Scope *sc)
+Statement asmSemantic(AsmStatement s, Scope* sc)
{
import dmd.iasm;
return dmd.iasm.asmSemantic(s, sc);
}
-void asmSemantic(CAsmDeclaration d, Scope *sc)
+void asmSemantic(CAsmDeclaration d, Scope* sc)
{
import dmd.iasm;
return dmd.iasm.asmSemantic(d, sc);
/***********************************************************
* iasmgcc.d
*/
-Statement gccAsmSemantic(GccAsmStatement s, Scope *sc)
+Statement gccAsmSemantic(GccAsmStatement s, Scope* sc)
{
import dmd.iasmgcc;
return dmd.iasmgcc.gccAsmSemantic(s, sc);
}
-void gccAsmSemantic(CAsmDeclaration d, Scope *sc)
+void gccAsmSemantic(CAsmDeclaration d, Scope* sc)
{
import dmd.iasmgcc;
return dmd.iasmgcc.gccAsmSemantic(d, sc);
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;
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();
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
}
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)
{
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
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)
{
auto ale = e.isArrayLiteralExp();
e = ale[0];
- if (other.ty == Tsarray || other.ty == Tarray)
+ if (other.isStaticOrDynamicArray())
other = other.nextOf();
else
return false;
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[]
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[]
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
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
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
return convert(e1, t2);
/// Covers array operations for user-defined types
- Type checkArrayOpType(Expression e1, Expression e2, EXP op, Scope *sc)
+ Type checkArrayOpType(Expression e1, Expression e2, EXP op, Scope* sc)
{
// scalar op scalar - we shouldn't be here
if (e1.type.ty != Tarray && e1.type.ty != Tsarray && e2.type.ty != Tarray && e2.type.ty != Tsarray)
{
Expression errorReturn()
{
- Expression ex = be.incompatibleTypes();
+ Expression ex = be.incompatibleTypes(sc);
if (ex.op == EXP.error)
return ex;
return ErrorExp.get();
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;
assert(0); // should never be produced by syntax
}
- override final const(char)* toChars() const
- {
- //printf("TypeInfoDeclaration::toChars() tinfo = %s\n", tinfo.toChars());
- OutBuffer buf;
- buf.writestring("typeid(");
- buf.writestring(tinfo.toChars());
- buf.writeByte(')');
- return buf.extractChars();
- }
-
override final inout(TypeInfoDeclaration) isTypeInfoDeclaration() inout @nogc nothrow pure @safe
{
return this;
static TypeInfoDeclaration *create(Type *tinfo);
TypeInfoDeclaration *syntaxCopy(Dsymbol *) override final;
- const char *toChars() const override final;
TypeInfoDeclaration *isTypeInfoDeclaration() override final { return this; }
void accept(Visitor *v) override { v->visit(this); }
d_bool isMoveCtor;
CtorDeclaration *syntaxCopy(Dsymbol *) override;
const char *kind() const override;
- const char *toChars() const override;
bool isVirtual() const override;
bool addPreInvariant() override;
bool addPostInvariant() override;
public:
DtorDeclaration *syntaxCopy(Dsymbol *) override;
const char *kind() const override;
- const char *toChars() const override;
bool isVirtual() const override;
bool addPreInvariant() override;
bool addPostInvariant() override;
// 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;
}
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;
// 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))
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++)
{
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;
}
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,
// 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[]
Modules aimports; // all imported modules
- uint debuglevel; // debug level
Identifiers* debugids; // debug identifiers
Identifiers* debugidsNot; // forward referenced debug identifiers
- uint versionlevel; // version level
Identifiers* versionids; // version identifiers
Identifiers* versionidsNot; // forward referenced version identifiers
OutBuffer buf;
if (m.filetype == FileType.ddoc)
{
- const ploc = m.md ? &m.md.loc : &m.loc;
- Loc loc = *ploc;
- if (!loc.filename)
- loc.filename = srcfilename.ptr;
+ Loc loc = m.md ? m.md.loc : m.loc;
size_t commentlen = m.comment ? strlen(cast(char*)m.comment) : 0;
Dsymbols a;
}
else
{
- /* We just want the identifier, not overloads like TemplateDeclaration::toChars.
- * We don't want the template parameter list and constraints. */
- buf.writestring(s.Dsymbol.toChars());
+ buf.writestring(s.ident ? s.ident.toString : "__anonymous");
}
return true;
}
}
else
{
- auto symbolName = ident.toString();
+ // buf.writestring("<<<");
+ // buf.writestring(typeof(ident).stringof);
+ // buf.writestring(">>>");
+ // auto symbolName = ident.toString();
+ auto symbolName = ident.toChars().toDString();
buf.printf("$(%.*s %.*s", cast(int) macroName.length, macroName.ptr,
cast(int) symbolName.length, symbolName.ptr);
/****************************************************
*/
-Parameter isEponymousFunctionParameter(Dsymbols *a, const(char)[] p) @safe
+Parameter isEponymousFunctionParameter(Dsymbols* a, const(char)[] p) @safe
{
foreach (Dsymbol dsym; *a)
{
auto id = Identifier.lookup(ids[0].ptr, ids[0].length);
if (id)
{
- auto loc = Loc();
+ auto loc = Loc.initial;
Dsymbol pscopesym;
auto symbol = _scope.search(loc, id, pscopesym, SearchOpt.ignoreErrors);
for (size_t i = 1; symbol && i < ids.length; ++i)
*/
void highlightText(Scope* sc, Dsymbols* a, Loc loc, ref OutBuffer buf, size_t offset)
{
- const incrementLoc = loc.linnum == 0 ? 1 : 0;
- loc.linnum = loc.linnum + incrementLoc;
- loc.charnum = 0;
+ loc.nextLine();
+
//printf("highlightText()\n");
bool leadingBlank = true;
size_t iParagraphStart = offset;
lineQuoted = false;
tableRowDetected = false;
iLineStart = i + 1;
- loc.linnum = loc.linnum + incrementLoc;
+ loc.nextLine();
// update the paragraph start if we just entered a macro
if (previousMacroLevel < macroLevel && iParagraphStart < iLineStart)
import dmd.common.outbuffer;
/***************************************
- * Calls dg(Dsymbol *sym) for each Dsymbol.
+ * Calls dg(Dsymbol* sym) for each Dsymbol.
* If dg returns !=0, stops and returns that value else returns 0.
* Params:
* symbols = Dsymbols
}
/***************************************
- * Calls dg(Dsymbol *sym) for each Dsymbol.
+ * Calls dg(Dsymbol* sym) for each Dsymbol.
* Params:
* symbols = Dsymbols
* dg = delegate to call for each Dsymbol
return new Dsymbol(ident);
}
- override const(char)* toChars() const
+ final override const(char)* toChars() const
{
- return ident ? ident.toChars() : "__anonymous";
+ import dmd.hdrgen : toChars;
+ return toChars(this);
}
// Getters / setters for fields stored in `DsymbolAttributes`
PASS semanticRun;
unsigned short localNum; // perturb mangled name to avoid collisions with those in FuncDeclaration.localsymtab
static Dsymbol *create(Identifier *);
- const char *toChars() const override;
+ const char *toChars() const final override;
DeprecatedDeclaration* depdecl();
CPPNamespaceDeclaration* cppnamespace();
UserAttributeDeclaration* userAttribDecl();
}
// Save the scope and defer semantic analysis on the Dsymbol.
-void deferDsymbolSemantic(Scope* sc, Dsymbol s, Scope *scx)
+void deferDsymbolSemantic(Scope* sc, Dsymbol s, Scope* scx)
{
s._scope = scx ? scx : sc.copy();
s._scope.setNoFree();
Module m = sds.isModule();
// Do not add the member to the symbol table,
// just make sure subsequent debug declarations work.
- if (ds.ident)
+ if (!m)
{
- if (!m)
- {
- .error(ds.loc, "%s `%s` declaration must be at module level", ds.kind, ds.toPrettyChars);
- ds.errors = true;
- }
- else
- {
- if (m.debugidsNot && findCondition(*m.debugidsNot, ds.ident))
- {
- .error(ds.loc, "%s `%s` defined after use", ds.kind, ds.toPrettyChars);
- ds.errors = true;
- }
- if (!m.debugids)
- m.debugids = new Identifiers();
- m.debugids.push(ds.ident);
- }
+ .error(ds.loc, "%s `%s` declaration must be at module level", ds.kind, ds.toPrettyChars);
+ ds.errors = true;
}
else
{
- if (!m)
+ if (m.debugidsNot && findCondition(*m.debugidsNot, ds.ident))
{
- .error(ds.loc, "%s `%s` level declaration must be at module level", ds.kind, ds.toPrettyChars);
+ .error(ds.loc, "%s `%s` defined after use", ds.kind, ds.toPrettyChars);
ds.errors = true;
}
- else
- m.debuglevel = ds.level;
+ if (!m.debugids)
+ m.debugids = new Identifiers();
+ m.debugids.push(ds.ident);
}
}
Module m = sds.isModule();
// Do not add the member to the symbol table,
// just make sure subsequent debug declarations work.
- if (vs.ident)
+ VersionCondition.checkReserved(vs.loc, vs.ident.toString());
+ if (!m)
{
- VersionCondition.checkReserved(vs.loc, vs.ident.toString());
- if (!m)
- {
- .error(vs.loc, "%s `%s` declaration must be at module level", vs.kind, vs.toPrettyChars);
- vs.errors = true;
- }
- else
- {
- if (m.versionidsNot && findCondition(*m.versionidsNot, vs.ident))
- {
- .error(vs.loc, "%s `%s` defined after use", vs.kind, vs.toPrettyChars);
- vs.errors = true;
- }
- if (!m.versionids)
- m.versionids = new Identifiers();
- m.versionids.push(vs.ident);
- }
+ .error(vs.loc, "%s `%s` declaration must be at module level", vs.kind, vs.toPrettyChars);
+ vs.errors = true;
}
else
{
- if (!m)
+ if (m.versionidsNot && findCondition(*m.versionidsNot, vs.ident))
{
- .error(vs.loc, "%s `%s` level declaration must be at module level", vs.kind, vs.toPrettyChars);
+ .error(vs.loc, "%s `%s` defined after use", vs.kind, vs.toPrettyChars);
vs.errors = true;
}
- else
- m.versionlevel = vs.level;
+ if (!m.versionids)
+ m.versionids = new Identifiers();
+ m.versionids.push(vs.ident);
}
+
}
override void visit(Nspace ns)
import dmd.errors;
import dmd.errorsink;
import dmd.expression;
-import dmd.expressionsem : resolveLoc, expressionSemantic, resolveProperties;
+import dmd.expressionsem : resolveLoc, expressionSemantic, resolveProperties, checkValue;
import dmd.func;
import dmd.funcsem : functionSemantic, leastAsSpecialized, overloadApply;
import dmd.globals;
return (onemember && onemember.isAggregateDeclaration()) ? onemember.kind() : "template";
}
- override const(char)* toChars() const
- {
- HdrGenState hgs;
- OutBuffer buf;
- toCharsMaybeConstraints(this, buf, hgs);
- return buf.extractChars();
- }
-
/****************************
* Similar to `toChars`, but does not print the template constraints
*/
return true;
}
- override const(char)* toChars() const
- {
- OutBuffer buf;
- toCBufferInstance(this, buf);
- return buf.extractChars();
- }
-
override final const(char)* toPrettyCharsHelper()
{
OutBuffer buf;
return members.foreachDsymbol( (s) { return s.hasPointers(); } ) != 0;
}
- override const(char)* toChars() const
- {
- OutBuffer buf;
- toCBufferInstance(this, buf);
- return buf.extractChars();
- }
-
extern (D) bool findTempDecl(Scope* sc)
{
// Follow qualifications to find the TemplateDeclaration
/***********************************************************
* DebugSymbol's happen for statements like:
* debug = identifier;
- * debug = integer;
*/
extern (C++) final class DebugSymbol : Dsymbol
{
- uint level;
-
extern (D) this(const ref Loc loc, Identifier ident) @safe
{
super(loc, ident);
}
- extern (D) this(const ref Loc loc, uint level) @safe
+ extern (D) this(const ref Loc loc) @safe
{
super(loc, null);
- this.level = level;
}
override DebugSymbol syntaxCopy(Dsymbol s)
assert(!s);
auto ds = new DebugSymbol(loc, ident);
ds.comment = comment;
- ds.level = level;
return ds;
}
- override const(char)* toChars() const nothrow
- {
- if (ident)
- return ident.toChars();
- OutBuffer buf;
- buf.print(level);
- return buf.extractChars();
- }
-
override const(char)* kind() const nothrow
{
return "debug";
/***********************************************************
* VersionSymbol's happen for statements like:
* version = identifier;
- * version = integer;
*/
extern (C++) final class VersionSymbol : Dsymbol
{
- uint level;
extern (D) this(const ref Loc loc, Identifier ident) @safe
{
super(loc, ident);
}
- extern (D) this(const ref Loc loc, uint level) @safe
+ extern (D) this(const ref Loc loc) @safe
{
super(loc, null);
- this.level = level;
}
override VersionSymbol syntaxCopy(Dsymbol s)
{
assert(!s);
- auto ds = ident ? new VersionSymbol(loc, ident)
- : new VersionSymbol(loc, level);
+ auto ds = new VersionSymbol(loc, ident);
ds.comment = comment;
return ds;
}
- override const(char)* toChars() const nothrow
- {
- if (ident)
- return ident.toChars();
- OutBuffer buf;
- buf.print(level);
- return buf.extractChars();
- }
-
override const(char)* kind() const nothrow
{
return "version";
module dmd.errors;
-import core.stdc.stdarg;
+public import core.stdc.stdarg;
+public import dmd.root.string: fTuple;
import dmd.errorsink;
import dmd.globals;
import dmd.location;
* see verrorReport for arguments
* Returns: true if error handling is done, false to continue printing to stderr
*/
-alias DiagnosticHandler = bool delegate(const ref Loc location, Color headerColor, const(char)* header, const(char)* messageFormat, va_list args, const(char)* prefix1, const(char)* prefix2);
+alias DiagnosticHandler = bool delegate(const ref SourceLoc location, Color headerColor, const(char)* header, const(char)* messageFormat, va_list args, const(char)* prefix1, const(char)* prefix2);
/**
* The diagnostic handler.
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);
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;
Loc loc; // file location
const EXP op; // to minimize use of dynamic_cast
- bool parens; // if this is a parenthesized expression
- bool rvalue; // true if this is considered to be an rvalue, even if it is an lvalue
+
+ static struct BitFields
+ {
+ bool parens; // if this is a parenthesized expression
+ bool rvalue; // true if this is considered to be an rvalue, even if it is an lvalue
+ }
+ import dmd.common.bitfields;
+ mixin(generateBitFields!(BitFields, ubyte));
extern (D) this(const ref Loc loc, EXP op) scope @safe
{
return DYNCAST.expression;
}
- override const(char)* toChars() const
+ final override const(char)* toChars() const
{
+ // FIXME: Test suite relies on lambda's being printed as __lambdaXXX in errors and .stringof
+ // Printing a (truncated) lambda body is more user friendly
+ if (auto fe = isFuncExp())
+ return fe.fd.toChars();
+
return .toChars(this);
}
return false;
}
- /****************************************
- * Check that the expression has a valid value.
- * If not, generates an error "... has no value".
- * Returns:
- * true if the expression is not valid or has void type.
- */
- bool checkValue()
- {
- if (type && type.toBasetype().ty == Tvoid)
- {
- error(loc, "expression `%s` is `void` and has no value", toChars());
- //print(); assert(0);
- if (!global.gag)
- type = Type.terror;
- return true;
- }
- return false;
- }
-
/******************************
* Take address of expression.
*/
*/
extern (C++) final class StructLiteralExp : Expression
{
+ struct BitFields
+ {
+ bool useStaticInit; /// if this is true, use the StructDeclaration's init symbol
+ bool isOriginal = false; /// used when moving instances to indicate `this is this.origin`
+ OwnedBy ownedByCtfe = OwnedBy.code;
+ }
+ import dmd.common.bitfields;
+ mixin(generateBitFields!(BitFields, ubyte));
+ StageFlags stageflags;
+
StructDeclaration sd; /// which aggregate this is for
Expressions* elements; /// parallels sd.fields[] with null entries for fields to skip
Type stype; /// final type of result (can be different from sd's type)
inlineScan = 0x10, /// inlineScan is running
toCBuffer = 0x20 /// toCBuffer is running
}
- StageFlags stageflags;
-
- bool useStaticInit; /// if this is true, use the StructDeclaration's init symbol
- bool isOriginal = false; /// used when moving instances to indicate `this is this.origin`
- OwnedBy ownedByCtfe = OwnedBy.code;
extern (D) this(const ref Loc loc, StructDeclaration sd, Expressions* elements, Type stype = null) @safe
{
return true;
}
- override bool checkValue()
- {
- error(loc, "type `%s` has no value", toChars());
- return true;
- }
-
override void accept(Visitor v)
{
v.visit(this);
return false;
}
- override bool checkValue()
- {
- error(loc, "%s `%s` has no value", sds.kind(), sds.toChars());
- return true;
- }
-
override void accept(Visitor v)
{
v.visit(this);
return true;
}
- override bool checkValue()
- {
- error(loc, "%s `%s` has no value", td.kind(), toChars());
- return true;
- }
-
override void accept(Visitor v)
{
v.visit(this);
return new FuncExp(loc, fd);
}
- override const(char)* toChars() const
- {
- return fd.toChars();
- }
-
override bool checkType()
{
if (td)
return false;
}
- override bool checkValue()
- {
- if (td)
- {
- error(loc, "template lambda has no value");
- return true;
- }
- return false;
- }
-
override void accept(Visitor v)
{
v.visit(this);
return true;
}
- override bool checkValue()
- {
- error(loc, "%s `%s` has no value", td.kind(), toChars());
- return true;
- }
-
override void accept(Visitor v)
{
v.visit(this);
return false;
}
- override bool checkValue()
- {
- if (ti.tempdecl &&
- ti.semantictiargsdone &&
- ti.semanticRun == PASS.initial)
-
- error(loc, "partial %s `%s` has no value", ti.kind(), toChars());
- else
- error(loc, "%s `%s` has no value", ti.kind(), ti.toChars());
- return true;
- }
-
override void accept(Visitor v)
{
v.visit(this);
this.lowering = lowering;
}
- override const(char)* toChars() const
- {
- return lowering.toChars();
- }
override void accept(Visitor v)
{
v.visit(this);
type = Type.tvoid;
}
- override const(char)* toChars() const
- {
- switch (op)
- {
- case EXP.cantExpression:
- return "<cant>";
- case EXP.voidExpression:
- return "cast(void)0";
- case EXP.showCtfeContext:
- return "<error>";
- case EXP.break_:
- return "<break>";
- case EXP.continue_:
- return "<continue>";
- case EXP.goto_:
- return "<goto>";
- default:
- assert(0);
- }
- }
-
extern (D) __gshared CTFEExp cantexp;
extern (D) __gshared CTFEExp voidexp;
extern (D) __gshared CTFEExp breakexp;
this.type = victim.type;
}
- override const(char)* toChars() const
- {
- return "CTFE ThrownException";
- }
-
override void accept(Visitor v)
{
v.visit(this);
Type *type; // !=NULL means that semantic() has been run
Loc loc; // file location
EXP op; // to minimize use of dynamic_cast
- d_bool parens; // if this is a parenthesized expression
- d_bool rvalue; // consider this an rvalue, even if it is an lvalue
+ uint8_t bitFields;
+
+ bool parens() const;
+ bool parens(bool v);
+ bool rvalue() const;
+ bool rvalue(bool v);
size_t size() const;
static void _init();
// kludge for template.isExpression()
DYNCAST dyncast() const override final { return DYNCAST_EXPRESSION; }
- const char *toChars() const override;
+ const char* toChars() const final override;
virtual dinteger_t toInteger();
virtual uinteger_t toUInteger();
virtual StringExp *toStringExp();
virtual bool isLvalue();
virtual bool checkType();
- virtual bool checkValue();
Expression *addressOf();
Expression *deref();
class StructLiteralExp final : public Expression
{
public:
+ uint8_t bitFields;
+
+ // if this is true, use the StructDeclaration's init symbol
+ bool useStaticInit() const;
+ bool useStaticInit(bool v);
+ // used when moving instances to indicate `this is this.origin`
+ bool isOriginal() const;
+ bool isOriginal(bool v);
+ OwnedBy ownedByCtfe() const;
+ OwnedBy ownedByCtfe(OwnedBy v);
+
+ /** anytime when recursive function is calling, 'stageflags' marks with bit flag of
+ * current stage and unmarks before return from this function.
+ * 'inlinecopy' uses similar 'stageflags' and from multiple evaluation 'doInline'
+ * (with infinite recursion) of this expression.
+ */
+ uint8_t stageflags;
+
StructDeclaration *sd; // which aggregate this is for
Expressions *elements; // parallels sd->fields[] with NULL entries for fields to skip
Type *stype; // final type of result (can be different from sd's type)
StructLiteralExp *origin;
- /** anytime when recursive function is calling, 'stageflags' marks with bit flag of
- * current stage and unmarks before return from this function.
- * 'inlinecopy' uses similar 'stageflags' and from multiple evaluation 'doInline'
- * (with infinite recursion) of this expression.
- */
- uint8_t stageflags;
-
- d_bool useStaticInit; // if this is true, use the StructDeclaration's init symbol
- d_bool isOriginal; // used when moving instances to indicate `this is this.origin`
- OwnedBy ownedByCtfe;
-
static StructLiteralExp *create(const Loc &loc, StructDeclaration *sd, void *elements, Type *stype = nullptr);
bool equals(const RootObject * const o) const override;
StructLiteralExp *syntaxCopy() override;
public:
TypeExp *syntaxCopy() override;
bool checkType() override;
- bool checkValue() override;
void accept(Visitor *v) override { v->visit(this); }
};
ScopeExp *syntaxCopy() override;
bool checkType() override;
- bool checkValue() override;
void accept(Visitor *v) override { v->visit(this); }
};
bool isLvalue() override;
bool checkType() override;
- bool checkValue() override;
void accept(Visitor *v) override { v->visit(this); }
};
bool equals(const RootObject * const o) const override;
FuncExp *syntaxCopy() override;
- const char *toChars() const override;
bool checkType() override;
- bool checkValue() override;
void accept(Visitor *v) override { v->visit(this); }
};
TemplateDeclaration *td;
bool checkType() override;
- bool checkValue() override;
void accept(Visitor *v) override { v->visit(this); }
};
DotTemplateInstanceExp *syntaxCopy() override;
bool checkType() override;
- bool checkValue() override;
void accept(Visitor *v) override { v->visit(this); }
};
public:
Expression *lowering;
- const char *toChars() const override;
void accept(Visitor *v) override { v->visit(this); }
};
* Returns:
* String literal, or `null` if error happens.
*/
-StringExp semanticString(Scope *sc, Expression exp, const char* s)
+StringExp semanticString(Scope* sc, Expression exp, const char* s)
{
sc = sc.startCTFE();
exp = exp.expressionSemantic(sc);
* Returns:
* ErrorExp
*/
-extern (D) Expression incompatibleTypes(BinExp e)
+extern (D) Expression incompatibleTypes(BinExp e, Scope* sc = null)
{
if (e.e1.type.toBasetype() == Type.terror)
return e.e1;
// CondExp uses 'a ? b : c' but we're comparing 'b : c'
const(char)* thisOp = (e.op == EXP.question) ? ":" : EXPtoString(e.op).ptr;
+
+ if (sc && suggestBinaryOverloads(e, sc))
+ return ErrorExp.get();
+
if (e.e1.op == EXP.type || e.e2.op == EXP.type)
{
error(e.loc, "incompatible types for `(%s) %s (%s)`: cannot use `%s` with types",
* Runs semantic on ae.arguments. Declares temporary variables
* if '$' was used.
*/
-Expression resolveOpDollar(Scope* sc, ArrayExp ae, Expression* pe0)
+Expression resolveOpDollar(Scope* sc, ArrayExp ae, out Expression pe0)
{
assert(!ae.lengthVar);
- *pe0 = null;
AggregateDeclaration ad = isAggregate(ae.e1.type);
Dsymbol slice = search_function(ad, Id.opSlice);
//printf("slice = %s %s\n", slice.kind(), slice.toChars());
foreach (i, e; *ae.arguments)
{
if (i == 0)
- *pe0 = extractOpDollarSideEffect(sc, ae);
+ pe0 = extractOpDollarSideEffect(sc, ae);
if (e.op == EXP.interval && !(slice && slice.isTemplateDeclaration()))
{
// If $ was used, declare it now
Expression de = new DeclarationExp(ae.loc, ae.lengthVar);
de = de.expressionSemantic(sc);
- *pe0 = Expression.combine(*pe0, de);
+ pe0 = Expression.combine(pe0, de);
}
sc = sc.pop();
if (!fslice)
return fallback();
- e = new DotTemplateInstanceExp(ae.loc, ae.e1, slice.ident, tiargs);
+ e = new DotTemplateInstanceExp(ae.loc, ae.e1, Id.opSlice, tiargs);
e = new CallExp(ae.loc, e, fargs);
e = e.expressionSemantic(sc);
}
* Returns:
* ae, or ErrorExp if errors occurred
*/
-Expression resolveOpDollar(Scope* sc, ArrayExp ae, IntervalExp ie, Expression* pe0)
+Expression resolveOpDollar(Scope* sc, ArrayExp ae, IntervalExp ie, ref Expression pe0)
{
//assert(!ae.lengthVar);
if (!ie)
// If $ was used, declare it now
Expression de = new DeclarationExp(ae.loc, ae.lengthVar);
de = de.expressionSemantic(sc);
- *pe0 = Expression.combine(*pe0, de);
+ pe0 = Expression.combine(pe0, de);
}
sc = sc.pop();
* Returns:
* The expression that copy constructs or moves the value.
*/
-extern (D) Expression doCopyOrMove(Scope *sc, Expression e, Type t, bool nrvo, bool move = false)
+extern (D) Expression doCopyOrMove(Scope* sc, Expression e, Type t, bool nrvo, bool move = false)
{
//printf("doCopyOrMove() %s\n", toChars(e));
StructDeclaration sd;
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()
* Returns:
* `s` turned into an expression, `ErrorExp` if an error occurred
*/
-Expression symbolToExp(Dsymbol s, const ref Loc loc, Scope *sc, bool hasOverloads)
+Expression symbolToExp(Dsymbol s, const ref Loc loc, Scope* sc, bool hasOverloads)
{
static if (LOGSEMANTIC)
{
if (isRootTraitsCompilesScope(sc) ? !sc.func.isNogcBypassingInference() : !sc.func.setGCCall(f))
return false;
- if (loc.linnum == 0) // e.g. implicitly generated dtor
+ if (loc == Loc.initial) // e.g. implicitly generated dtor
loc = sc.func.loc;
// Lowered non-@nogc'd hooks will print their own error message inside of nogc.d (NOGCVisitor.visit(CallExp e)),
}
/********************************************
- * Check that the postblit is callable if t is an array of structs.
- * Returns true if error happens.
+ * Check that the postblit of `t` isn't @disabled and has the right
+ * function attributes for this scope.
+ *
+ * Params:
+ * t = struct type, or static array of struct type to check
+ * loc = error message location
+ * sc = scope in which attributes are checked
+ * Returns: true if there's an error
*/
private bool checkPostblit(Type t, ref Loc loc, Scope* sc)
{
return true;
//checkDeprecated(sc, sd.postblit); // necessary?
- sd.postblit.checkPurity(loc, sc);
- sd.postblit.checkSafety(loc, sc);
- sd.postblit.checkNogc(loc, sc);
//checkAccess(sd, loc, sc, sd.postblit); // necessary?
- return false;
-
+ bool result = false;
+ result |= sd.postblit.checkPurity(loc, sc);
+ result |= sd.postblit.checkSafety(loc, sc);
+ result |= sd.postblit.checkNogc(loc, sc);
+ return result;
}
/***************************************
// See tryAliasThisSemantic
Type[2] aliasThisStop;
+ // (Optional) the expression this was lowered from, for better error messages
+ Expression parent;
+
this(Scope* sc) scope @safe
{
this.sc = sc;
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();
exp.e1 = exp.e1.optimize(WANTvalue, /*keepLvalue*/ true);
exp.type = exp.e1.type;
- if (auto ad = isAggregate(exp.e1.type))
- {
- if (const s = search_function(ad, Id.opOpAssign))
- {
- error(exp.loc, "none of the `opOpAssign` overloads of `%s` are callable for `%s` of type `%s`", ad.toChars(), exp.e1.toChars(), exp.e1.type.toChars());
- return setError();
- }
- }
- if (exp.e1.checkScalar() ||
+ if (exp.suggestOpOpAssign(sc, parent) ||
+ exp.e1.checkScalar() ||
exp.e1.checkReadModifyWrite(exp.op, exp.e2) ||
exp.e1.checkSharedAccess(sc))
return setError();
result = (cast(BinExp)e).reorderSettingAAElem(sc);
}
- private Expression compileIt(MixinExp exp, Scope *sc)
+ private Expression compileIt(MixinExp exp, Scope* sc)
{
OutBuffer buf;
if (expressionsToString(buf, sc, exp.exps, exp.loc, null, true))
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))
{
result = exp.incompatibleTypes();
return;
}
- if (exp.e1.checkNoBool())
- return setError();
- if (exp.e1.checkArithmetic(exp.op) ||
+ if (exp.e1.checkNoBool() ||
+ exp.e1.checkArithmetic(exp.op) ||
exp.e1.checkSharedAccess(sc))
return setError();
result = exp.incompatibleTypes();
return;
}
- if (exp.e1.checkNoBool())
- return setError();
- if (exp.e1.checkArithmetic(exp.op))
- return setError();
- if (exp.e1.checkSharedAccess(sc))
+
+ if (exp.e1.checkNoBool() ||
+ exp.e1.checkArithmetic(exp.op) ||
+ exp.e1.checkSharedAccess(sc))
return setError();
result = exp.e1;
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))
{
result = exp.incompatibleTypes();
return;
}
- if (exp.e1.checkNoBool())
- return setError();
- if (exp.e1.checkIntegral() ||
+ if (exp.e1.checkNoBool() ||
+ exp.e1.checkIntegral() ||
exp.e1.checkSharedAccess(sc))
return setError();
}
}
- if (!t1b.equals(tob) && (t1b.ty == Tarray || t1b.ty == Tsarray))
+ if (!t1b.equals(tob) && t1b.isStaticOrDynamicArray())
{
if (checkNonAssignmentArrayOp(exp.e1))
return setError();
/* 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);
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);
if (auto ad = isAggregate(exp.e1.type))
{
- error(exp.loc, "no `[]` operator overload for type `%s`", exp.e1.type.toChars());
- errorSupplemental(ad.loc, "`%s` declared here", ad.toPrettyChars());
+ if (exp.arguments.length == 0)
+ {
+ error(exp.loc, "no `[]` operator overload for type `%s`", exp.e1.type.toChars());
+ errorSupplemental(ad.loc, "perhaps define `auto opIndex() {}` for `%s`", ad.toPrettyChars());
+ }
+ else
+ {
+ const(char)* typeString(Expression exp)
+ {
+ if (auto e = exp.trySemantic(sc))
+ return e.type.toChars();
+ else
+ return "__error__";
+ }
+
+ if (auto ie = (*exp.arguments)[0].isIntervalExp())
+ {
+ error(exp.loc, "no `[%s]` operator overload for type `%s`", ie.toChars(), exp.e1.type.toChars());
+ errorSupplemental(ad.loc, "perhaps define `auto opSlice(%s lower, %s upper) {}` for `%s`",
+ typeString(ie.lwr), typeString(ie.upr), ad.toPrettyChars());
+ }
+ else
+ {
+ OutBuffer buf;
+ buf.printf("%s", typeString((*exp.arguments)[0]));
+ foreach (e; (*exp.arguments)[1 .. $])
+ buf.printf(", %s", typeString(e));
+
+ error(exp.loc, "no `[]` operator overload for type `%s`", exp.e1.type.toChars());
+ errorSupplemental(ad.loc, "perhaps define `auto opIndex(%s) {}` for `%s`",
+ buf.extractChars, ad.toPrettyChars());
+ }
+ }
}
else if (exp.e1.op == EXP.type && exp.e1.type.ty != Ttuple)
error(exp.loc, "static array of `%s` with multiple lengths not allowed", exp.e1.type.toChars());
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();
/* 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);
// 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);
e = new AddAssignExp(exp.loc, exp.e1, IntegerExp.literal!1);
else
e = new MinAssignExp(exp.loc, exp.e1, IntegerExp.literal!1);
- result = e.expressionSemantic(sc);
+ result = e.expressionSemanticWithParent(sc, exp);
}
/*
if (search_function(ad, Id.opIndexAssign))
{
// Deal with $
- res = resolveOpDollar(sc, ae, &e0);
+ res = resolveOpDollar(sc, ae, e0);
if (!res) // a[i..j] = e2 might be: a.opSliceAssign(e2, i, j)
goto Lfallback;
if (res.op == EXP.error)
if (maybeSlice && search_function(ad, Id.opSliceAssign))
{
// Deal with $
- res = resolveOpDollar(sc, ae, ie, &e0);
+ res = resolveOpDollar(sc, ae, ie, e0);
if (res.op == EXP.error)
return setResult(res);
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.
}
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()))
/* 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 &&
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) &&
return;
}
- if (exp.e1.checkReadModifyWrite(exp.op, exp.e2))
+ if (exp.suggestOpOpAssign(sc, parent) ||
+ exp.e1.checkReadModifyWrite(exp.op, exp.e2))
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();
// 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()))
{
return;
}
+ if (exp.suggestOpOpAssign(sc, parent))
+ return setError();
+
if (SliceExp se = exp.e1.isSliceExp())
{
if (se.e1.type.toBasetype().ty == Tsarray)
* 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)[]
}
Type tb = exp.type.toBasetype();
- if (tb.ty == Tarray || tb.ty == Tsarray)
+ if (tb.isStaticOrDynamicArray())
{
if (!isArrayOpValid(exp))
{
return;
}
- if (exp.checkArithmeticBin())
+ if (exp.suggestBinaryOverloads(sc) || exp.checkArithmeticBin())
return setError();
tb1 = exp.e1.type.toBasetype();
}
Type tb = exp.type.toBasetype();
- if (tb.ty == Tarray || tb.ty == Tsarray)
+ if (tb.isStaticOrDynamicArray())
{
if (!isArrayOpValid(exp))
{
return;
}
- if (exp.checkArithmeticBin())
+ if (exp.suggestBinaryOverloads(sc) || exp.checkArithmeticBin())
return setError();
t1 = exp.e1.type.toBasetype();
return result;
}
- void handleCatArgument(Expressions *arguments, Expression e, Type catType, bool isRightArg)
+ void handleCatArgument(Expressions* arguments, Expression e, Type catType, bool isRightArg)
{
auto tb = e.type.toBasetype();
}
// 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)
{
}
}
// 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)
{
}
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();
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);
trySetCatExpLowering(result);
}
- bool commonBinOpSemantic(BinExp exp)
+ bool commonArithBinOpSemantic(BinExp exp)
{
if (Expression e = exp.opOverloadBinary(sc, aliasThisStop))
{
result = ex;
return true;
}
- return false;
- }
- bool commonArithBinOpSemantic(BinExp exp)
- {
- if (commonBinOpSemantic(exp))
- return true;
Type tb = exp.type.toBasetype();
- if (tb.ty == Tarray || tb.ty == Tsarray)
+ if (tb.isStaticOrDynamicArray())
{
if (!isArrayOpValid(exp))
{
return true;
}
- if (exp.checkArithmeticBin() || exp.checkSharedAccessBin(sc))
+ if (exp.suggestBinaryOverloads(sc) || exp.checkArithmeticBin() || exp.checkSharedAccessBin(sc))
{
setError();
return true;
return;
}
- if (exp.checkIntegralBin() || exp.checkSharedAccessBin(sc))
+ if (exp.suggestBinaryOverloads(sc) || exp.checkIntegralBin() || exp.checkSharedAccessBin(sc))
return setError();
if (!target.isVectorOpSupported(exp.e1.type.toBasetype(), exp.op, exp.e2.type.toBasetype()))
}
Type tb = exp.type.toBasetype();
- if (tb.ty == Tarray || tb.ty == Tsarray)
+ if (tb.isStaticOrDynamicArray())
{
if (!isArrayOpValid(exp))
{
result = exp.incompatibleTypes();
return;
}
- if (exp.checkIntegralBin() || exp.checkSharedAccessBin(sc))
+
+ if (exp.suggestBinaryOverloads(sc) || exp.checkIntegralBin() || exp.checkSharedAccessBin(sc))
return setError();
result = exp;
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();
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();
arrayLowering = al;
}
}
- else if (t1.ty == Tstruct || t2.ty == Tstruct || (t1.ty == Tclass && t2.ty == Tclass))
+ else if (t1.isTypeClass() && t2.isTypeClass())
{
- if (t2.ty == Tstruct)
- error(exp.loc, "need member function `opCmp()` for %s `%s` to compare", t2.toDsymbol(sc).kind(), t2.toChars());
- else
- error(exp.loc, "need member function `opCmp()` for %s `%s` to compare", t1.toDsymbol(sc).kind(), t1.toChars());
+ error(exp.loc, "need member function `opCmp()` for %s `%s` to compare", t1.toDsymbol(sc).kind(), t1.toChars());
return setError();
}
else if (t1.isComplex() || t2.isComplex())
return setError();
case Tarray, Tsarray:
- result = exp.incompatibleTypes();
+ result = exp.incompatibleTypes(sc);
errorSupplemental(exp.loc, "`in` is only allowed on associative arrays");
const(char)* slice = (t2b.ty == Tsarray) ? "[]" : "";
errorSupplemental(exp.loc, "perhaps use `std.algorithm.find(%s, %s%s)` instead",
return;
default:
- result = exp.incompatibleTypes();
+ result = exp.incompatibleTypes(sc);
return;
}
result = exp;
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)
return v.result;
}
+// ditto, but with `parent` parameter that represents the expression before rewriting.
+// This way, when lowering an expression (e.g. i++ to i+=1), error messages can still
+// refer to the original expression.
+private Expression expressionSemanticWithParent(Expression e, Scope* sc, Expression parent)
+{
+ if (e.expressionSemanticDone)
+ return e;
+
+ scope v = new ExpressionSemanticVisitor(sc);
+ v.parent = parent;
+ e.accept(v);
+ return v.result;
+}
+
private Expression dotIdSemanticPropX(DotIdExp exp, Scope* sc)
{
//printf("dotIdSemanticPropX() %s\n", toChars(exp));
{
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"
return true;
}
- // FIXME: Existing code relies on adding / subtracting types in typeof() expressions:
- // alias I = ulong; alias U = typeof(I + 1u);
- // https://github.com/dlang/dmd/issues/20763
- if (op == EXP.add || op == EXP.min)
+ if ((op == EXP.add || op == EXP.min) && e.isTypeExp())
+ {
+ // @@@DEPRECATED_2.121@@@
+ // Deprecated in 2.111
+ // In 2.121, remove this branch to let `checkValue` raise the error
+ deprecation(e.loc, "type `%s` has no value", e.toChars);
+ if (!e.type.isOpaqueType)
+ deprecationSupplemental(e.loc, "perhaps use `%s.init`", e.toChars);
return false;
+ }
return e.checkValue();
}
return (e.e1.checkArithmetic(e.op) || e.e2.checkArithmetic(e.op));
}
+/****************************************
+ * Check that the expression has a valid value.
+ * If not, generates an error "... has no value".`
+ *
+ * Params:
+ * e = expression to check
+ *
+ * Returns:
+ * `true` if the expression is not valid or has `void` type.
+ */
+bool checkValue(Expression e)
+{
+ if (auto te = e.isTypeExp())
+ {
+ error(e.loc, "type `%s` has no value", e.toChars());
+ if (!e.type.isOpaqueType)
+ errorSupplemental(e.loc, "perhaps use `%s.init`", e.toChars());
+ return true;
+ }
+
+ if (auto dtie = e.isDotTemplateInstanceExp())
+ {
+ if (dtie.ti.tempdecl &&
+ dtie.ti.semantictiargsdone &&
+ dtie.ti.semanticRun == PASS.initial)
+
+ error(e.loc, "partial %s `%s` has no value", dtie.ti.kind(), e.toChars());
+ else
+ error(e.loc, "%s `%s` has no value", dtie.ti.kind(), dtie.ti.toChars());
+ return true;
+ }
+
+ if (auto se = e.isScopeExp())
+ {
+ error(e.loc, "%s `%s` has no value", se.sds.kind(), se.sds.toChars());
+ return true;
+ }
+
+ if (auto te = e.isTemplateExp())
+ {
+ error(e.loc, "%s `%s` has no value", te.td.kind(), te.toChars());
+ return true;
+ }
+
+ if (auto fe = e.isFuncExp())
+ {
+ if (fe.td)
+ {
+ error(e.loc, "template lambda has no value");
+ return true;
+ }
+ return false;
+ }
+
+ if (auto dte = e.isDotTemplateExp())
+ {
+ error(e.loc, "%s `%s` has no value", dte.td.kind(), e.toChars());
+ return true;
+ }
+
+ if (e.type && e.type.toBasetype().ty == Tvoid)
+ {
+ error(e.loc, "expression `%s` is `void` and has no value", e.toChars());
+ //print(); assert(0);
+ if (!global.gag)
+ e.type = Type.terror;
+ return true;
+ }
+ return false;
+}
+
/***************************************
* If expression is shared, check that we can access it.
* Give error message if not.
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);
if (scx.func == vthis.parent && scx.contract != Contract.none)
{
if (!(flag & ModifyFlags.noError))
- error(loc, "%s `%s` cannot modify parameter `this` in contract", d.kind, d.toPrettyChars);
+ error(loc, "cannot modify member variable `%s` in contract", d.toPrettyChars());
return Modifiable.initialization; // do not report type related errors
}
}
/// Sibling nested functions which called this one
FuncDeclarations siblingCallers;
- FuncDeclarations *inlinedNestedCallees;
+ FuncDeclarations* inlinedNestedCallees;
/// In case of failed `@safe` inference, store the error that made the function `@system` for
/// better diagnostics
return isCpCtor ? "copy constructor" : "constructor";
}
- override const(char)* toChars() const
- {
- return "this";
- }
-
override bool isVirtual() const
{
return false;
return "destructor";
}
- override const(char)* toChars() const
- {
- return "~this";
- }
-
override bool isVirtual() const
{
// D dtor's don't get put into the vtbl[]
Output mixinOut; // write expanded mixins for debugging
Output moduleDeps; // Generate `.deps` module dependencies
- uint debuglevel; // debug level
- uint versionlevel; // version level
+ bool debugEnabled; // Global -debug flag (no -debug=XXX) is active
bool run; // run resulting executable
Strings runargs; // arguments for executable
Output mixinOut; // write expanded mixins for debugging
Output moduleDeps; // Generate `.deps` module dependencies
- unsigned debuglevel; // debug level
- unsigned versionlevel; // version level
+ d_bool debugEnabled; // -debug flag is passed
d_bool run; // run resulting executable
Strings runargs; // arguments for executable
return buf.extractChars();
}
+public const(char)* toChars(const Dsymbol d)
+{
+ if (auto td = d.isTemplateDeclaration())
+ {
+ HdrGenState hgs;
+ OutBuffer buf;
+ toCharsMaybeConstraints(td, buf, hgs);
+ return buf.extractChars();
+ }
+
+ if (auto ti = d.isTemplateInstance())
+ {
+ OutBuffer buf;
+ toCBufferInstance(ti, buf);
+ return buf.extractChars();
+ }
+
+ if (auto tm = d.isTemplateMixin())
+ {
+ OutBuffer buf;
+ toCBufferInstance(tm, buf);
+ return buf.extractChars();
+ }
+
+ if (auto tid = d.isTypeInfoDeclaration())
+ {
+ OutBuffer buf;
+ buf.writestring("typeid(");
+ buf.writestring(tid.tinfo.toChars());
+ buf.writeByte(')');
+ return buf.extractChars();
+ }
+
+ return d.ident ? d.ident.toHChars2() : "__anonymous";
+}
+
public const(char)[] toString(const Initializer i)
{
OutBuffer buf;
void visitDebugSymbol(DebugSymbol s)
{
buf.writestring("debug = ");
- if (s.ident)
- buf.writestring(s.ident.toString());
- else
- buf.print(s.level);
+ buf.writestring(s.ident.toString());
buf.writeByte(';');
buf.writenl();
}
void visitVersionSymbol(VersionSymbol s)
{
buf.writestring("version = ");
- if (s.ident)
- buf.writestring(s.ident.toString());
- else
- buf.print(s.level);
+ buf.writestring(s.ident.toString());
buf.writeByte(';');
buf.writenl();
}
buf.writestring(e.ident.toString());
}
- void visitDsymbol(DsymbolExp e)
+ void visitDsymbol(Dsymbol s)
+ {
+ // For -vcg-ast, print internal names such as __invariant, __ctor etc.
+ // This condition is a bit kludge, and can be cleaned up if the
+ // mutual dependency `AST.toChars <> hdrgen.d` gets refactored
+ if (hgs.vcg_ast && s.ident && !s.isTemplateInstance() && !s.isTemplateDeclaration())
+ buf.writestring(s.ident.toChars());
+ else
+ buf.writestring(s.toChars());
+ }
+
+ void visitDsymbolExp(DsymbolExp e)
{
- buf.writestring(e.s.toChars());
+ visitDsymbol(e.s);
}
void visitThis(ThisExp e)
void visitVar(VarExp e)
{
- buf.writestring(e.var.toChars());
+ visitDsymbol(e.var);
}
void visitOver(OverExp e)
{
expToBuffer(e.e1, PREC.primary, buf, hgs);
buf.writeByte('.');
- buf.writestring(e.var.toChars());
+ visitDsymbol(e.var);
}
void visitDotTemplateInstance(DotTemplateInstanceExp e)
case EXP.float64: return visitReal(e.isRealExp());
case EXP.complex80: return visitComplex(e.isComplexExp());
case EXP.identifier: return visitIdentifier(e.isIdentifierExp());
- case EXP.dSymbol: return visitDsymbol(e.isDsymbolExp());
+ case EXP.dSymbol: return visitDsymbolExp(e.isDsymbolExp());
case EXP.this_: return visitThis(e.isThisExp());
case EXP.super_: return visitSuper(e.isSuperExp());
case EXP.null_: return visitNull(e.isNullExp());
override void visit(DebugCondition c)
{
buf.writestring("debug (");
- if (c.ident)
- buf.writestring(c.ident.toString());
- else
- buf.print(c.level);
+ buf.writestring(c.ident.toString());
buf.writeByte(')');
}
override void visit(VersionCondition c)
{
buf.writestring("version (");
- if (c.ident)
- buf.writestring(c.ident.toString());
- else
- buf.print(c.level);
+ buf.writestring(c.ident.toString());
buf.writeByte(')');
}
EXP.declaration : "declaration",
EXP.interval : "interval",
- EXP.loweredAssignExp : "="
+ EXP.loweredAssignExp : "=",
+
+ EXP.thrownException : "CTFE ThrownException",
+ EXP.cantExpression : "<cant>",
+ EXP.voidExpression : "cast(void)0",
+ EXP.showCtfeContext : "<error>",
+ EXP.break_ : "<break>",
+ EXP.continue_ : "<continue>",
+ EXP.goto_ : "<goto>",
];
const p = strings[op];
if (!p)
/************************ AsmStatement ***************************************/
-Statement asmSemantic(AsmStatement s, Scope *sc)
+Statement asmSemantic(AsmStatement s, Scope* sc)
{
//printf("AsmStatement.semantic()\n");
/************************ CAsmDeclaration ************************************/
-void asmSemantic(CAsmDeclaration ad, Scope *sc)
+void asmSemantic(CAsmDeclaration ad, Scope* sc)
{
version (NoBackend)
{
* Returns:
* the completed gcc asm statement, or null if errors occurred
*/
-public Statement gccAsmSemantic(GccAsmStatement s, Scope *sc)
+public Statement gccAsmSemantic(GccAsmStatement s, Scope* sc)
{
//printf("GccAsmStatement.semantic()\n");
const bool doUnittests = global.params.parsingUnittestsRequired();
scope p = new Parser!ASTCodegen(sc._module, ";", false, global.errorSink, &global.compileEnv, doUnittests);
// Make a safe copy of the token list before parsing.
- Token *toklist = null;
+ Token* toklist = null;
Token **ptoklist = &toklist;
- for (Token *token = s.tokens; token; token = token.next)
+ for (Token* token = s.tokens; token; token = token.next)
{
*ptoklist = p.allocateToken();
memcpy(*ptoklist, token, Token.sizeof);
* ad = asm declaration
* sc = the scope where the asm declaration is located
*/
-public void gccAsmSemantic(CAsmDeclaration ad, Scope *sc)
+public void gccAsmSemantic(CAsmDeclaration ad, Scope* sc)
{
import dmd.typesem : pointerTo;
ad.code = semanticString(sc, ad.code, "asm definition");
* Returns:
* array of parsed clobber expressions
*/
-Expressions *parseExtAsmClobbers(Parser)(Parser p)
+Expressions* parseExtAsmClobbers(Parser)(Parser p)
{
- Expressions *clobbers;
+ Expressions* clobbers;
while (1)
{
* Returns:
* array of parsed goto labels
*/
-Identifiers *parseExtAsmGotoLabels(Parser)(Parser p)
+Identifiers* parseExtAsmGotoLabels(Parser)(Parser p)
{
- Identifiers *labels;
+ Identifiers* labels;
while (1)
{
const(char)* p = null;
if (this == Id.ctor)
p = "this";
- else if (this == Id.dtor)
+ else if (this == Id.dtor || this == Id.__xdtor || this == Id.__fieldDtor ||
+ this == Id.__aggrDtor || this == Id.cppdtor || this == Id.ticppdtor)
p = "~this";
else if (this == Id.unitTest)
p = "unittest";
p = "result";
else if (this == Id.returnLabel)
p = "return";
+ else if (this == Id.postblit)
+ p = "this(this)";
else
{
p = toChars();
* 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
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
}
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);
SignExtendedNumber opBinary(string op : "*")(SignExtendedNumber rhs)
{
- // perform *saturated* multiplication, otherwise we may get bogus ranges
+ // perform* saturated* multiplication, otherwise we may get bogus ranges
// like 0x10 * 0x10 == 0x100 == 0.
/* Special handling for zeros:
{
if (loc.isValid())
{
- if (auto filename = loc.filename.toDString)
+ SourceLoc sl = SourceLoc(loc);
+ if (sl.filename.length > 0 && sl.filename != this.filename)
{
- if (filename != this.filename)
- {
- this.filename = filename;
- property("file", filename);
- }
+ this.filename = sl.filename;
+ property("file", sl.filename);
}
- if (loc.linnum)
+
+ if (sl.linnum)
{
- property(linename, loc.linnum);
- if (loc.charnum)
- property(charname, loc.charnum);
+ property(linename, sl.linnum);
+ if (sl.charnum)
+ property(charname, sl.charnum);
}
}
}
return _linnum = num;
}
+ /// Advance this location to the first column of the next line
+ void nextLine()
+ {
+ if (this._linnum)
+ {
+ this._linnum++;
+ this.charnum = 0;
+ }
+ }
+
/***
* Returns: filename for this location, null if none
*/
bool showColumns = Loc.showColumns,
MessageStyle messageStyle = Loc.messageStyle) const nothrow
{
- OutBuffer buf;
- writeSourceLoc(buf, SourceLoc(this), showColumns, messageStyle);
- return buf.extractChars();
+ return SourceLoc(this).toChars(showColumns, messageStyle);
}
/**
*/
extern (C++) bool equals(ref const(Loc) loc) const
{
- return (!showColumns || charnum == loc.charnum) &&
- linnum == loc.linnum &&
- FileName.equals(filename, loc.filename);
+ SourceLoc lhs = SourceLoc(this);
+ SourceLoc rhs = SourceLoc(loc);
+ return (!showColumns || lhs.column == rhs.column) &&
+ lhs.line == rhs.line &&
+ FileName.equals(lhs.filename, rhs.filename);
}
/**
bool showColumns,
MessageStyle messageStyle) nothrow
{
+ if (loc.filename.length == 0)
+ return;
buf.writestring(loc.filename);
if (loc.line == 0)
return;
this.line = loc.linnum;
this.column = loc.charnum;
}
+
+ extern (C++) const(char)* toChars(
+ bool showColumns = Loc.showColumns,
+ MessageStyle messageStyle = Loc.messageStyle) const nothrow
+ {
+ OutBuffer buf;
+ writeSourceLoc(buf, this, showColumns, messageStyle);
+ return buf.extractChars();
+ }
+
+ bool opEquals(SourceLoc other) const nothrow
+ {
+ return this.filename == other.filename && this.line == other.line && this.column == other.column;
+ }
}
Modules aimports; // all imported modules
- unsigned debuglevel; // debug level
Identifiers *debugids; // debug identifiers
Identifiers *debugidsNot; // forward referenced debug identifiers
- unsigned versionlevel; // version level
Identifiers *versionids; // version identifiers
Identifiers *versionidsNot; // forward referenced version identifiers
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)
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())
/***************************************
* Expands tuples in args in depth first order. Calls
- * dg(void *ctx, size_t argidx, Parameter *arg) for each Parameter.
+ * dg(void* ctx, size_t argidx, Parameter* arg) for each Parameter.
* If dg returns !=0, stops and returns that value else returns 0.
* Use this function to avoid the O(N + N^2/2) complexity of
* calculating dim and calling N times getNth.
AggregateDeclaration isAggregate(Type t)
{
t = t.toBasetype();
- if (t.ty == Tclass)
- return (cast(TypeClass)t).sym;
- if (t.ty == Tstruct)
- return (cast(TypeStruct)t).sym;
+ if (auto tc = t.isTypeClass())
+ return tc.sym;
+ if (auto ts = t.isTypeStruct())
+ return ts.sym;
return null;
}
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);
}
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);
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);
return false;
}
+/// Returns: whether `op` can be overloaded with `opBinary`
+private bool hasOpBinary(EXP op) pure @safe
+{
+ switch (op)
+ {
+ case EXP.add: return true;
+ case EXP.min: return true;
+ case EXP.mul: return true;
+ case EXP.div: return true;
+ case EXP.mod: return true;
+ case EXP.and: return true;
+ case EXP.or: return true;
+ case EXP.xor: return true;
+ case EXP.leftShift: return true;
+ case EXP.rightShift: return true;
+ case EXP.unsignedRightShift: return true;
+ case EXP.concatenate: return true;
+ case EXP.pow: return true;
+ case EXP.in_: return true;
+ default: return false;
+ }
+}
+
+/**
+ * Remove the = from op=, e.g. += becomes +
+ *
+ * Params:
+ * op = tag for a binary assign operator
+ * Returns: the corresponding binary operator, or `op` if it wasn't an assign operator
+*/
+private EXP stripAssignOp(EXP op)
+{
+ switch (op)
+ {
+ case EXP.addAssign: return EXP.add;
+ case EXP.minAssign: return EXP.min;
+ case EXP.mulAssign: return EXP.mul;
+ case EXP.divAssign: return EXP.div;
+ case EXP.modAssign: return EXP.mod;
+ case EXP.andAssign: return EXP.and;
+ case EXP.orAssign: return EXP.or;
+ case EXP.xorAssign: return EXP.xor;
+ case EXP.leftShiftAssign: return EXP.leftShift;
+ case EXP.rightShiftAssign: return EXP.rightShift;
+ case EXP.unsignedRightShiftAssign: return EXP.unsignedRightShift;
+ case EXP.concatenateAssign: return EXP.concatenate;
+ case EXP.powAssign: return EXP.pow;
+ default: return op;
+ }
+}
+
/*******************************************
* Helper function to turn operator into template argument list
*/
Objects* opToArg(Scope* sc, EXP op)
{
- /* Remove the = from op=
- */
- switch (op)
- {
- case EXP.addAssign:
- op = EXP.add;
- break;
- case EXP.minAssign:
- op = EXP.min;
- break;
- case EXP.mulAssign:
- op = EXP.mul;
- break;
- case EXP.divAssign:
- op = EXP.div;
- break;
- case EXP.modAssign:
- op = EXP.mod;
- break;
- case EXP.andAssign:
- op = EXP.and;
- break;
- case EXP.orAssign:
- op = EXP.or;
- break;
- case EXP.xorAssign:
- op = EXP.xor;
- break;
- case EXP.leftShiftAssign:
- op = EXP.leftShift;
- break;
- case EXP.rightShiftAssign:
- op = EXP.rightShift;
- break;
- case EXP.unsignedRightShiftAssign:
- op = EXP.unsignedRightShift;
- break;
- case EXP.concatenateAssign:
- op = EXP.concatenate;
- break;
- case EXP.powAssign:
- op = EXP.pow;
- break;
- default:
- break;
- }
- Expression e = new StringExp(Loc.initial, EXPtoString(op));
+ Expression e = new StringExp(Loc.initial, EXPtoString(stripAssignOp(op)));
e = e.expressionSemantic(sc);
auto tiargs = new Objects();
tiargs.push(e);
BinExp be = cast(BinExp)e.copy();
// Resolve 'alias this' but in case of assigment don't resolve properties yet
// because 'e1 = e2' could mean 'e1(e2)' or 'e1() = e2'
- bool findOnly = (e.op == EXP.assign);
+ bool findOnly = e.isAssignExp() !is null;
be.e1 = resolveAliasThis(sc, e.e1, true, findOnly);
if (!be.e1)
return null;
Expression opOverloadUnary(UnaExp e, Scope* sc)
{
- Expression result;
if (auto ae = e.e1.isArrayExp())
{
ae.e1 = ae.e1.expressionSemantic(sc);
ae.e1 = resolveProperties(sc, ae.e1);
Expression ae1old = ae.e1;
- const(bool) maybeSlice = (ae.arguments.length == 0 || ae.arguments.length == 1 && (*ae.arguments)[0].op == EXP.interval);
+ const(bool) maybeSlice = (ae.arguments.length == 0 || ae.arguments.length == 1 && (*ae.arguments)[0].isIntervalExp());
IntervalExp ie = null;
if (maybeSlice && ae.arguments.length)
{
Type att = null; // first cyclic `alias this` type
while (true)
{
- if (ae.e1.op == EXP.error)
+ if (ae.e1.isErrorExp())
{
return ae.e1;
}
- Expression e0 = null;
Expression ae1save = ae.e1;
ae.lengthVar = null;
- Type t1b = ae.e1.type.toBasetype();
- AggregateDeclaration ad = isAggregate(t1b);
+
+ AggregateDeclaration ad = isAggregate(ae.e1.type);
if (!ad)
break;
+
if (search_function(ad, Id.opIndexUnary))
{
+ Expression e0;
// Deal with $
- result = resolveOpDollar(sc, ae, &e0);
- if (!result) // op(a[i..j]) might be: a.opSliceUnary!(op)(i, j)
+ Expression ae2 = resolveOpDollar(sc, ae, e0);
+ if (!ae2) // op(a[i..j]) might be: a.opSliceUnary!(op)(i, j)
goto Lfallback;
- if (result.op == EXP.error)
- return result;
+ if (ae2.isErrorExp())
+ return ae2;
/* Rewrite op(a[arguments]) as:
- * a.opIndexUnary!(op)(arguments)
- */
- Expressions* a = ae.arguments.copy();
- Objects* tiargs = opToArg(sc, e.op);
- result = new DotTemplateInstanceExp(e.loc, ae.e1, Id.opIndexUnary, tiargs);
- result = new CallExp(e.loc, result, a);
+ * a.opIndexUnary!(op)(arguments)
+ */
+ Expression result = dotTemplateCall(ae.e1, Id.opIndexUnary, opToArg(sc, e.op), (*ae.arguments)[]);
if (maybeSlice) // op(a[]) might be: a.opSliceUnary!(op)()
result = result.trySemantic(sc);
else
result = result.expressionSemantic(sc);
+
if (result)
- {
return Expression.combine(e0, result);
- }
}
Lfallback:
if (maybeSlice && search_function(ad, Id.opSliceUnary))
{
// Deal with $
- result = resolveOpDollar(sc, ae, ie, &e0);
- if (result.op == EXP.error)
- return result;
+ Expression e0;
+ auto ae2 = resolveOpDollar(sc, ae, ie, e0);
+ if (ae2.isErrorExp())
+ return ae2;
/* Rewrite op(a[i..j]) as:
- * a.opSliceUnary!(op)(i, j)
- */
- auto a = new Expressions();
- if (ie)
- {
- a.push(ie.lwr);
- a.push(ie.upr);
- }
- Objects* tiargs = opToArg(sc, e.op);
- result = new DotTemplateInstanceExp(e.loc, ae.e1, Id.opSliceUnary, tiargs);
- result = new CallExp(e.loc, result, a);
- result = result.expressionSemantic(sc);
- result = Expression.combine(e0, result);
- return result;
+ * a.opSliceUnary!(op)(i, j)
+ */
+ Expression result = ie ?
+ dotTemplateCall(ae.e1, Id.opSliceUnary, opToArg(sc, e.op), ie.lwr, ie.upr) :
+ dotTemplateCall(ae.e1, Id.opSliceUnary, opToArg(sc, e.op));
+
+ return Expression.combine(e0, result.expressionSemantic(sc));
}
// Didn't find it. Forward to aliasthis
if (ad.aliasthis && !isRecursiveAliasThis(att, ae.e1.type))
{
/* Rewrite op(a[arguments]) as:
- * op(a.aliasthis[arguments])
- */
+ * op(a.aliasthis[arguments])
+ */
ae.e1 = resolveAliasThis(sc, ae1save, true);
if (ae.e1)
continue;
Type att = null; // first cyclic `alias this` type
while (1)
{
- if (e.e1.op == EXP.error)
+ if (e.e1.isErrorExp())
{
return e.e1;
}
if (!ad)
break;
- Dsymbol fd = null;
/* Rewrite as:
* e1.opUnary!(op)()
*/
- fd = search_function(ad, Id.opUnary);
- if (fd)
- {
- Objects* tiargs = opToArg(sc, e.op);
- result = new DotTemplateInstanceExp(e.loc, e.e1, fd.ident, tiargs);
- result = new CallExp(e.loc, result);
- result = result.expressionSemantic(sc);
- return result;
- }
+ if (Dsymbol fd = search_function(ad, Id.opUnary))
+ return dotTemplateCall(e.e1, Id.opUnary, opToArg(sc, e.op)).expressionSemantic(sc);
// Didn't find it. Forward to aliasthis
if (ad.aliasthis && !isRecursiveAliasThis(att, e.e1.type))
}
break;
}
+
+ // For ++ and --, rewrites to += and -= are also tried, so don't error yet
+ if (!e.isPreExp())
+ {
+ error(e.loc, "operator `%s` is not defined for `%s`", EXPtoString(e.op).ptr, ad.toChars());
+ errorSupplemental(ad.loc, "perhaps overload the operator with `auto opUnary(string op : \"%s\")() {}`",
+ EXPtoString(e.op).ptr);
+ return ErrorExp.get();
+ }
+
break;
}
- return result;
+ return null;
}
Expression opOverloadArray(ArrayExp ae, Scope* sc)
ae.e1 = ae.e1.expressionSemantic(sc);
ae.e1 = resolveProperties(sc, ae.e1);
Expression ae1old = ae.e1;
- const(bool) maybeSlice = (ae.arguments.length == 0 || ae.arguments.length == 1 && (*ae.arguments)[0].op == EXP.interval);
+ const(bool) maybeSlice = (ae.arguments.length == 0 || ae.arguments.length == 1 && (*ae.arguments)[0].isIntervalExp());
IntervalExp ie = null;
if (maybeSlice && ae.arguments.length)
{
ie = (*ae.arguments)[0].isIntervalExp();
}
- Expression result;
Type att = null; // first cyclic `alias this` type
while (true)
{
- if (ae.e1.op == EXP.error)
+ if (ae.e1.isErrorExp())
{
return ae.e1;
}
{
// If the non-aggregate expression ae.e1 is indexable or sliceable,
// convert it to the corresponding concrete expression.
- if (isIndexableNonAggregate(t1b) || ae.e1.op == EXP.type)
+ if (isIndexableNonAggregate(t1b) || ae.e1.isTypeExp())
{
// Convert to SliceExp
if (maybeSlice)
- {
- result = new SliceExp(ae.loc, ae.e1, ie);
- result = result.expressionSemantic(sc);
- return result;
- }
+ return new SliceExp(ae.loc, ae.e1, ie).expressionSemantic(sc);
+
// Convert to IndexExp
if (ae.arguments.length == 1)
- {
- result = new IndexExp(ae.loc, ae.e1, (*ae.arguments)[0]);
- result = result.expressionSemantic(sc);
- return result;
- }
+ return new IndexExp(ae.loc, ae.e1, (*ae.arguments)[0]).expressionSemantic(sc);
}
break;
}
if (search_function(ad, Id.opIndex))
{
// Deal with $
- result = resolveOpDollar(sc, ae, &e0);
- if (!result) // a[i..j] might be: a.opSlice(i, j)
+ auto ae2 = resolveOpDollar(sc, ae, e0);
+ if (!ae2) // a[i..j] might be: a.opSlice(i, j)
goto Lfallback;
- if (result.op == EXP.error)
- return result;
+ if (ae2.isErrorExp())
+ return ae2;
/* Rewrite e1[arguments] as:
* e1.opIndex(arguments)
*/
Expressions* a = ae.arguments.copy();
- result = new DotIdExp(ae.loc, ae.e1, Id.opIndex);
+ Expression result = new DotIdExp(ae.loc, ae.e1, Id.opIndex);
result = new CallExp(ae.loc, result, a);
if (maybeSlice) // a[] might be: a.opSlice()
result = result.trySemantic(sc);
else
result = result.expressionSemantic(sc);
+
if (result)
- {
return Expression.combine(e0, result);
- }
}
Lfallback:
- if (maybeSlice && ae.e1.op == EXP.type)
+ if (maybeSlice && ae.e1.isTypeExp())
{
- result = new SliceExp(ae.loc, ae.e1, ie);
+ Expression result = new SliceExp(ae.loc, ae.e1, ie);
result = result.expressionSemantic(sc);
- result = Expression.combine(e0, result);
- return result;
+ return Expression.combine(e0, result);
}
if (maybeSlice && search_function(ad, Id.opSlice))
{
// Deal with $
- result = resolveOpDollar(sc, ae, ie, &e0);
+ auto ae2 = resolveOpDollar(sc, ae, ie, e0);
- if (result.op == EXP.error)
+ if (ae2.isErrorExp())
{
- if (!e0 && !search_function(ad, Id.dollar)) {
- ae.loc.errorSupplemental("Aggregate declaration '%s' does not define 'opDollar'", ae.e1.toChars());
- }
- return result;
+ if (!e0 && !search_function(ad, Id.dollar))
+ ad.loc.errorSupplemental("perhaps define `opDollar` for `%s`", ad.toChars());
+
+ return ae2;
}
/* Rewrite a[i..j] as:
* a.opSlice(i, j)
a.push(ie.lwr);
a.push(ie.upr);
}
- result = new DotIdExp(ae.loc, ae.e1, Id.opSlice);
+ Expression result = new DotIdExp(ae.loc, ae.e1, Id.opSlice);
result = new CallExp(ae.loc, result, a);
result = result.expressionSemantic(sc);
- result = Expression.combine(e0, result);
- return result;
+ return Expression.combine(e0, result);
}
// Didn't find it. Forward to aliasthis
if (ad.aliasthis && !isRecursiveAliasThis(att, ae.e1.type))
}
ae.e1 = ae1old; // recovery
ae.lengthVar = null;
- return result;
+ return null;
}
/***********************************************
*/
Expression opOverloadCast(CastExp e, Scope* sc, Type att = null)
{
- Expression result;
- if (AggregateDeclaration ad = isAggregate(e.e1.type))
+ AggregateDeclaration ad = isAggregate(e.e1.type);
+ if (!ad)
+ return null;
+
+ // Rewrite as: e1.opCast!(T)()
+ if (Dsymbol fd = search_function(ad, Id.opCast))
{
- Dsymbol fd = null;
- /* Rewrite as:
- * e1.opCast!(T)()
- */
- fd = search_function(ad, Id.opCast);
- if (fd)
+ version (all)
{
- version (all)
+ // Backwards compatibility with D1 if opCast is a function, not a template
+ if (fd.isFuncDeclaration())
{
- // Backwards compatibility with D1 if opCast is a function, not a template
- if (fd.isFuncDeclaration())
- {
- // Rewrite as: e1.opCast()
- return build_overload(e.loc, sc, e.e1, null, fd);
- }
+ // Rewrite as: e1.opCast()
+ return build_overload(e.loc, sc, e.e1, null, fd);
}
- auto tiargs = new Objects();
- tiargs.push(e.to);
- result = new DotTemplateInstanceExp(e.loc, e.e1, fd.ident, tiargs);
- result = new CallExp(e.loc, result);
- result = result.expressionSemantic(sc);
- return result;
}
- // Didn't find it. Forward to aliasthis
- if (ad.aliasthis && !isRecursiveAliasThis(att, e.e1.type))
+ auto tiargs = new Objects();
+ tiargs.push(e.to);
+ return dotTemplateCall(e.e1, Id.opCast, tiargs).expressionSemantic(sc);
+ }
+ // Didn't find it. Forward to aliasthis
+ if (ad.aliasthis && !isRecursiveAliasThis(att, e.e1.type))
+ {
+ // Rewrite `e1.opCast()` as `e1.aliasthis.opCast()`
+ if (auto e1 = resolveAliasThis(sc, e.e1, true))
{
- /* Rewrite op(e1) as:
- * op(e1.aliasthis)
- */
- if (auto e1 = resolveAliasThis(sc, e.e1, true))
- {
- result = e.copy();
- (cast(UnaExp)result).e1 = e1;
- result = opOverloadCast(result.isCastExp(), sc, att);
- return result;
- }
+ CastExp result = e.copy().isCastExp();
+ result.e1 = e1;
+ return result.opOverloadCast(sc, att);
}
}
- return result;
+ return null;
}
// When no operator overload functions are found for `e`, recursively try with `alias this`
AggregateDeclaration ad1 = isAggregate(e.e1.type);
AggregateDeclaration ad2 = isAggregate(e.e2.type);
Expression rewrittenLhs;
- if (!(e.op == EXP.assign && ad2 && ad1 == ad2)) // https://issues.dlang.org/show_bug.cgi?id=2943
+ if (!(e.isAssignExp && ad2 && ad1 == ad2)) // https://issues.dlang.org/show_bug.cgi?id=2943
{
if (Expression result = checkAliasThisForLhs(ad1, sc, e, aliasThisStop))
{
* one of the members, hence the `ad1.fields.length == 2 && ad1.vthis`
* condition.
*/
- if (result.op != EXP.assign)
+ auto ae = result.isAssignExp();
+ if (!ae)
return result; // i.e: Rewrote `e1 = e2` -> `e1(e2)`
- auto ae = result.isAssignExp();
- if (ae.e1.op != EXP.dotVariable)
+ auto dve = ae.e1.isDotVarExp();
+ if (!dve)
return result; // i.e: Rewrote `e1 = e2` -> `e1() = e2`
- auto dve = ae.e1.isDotVarExp();
if (auto ad = dve.var.isMember2())
{
// i.e: Rewrote `e1 = e2` -> `e1.some.var = e2`
rewrittenLhs = ae.e1;
}
}
- if (!(e.op == EXP.assign && ad1 && ad1 == ad2)) // https://issues.dlang.org/show_bug.cgi?id=2943
+ if (!(e.isAssignExp && ad1 && ad1 == ad2)) // https://issues.dlang.org/show_bug.cgi?id=2943
{
if (Expression result = checkAliasThisForRhs(ad2, sc, e, aliasThisStop))
return result;
s_r = null;
bool choseReverse;
- if (auto res = pickBestBinaryOverload(sc, opToArg(sc, e.op), s, s_r, e, choseReverse))
- return res;
+ if (auto result = pickBestBinaryOverload(sc, opToArg(sc, e.op), s, s_r, e, choseReverse))
+ return result;
return binAliasThis(e, sc, aliasThisStop);
}
+/**
+ * If applicable, print an error relating to implementing / fixing `opBinary` functions.
+ * Params:
+ * e = binary operation
+ * sc = scope to try `opBinary!""` semantic in for error messages
+ * Returns: `true` when an error related to `opBinary` was printed
+ */
+bool suggestBinaryOverloads(BinExp e, Scope* sc)
+{
+ if (!e.op.hasOpBinary)
+ return false;
+
+ AggregateDeclaration ad1 = isAggregate(e.e1.type);
+ AggregateDeclaration ad2 = isAggregate(e.e2.type);
+
+ if (ad1)
+ {
+ if (Dsymbol s = search_function(ad1, Id.opBinary))
+ {
+ // This expressionSemantic will fail, otherwise operator overloading would have succeeded before
+ dotTemplateCall(e.e1, Id.opBinary, opToArg(sc, e.op), e.e2).expressionSemantic(sc);
+ errorSupplemental(s.loc, "`opBinary` defined here");
+ return true;
+ }
+ error(e.loc, "operator `%s` is not defined for type `%s`", EXPtoString(e.op).ptr, e.e1.type.toChars);
+ errorSupplemental(ad1.loc, "perhaps overload the operator with `auto opBinary(string op : \"%s\")(%s rhs) {}`", EXPtoString(e.op).ptr, e.e2.type.toChars);
+ return true;
+ }
+ else if (ad2)
+ {
+ if (Dsymbol s_r = search_function(ad1, Id.opBinaryRight))
+ {
+ dotTemplateCall(e.e2, Id.opBinaryRight, opToArg(sc, e.op), e.e1).expressionSemantic(sc);
+ errorSupplemental(s_r.loc, "`opBinaryRight` defined here");
+ return true;
+ }
+ error(e.loc, "operator `%s` is not defined for type `%s`", EXPtoString(e.op).ptr, e.e2.type.toChars);
+ errorSupplemental(ad2.loc, "perhaps overload the operator with `auto opBinaryRight(string op : \"%s\")(%s rhs) {}`", EXPtoString(e.op).ptr, e.e1.type.toChars);
+ return true;
+ }
+ return false;
+}
+
+/**
+ * If applicable, print an error relating to implementing / fixing `opOpAssign` or `opUnary` functions.
+ * Params:
+ * exp = binary operation
+ * sc = scope to try `opOpAssign!""` semantic in for error messages
+ * parent = if `exp` was lowered from this `PreExp` or `PostExp`, mention `opUnary` as well
+ * Returns: `true` when an error related to `opOpAssign` was printed
+ */
+bool suggestOpOpAssign(BinAssignExp exp, Scope* sc, Expression parent)
+{
+ auto ad = isAggregate(exp.e1.type);
+ if (!ad)
+ return false;
+
+ if (parent && (parent.isPreExp() || parent.isPostExp()))
+ {
+ error(exp.loc, "operator `%s` not supported for `%s` of type `%s`", EXPtoString(parent.op).ptr, exp.e1.toChars(), ad.toChars());
+ errorSupplemental(ad.loc,
+ "perhaps implement `auto opUnary(string op : \"%s\")() {}`"~
+ " or `auto opOpAssign(string op : \"%s\")(int) {}`",
+ EXPtoString(stripAssignOp(parent.op)).ptr,
+ EXPtoString(stripAssignOp(exp.op)).ptr
+ );
+ return true;
+ }
+
+ if (const s = search_function(ad, Id.opOpAssign))
+ {
+ // This expressionSemantic will fail, otherwise operator overloading would have succeeded before
+ dotTemplateCall(exp.e1, Id.opOpAssign, opToArg(sc, exp.op), exp.e2).expressionSemantic(sc);
+ }
+ else
+ {
+ error(exp.loc, "operator `%s` not supported for `%s` of type `%s`", EXPtoString(exp.op).ptr, exp.e1.toChars(), ad.toChars());
+ errorSupplemental(ad.loc, "perhaps implement `auto opOpAssign(string op : \"%s\")(%s) {}`",
+ EXPtoString(stripAssignOp(exp.op)).ptr, exp.e2.type.toChars());
+ }
+ return true;
+}
+
+// Helper to construct e.id!tiargs(args), e.g. `lhs.opBinary!"+"(rhs)`
+private Expression dotTemplateCall(Expression e, Identifier id, Objects* tiargs, Expression[] args...)
+{
+ auto ti = new DotTemplateInstanceExp(e.loc, e, id, tiargs);
+ auto expressions = new Expressions();
+ expressions.pushSlice(args);
+ return new CallExp(e.loc, ti, expressions);
+}
+
Expression opOverloadEqual(EqualExp e, Scope* sc, Type[2] aliasThisStop)
{
Type t1 = e.e1.type.toBasetype();
* lowering to object.__equals(), which takes care of overloaded
* operators for the element types.
*/
- if ((t1.ty == Tarray || t1.ty == Tsarray) &&
- (t2.ty == Tarray || t2.ty == Tsarray))
+ if (t1.isStaticOrDynamicArray() && t2.isStaticOrDynamicArray())
{
return null;
}
/* Check for class equality with null literal or typeof(null).
*/
- if (t1.ty == Tclass && e.e2.op == EXP.null_ ||
- t2.ty == Tclass && e.e1.op == EXP.null_)
+ if (t1.isTypeClass() && e.e2.isNullExp() ||
+ t2.isTypeClass() && e.e1.isNullExp())
{
error(e.loc, "use `%s` instead of `%s` when comparing with `null`",
EXPtoString(e.op == EXP.equal ? EXP.identity : EXP.notIdentity).ptr,
EXPtoString(e.op).ptr);
return ErrorExp.get();
}
- if (t1.ty == Tclass && t2.ty == Tnull ||
- t1.ty == Tnull && t2.ty == Tclass)
+ if (t1.isTypeClass() && t2.isTypeNull() ||
+ t1.isTypeNull() && t2.isTypeClass())
{
// Comparing a class with typeof(null) should not call opEquals
return null;
/* Check for class equality.
*/
- if (t1.ty == Tclass && t2.ty == Tclass)
+ if (t1.isTypeClass() && t2.isTypeClass())
{
ClassDeclaration cd1 = t1.isClassHandle();
ClassDeclaration cd2 = t2.isClassHandle();
EXP cmpOp;
if (Expression result = compare_overload(e, sc, Id.opEquals, cmpOp, aliasThisStop))
{
- if (lastComma(result).op == EXP.call && e.op == EXP.notEqual)
+ if (lastComma(result).isCallExp() && e.op == EXP.notEqual)
{
result = new NotExp(result.loc, result);
result = result.expressionSemantic(sc);
/* Check for pointer equality.
*/
- if (t1.ty == Tpointer || t2.ty == Tpointer)
+ if (t1.isTypePointer() || t2.isTypePointer())
{
/* Rewrite:
* ptr1 == ptr2
/* Check for struct equality without opEquals.
*/
- if (t1.ty == Tstruct && t2.ty == Tstruct)
+ if (t1.isTypeStruct() && t2.isTypeStruct())
{
auto sd = t1.isTypeStruct().sym;
if (sd != t2.isTypeStruct().sym)
/* Check for tuple equality.
*/
- if (e.e1.op == EXP.tuple && e.e2.op == EXP.tuple)
+ auto tup1 = e.e1.isTupleExp();
+ auto tup2 = e.e2.isTupleExp();
+ if (tup1 && tup2)
{
- auto tup1 = e.e1.isTupleExp();
- auto tup2 = e.e2.isTupleExp();
size_t dim = tup1.exps.length;
if (dim != tup2.exps.length)
{
error(e.loc, "recursive `opCmp` expansion");
return ErrorExp.get();
}
- if (e.op != EXP.call)
+ if (!e.isCallExp())
return e;
Type t1 = exp.e1.type.toBasetype();
Type t2 = exp.e2.type.toBasetype();
- if (t1.ty != Tclass || t2.ty != Tclass)
+ if (!t1.isTypeClass() || !t2.isTypeClass())
{
return new CmpExp(cmpOp, exp.loc, e, IntegerExp.literal!0).expressionSemantic(sc);
}
ae.e1 = ae.e1.expressionSemantic(sc);
ae.e1 = resolveProperties(sc, ae.e1);
Expression ae1old = ae.e1;
- const(bool) maybeSlice = (ae.arguments.length == 0 || ae.arguments.length == 1 && (*ae.arguments)[0].op == EXP.interval);
+ const(bool) maybeSlice = (ae.arguments.length == 0 || ae.arguments.length == 1 && (*ae.arguments)[0].isIntervalExp());
IntervalExp ie = null;
if (maybeSlice && ae.arguments.length)
{
Type att = null; // first cyclic `alias this` type
while (true)
{
- if (ae.e1.op == EXP.error)
- {
+ if (ae.e1.isErrorExp())
return ae.e1;
- }
+
Expression e0 = null;
Expression ae1save = ae.e1;
ae.lengthVar = null;
- Type t1b = ae.e1.type.toBasetype();
- AggregateDeclaration ad = isAggregate(t1b);
+ AggregateDeclaration ad = isAggregate(ae.e1.type);
if (!ad)
break;
if (search_function(ad, Id.opIndexOpAssign))
{
// Deal with $
- Expression result = resolveOpDollar(sc, ae, &e0);
- if (!result) // (a[i..j] op= e2) might be: a.opSliceOpAssign!(op)(e2, i, j)
+ Expression ae2 = resolveOpDollar(sc, ae, e0);
+ if (!ae2) // (a[i..j] op= e2) might be: a.opSliceOpAssign!(op)(e2, i, j)
goto Lfallback;
- if (result.op == EXP.error)
- return result;
- result = e.e2.expressionSemantic(sc);
- if (result.op == EXP.error)
- return result;
- e.e2 = result;
+ if (ae2.isErrorExp())
+ return ae2;
+ e.e2 = e.e2.expressionSemantic(sc);
+ if (e.e2.isErrorExp())
+ return e.e2;
+
/* Rewrite a[arguments] op= e2 as:
* a.opIndexOpAssign!(op)(e2, arguments)
*/
Expressions* a = ae.arguments.copy();
a.insert(0, e.e2);
- Objects* tiargs = opToArg(sc, e.op);
- result = new DotTemplateInstanceExp(e.loc, ae.e1, Id.opIndexOpAssign, tiargs);
- result = new CallExp(e.loc, result, a);
+ Expression result = dotTemplateCall(ae.e1, Id.opIndexOpAssign, opToArg(sc, e.op), (*a)[]);
if (maybeSlice) // (a[] op= e2) might be: a.opSliceOpAssign!(op)(e2)
result = result.trySemantic(sc);
else
result = result.expressionSemantic(sc);
+
if (result)
- {
return Expression.combine(e0, result);
- }
}
Lfallback:
if (maybeSlice && search_function(ad, Id.opSliceOpAssign))
{
// Deal with $
- Expression result = resolveOpDollar(sc, ae, ie, &e0);
- if (result.op == EXP.error)
- return result;
- result = e.e2.expressionSemantic(sc);
- if (result.op == EXP.error)
- return result;
- e.e2 = result;
+ Expression ae2 = resolveOpDollar(sc, ae, ie, e0);
+ if (ae2.isErrorExp())
+ return ae2;
+
+ e.e2 = e.e2.expressionSemantic(sc);
+ if (e.e2.isErrorExp())
+ return e.e2;
+
/* Rewrite (a[i..j] op= e2) as:
* a.opSliceOpAssign!(op)(e2, i, j)
*/
- auto a = new Expressions();
- a.push(e.e2);
- if (ie)
- {
- a.push(ie.lwr);
- a.push(ie.upr);
- }
- Objects* tiargs = opToArg(sc, e.op);
- result = new DotTemplateInstanceExp(e.loc, ae.e1, Id.opSliceOpAssign, tiargs);
- result = new CallExp(e.loc, result, a);
- result = result.expressionSemantic(sc);
- result = Expression.combine(e0, result);
- return result;
+ auto result = ie ?
+ dotTemplateCall(ae.e1, Id.opSliceOpAssign, opToArg(sc, e.op), e.e2, ie.lwr, ie.upr) :
+ dotTemplateCall(ae.e1, Id.opSliceOpAssign, opToArg(sc, e.op), e.e2);
+
+ return Expression.combine(e0, result.expressionSemantic(sc));
}
// Didn't find it. Forward to aliasthis
if (ad.aliasthis && !isRecursiveAliasThis(att, ae.e1.type))
ae.e1 = ae1old; // recovery
ae.lengthVar = null;
}
- Expression result = e.binSemanticProp(sc);
- if (result)
+
+ if (Expression result = e.binSemanticProp(sc))
return result;
+
// Don't attempt 'alias this' if an error occurred
- if (e.e1.type.ty == Terror || e.e2.type.ty == Terror)
- {
+ if (e.e1.type.isTypeError() || e.e2.type.isTypeError())
return ErrorExp.get();
- }
+
AggregateDeclaration ad1 = isAggregate(e.e1.type);
Dsymbol s = search_function(ad1, Id.opOpAssign);
if (s && !s.isTemplateDeclaration())
if (auto res = pickBestBinaryOverload(sc, opToArg(sc, e.op), s, null, e, choseReverse))
return res;
- result = checkAliasThisForLhs(ad1, sc, e, aliasThisStop);
+ Expression result = checkAliasThisForLhs(ad1, sc, e, aliasThisStop);
if (result || !s) // no point in trying Rhs alias-this if there's no overload of any kind in lhs
return result;
if (s)
{
- functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, ArgumentList(args2));
+ functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, ArgumentList(args2), null);
if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors()))
return ErrorExp.get();
}
int count = m.count;
if (s_r)
{
- functionResolve(m, s_r, e.loc, sc, tiargs, e.e2.type, ArgumentList(args1));
+ functionResolve(m, s_r, e.loc, sc, tiargs, e.e2.type, ArgumentList(args1), null);
if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors()))
return ErrorExp.get();
}
* at this point, no matching opEquals was found for structs,
* so we should not follow the alias this comparison code.
*/
- if ((e.op == EXP.equal || e.op == EXP.notEqual) && ad1 == ad2)
+ if (e.isEqualExp() && ad1 == ad2)
return null;
Expression result = checkAliasThisForLhs(ad1, sc, e, aliasThisStop);
- return result ? result : checkAliasThisForRhs(isAggregate(e.e2.type), sc, e, aliasThisStop);
+ if (result)
+ return result;
+
+ result = checkAliasThisForRhs(isAggregate(e.e2.type), sc, e, aliasThisStop);
+ if (result)
+ return result;
+
+ if (s || s_r)
+ return null;
+
+ Expression suggestOverloading(Expression other, AggregateDeclaration ad)
+ {
+ error(e.loc, "no operator `%s` for type `%s`", EXPtoString(e.op).ptr, ad.toChars);
+ string op = e.isEqualExp() ? "bool" : "int";
+ errorSupplemental(ad.loc, "perhaps overload it with `%.*s %s(%s other) const {}`", op.fTuple.expand, id.toChars, other.type.toChars);
+ return ErrorExp.get();
+ }
+
+ // Classes have opCmp and opEquals defined in `Object` to fall back on already
+ if (ad1 && ad1.isStructDeclaration)
+ return suggestOverloading(e.e2, ad1);
+ if (ad2 && ad2.isStructDeclaration)
+ return suggestOverloading(e.e1, ad2);
+
+ return null;
}
/***********************************
Dsymbol s2 = s.toAlias();
//printf("search_function: s2 = '%s'\n", s2.kind());
FuncDeclaration fd = s2.isFuncDeclaration();
- if (fd && fd.type.ty == Tfunction)
+ if (fd && fd.type.isTypeFunction())
return fd;
if (TemplateDeclaration td = s2.isTemplateDeclaration())
return td;
aggr = aggr.expressionSemantic(sc);
aggr = resolveProperties(sc, aggr);
aggr = aggr.optimize(WANTvalue);
- if (!aggr.type || aggr.op == EXP.error)
+ if (!aggr.type || aggr.isErrorExp())
return false;
Type tab = aggr.type.toBasetype();
switch (tab.ty)
case Tclass:
case Tstruct:
{
- AggregateDeclaration ad = (tab.ty == Tclass) ? tab.isTypeClass().sym
- : tab.isTypeStruct().sym;
+ AggregateDeclaration ad = isAggregate(tab);
if (!sliced)
{
sapply = search_function(ad, isForeach ? Id.apply : Id.applyReverse);
// Determine ethis for sapply
Expression ethis;
Type tab = fes.aggr.type.toBasetype();
- if (tab.ty == Tclass || tab.ty == Tstruct)
+ if (tab.isTypeClass() || tab.isTypeStruct())
ethis = fes.aggr;
else
{
- assert(tab.ty == Tdelegate && fes.aggr.op == EXP.delegate_);
+ assert(tab.isTypeDelegate() && fes.aggr.isDelegateExp());
ethis = fes.aggr.isDelegateExp().e1;
}
}
p = (*fes.parameters)[1];
}
- if (!p.type && tab.ty != Ttuple)
+ if (!p.type && !tab.isTypeTuple())
{
p.type = tab.nextOf(); // value type
p.type = p.type.addStorageClass(p.storageClass);
case Tclass:
case Tstruct:
{
- AggregateDeclaration ad = (tab.ty == Tclass) ? tab.isTypeClass().sym
- : tab.isTypeStruct().sym;
+ AggregateDeclaration ad = isAggregate(tab);
if (fes.parameters.length == 1)
{
if (!p.type)
*/
private AST.Condition parseDebugCondition()
{
- uint level = 1;
Identifier id = null;
Loc loc = token.loc;
nextToken();
check(TOK.rightParenthesis);
}
- return new AST.DebugCondition(loc, mod, level, id);
+ return new AST.DebugCondition(loc, mod, id);
}
/**************************************
*/
private AST.Condition parseVersionCondition()
{
- uint level = 1;
Identifier id = null;
Loc loc;
}
else
error("(condition) expected following `version`");
- return new AST.VersionCondition(loc, mod, level, id);
+ return new AST.VersionCondition(loc, mod, id);
}
/***********************************************
*/
private void checkDanglingElse(Loc elseloc)
{
- if (token.value != TOK.else_ && token.value != TOK.catch_ && token.value != TOK.finally_ && lookingForElse.linnum != 0)
+ if (token.value != TOK.else_ && token.value != TOK.catch_ && token.value != TOK.finally_ && lookingForElse.isValid)
{
eSink.warning(elseloc, "else is dangling, add { } after condition at %s", lookingForElse.toChars());
}
if (token.value == TOK.assign)
{
if (auto ds = parseDebugSpecification())
- {
- if (ds.ident)
- eSink.error(ds.loc, "%s `%s` declaration must be at module level", ds.kind, ds.toPrettyChars);
- else
- eSink.error(ds.loc, "%s `%s` level declaration must be at module level", ds.kind, ds.toPrettyChars);
- }
+ eSink.error(ds.loc, "%s `%s` declaration must be at module level", ds.kind, ds.toPrettyChars);
+
break;
}
cond = parseDebugCondition();
if (token.value == TOK.assign)
{
if (auto vs = parseVersionSpecification())
- {
- if (vs.ident)
- eSink.error(vs.loc, "%s `%s` declaration must be at module level", vs.kind, vs.toPrettyChars);
- else
- eSink.error(vs.loc, "%s `%s` level declaration must be at module level", vs.kind, vs.toPrettyChars);
- }
+ eSink.error(vs.loc, "%s `%s` declaration must be at module level", vs.kind, vs.toPrettyChars);
+
break;
}
cond = parseVersionCondition();
// Make a copy of all the cases so that qsort doesn't scramble the actual
// data we pass to codegen (the order of the cases in the switch).
- CaseStatements *csCopy = (*ss.cases).copy();
+ CaseStatements* csCopy = (*ss.cases).copy();
if (numcases)
{
bool overloadInsert(Dsymbol *s) override;
bool hasStaticCtorOrDtor() override;
const char *kind() const override;
- const char *toChars() const override;
Visibility visible() override;
Dsymbol *toAlias() override final; // resolve real symbol
const char *kind() const override;
bool oneMember(Dsymbol *&ps, Identifier *ident) override;
- const char *toChars() const override;
const char* toPrettyCharsHelper() override final;
Identifier *getIdent() override final;
const char *kind() const override;
bool oneMember(Dsymbol *&ps, Identifier *ident) override;
bool hasPointers() override;
- const char *toChars() const override;
TemplateMixin *isTemplateMixin() override { return this; }
void accept(Visitor *v) override { v->visit(this); }
Expression e;
Type t;
Dsymbol s;
- Scope *sco;
+ Scope* sco;
const errors = global.startGagging();
/* ref: https://issues.dlang.org/show_bug.cgi?id=11118
else
{
/* struct S { int a; };
- * struct S *s;
+ * struct S* s;
*/
}
mtype.resolved = sd.type;
mtype.tok == TOK.struct_ && s.isStructDeclaration())
{
/* struct S;
- * { struct S *s; }
+ * { struct S* s; }
*/
mtype.resolved = s.isStructDeclaration().type;
}
else
{
/* union S;
- * { struct S *s; }
+ * { struct S* s; }
*/
.error(mtype.loc, "redeclaring `%s %s` as `%s %s`",
s.kind(), s.toChars(), Token.toChars(mtype.tok), mtype.id.toChars());
return false;
}
+/// Returns: whether `t` is a struct/class/enum without a body
+bool isOpaqueType(Type t)
+{
+ if (auto te = t.isTypeEnum())
+ return te.sym.members is null;
+ if (auto ts = t.isTypeStruct())
+ return ts.sym.members is null;
+ if (auto tc = t.isTypeClass())
+ return tc.sym.members is null;
+ return false;
+}
+
/******************************* Private *****************************************/
class DebugSymbol final : public Dsymbol
{
public:
- unsigned level;
-
DebugSymbol *syntaxCopy(Dsymbol *) override;
- const char *toChars() const override;
const char *kind() const override;
DebugSymbol *isDebugSymbol() override;
void accept(Visitor *v) override { v->visit(this); }
class VersionSymbol final : public Dsymbol
{
public:
- unsigned level;
-
VersionSymbol *syntaxCopy(Dsymbol *) override;
- const char *toChars() const override;
const char *kind() const override;
VersionSymbol *isVersionSymbol() override;
void accept(Visitor *v) override { v->visit(this); }
if (dve->e1->op == EXP::structLiteral)
{
StructLiteralExp *sle = dve->e1->isStructLiteralExp ();
- sle->useStaticInit = false;
+ sle->useStaticInit (false);
}
FuncDeclaration *fd = dve->var->isFuncDeclaration ();
/* Building sinit trees are delayed until after frontend semantic
processing has complete. Build the static initializer now. */
- if (e->useStaticInit && !this->constp_ && !e->sd->isCsymbol ())
+ if (e->useStaticInit () && !this->constp_ && !e->sd->isCsymbol ())
{
tree init = aggregate_initializer_decl (e->sd);
tree field = get_symbol_decl (e->sd->vthis);
tree value = build_vthis (e->sd);
CONSTRUCTOR_APPEND_ELT (ve, field, value);
- gcc_assert (e->useStaticInit == false);
+ gcc_assert (e->useStaticInit () == false);
}
/* Build a constructor in the correct shape of the aggregate type. */
/*
TEST_OUTPUT:
---
-fail_compilation/b17285.d(14): Error: type `ONE` has no value
-fail_compilation/b17285.d(14): Error: type `TWO` has no value
-fail_compilation/b17285.d(14): Error: cannot implicitly convert expression `ONE` of type `b17285.ONE` to `int`
+fail_compilation/b17285.d(15): Error: type `ONE` has no value
+fail_compilation/b17285.d(15): perhaps use `ONE.init`
+fail_compilation/b17285.d(15): Error: type `TWO` has no value
+fail_compilation/b17285.d(15): Error: cannot implicitly convert expression `ONE` of type `b17285.ONE` to `int`
---
*/
{
T2!().F x = T1!().F();
}
-
/*
TEST_OUTPUT:
---
-fail_compilation/bug9631.d(41): Error: incompatible types for `(x) == (y)`: `bug9631.S` and `bug9631.tem!().S`
+fail_compilation/bug9631.d(41): Error: no operator `==` for type `S`
+fail_compilation/bug9631.d(30): perhaps overload it with `bool opEquals(S other) const {}`
---
*/
REQUIRED_ARGS:
TEST_OUTPUT:
---
-fail_compilation/dep_d1_ops.d(198): Error: incompatible types for `(s) + (1)`: `S` and `int`
-fail_compilation/dep_d1_ops.d(199): Error: incompatible types for `(1) + (s)`: `int` and `S`
-fail_compilation/dep_d1_ops.d(200): Error: incompatible types for `(s) - (1)`: `S` and `int`
-fail_compilation/dep_d1_ops.d(201): Error: incompatible types for `(1) - (s)`: `int` and `S`
-fail_compilation/dep_d1_ops.d(202): Error: incompatible types for `(s) * (1)`: `S` and `int`
-fail_compilation/dep_d1_ops.d(203): Error: incompatible types for `(1) * (s)`: `int` and `S`
-fail_compilation/dep_d1_ops.d(204): Error: incompatible types for `(s) / (1)`: `S` and `int`
-fail_compilation/dep_d1_ops.d(205): Error: incompatible types for `(1) / (s)`: `int` and `S`
-fail_compilation/dep_d1_ops.d(206): Error: incompatible types for `(s) % (1)`: `S` and `int`
-fail_compilation/dep_d1_ops.d(207): Error: incompatible types for `(1) % (s)`: `int` and `S`
-fail_compilation/dep_d1_ops.d(209): Error: incompatible types for `(s) & (1)`: `S` and `int`
-fail_compilation/dep_d1_ops.d(210): Error: incompatible types for `(s) | (1)`: `S` and `int`
-fail_compilation/dep_d1_ops.d(211): Error: incompatible types for `(s) ^ (1)`: `S` and `int`
-fail_compilation/dep_d1_ops.d(213): Error: `s` is not of integral type, it is a `S`
-fail_compilation/dep_d1_ops.d(214): Error: `s` is not of integral type, it is a `S`
-fail_compilation/dep_d1_ops.d(215): Error: `s` is not of integral type, it is a `S`
-fail_compilation/dep_d1_ops.d(216): Error: `s` is not of integral type, it is a `S`
-fail_compilation/dep_d1_ops.d(217): Error: `s` is not of integral type, it is a `S`
-fail_compilation/dep_d1_ops.d(218): Error: `s` is not of integral type, it is a `S`
-fail_compilation/dep_d1_ops.d(220): Error: incompatible types for `(s) ~ (1)`: `S` and `int`
-fail_compilation/dep_d1_ops.d(221): Error: incompatible types for `(1) ~ (s)`: `int` and `S`
-fail_compilation/dep_d1_ops.d(223): Error: operator `+` is not defined for `s` of type `S`
-fail_compilation/dep_d1_ops.d(224): Error: operator `-` is not defined for `s` of type `S`
-fail_compilation/dep_d1_ops.d(225): Error: `s` is not of integral type, it is a `S`
-fail_compilation/dep_d1_ops.d(226): Error: `s` is not a scalar, it is a `S`
-fail_compilation/dep_d1_ops.d(227): Error: `s` is not a scalar, it is a `S`
-fail_compilation/dep_d1_ops.d(228): Error: can only `*` a pointer, not a `S`
-fail_compilation/dep_d1_ops.d(230): Error: incompatible types for `(s) in (1)`: `S` and `int`
-fail_compilation/dep_d1_ops.d(231): Error: incompatible types for `(1) in (s)`: `int` and `S`
-fail_compilation/dep_d1_ops.d(233): Error: `s` is not a scalar, it is a `S`
-fail_compilation/dep_d1_ops.d(234): Error: `s` is not a scalar, it is a `S`
-fail_compilation/dep_d1_ops.d(235): Error: `s` is not a scalar, it is a `S`
-fail_compilation/dep_d1_ops.d(236): Error: `s` is not a scalar, it is a `S`
-fail_compilation/dep_d1_ops.d(237): Error: `s` is not a scalar, it is a `S`
-fail_compilation/dep_d1_ops.d(238): Error: `s` is not a scalar, it is a `S`
-fail_compilation/dep_d1_ops.d(239): Error: `s` is not a scalar, it is a `S`
-fail_compilation/dep_d1_ops.d(240): Error: `s` is not a scalar, it is a `S`
-fail_compilation/dep_d1_ops.d(241): Error: `s` is not a scalar, it is a `S`
-fail_compilation/dep_d1_ops.d(242): Error: `s` is not a scalar, it is a `S`
-fail_compilation/dep_d1_ops.d(243): Error: `s` is not a scalar, it is a `S`
-fail_compilation/dep_d1_ops.d(244): Error: cannot append type `int` to type `S`
-fail_compilation/dep_d1_ops.d(248): Error: incompatible types for `(c) + (1)`: `dep_d1_ops.C` and `int`
-fail_compilation/dep_d1_ops.d(249): Error: incompatible types for `(1) + (c)`: `int` and `dep_d1_ops.C`
-fail_compilation/dep_d1_ops.d(250): Error: incompatible types for `(c) - (1)`: `dep_d1_ops.C` and `int`
-fail_compilation/dep_d1_ops.d(251): Error: incompatible types for `(1) - (c)`: `int` and `dep_d1_ops.C`
-fail_compilation/dep_d1_ops.d(252): Error: incompatible types for `(c) * (1)`: `dep_d1_ops.C` and `int`
-fail_compilation/dep_d1_ops.d(253): Error: incompatible types for `(1) * (c)`: `int` and `dep_d1_ops.C`
-fail_compilation/dep_d1_ops.d(254): Error: incompatible types for `(c) / (1)`: `dep_d1_ops.C` and `int`
-fail_compilation/dep_d1_ops.d(255): Error: incompatible types for `(1) / (c)`: `int` and `dep_d1_ops.C`
-fail_compilation/dep_d1_ops.d(256): Error: incompatible types for `(c) % (1)`: `dep_d1_ops.C` and `int`
-fail_compilation/dep_d1_ops.d(257): Error: incompatible types for `(1) % (c)`: `int` and `dep_d1_ops.C`
-fail_compilation/dep_d1_ops.d(259): Error: incompatible types for `(c) & (1)`: `dep_d1_ops.C` and `int`
-fail_compilation/dep_d1_ops.d(260): Error: incompatible types for `(c) | (1)`: `dep_d1_ops.C` and `int`
-fail_compilation/dep_d1_ops.d(261): Error: incompatible types for `(c) ^ (1)`: `dep_d1_ops.C` and `int`
-fail_compilation/dep_d1_ops.d(263): Error: `c` is not of integral type, it is a `dep_d1_ops.C`
-fail_compilation/dep_d1_ops.d(264): Error: `c` is not of integral type, it is a `dep_d1_ops.C`
-fail_compilation/dep_d1_ops.d(265): Error: `c` is not of integral type, it is a `dep_d1_ops.C`
-fail_compilation/dep_d1_ops.d(266): Error: `c` is not of integral type, it is a `dep_d1_ops.C`
-fail_compilation/dep_d1_ops.d(267): Error: `c` is not of integral type, it is a `dep_d1_ops.C`
-fail_compilation/dep_d1_ops.d(268): Error: `c` is not of integral type, it is a `dep_d1_ops.C`
-fail_compilation/dep_d1_ops.d(270): Error: incompatible types for `(c) ~ (1)`: `dep_d1_ops.C` and `int`
-fail_compilation/dep_d1_ops.d(271): Error: incompatible types for `(1) ~ (c)`: `int` and `dep_d1_ops.C`
-fail_compilation/dep_d1_ops.d(273): Error: operator `+` is not defined for `c` of type `dep_d1_ops.C`
-fail_compilation/dep_d1_ops.d(274): Error: operator `-` is not defined for `c` of type `dep_d1_ops.C`
-fail_compilation/dep_d1_ops.d(275): Error: `c` is not of integral type, it is a `dep_d1_ops.C`
-fail_compilation/dep_d1_ops.d(276): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
-fail_compilation/dep_d1_ops.d(277): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
-fail_compilation/dep_d1_ops.d(278): Error: can only `*` a pointer, not a `dep_d1_ops.C`
-fail_compilation/dep_d1_ops.d(280): Error: incompatible types for `(c) in (1)`: `dep_d1_ops.C` and `int`
-fail_compilation/dep_d1_ops.d(281): Error: incompatible types for `(1) in (c)`: `int` and `dep_d1_ops.C`
-fail_compilation/dep_d1_ops.d(283): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
-fail_compilation/dep_d1_ops.d(284): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
-fail_compilation/dep_d1_ops.d(285): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
-fail_compilation/dep_d1_ops.d(286): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
-fail_compilation/dep_d1_ops.d(287): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
-fail_compilation/dep_d1_ops.d(288): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
-fail_compilation/dep_d1_ops.d(289): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
-fail_compilation/dep_d1_ops.d(290): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
-fail_compilation/dep_d1_ops.d(291): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
-fail_compilation/dep_d1_ops.d(292): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
-fail_compilation/dep_d1_ops.d(293): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
-fail_compilation/dep_d1_ops.d(294): Error: cannot append type `int` to type `dep_d1_ops.C`
-fail_compilation/dep_d1_ops.d(303): Error: `nd` is not of integral type, it is a `dep_d1_ops.NoDeprecation`
+fail_compilation/dep_d1_ops.d(281): Error: operator `+` is not defined for type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : "+")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(282): Error: operator `+` is not defined for type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : "+")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(283): Error: operator `-` is not defined for type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : "-")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(284): Error: operator `-` is not defined for type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : "-")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(285): Error: operator `*` is not defined for type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : "*")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(286): Error: operator `*` is not defined for type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : "*")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(287): Error: operator `/` is not defined for type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : "/")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(288): Error: operator `/` is not defined for type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : "/")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(289): Error: operator `%` is not defined for type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : "%")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(290): Error: operator `%` is not defined for type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : "%")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(292): Error: operator `&` is not defined for type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : "&")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(293): Error: operator `|` is not defined for type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : "|")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(294): Error: operator `^` is not defined for type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : "^")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(296): Error: operator `<<` is not defined for type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : "<<")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(297): Error: operator `<<` is not defined for type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : "<<")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(298): Error: operator `>>` is not defined for type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : ">>")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(299): Error: operator `>>` is not defined for type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : ">>")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(300): Error: operator `>>>` is not defined for type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : ">>>")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(301): Error: operator `>>>` is not defined for type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : ">>>")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(303): Error: operator `~` is not defined for type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : "~")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(304): Error: operator `~` is not defined for type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : "~")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(306): Error: operator `+` is not defined for `S`
+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opUnary(string op : "+")() {}`
+fail_compilation/dep_d1_ops.d(307): Error: operator `-` is not defined for `S`
+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opUnary(string op : "-")() {}`
+fail_compilation/dep_d1_ops.d(308): Error: operator `~` is not defined for `S`
+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opUnary(string op : "~")() {}`
+fail_compilation/dep_d1_ops.d(309): Error: operator `++` not supported for `s` of type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps implement `auto opUnary(string op : "++")() {}` or `auto opOpAssign(string op : "+")(int) {}`
+fail_compilation/dep_d1_ops.d(310): Error: operator `--` not supported for `s` of type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps implement `auto opUnary(string op : "--")() {}` or `auto opOpAssign(string op : "-")(int) {}`
+fail_compilation/dep_d1_ops.d(311): Error: operator `*` is not defined for `S`
+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opUnary(string op : "*")() {}`
+fail_compilation/dep_d1_ops.d(313): Error: operator `in` is not defined for type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : "in")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(314): Error: operator `in` is not defined for type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : "in")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(316): Error: operator `+=` not supported for `s` of type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps implement `auto opOpAssign(string op : "+")(int) {}`
+fail_compilation/dep_d1_ops.d(317): Error: operator `-=` not supported for `s` of type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps implement `auto opOpAssign(string op : "-")(int) {}`
+fail_compilation/dep_d1_ops.d(318): Error: operator `*=` not supported for `s` of type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps implement `auto opOpAssign(string op : "*")(int) {}`
+fail_compilation/dep_d1_ops.d(319): Error: operator `/=` not supported for `s` of type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps implement `auto opOpAssign(string op : "/")(int) {}`
+fail_compilation/dep_d1_ops.d(320): Error: operator `%=` not supported for `s` of type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps implement `auto opOpAssign(string op : "%")(int) {}`
+fail_compilation/dep_d1_ops.d(321): Error: operator `&=` not supported for `s` of type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps implement `auto opOpAssign(string op : "&")(int) {}`
+fail_compilation/dep_d1_ops.d(322): Error: operator `|=` not supported for `s` of type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps implement `auto opOpAssign(string op : "|")(int) {}`
+fail_compilation/dep_d1_ops.d(323): Error: operator `^=` not supported for `s` of type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps implement `auto opOpAssign(string op : "^")(int) {}`
+fail_compilation/dep_d1_ops.d(324): Error: operator `<<=` not supported for `s` of type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps implement `auto opOpAssign(string op : "<<")(int) {}`
+fail_compilation/dep_d1_ops.d(325): Error: operator `>>=` not supported for `s` of type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps implement `auto opOpAssign(string op : ">>")(int) {}`
+fail_compilation/dep_d1_ops.d(326): Error: operator `>>>=` not supported for `s` of type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps implement `auto opOpAssign(string op : ">>>")(int) {}`
+fail_compilation/dep_d1_ops.d(327): Error: operator `~=` not supported for `s` of type `S`
+fail_compilation/dep_d1_ops.d(174): perhaps implement `auto opOpAssign(string op : "~")(int) {}`
+fail_compilation/dep_d1_ops.d(331): Error: operator `+` is not defined for type `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : "+")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(332): Error: operator `+` is not defined for type `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : "+")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(333): Error: operator `-` is not defined for type `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : "-")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(334): Error: operator `-` is not defined for type `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : "-")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(335): Error: operator `*` is not defined for type `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : "*")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(336): Error: operator `*` is not defined for type `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : "*")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(337): Error: operator `/` is not defined for type `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : "/")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(338): Error: operator `/` is not defined for type `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : "/")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(339): Error: operator `%` is not defined for type `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : "%")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(340): Error: operator `%` is not defined for type `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : "%")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(342): Error: operator `&` is not defined for type `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : "&")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(343): Error: operator `|` is not defined for type `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : "|")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(344): Error: operator `^` is not defined for type `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : "^")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(346): Error: operator `<<` is not defined for type `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : "<<")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(347): Error: operator `<<` is not defined for type `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : "<<")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(348): Error: operator `>>` is not defined for type `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : ">>")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(349): Error: operator `>>` is not defined for type `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : ">>")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(350): Error: operator `>>>` is not defined for type `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : ">>>")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(351): Error: operator `>>>` is not defined for type `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : ">>>")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(353): Error: operator `~` is not defined for type `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : "~")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(354): Error: operator `~` is not defined for type `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : "~")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(356): Error: operator `+` is not defined for `C`
+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opUnary(string op : "+")() {}`
+fail_compilation/dep_d1_ops.d(357): Error: operator `-` is not defined for `C`
+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opUnary(string op : "-")() {}`
+fail_compilation/dep_d1_ops.d(358): Error: operator `~` is not defined for `C`
+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opUnary(string op : "~")() {}`
+fail_compilation/dep_d1_ops.d(359): Error: operator `++` not supported for `c` of type `C`
+fail_compilation/dep_d1_ops.d(225): perhaps implement `auto opUnary(string op : "++")() {}` or `auto opOpAssign(string op : "+")(int) {}`
+fail_compilation/dep_d1_ops.d(360): Error: operator `--` not supported for `c` of type `C`
+fail_compilation/dep_d1_ops.d(225): perhaps implement `auto opUnary(string op : "--")() {}` or `auto opOpAssign(string op : "-")(int) {}`
+fail_compilation/dep_d1_ops.d(361): Error: operator `*` is not defined for `C`
+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opUnary(string op : "*")() {}`
+fail_compilation/dep_d1_ops.d(363): Error: operator `in` is not defined for type `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : "in")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(364): Error: operator `in` is not defined for type `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : "in")(int rhs) {}`
+fail_compilation/dep_d1_ops.d(366): Error: operator `+=` not supported for `c` of type `C`
+fail_compilation/dep_d1_ops.d(225): perhaps implement `auto opOpAssign(string op : "+")(int) {}`
+fail_compilation/dep_d1_ops.d(367): Error: operator `-=` not supported for `c` of type `C`
+fail_compilation/dep_d1_ops.d(225): perhaps implement `auto opOpAssign(string op : "-")(int) {}`
+fail_compilation/dep_d1_ops.d(368): Error: operator `*=` not supported for `c` of type `C`
+fail_compilation/dep_d1_ops.d(225): perhaps implement `auto opOpAssign(string op : "*")(int) {}`
+fail_compilation/dep_d1_ops.d(369): Error: operator `/=` not supported for `c` of type `C`
+fail_compilation/dep_d1_ops.d(225): perhaps implement `auto opOpAssign(string op : "/")(int) {}`
+fail_compilation/dep_d1_ops.d(370): Error: operator `%=` not supported for `c` of type `C`
+fail_compilation/dep_d1_ops.d(225): perhaps implement `auto opOpAssign(string op : "%")(int) {}`
+fail_compilation/dep_d1_ops.d(371): Error: operator `&=` not supported for `c` of type `C`
+fail_compilation/dep_d1_ops.d(225): perhaps implement `auto opOpAssign(string op : "&")(int) {}`
+fail_compilation/dep_d1_ops.d(372): Error: operator `|=` not supported for `c` of type `C`
+fail_compilation/dep_d1_ops.d(225): perhaps implement `auto opOpAssign(string op : "|")(int) {}`
+fail_compilation/dep_d1_ops.d(373): Error: operator `^=` not supported for `c` of type `C`
+fail_compilation/dep_d1_ops.d(225): perhaps implement `auto opOpAssign(string op : "^")(int) {}`
+fail_compilation/dep_d1_ops.d(374): Error: operator `<<=` not supported for `c` of type `C`
+fail_compilation/dep_d1_ops.d(225): perhaps implement `auto opOpAssign(string op : "<<")(int) {}`
+fail_compilation/dep_d1_ops.d(375): Error: operator `>>=` not supported for `c` of type `C`
+fail_compilation/dep_d1_ops.d(225): perhaps implement `auto opOpAssign(string op : ">>")(int) {}`
+fail_compilation/dep_d1_ops.d(376): Error: operator `>>>=` not supported for `c` of type `C`
+fail_compilation/dep_d1_ops.d(225): perhaps implement `auto opOpAssign(string op : ">>>")(int) {}`
+fail_compilation/dep_d1_ops.d(377): Error: operator `~=` not supported for `c` of type `C`
+fail_compilation/dep_d1_ops.d(225): perhaps implement `auto opOpAssign(string op : "~")(int) {}`
+fail_compilation/dep_d1_ops.d(386): Error: operator `~` is not defined for `NoDeprecation`
+fail_compilation/dep_d1_ops.d(390): perhaps overload the operator with `auto opUnary(string op : "~")() {}`
---
*/
/*
TEST_OUTPUT:
---
-fail_compilation/diag12063.d(19): Error: cannot check `diag12063.Bar.b` value for overflow
-fail_compilation/diag12063.d(16): Error: no property `max` for type `Foo`, perhaps `import std.algorithm;` is needed?
-fail_compilation/diag12063.d(19): Error: cannot generate value for `diag12063.Bar.b`
-fail_compilation/diag12063.d(19): Error: incompatible types for `(Foo()) + (1)`: `Bar` and `int`
-fail_compilation/diag12063.d(29): Error: cannot check `diag12063.b` value for overflow
-fail_compilation/diag12063.d(29): Error: incompatible types for `(S()) == (1)`: `S` and `int`
-fail_compilation/diag12063.d(38): Error: enum member `diag12063.d` initialization with `__anonymous.c+1` causes overflow for type `Q`
+fail_compilation/diag12063.d(21): Error: cannot check `diag12063.Bar.b` value for overflow
+fail_compilation/diag12063.d(18): Error: no property `max` for type `Foo`, perhaps `import std.algorithm;` is needed?
+fail_compilation/diag12063.d(21): Error: cannot generate value for `diag12063.Bar.b`
+fail_compilation/diag12063.d(21): Error: operator `+` is not defined for type `Bar`
+fail_compilation/diag12063.d(16): perhaps overload the operator with `auto opBinary(string op : "+")(int rhs) {}`
+fail_compilation/diag12063.d(31): Error: cannot check `diag12063.b` value for overflow
+fail_compilation/diag12063.d(31): Error: no operator `==` for type `S`
+fail_compilation/diag12063.d(24): perhaps overload it with `bool opEquals(int other) const {}`
+fail_compilation/diag12063.d(40): Error: enum member `diag12063.d` initialization with `__anonymous.c+1` causes overflow for type `Q`
---
*/
/*
TEST_OUTPUT:
---
-fail_compilation/diag13320.d(13): Error: `f` is not a scalar, it is a `Foo`
+fail_compilation/diag13320.d(14): Error: operator `++` not supported for `f` of type `Foo`
+fail_compilation/diag13320.d(9): perhaps implement `auto opUnary(string op : "++")() {}` or `auto opOpAssign(string op : "+")(int) {}`
---
*/
/*
TEST_OUTPUT:
---
-fail_compilation/diag16499.d(22): Error: incompatible types for `(2) in (foo)`: `int` and `A`
-fail_compilation/diag16499.d(24): Error: incompatible types for `(1.0) in (bar)`: `double` and `B`
+fail_compilation/diag16499.d(24): Error: operator `in` is not defined for type `A`
+fail_compilation/diag16499.d(11): perhaps overload the operator with `auto opBinaryRight(string op : "in")(int rhs) {}`
+fail_compilation/diag16499.d(26): Error: operator `in` is not defined for type `B`
+fail_compilation/diag16499.d(12): perhaps overload the operator with `auto opBinaryRight(string op : "in")(double rhs) {}`
---
*/
/*
TEST_OUTPUT:
---
-fail_compilation/fail10964.d(28): Error: function `fail10964.S.__postblit` is not `nothrow`
-fail_compilation/fail10964.d(29): Error: function `fail10964.S.__postblit` is not `nothrow`
-fail_compilation/fail10964.d(30): Error: function `fail10964.S.__postblit` is not `nothrow`
-fail_compilation/fail10964.d(33): Error: function `fail10964.S.__postblit` is not `nothrow`
-fail_compilation/fail10964.d(34): Error: function `fail10964.S.__postblit` is not `nothrow`
-fail_compilation/fail10964.d(35): Error: function `fail10964.S.__postblit` is not `nothrow`
+fail_compilation/fail10964.d(28): Error: function `fail10964.S.this(this)` is not `nothrow`
+fail_compilation/fail10964.d(29): Error: function `fail10964.S.this(this)` is not `nothrow`
+fail_compilation/fail10964.d(30): Error: function `fail10964.S.this(this)` is not `nothrow`
+fail_compilation/fail10964.d(33): Error: function `fail10964.S.this(this)` is not `nothrow`
+fail_compilation/fail10964.d(34): Error: function `fail10964.S.this(this)` is not `nothrow`
+fail_compilation/fail10964.d(35): Error: function `fail10964.S.this(this)` is not `nothrow`
fail_compilation/fail10964.d(22): Error: function `fail10964.foo` may throw but is marked as `nothrow`
---
*/
/*
TEST_OUTPUT:
---
-fail_compilation/fail10968.d(43): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(43): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(31): `fail10968.SA.__postblit` is declared here
-fail_compilation/fail10968.d(44): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(44): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(31): `fail10968.SA.__postblit` is declared here
-fail_compilation/fail10968.d(44): Error: `pure` function `fail10968.bar` cannot call impure function `core.internal.array.arrayassign._d_arraysetassign!(SA[], SA)._d_arraysetassign`
-$p:druntime/import/core/internal/array/arrayassign.d$($n$): which calls `core.lifetime.copyEmplace!(SA, SA).copyEmplace`
-$p:druntime/import/core/lifetime.d$($n$): which calls `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(45): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(45): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(31): `fail10968.SA.__postblit` is declared here
-fail_compilation/fail10968.d(45): Error: `pure` function `fail10968.bar` cannot call impure function `core.internal.array.arrayassign._d_arrayassign_l!(SA[], SA)._d_arrayassign_l`
-$p:druntime/import/core/internal/array/arrayassign.d$-mixin-$n$($n$): which calls `core.lifetime.copyEmplace!(SA, SA).copyEmplace`
-$p:druntime/import/core/lifetime.d$($n$): which calls `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(48): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(48): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(31): `fail10968.SA.__postblit` is declared here
-fail_compilation/fail10968.d(49): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(49): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(31): `fail10968.SA.__postblit` is declared here
-fail_compilation/fail10968.d(49): Error: `pure` function `fail10968.bar` cannot call impure function `core.internal.array.construction._d_arraysetctor!(SA[], SA)._d_arraysetctor`
-$p:druntime/import/core/internal/array/construction.d$($n$): which calls `core.lifetime.copyEmplace!(SA, SA).copyEmplace`
-$p:druntime/import/core/lifetime.d$($n$): which calls `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(50): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(50): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(31): `fail10968.SA.__postblit` is declared here
-fail_compilation/fail10968.d(50): Error: `pure` function `fail10968.bar` cannot call impure function `core.internal.array.construction._d_arrayctor!(SA[], SA)._d_arrayctor`
-$p:druntime/import/core/internal/array/construction.d$($n$): which calls `core.lifetime.copyEmplace!(SA, SA).copyEmplace`
-$p:druntime/import/core/lifetime.d$($n$): which calls `fail10968.SA.__postblit`
+fail_compilation/fail10968.d(43): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.this(this)`
+fail_compilation/fail10968.d(43): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.this(this)`
+fail_compilation/fail10968.d(31): `fail10968.SA.this(this)` is declared here
+fail_compilation/fail10968.d(44): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.this(this)`
+fail_compilation/fail10968.d(44): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.this(this)`
+fail_compilation/fail10968.d(31): `fail10968.SA.this(this)` is declared here
+fail_compilation/fail10968.d(45): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.this(this)`
+fail_compilation/fail10968.d(45): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.this(this)`
+fail_compilation/fail10968.d(31): `fail10968.SA.this(this)` is declared here
+fail_compilation/fail10968.d(48): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.this(this)`
+fail_compilation/fail10968.d(48): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.this(this)`
+fail_compilation/fail10968.d(31): `fail10968.SA.this(this)` is declared here
+fail_compilation/fail10968.d(49): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.this(this)`
+fail_compilation/fail10968.d(49): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.this(this)`
+fail_compilation/fail10968.d(31): `fail10968.SA.this(this)` is declared here
+fail_compilation/fail10968.d(50): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.this(this)`
+fail_compilation/fail10968.d(50): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.this(this)`
+fail_compilation/fail10968.d(31): `fail10968.SA.this(this)` is declared here
---
*/
/*
TEST_OUTPUT:
---
-fail_compilation/fail18143.d(20): Error: variable `fail18143.S.a` cannot modify parameter `this` in contract
-fail_compilation/fail18143.d(21): Error: variable `fail18143.S.a` cannot modify parameter `this` in contract
-fail_compilation/fail18143.d(25): Error: variable `fail18143.S.a` cannot modify parameter `this` in contract
-fail_compilation/fail18143.d(26): Error: variable `fail18143.S.a` cannot modify parameter `this` in contract
-fail_compilation/fail18143.d(35): Error: variable `fail18143.C.a` cannot modify parameter `this` in contract
-fail_compilation/fail18143.d(36): Error: variable `fail18143.C.a` cannot modify parameter `this` in contract
-fail_compilation/fail18143.d(40): Error: variable `fail18143.C.a` cannot modify parameter `this` in contract
-fail_compilation/fail18143.d(41): Error: variable `fail18143.C.a` cannot modify parameter `this` in contract
+fail_compilation/fail18143.d(20): Error: cannot modify member variable `fail18143.S.a` in contract
+fail_compilation/fail18143.d(21): Error: cannot modify member variable `fail18143.S.a` in contract
+fail_compilation/fail18143.d(25): Error: cannot modify member variable `fail18143.S.a` in contract
+fail_compilation/fail18143.d(26): Error: cannot modify member variable `fail18143.S.a` in contract
+fail_compilation/fail18143.d(35): Error: cannot modify member variable `fail18143.C.a` in contract
+fail_compilation/fail18143.d(36): Error: cannot modify member variable `fail18143.C.a` in contract
+fail_compilation/fail18143.d(40): Error: cannot modify member variable `fail18143.C.a` in contract
+fail_compilation/fail18143.d(41): Error: cannot modify member variable `fail18143.C.a` in contract
---
*/
/*
TEST_OUTPUT:
---
-fail_compilation/fail18985.d(16): Error: `foo` is not a scalar, it is a `object.Object`
-fail_compilation/fail18985.d(17): Error: `bar` is not a scalar, it is a `shared(Object)`
+fail_compilation/fail18985.d(20): Error: operator `+=` not supported for `foo` of type `C`
+fail_compilation/fail18985.d(13): perhaps implement `auto opOpAssign(string op : "+")(int) {}`
+fail_compilation/fail18985.d(21): Error: operator `+=` not supported for `bar` of type `C`
+fail_compilation/fail18985.d(13): perhaps implement `auto opOpAssign(string op : "+")(int) {}`
---
*/
// https://issues.dlang.org/show_bug.cgi?id=18985
-Object foo;
-shared Object bar;
+class C {}
+
+C foo;
+shared C bar;
void main()
{
/*
TEST_OUTPUT:
---
-fail_compilation/fail20.d(16): Error: need member function `opCmp()` for struct `FOO` to compare
+fail_compilation/fail20.d(17): Error: no operator `<` for type `FOO`
+fail_compilation/fail20.d(11): perhaps overload it with `int opCmp(FOO other) const {}`
---
*/
TEST_OUTPUT:
---
fail_compilation/fail20616.d(16): Error: undefined identifier `$`
-fail_compilation/fail20616.d(16): Aggregate declaration 'X()' does not define 'opDollar'
+fail_compilation/fail20616.d(13): perhaps define `opDollar` for `X`
fail_compilation/fail20616.d(18): Error: undefined identifier `$`
-fail_compilation/fail20616.d(18): Aggregate declaration 'b' does not define 'opDollar'
+fail_compilation/fail20616.d(13): perhaps define `opDollar` for `X`
---
*/
module fail20616;
/*
TEST_OUTPUT:
---
-fail_compilation/fail297.d(30): Error: operator `+` is not defined for `Bar()` of type `Bar`
+fail_compilation/fail297.d(31): Error: operator `+` is not defined for type `Bar`
+fail_compilation/fail297.d(25): perhaps overload the operator with `auto opBinary(string op : "+")(const(Bar) rhs) {}`
---
*/
/*
TEST_OUTPUT:
---
-fail_compilation/fail3.d(41): Error: operator `+` is not defined for `a` of type `vec2`
+fail_compilation/fail3.d(42): Error: operator `+` is not defined for type `vec2`
+fail_compilation/fail3.d(13): perhaps overload the operator with `auto opBinary(string op : "+")(vec2 rhs) {}`
---
*/
/*
TEST_OUTPUT:
---
-fail_compilation/fail3672.d(28): Error: read-modify-write operations are not allowed for `shared` variables
-fail_compilation/fail3672.d(28): Use `core.atomic.atomicOp!"+="(*p, 1)` instead
-fail_compilation/fail3672.d(32): Error: none of the `opOpAssign` overloads of `SF` are callable for `*sfp` of type `shared(SF)`
+fail_compilation/fail3672.d(29): Error: read-modify-write operations are not allowed for `shared` variables
+fail_compilation/fail3672.d(29): Use `core.atomic.atomicOp!"+="(*p, 1)` instead
+fail_compilation/fail3672.d(33): Error: template `opOpAssign` is not callable using argument types `!("+")(int) shared`
+fail_compilation/fail3672.d(13): Candidate is: `opOpAssign(string op, T)(T rhs)`
---
*/
/*
TEST_OUTPUT:
---
-fail_compilation/fail4421.d(16): Error: function `fail4421.U1.__postblit` destructors, postblits and invariants are not allowed in union `U1`
+fail_compilation/fail4421.d(16): Error: function `fail4421.U1.this(this)` destructors, postblits and invariants are not allowed in union `U1`
fail_compilation/fail4421.d(17): Error: destructor `fail4421.U1.~this` destructors, postblits and invariants are not allowed in union `U1`
-fail_compilation/fail4421.d(18): Error: function `fail4421.U1.__invariant1` destructors, postblits and invariants are not allowed in union `U1`
+fail_compilation/fail4421.d(18): Error: function `fail4421.U1.invariant` destructors, postblits and invariants are not allowed in union `U1`
---
/*
TEST_OUTPUT:
---
-fail_compilation/fail6107.d(10): Error: variable `fail6107.Foo.__ctor` is not a constructor; identifiers starting with `__` are reserved for the implementation
-fail_compilation/fail6107.d(14): Error: variable `fail6107.Bar.__ctor` is not a constructor; identifiers starting with `__` are reserved for the implementation
+fail_compilation/fail6107.d(12): Error: variable name `__ctor` is not allowed
+fail_compilation/fail6107.d(12): identifiers starting with `__` are reserved for internal use
+fail_compilation/fail6107.d(16): Error: variable name `__ctor` is not allowed
+fail_compilation/fail6107.d(16): identifiers starting with `__` are reserved for internal use
---
*/
struct Foo
fail_compilation/fail7848.d(27): Error: `@nogc` function `fail7848.C.__unittest_L25_C30` cannot call non-@nogc function `fail7848.func`
fail_compilation/fail7848.d(27): Error: function `fail7848.func` is not `nothrow`
fail_compilation/fail7848.d(25): Error: function `fail7848.C.__unittest_L25_C30` may throw but is marked as `nothrow`
-fail_compilation/fail7848.d(32): Error: `pure` function `fail7848.C.__invariant0` cannot call impure function `fail7848.func`
-fail_compilation/fail7848.d(32): Error: `@safe` function `fail7848.C.__invariant0` cannot call `@system` function `fail7848.func`
+fail_compilation/fail7848.d(32): Error: `pure` function `fail7848.C.invariant` cannot call impure function `fail7848.func`
+fail_compilation/fail7848.d(32): Error: `@safe` function `fail7848.C.invariant` cannot call `@system` function `fail7848.func`
fail_compilation/fail7848.d(21): `fail7848.func` is declared here
-fail_compilation/fail7848.d(32): Error: `@nogc` function `fail7848.C.__invariant0` cannot call non-@nogc function `fail7848.func`
+fail_compilation/fail7848.d(32): Error: `@nogc` function `fail7848.C.invariant` cannot call non-@nogc function `fail7848.func`
fail_compilation/fail7848.d(32): Error: function `fail7848.func` is not `nothrow`
-fail_compilation/fail7848.d(30): Error: function `fail7848.C.__invariant0` may throw but is marked as `nothrow`
+fail_compilation/fail7848.d(30): Error: function `fail7848.C.invariant` may throw but is marked as `nothrow`
---
*/
fail_compilation/fail_arrayexp.d(26): Error: static array of `const(int)[]` with multiple lengths not allowed
fail_compilation/fail_arrayexp.d(27): Error: only one index allowed to index `string`
fail_compilation/fail_arrayexp.d(28): Error: no `[]` operator overload for type `U`
-fail_compilation/fail_arrayexp.d(16): `fail_arrayexp.U` declared here
+fail_compilation/fail_arrayexp.d(16): perhaps define `auto opIndex() {}` for `fail_arrayexp.U`
fail_compilation/fail_arrayexp.d(29): Error: only one index allowed to index `(int, string)`
---
*/
auto t = agg[];
auto u = getTuple!(int, string)[1, 2];
}
+
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fail_arrayexp.d(49): Error: no `[3.."4"]` operator overload for type `S`
+fail_compilation/fail_arrayexp.d(42): perhaps define `auto opSlice(int lower, string upper) {}` for `fail_arrayexp.S`
+fail_compilation/fail_arrayexp.d(50): Error: no `[]` operator overload for type `S`
+fail_compilation/fail_arrayexp.d(42): perhaps define `auto opIndex(int, string, char) {}` for `fail_arrayexp.S`
+---
+*/
+
+struct S
+{
+}
+
+void testSlice()
+{
+ S s;
+ const b = s[3 .. "4"];
+ const c = s[3, "4", 'c'];
+}
TEST_OUTPUT:
---
fail_compilation/fail_opover.d(39): Error: no `[]` operator overload for type `object.Object`
-$p:object.d$(110): `object.Object` declared here
+$p:object.d$(110): perhaps define `auto opIndex() {}` for `object.Object`
fail_compilation/fail_opover.d(43): Error: no `[]` operator overload for type `TestS`
-fail_compilation/fail_opover.d(41): `fail_opover.test1.TestS` declared here
+fail_compilation/fail_opover.d(41): perhaps define `auto opIndex() {}` for `fail_opover.test1.TestS`
fail_compilation/fail_opover.d(55): Error: no `[]` operator overload for type `S`
-fail_compilation/fail_opover.d(48): `fail_opover.test2.S` declared here
+fail_compilation/fail_opover.d(48): perhaps define `auto opIndex() {}` for `fail_opover.test2.S`
fail_compilation/fail_opover.d(56): Error: no `[]` operator overload for type `S`
-fail_compilation/fail_opover.d(48): `fail_opover.test2.S` declared here
-fail_compilation/fail_opover.d(57): Error: no `[]` operator overload for type `S`
-fail_compilation/fail_opover.d(48): `fail_opover.test2.S` declared here
+fail_compilation/fail_opover.d(48): perhaps define `auto opIndex(int) {}` for `fail_opover.test2.S`
+fail_compilation/fail_opover.d(57): Error: no `[1..2]` operator overload for type `S`
+fail_compilation/fail_opover.d(48): perhaps define `auto opSlice(int lower, int upper) {}` for `fail_opover.test2.S`
fail_compilation/fail_opover.d(58): Error: no `[]` operator overload for type `S`
-fail_compilation/fail_opover.d(48): `fail_opover.test2.S` declared here
+fail_compilation/fail_opover.d(48): perhaps define `auto opIndex() {}` for `fail_opover.test2.S`
fail_compilation/fail_opover.d(59): Error: no `[]` operator overload for type `S`
-fail_compilation/fail_opover.d(48): `fail_opover.test2.S` declared here
-fail_compilation/fail_opover.d(60): Error: no `[]` operator overload for type `S`
-fail_compilation/fail_opover.d(48): `fail_opover.test2.S` declared here
+fail_compilation/fail_opover.d(48): perhaps define `auto opIndex(int) {}` for `fail_opover.test2.S`
+fail_compilation/fail_opover.d(60): Error: no `[1..2]` operator overload for type `S`
+fail_compilation/fail_opover.d(48): perhaps define `auto opSlice(int lower, int upper) {}` for `fail_opover.test2.S`
fail_compilation/fail_opover.d(61): Error: no `[]` operator overload for type `S`
-fail_compilation/fail_opover.d(48): `fail_opover.test2.S` declared here
+fail_compilation/fail_opover.d(48): perhaps define `auto opIndex() {}` for `fail_opover.test2.S`
fail_compilation/fail_opover.d(62): Error: no `[]` operator overload for type `S`
-fail_compilation/fail_opover.d(48): `fail_opover.test2.S` declared here
-fail_compilation/fail_opover.d(63): Error: no `[]` operator overload for type `S`
-fail_compilation/fail_opover.d(48): `fail_opover.test2.S` declared here
+fail_compilation/fail_opover.d(48): perhaps define `auto opIndex(int) {}` for `fail_opover.test2.S`
+fail_compilation/fail_opover.d(63): Error: no `[1..2]` operator overload for type `S`
+fail_compilation/fail_opover.d(48): perhaps define `auto opSlice(int lower, int upper) {}` for `fail_opover.test2.S`
fail_compilation/fail_opover.d(64): Error: no `[]` operator overload for type `S`
-fail_compilation/fail_opover.d(48): `fail_opover.test2.S` declared here
+fail_compilation/fail_opover.d(48): perhaps define `auto opIndex() {}` for `fail_opover.test2.S`
fail_compilation/fail_opover.d(65): Error: no `[]` operator overload for type `S`
-fail_compilation/fail_opover.d(48): `fail_opover.test2.S` declared here
-fail_compilation/fail_opover.d(66): Error: no `[]` operator overload for type `S`
-fail_compilation/fail_opover.d(48): `fail_opover.test2.S` declared here
+fail_compilation/fail_opover.d(48): perhaps define `auto opIndex(int) {}` for `fail_opover.test2.S`
+fail_compilation/fail_opover.d(66): Error: no `[1..2]` operator overload for type `S`
+fail_compilation/fail_opover.d(48): perhaps define `auto opSlice(int lower, int upper) {}` for `fail_opover.test2.S`
---
*/
void test1()
/*
TEST_OUTPUT:
---
-fail_compilation/ice10624.d(38): Error: need member function `opCmp()` for struct `Tuple!(Msg)` to compare
-fail_compilation/ice10624.d(48): Error: template instance `ice10624.Variant.handler!(Tuple!(Msg))` error instantiating
-fail_compilation/ice10624.d(21): instantiated from here: `opAssign!(Tuple!(Msg))`
+fail_compilation/ice10624.d(39): Error: no operator `<` for type `Tuple`
+fail_compilation/ice10624.d(13): perhaps overload it with `int opCmp(Tuple!(Msg) other) const {}`
+fail_compilation/ice10624.d(49): Error: template instance `ice10624.Variant.handler!(Tuple!(Msg))` error instantiating
+fail_compilation/ice10624.d(22): instantiated from here: `opAssign!(Tuple!(Msg))`
---
*/
/*
TEST_OUTPUT:
---
-fail_compilation/ice12902.d(20): Error: variable `ice12902.main.__dollar` - type `void` is inferred from initializer `s.opDollar()`, and variables cannot be of type `void`
+fail_compilation/ice12902.d(20): Error: variable `ice12902.main.$` - type `void` is inferred from initializer `s.opDollar()`, and variables cannot be of type `void`
fail_compilation/ice12902.d(20): Error: expression `s.opDollar()` is `void` and has no value
---
*/
/*
TEST_OUTPUT:
----
-fail_compilation/ice9545.d(13): Error: type `int` has no value
+fail_compilation/ice9545.d(14): Error: type `int` has no value
+fail_compilation/ice9545.d(14): perhaps use `int.init`
----
*/
/*
TEST_OUTPUT:
---
-fail_compilation/operator_undefined.d(19): Error: operator `-` is not defined for `toJson(2)` of type `Json`
+fail_compilation/operator_undefined.d(20): Error: operator `-` is not defined for `Json`
+fail_compilation/operator_undefined.d(11): perhaps overload the operator with `auto opUnary(string op : "-")() {}`
---
*/
--- /dev/null
+/*
+REQUIRED_ARGS: -de
+
+TEST_OUTPUT:
+---
+fail_compilation/test20763.d(25): Deprecation: type `ulong` has no value
+fail_compilation/test20763.d(25): perhaps use `ulong.init`
+fail_compilation/test20763.d(26): Deprecation: type `ulong` has no value
+fail_compilation/test20763.d(26): perhaps use `ulong.init`
+fail_compilation/test20763.d(27): Error: type `ulong` has no value
+fail_compilation/test20763.d(27): perhaps use `ulong.init`
+fail_compilation/test20763.d(28): Error: type `ulong` has no value
+fail_compilation/test20763.d(28): perhaps use `ulong.init`
+fail_compilation/test20763.d(29): Error: type `ulong` has no value
+fail_compilation/test20763.d(29): perhaps use `ulong.init`
+fail_compilation/test20763.d(30): Error: type `ulong` has no value
+fail_compilation/test20763.d(30): perhaps use `ulong.init`
+---
+*/
+
+// https://github.com/dlang/dmd/issues/20763
+void test()
+{
+ alias I = ulong;
+ alias U0 = typeof(I + 1u);
+ alias U1 = typeof(1 - I);
+ alias U2 = typeof(+I);
+ alias U3 = typeof(I * 1);
+ alias U4 = typeof(I << 1);
+ alias U5 = typeof(I | 1);
+}
TEST_OUTPUT:
---
fail_compilation/imports/imp22329.d(3): Error: no property `values` for type `test22329.Foo`
-fail_compilation/test22329.d(13): struct `Foo` defined here
-fail_compilation/imports/imp22329.d(3): Error: incompatible types for `(arg) + (1)`: `Foo` and `int`
-fail_compilation/test22329.d(21): Error: template instance `imp22329.func!(Foo)` error instantiating
+fail_compilation/test22329.d(14): struct `Foo` defined here
+fail_compilation/imports/imp22329.d(3): Error: operator `+` is not defined for type `Foo`
+fail_compilation/test22329.d(14): perhaps overload the operator with `auto opBinary(string op : "+")(int rhs) {}`
+fail_compilation/test22329.d(22): Error: template instance `imp22329.func!(Foo)` error instantiating
---
*/
-b7e3b3b61711bf6c6cad27c7b5b73df0e570c215
+d29e3eca45edaeef63b31f78c9846fc6e2870c49
The first line of this file holds the git revision number of the last
merge done from the dlang/dmd repository.
return cast(int) x;
}
+version (DigitalMars) version (AArch64)
+{
+ int _popcnt(ulong x) pure;
+}
+
version (DigitalMars) version (AnyX86)
{
/**
}
}
-bool NT_SUCCESS(int x) { return x >= 0; }
+pragma(inline, true) @safe pure nothrow @nogc {
+ bool NT_SUCCESS(NTSTATUS Status) { return Status >= 0; }
+ bool NT_INFORMATION(NTSTATUS Status) { return ((cast(ULONG) Status) >> 30) == 1; }
+ bool NT_WARNING(NTSTATUS Status) { return ((cast(ULONG) Status) >> 30) == 2; }
+ bool NT_ERROR(NTSTATUS Status) { return ((cast(ULONG) Status) >> 30) == 3; }
+}
/* In MinGW, NTSTATUS, UNICODE_STRING, STRING and their associated pointer
* type aliases are defined in ntdef.h, ntsecapi.h and subauth.h, each of