d: Merge upstream dmd, druntime 17ccd12af3, phobos 8d3800bee.
D front-end changes: - Import dmd v2.104.0. - Assignment-style syntax is now allowed for `alias this'. - Overloading `extern(C)' functions is now an error. D runtime changes: - Import druntime v2.104.0. Phobos changes: - Import phobos v2.104.0. - Better static assert messages when instantiating `std.algorithm.iteration.permutations' with wrong inputs. - Added `std.system.instructionSetArchitecture' and `std.system.ISA'. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd 17ccd12af3. * dmd/VERSION: Bump version to v2.104.0. * Make-lang.in (D_FRONTEND_OBJS): Rename d/apply.o to d/postordervisitor.o. * d-codegen.cc (make_location_t): Update for new front-end interface. (build_filename_from_loc): Likewise. (build_assert_call): Likewise. (build_array_bounds_call): Likewise. (build_bounds_index_condition): Likewise. (build_bounds_slice_condition): Likewise. (build_frame_type): Likewise. (get_frameinfo): Likewise. * d-diagnostic.cc (d_diagnostic_report_diagnostic): Likewise. * decl.cc (build_decl_tree): Likewise. (start_function): Likewise. * expr.cc (ExprVisitor::visit (NewExp *)): Replace code generation of `new pointer' with front-end lowering. * runtime.def (NEWITEMT): Remove. (NEWITEMIT): Remove. * toir.cc (IRVisitor::visit (LabelStatement *)): Update for new front-end interface. * typeinfo.cc (check_typeinfo_type): Likewise. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime 17ccd12af3. * src/MERGE: Merge upstream phobos 8d3800bee. gcc/testsuite/ChangeLog: * gdc.dg/asm4.d: Update test.
This commit is contained in:
parent
d41a57c46d
commit
0cafc3b627
147 changed files with 1849 additions and 929 deletions
|
@ -81,7 +81,6 @@ D_FRONTEND_OBJS = \
|
|||
d/access.o \
|
||||
d/aggregate.o \
|
||||
d/aliasthis.o \
|
||||
d/apply.o \
|
||||
d/arrayop.o \
|
||||
d/arraytypes.o \
|
||||
d/attrib.o \
|
||||
|
@ -160,6 +159,7 @@ D_FRONTEND_OBJS = \
|
|||
d/parse.o \
|
||||
d/parsetimevisitor.o \
|
||||
d/permissivevisitor.o \
|
||||
d/postordervisitor.o \
|
||||
d/printast.o \
|
||||
d/root-aav.o \
|
||||
d/root-array.o \
|
||||
|
|
|
@ -50,11 +50,11 @@ make_location_t (const Loc &loc)
|
|||
{
|
||||
location_t gcc_location = input_location;
|
||||
|
||||
if (loc.filename)
|
||||
if (const char *filename = loc.filename ())
|
||||
{
|
||||
linemap_add (line_table, LC_ENTER, 0, loc.filename, loc.linnum);
|
||||
linemap_line_start (line_table, loc.linnum, 0);
|
||||
gcc_location = linemap_position_for_column (line_table, loc.charnum);
|
||||
linemap_add (line_table, LC_ENTER, 0, filename, loc.linnum ());
|
||||
linemap_line_start (line_table, loc.linnum (), 0);
|
||||
gcc_location = linemap_position_for_column (line_table, loc.charnum ());
|
||||
linemap_add (line_table, LC_LEAVE, 0, NULL, 0);
|
||||
}
|
||||
|
||||
|
@ -1872,8 +1872,10 @@ void_okay_p (tree t)
|
|||
static tree
|
||||
build_filename_from_loc (const Loc &loc)
|
||||
{
|
||||
const char *filename = loc.filename
|
||||
? loc.filename : d_function_chain->module->srcfile.toChars ();
|
||||
const char *filename = loc.filename ();
|
||||
|
||||
if (filename == NULL)
|
||||
filename = d_function_chain->module->srcfile.toChars ();
|
||||
|
||||
unsigned length = strlen (filename);
|
||||
tree str = build_string (length, filename);
|
||||
|
@ -1890,17 +1892,17 @@ tree
|
|||
build_assert_call (const Loc &loc, libcall_fn libcall, tree msg)
|
||||
{
|
||||
tree file;
|
||||
tree line = size_int (loc.linnum);
|
||||
tree line = size_int (loc.linnum ());
|
||||
|
||||
switch (libcall)
|
||||
{
|
||||
case LIBCALL_ASSERT_MSG:
|
||||
case LIBCALL_UNITTEST_MSG:
|
||||
/* File location is passed as a D string. */
|
||||
if (loc.filename)
|
||||
if (const char *filename = loc.filename ())
|
||||
{
|
||||
unsigned len = strlen (loc.filename);
|
||||
tree str = build_string (len, loc.filename);
|
||||
unsigned len = strlen (filename);
|
||||
tree str = build_string (len, filename);
|
||||
TREE_TYPE (str) = make_array_type (Type::tchar, len);
|
||||
|
||||
file = d_array_value (build_ctype (Type::tchar->arrayOf ()),
|
||||
|
@ -1939,7 +1941,7 @@ build_array_bounds_call (const Loc &loc)
|
|||
{
|
||||
return build_libcall (LIBCALL_ARRAYBOUNDSP, Type::tvoid, 2,
|
||||
build_filename_from_loc (loc),
|
||||
size_int (loc.linnum));
|
||||
size_int (loc.linnum ()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1968,7 +1970,8 @@ build_bounds_index_condition (IndexExp *ie, tree index, tree length)
|
|||
{
|
||||
boundserr = build_libcall (LIBCALL_ARRAYBOUNDS_INDEXP, Type::tvoid, 4,
|
||||
build_filename_from_loc (ie->e2->loc),
|
||||
size_int (ie->e2->loc.linnum), index, length);
|
||||
size_int (ie->e2->loc.linnum ()),
|
||||
index, length);
|
||||
}
|
||||
|
||||
return build_condition (TREE_TYPE (index), condition, boundserr, index);
|
||||
|
@ -2017,7 +2020,7 @@ build_bounds_slice_condition (SliceExp *se, tree lower, tree upper, tree length)
|
|||
boundserr = build_libcall (LIBCALL_ARRAYBOUNDS_SLICEP,
|
||||
Type::tvoid, 5,
|
||||
build_filename_from_loc (se->loc),
|
||||
size_int (se->loc.linnum),
|
||||
size_int (se->loc.linnum ()),
|
||||
lower, upper, length);
|
||||
}
|
||||
|
||||
|
@ -2659,8 +2662,8 @@ build_frame_type (tree ffi, FuncDeclaration *fd)
|
|||
of the calling function non-locally. So we add all parameters with nested
|
||||
refs to the function frame, this should also mean overriding methods will
|
||||
have the same frame layout when inheriting a contract. */
|
||||
if ((global.params.useIn == CHECKENABLEon && fd->frequire)
|
||||
|| (global.params.useOut == CHECKENABLEon && fd->fensure))
|
||||
if ((global.params.useIn == CHECKENABLEon && fd->frequire ())
|
||||
|| (global.params.useOut == CHECKENABLEon && fd->fensure ()))
|
||||
{
|
||||
if (fd->parameters)
|
||||
{
|
||||
|
@ -2870,8 +2873,8 @@ get_frameinfo (FuncDeclaration *fd)
|
|||
|
||||
/* In checkNestedReference, references from contracts are not added to the
|
||||
closureVars array, so assume all parameters referenced. */
|
||||
if ((global.params.useIn == CHECKENABLEon && fd->frequire)
|
||||
|| (global.params.useOut == CHECKENABLEon && fd->fensure))
|
||||
if ((global.params.useIn == CHECKENABLEon && fd->frequire ())
|
||||
|| (global.params.useOut == CHECKENABLEon && fd->fensure ()))
|
||||
FRAMEINFO_CREATES_FRAME (ffi) = 1;
|
||||
|
||||
/* If however `fd` is nested (deeply) in a function that creates a
|
||||
|
|
|
@ -189,7 +189,7 @@ d_diagnostic_report_diagnostic (const Loc &loc, int opt, const char *format,
|
|||
va_list argp;
|
||||
va_copy (argp, ap);
|
||||
|
||||
if (loc.filename || !verbatim)
|
||||
if (loc.filename () || !verbatim)
|
||||
{
|
||||
rich_location rich_loc (line_table, make_location_t (loc));
|
||||
diagnostic_info diagnostic;
|
||||
|
|
|
@ -1083,7 +1083,7 @@ build_decl_tree (Dsymbol *d)
|
|||
location_t saved_location = input_location;
|
||||
|
||||
/* Set input location, empty DECL_SOURCE_FILE can crash debug generator. */
|
||||
if (d->loc.filename)
|
||||
if (d->loc.filename ())
|
||||
input_location = make_location_t (d->loc);
|
||||
else
|
||||
input_location = make_location_t (Loc ("<no_file>", 1, 0));
|
||||
|
@ -2064,7 +2064,7 @@ start_function (FuncDeclaration *fd)
|
|||
allocate_struct_function (fndecl, false);
|
||||
|
||||
/* Store the end of the function. */
|
||||
if (fd->endloc.filename)
|
||||
if (fd->endloc.filename ())
|
||||
cfun->function_end_locus = make_location_t (fd->endloc);
|
||||
else
|
||||
cfun->function_end_locus = DECL_SOURCE_LOCATION (fndecl);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
28a3b24c2e45de39cd3df528142fd06b6456e8fd
|
||||
17ccd12af386543c0b9935bf7e0a8e701b903105
|
||||
|
||||
The first line of this file holds the git revision number of the last
|
||||
merge done from the dlang/dmd repository.
|
||||
|
|
|
@ -99,7 +99,7 @@ Note that these groups have no strict meaning, the category assignments are a bi
|
|||
| [strictvisitor.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/strictvisitor.d) | Visitor that forces derived classes to implement `visit` for every possible node |
|
||||
| [visitor.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/visitor.d) | A visitor implementing `visit` for all nodes present in the compiler |
|
||||
| [transitivevisitor.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/transitivevisitor.d) | Provide a mixin template with visit methods for the parse time AST |
|
||||
| [apply.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/apply.d) | Depth-first expression visitor |
|
||||
| [postordervisitor.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/postordervisitor.d) | Depth-first expression visitor |
|
||||
| [sapply.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/sapply.d) | Depth-first statement visitor |
|
||||
| [statement_rewrite_walker.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/statement_rewrite_walker.d) | Statement visitor that allows replacing the currently visited node |
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
v2.104.0-beta.1
|
||||
v2.104.0
|
||||
|
|
|
@ -18,7 +18,6 @@ import core.stdc.stdio;
|
|||
import core.checkedint;
|
||||
|
||||
import dmd.aliasthis;
|
||||
import dmd.apply;
|
||||
import dmd.arraytypes;
|
||||
import dmd.astenums;
|
||||
import dmd.attrib;
|
||||
|
@ -764,21 +763,18 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol
|
|||
if (s)
|
||||
{
|
||||
// Finish all constructors semantics to determine this.noDefaultCtor.
|
||||
struct SearchCtor
|
||||
static int searchCtor(Dsymbol s, void*)
|
||||
{
|
||||
extern (C++) static int fp(Dsymbol s, void* ctxt)
|
||||
{
|
||||
auto f = s.isCtorDeclaration();
|
||||
if (f && f.semanticRun == PASS.initial)
|
||||
f.dsymbolSemantic(null);
|
||||
return 0;
|
||||
}
|
||||
auto f = s.isCtorDeclaration();
|
||||
if (f && f.semanticRun == PASS.initial)
|
||||
f.dsymbolSemantic(null);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < members.length; i++)
|
||||
{
|
||||
auto sm = (*members)[i];
|
||||
sm.apply(&SearchCtor.fp, null);
|
||||
sm.apply(&searchCtor, null);
|
||||
}
|
||||
}
|
||||
return s;
|
||||
|
@ -814,3 +810,36 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol
|
|||
v.visit(this);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************
|
||||
* Iterate this dsymbol or members of this scoped dsymbol, then
|
||||
* call `fp` with the found symbol and `params`.
|
||||
* Params:
|
||||
* symbol = the dsymbol or parent of members to call fp on
|
||||
* fp = function pointer to process the iterated symbol.
|
||||
* If it returns nonzero, the iteration will be aborted.
|
||||
* ctx = context parameter passed to fp.
|
||||
* Returns:
|
||||
* nonzero if the iteration is aborted by the return value of fp,
|
||||
* or 0 if it's completed.
|
||||
*/
|
||||
int apply(Dsymbol symbol, int function(Dsymbol, void*) fp, void* ctx)
|
||||
{
|
||||
if (auto nd = symbol.isNspace())
|
||||
{
|
||||
return nd.members.foreachDsymbol( (s) { return s && s.apply(fp, ctx); } );
|
||||
}
|
||||
if (auto ad = symbol.isAttribDeclaration())
|
||||
{
|
||||
return ad.include(ad._scope).foreachDsymbol( (s) { return s && s.apply(fp, ctx); } );
|
||||
}
|
||||
if (auto tm = symbol.isTemplateMixin())
|
||||
{
|
||||
if (tm._scope) // if fwd reference
|
||||
dsymbolSemantic(tm, null); // try to resolve it
|
||||
|
||||
return tm.members.foreachDsymbol( (s) { return s && s.apply(fp, ctx); } );
|
||||
}
|
||||
|
||||
return fp(symbol, ctx);
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
module dmd.canthrow;
|
||||
|
||||
import dmd.aggregate;
|
||||
import dmd.apply;
|
||||
import dmd.arraytypes;
|
||||
import dmd.attrib;
|
||||
import dmd.astenums;
|
||||
|
@ -26,6 +25,7 @@ import dmd.func;
|
|||
import dmd.globals;
|
||||
import dmd.init;
|
||||
import dmd.mtype;
|
||||
import dmd.postordervisitor;
|
||||
import dmd.root.rootobject;
|
||||
import dmd.tokens;
|
||||
import dmd.visitor;
|
||||
|
@ -133,16 +133,9 @@ extern (C++) /* CT */ BE canThrow(Expression e, FuncDeclaration func, bool mustN
|
|||
*/
|
||||
if (ce.f && ce.f == func)
|
||||
return;
|
||||
Type t = ce.e1.type.toBasetype();
|
||||
auto tf = t.isTypeFunction();
|
||||
const tf = ce.calledFunctionType();
|
||||
if (tf && tf.isnothrow)
|
||||
return;
|
||||
else
|
||||
{
|
||||
auto td = t.isTypeDelegate();
|
||||
if (td && td.nextOf().isTypeFunction().isnothrow)
|
||||
return;
|
||||
}
|
||||
|
||||
if (ce.f)
|
||||
checkFuncThrows(ce, ce.f);
|
||||
|
|
|
@ -177,6 +177,8 @@ bool checkPrintfFormat(ref const Loc loc, scope const char[] format, scope Expre
|
|||
errorMsg(null, e, (c_longsize == 4 ? "uint" : "ulong"), t);
|
||||
else
|
||||
errorMsg(null, e, (c_longsize == 4 ? "int" : "long"), t);
|
||||
if (t.isintegral() && t.size() != c_longsize)
|
||||
errorSupplemental(e.loc, "C `long` is %d bytes on your system", c_longsize);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -106,18 +106,18 @@ FuncDeclaration hasIdentityOpAssign(AggregateDeclaration ad, Scope* sc)
|
|||
scope er = new NullExp(ad.loc, ad.type); // dummy rvalue
|
||||
scope el = new IdentifierExp(ad.loc, Id.p); // dummy lvalue
|
||||
el.type = ad.type;
|
||||
auto a = Expressions(1);
|
||||
auto a = new Expressions(1);
|
||||
const errors = global.startGagging(); // Do not report errors, even if the template opAssign fbody makes it.
|
||||
sc = sc.push();
|
||||
sc.tinst = null;
|
||||
sc.minst = null;
|
||||
|
||||
a[0] = er;
|
||||
auto f = resolveFuncCall(ad.loc, sc, assign, null, ad.type, ArgumentList(&a), FuncResolveFlag.quiet);
|
||||
(*a)[0] = er;
|
||||
auto f = resolveFuncCall(ad.loc, sc, assign, null, ad.type, ArgumentList(a), FuncResolveFlag.quiet);
|
||||
if (!f)
|
||||
{
|
||||
a[0] = el;
|
||||
f = resolveFuncCall(ad.loc, sc, assign, null, ad.type, ArgumentList(&a), FuncResolveFlag.quiet);
|
||||
(*a)[0] = el;
|
||||
f = resolveFuncCall(ad.loc, sc, assign, null, ad.type, ArgumentList(a), FuncResolveFlag.quiet);
|
||||
}
|
||||
|
||||
sc = sc.pop();
|
||||
|
@ -465,7 +465,7 @@ private FuncDeclaration hasIdentityOpEquals(AggregateDeclaration ad, Scope* sc)
|
|||
*/
|
||||
scope er = new NullExp(ad.loc, null); // dummy rvalue
|
||||
scope el = new IdentifierExp(ad.loc, Id.p); // dummy lvalue
|
||||
auto a = Expressions(1);
|
||||
auto a = new Expressions(1);
|
||||
|
||||
bool hasIt(Type tthis)
|
||||
{
|
||||
|
@ -476,9 +476,9 @@ private FuncDeclaration hasIdentityOpEquals(AggregateDeclaration ad, Scope* sc)
|
|||
|
||||
FuncDeclaration rfc(Expression e)
|
||||
{
|
||||
a[0] = e;
|
||||
a[0].type = tthis;
|
||||
return resolveFuncCall(ad.loc, sc, eq, null, tthis, ArgumentList(&a), FuncResolveFlag.quiet);
|
||||
(*a)[0] = e;
|
||||
(*a)[0].type = tthis;
|
||||
return resolveFuncCall(ad.loc, sc, eq, null, tthis, ArgumentList(a), FuncResolveFlag.quiet);
|
||||
}
|
||||
|
||||
f = rfc(er);
|
||||
|
|
|
@ -259,7 +259,7 @@ extern (C++) final class StaticForeach : RootObject
|
|||
auto sdecl = new StructDeclaration(loc, sid, false);
|
||||
sdecl.storage_class |= STC.static_;
|
||||
sdecl.members = new Dsymbols();
|
||||
auto fid = Identifier.idPool(tupleFieldName.ptr, tupleFieldName.length);
|
||||
auto fid = Identifier.idPool(tupleFieldName);
|
||||
auto ty = new TypeTypeof(loc, new TupleExp(loc, e));
|
||||
sdecl.members.push(new VarDeclaration(loc, ty, fid, null, 0));
|
||||
auto r = cast(TypeStruct)sdecl.type;
|
||||
|
|
|
@ -324,6 +324,8 @@ final class CParser(AST) : Parser!AST
|
|||
// atomic-type-specifier or type_qualifier
|
||||
case TOK._Atomic:
|
||||
|
||||
case TOK.__attribute__:
|
||||
|
||||
Ldeclaration:
|
||||
{
|
||||
cparseDeclaration(LVL.local);
|
||||
|
@ -2356,6 +2358,8 @@ final class CParser(AST) : Parser!AST
|
|||
cparseGnuAttributes(tagSpecifier);
|
||||
else if (token.value == TOK.__declspec)
|
||||
cparseDeclspec(tagSpecifier);
|
||||
else if (token.value == TOK.__pragma)
|
||||
uupragmaDirective(sloc);
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
@ -2710,7 +2714,7 @@ final class CParser(AST) : Parser!AST
|
|||
*
|
||||
* Params:
|
||||
* declarator = declarator kind
|
||||
* t = base type to start with
|
||||
* tbase = base type to start with
|
||||
* pident = set to Identifier if there is one, null if not
|
||||
* specifier = specifiers in and out
|
||||
* Returns:
|
||||
|
@ -2718,12 +2722,26 @@ final class CParser(AST) : Parser!AST
|
|||
* symbol table for the parameter-type-list, which will contain any
|
||||
* declared struct, union or enum tags.
|
||||
*/
|
||||
private AST.Type cparseDeclarator(DTR declarator, AST.Type t,
|
||||
private AST.Type cparseDeclarator(DTR declarator, AST.Type tbase,
|
||||
out Identifier pident, ref Specifier specifier)
|
||||
{
|
||||
//printf("cparseDeclarator(%d, %p)\n", declarator, t);
|
||||
AST.Types constTypes; // all the Types that will need `const` applied to them
|
||||
|
||||
/* Insert tx -> t into
|
||||
* ts -> ... -> t
|
||||
* so that
|
||||
* ts -> ... -> tx -> t
|
||||
*/
|
||||
static void insertTx(ref AST.Type ts, AST.Type tx, AST.Type t)
|
||||
{
|
||||
AST.Type* pt;
|
||||
for (pt = &ts; *pt != t; pt = &(cast(AST.TypeNext)*pt).next)
|
||||
{
|
||||
}
|
||||
*pt = tx;
|
||||
}
|
||||
|
||||
AST.Type parseDecl(AST.Type t)
|
||||
{
|
||||
AST.Type ts;
|
||||
|
@ -2789,20 +2807,6 @@ final class CParser(AST) : Parser!AST
|
|||
// parse DeclaratorSuffixes
|
||||
while (1)
|
||||
{
|
||||
/* Insert tx -> t into
|
||||
* ts -> ... -> t
|
||||
* so that
|
||||
* ts -> ... -> tx -> t
|
||||
*/
|
||||
static void insertTx(ref AST.Type ts, AST.Type tx, AST.Type t)
|
||||
{
|
||||
AST.Type* pt;
|
||||
for (pt = &ts; *pt != t; pt = &(cast(AST.TypeNext)*pt).next)
|
||||
{
|
||||
}
|
||||
*pt = tx;
|
||||
}
|
||||
|
||||
switch (token.value)
|
||||
{
|
||||
case TOK.leftBracket:
|
||||
|
@ -2915,7 +2919,17 @@ final class CParser(AST) : Parser!AST
|
|||
return ts;
|
||||
}
|
||||
|
||||
t = parseDecl(t);
|
||||
auto t = parseDecl(tbase);
|
||||
|
||||
if (specifier.vector_size)
|
||||
{
|
||||
auto length = new AST.IntegerExp(token.loc, specifier.vector_size / tbase.size(), AST.Type.tuns32);
|
||||
auto tsa = new AST.TypeSArray(tbase, length);
|
||||
AST.Type tv = new AST.TypeVector(tsa);
|
||||
specifier.vector_size = 0; // used it up
|
||||
|
||||
insertTx(t, tv, tbase); // replace tbase with tv
|
||||
}
|
||||
|
||||
/* Because const is transitive, cannot assemble types from
|
||||
* fragments. Instead, types to be annotated with const are put
|
||||
|
@ -3553,7 +3567,19 @@ final class CParser(AST) : Parser!AST
|
|||
{
|
||||
nextToken();
|
||||
check(TOK.leftParenthesis);
|
||||
cparseConstantExp(); // TODO implement
|
||||
if (token.value == TOK.int32Literal)
|
||||
{
|
||||
const n = token.unsvalue;
|
||||
if (n < 1 || n & (n - 1) || ushort.max < n)
|
||||
error("__attribute__((vector_size(%lld))) must be an integer positive power of 2 and be <= 32,768", cast(ulong)n);
|
||||
specifier.vector_size = cast(uint) n;
|
||||
nextToken();
|
||||
}
|
||||
else
|
||||
{
|
||||
error("value for vector_size expected, not `%s`", token.toChars());
|
||||
nextToken();
|
||||
}
|
||||
check(TOK.rightParenthesis);
|
||||
}
|
||||
else
|
||||
|
@ -3852,6 +3878,10 @@ final class CParser(AST) : Parser!AST
|
|||
else if (!tag)
|
||||
error("missing tag `identifier` after `%s`", Token.toChars(structOrUnion));
|
||||
|
||||
// many ways and places to declare alignment
|
||||
if (packalign.isUnknown() && !this.packalign.isUnknown())
|
||||
packalign.set(this.packalign.get());
|
||||
|
||||
/* Need semantic information to determine if this is a declaration,
|
||||
* redeclaration, or reference to existing declaration.
|
||||
* Defer to the semantic() pass with a TypeTag.
|
||||
|
@ -4694,6 +4724,7 @@ final class CParser(AST) : Parser!AST
|
|||
// atomic-type-specifier
|
||||
case TOK._Atomic:
|
||||
case TOK.typeof_:
|
||||
case TOK.__attribute__:
|
||||
t = peek(t);
|
||||
if (t.value != TOK.leftParenthesis ||
|
||||
!skipParens(t, &t))
|
||||
|
@ -4959,6 +4990,7 @@ final class CParser(AST) : Parser!AST
|
|||
bool dllexport; /// dllexport attribute
|
||||
bool _deprecated; /// deprecated attribute
|
||||
AST.Expression depMsg; /// deprecated message
|
||||
uint vector_size; /// positive power of 2 multipe of base type size
|
||||
|
||||
SCW scw; /// storage-class specifiers
|
||||
MOD mod; /// type qualifiers
|
||||
|
@ -5400,6 +5432,24 @@ final class CParser(AST) : Parser!AST
|
|||
pragmaDirective(scanloc);
|
||||
return true;
|
||||
}
|
||||
else if (n.ident == Id.ident) // #ident "string"
|
||||
{
|
||||
scan(&n);
|
||||
if (n.value == TOK.string_ && n.ptr[0] == '"' && n.postfix == 0)
|
||||
{
|
||||
/* gcc inserts string into the .comment section in the object file.
|
||||
* Just ignore it for now, but can support it later by writing
|
||||
* the string to obj_exestr()
|
||||
*/
|
||||
//auto comment = n.ustring;
|
||||
|
||||
scan(&n);
|
||||
if (n.value == TOK.endOfFile || n.value == TOK.endOfLine)
|
||||
return true;
|
||||
}
|
||||
error("\"string\" expected after `#ident`");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (n.ident != Id.undef)
|
||||
error("C preprocessor directive `#%s` is not supported", n.toChars());
|
||||
|
@ -5416,20 +5466,39 @@ final class CParser(AST) : Parser!AST
|
|||
private void uupragmaDirective(const ref Loc startloc)
|
||||
{
|
||||
const loc = startloc;
|
||||
nextToken();
|
||||
nextToken(); // move past __pragma
|
||||
if (token.value != TOK.leftParenthesis)
|
||||
{
|
||||
error(loc, "left parenthesis expected to follow `__pragma`");
|
||||
error(loc, "left parenthesis expected to follow `__pragma` instead of `%s`", token.toChars());
|
||||
nextToken();
|
||||
return;
|
||||
}
|
||||
nextToken();
|
||||
if (token.value == TOK.identifier && token.ident == Id.pack)
|
||||
pragmaPack(startloc, false);
|
||||
|
||||
if (token.value == TOK.identifier)
|
||||
{
|
||||
if (token.ident == Id.pack)
|
||||
pragmaPack(startloc, false);
|
||||
else
|
||||
{
|
||||
nextToken();
|
||||
if (token.value == TOK.leftParenthesis)
|
||||
cparseParens();
|
||||
}
|
||||
|
||||
}
|
||||
else if (token.value == TOK.endOfFile)
|
||||
{
|
||||
}
|
||||
else if (token.value == TOK.rightParenthesis)
|
||||
{
|
||||
}
|
||||
else
|
||||
error(loc, "unrecognized __pragma");
|
||||
error(loc, "unrecognized `__pragma(%s)`", token.toChars());
|
||||
|
||||
if (token.value != TOK.rightParenthesis)
|
||||
{
|
||||
error(loc, "right parenthesis expected to close `__pragma(...)`");
|
||||
error(loc, "right parenthesis expected to close `__pragma(...)` instead of `%s`", token.toChars());
|
||||
return;
|
||||
}
|
||||
nextToken();
|
||||
|
|
|
@ -446,7 +446,15 @@ private final class CppMangleVisitor : Visitor
|
|||
if (this.context.res.dyncast() == DYNCAST.dsymbol)
|
||||
parentti = this.context.res.asFuncDecl().parent.isTemplateInstance();
|
||||
else
|
||||
parentti = this.context.res.asType().toDsymbol(null).parent.isTemplateInstance();
|
||||
{
|
||||
auto parent = this.context.res.asType().toDsymbol(null).parent;
|
||||
parentti = parent.isTemplateInstance();
|
||||
// https://issues.dlang.org/show_bug.cgi?id=22760
|
||||
// The template instance may sometimes have the form
|
||||
// S1!int.S1, therefore the above instruction might yield null
|
||||
if (parentti is null && parent.parent)
|
||||
parentti = parent.parent.isTemplateInstance();
|
||||
}
|
||||
return (*parentti.tiargs)[arg];
|
||||
}());
|
||||
scope (exit) this.context.pop(prev);
|
||||
|
|
|
@ -71,6 +71,8 @@ Expression implicitCastTo(Expression e, Scope* sc, Type t)
|
|||
|
||||
if (const match = (sc && sc.flags & SCOPE.Cfile) ? e.cimplicitConvTo(t) : e.implicitConvTo(t))
|
||||
{
|
||||
// no need for an extra cast when matching is exact
|
||||
|
||||
if (match == MATCH.convert && e.type.isTypeNoreturn())
|
||||
{
|
||||
return specialNoreturnCast(e, t);
|
||||
|
@ -88,6 +90,8 @@ Expression implicitCastTo(Expression e, Scope* sc, Type t)
|
|||
auto ad = isAggregate(e.type);
|
||||
if (ad && ad.aliasthis)
|
||||
{
|
||||
if (!ad.type || ad.type.isTypeError())
|
||||
return e;
|
||||
auto ts = ad.type.isTypeStruct();
|
||||
const adMatch = ts
|
||||
? ts.implicitConvToWithoutAliasThis(t)
|
||||
|
|
|
@ -17,7 +17,6 @@ import core.stdc.stdio;
|
|||
import core.stdc.string;
|
||||
|
||||
import dmd.aggregate;
|
||||
import dmd.apply;
|
||||
import dmd.arraytypes;
|
||||
import dmd.astenums;
|
||||
import dmd.attrib;
|
||||
|
@ -867,7 +866,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
|
|||
* Resolve forward references to all class member functions,
|
||||
* and determine whether this class is abstract.
|
||||
*/
|
||||
static int func(Dsymbol s)
|
||||
static int func(Dsymbol s, void*)
|
||||
{
|
||||
auto fd = s.isFuncDeclaration();
|
||||
if (!fd)
|
||||
|
@ -883,7 +882,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
|
|||
for (size_t i = 0; i < members.length; i++)
|
||||
{
|
||||
auto s = (*members)[i];
|
||||
if (s.apply(&func))
|
||||
if (s.apply(&func, null))
|
||||
{
|
||||
return yes();
|
||||
}
|
||||
|
@ -910,7 +909,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
|
|||
* each of the virtual functions,
|
||||
* which will fill in the vtbl[] overrides.
|
||||
*/
|
||||
static int virtualSemantic(Dsymbol s)
|
||||
static int virtualSemantic(Dsymbol s, void*)
|
||||
{
|
||||
auto fd = s.isFuncDeclaration();
|
||||
if (fd && !(fd.storage_class & STC.static_) && !fd.isUnitTestDeclaration())
|
||||
|
@ -921,7 +920,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
|
|||
for (size_t i = 0; i < members.length; i++)
|
||||
{
|
||||
auto s = (*members)[i];
|
||||
s.apply(&virtualSemantic);
|
||||
s.apply(&virtualSemantic,null);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,6 +44,10 @@ import dmd.tokens;
|
|||
import dmd.typesem;
|
||||
import dmd.visitor;
|
||||
|
||||
version (IN_GCC) {}
|
||||
else version (IN_LLVM) {}
|
||||
else version = MARS;
|
||||
|
||||
/************************************
|
||||
* Check to see the aggregate type is nested and its context pointer is
|
||||
* accessible from the current scope.
|
||||
|
@ -633,9 +637,7 @@ extern (C++) final class TupleDeclaration : Declaration
|
|||
version (none)
|
||||
{
|
||||
buf.printf("_%s_%d", ident.toChars(), i);
|
||||
const len = buf.offset;
|
||||
const name = buf.extractSlice().ptr;
|
||||
auto id = Identifier.idPool(name, len);
|
||||
auto id = Identifier.idPool(buf.extractSlice());
|
||||
auto arg = new Parameter(STC.in_, t, id, null);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -534,22 +534,19 @@ enum class BUILTIN : unsigned char
|
|||
Expression *eval_builtin(const Loc &loc, FuncDeclaration *fd, Expressions *arguments);
|
||||
BUILTIN isBuiltin(FuncDeclaration *fd);
|
||||
|
||||
struct ContractInfo;
|
||||
|
||||
class FuncDeclaration : public Declaration
|
||||
{
|
||||
public:
|
||||
Statements *frequires; // in contracts
|
||||
Ensures *fensures; // out contracts
|
||||
Statement *frequire; // lowered in contract
|
||||
Statement *fensure; // lowered out contract
|
||||
Statement *fbody;
|
||||
|
||||
FuncDeclarations foverrides; // functions this function overrides
|
||||
FuncDeclaration *fdrequire; // function that does the in contract
|
||||
FuncDeclaration *fdensure; // function that does the out contract
|
||||
|
||||
Expressions *fdrequireParams; // argument list for __require
|
||||
Expressions *fdensureParams; // argument list for __ensure
|
||||
private:
|
||||
ContractInfo *contracts; // contract information
|
||||
|
||||
public:
|
||||
const char *mangleString; // mangled symbol created from mangleExact()
|
||||
|
||||
VarDeclaration *vresult; // result variable for out contracts
|
||||
|
@ -686,6 +683,22 @@ public:
|
|||
|
||||
static FuncDeclaration *create(const Loc &loc, const Loc &endloc, Identifier *id, StorageClass storage_class, Type *type, bool noreturn = false);
|
||||
FuncDeclaration *syntaxCopy(Dsymbol *) override;
|
||||
Statements *frequires();
|
||||
Ensures *fensures();
|
||||
Statement *frequire();
|
||||
Statement *fensure();
|
||||
FuncDeclaration *fdrequire();
|
||||
FuncDeclaration *fdensure();
|
||||
Expressions *fdrequireParams();
|
||||
Expressions *fdensureParams();
|
||||
Statements *frequires(Statements *frs);
|
||||
Ensures *fensures(Statements *fes);
|
||||
Statement *frequire(Statement *fr);
|
||||
Statement *fensure(Statement *fe);
|
||||
FuncDeclaration *fdrequire(FuncDeclaration *fdr);
|
||||
FuncDeclaration *fdensure(FuncDeclaration *fde);
|
||||
Expressions *fdrequireParams(Expressions *fdrp);
|
||||
Expressions *fdensureParams(Expressions *fdep);
|
||||
bool functionSemantic();
|
||||
bool functionSemantic3();
|
||||
bool equals(const RootObject * const o) const override final;
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
module dmd.delegatize;
|
||||
|
||||
import core.stdc.stdio;
|
||||
import dmd.apply;
|
||||
import dmd.astenums;
|
||||
import dmd.declaration;
|
||||
import dmd.dscope;
|
||||
|
@ -27,6 +26,7 @@ import dmd.init;
|
|||
import dmd.initsem;
|
||||
import dmd.location;
|
||||
import dmd.mtype;
|
||||
import dmd.postordervisitor;
|
||||
import dmd.statement;
|
||||
import dmd.tokens;
|
||||
import dmd.visitor;
|
||||
|
|
|
@ -169,7 +169,12 @@ extern (C++) final class EnumDeclaration : ScopeDsymbol
|
|||
return defaultval;
|
||||
}
|
||||
//printf("EnumDeclaration::getDefaultValue() %p %s\n", this, toChars());
|
||||
if (defaultval)
|
||||
// https://issues.dlang.org/show_bug.cgi?id=23904
|
||||
// Return defaultval only if it is not ErrorExp.
|
||||
// A speculative context may set defaultval to ErrorExp;
|
||||
// subsequent non-speculative contexts need to be able
|
||||
// to print the error.
|
||||
if (defaultval && !defaultval.isErrorExp())
|
||||
return defaultval;
|
||||
|
||||
if (isCsymbol())
|
||||
|
|
|
@ -26,6 +26,7 @@ import dmd.location;
|
|||
import dmd.mtype;
|
||||
import dmd.visitor;
|
||||
|
||||
import core.stdc.stdio;
|
||||
/***********************************************************
|
||||
*/
|
||||
extern (C++) final class Import : Dsymbol
|
||||
|
@ -232,7 +233,20 @@ extern (C++) final class Import : Dsymbol
|
|||
* most likely because of parsing errors.
|
||||
* Therefore we cannot trust the resulting AST.
|
||||
*/
|
||||
if (load(sc)) return;
|
||||
if (load(sc))
|
||||
{
|
||||
// https://issues.dlang.org/show_bug.cgi?id=23873
|
||||
// For imports that are not at module or function level,
|
||||
// e.g. aggregate level, the import symbol is added to the
|
||||
// symbol table and later semantic is performed on it.
|
||||
// This leads to semantic analysis on an malformed AST
|
||||
// which causes all kinds of segfaults.
|
||||
// The fix is to note that the module has errors and avoid
|
||||
// semantic analysis on it.
|
||||
if(mod)
|
||||
mod.errors = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mod) return; // Failed
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@ module dmd.dinterpret;
|
|||
import core.stdc.stdio;
|
||||
import core.stdc.stdlib;
|
||||
import core.stdc.string;
|
||||
import dmd.apply;
|
||||
import dmd.arraytypes;
|
||||
import dmd.astenums;
|
||||
import dmd.attrib;
|
||||
|
|
|
@ -429,9 +429,9 @@ extern(C++) void gendocfile(Module m)
|
|||
if (m.filetype == FileType.ddoc)
|
||||
{
|
||||
const ploc = m.md ? &m.md.loc : &m.loc;
|
||||
const loc = Loc(ploc.filename ? ploc.filename : srcfilename.ptr,
|
||||
ploc.linnum,
|
||||
ploc.charnum);
|
||||
Loc loc = *ploc;
|
||||
if (!loc.filename)
|
||||
loc.filename = srcfilename.ptr;
|
||||
|
||||
size_t commentlen = strlen(cast(char*)m.comment);
|
||||
Dsymbols a;
|
||||
|
@ -4151,7 +4151,7 @@ private size_t endRowAndTable(ref OutBuffer buf, size_t iStart, size_t iEnd, con
|
|||
private void highlightText(Scope* sc, Dsymbols* a, Loc loc, ref OutBuffer buf, size_t offset)
|
||||
{
|
||||
const incrementLoc = loc.linnum == 0 ? 1 : 0;
|
||||
loc.linnum += incrementLoc;
|
||||
loc.linnum = loc.linnum + incrementLoc;
|
||||
loc.charnum = 0;
|
||||
//printf("highlightText()\n");
|
||||
bool leadingBlank = true;
|
||||
|
@ -4256,7 +4256,7 @@ private void highlightText(Scope* sc, Dsymbols* a, Loc loc, ref OutBuffer buf, s
|
|||
lineQuoted = false;
|
||||
tableRowDetected = false;
|
||||
iLineStart = i + 1;
|
||||
loc.linnum += incrementLoc;
|
||||
loc.linnum = loc.linnum + incrementLoc;
|
||||
|
||||
// update the paragraph start if we just entered a macro
|
||||
if (previousMacroLevel < macroLevel && iParagraphStart < iLineStart)
|
||||
|
|
|
@ -17,7 +17,6 @@ import core.stdc.string;
|
|||
|
||||
import dmd.aggregate;
|
||||
import dmd.aliasthis;
|
||||
import dmd.apply;
|
||||
import dmd.arraytypes;
|
||||
import dmd.astcodegen;
|
||||
import dmd.astenums;
|
||||
|
@ -78,6 +77,10 @@ import dmd.templateparamsem;
|
|||
import dmd.typesem;
|
||||
import dmd.visitor;
|
||||
|
||||
version (IN_GCC) {}
|
||||
else version (IN_LLVM) {}
|
||||
else version = MARS;
|
||||
|
||||
enum LOG = false;
|
||||
|
||||
private uint setMangleOverride(Dsymbol s, const(char)[] sym)
|
||||
|
@ -484,7 +487,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
|
|||
|
||||
// Infering the type requires running semantic,
|
||||
// so mark the scope as ctfe if required
|
||||
bool needctfe = (dsym.storage_class & (STC.manifest | STC.static_)) != 0;
|
||||
bool needctfe = (dsym.storage_class & (STC.manifest | STC.static_)) != 0 || !sc.func;
|
||||
if (needctfe)
|
||||
{
|
||||
sc.flags |= SCOPE.condition;
|
||||
|
@ -1366,9 +1369,9 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
|
|||
{
|
||||
static if (LOG)
|
||||
{
|
||||
printf("Import::semantic('%s') %s\n", toPrettyChars(), id.toChars());
|
||||
printf("Import::semantic('%s') %s\n", imp.toPrettyChars(), imp.id.toChars());
|
||||
scope(exit)
|
||||
printf("-Import::semantic('%s'), pkg = %p\n", toChars(), pkg);
|
||||
printf("-Import::semantic('%s'), pkg = %p\n", imp.toChars(), imp.pkg);
|
||||
}
|
||||
if (imp.semanticRun > PASS.initial)
|
||||
return;
|
||||
|
@ -1434,7 +1437,9 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
|
|||
imp.addPackageAccess(scopesym);
|
||||
}
|
||||
|
||||
imp.mod.dsymbolSemantic(null);
|
||||
// if a module has errors it means that parsing has failed.
|
||||
if (!imp.mod.errors)
|
||||
imp.mod.dsymbolSemantic(null);
|
||||
|
||||
if (imp.mod.needmoduleinfo)
|
||||
{
|
||||
|
@ -1463,7 +1468,9 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
|
|||
else
|
||||
{
|
||||
Dsymbol s = imp.mod.search_correct(imp.names[i]);
|
||||
if (s)
|
||||
// https://issues.dlang.org/show_bug.cgi?id=23908
|
||||
// Don't suggest symbols from the importer's module
|
||||
if (s && s.parent != importer)
|
||||
imp.mod.error(imp.loc, "import `%s` not found, did you mean %s `%s`?", imp.names[i].toChars(), s.kind(), s.toPrettyChars());
|
||||
else
|
||||
imp.mod.error(imp.loc, "import `%s` not found", imp.names[i].toChars());
|
||||
|
@ -7124,8 +7131,9 @@ bool determineFields(AggregateDeclaration ad)
|
|||
// determineFields can be called recursively from one of the fields's v.semantic
|
||||
ad.fields.setDim(0);
|
||||
|
||||
static int func(Dsymbol s, AggregateDeclaration ad)
|
||||
static int func(Dsymbol s, void* ctx)
|
||||
{
|
||||
auto ad = cast(AggregateDeclaration)ctx;
|
||||
auto v = s.isVarDeclaration();
|
||||
if (!v)
|
||||
return 0;
|
||||
|
@ -7141,7 +7149,7 @@ bool determineFields(AggregateDeclaration ad)
|
|||
if (v.aliasTuple)
|
||||
{
|
||||
// If this variable was really a tuple, process each element.
|
||||
return v.aliasTuple.foreachVar(tv => tv.apply(&func, ad));
|
||||
return v.aliasTuple.foreachVar(tv => tv.apply(&func, cast(void*) ad));
|
||||
}
|
||||
|
||||
if (v.storage_class & (STC.static_ | STC.extern_ | STC.tls | STC.gshared | STC.manifest | STC.ctfe | STC.templateparameter))
|
||||
|
@ -7173,7 +7181,7 @@ bool determineFields(AggregateDeclaration ad)
|
|||
for (size_t i = 0; i < ad.members.length; i++)
|
||||
{
|
||||
auto s = (*ad.members)[i];
|
||||
if (s.apply(&func, ad))
|
||||
if (s.apply(&func, cast(void *)ad))
|
||||
{
|
||||
if (ad.sizeok != Sizeok.none)
|
||||
{
|
||||
|
|
|
@ -4141,178 +4141,8 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
|
|||
goto Lnomatch;
|
||||
|
||||
L2:
|
||||
for (size_t i = 0; 1; i++)
|
||||
{
|
||||
//printf("\ttest: tempinst.tiargs[%zu]\n", i);
|
||||
RootObject o1 = null;
|
||||
if (i < t.tempinst.tiargs.length)
|
||||
o1 = (*t.tempinst.tiargs)[i];
|
||||
else if (i < t.tempinst.tdtypes.length && i < tp.tempinst.tiargs.length)
|
||||
{
|
||||
// Pick up default arg
|
||||
o1 = t.tempinst.tdtypes[i];
|
||||
}
|
||||
else if (i >= tp.tempinst.tiargs.length)
|
||||
break;
|
||||
//printf("\ttest: o1 = %s\n", o1.toChars());
|
||||
if (i >= tp.tempinst.tiargs.length)
|
||||
{
|
||||
size_t dim = tempdecl.parameters.length - (tempdecl.isVariadic() ? 1 : 0);
|
||||
while (i < dim && ((*tempdecl.parameters)[i].dependent || (*tempdecl.parameters)[i].hasDefaultArg()))
|
||||
{
|
||||
i++;
|
||||
}
|
||||
if (i >= dim)
|
||||
break; // match if all remained parameters are dependent
|
||||
goto Lnomatch;
|
||||
}
|
||||
|
||||
RootObject o2 = (*tp.tempinst.tiargs)[i];
|
||||
Type t2 = isType(o2);
|
||||
//printf("\ttest: o2 = %s\n", o2.toChars());
|
||||
size_t j = (t2 && t2.ty == Tident && i == tp.tempinst.tiargs.length - 1)
|
||||
? templateParameterLookup(t2, parameters) : IDX_NOTFOUND;
|
||||
if (j != IDX_NOTFOUND && j == parameters.length - 1 &&
|
||||
(*parameters)[j].isTemplateTupleParameter())
|
||||
{
|
||||
/* Given:
|
||||
* struct A(B...) {}
|
||||
* alias A!(int, float) X;
|
||||
* static if (is(X Y == A!(Z), Z...)) {}
|
||||
* deduce that Z is a tuple(int, float)
|
||||
*/
|
||||
|
||||
/* Create tuple from remaining args
|
||||
*/
|
||||
size_t vtdim = (tempdecl.isVariadic() ? t.tempinst.tiargs.length : t.tempinst.tdtypes.length) - i;
|
||||
auto vt = new Tuple(vtdim);
|
||||
for (size_t k = 0; k < vtdim; k++)
|
||||
{
|
||||
RootObject o;
|
||||
if (k < t.tempinst.tiargs.length)
|
||||
o = (*t.tempinst.tiargs)[i + k];
|
||||
else // Pick up default arg
|
||||
o = t.tempinst.tdtypes[i + k];
|
||||
vt.objects[k] = o;
|
||||
}
|
||||
|
||||
Tuple v = cast(Tuple)(*dedtypes)[j];
|
||||
if (v)
|
||||
{
|
||||
if (!match(v, vt))
|
||||
goto Lnomatch;
|
||||
}
|
||||
else
|
||||
(*dedtypes)[j] = vt;
|
||||
break;
|
||||
}
|
||||
else if (!o1)
|
||||
break;
|
||||
|
||||
Type t1 = isType(o1);
|
||||
Dsymbol s1 = isDsymbol(o1);
|
||||
Dsymbol s2 = isDsymbol(o2);
|
||||
Expression e1 = s1 ? getValue(s1) : getValue(isExpression(o1));
|
||||
Expression e2 = isExpression(o2);
|
||||
version (none)
|
||||
{
|
||||
Tuple v1 = isTuple(o1);
|
||||
Tuple v2 = isTuple(o2);
|
||||
if (t1)
|
||||
printf("t1 = %s\n", t1.toChars());
|
||||
if (t2)
|
||||
printf("t2 = %s\n", t2.toChars());
|
||||
if (e1)
|
||||
printf("e1 = %s\n", e1.toChars());
|
||||
if (e2)
|
||||
printf("e2 = %s\n", e2.toChars());
|
||||
if (s1)
|
||||
printf("s1 = %s\n", s1.toChars());
|
||||
if (s2)
|
||||
printf("s2 = %s\n", s2.toChars());
|
||||
if (v1)
|
||||
printf("v1 = %s\n", v1.toChars());
|
||||
if (v2)
|
||||
printf("v2 = %s\n", v2.toChars());
|
||||
}
|
||||
|
||||
if (t1 && t2)
|
||||
{
|
||||
if (!deduceType(t1, sc, t2, parameters, dedtypes))
|
||||
goto Lnomatch;
|
||||
}
|
||||
else if (e1 && e2)
|
||||
{
|
||||
Le:
|
||||
e1 = e1.ctfeInterpret();
|
||||
|
||||
/* If it is one of the template parameters for this template,
|
||||
* we should not attempt to interpret it. It already has a value.
|
||||
*/
|
||||
if (e2.op == EXP.variable && (e2.isVarExp().var.storage_class & STC.templateparameter))
|
||||
{
|
||||
/*
|
||||
* (T:Number!(e2), int e2)
|
||||
*/
|
||||
j = templateIdentifierLookup(e2.isVarExp().var.ident, parameters);
|
||||
if (j != IDX_NOTFOUND)
|
||||
goto L1;
|
||||
// The template parameter was not from this template
|
||||
// (it may be from a parent template, for example)
|
||||
}
|
||||
|
||||
e2 = e2.expressionSemantic(sc); // https://issues.dlang.org/show_bug.cgi?id=13417
|
||||
e2 = e2.ctfeInterpret();
|
||||
|
||||
//printf("e1 = %s, type = %s %d\n", e1.toChars(), e1.type.toChars(), e1.type.ty);
|
||||
//printf("e2 = %s, type = %s %d\n", e2.toChars(), e2.type.toChars(), e2.type.ty);
|
||||
if (!e1.equals(e2))
|
||||
{
|
||||
if (!e2.implicitConvTo(e1.type))
|
||||
goto Lnomatch;
|
||||
|
||||
e2 = e2.implicitCastTo(sc, e1.type);
|
||||
e2 = e2.ctfeInterpret();
|
||||
if (!e1.equals(e2))
|
||||
goto Lnomatch;
|
||||
}
|
||||
}
|
||||
else if (e1 && t2 && t2.ty == Tident)
|
||||
{
|
||||
j = templateParameterLookup(t2, parameters);
|
||||
L1:
|
||||
if (j == IDX_NOTFOUND)
|
||||
{
|
||||
t2.resolve((cast(TypeIdentifier)t2).loc, sc, e2, t2, s2);
|
||||
if (e2)
|
||||
goto Le;
|
||||
goto Lnomatch;
|
||||
}
|
||||
if (!(*parameters)[j].matchArg(sc, e1, j, parameters, dedtypes, null))
|
||||
goto Lnomatch;
|
||||
}
|
||||
else if (s1 && s2)
|
||||
{
|
||||
Ls:
|
||||
if (!s1.equals(s2))
|
||||
goto Lnomatch;
|
||||
}
|
||||
else if (s1 && t2 && t2.ty == Tident)
|
||||
{
|
||||
j = templateParameterLookup(t2, parameters);
|
||||
if (j == IDX_NOTFOUND)
|
||||
{
|
||||
t2.resolve((cast(TypeIdentifier)t2).loc, sc, e2, t2, s2);
|
||||
if (s2)
|
||||
goto Ls;
|
||||
goto Lnomatch;
|
||||
}
|
||||
if (!(*parameters)[j].matchArg(sc, s1, j, parameters, dedtypes, null))
|
||||
goto Lnomatch;
|
||||
}
|
||||
else
|
||||
goto Lnomatch;
|
||||
}
|
||||
if (!resolveTemplateInstantiation(t.tempinst.tiargs, &t.tempinst.tdtypes, tempdecl, tp, dedtypes))
|
||||
goto Lnomatch;
|
||||
}
|
||||
visit(cast(Type)t);
|
||||
return;
|
||||
|
@ -4322,6 +4152,198 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
|
|||
result = MATCH.nomatch;
|
||||
}
|
||||
|
||||
/********************
|
||||
* Match template `parameters` to the target template instance.
|
||||
* Example:
|
||||
* struct Temp(U, int Z) {}
|
||||
* void foo(T)(Temp!(T, 3));
|
||||
* foo(Temp!(int, 3)());
|
||||
* Input:
|
||||
* this.parameters = template params of foo -> [T]
|
||||
* tiargs = <Temp!(int, 3)>.tiargs -> [int, 3]
|
||||
* tdtypes = <Temp!(int, 3)>.tdtypes -> [int, 3]
|
||||
* tempdecl = <struct Temp!(T, int Z)> -> [T, Z]
|
||||
* tp = <Temp!(T, 3)>
|
||||
* Output:
|
||||
* dedtypes = deduced params of `foo(Temp!(int, 3)())` -> [int]
|
||||
*/
|
||||
private bool resolveTemplateInstantiation(Objects* tiargs, Objects* tdtypes, TemplateDeclaration tempdecl, TypeInstance tp, Objects* dedtypes)
|
||||
{
|
||||
for (size_t i = 0; 1; i++)
|
||||
{
|
||||
//printf("\ttest: tempinst.tiargs[%zu]\n", i);
|
||||
RootObject o1 = null;
|
||||
if (i < tiargs.length)
|
||||
o1 = (*tiargs)[i];
|
||||
else if (i < tdtypes.length && i < tp.tempinst.tiargs.length)
|
||||
{
|
||||
// Pick up default arg
|
||||
o1 = (*tdtypes)[i];
|
||||
}
|
||||
else if (i >= tp.tempinst.tiargs.length)
|
||||
break;
|
||||
//printf("\ttest: o1 = %s\n", o1.toChars());
|
||||
if (i >= tp.tempinst.tiargs.length)
|
||||
{
|
||||
size_t dim = tempdecl.parameters.length - (tempdecl.isVariadic() ? 1 : 0);
|
||||
while (i < dim && ((*tempdecl.parameters)[i].dependent || (*tempdecl.parameters)[i].hasDefaultArg()))
|
||||
{
|
||||
i++;
|
||||
}
|
||||
if (i >= dim)
|
||||
break; // match if all remained parameters are dependent
|
||||
return false;
|
||||
}
|
||||
|
||||
RootObject o2 = (*tp.tempinst.tiargs)[i];
|
||||
Type t2 = isType(o2);
|
||||
//printf("\ttest: o2 = %s\n", o2.toChars());
|
||||
size_t j = (t2 && t2.ty == Tident && i == tp.tempinst.tiargs.length - 1)
|
||||
? templateParameterLookup(t2, parameters) : IDX_NOTFOUND;
|
||||
if (j != IDX_NOTFOUND && j == parameters.length - 1 &&
|
||||
(*parameters)[j].isTemplateTupleParameter())
|
||||
{
|
||||
/* Given:
|
||||
* struct A(B...) {}
|
||||
* alias A!(int, float) X;
|
||||
* static if (is(X Y == A!(Z), Z...)) {}
|
||||
* deduce that Z is a tuple(int, float)
|
||||
*/
|
||||
|
||||
/* Create tuple from remaining args
|
||||
*/
|
||||
size_t vtdim = (tempdecl.isVariadic() ? tiargs.length : tdtypes.length) - i;
|
||||
auto vt = new Tuple(vtdim);
|
||||
for (size_t k = 0; k < vtdim; k++)
|
||||
{
|
||||
RootObject o;
|
||||
if (k < tiargs.length)
|
||||
o = (*tiargs)[i + k];
|
||||
else // Pick up default arg
|
||||
o = (*tdtypes)[i + k];
|
||||
vt.objects[k] = o;
|
||||
}
|
||||
|
||||
Tuple v = cast(Tuple)(*dedtypes)[j];
|
||||
if (v)
|
||||
{
|
||||
if (!match(v, vt))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
(*dedtypes)[j] = vt;
|
||||
break;
|
||||
}
|
||||
else if (!o1)
|
||||
break;
|
||||
|
||||
Type t1 = isType(o1);
|
||||
Dsymbol s1 = isDsymbol(o1);
|
||||
Dsymbol s2 = isDsymbol(o2);
|
||||
Expression e1 = s1 ? getValue(s1) : getValue(isExpression(o1));
|
||||
Expression e2 = isExpression(o2);
|
||||
version (none)
|
||||
{
|
||||
Tuple v1 = isTuple(o1);
|
||||
Tuple v2 = isTuple(o2);
|
||||
if (t1)
|
||||
printf("t1 = %s\n", t1.toChars());
|
||||
if (t2)
|
||||
printf("t2 = %s\n", t2.toChars());
|
||||
if (e1)
|
||||
printf("e1 = %s\n", e1.toChars());
|
||||
if (e2)
|
||||
printf("e2 = %s\n", e2.toChars());
|
||||
if (s1)
|
||||
printf("s1 = %s\n", s1.toChars());
|
||||
if (s2)
|
||||
printf("s2 = %s\n", s2.toChars());
|
||||
if (v1)
|
||||
printf("v1 = %s\n", v1.toChars());
|
||||
if (v2)
|
||||
printf("v2 = %s\n", v2.toChars());
|
||||
}
|
||||
|
||||
if (t1 && t2)
|
||||
{
|
||||
if (!deduceType(t1, sc, t2, parameters, dedtypes))
|
||||
return false;
|
||||
}
|
||||
else if (e1 && e2)
|
||||
{
|
||||
Le:
|
||||
e1 = e1.ctfeInterpret();
|
||||
|
||||
/* If it is one of the template parameters for this template,
|
||||
* we should not attempt to interpret it. It already has a value.
|
||||
*/
|
||||
if (e2.op == EXP.variable && (e2.isVarExp().var.storage_class & STC.templateparameter))
|
||||
{
|
||||
/*
|
||||
* (T:Number!(e2), int e2)
|
||||
*/
|
||||
j = templateIdentifierLookup(e2.isVarExp().var.ident, parameters);
|
||||
if (j != IDX_NOTFOUND)
|
||||
goto L1;
|
||||
// The template parameter was not from this template
|
||||
// (it may be from a parent template, for example)
|
||||
}
|
||||
|
||||
e2 = e2.expressionSemantic(sc); // https://issues.dlang.org/show_bug.cgi?id=13417
|
||||
e2 = e2.ctfeInterpret();
|
||||
|
||||
//printf("e1 = %s, type = %s %d\n", e1.toChars(), e1.type.toChars(), e1.type.ty);
|
||||
//printf("e2 = %s, type = %s %d\n", e2.toChars(), e2.type.toChars(), e2.type.ty);
|
||||
if (!e1.equals(e2))
|
||||
{
|
||||
if (!e2.implicitConvTo(e1.type))
|
||||
return false;
|
||||
|
||||
e2 = e2.implicitCastTo(sc, e1.type);
|
||||
e2 = e2.ctfeInterpret();
|
||||
if (!e1.equals(e2))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (e1 && t2 && t2.ty == Tident)
|
||||
{
|
||||
j = templateParameterLookup(t2, parameters);
|
||||
L1:
|
||||
if (j == IDX_NOTFOUND)
|
||||
{
|
||||
t2.resolve((cast(TypeIdentifier)t2).loc, sc, e2, t2, s2);
|
||||
if (e2)
|
||||
goto Le;
|
||||
return false;
|
||||
}
|
||||
if (!(*parameters)[j].matchArg(sc, e1, j, parameters, dedtypes, null))
|
||||
return false;
|
||||
}
|
||||
else if (s1 && s2)
|
||||
{
|
||||
Ls:
|
||||
if (!s1.equals(s2))
|
||||
return false;
|
||||
}
|
||||
else if (s1 && t2 && t2.ty == Tident)
|
||||
{
|
||||
j = templateParameterLookup(t2, parameters);
|
||||
if (j == IDX_NOTFOUND)
|
||||
{
|
||||
t2.resolve((cast(TypeIdentifier)t2).loc, sc, e2, t2, s2);
|
||||
if (s2)
|
||||
goto Ls;
|
||||
return false;
|
||||
}
|
||||
if (!(*parameters)[j].matchArg(sc, s1, j, parameters, dedtypes, null))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
override void visit(TypeStruct t)
|
||||
{
|
||||
/* If this struct is a template struct, and we're matching
|
||||
|
|
|
@ -377,13 +377,18 @@ bool checkParamArgumentEscape(Scope* sc, FuncDeclaration fdc, Identifier parId,
|
|||
desc ~ " `%s` assigned to non-scope parameter calling `assert()`", v);
|
||||
return;
|
||||
}
|
||||
|
||||
bool isThis = fdc && fdc.needThis() && fdc.vthis == vPar; // implicit `this` parameter to member function
|
||||
|
||||
const(char)* msg =
|
||||
(isThis) ? (desc ~ " `%s` calling non-scope member function `%s.%s()`") :
|
||||
(fdc && parId) ? (desc ~ " `%s` assigned to non-scope parameter `%s` calling `%s`") :
|
||||
(fdc && !parId) ? (desc ~ " `%s` assigned to non-scope anonymous parameter calling `%s`") :
|
||||
(!fdc && parId) ? (desc ~ " `%s` assigned to non-scope parameter `%s`") :
|
||||
(desc ~ " `%s` assigned to non-scope anonymous parameter");
|
||||
|
||||
if (sc.setUnsafeDIP1000(gag, arg.loc, msg, v, parId ? parId : fdc, fdc))
|
||||
auto param = isThis ? v : (parId ? parId : fdc);
|
||||
if (sc.setUnsafeDIP1000(gag, arg.loc, msg, v, param, fdc))
|
||||
{
|
||||
result = true;
|
||||
printScopeFailure(previewSupplementalFunc(sc.isDeprecated(), global.params.useDIP1000), vPar, 10);
|
||||
|
@ -1746,20 +1751,8 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false, bool re
|
|||
/* Check each argument that is
|
||||
* passed as 'return scope'.
|
||||
*/
|
||||
Type t1 = e.e1.type.toBasetype();
|
||||
TypeFunction tf;
|
||||
TypeDelegate dg;
|
||||
if (t1.ty == Tdelegate)
|
||||
{
|
||||
dg = t1.isTypeDelegate();
|
||||
tf = dg.next.isTypeFunction();
|
||||
}
|
||||
else if (t1.ty == Tfunction)
|
||||
tf = t1.isTypeFunction();
|
||||
else
|
||||
return;
|
||||
|
||||
if (!e.type.hasPointers())
|
||||
TypeFunction tf = e.calledFunctionType();
|
||||
if (!tf || !e.type.hasPointers())
|
||||
return;
|
||||
|
||||
if (e.arguments && e.arguments.length)
|
||||
|
@ -1815,6 +1808,7 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false, bool re
|
|||
}
|
||||
}
|
||||
// If 'this' is returned, check it too
|
||||
Type t1 = e.e1.type.toBasetype();
|
||||
if (e.e1.op == EXP.dotVariable && t1.ty == Tfunction)
|
||||
{
|
||||
DotVarExp dve = e.e1.isDotVarExp();
|
||||
|
@ -1880,7 +1874,7 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false, bool re
|
|||
/* If returning the result of a delegate call, the .ptr
|
||||
* field of the delegate must be checked.
|
||||
*/
|
||||
if (dg)
|
||||
if (t1.isTypeDelegate())
|
||||
{
|
||||
if (tf.isreturn)
|
||||
escapeByValue(e.e1, er, live, retRefTransition);
|
||||
|
@ -2066,13 +2060,8 @@ void escapeByRef(Expression e, EscapeByResults* er, bool live = false, bool retR
|
|||
/* If the function returns by ref, check each argument that is
|
||||
* passed as 'return ref'.
|
||||
*/
|
||||
Type t1 = e.e1.type.toBasetype();
|
||||
TypeFunction tf;
|
||||
if (t1.ty == Tdelegate)
|
||||
tf = t1.isTypeDelegate().next.isTypeFunction();
|
||||
else if (t1.ty == Tfunction)
|
||||
tf = t1.isTypeFunction();
|
||||
else
|
||||
TypeFunction tf = e.calledFunctionType();
|
||||
if (!tf)
|
||||
return;
|
||||
if (tf.isref)
|
||||
{
|
||||
|
@ -2107,6 +2096,7 @@ void escapeByRef(Expression e, EscapeByResults* er, bool live = false, bool retR
|
|||
}
|
||||
}
|
||||
// If 'this' is returned by ref, check it too
|
||||
Type t1 = e.e1.type.toBasetype();
|
||||
if (e.e1.op == EXP.dotVariable && t1.ty == Tfunction)
|
||||
{
|
||||
DotVarExp dve = e.e1.isDotVarExp();
|
||||
|
|
|
@ -19,7 +19,6 @@ import core.stdc.string;
|
|||
|
||||
import dmd.aggregate;
|
||||
import dmd.aliasthis;
|
||||
import dmd.apply;
|
||||
import dmd.arrayop;
|
||||
import dmd.arraytypes;
|
||||
import dmd.astenums;
|
||||
|
@ -56,6 +55,7 @@ import dmd.nspace;
|
|||
import dmd.objc;
|
||||
import dmd.opover;
|
||||
import dmd.optimize;
|
||||
import dmd.postordervisitor;
|
||||
import dmd.root.complex;
|
||||
import dmd.root.ctfloat;
|
||||
import dmd.root.filename;
|
||||
|
@ -699,6 +699,20 @@ VarDeclaration expToVariable(Expression e)
|
|||
case EXP.super_:
|
||||
return (cast(ThisExp)e).var.isVarDeclaration();
|
||||
|
||||
// Temporaries for rvalues that need destruction
|
||||
// are of form: (T s = rvalue, s). For these cases
|
||||
// we can just return var declaration of `s`. However,
|
||||
// this is intentionally not calling `Expression.extractLast`
|
||||
// because at this point we cannot infer the var declaration
|
||||
// of more complex generated comma expressions such as the
|
||||
// one for the array append hook.
|
||||
case EXP.comma:
|
||||
{
|
||||
if (auto ve = e.isCommaExp().e2.isVarExp())
|
||||
return ve.var.isVarDeclaration();
|
||||
|
||||
return null;
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
@ -723,7 +737,6 @@ extern (C++) abstract class Expression : ASTNode
|
|||
Type type; // !=null means that semantic() has been run
|
||||
Loc loc; // file location
|
||||
const EXP op; // to minimize use of dynamic_cast
|
||||
bool parens; // if this is a parenthesized expression
|
||||
|
||||
extern (D) this(const ref Loc loc, EXP op) scope
|
||||
{
|
||||
|
@ -1530,6 +1543,11 @@ extern (C++) abstract class Expression : ASTNode
|
|||
return false;
|
||||
if (sc.flags & (SCOPE.ctfe | SCOPE.debug_))
|
||||
return false;
|
||||
/* The original expression (`new S(...)`) will be verified instead. This
|
||||
* is to keep errors related to the original code and not the lowering.
|
||||
*/
|
||||
if (f.ident == Id._d_newitemT)
|
||||
return false;
|
||||
|
||||
if (!f.isNogc())
|
||||
{
|
||||
|
@ -2338,6 +2356,7 @@ extern (C++) final class ComplexExp : Expression
|
|||
extern (C++) class IdentifierExp : Expression
|
||||
{
|
||||
Identifier ident;
|
||||
bool parens; // if it appears as (identifier)
|
||||
|
||||
extern (D) this(const ref Loc loc, Identifier ident) scope
|
||||
{
|
||||
|
@ -3520,6 +3539,8 @@ extern (C++) final class CompoundLiteralExp : Expression
|
|||
*/
|
||||
extern (C++) final class TypeExp : Expression
|
||||
{
|
||||
bool parens; // if this is a parenthesized expression
|
||||
|
||||
extern (D) this(const ref Loc loc, Type type)
|
||||
{
|
||||
super(loc, EXP.type);
|
||||
|
@ -3672,7 +3693,7 @@ extern (C++) final class NewExp : Expression
|
|||
bool onstack; // allocate on stack
|
||||
bool thrownew; // this NewExp is the expression of a ThrowStatement
|
||||
|
||||
Expression lowering; // lowered druntime hook: `_d_newclass`
|
||||
Expression lowering; // lowered druntime hook: `_d_new{class,itemT}`
|
||||
|
||||
/// Puts the `arguments` and `names` into an `ArgumentList` for easily passing them around.
|
||||
/// The fields are still separate for backwards compatibility
|
||||
|
@ -5188,6 +5209,7 @@ extern (C++) final class CallExp : UnaExp
|
|||
bool directcall; // true if a virtual call is devirtualized
|
||||
bool inDebugStatement; /// true if this was in a debug statement
|
||||
bool ignoreAttributes; /// don't enforce attributes (e.g. call @gc function in @nogc code)
|
||||
bool isUfcsRewrite; /// the first argument was pushed in here by a UFCS rewrite
|
||||
VarDeclaration vthis2; // container for multi-context
|
||||
|
||||
/// Puts the `arguments` and `names` into an `ArgumentList` for easily passing them around.
|
||||
|
@ -5329,6 +5351,26 @@ extern (C++) final class CallExp : UnaExp
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the called function type from a call expression
|
||||
* Params:
|
||||
* ce = function call expression. Must have had semantic analysis done.
|
||||
* Returns: called function type, or `null` if error / no semantic analysis done
|
||||
*/
|
||||
TypeFunction calledFunctionType(CallExp ce)
|
||||
{
|
||||
Type t = ce.e1.type;
|
||||
if (!t)
|
||||
return null;
|
||||
t = t.toBasetype();
|
||||
if (auto tf = t.isTypeFunction())
|
||||
return tf;
|
||||
else if (auto td = t.isTypeDelegate())
|
||||
return td.nextOf().isTypeFunction();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
FuncDeclaration isFuncAddress(Expression e, bool* hasOverloads = null)
|
||||
{
|
||||
if (auto ae = e.isAddrExp())
|
||||
|
@ -7058,9 +7100,7 @@ extern (C++) final class FileInitExp : DefaultInitExp
|
|||
s = loc.isValid() ? loc.filename : sc._module.ident.toChars();
|
||||
|
||||
Expression e = new StringExp(loc, s.toDString());
|
||||
e = e.expressionSemantic(sc);
|
||||
e = e.castTo(sc, type);
|
||||
return e;
|
||||
return e.expressionSemantic(sc);
|
||||
}
|
||||
|
||||
override void accept(Visitor v)
|
||||
|
@ -7082,8 +7122,7 @@ extern (C++) final class LineInitExp : DefaultInitExp
|
|||
override Expression resolveLoc(const ref Loc loc, Scope* sc)
|
||||
{
|
||||
Expression e = new IntegerExp(loc, loc.linnum, Type.tint32);
|
||||
e = e.castTo(sc, type);
|
||||
return e;
|
||||
return e.expressionSemantic(sc);
|
||||
}
|
||||
|
||||
override void accept(Visitor v)
|
||||
|
@ -7106,9 +7145,7 @@ extern (C++) final class ModuleInitExp : DefaultInitExp
|
|||
{
|
||||
const auto s = (sc.callsc ? sc.callsc : sc)._module.toPrettyChars().toDString();
|
||||
Expression e = new StringExp(loc, s);
|
||||
e = e.expressionSemantic(sc);
|
||||
e = e.castTo(sc, type);
|
||||
return e;
|
||||
return e.expressionSemantic(sc);
|
||||
}
|
||||
|
||||
override void accept(Visitor v)
|
||||
|
@ -7137,9 +7174,7 @@ extern (C++) final class FuncInitExp : DefaultInitExp
|
|||
else
|
||||
s = "";
|
||||
Expression e = new StringExp(loc, s.toDString());
|
||||
e = e.expressionSemantic(sc);
|
||||
e.type = Type.tstring;
|
||||
return e;
|
||||
return e.expressionSemantic(sc);
|
||||
}
|
||||
|
||||
override void accept(Visitor v)
|
||||
|
|
|
@ -83,7 +83,6 @@ public:
|
|||
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
|
||||
|
||||
size_t size() const;
|
||||
static void _init();
|
||||
|
@ -316,6 +315,7 @@ class IdentifierExp : public Expression
|
|||
{
|
||||
public:
|
||||
Identifier *ident;
|
||||
d_bool parens;
|
||||
|
||||
static IdentifierExp *create(const Loc &loc, Identifier *ident);
|
||||
bool isLvalue() override final;
|
||||
|
@ -839,6 +839,7 @@ public:
|
|||
d_bool directcall; // true if a virtual call is devirtualized
|
||||
d_bool inDebugStatement; // true if this was in a debug statement
|
||||
d_bool ignoreAttributes; // don't enforce attributes (e.g. call @gc function in @nogc code)
|
||||
d_bool isUfcsRewrite; // the first argument was pushed in here by a UFCS rewrite
|
||||
VarDeclaration *vthis2; // container for multi-context
|
||||
|
||||
static CallExp *create(const Loc &loc, Expression *e, Expressions *exps);
|
||||
|
|
|
@ -653,7 +653,7 @@ private Expression resolveUFCS(Scope* sc, CallExp ce)
|
|||
if (!ce.names)
|
||||
ce.names = new Identifiers();
|
||||
ce.names.shift(null);
|
||||
|
||||
ce.isUfcsRewrite = true;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -1254,12 +1254,12 @@ private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 =
|
|||
return ErrorExp.get();
|
||||
e2 = resolveProperties(sc, e2);
|
||||
|
||||
Expressions a;
|
||||
Expressions* a = new Expressions();
|
||||
a.push(e2);
|
||||
|
||||
for (size_t i = 0; i < os.a.length; i++)
|
||||
{
|
||||
if (FuncDeclaration f = resolveFuncCall(loc, sc, os.a[i], tiargs, tthis, ArgumentList(&a), FuncResolveFlag.quiet))
|
||||
if (FuncDeclaration f = resolveFuncCall(loc, sc, os.a[i], tiargs, tthis, ArgumentList(a), FuncResolveFlag.quiet))
|
||||
{
|
||||
if (f.errors)
|
||||
return ErrorExp.get();
|
||||
|
@ -1378,10 +1378,10 @@ private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 =
|
|||
return ErrorExp.get();
|
||||
e2 = resolveProperties(sc, e2);
|
||||
|
||||
Expressions a;
|
||||
Expressions* a = new Expressions();
|
||||
a.push(e2);
|
||||
|
||||
FuncDeclaration fd = resolveFuncCall(loc, sc, s, tiargs, tthis, ArgumentList(&a), FuncResolveFlag.quiet);
|
||||
FuncDeclaration fd = resolveFuncCall(loc, sc, s, tiargs, tthis, ArgumentList(a), FuncResolveFlag.quiet);
|
||||
if (fd && fd.type)
|
||||
{
|
||||
if (fd.errors)
|
||||
|
@ -3574,6 +3574,51 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
result = exp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the `lowering` field of a `NewExp` to a call to `_d_newitemT` unless
|
||||
* compiling with `-betterC` or within `__traits(compiles)`.
|
||||
*
|
||||
* Params:
|
||||
* ne = the `NewExp` to lower
|
||||
*/
|
||||
private void tryLowerToNewItem(NewExp ne)
|
||||
{
|
||||
if (global.params.betterC || !sc.needsCodegen())
|
||||
return;
|
||||
|
||||
auto hook = global.params.tracegc ? Id._d_newitemTTrace : Id._d_newitemT;
|
||||
if (!verifyHookExist(ne.loc, *sc, hook, "new struct"))
|
||||
return;
|
||||
|
||||
/* Lower the memory allocation and initialization of `new T()` to
|
||||
* `_d_newitemT!T()`.
|
||||
*/
|
||||
Expression id = new IdentifierExp(ne.loc, Id.empty);
|
||||
id = new DotIdExp(ne.loc, id, Id.object);
|
||||
auto tiargs = new Objects();
|
||||
/*
|
||||
* Remove `inout`, `const`, `immutable` and `shared` to reduce the
|
||||
* number of generated `_d_newitemT` instances.
|
||||
*/
|
||||
auto t = ne.type.nextOf.unqualify(MODFlags.wild | MODFlags.const_ |
|
||||
MODFlags.immutable_ | MODFlags.shared_);
|
||||
tiargs.push(t);
|
||||
id = new DotTemplateInstanceExp(ne.loc, id, hook, tiargs);
|
||||
|
||||
auto arguments = new Expressions();
|
||||
if (global.params.tracegc)
|
||||
{
|
||||
auto funcname = (sc.callsc && sc.callsc.func) ?
|
||||
sc.callsc.func.toPrettyChars() : sc.func.toPrettyChars();
|
||||
arguments.push(new StringExp(ne.loc, ne.loc.filename.toDString()));
|
||||
arguments.push(new IntegerExp(ne.loc, ne.loc.linnum, Type.tint32));
|
||||
arguments.push(new StringExp(ne.loc, funcname.toDString()));
|
||||
}
|
||||
id = new CallExp(ne.loc, id, arguments);
|
||||
|
||||
ne.lowering = id.expressionSemantic(sc);
|
||||
}
|
||||
|
||||
override void visit(NewExp exp)
|
||||
{
|
||||
static if (LOGSEMANTIC)
|
||||
|
@ -4007,6 +4052,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
}
|
||||
|
||||
exp.type = exp.type.pointerTo();
|
||||
tryLowerToNewItem(exp);
|
||||
}
|
||||
else if (tb.ty == Tarray)
|
||||
{
|
||||
|
@ -4078,6 +4124,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
}
|
||||
|
||||
exp.type = exp.type.pointerTo();
|
||||
tryLowerToNewItem(exp);
|
||||
}
|
||||
else if (tb.ty == Taarray)
|
||||
{
|
||||
|
@ -5192,7 +5239,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
{
|
||||
s = (cast(TemplateExp)exp.e1).td;
|
||||
L2:
|
||||
exp.f = resolveFuncCall(exp.loc, sc, s, tiargs, null, exp.argumentList, FuncResolveFlag.standard);
|
||||
exp.f = resolveFuncCall(exp.loc, sc, s, tiargs, null, exp.argumentList,
|
||||
exp.isUfcsRewrite ? FuncResolveFlag.ufcs : FuncResolveFlag.standard);
|
||||
if (!exp.f || exp.f.errors)
|
||||
return setError();
|
||||
if (exp.f.needThis())
|
||||
|
@ -5301,6 +5349,13 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
buf.writeByte(')');
|
||||
|
||||
//printf("tf = %s, args = %s\n", tf.deco, (*arguments)[0].type.deco);
|
||||
if (exp.isUfcsRewrite)
|
||||
{
|
||||
const arg = (*exp.argumentList.arguments)[0];
|
||||
.error(exp.loc, "no property `%s` for `%s` of type `%s`", exp.f.ident.toChars(), arg.toChars(), arg.type.toChars());
|
||||
.errorSupplemental(exp.loc, "the following error occured while looking for a UFCS match");
|
||||
}
|
||||
|
||||
.error(exp.loc, "%s `%s%s` is not callable using argument types `%s`",
|
||||
exp.f.kind(), exp.f.toPrettyChars(), parametersTypeToChars(tf.parameterList), buf.peekChars());
|
||||
if (failMessage)
|
||||
|
@ -6733,7 +6788,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
|
||||
if (exp.ident != Id.__sizeof)
|
||||
{
|
||||
result = fieldLookup(exp.e1, sc, exp.ident);
|
||||
result = fieldLookup(exp.e1, sc, exp.ident, exp.arrow);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -9068,7 +9123,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
else if (sc.flags & SCOPE.Cfile && e1x.isDotIdExp())
|
||||
{
|
||||
auto die = e1x.isDotIdExp();
|
||||
e1x = fieldLookup(die.e1, sc, die.ident);
|
||||
e1x = fieldLookup(die.e1, sc, die.ident, die.arrow);
|
||||
}
|
||||
else if (auto die = e1x.isDotIdExp())
|
||||
{
|
||||
|
@ -11023,7 +11078,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
/* `_d_arraycatnTX` canot be used with `-betterC`, but `CatExp`s may be
|
||||
* used with `-betterC`, but only during CTFE.
|
||||
*/
|
||||
if (global.params.betterC)
|
||||
if (global.params.betterC || !sc.needsCodegen())
|
||||
return;
|
||||
|
||||
if (auto ce = exp.isCatExp())
|
||||
|
@ -13175,10 +13230,20 @@ Expression dotIdSemanticProp(DotIdExp exp, Scope* sc, bool gag)
|
|||
Expression se = new ScopeExp(exp.loc, imp.pkg);
|
||||
return se.expressionSemantic(sc);
|
||||
}
|
||||
|
||||
if (auto attr = s.isAttribDeclaration())
|
||||
{
|
||||
if (auto sm = ie.sds.search(exp.loc, exp.ident, flags))
|
||||
{
|
||||
auto es = new DsymbolExp(exp.loc, sm);
|
||||
return es;
|
||||
}
|
||||
}
|
||||
|
||||
// BUG: handle other cases like in IdentifierExp::semantic()
|
||||
debug
|
||||
{
|
||||
printf("s = '%s', kind = '%s'\n", s.toChars(), s.kind());
|
||||
printf("s = %p '%s', kind = '%s'\n", s, s.toChars(), s.kind());
|
||||
}
|
||||
assert(0);
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ import core.stdc.stdio;
|
|||
import core.stdc.stdlib;
|
||||
import core.stdc.string;
|
||||
|
||||
import dmd.apply;
|
||||
import dmd.arraytypes;
|
||||
import dmd.astenums;
|
||||
import dmd.attrib;
|
||||
|
@ -33,6 +32,7 @@ import dmd.identifier;
|
|||
import dmd.init;
|
||||
import dmd.initsem;
|
||||
import dmd.mtype;
|
||||
import dmd.postordervisitor;
|
||||
import dmd.printast;
|
||||
import dmd.root.array;
|
||||
import dmd.root.rootobject;
|
||||
|
|
|
@ -59,6 +59,10 @@ import dmd.statementsem;
|
|||
import dmd.tokens;
|
||||
import dmd.visitor;
|
||||
|
||||
version (IN_GCC) {}
|
||||
else version (IN_LLVM) {}
|
||||
else version = MARS;
|
||||
|
||||
/// Inline Status
|
||||
enum ILS : ubyte
|
||||
{
|
||||
|
@ -259,21 +263,30 @@ extern (C++) struct Ensure
|
|||
}
|
||||
|
||||
/***********************************************************
|
||||
* Most functions don't have contracts, so save memory by grouping
|
||||
* this information into a separate struct
|
||||
*/
|
||||
extern (C++) class FuncDeclaration : Declaration
|
||||
private struct ContractInfo
|
||||
{
|
||||
Statements* frequires; /// in contracts
|
||||
Ensures* fensures; /// out contracts
|
||||
Statement frequire; /// lowered in contract
|
||||
Statement fensure; /// lowered out contract
|
||||
FuncDeclaration fdrequire; /// function that does the in contract
|
||||
FuncDeclaration fdensure; /// function that does the out contract
|
||||
Expressions* fdrequireParams; /// argument list for __require
|
||||
Expressions* fdensureParams; /// argument list for __ensure
|
||||
}
|
||||
|
||||
/***********************************************************
|
||||
*/
|
||||
extern (C++) class FuncDeclaration : Declaration
|
||||
{
|
||||
Statement fbody; /// function body
|
||||
|
||||
FuncDeclarations foverrides; /// functions this function overrides
|
||||
FuncDeclaration fdrequire; /// function that does the in contract
|
||||
FuncDeclaration fdensure; /// function that does the out contract
|
||||
|
||||
Expressions* fdrequireParams; /// argument list for __require
|
||||
Expressions* fdensureParams; /// argument list for __ensure
|
||||
private ContractInfo* contracts; /// contract information
|
||||
|
||||
const(char)* mangleString; /// mangled symbol created from mangleExact()
|
||||
|
||||
|
@ -403,6 +416,44 @@ extern (C++) class FuncDeclaration : Declaration
|
|||
return new FuncDeclaration(loc, endloc, id, storage_class, type, noreturn);
|
||||
}
|
||||
|
||||
final nothrow pure @safe
|
||||
{
|
||||
private ref ContractInfo getContracts()
|
||||
{
|
||||
if (!contracts)
|
||||
contracts = new ContractInfo();
|
||||
return *contracts;
|
||||
}
|
||||
|
||||
// getters
|
||||
inout(Statements*) frequires() inout { return contracts ? contracts.frequires : null; }
|
||||
inout(Ensures*) fensures() inout { return contracts ? contracts.fensures : null; }
|
||||
inout(Statement) frequire() inout { return contracts ? contracts.frequire: null; }
|
||||
inout(Statement) fensure() inout { return contracts ? contracts.fensure : null; }
|
||||
inout(FuncDeclaration) fdrequire() inout { return contracts ? contracts.fdrequire : null; }
|
||||
inout(FuncDeclaration) fdensure() inout { return contracts ? contracts.fdensure: null; }
|
||||
inout(Expressions*) fdrequireParams() inout { return contracts ? contracts.fdrequireParams: null; }
|
||||
inout(Expressions*) fdensureParams() inout { return contracts ? contracts.fdensureParams: null; }
|
||||
|
||||
extern (D) private static string generateContractSetter(string field, string type)
|
||||
{
|
||||
return type ~ " " ~ field ~ "(" ~ type ~ " param)" ~
|
||||
"{
|
||||
if (!param && !contracts) return null;
|
||||
return getContracts()." ~ field ~ " = param;
|
||||
}";
|
||||
}
|
||||
|
||||
mixin(generateContractSetter("frequires", "Statements*"));
|
||||
mixin(generateContractSetter("fensures", "Ensures*"));
|
||||
mixin(generateContractSetter("frequire", "Statement"));
|
||||
mixin(generateContractSetter("fensure", "Statement"));
|
||||
mixin(generateContractSetter("fdrequire", "FuncDeclaration"));
|
||||
mixin(generateContractSetter("fdensure", "FuncDeclaration"));
|
||||
mixin(generateContractSetter("fdrequireParams", "Expressions*"));
|
||||
mixin(generateContractSetter("fdensureParams", "Expressions*"));
|
||||
}
|
||||
|
||||
override FuncDeclaration syntaxCopy(Dsymbol s)
|
||||
{
|
||||
//printf("FuncDeclaration::syntaxCopy('%s')\n", toChars());
|
||||
|
@ -2717,7 +2768,7 @@ extern (C++) class FuncDeclaration : Declaration
|
|||
*/
|
||||
static FuncDeclaration genCfunc(Parameters* fparams, Type treturn, const(char)* name, StorageClass stc = 0)
|
||||
{
|
||||
return genCfunc(fparams, treturn, Identifier.idPool(name, cast(uint)strlen(name)), stc);
|
||||
return genCfunc(fparams, treturn, Identifier.idPool(name[0 .. strlen(name)]), stc);
|
||||
}
|
||||
|
||||
static FuncDeclaration genCfunc(Parameters* fparams, Type treturn, Identifier id, StorageClass stc = 0)
|
||||
|
@ -3199,6 +3250,7 @@ enum FuncResolveFlag : ubyte
|
|||
quiet = 1, /// do not issue error message on no match, just return `null`.
|
||||
overloadOnly = 2, /// only resolve overloads, i.e. do not issue error on ambiguous
|
||||
/// matches and need explicit this.
|
||||
ufcs = 4, /// trying to resolve UFCS call
|
||||
}
|
||||
|
||||
/*******************************************
|
||||
|
@ -3316,12 +3368,22 @@ FuncDeclaration resolveFuncCall(const ref Loc loc, Scope* sc, Dsymbol s,
|
|||
}
|
||||
|
||||
// no match, generate an error messages
|
||||
if (flags & FuncResolveFlag.ufcs)
|
||||
{
|
||||
auto arg = (*fargs)[0];
|
||||
.error(loc, "no property `%s` for `%s` of type `%s`", s.ident.toChars(), arg.toChars(), arg.type.toChars());
|
||||
.errorSupplemental(loc, "the following error occured while looking for a UFCS match");
|
||||
}
|
||||
|
||||
if (!fd)
|
||||
{
|
||||
// all of overloads are templates
|
||||
if (td)
|
||||
{
|
||||
.error(loc, "none of the overloads of %s `%s.%s` are callable using argument types `!(%s)%s`",
|
||||
const(char)* msg = "none of the overloads of %s `%s.%s` are callable using argument types `!(%s)%s`";
|
||||
if (!od && !td.overnext)
|
||||
msg = "%s `%s.%s` is not callable using argument types `!(%s)%s`";
|
||||
.error(loc, msg,
|
||||
td.kind(), td.parent.toPrettyChars(), td.ident.toChars(),
|
||||
tiargsBuf.peekChars(), fargsBuf.peekChars());
|
||||
|
||||
|
|
|
@ -26,6 +26,10 @@ import dmd.location;
|
|||
import dmd.lexer : CompileEnv;
|
||||
import dmd.utils;
|
||||
|
||||
version (IN_GCC) {}
|
||||
else version (IN_LLVM) {}
|
||||
else version = MARS;
|
||||
|
||||
/// Defines a setting for how compiler warnings and deprecations are handled
|
||||
enum DiagnosticReporting : ubyte
|
||||
{
|
||||
|
|
|
@ -353,10 +353,11 @@ typedef unsigned long long uinteger_t;
|
|||
// file location
|
||||
struct Loc
|
||||
{
|
||||
const char *filename; // either absolute or relative to cwd
|
||||
unsigned linnum;
|
||||
unsigned charnum;
|
||||
|
||||
private:
|
||||
unsigned _linnum;
|
||||
unsigned short _charnum;
|
||||
unsigned short fileIndex;
|
||||
public:
|
||||
static void set(bool showColumns, MessageStyle messageStyle);
|
||||
|
||||
static bool showColumns;
|
||||
|
@ -364,18 +365,25 @@ struct Loc
|
|||
|
||||
Loc()
|
||||
{
|
||||
linnum = 0;
|
||||
charnum = 0;
|
||||
filename = NULL;
|
||||
_linnum = 0;
|
||||
_charnum = 0;
|
||||
fileIndex = 0;
|
||||
}
|
||||
|
||||
Loc(const char *filename, unsigned linnum, unsigned charnum)
|
||||
{
|
||||
this->linnum = linnum;
|
||||
this->charnum = charnum;
|
||||
this->filename = filename;
|
||||
this->linnum(linnum);
|
||||
this->charnum(charnum);
|
||||
this->filename(filename);
|
||||
}
|
||||
|
||||
uint32_t charnum() const;
|
||||
uint32_t charnum(uint32_t num);
|
||||
uint32_t linnum() const;
|
||||
uint32_t linnum(uint32_t num);
|
||||
const char *filename() const;
|
||||
void filename(const char *name);
|
||||
|
||||
const char *toChars(
|
||||
bool showColumns = Loc::showColumns,
|
||||
MessageStyle messageStyle = Loc::messageStyle) const;
|
||||
|
|
|
@ -48,25 +48,6 @@ version (NoBackend)
|
|||
}
|
||||
}
|
||||
}
|
||||
else version (MARS)
|
||||
{
|
||||
public import dmd.backend.cc : block, Blockx, Symbol;
|
||||
public import dmd.backend.type : type;
|
||||
public import dmd.backend.el : elem;
|
||||
public import dmd.backend.code_x86 : code;
|
||||
|
||||
extern (C++)
|
||||
{
|
||||
Statement asmSemantic(AsmStatement s, Scope* sc);
|
||||
|
||||
void toObjFile(Dsymbol ds, bool multiobj);
|
||||
|
||||
extern(C++) abstract class ObjcGlue
|
||||
{
|
||||
static void initialize();
|
||||
}
|
||||
}
|
||||
}
|
||||
else version (IN_GCC)
|
||||
{
|
||||
extern (C++) union tree_node;
|
||||
|
@ -88,4 +69,12 @@ else version (IN_GCC)
|
|||
}
|
||||
}
|
||||
else
|
||||
static assert(false, "Unsupported compiler backend");
|
||||
{
|
||||
public import dmd.backend.cc : block, Blockx, Symbol;
|
||||
public import dmd.backend.type : type;
|
||||
public import dmd.backend.el : elem;
|
||||
public import dmd.backend.code_x86 : code;
|
||||
public import dmd.iasm : asmSemantic;
|
||||
public import dmd.objc_glue : ObjcGlue;
|
||||
public import dmd.toobj : toObjFile;
|
||||
}
|
||||
|
|
|
@ -23,14 +23,15 @@ import dmd.tokens;
|
|||
import dmd.statement;
|
||||
import dmd.statementsem;
|
||||
|
||||
version (MARS)
|
||||
{
|
||||
import dmd.iasmdmd;
|
||||
}
|
||||
else version (IN_GCC)
|
||||
version (IN_GCC)
|
||||
{
|
||||
import dmd.iasmgcc;
|
||||
}
|
||||
else
|
||||
{
|
||||
import dmd.iasmdmd;
|
||||
version = MARS;
|
||||
}
|
||||
|
||||
/************************ AsmStatement ***************************************/
|
||||
|
||||
|
|
|
@ -315,6 +315,8 @@ immutable Msgtable[] msgtable =
|
|||
{ "_d_newThrowable" },
|
||||
{ "_d_newclassT" },
|
||||
{ "_d_newclassTTrace" },
|
||||
{ "_d_newitemT" },
|
||||
{ "_d_newitemTTrace" },
|
||||
{ "_d_assert_fail" },
|
||||
{ "dup" },
|
||||
{ "_aaApply" },
|
||||
|
@ -549,6 +551,7 @@ immutable Msgtable[] msgtable =
|
|||
{ "_pure", "pure" },
|
||||
{ "define" },
|
||||
{ "undef" },
|
||||
{ "ident" },
|
||||
];
|
||||
|
||||
|
||||
|
|
|
@ -274,12 +274,7 @@ nothrow:
|
|||
return idPool(s[0 .. len]);
|
||||
}
|
||||
|
||||
extern (D) static Identifier idPool(const(char)[] s)
|
||||
{
|
||||
return idPool(s, false);
|
||||
}
|
||||
|
||||
extern (D) private static Identifier idPool(const(char)[] s, bool isAnonymous)
|
||||
extern (D) static Identifier idPool(const(char)[] s, bool isAnonymous = false)
|
||||
{
|
||||
auto sv = stringtable.update(s);
|
||||
auto id = sv.value;
|
||||
|
@ -291,18 +286,18 @@ nothrow:
|
|||
return id;
|
||||
}
|
||||
|
||||
extern (D) static Identifier idPool(const(char)* s, size_t len, int value)
|
||||
{
|
||||
return idPool(s[0 .. len], value);
|
||||
}
|
||||
|
||||
extern (D) static Identifier idPool(const(char)[] s, int value)
|
||||
/******************************************
|
||||
* Used for inserting keywords into the string table.
|
||||
* Params:
|
||||
* s = string for keyword
|
||||
* value = TOK.xxxx for the keyword
|
||||
*/
|
||||
extern (D) static void idPool(const(char)[] s, TOK value)
|
||||
{
|
||||
auto sv = stringtable.insert(s, null);
|
||||
assert(sv);
|
||||
auto id = new Identifier(sv.toString(), value);
|
||||
sv.value = id;
|
||||
return id;
|
||||
}
|
||||
|
||||
/**********************************
|
||||
|
|
|
@ -108,11 +108,12 @@ Expression arrayFuncConv(Expression e, Scope* sc)
|
|||
* e = evaluates to an instance of a struct
|
||||
* sc = context
|
||||
* id = identifier of a field in that struct
|
||||
* arrow = -> was used
|
||||
* Returns:
|
||||
* if successful `e.ident`
|
||||
* if not then `ErrorExp` and message is printed
|
||||
*/
|
||||
Expression fieldLookup(Expression e, Scope* sc, Identifier id)
|
||||
Expression fieldLookup(Expression e, Scope* sc, Identifier id, bool arrow)
|
||||
{
|
||||
e = e.expressionSemantic(sc);
|
||||
if (e.isErrorExp())
|
||||
|
@ -123,6 +124,9 @@ Expression fieldLookup(Expression e, Scope* sc, Identifier id)
|
|||
if (t.isTypePointer())
|
||||
{
|
||||
t = t.isTypePointer().next;
|
||||
auto pe = e.toChars();
|
||||
if (!arrow)
|
||||
e.error("since `%s` is a pointer, use `%s->%s` instead of `%s.%s`", pe, pe, id.toChars(), pe, id.toChars());
|
||||
e = new PtrExp(e.loc, e);
|
||||
}
|
||||
if (auto ts = t.isTypeStruct())
|
||||
|
@ -237,15 +241,16 @@ Expression castCallAmbiguity(Expression e, Scope* sc)
|
|||
|
||||
case EXP.call:
|
||||
auto ce = (*pe).isCallExp();
|
||||
if (ce.e1.parens)
|
||||
auto ie = ce.e1.isIdentifierExp();
|
||||
if (ie && ie.parens)
|
||||
{
|
||||
ce.e1 = expressionSemantic(ce.e1, sc);
|
||||
ce.e1 = expressionSemantic(ie, sc);
|
||||
if (ce.e1.op == EXP.type)
|
||||
{
|
||||
const numArgs = ce.arguments ? ce.arguments.length : 0;
|
||||
if (numArgs >= 1)
|
||||
{
|
||||
ce.e1.parens = false;
|
||||
ie.parens = false;
|
||||
Expression arg;
|
||||
foreach (a; (*ce.arguments)[])
|
||||
{
|
||||
|
|
|
@ -587,6 +587,9 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
|
|||
*/
|
||||
t = t.toBasetype();
|
||||
|
||||
if (auto tv = t.isTypeVector())
|
||||
t = tv.basetype;
|
||||
|
||||
/* If `{ expression }` return the expression initializer
|
||||
*/
|
||||
ExpInitializer isBraceExpression()
|
||||
|
|
|
@ -119,7 +119,7 @@ class Lexer
|
|||
this(const(char)* filename, const(char)* base, size_t begoffset,
|
||||
size_t endoffset, bool doDocComment, bool commentToken,
|
||||
ErrorSink errorSink,
|
||||
const CompileEnv* compileEnv) pure scope
|
||||
const CompileEnv* compileEnv) scope
|
||||
{
|
||||
scanloc = Loc(filename, 1, 1);
|
||||
// debug printf("Lexer::Lexer(%p)\n", base);
|
||||
|
@ -573,7 +573,7 @@ class Lexer
|
|||
}
|
||||
break;
|
||||
}
|
||||
Identifier id = Identifier.idPool(cast(char*)t.ptr, cast(uint)(p - t.ptr));
|
||||
Identifier id = Identifier.idPool((cast(char*)t.ptr)[0 .. p - t.ptr], false);
|
||||
t.ident = id;
|
||||
t.value = cast(TOK)id.getValue();
|
||||
|
||||
|
@ -2672,9 +2672,9 @@ class Lexer
|
|||
return result;
|
||||
}
|
||||
|
||||
final Loc loc() pure @nogc
|
||||
final Loc loc() @nogc
|
||||
{
|
||||
scanloc.charnum = cast(uint)(1 + p - line);
|
||||
scanloc.charnum = cast(ushort)(1 + p - line);
|
||||
version (LocOffset)
|
||||
scanloc.fileOffset = cast(uint)(p - base);
|
||||
return scanloc;
|
||||
|
@ -3098,9 +3098,9 @@ class Lexer
|
|||
/**************************
|
||||
* `p` should be at start of next line
|
||||
*/
|
||||
private void endOfLine() pure @nogc @safe
|
||||
private void endOfLine() @nogc @safe
|
||||
{
|
||||
scanloc.linnum++;
|
||||
scanloc.linnum = scanloc.linnum + 1;
|
||||
line = p;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,10 @@
|
|||
|
||||
module dmd.location;
|
||||
|
||||
import core.stdc.stdio;
|
||||
|
||||
import dmd.common.outbuffer;
|
||||
import dmd.root.array;
|
||||
import dmd.root.filename;
|
||||
|
||||
version (DMDLIB)
|
||||
|
@ -34,10 +37,9 @@ debug info etc.
|
|||
*/
|
||||
struct Loc
|
||||
{
|
||||
/// zero-terminated filename string, either absolute or relative to cwd
|
||||
const(char)* filename;
|
||||
uint linnum; /// line number, starting from 1
|
||||
uint charnum; /// utf8 code unit index relative to start of line, starting from 1
|
||||
private uint _linnum;
|
||||
private ushort _charnum;
|
||||
private ushort fileIndex; // index into filenames[], starting from 1 (0 means no filename)
|
||||
version (LocOffset)
|
||||
uint fileOffset; /// utf8 code unit index relative to start of file, starting from 0
|
||||
|
||||
|
@ -46,6 +48,8 @@ struct Loc
|
|||
extern (C++) __gshared bool showColumns;
|
||||
extern (C++) __gshared MessageStyle messageStyle;
|
||||
|
||||
__gshared Array!(const(char)*) filenames;
|
||||
|
||||
nothrow:
|
||||
|
||||
/*******************************
|
||||
|
@ -60,19 +64,69 @@ nothrow:
|
|||
this.messageStyle = messageStyle;
|
||||
}
|
||||
|
||||
extern (D) this(const(char)* filename, uint linnum, uint charnum) pure
|
||||
extern (D) this(const(char)* filename, uint linnum, uint charnum)
|
||||
{
|
||||
this.linnum = linnum;
|
||||
this.charnum = charnum;
|
||||
this._linnum = linnum;
|
||||
this._charnum = cast(ushort) charnum;
|
||||
this.filename = filename;
|
||||
}
|
||||
|
||||
/// utf8 code unit index relative to start of line, starting from 1
|
||||
extern (C++) uint charnum() const @nogc @safe
|
||||
{
|
||||
return _charnum;
|
||||
}
|
||||
|
||||
/// ditto
|
||||
extern (C++) uint charnum(uint num) @nogc @safe
|
||||
{
|
||||
return _charnum = cast(ushort) num;
|
||||
}
|
||||
|
||||
/// line number, starting from 1
|
||||
extern (C++) uint linnum() const @nogc @safe
|
||||
{
|
||||
return _linnum;
|
||||
}
|
||||
|
||||
/// ditto
|
||||
extern (C++) uint linnum(uint num) @nogc @safe
|
||||
{
|
||||
return _linnum = num;
|
||||
}
|
||||
|
||||
/***
|
||||
* Returns: filename for this location, null if none
|
||||
*/
|
||||
extern (C++) const(char)* filename() const @nogc
|
||||
{
|
||||
return fileIndex ? filenames[fileIndex - 1] : null;
|
||||
}
|
||||
|
||||
/***
|
||||
* Set file name for this location
|
||||
* Params:
|
||||
* name = file name for location, null for no file name
|
||||
*/
|
||||
extern (C++) void filename(const(char)* name)
|
||||
{
|
||||
if (name)
|
||||
{
|
||||
//printf("setting %s\n", name);
|
||||
filenames.push(name);
|
||||
fileIndex = cast(ushort)filenames.length;
|
||||
assert(fileIndex); // no overflow
|
||||
}
|
||||
else
|
||||
fileIndex = 0;
|
||||
}
|
||||
|
||||
extern (C++) const(char)* toChars(
|
||||
bool showColumns = Loc.showColumns,
|
||||
MessageStyle messageStyle = Loc.messageStyle) const pure nothrow
|
||||
MessageStyle messageStyle = Loc.messageStyle) const nothrow
|
||||
{
|
||||
OutBuffer buf;
|
||||
if (filename)
|
||||
if (fileIndex)
|
||||
{
|
||||
buf.writestring(filename);
|
||||
}
|
||||
|
@ -126,7 +180,7 @@ nothrow:
|
|||
* may lead to multiple equivalent filenames (`foo.d-mixin-<line>`),
|
||||
* e.g., for test/runnable/test18880.d.
|
||||
*/
|
||||
extern (D) bool opEquals(ref const(Loc) loc) const @trusted pure nothrow @nogc
|
||||
extern (D) bool opEquals(ref const(Loc) loc) const @trusted nothrow @nogc
|
||||
{
|
||||
import core.stdc.string : strcmp;
|
||||
|
||||
|
@ -137,7 +191,7 @@ nothrow:
|
|||
}
|
||||
|
||||
/// ditto
|
||||
extern (D) size_t toHash() const @trusted pure nothrow
|
||||
extern (D) size_t toHash() const @trusted nothrow
|
||||
{
|
||||
import dmd.root.string : toDString;
|
||||
|
||||
|
@ -153,6 +207,6 @@ nothrow:
|
|||
*/
|
||||
bool isValid() const pure
|
||||
{
|
||||
return filename !is null;
|
||||
return fileIndex != 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2448,7 +2448,7 @@ extern (C++) abstract class Type : ASTNode
|
|||
//printf("%p %s, deco = %s, name = %s\n", this, toChars(), deco, name);
|
||||
assert(0 < length && length < namelen); // don't overflow the buffer
|
||||
|
||||
auto id = Identifier.idPool(name, length);
|
||||
auto id = Identifier.idPool(name[0 .. length]);
|
||||
|
||||
if (name != namebuf.ptr)
|
||||
free(name);
|
||||
|
@ -7119,9 +7119,9 @@ bool isCopyable(Type t)
|
|||
assert(ctor);
|
||||
scope el = new IdentifierExp(Loc.initial, Id.p); // dummy lvalue
|
||||
el.type = cast() ts;
|
||||
Expressions args;
|
||||
Expressions* args = new Expressions();
|
||||
args.push(el);
|
||||
FuncDeclaration f = resolveFuncCall(Loc.initial, null, ctor, null, cast()ts, ArgumentList(&args), FuncResolveFlag.quiet);
|
||||
FuncDeclaration f = resolveFuncCall(Loc.initial, null, ctor, null, cast()ts, ArgumentList(args), FuncResolveFlag.quiet);
|
||||
if (!f || f.storage_class & STC.disable)
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@ module dmd.nogc;
|
|||
import core.stdc.stdio;
|
||||
|
||||
import dmd.aggregate;
|
||||
import dmd.apply;
|
||||
import dmd.astenums;
|
||||
import dmd.declaration;
|
||||
import dmd.dscope;
|
||||
|
@ -26,6 +25,7 @@ import dmd.func;
|
|||
import dmd.globals;
|
||||
import dmd.init;
|
||||
import dmd.mtype;
|
||||
import dmd.postordervisitor;
|
||||
import dmd.tokens;
|
||||
import dmd.visitor;
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@ import dmd.root.rootobject;
|
|||
import dmd.root.rmem;
|
||||
|
||||
import dmd.aggregate;
|
||||
import dmd.apply;
|
||||
import dmd.arraytypes;
|
||||
import dmd.astenums;
|
||||
import dmd.declaration;
|
||||
|
|
|
@ -607,8 +607,6 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
|
|||
//printf("BinExp::op_overload() (%s)\n", e.toChars());
|
||||
Identifier id = opId(e);
|
||||
Identifier id_r = opId_r(e);
|
||||
Expressions args1;
|
||||
Expressions args2;
|
||||
int argsset = 0;
|
||||
AggregateDeclaration ad1 = isAggregate(e.e1.type);
|
||||
AggregateDeclaration ad2 = isAggregate(e.e2.type);
|
||||
|
@ -701,6 +699,8 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
|
|||
}
|
||||
}
|
||||
}
|
||||
Expressions* args1 = new Expressions();
|
||||
Expressions* args2 = new Expressions();
|
||||
if (s || s_r)
|
||||
{
|
||||
/* Try:
|
||||
|
@ -709,16 +709,16 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
|
|||
* and see which is better.
|
||||
*/
|
||||
args1.setDim(1);
|
||||
args1[0] = e.e1;
|
||||
expandTuples(&args1);
|
||||
(*args1)[0] = e.e1;
|
||||
expandTuples(args1);
|
||||
args2.setDim(1);
|
||||
args2[0] = e.e2;
|
||||
expandTuples(&args2);
|
||||
(*args2)[0] = e.e2;
|
||||
expandTuples(args2);
|
||||
argsset = 1;
|
||||
MatchAccumulator m;
|
||||
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));
|
||||
if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors()))
|
||||
{
|
||||
return ErrorExp.get();
|
||||
|
@ -727,7 +727,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
|
|||
FuncDeclaration lastf = m.lastf;
|
||||
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));
|
||||
if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors()))
|
||||
{
|
||||
return ErrorExp.get();
|
||||
|
@ -791,16 +791,16 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
|
|||
if (!argsset)
|
||||
{
|
||||
args1.setDim(1);
|
||||
args1[0] = e.e1;
|
||||
expandTuples(&args1);
|
||||
(*args1)[0] = e.e1;
|
||||
expandTuples(args1);
|
||||
args2.setDim(1);
|
||||
args2[0] = e.e2;
|
||||
expandTuples(&args2);
|
||||
(*args2)[0] = e.e2;
|
||||
expandTuples(args2);
|
||||
}
|
||||
MatchAccumulator m;
|
||||
if (s_r)
|
||||
{
|
||||
functionResolve(m, s_r, e.loc, sc, tiargs, e.e1.type, ArgumentList(&args2));
|
||||
functionResolve(m, s_r, e.loc, sc, tiargs, e.e1.type, ArgumentList(args2));
|
||||
if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors()))
|
||||
{
|
||||
return ErrorExp.get();
|
||||
|
@ -809,7 +809,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
|
|||
FuncDeclaration lastf = m.lastf;
|
||||
if (s)
|
||||
{
|
||||
functionResolve(m, s, e.loc, sc, tiargs, e.e2.type, ArgumentList(&args1));
|
||||
functionResolve(m, s, e.loc, sc, tiargs, e.e2.type, ArgumentList(args1));
|
||||
if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors()))
|
||||
{
|
||||
return ErrorExp.get();
|
||||
|
@ -1197,7 +1197,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
|
|||
return ErrorExp.get();
|
||||
}
|
||||
Identifier id = opId(e);
|
||||
Expressions args2;
|
||||
Expressions* args2 = new Expressions();
|
||||
AggregateDeclaration ad1 = isAggregate(e.e1.type);
|
||||
Dsymbol s = null;
|
||||
Objects* tiargs = null;
|
||||
|
@ -1240,10 +1240,10 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
|
|||
* a.opOpAssign(b)
|
||||
*/
|
||||
args2.setDim(1);
|
||||
args2[0] = e.e2;
|
||||
expandTuples(&args2);
|
||||
(*args2)[0] = e.e2;
|
||||
expandTuples(args2);
|
||||
MatchAccumulator m;
|
||||
functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, ArgumentList(&args2));
|
||||
functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, ArgumentList(args2));
|
||||
if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors()))
|
||||
{
|
||||
return ErrorExp.get();
|
||||
|
@ -1322,12 +1322,12 @@ private Expression compare_overload(BinExp e, Scope* sc, Identifier id, EXP* pop
|
|||
* b.opEquals(a)
|
||||
* and see which is better.
|
||||
*/
|
||||
Expressions args1 = Expressions(1);
|
||||
args1[0] = e.e1;
|
||||
expandTuples(&args1);
|
||||
Expressions args2 = Expressions(1);
|
||||
args2[0] = e.e2;
|
||||
expandTuples(&args2);
|
||||
Expressions* args1 = new Expressions(1);
|
||||
(*args1)[0] = e.e1;
|
||||
expandTuples(args1);
|
||||
Expressions* args2 = new Expressions(1);
|
||||
(*args2)[0] = e.e2;
|
||||
expandTuples(args2);
|
||||
MatchAccumulator m;
|
||||
if (0 && s && s_r)
|
||||
{
|
||||
|
@ -1336,7 +1336,7 @@ private Expression compare_overload(BinExp e, Scope* sc, Identifier id, EXP* pop
|
|||
}
|
||||
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));
|
||||
if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors()))
|
||||
return ErrorExp.get();
|
||||
}
|
||||
|
@ -1344,7 +1344,7 @@ private Expression compare_overload(BinExp e, Scope* sc, Identifier id, EXP* pop
|
|||
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));
|
||||
if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors()))
|
||||
return ErrorExp.get();
|
||||
}
|
||||
|
|
|
@ -769,11 +769,8 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue)
|
|||
return;
|
||||
if (e.arguments)
|
||||
{
|
||||
Type t1 = e.e1.type.toBasetype();
|
||||
if (auto td = t1.isTypeDelegate())
|
||||
t1 = td.next;
|
||||
// t1 can apparently be void for __ArrayDtor(T) calls
|
||||
if (auto tf = t1.isTypeFunction())
|
||||
if (auto tf = e.calledFunctionType())
|
||||
{
|
||||
foreach (i, ref arg; (*e.arguments)[])
|
||||
{
|
||||
|
|
|
@ -4515,10 +4515,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
|
|||
}
|
||||
if (_init)
|
||||
{
|
||||
if (isThis)
|
||||
error(token.loc, "cannot use syntax `alias this = %s`, use `alias %s this` instead", _init.toChars(), _init.toChars());
|
||||
else
|
||||
error("alias cannot have initializer");
|
||||
error("alias cannot have initializer");
|
||||
}
|
||||
v = new AST.AliasDeclaration(aliasLoc, ident, t);
|
||||
|
||||
|
@ -4780,23 +4777,20 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
|
|||
addComment(s, comment);
|
||||
return a;
|
||||
}
|
||||
version (none)
|
||||
/* Look for:
|
||||
* alias this = identifier;
|
||||
*/
|
||||
if (token.value == TOK.this_ && peekNext() == TOK.assign && peekNext2() == TOK.identifier)
|
||||
{
|
||||
/* Look for:
|
||||
* alias this = identifier;
|
||||
*/
|
||||
if (token.value == TOK.this_ && peekNext() == TOK.assign && peekNext2() == TOK.identifier)
|
||||
{
|
||||
check(TOK.this_);
|
||||
check(TOK.assign);
|
||||
auto s = new AliasThis(loc, token.ident);
|
||||
nextToken();
|
||||
check(TOK.semicolon, "`alias this = Identifier`");
|
||||
auto a = new Dsymbols();
|
||||
a.push(s);
|
||||
addComment(s, comment);
|
||||
return a;
|
||||
}
|
||||
check(TOK.this_);
|
||||
check(TOK.assign);
|
||||
auto s = new AST.AliasThis(loc, token.ident);
|
||||
nextToken();
|
||||
check(TOK.semicolon, "`alias this = Identifier`");
|
||||
auto a = new AST.Dsymbols();
|
||||
a.push(s);
|
||||
addComment(s, comment);
|
||||
return a;
|
||||
}
|
||||
/* Look for:
|
||||
* alias identifier = type;
|
||||
|
@ -5032,7 +5026,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
|
|||
stc = STC.ref_;
|
||||
nextToken();
|
||||
}
|
||||
if (token.value != TOK.leftParenthesis && token.value != TOK.leftCurly)
|
||||
if (token.value != TOK.leftParenthesis && token.value != TOK.leftCurly &&
|
||||
token.value != TOK.goesTo)
|
||||
{
|
||||
// function type (parameters) { statements... }
|
||||
// delegate type (parameters) { statements... }
|
||||
|
@ -5331,7 +5326,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
|
|||
error("cannot use function constraints for non-template functions. Use `static if` instead");
|
||||
}
|
||||
else
|
||||
error("semicolon expected following function declaration");
|
||||
error("semicolon expected following function declaration, not `%s`", token.toChars());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -7081,7 +7076,7 @@ LagainStc:
|
|||
|
||||
private void checkParens(TOK value, AST.Expression e)
|
||||
{
|
||||
if (precedence[e.op] == PREC.rel && !e.parens)
|
||||
if (precedence[e.op] == PREC.rel)
|
||||
error(e.loc, "`%s` must be surrounded by parentheses when next to operator `%s`", e.toChars(), Token.toChars(value));
|
||||
}
|
||||
|
||||
|
@ -8485,7 +8480,6 @@ LagainStc:
|
|||
// ( expression )
|
||||
nextToken();
|
||||
e = parseExpression();
|
||||
e.parens = true;
|
||||
check(loc, TOK.rightParenthesis);
|
||||
break;
|
||||
}
|
||||
|
@ -8806,9 +8800,9 @@ LagainStc:
|
|||
nextToken();
|
||||
return AST.ErrorExp.get();
|
||||
}
|
||||
e = new AST.TypeExp(loc, t);
|
||||
e.parens = true;
|
||||
e = parsePostExp(e);
|
||||
auto te = new AST.TypeExp(loc, t);
|
||||
te.parens = true;
|
||||
e = parsePostExp(te);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -9115,14 +9109,18 @@ LagainStc:
|
|||
private AST.Expression parseAndExp()
|
||||
{
|
||||
Loc loc = token.loc;
|
||||
bool parens = token.value == TOK.leftParenthesis;
|
||||
auto e = parseCmpExp();
|
||||
while (token.value == TOK.and)
|
||||
{
|
||||
checkParens(TOK.and, e);
|
||||
nextToken();
|
||||
if (!parens)
|
||||
checkParens(TOK.and, e);
|
||||
parens = nextToken() == TOK.leftParenthesis;
|
||||
auto e2 = parseCmpExp();
|
||||
checkParens(TOK.and, e2);
|
||||
if (!parens)
|
||||
checkParens(TOK.and, e2);
|
||||
e = new AST.AndExp(loc, e, e2);
|
||||
parens = true; // don't call checkParens() for And
|
||||
loc = token.loc;
|
||||
}
|
||||
return e;
|
||||
|
@ -9130,32 +9128,42 @@ LagainStc:
|
|||
|
||||
private AST.Expression parseXorExp()
|
||||
{
|
||||
const loc = token.loc;
|
||||
Loc loc = token.loc;
|
||||
|
||||
bool parens = token.value == TOK.leftParenthesis;
|
||||
auto e = parseAndExp();
|
||||
while (token.value == TOK.xor)
|
||||
{
|
||||
checkParens(TOK.xor, e);
|
||||
nextToken();
|
||||
if (!parens)
|
||||
checkParens(TOK.xor, e);
|
||||
parens = nextToken() == TOK.leftParenthesis;
|
||||
auto e2 = parseAndExp();
|
||||
checkParens(TOK.xor, e2);
|
||||
if (!parens)
|
||||
checkParens(TOK.xor, e2);
|
||||
e = new AST.XorExp(loc, e, e2);
|
||||
parens = true;
|
||||
loc = token.loc;
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
private AST.Expression parseOrExp()
|
||||
{
|
||||
const loc = token.loc;
|
||||
Loc loc = token.loc;
|
||||
|
||||
bool parens = token.value == TOK.leftParenthesis;
|
||||
auto e = parseXorExp();
|
||||
while (token.value == TOK.or)
|
||||
{
|
||||
checkParens(TOK.or, e);
|
||||
nextToken();
|
||||
if (!parens)
|
||||
checkParens(TOK.or, e);
|
||||
parens = nextToken() == TOK.leftParenthesis;
|
||||
auto e2 = parseXorExp();
|
||||
checkParens(TOK.or, e2);
|
||||
if (!parens)
|
||||
checkParens(TOK.or, e2);
|
||||
e = new AST.OrExp(loc, e, e2);
|
||||
parens = true;
|
||||
loc = token.loc;
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
@ -9206,6 +9214,7 @@ LagainStc:
|
|||
|
||||
AST.Expression parseAssignExp()
|
||||
{
|
||||
bool parens = token.value == TOK.leftParenthesis;
|
||||
AST.Expression e;
|
||||
e = parseCondExp();
|
||||
if (e is null)
|
||||
|
@ -9214,7 +9223,7 @@ LagainStc:
|
|||
// require parens for e.g. `t ? a = 1 : b = 2`
|
||||
void checkRequiredParens()
|
||||
{
|
||||
if (e.op == EXP.question && !e.parens)
|
||||
if (e.op == EXP.question && !parens)
|
||||
eSink.error(e.loc, "`%s` must be surrounded by parentheses when next to operator `%s`",
|
||||
e.toChars(), Token.toChars(token.value));
|
||||
}
|
||||
|
|
|
@ -9,11 +9,9 @@
|
|||
* Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/apply.d
|
||||
*/
|
||||
|
||||
module dmd.apply;
|
||||
module dmd.postordervisitor;
|
||||
|
||||
import dmd.arraytypes;
|
||||
import dmd.dsymbol;
|
||||
import dmd.dsymbolsem;
|
||||
import dmd.dtemplate;
|
||||
import dmd.expression;
|
||||
import dmd.root.array;
|
||||
|
@ -26,39 +24,6 @@ bool walkPostorder(Expression e, StoppableVisitor v)
|
|||
return v.stop;
|
||||
}
|
||||
|
||||
/*********************************
|
||||
* Iterate this dsymbol or members of this scoped dsymbol, then
|
||||
* call `fp` with the found symbol and `params`.
|
||||
* Params:
|
||||
* symbol = the dsymbol or parent of members to call fp on
|
||||
* fp = function pointer to process the iterated symbol.
|
||||
* If it returns nonzero, the iteration will be aborted.
|
||||
* params = any parameters passed to fp.
|
||||
* Returns:
|
||||
* nonzero if the iteration is aborted by the return value of fp,
|
||||
* or 0 if it's completed.
|
||||
*/
|
||||
int apply(FP, Params...)(Dsymbol symbol, FP fp, Params params)
|
||||
{
|
||||
if (auto nd = symbol.isNspace())
|
||||
{
|
||||
return nd.members.foreachDsymbol( (s) { return s && s.apply(fp, params); } );
|
||||
}
|
||||
if (auto ad = symbol.isAttribDeclaration())
|
||||
{
|
||||
return ad.include(ad._scope).foreachDsymbol( (s) { return s && s.apply(fp, params); } );
|
||||
}
|
||||
if (auto tm = symbol.isTemplateMixin())
|
||||
{
|
||||
if (tm._scope) // if fwd reference
|
||||
dsymbolSemantic(tm, null); // try to resolve it
|
||||
|
||||
return tm.members.foreachDsymbol( (s) { return s && s.apply(fp, params); } );
|
||||
}
|
||||
|
||||
return fp(symbol, params);
|
||||
}
|
||||
|
||||
/**************************************
|
||||
* An Expression tree walker that will visit each Expression e in the tree,
|
||||
* in depth-first evaluation order, and call fp(e,param) on it.
|
|
@ -447,14 +447,12 @@ private extern(C++) final class Semantic2Visitor : Visitor
|
|||
const sameParams = tf1.parameterList == tf2.parameterList;
|
||||
|
||||
// Allow the hack to declare overloads with different parameters/STC's
|
||||
// @@@DEPRECATED_2.104@@@
|
||||
// Deprecated in 2020-08, make this an error in 2.104
|
||||
if (parent1.isModule() &&
|
||||
linkage1 != LINK.d && linkage1 != LINK.cpp &&
|
||||
(!sameAttr || !sameParams)
|
||||
)
|
||||
{
|
||||
f2.deprecation("cannot overload `extern(%s)` function at %s",
|
||||
f2.error("cannot overload `extern(%s)` function at %s",
|
||||
linkageToChars(f1._linkage),
|
||||
f1.loc.toChars());
|
||||
return 0;
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
|
||||
module dmd.sideeffect;
|
||||
|
||||
import dmd.apply;
|
||||
import dmd.astenums;
|
||||
import dmd.declaration;
|
||||
import dmd.dscope;
|
||||
|
@ -22,6 +21,7 @@ import dmd.globals;
|
|||
import dmd.identifier;
|
||||
import dmd.init;
|
||||
import dmd.mtype;
|
||||
import dmd.postordervisitor;
|
||||
import dmd.tokens;
|
||||
import dmd.visitor;
|
||||
|
||||
|
@ -101,9 +101,11 @@ extern (C++) bool hasSideEffect(Expression e, bool assumeImpureCalls = false)
|
|||
int callSideEffectLevel(FuncDeclaration f)
|
||||
{
|
||||
/* https://issues.dlang.org/show_bug.cgi?id=12760
|
||||
* ctor call always has side effects.
|
||||
* https://issues.dlang.org/show_bug.cgi?id=16384
|
||||
*
|
||||
* ctor calls and invariant calls always have side effects
|
||||
*/
|
||||
if (f.isCtorDeclaration())
|
||||
if (f.isCtorDeclaration() || f.isInvariantDeclaration())
|
||||
return 0;
|
||||
assert(f.type.ty == Tfunction);
|
||||
TypeFunction tf = cast(TypeFunction)f.type;
|
||||
|
|
|
@ -1273,8 +1273,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
|
|||
}
|
||||
else if (auto td = sfront.isTemplateDeclaration())
|
||||
{
|
||||
Expressions a;
|
||||
if (auto f = resolveFuncCall(loc, sc, td, null, tab, ArgumentList(&a), FuncResolveFlag.quiet))
|
||||
if (auto f = resolveFuncCall(loc, sc, td, null, tab, ArgumentList(), FuncResolveFlag.quiet))
|
||||
tfront = f.type;
|
||||
}
|
||||
else if (auto d = sfront.toAlias().isDeclaration())
|
||||
|
@ -2733,7 +2732,8 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
|
|||
tbret = tret.toBasetype();
|
||||
}
|
||||
|
||||
if (inferRef) // deduce 'auto ref'
|
||||
// https://issues.dlang.org/show_bug.cgi?id=23914
|
||||
if (inferRef && !resType.isTypeNoreturn()) // deduce 'auto ref'
|
||||
tf.isref = false;
|
||||
|
||||
if (tbret.ty != Tvoid && !resType.isTypeNoreturn()) // if non-void return
|
||||
|
@ -3593,6 +3593,11 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
|
|||
cas.error("`asm` statement is assumed to be impure - mark it with `pure` if it is not");
|
||||
if (!(cas.stc & STC.nogc) && sc.func.setGC(cas.loc, "`asm` statement in %s `%s` is assumed to use the GC - mark it with `@nogc` if it does not"))
|
||||
cas.error("`asm` statement is assumed to use the GC - mark it with `@nogc` if it does not");
|
||||
// @@@DEPRECATED_2.114@@@
|
||||
// change deprecation() to error(), add `else` and remove `| STC.safe`
|
||||
// to turn deprecation into an error when deprecation cycle is over
|
||||
if (cas.stc & STC.safe)
|
||||
cas.deprecation("`asm` statement cannot be marked `@safe`, use `@system` or `@trusted` instead");
|
||||
if (!(cas.stc & (STC.trusted | STC.safe)))
|
||||
{
|
||||
sc.setUnsafe(false, cas.loc, "`asm` statement is assumed to be `@system` - mark it with `@trusted` if it is not");
|
||||
|
@ -4045,6 +4050,13 @@ void catchSemantic(Catch c, Scope* sc)
|
|||
// reference .object.Throwable
|
||||
c.type = getThrowable();
|
||||
}
|
||||
else if (!c.type.isNaked() && !c.type.isConst())
|
||||
{
|
||||
// @@@DEPRECATED_2.113@@@
|
||||
// Deprecated in 2.103, change into an error & uncomment in 2.113
|
||||
deprecation(c.loc, "can only catch mutable or const qualified types, not `%s`", c.type.toChars());
|
||||
//c.errors = true;
|
||||
}
|
||||
c.type = c.type.typeSemantic(c.loc, sc);
|
||||
if (c.type == Type.terror)
|
||||
{
|
||||
|
|
|
@ -593,7 +593,7 @@ shared static this() nothrow
|
|||
foreach (kw; keywords)
|
||||
{
|
||||
//printf("keyword[%d] = '%s'\n",kw, Token.tochars[kw].ptr);
|
||||
Identifier.idPool(Token.tochars[kw].ptr, Token.tochars[kw].length, cast(uint)kw);
|
||||
Identifier.idPool(Token.tochars[kw], kw);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1215,7 +1215,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
|
|||
{
|
||||
if (fd.overnext)
|
||||
{
|
||||
deprecation(e.loc, "`__traits(getAttributes)` may only be used for individual functions, not overload sets such as: `%s`", fd.toChars());
|
||||
deprecation(e.loc, "`__traits(getAttributes)` may only be used for individual functions, not the overload set `%s`", fd.toChars());
|
||||
deprecationSupplemental(e.loc, "the result of `__traits(getOverloads)` may be used to select the desired function to extract attributes from");
|
||||
}
|
||||
}
|
||||
|
@ -1225,7 +1225,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
|
|||
{
|
||||
if (td.overnext || td.funcroot)
|
||||
{
|
||||
deprecation(e.loc, "`__traits(getAttributes)` may only be used for individual functions, not overload sets such as: `%s`", td.ident.toChars());
|
||||
deprecation(e.loc, "`__traits(getAttributes)` may only be used for individual functions, not the overload set `%s`", td.ident.toChars());
|
||||
deprecationSupplemental(e.loc, "the result of `__traits(getOverloads)` may be used to select the desired function to extract attributes from");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -161,6 +161,16 @@ package mixin template ParseVisitMethods(AST)
|
|||
s._body.accept(this);
|
||||
}
|
||||
|
||||
override void visit(AST.StaticForeachStatement s)
|
||||
{
|
||||
// printf("Visiting StaticForeachStatement\n");
|
||||
if (s.sfe.aggrfe)
|
||||
s.sfe.aggrfe.accept(this);
|
||||
|
||||
if (s.sfe.rangefe)
|
||||
s.sfe.rangefe.accept(this);
|
||||
}
|
||||
|
||||
override void visit(AST.IfStatement s)
|
||||
{
|
||||
//printf("Visiting IfStatement\n");
|
||||
|
|
|
@ -163,7 +163,7 @@ private void resolveHelper(TypeQualified mt, const ref Loc loc, Scope* sc, Dsymb
|
|||
/* Look for what user might have intended
|
||||
*/
|
||||
const p = mt.mutableOf().unSharedOf().toChars();
|
||||
auto id = Identifier.idPool(p, cast(uint)strlen(p));
|
||||
auto id = Identifier.idPool(p[0 .. strlen(p)]);
|
||||
if (const n = importHint(id.toString()))
|
||||
error(loc, "`%s` is not defined, perhaps `import %.*s;` ?", p, cast(int)n.length, n.ptr);
|
||||
else if (auto s2 = sc.search_correct(id))
|
||||
|
|
|
@ -2296,11 +2296,12 @@ public:
|
|||
return;
|
||||
}
|
||||
|
||||
/* This case should have been rewritten to `_d_newitemT' during the
|
||||
semantic phase. */
|
||||
gcc_assert (e->lowering);
|
||||
|
||||
/* Generate: _d_newitemT() */
|
||||
libcall_fn libcall = htype->isZeroInit ()
|
||||
? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;
|
||||
tree arg = build_typeinfo (e, e->newtype);
|
||||
new_call = build_libcall (libcall, tb, 1, arg);
|
||||
new_call = build_expr (e->lowering);
|
||||
|
||||
if (e->member || !e->arguments)
|
||||
{
|
||||
|
@ -2423,11 +2424,12 @@ public:
|
|||
return;
|
||||
}
|
||||
|
||||
libcall_fn libcall = tpointer->next->isZeroInit (e->loc)
|
||||
? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;
|
||||
/* This case should have been rewritten to `_d_newitemT' during the
|
||||
semantic phase. */
|
||||
gcc_assert (e->lowering);
|
||||
|
||||
tree arg = build_typeinfo (e, e->newtype);
|
||||
result = build_libcall (libcall, tb, 1, arg);
|
||||
/* Generate: _d_newitemT() */
|
||||
result = build_expr (e->lowering);
|
||||
|
||||
if (e->arguments && e->arguments->length == 1)
|
||||
{
|
||||
|
|
|
@ -70,11 +70,6 @@ DEF_D_RUNTIME (DYNAMIC_CAST, "_d_dynamic_cast", RT(OBJECT),
|
|||
DEF_D_RUNTIME (INTERFACE_CAST, "_d_interface_cast", RT(OBJECT),
|
||||
P2(OBJECT, CLASSINFO), 0)
|
||||
|
||||
/* Used when calling new on a pointer. The `i' variant is for when the
|
||||
initializer is nonzero. */
|
||||
DEF_D_RUNTIME (NEWITEMT, "_d_newitemT", RT(VOIDPTR), P1(CONST_TYPEINFO), 0)
|
||||
DEF_D_RUNTIME (NEWITEMIT, "_d_newitemiT", RT(VOIDPTR), P1(CONST_TYPEINFO), 0)
|
||||
|
||||
/* Used when calling new on an array. The `i' variant is for when the
|
||||
initializer is nonzero, and the `m' variant is when initializing a
|
||||
multi-dimensional array. */
|
||||
|
|
|
@ -780,8 +780,8 @@ public:
|
|||
|
||||
this->do_label (label);
|
||||
|
||||
if (this->is_return_label (s->ident) && this->func_->fensure != NULL)
|
||||
this->build_stmt (this->func_->fensure);
|
||||
if (this->is_return_label (s->ident) && this->func_->fensure () != NULL)
|
||||
this->build_stmt (this->func_->fensure ());
|
||||
else if (s->statement)
|
||||
this->build_stmt (s->statement);
|
||||
}
|
||||
|
|
|
@ -1421,7 +1421,7 @@ check_typeinfo_type (const Loc &loc, Scope *sc, Expression *expr)
|
|||
/* If TypeInfo has not been declared, warn about each location once. */
|
||||
static Loc warnloc;
|
||||
|
||||
if (loc.filename && !warnloc.equals (loc))
|
||||
if (loc.filename () && !warnloc.equals (loc))
|
||||
{
|
||||
error_at (make_location_t (loc),
|
||||
"%<object.TypeInfo%> could not be found, "
|
||||
|
|
|
@ -6,7 +6,7 @@ module asm4;
|
|||
void test1()
|
||||
{
|
||||
asm pure nothrow @nogc @trusted {}
|
||||
asm @safe {}
|
||||
asm @system {}
|
||||
}
|
||||
|
||||
void test2() pure nothrow @nogc @safe
|
||||
|
|
|
@ -36,12 +36,12 @@ void main()
|
|||
enum a = 1;
|
||||
}
|
||||
|
||||
/+ struct S
|
||||
struct S2
|
||||
{
|
||||
int value;
|
||||
alias this = value;
|
||||
}
|
||||
auto s = S(10);
|
||||
auto s = S2(10);
|
||||
int n = s;
|
||||
assert(n == 10); +/
|
||||
assert(n == 10);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
// REQUIRED_ARGS: -preview=nosharedaccess
|
||||
import core.atomic;
|
||||
|
||||
class Foo
|
||||
{
|
||||
}
|
||||
|
||||
void oops()
|
||||
{
|
||||
auto f0 = new shared Foo;
|
||||
auto f1 = new shared Foo;
|
||||
atomicStore(f0, f1);
|
||||
}
|
5
gcc/testsuite/gdc.test/compilable/imports/library.c
Normal file
5
gcc/testsuite/gdc.test/compilable/imports/library.c
Normal file
|
@ -0,0 +1,5 @@
|
|||
typedef enum SomeEnum
|
||||
{
|
||||
foo = 0,
|
||||
bar = -10000,
|
||||
} SomeEnum;
|
|
@ -91,8 +91,8 @@ auto ref forwardOrExit(ref int num)
|
|||
|
||||
static assert( is(typeof(forwardOrExit(global)) == int));
|
||||
|
||||
// // Must not infer ref due to the noreturn rvalue
|
||||
static assert(!is(typeof(&forwardOrExit(global))));
|
||||
// Noreturn types do not affect `auto ref` deduction
|
||||
static assert(is(typeof(&forwardOrExit(global))));
|
||||
|
||||
auto ref forwardOrExit2(ref int num)
|
||||
{
|
||||
|
@ -104,8 +104,8 @@ auto ref forwardOrExit2(ref int num)
|
|||
|
||||
static assert( is(typeof(forwardOrExit2(global)) == int));
|
||||
|
||||
// // Must not infer ref due to the noreturn rvalue
|
||||
static assert(!is(typeof(&forwardOrExit2(global))));
|
||||
// Noreturn types do not affect `auto ref` deduction
|
||||
static assert(is(typeof(&forwardOrExit2(global))));
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
15
gcc/testsuite/gdc.test/compilable/test22760.d
Normal file
15
gcc/testsuite/gdc.test/compilable/test22760.d
Normal file
|
@ -0,0 +1,15 @@
|
|||
// https://issues.dlang.org/show_bug.cgi?id=22760
|
||||
|
||||
extern(C++) void f(T)(T)
|
||||
{
|
||||
}
|
||||
struct S1(T)
|
||||
{
|
||||
struct S2
|
||||
{
|
||||
}
|
||||
}
|
||||
void fun()
|
||||
{
|
||||
f(S1!int.S2());
|
||||
}
|
10
gcc/testsuite/gdc.test/compilable/test23874.d
Normal file
10
gcc/testsuite/gdc.test/compilable/test23874.d
Normal file
|
@ -0,0 +1,10 @@
|
|||
// https://issues.dlang.org/show_bug.cgi?id=23874
|
||||
// REQUIRED_ARGS: -profile=gc
|
||||
|
||||
string myToString()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
enum x = myToString ~ "";
|
||||
immutable x2 = myToString ~ "";
|
17
gcc/testsuite/gdc.test/compilable/test23912.d
Normal file
17
gcc/testsuite/gdc.test/compilable/test23912.d
Normal file
|
@ -0,0 +1,17 @@
|
|||
// https://issues.dlang.org/show_bug.cgi?id=23912
|
||||
// REQUIRED_ARGS: -preview=dip1000
|
||||
|
||||
struct Test
|
||||
{
|
||||
string val;
|
||||
|
||||
this(return scope string val) scope @safe {}
|
||||
~this() scope @safe {}
|
||||
}
|
||||
|
||||
void giver(scope string input) @safe
|
||||
{
|
||||
accepts(Test(input));
|
||||
}
|
||||
|
||||
void accepts(scope Test test) @safe {}
|
7
gcc/testsuite/gdc.test/compilable/test23913.d
Normal file
7
gcc/testsuite/gdc.test/compilable/test23913.d
Normal file
|
@ -0,0 +1,7 @@
|
|||
// EXTRA_FILES: imports/library.c
|
||||
|
||||
// https://issues.dlang.org/show_bug.cgi?id=23913
|
||||
|
||||
import imports.library;
|
||||
|
||||
alias x = __traits(getMember, imports.library, "SomeEnum");
|
29
gcc/testsuite/gdc.test/compilable/test23948.d
Normal file
29
gcc/testsuite/gdc.test/compilable/test23948.d
Normal file
|
@ -0,0 +1,29 @@
|
|||
// https://issues.dlang.org/show_bug.cgi?id=23948
|
||||
|
||||
void foo1(const(char)* fun = __FILE__)() {
|
||||
|
||||
}
|
||||
|
||||
void foo2(const(char)* fun = __FILE_FULL_PATH__)() {
|
||||
|
||||
}
|
||||
|
||||
void foo3(const(char)* fun = __MODULE__)() {
|
||||
|
||||
}
|
||||
|
||||
void foo4(const(char)* fun = __FUNCTION__)() {
|
||||
|
||||
}
|
||||
|
||||
void foo5(const(char)* fun = __PRETTY_FUNCTION__)() {
|
||||
|
||||
}
|
||||
|
||||
void main() {
|
||||
foo1();
|
||||
foo2();
|
||||
foo3();
|
||||
foo4();
|
||||
foo5();
|
||||
}
|
|
@ -91,9 +91,9 @@ TEST_OUTPUT:
|
|||
---
|
||||
fail_compilation/bug9631.d(106): Error: function `bug9631.targ.ft!().ft(S __param_0)` is not callable using argument types `(S)`
|
||||
fail_compilation/bug9631.d(106): cannot pass argument `x` of type `bug9631.S` to parameter `bug9631.tem!().S __param_0`
|
||||
fail_compilation/bug9631.d(107): Error: none of the overloads of template `bug9631.targ.ft` are callable using argument types `!()(S)`
|
||||
fail_compilation/bug9631.d(107): Error: template `bug9631.targ.ft` is not callable using argument types `!()(S)`
|
||||
fail_compilation/bug9631.d(105): Candidate is: `ft()(tem!().S)`
|
||||
fail_compilation/bug9631.d(109): Error: none of the overloads of template `bug9631.targ.ft2` are callable using argument types `!()(S, int)`
|
||||
fail_compilation/bug9631.d(109): Error: template `bug9631.targ.ft2` is not callable using argument types `!()(S, int)`
|
||||
fail_compilation/bug9631.d(108): Candidate is: `ft2(T)(S, T)`
|
||||
---
|
||||
*/
|
||||
|
|
|
@ -19,7 +19,11 @@ fail_compilation/chkformat.d(115): Deprecation: argument `& u` for format specif
|
|||
fail_compilation/chkformat.d(116): Deprecation: argument `16L` for format specification `"%c"` must be `char`, not `long`
|
||||
fail_compilation/chkformat.d(117): Deprecation: argument `17L` for format specification `"%c"` must be `char`, not `long`
|
||||
fail_compilation/chkformat.d(118): Deprecation: argument `& u` for format specification `"%s"` must be `char*`, not `int*`
|
||||
fail_compilation/chkformat.d(119): Deprecation: argument `& u` for format specification `"%ls"` must be `wchar_t*`, not `int*`
|
||||
fail_compilation/chkformat.d(119): Deprecation: argument `& u` for format specification `"%ls"` must be `wchar_t*`, not `int*`$?:windows=
|
||||
fail_compilation/chkformat.d(122): Deprecation: argument `0LU` for format specification `"%lu"` must be `uint`, not `ulong`
|
||||
fail_compilation/chkformat.d(122): C `long` is 4 bytes on your system|32=
|
||||
fail_compilation/chkformat.d(122): Deprecation: argument `0LU` for format specification `"%lu"` must be `uint`, not `ulong`
|
||||
fail_compilation/chkformat.d(122): C `long` is 4 bytes on your system$
|
||||
fail_compilation/chkformat.d(201): Deprecation: argument `0L` for format specification `"%d"` must be `int*`, not `long`
|
||||
fail_compilation/chkformat.d(202): Deprecation: more format specifiers than 1 arguments
|
||||
fail_compilation/chkformat.d(203): Deprecation: argument `0L` for format specification `"%d"` must be `int*`, not `long`
|
||||
|
@ -81,6 +85,7 @@ void test18() { int u; printf("%s\n", &u); }
|
|||
void test19() { int u; printf("%ls\n", &u); }
|
||||
//void test20() { int u; char[] s; sprintf(&s[0], "%d\n", &u); }
|
||||
//void test21() { int u; fprintf(null, "%d\n", &u); }
|
||||
void test20() { printf("%lu", ulong.init); }
|
||||
|
||||
#line 200
|
||||
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
EXTRA_FILES: imports/constraints.d
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/constraints_aggr.d(32): Error: none of the overloads of template `imports.constraints.C.f` are callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_aggr.d(32): Error: template `imports.constraints.C.f` is not callable using argument types `!()(int)`
|
||||
fail_compilation/imports/constraints.d(60): Candidate is: `f(T)(T v)`
|
||||
with `T = int`
|
||||
must satisfy the following constraint:
|
||||
` !P!T`
|
||||
fail_compilation/constraints_aggr.d(33): Error: none of the overloads of template `imports.constraints.C.g` are callable using argument types `!()()`
|
||||
fail_compilation/constraints_aggr.d(33): Error: template `imports.constraints.C.g` is not callable using argument types `!()()`
|
||||
fail_compilation/imports/constraints.d(63): Candidate is: `g(this T)()`
|
||||
with `T = imports.constraints.C`
|
||||
must satisfy the following constraint:
|
||||
|
|
|
@ -2,72 +2,72 @@
|
|||
EXTRA_FILES: imports/constraints.d
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/constraints_func1.d(79): Error: none of the overloads of template `imports.constraints.test1` are callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func1.d(79): Error: template `imports.constraints.test1` is not callable using argument types `!()(int)`
|
||||
fail_compilation/imports/constraints.d(9): Candidate is: `test1(T)(T v)`
|
||||
with `T = int`
|
||||
must satisfy the following constraint:
|
||||
` N!T`
|
||||
fail_compilation/constraints_func1.d(80): Error: none of the overloads of template `imports.constraints.test2` are callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func1.d(80): Error: template `imports.constraints.test2` is not callable using argument types `!()(int)`
|
||||
fail_compilation/imports/constraints.d(10): Candidate is: `test2(T)(T v)`
|
||||
with `T = int`
|
||||
must satisfy the following constraint:
|
||||
` !P!T`
|
||||
fail_compilation/constraints_func1.d(81): Error: none of the overloads of template `imports.constraints.test3` are callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func1.d(81): Error: template `imports.constraints.test3` is not callable using argument types `!()(int)`
|
||||
fail_compilation/imports/constraints.d(11): Candidate is: `test3(T)(T v)`
|
||||
with `T = int`
|
||||
must satisfy the following constraint:
|
||||
` N!T`
|
||||
fail_compilation/constraints_func1.d(82): Error: none of the overloads of template `imports.constraints.test4` are callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func1.d(82): Error: template `imports.constraints.test4` is not callable using argument types `!()(int)`
|
||||
fail_compilation/imports/constraints.d(12): Candidate is: `test4(T)(T v)`
|
||||
with `T = int`
|
||||
must satisfy the following constraint:
|
||||
` N!T`
|
||||
fail_compilation/constraints_func1.d(83): Error: none of the overloads of template `imports.constraints.test5` are callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func1.d(83): Error: template `imports.constraints.test5` is not callable using argument types `!()(int)`
|
||||
fail_compilation/imports/constraints.d(13): Candidate is: `test5(T)(T v)`
|
||||
with `T = int`
|
||||
must satisfy one of the following constraints:
|
||||
` N!T
|
||||
N!T`
|
||||
fail_compilation/constraints_func1.d(84): Error: none of the overloads of template `imports.constraints.test6` are callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func1.d(84): Error: template `imports.constraints.test6` is not callable using argument types `!()(int)`
|
||||
fail_compilation/imports/constraints.d(14): Candidate is: `test6(T)(T v)`
|
||||
with `T = int`
|
||||
must satisfy one of the following constraints:
|
||||
` N!T
|
||||
N!T
|
||||
!P!T`
|
||||
fail_compilation/constraints_func1.d(85): Error: none of the overloads of template `imports.constraints.test7` are callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func1.d(85): Error: template `imports.constraints.test7` is not callable using argument types `!()(int)`
|
||||
fail_compilation/imports/constraints.d(15): Candidate is: `test7(T)(T v)`
|
||||
with `T = int`
|
||||
must satisfy one of the following constraints:
|
||||
` N!T
|
||||
N!T`
|
||||
fail_compilation/constraints_func1.d(86): Error: none of the overloads of template `imports.constraints.test8` are callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func1.d(86): Error: template `imports.constraints.test8` is not callable using argument types `!()(int)`
|
||||
fail_compilation/imports/constraints.d(16): Candidate is: `test8(T)(T v)`
|
||||
with `T = int`
|
||||
must satisfy the following constraint:
|
||||
` N!T`
|
||||
fail_compilation/constraints_func1.d(87): Error: none of the overloads of template `imports.constraints.test9` are callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func1.d(87): Error: template `imports.constraints.test9` is not callable using argument types `!()(int)`
|
||||
fail_compilation/imports/constraints.d(17): Candidate is: `test9(T)(T v)`
|
||||
with `T = int`
|
||||
must satisfy the following constraint:
|
||||
` !P!T`
|
||||
fail_compilation/constraints_func1.d(88): Error: none of the overloads of template `imports.constraints.test10` are callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func1.d(88): Error: template `imports.constraints.test10` is not callable using argument types `!()(int)`
|
||||
fail_compilation/imports/constraints.d(18): Candidate is: `test10(T)(T v)`
|
||||
with `T = int`
|
||||
must satisfy the following constraint:
|
||||
` !P!T`
|
||||
fail_compilation/constraints_func1.d(89): Error: none of the overloads of template `imports.constraints.test11` are callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func1.d(89): Error: template `imports.constraints.test11` is not callable using argument types `!()(int)`
|
||||
fail_compilation/imports/constraints.d(19): Candidate is: `test11(T)(T v)`
|
||||
with `T = int`
|
||||
must satisfy one of the following constraints:
|
||||
` N!T
|
||||
!P!T`
|
||||
fail_compilation/constraints_func1.d(90): Error: none of the overloads of template `imports.constraints.test12` are callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func1.d(90): Error: template `imports.constraints.test12` is not callable using argument types `!()(int)`
|
||||
fail_compilation/imports/constraints.d(20): Candidate is: `test12(T)(T v)`
|
||||
with `T = int`
|
||||
must satisfy the following constraint:
|
||||
` !P!T`
|
||||
fail_compilation/constraints_func1.d(92): Error: none of the overloads of template `imports.constraints.test1` are callable using argument types `!()(int, int)`
|
||||
fail_compilation/constraints_func1.d(92): Error: template `imports.constraints.test1` is not callable using argument types `!()(int, int)`
|
||||
fail_compilation/imports/constraints.d(9): Candidate is: `test1(T)(T v)`
|
||||
---
|
||||
*/
|
||||
|
|
|
@ -2,83 +2,83 @@
|
|||
EXTRA_FILES: imports/constraints.d
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/constraints_func2.d(94): Error: none of the overloads of template `imports.constraints.test13` are callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func2.d(94): Error: template `imports.constraints.test13` is not callable using argument types `!()(int)`
|
||||
fail_compilation/imports/constraints.d(23): Candidate is: `test13(T)(T v)`
|
||||
with `T = int`
|
||||
must satisfy one of the following constraints:
|
||||
` N!T
|
||||
!P!T`
|
||||
fail_compilation/constraints_func2.d(95): Error: none of the overloads of template `imports.constraints.test14` are callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func2.d(95): Error: template `imports.constraints.test14` is not callable using argument types `!()(int)`
|
||||
fail_compilation/imports/constraints.d(24): Candidate is: `test14(T)(T v)`
|
||||
with `T = int`
|
||||
must satisfy one of the following constraints:
|
||||
` !P!T
|
||||
N!T`
|
||||
fail_compilation/constraints_func2.d(96): Error: none of the overloads of template `imports.constraints.test15` are callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func2.d(96): Error: template `imports.constraints.test15` is not callable using argument types `!()(int)`
|
||||
fail_compilation/imports/constraints.d(25): Candidate is: `test15(T)(T v)`
|
||||
with `T = int`
|
||||
must satisfy one of the following constraints:
|
||||
` !P!T
|
||||
!P!T`
|
||||
fail_compilation/constraints_func2.d(97): Error: none of the overloads of template `imports.constraints.test16` are callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func2.d(97): Error: template `imports.constraints.test16` is not callable using argument types `!()(int)`
|
||||
fail_compilation/imports/constraints.d(26): Candidate is: `test16(T)(T v)`
|
||||
with `T = int`
|
||||
must satisfy one of the following constraints:
|
||||
` N!T
|
||||
N!T`
|
||||
fail_compilation/constraints_func2.d(98): Error: none of the overloads of template `imports.constraints.test17` are callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func2.d(98): Error: template `imports.constraints.test17` is not callable using argument types `!()(int)`
|
||||
fail_compilation/imports/constraints.d(27): Candidate is: `test17(T)(T v)`
|
||||
with `T = int`
|
||||
must satisfy the following constraint:
|
||||
` N!T`
|
||||
fail_compilation/constraints_func2.d(99): Error: none of the overloads of template `imports.constraints.test18` are callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func2.d(99): Error: template `imports.constraints.test18` is not callable using argument types `!()(int)`
|
||||
fail_compilation/imports/constraints.d(28): Candidate is: `test18(T)(T v)`
|
||||
with `T = int`
|
||||
must satisfy one of the following constraints:
|
||||
` N!T
|
||||
N!T`
|
||||
fail_compilation/constraints_func2.d(100): Error: none of the overloads of template `imports.constraints.test19` are callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func2.d(100): Error: template `imports.constraints.test19` is not callable using argument types `!()(int)`
|
||||
fail_compilation/imports/constraints.d(29): Candidate is: `test19(T)(T v)`
|
||||
with `T = int`
|
||||
must satisfy one of the following constraints:
|
||||
` N!T
|
||||
!P!T
|
||||
N!T`
|
||||
fail_compilation/constraints_func2.d(101): Error: none of the overloads of template `imports.constraints.test20` are callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func2.d(101): Error: template `imports.constraints.test20` is not callable using argument types `!()(int)`
|
||||
fail_compilation/imports/constraints.d(30): Candidate is: `test20(T)(T v)`
|
||||
with `T = int`
|
||||
must satisfy the following constraint:
|
||||
` N!T`
|
||||
fail_compilation/constraints_func2.d(102): Error: none of the overloads of template `imports.constraints.test21` are callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func2.d(102): Error: template `imports.constraints.test21` is not callable using argument types `!()(int)`
|
||||
fail_compilation/imports/constraints.d(31): Candidate is: `test21(T)(T v)`
|
||||
with `T = int`
|
||||
must satisfy one of the following constraints:
|
||||
` N!T
|
||||
N!T`
|
||||
fail_compilation/constraints_func2.d(103): Error: none of the overloads of template `imports.constraints.test22` are callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func2.d(103): Error: template `imports.constraints.test22` is not callable using argument types `!()(int)`
|
||||
fail_compilation/imports/constraints.d(32): Candidate is: `test22(T)(T v)`
|
||||
with `T = int`
|
||||
must satisfy one of the following constraints:
|
||||
` !P!T
|
||||
!P!T`
|
||||
fail_compilation/constraints_func2.d(104): Error: none of the overloads of template `imports.constraints.test23` are callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func2.d(104): Error: template `imports.constraints.test23` is not callable using argument types `!()(int)`
|
||||
fail_compilation/imports/constraints.d(33): Candidate is: `test23(T)(T v)`
|
||||
with `T = int`
|
||||
must satisfy one of the following constraints:
|
||||
` !P!T
|
||||
N!T
|
||||
!P!T`
|
||||
fail_compilation/constraints_func2.d(105): Error: none of the overloads of template `imports.constraints.test24` are callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func2.d(105): Error: template `imports.constraints.test24` is not callable using argument types `!()(int)`
|
||||
fail_compilation/imports/constraints.d(34): Candidate is: `test24(R)(R r)`
|
||||
with `R = int`
|
||||
must satisfy the following constraint:
|
||||
` __traits(hasMember, R, "stuff")`
|
||||
fail_compilation/constraints_func2.d(106): Error: none of the overloads of template `imports.constraints.test25` are callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func2.d(106): Error: template `imports.constraints.test25` is not callable using argument types `!()(int)`
|
||||
fail_compilation/imports/constraints.d(35): Candidate is: `test25(T)(T v)`
|
||||
with `T = int`
|
||||
must satisfy the following constraint:
|
||||
` N!T`
|
||||
fail_compilation/constraints_func2.d(107): Error: none of the overloads of template `imports.constraints.test26` are callable using argument types `!(float)(int)`
|
||||
fail_compilation/constraints_func2.d(107): Error: template `imports.constraints.test26` is not callable using argument types `!(float)(int)`
|
||||
fail_compilation/imports/constraints.d(36): Candidate is: `test26(T, U)(U u)`
|
||||
with `T = float,
|
||||
U = int`
|
||||
|
|
|
@ -23,21 +23,21 @@ fail_compilation/imports/constraints.d(42): `overload(T,
|
|||
must satisfy one of the following constraints:
|
||||
` N!T
|
||||
N!V`
|
||||
fail_compilation/constraints_func3.d(56): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()()`
|
||||
fail_compilation/constraints_func3.d(56): Error: template `imports.constraints.variadic` is not callable using argument types `!()()`
|
||||
fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)`
|
||||
fail_compilation/constraints_func3.d(57): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func3.d(57): Error: template `imports.constraints.variadic` is not callable using argument types `!()(int)`
|
||||
fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)`
|
||||
with `A = int,
|
||||
T = ()`
|
||||
must satisfy the following constraint:
|
||||
` N!int`
|
||||
fail_compilation/constraints_func3.d(58): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()(int, int)`
|
||||
fail_compilation/constraints_func3.d(58): Error: template `imports.constraints.variadic` is not callable using argument types `!()(int, int)`
|
||||
fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)`
|
||||
with `A = int,
|
||||
T = (int)`
|
||||
must satisfy the following constraint:
|
||||
` N!int`
|
||||
fail_compilation/constraints_func3.d(59): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()(int, int, int)`
|
||||
fail_compilation/constraints_func3.d(59): Error: template `imports.constraints.variadic` is not callable using argument types `!()(int, int, int)`
|
||||
fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)`
|
||||
with `A = int,
|
||||
T = (int, int)`
|
||||
|
|
|
@ -44,13 +44,13 @@ fail_compilation/imports/constraints.d(42): `overload(T,
|
|||
N!V`
|
||||
void overload(T, V)(T v1, V v2) if (N!T || N!V);
|
||||
^
|
||||
fail_compilation/constraints_func4.d(93): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()()`
|
||||
fail_compilation/constraints_func4.d(93): Error: template `imports.constraints.variadic` is not callable using argument types `!()()`
|
||||
variadic();
|
||||
^
|
||||
fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)`
|
||||
void variadic(A, T...)(A a, T v) if (N!int);
|
||||
^
|
||||
fail_compilation/constraints_func4.d(94): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func4.d(94): Error: template `imports.constraints.variadic` is not callable using argument types `!()(int)`
|
||||
variadic(0);
|
||||
^
|
||||
fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)`
|
||||
|
@ -60,7 +60,7 @@ fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T.
|
|||
` N!int`
|
||||
void variadic(A, T...)(A a, T v) if (N!int);
|
||||
^
|
||||
fail_compilation/constraints_func4.d(95): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()(int, int)`
|
||||
fail_compilation/constraints_func4.d(95): Error: template `imports.constraints.variadic` is not callable using argument types `!()(int, int)`
|
||||
variadic(0, 1);
|
||||
^
|
||||
fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)`
|
||||
|
@ -70,7 +70,7 @@ fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T.
|
|||
` N!int`
|
||||
void variadic(A, T...)(A a, T v) if (N!int);
|
||||
^
|
||||
fail_compilation/constraints_func4.d(96): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()(int, int, int)`
|
||||
fail_compilation/constraints_func4.d(96): Error: template `imports.constraints.variadic` is not callable using argument types `!()(int, int, int)`
|
||||
variadic(0, 1, 2);
|
||||
^
|
||||
fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)`
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/diag13942.d(18): Error: template instance `isRawStaticArray!()` does not match template declaration `isRawStaticArray(T, A...)`
|
||||
fail_compilation/diag13942.d(26): Error: none of the overloads of template `diag13942.to!double.to` are callable using argument types `!()()`
|
||||
fail_compilation/diag13942.d(26): Error: template `diag13942.to!double.to` is not callable using argument types `!()()`
|
||||
fail_compilation/diag13942.d(17): Candidate is: `to(A...)(A args)`
|
||||
---
|
||||
*/
|
||||
|
|
|
@ -3,7 +3,7 @@ TEST_OUTPUT:
|
|||
---
|
||||
fail_compilation/diag16977.d(25): Error: undefined identifier `undefined`, did you mean function `undefinedId`?
|
||||
fail_compilation/diag16977.d(26): Error: cannot implicitly convert expression `"\x01string"` of type `string` to `int`
|
||||
fail_compilation/diag16977.d(27): Error: none of the overloads of template `diag16977.templ` are callable using argument types `!()(int)`
|
||||
fail_compilation/diag16977.d(27): Error: template `diag16977.templ` is not callable using argument types `!()(int)`
|
||||
fail_compilation/diag16977.d(20): Candidate is: `templ(S)(S s)`
|
||||
with `S = int`
|
||||
must satisfy the following constraint:
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/diag20268.d(12): Error: none of the overloads of template `diag20268.__lambda4` are callable using argument types `!()(int)`
|
||||
fail_compilation/diag20268.d(12): Error: template `diag20268.__lambda4` is not callable using argument types `!()(int)`
|
||||
fail_compilation/diag20268.d(11): Candidate is: `__lambda4(__T1, __T2)(x, y)`
|
||||
---
|
||||
*/
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/diag23355.d(1): Error: undefined identifier `n`
|
||||
fail_compilation/diag23355.d(4): Error: none of the overloads of template `diag23355.ffi1` are callable using argument types `!()(int[4])`
|
||||
fail_compilation/diag23355.d(4): Error: template `diag23355.ffi1` is not callable using argument types `!()(int[4])`
|
||||
fail_compilation/diag23355.d(1): Candidate is: `ffi1(T)(T[n] s)`
|
||||
fail_compilation/diag23355.d(2): Error: undefined identifier `n`
|
||||
fail_compilation/diag23355.d(4): Error: none of the overloads of template `diag23355.ffi2` are callable using argument types `!()(int[4])`
|
||||
fail_compilation/diag23355.d(4): Error: template `diag23355.ffi2` is not callable using argument types `!()(int[4])`
|
||||
fail_compilation/diag23355.d(2): Candidate is: `ffi2()(T[n] s)`
|
||||
---
|
||||
*/
|
||||
|
|
|
@ -14,7 +14,7 @@ fail_compilation/diag8101.d(41): `diag8101.f_2(int, int,
|
|||
fail_compilation/diag8101.d(42): `diag8101.f_2(int, int, int, int, int)`
|
||||
fail_compilation/diag8101.d(43): `diag8101.f_2(int, int, int, int, int, int)`
|
||||
fail_compilation/diag8101.d(63): ... (1 more, -v to show) ...
|
||||
fail_compilation/diag8101.d(65): Error: none of the overloads of template `diag8101.t_0` are callable using argument types `!()()`
|
||||
fail_compilation/diag8101.d(65): Error: template `diag8101.t_0` is not callable using argument types `!()()`
|
||||
fail_compilation/diag8101.d(46): Candidate is: `t_0(T1)()`
|
||||
fail_compilation/diag8101.d(66): Error: none of the overloads of template `diag8101.t_1` are callable using argument types `!()()`
|
||||
fail_compilation/diag8101.d(48): Candidates are: `t_1(T1)()`
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/diag8648.d(18): Error: undefined identifier `X`
|
||||
fail_compilation/diag8648.d(29): Error: none of the overloads of template `diag8648.foo` are callable using argument types `!()(Foo!(int, 1))`
|
||||
fail_compilation/diag8648.d(29): Error: template `diag8648.foo` is not callable using argument types `!()(Foo!(int, 1))`
|
||||
fail_compilation/diag8648.d(18): Candidate is: `foo(T, n)(X!(T, n))`
|
||||
fail_compilation/diag8648.d(20): Error: undefined identifier `a`
|
||||
fail_compilation/diag8648.d(31): Error: none of the overloads of template `diag8648.bar` are callable using argument types `!()(Foo!(int, 1))`
|
||||
fail_compilation/diag8648.d(31): Error: template `diag8648.bar` is not callable using argument types `!()(Foo!(int, 1))`
|
||||
fail_compilation/diag8648.d(20): Candidate is: `bar(T)(Foo!(T, a))`
|
||||
fail_compilation/diag8648.d(20): Error: undefined identifier `a`
|
||||
fail_compilation/diag8648.d(32): Error: none of the overloads of template `diag8648.bar` are callable using argument types `!()(Foo!(int, f))`
|
||||
fail_compilation/diag8648.d(32): Error: template `diag8648.bar` is not callable using argument types `!()(Foo!(int, f))`
|
||||
fail_compilation/diag8648.d(20): Candidate is: `bar(T)(Foo!(T, a))`
|
||||
---
|
||||
*/
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/diag9004.d(21): Error: none of the overloads of template `diag9004.bar` are callable using argument types `!()(Foo!int, int)`
|
||||
fail_compilation/diag9004.d(21): Error: template `diag9004.bar` is not callable using argument types `!()(Foo!int, int)`
|
||||
fail_compilation/diag9004.d(14): Candidate is: `bar(FooT)(FooT foo, FooT.T x)`
|
||||
---
|
||||
*/
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/diag9574.d(12): Error: cannot use syntax `alias this = x`, use `alias x this` instead
|
||||
fail_compilation/diag9574.d(18): Error: cannot use syntax `alias this = x`, use `alias x this` instead
|
||||
---
|
||||
*/
|
||||
|
||||
struct S
|
||||
{
|
||||
int x;
|
||||
alias this = x;
|
||||
}
|
||||
|
||||
class C
|
||||
{
|
||||
int x;
|
||||
alias this = x;
|
||||
}
|
|
@ -3,7 +3,7 @@ TEST_OUTPUT:
|
|||
---
|
||||
fail_compilation/diag_template_alias.d(1): Error: identifier expected for template `alias` parameter
|
||||
fail_compilation/diag_template_alias.d(1): Error: found `alias` when expecting `(`
|
||||
fail_compilation/diag_template_alias.d(1): Error: semicolon expected following function declaration
|
||||
fail_compilation/diag_template_alias.d(1): Error: semicolon expected following function declaration, not `(`
|
||||
fail_compilation/diag_template_alias.d(1): Error: declaration expected, not `(`
|
||||
---
|
||||
*/
|
||||
|
|
|
@ -3,7 +3,7 @@ TEST_OUTPUT:
|
|||
---
|
||||
fail_compilation/diag_template_this.d(1): Error: identifier expected for template `this` parameter
|
||||
fail_compilation/diag_template_this.d(1): Error: found `this` when expecting `(`
|
||||
fail_compilation/diag_template_this.d(1): Error: semicolon expected following function declaration
|
||||
fail_compilation/diag_template_this.d(1): Error: semicolon expected following function declaration, not `(`
|
||||
fail_compilation/diag_template_this.d(1): Error: declaration expected, not `(`
|
||||
---
|
||||
*/
|
||||
|
|
|
@ -4,7 +4,7 @@ TEST_OUTPUT:
|
|||
---
|
||||
fail_compilation/diagin.d(14): Error: function `diagin.foo(in int)` is not callable using argument types `()`
|
||||
fail_compilation/diagin.d(14): too few arguments, expected 1, got 0
|
||||
fail_compilation/diagin.d(16): Error: none of the overloads of template `diagin.foo1` are callable using argument types `!()(bool[])`
|
||||
fail_compilation/diagin.d(16): Error: template `diagin.foo1` is not callable using argument types `!()(bool[])`
|
||||
fail_compilation/diagin.d(20): Candidate is: `foo1(T)(in T v, string)`
|
||||
---
|
||||
*/
|
||||
|
|
|
@ -21,7 +21,7 @@ __error__
|
|||
}
|
||||
}
|
||||
)`
|
||||
fail_compilation/e15876_3.d(28): Error: semicolon expected following function declaration
|
||||
fail_compilation/e15876_3.d(28): Error: semicolon expected following function declaration, not `End of File`
|
||||
---
|
||||
*/
|
||||
d(={for
|
||||
|
|
|
@ -14,10 +14,10 @@ fail_compilation/fail12744.d(61): Error: template instance `fail12744.bar12744L!
|
|||
fail_compilation/fail12744.d(40): Error: incompatible parameter storage classes `lazy` and `out`
|
||||
fail_compilation/fail12744.d(62): Error: template instance `fail12744.bar12744L!(foo12744O)` error instantiating
|
||||
fail_compilation/fail12744.d(41): Error: incompatible parameter storage classes `auto ref` and `out`
|
||||
fail_compilation/fail12744.d(67): Error: none of the overloads of template `fail12744.bar12744A` are callable using argument types `!(foo12744O)(int)`
|
||||
fail_compilation/fail12744.d(67): Error: template `fail12744.bar12744A` is not callable using argument types `!(foo12744O)(int)`
|
||||
fail_compilation/fail12744.d(41): Candidate is: `bar12744A(alias f)(auto ref PTT12744!f args)`
|
||||
fail_compilation/fail12744.d(41): Error: incompatible parameter storage classes `auto ref` and `lazy`
|
||||
fail_compilation/fail12744.d(68): Error: none of the overloads of template `fail12744.bar12744A` are callable using argument types `!(foo12744L)(int)`
|
||||
fail_compilation/fail12744.d(68): Error: template `fail12744.bar12744A` is not callable using argument types `!(foo12744L)(int)`
|
||||
fail_compilation/fail12744.d(41): Candidate is: `bar12744A(alias f)(auto ref PTT12744!f args)`
|
||||
---
|
||||
*/
|
||||
|
|
|
@ -4,7 +4,7 @@ TEST_OUTPUT:
|
|||
fail_compilation/fail14669.d(11): Error: `auto` can only be used as part of `auto ref` for template function parameters
|
||||
fail_compilation/fail14669.d(16): Error: template instance `fail14669.foo1!()` error instantiating
|
||||
fail_compilation/fail14669.d(12): Error: `auto` can only be used as part of `auto ref` for template function parameters
|
||||
fail_compilation/fail14669.d(17): Error: none of the overloads of template `fail14669.foo2` are callable using argument types `!()(int)`
|
||||
fail_compilation/fail14669.d(17): Error: template `fail14669.foo2` is not callable using argument types `!()(int)`
|
||||
fail_compilation/fail14669.d(12): Candidate is: `foo2()(auto int a)`
|
||||
---
|
||||
*/
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail15414.d(20): Deprecation: `__traits(getAttributes)` may only be used for individual functions, not overload sets such as: `fun`
|
||||
fail_compilation/fail15414.d(20): Deprecation: `__traits(getAttributes)` may only be used for individual functions, not the overload set `fun`
|
||||
fail_compilation/fail15414.d(20): the result of `__traits(getOverloads)` may be used to select the desired function to extract attributes from
|
||||
---
|
||||
*/
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail162.d(25): Error: none of the overloads of template `fail162.testHelper` are callable using argument types `!()(string, string)`
|
||||
fail_compilation/fail162.d(25): Error: template `fail162.testHelper` is not callable using argument types `!()(string, string)`
|
||||
fail_compilation/fail162.d(10): Candidate is: `testHelper(A...)()`
|
||||
fail_compilation/fail162.d(30): Error: template instance `fail162.test!("hello", "world")` error instantiating
|
||||
---
|
||||
|
|
|
@ -3,7 +3,7 @@ REQUIRED_ARGS: -verrors=spec -o-
|
|||
TEST_OUTPUT:
|
||||
---
|
||||
(spec:1) fail_compilation/fail20730b.d-mixin-43(43): Error: C style cast illegal, use `cast(int)mod`
|
||||
fail_compilation/fail20730b.d(26): Error: none of the overloads of template `fail20730b.atomicOp` are callable using argument types `!("+=")(shared(uint), int)`
|
||||
fail_compilation/fail20730b.d(26): Error: template `fail20730b.atomicOp` is not callable using argument types `!("+=")(shared(uint), int)`
|
||||
fail_compilation/fail20730b.d(41): Candidate is: `atomicOp(string op, T, V1)(shared ref T val, V1 mod)`
|
||||
with `op = "+=",
|
||||
T = uint,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail236.d(14): Error: undefined identifier `x`
|
||||
fail_compilation/fail236.d(22): Error: none of the overloads of template `fail236.Templ2` are callable using argument types `!()(int)`
|
||||
fail_compilation/fail236.d(22): Error: template `fail236.Templ2` is not callable using argument types `!()(int)`
|
||||
fail_compilation/fail236.d(12): Candidate is: `Templ2(alias a)(x)`
|
||||
---
|
||||
*/
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail23626a.d(10): Deprecation: function `fail23626a.ambig` cannot overload `extern(D)` function at fail_compilation/fail23626a.d(9)
|
||||
fail_compilation/fail23626a.d(13): Deprecation: function `fail23626a.ambigC` cannot overload `extern(C)` function at fail_compilation/fail23626a.d(12)
|
||||
fail_compilation/fail23626a.d(13): Error: function `fail23626a.ambigC` cannot overload `extern(C)` function at fail_compilation/fail23626a.d(12)
|
||||
fail_compilation/fail23626a.d(16): Error: function `fail23626a.ambigCxx(int a)` conflicts with previous declaration at fail_compilation/fail23626a.d(15)
|
||||
---
|
||||
*/
|
||||
|
|
|
@ -108,3 +108,17 @@ void test2456b()
|
|||
catch (Throwable) {} // NG
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail2456.d(121): Deprecation: can only catch mutable or const qualified types, not `immutable(Exception)`
|
||||
---
|
||||
*/
|
||||
void main() {
|
||||
try {
|
||||
throw new Exception("");
|
||||
} catch (immutable Exception e) {
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,8 +61,8 @@ auto f6() { return ""; } // string(), conflict
|
|||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail2789.d(67): Error: function `fail2789.f_ExternC1()` conflicts with previous declaration at fail_compilation/fail2789.d(66)
|
||||
fail_compilation/fail2789.d(70): Deprecation: function `fail2789.f_ExternC2` cannot overload `extern(C)` function at fail_compilation/fail2789.d(69)
|
||||
fail_compilation/fail2789.d(73): Deprecation: function `fail2789.f_ExternC3` cannot overload `extern(C)` function at fail_compilation/fail2789.d(72)
|
||||
fail_compilation/fail2789.d(70): Error: function `fail2789.f_ExternC2` cannot overload `extern(C)` function at fail_compilation/fail2789.d(69)
|
||||
fail_compilation/fail2789.d(73): Error: function `fail2789.f_ExternC3` cannot overload `extern(C)` function at fail_compilation/fail2789.d(72)
|
||||
---
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail8009.d(9): Error: none of the overloads of template `fail8009.filter` are callable using argument types `!()(void)`
|
||||
fail_compilation/fail8009.d(9): Error: template `fail8009.filter` is not callable using argument types `!()(void)`
|
||||
fail_compilation/fail8009.d(8): Candidate is: `filter(R)(scope bool delegate(ref BAD!R) func)`
|
||||
---
|
||||
*/
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail95.d(19): Error: none of the overloads of template `fail95.A` are callable using argument types `!()(int)`
|
||||
fail_compilation/fail95.d(19): Error: template `fail95.A` is not callable using argument types `!()(int)`
|
||||
fail_compilation/fail95.d(11): Candidate is: `A(alias T)(T)`
|
||||
---
|
||||
*/
|
||||
|
|
|
@ -4,8 +4,8 @@ fail_compilation/failcontracts.d(18): Error: missing `{ ... }` for function lite
|
|||
fail_compilation/failcontracts.d(18): Error: semicolon expected following auto declaration, not `bode`
|
||||
fail_compilation/failcontracts.d(19): Error: function declaration without return type. (Note that constructors are always named `this`)
|
||||
fail_compilation/failcontracts.d(19): Error: no identifier for declarator `test1()`
|
||||
fail_compilation/failcontracts.d(19): Error: semicolon expected following function declaration
|
||||
fail_compilation/failcontracts.d(20): Error: semicolon expected following function declaration
|
||||
fail_compilation/failcontracts.d(19): Error: semicolon expected following function declaration, not `bode`
|
||||
fail_compilation/failcontracts.d(20): Error: semicolon expected following function declaration, not `bode`
|
||||
fail_compilation/failcontracts.d(22): Error: unexpected `(` in declarator
|
||||
fail_compilation/failcontracts.d(22): Error: found `T` when expecting `)`
|
||||
fail_compilation/failcontracts.d(22): Error: enum declaration is invalid
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue