d: Merge dmd. druntime e770945277, phobos 6d6e0b9b9
D front-end changes: - Import latest fixes from dmd v2.107.0-beta.1. - Hex strings can now be cast to integer arrays. - Add support for Interpolated Expression Sequences. D runtime changes: - Import latest fixes from druntime v2.107.0-beta.1. - New core.interpolation module to provide run-time support for D interpolated expression sequence literals. Phobos changes: - Import latest fixes from phobos v2.107.0-beta.1. - `std.range.primitives.isBidirectionalRange', and `std.range.primitives.isRandomAccessRange' now take an optional element type. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd e770945277. * Make-lang.in (D_FRONTEND_OBJS): Add d/basicmangle.o, d/enumsem.o, d/funcsem.o, d/templatesem.o. * d-builtins.cc (build_frontend_type): Update for new front-end interface. * d-codegen.cc (declaration_type): Likewise. (parameter_type): Likewise. * d-incpath.cc (add_globalpaths): Likewise. (add_filepaths): Likewise. (add_import_paths): Likewise. * d-lang.cc (d_init_options): Likewise. (d_handle_option): Likewise. (d_parse_file): Likewise. * decl.cc (DeclVisitor::finish_vtable): Likewise. (DeclVisitor::visit (FuncDeclaration *)): Likewise. (get_symbol_decl): Likewise. * expr.cc (ExprVisitor::visit (StringExp *)): Likewise. Implement support for 8-byte hexadecimal strings. * typeinfo.cc (create_tinfo_types): Update internal TypeInfo representation. (TypeInfoVisitor::visit (TypeInfoConstDeclaration *)): Update for new front-end interface. (TypeInfoVisitor::visit (TypeInfoInvariantDeclaration *)): Likewise. (TypeInfoVisitor::visit (TypeInfoSharedDeclaration *)): Likewise. (TypeInfoVisitor::visit (TypeInfoWildDeclaration *)): Likewise. (TypeInfoVisitor::visit (TypeInfoClassDeclaration *)): Move data for TypeInfo_Class.nameSig to the end of the object. (create_typeinfo): Update for new front-end interface. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime e770945277. * libdruntime/Makefile.am (DRUNTIME_SOURCES): Add core/interpolation.d. * libdruntime/Makefile.in: Regenerate. * src/MERGE: Merge upstream phobos 6d6e0b9b9.
This commit is contained in:
parent
854b8555bd
commit
51c4eb28c1
136 changed files with 4336 additions and 3051 deletions
|
@ -87,6 +87,7 @@ D_FRONTEND_OBJS = \
|
|||
d/ast_node.o \
|
||||
d/astcodegen.o \
|
||||
d/astenums.o \
|
||||
d/basicmangle.o \
|
||||
d/blockexit.o \
|
||||
d/builtin.o \
|
||||
d/canthrow.o \
|
||||
|
@ -122,6 +123,7 @@ D_FRONTEND_OBJS = \
|
|||
d/dtoh.o \
|
||||
d/dversion.o \
|
||||
d/entity.o \
|
||||
d/enumsem.o \
|
||||
d/errors.o \
|
||||
d/errorsink.o \
|
||||
d/escape.o \
|
||||
|
@ -130,6 +132,7 @@ D_FRONTEND_OBJS = \
|
|||
d/file_manager.o \
|
||||
d/foreachvar.o \
|
||||
d/func.o \
|
||||
d/funcsem.o \
|
||||
d/globals.o \
|
||||
d/gluelayer.o \
|
||||
d/hdrgen.o \
|
||||
|
@ -192,6 +195,7 @@ D_FRONTEND_OBJS = \
|
|||
d/stmtstate.o \
|
||||
d/target.o \
|
||||
d/templateparamsem.o \
|
||||
d/templatesem.o \
|
||||
d/tokens.o \
|
||||
d/traits.o \
|
||||
d/transitivevisitor.o \
|
||||
|
|
|
@ -240,7 +240,7 @@ build_frontend_type (tree type)
|
|||
sdecl->sizeok = Sizeok::done;
|
||||
sdecl->type = (TypeStruct::create (sdecl))->addMod (mod);
|
||||
sdecl->type->ctype = type;
|
||||
sdecl->type->merge2 ();
|
||||
merge2 (sdecl->type);
|
||||
|
||||
/* Add both named and anonymous fields as members of the struct.
|
||||
Anonymous fields still need a name in D, so call them "__pad%u". */
|
||||
|
|
|
@ -150,7 +150,7 @@ declaration_type (Declaration *decl)
|
|||
TypeFunction *tf = TypeFunction::create (NULL, decl->type,
|
||||
VARARGnone, LINK::d);
|
||||
TypeDelegate *t = TypeDelegate::create (tf);
|
||||
return build_ctype (t->merge2 ());
|
||||
return build_ctype (merge2 (t));
|
||||
}
|
||||
|
||||
/* Static array va_list have array->pointer conversions applied. */
|
||||
|
@ -200,7 +200,7 @@ parameter_type (Parameter *arg)
|
|||
TypeFunction *tf = TypeFunction::create (NULL, arg->type,
|
||||
VARARGnone, LINK::d);
|
||||
TypeDelegate *t = TypeDelegate::create (tf);
|
||||
return build_ctype (t->merge2 ());
|
||||
return build_ctype (merge2 (t));
|
||||
}
|
||||
|
||||
/* Static array va_list have array->pointer conversions applied. */
|
||||
|
|
|
@ -71,9 +71,6 @@ add_globalpaths (Strings *paths)
|
|||
{
|
||||
if (paths)
|
||||
{
|
||||
if (!global.path)
|
||||
global.path = d_gc_malloc<Strings> ();
|
||||
|
||||
for (size_t i = 0; i < paths->length; i++)
|
||||
{
|
||||
const char *path = (*paths)[i];
|
||||
|
@ -86,7 +83,7 @@ add_globalpaths (Strings *paths)
|
|||
continue;
|
||||
}
|
||||
|
||||
global.path->push (target);
|
||||
global.path.push (target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -98,9 +95,6 @@ add_filepaths (Strings *paths)
|
|||
{
|
||||
if (paths)
|
||||
{
|
||||
if (!global.filePath)
|
||||
global.filePath = d_gc_malloc<Strings> ();
|
||||
|
||||
for (size_t i = 0; i < paths->length; i++)
|
||||
{
|
||||
const char *path = (*paths)[i];
|
||||
|
@ -112,7 +106,7 @@ add_filepaths (Strings *paths)
|
|||
continue;
|
||||
}
|
||||
|
||||
global.filePath->push (target);
|
||||
global.filePath.push (target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -143,9 +137,9 @@ add_import_paths (const char *iprefix, const char *imultilib, bool stdinc)
|
|||
|
||||
/* Ignore duplicate entries. */
|
||||
bool found = false;
|
||||
for (size_t i = 0; i < global.params.imppath->length; i++)
|
||||
for (size_t i = 0; i < global.params.imppath.length; i++)
|
||||
{
|
||||
if (strcmp (path, (*global.params.imppath)[i]) == 0)
|
||||
if (strcmp (path, global.params.imppath[i]) == 0)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
|
@ -162,33 +156,26 @@ add_import_paths (const char *iprefix, const char *imultilib, bool stdinc)
|
|||
if (imultilib)
|
||||
{
|
||||
char *target_path = concat (path, "/", imultilib, NULL);
|
||||
global.params.imppath->shift (target_path);
|
||||
global.params.imppath.shift (target_path);
|
||||
}
|
||||
|
||||
global.params.imppath->shift (path);
|
||||
global.params.imppath.shift (path);
|
||||
}
|
||||
}
|
||||
|
||||
/* Add import search paths. */
|
||||
if (global.params.imppath)
|
||||
for (size_t i = 0; i < global.params.imppath.length; i++)
|
||||
{
|
||||
for (size_t i = 0; i < global.params.imppath->length; i++)
|
||||
{
|
||||
const char *path = (*global.params.imppath)[i];
|
||||
if (path)
|
||||
add_globalpaths (FileName::splitPath (path));
|
||||
}
|
||||
const char *path = global.params.imppath[i];
|
||||
if (path)
|
||||
add_globalpaths (FileName::splitPath (path));
|
||||
}
|
||||
|
||||
/* Add string import search paths. */
|
||||
if (global.params.fileImppath)
|
||||
for (size_t i = 0; i < global.params.fileImppath.length; i++)
|
||||
{
|
||||
for (size_t i = 0; i < global.params.fileImppath->length; i++)
|
||||
{
|
||||
const char *path = (*global.params.fileImppath)[i];
|
||||
if (path)
|
||||
add_filepaths (FileName::splitPath (path));
|
||||
}
|
||||
const char *path = global.params.fileImppath[i];
|
||||
if (path)
|
||||
add_filepaths (FileName::splitPath (path));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -306,9 +306,6 @@ d_init_options (unsigned int, cl_decoded_option *decoded_options)
|
|||
global.params.v.errorLimit = flag_max_errors;
|
||||
global.params.v.messageStyle = MessageStyle::gnu;
|
||||
|
||||
global.params.imppath = d_gc_malloc<Strings> ();
|
||||
global.params.fileImppath = d_gc_malloc<Strings> ();
|
||||
|
||||
/* Extra GDC-specific options. */
|
||||
d_option.fonly = NULL;
|
||||
d_option.multilib = NULL;
|
||||
|
@ -724,11 +721,11 @@ d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
|
|||
break;
|
||||
|
||||
case OPT_I:
|
||||
global.params.imppath->push (arg);
|
||||
global.params.imppath.push (arg);
|
||||
break;
|
||||
|
||||
case OPT_J:
|
||||
global.params.fileImppath->push (arg);
|
||||
global.params.fileImppath.push (arg);
|
||||
break;
|
||||
|
||||
case OPT_MM:
|
||||
|
@ -1045,25 +1042,24 @@ d_parse_file (void)
|
|||
{
|
||||
if (global.params.v.verbose)
|
||||
{
|
||||
/* Dump information about the D compiler and language version. */
|
||||
message ("binary %s", global.params.argv0.ptr);
|
||||
message ("version %s", global.versionChars ());
|
||||
|
||||
if (global.versionids)
|
||||
/* Dump all predefined version identifiers. */
|
||||
obstack buffer;
|
||||
gcc_obstack_init (&buffer);
|
||||
obstack_grow (&buffer, "predefs ", 9);
|
||||
for (size_t i = 0; i < global.versionids.length; i++)
|
||||
{
|
||||
obstack buffer;
|
||||
gcc_obstack_init (&buffer);
|
||||
obstack_grow (&buffer, "predefs ", 9);
|
||||
for (size_t i = 0; i < global.versionids->length; i++)
|
||||
{
|
||||
Identifier *id = (*global.versionids)[i];
|
||||
const char *str = id->toChars ();
|
||||
obstack_1grow (&buffer, ' ');
|
||||
obstack_grow (&buffer, str, strlen (str));
|
||||
}
|
||||
|
||||
obstack_1grow (&buffer, '\0');
|
||||
message ("%s", (char *) obstack_finish (&buffer));
|
||||
Identifier *id = global.versionids[i];
|
||||
const char *str = id->toChars ();
|
||||
obstack_1grow (&buffer, ' ');
|
||||
obstack_grow (&buffer, str, strlen (str));
|
||||
}
|
||||
|
||||
obstack_1grow (&buffer, '\0');
|
||||
message ("%s", (char *) obstack_finish (&buffer));
|
||||
}
|
||||
|
||||
/* Start the main input file, if the debug writer wants it. */
|
||||
|
|
|
@ -539,7 +539,7 @@ public:
|
|||
continue;
|
||||
|
||||
/* Ensure function has a return value. */
|
||||
if (!fd->functionSemantic ())
|
||||
if (!functionSemantic (fd))
|
||||
has_errors = true;
|
||||
|
||||
/* No name hiding to check for. */
|
||||
|
@ -563,20 +563,23 @@ public:
|
|||
if (fd2->isFuture ())
|
||||
continue;
|
||||
|
||||
if (fd->leastAsSpecialized (fd2, NULL) != MATCH::nomatch
|
||||
|| fd2->leastAsSpecialized (fd, NULL) != MATCH::nomatch)
|
||||
{
|
||||
error_at (make_location_t (fd->loc), "use of %qs",
|
||||
fd->toPrettyChars ());
|
||||
inform (make_location_t (fd2->loc), "is hidden by %qs",
|
||||
fd2->toPrettyChars ());
|
||||
inform (make_location_t (d->loc),
|
||||
"use %<alias %s = %s.%s;%> to introduce base class "
|
||||
"overload set", fd->toChars (),
|
||||
fd->parent->toChars (), fd->toChars ());
|
||||
has_errors = true;
|
||||
break;
|
||||
}
|
||||
if (FuncDeclaration::leastAsSpecialized (fd, fd2, NULL)
|
||||
== MATCH::nomatch
|
||||
&& FuncDeclaration::leastAsSpecialized (fd2, fd, NULL)
|
||||
== MATCH::nomatch)
|
||||
continue;
|
||||
|
||||
/* Hiding detected; same name, overlapping specializations. */
|
||||
error_at (make_location_t (fd->loc), "use of %qs",
|
||||
fd->toPrettyChars ());
|
||||
inform (make_location_t (fd2->loc), "is hidden by %qs",
|
||||
fd2->toPrettyChars ());
|
||||
inform (make_location_t (d->loc),
|
||||
"use %<alias %s = %s.%s;%> to introduce base class "
|
||||
"overload set", fd->toChars (),
|
||||
fd->parent->toChars (), fd->toChars ());
|
||||
has_errors = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -943,7 +946,7 @@ public:
|
|||
gcc_assert (!doing_semantic_analysis_p);
|
||||
|
||||
doing_semantic_analysis_p = true;
|
||||
d->functionSemantic3 ();
|
||||
functionSemantic3 (d);
|
||||
Module::runDeferredSemantic3 ();
|
||||
doing_semantic_analysis_p = false;
|
||||
}
|
||||
|
@ -1231,7 +1234,7 @@ get_symbol_decl (Declaration *decl)
|
|||
if (fd)
|
||||
{
|
||||
/* Run full semantic on functions we need to know about. */
|
||||
if (!fd->functionSemantic ())
|
||||
if (!functionSemantic (fd))
|
||||
{
|
||||
decl->csym = error_mark_node;
|
||||
return decl->csym;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
bce5c1f7b521d22dcf1ea4e2bc3f76d9d28274fa
|
||||
e7709452775d374c1e2dfb67566668ada3dec5fc
|
||||
|
||||
The first line of this file holds the git revision number of the last
|
||||
merge done from the dlang/dmd repository.
|
||||
|
|
|
@ -110,6 +110,8 @@ Note that these groups have no strict meaning, the category assignments are a bi
|
|||
| File | Purpose |
|
||||
|-------------------------------------------------------------------------------------------|-------------------------------------------------------------------|
|
||||
| [dsymbolsem.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/dsymbolsem.d) | Do semantic 1 pass (symbol identifiers/types) |
|
||||
| [enumsem.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/enumsem.d) | Enum semantics |
|
||||
| [funcsem.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/funcsem.d) | Function semantics |
|
||||
| [semantic2.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/semantic2.d) | Do semantic 2 pass (symbol initializers) |
|
||||
| [semantic3.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/semantic3.d) | Do semantic 3 pass (function bodies) |
|
||||
| [inline.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/inline.d) | Do inline pass (optimization pass that dmd does in the front-end) |
|
||||
|
@ -117,6 +119,7 @@ Note that these groups have no strict meaning, the category assignments are a bi
|
|||
| [expressionsem.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/expressionsem.d) | Do semantic analysis for expressions |
|
||||
| [statementsem.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/statementsem.d) | Do semantic analysis for statements |
|
||||
| [initsem.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/initsem.d) | Do semantic analysis for initializers |
|
||||
| [templatesem.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/templatesem.d) | Do semantic analysis for templates |
|
||||
| [templateparamsem.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/templateparamsem.d) | Do semantic analysis for template parameters |
|
||||
| [typesem.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/typesem.d) | Do semantic analysis for types |
|
||||
|
||||
|
@ -230,6 +233,7 @@ Note that these groups have no strict meaning, the category assignments are a bi
|
|||
|-----------------------------------------------------------------------------------|------------------------------------------------------------------|
|
||||
| [cppmangle.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/cppmangle.d) | C++ name mangling |
|
||||
| [cppmanglewin.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/cppmanglewin.d) | C++ name mangling for Windows |
|
||||
| [basicmangle.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/basicmangle.d) | D name mangling for basic types |
|
||||
| [dmangle.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/dmangle.d) | D [name mangling](https://dlang.org/spec/abi.html#name_mangling) |
|
||||
|
||||
### Linking
|
||||
|
|
|
@ -234,7 +234,8 @@ struct ClassFlags
|
|||
hasTypeInfo = 0x20,
|
||||
isAbstract = 0x40,
|
||||
isCPPclass = 0x80,
|
||||
hasDtor = 0x100
|
||||
hasDtor = 0x100,
|
||||
hasNameSig = 0x200,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
109
gcc/d/dmd/basicmangle.d
Normal file
109
gcc/d/dmd/basicmangle.d
Normal file
|
@ -0,0 +1,109 @@
|
|||
/**
|
||||
* Defines the building blocks for creating the mangled names for basic types.
|
||||
*
|
||||
* Copyright: Copyright (C) 1999-2024 by The D Language Foundation, All Rights Reserved
|
||||
* License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
|
||||
* Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/basicmangle.d, _basicmangle.d)
|
||||
* Documentation: https://dlang.org/phobos/dmd_basicmangle.html
|
||||
* Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/basicmangle.d
|
||||
*/
|
||||
module dmd.basicmangle;
|
||||
|
||||
import dmd.astenums;
|
||||
import dmd.common.outbuffer : OutBuffer;
|
||||
|
||||
/// Type mangling mapping for basic, derived and user defined types
|
||||
immutable char[TMAX] mangleChar =
|
||||
[
|
||||
Tchar : 'a',
|
||||
Tbool : 'b',
|
||||
Tcomplex80 : 'c',
|
||||
Tfloat64 : 'd',
|
||||
Tfloat80 : 'e',
|
||||
Tfloat32 : 'f',
|
||||
Tint8 : 'g',
|
||||
Tuns8 : 'h',
|
||||
Tint32 : 'i',
|
||||
Timaginary80 : 'j',
|
||||
Tuns32 : 'k',
|
||||
Tint64 : 'l',
|
||||
Tuns64 : 'm',
|
||||
Tnull : 'n',
|
||||
Timaginary32 : 'o',
|
||||
Timaginary64 : 'p',
|
||||
Tcomplex32 : 'q',
|
||||
Tcomplex64 : 'r',
|
||||
Tint16 : 's',
|
||||
Tuns16 : 't',
|
||||
Twchar : 'u',
|
||||
Tvoid : 'v',
|
||||
Tdchar : 'w',
|
||||
// x // const
|
||||
// y // immutable
|
||||
Tint128 : 'z', // zi
|
||||
Tuns128 : 'z', // zk
|
||||
|
||||
Tarray : 'A',
|
||||
Ttuple : 'B',
|
||||
Tclass : 'C',
|
||||
Tdelegate : 'D',
|
||||
Tenum : 'E',
|
||||
Tfunction : 'F', // D function
|
||||
Tsarray : 'G',
|
||||
Taarray : 'H',
|
||||
// I // in
|
||||
// J // out
|
||||
// K // ref
|
||||
// L // lazy
|
||||
// M // has this, or scope
|
||||
// N // Nh:vector Ng:wild Nn:noreturn
|
||||
// O // shared
|
||||
Tpointer : 'P',
|
||||
// Q // Type/symbol/identifier backward reference
|
||||
Treference : 'R',
|
||||
Tstruct : 'S',
|
||||
// T // Ttypedef
|
||||
// U // C function
|
||||
// W // Windows function
|
||||
// X // variadic T t...)
|
||||
// Y // variadic T t,...)
|
||||
// Z // not variadic, end of parameters
|
||||
|
||||
// '@' shouldn't appear anywhere in the deco'd names
|
||||
Tnone : '@',
|
||||
Tident : '@',
|
||||
Tinstance : '@',
|
||||
Terror : '@',
|
||||
Ttypeof : '@',
|
||||
Tslice : '@',
|
||||
Treturn : '@',
|
||||
Tvector : '@',
|
||||
Ttraits : '@',
|
||||
Tmixin : '@',
|
||||
Ttag : '@',
|
||||
Tnoreturn : '@', // becomes 'Nn'
|
||||
];
|
||||
|
||||
unittest
|
||||
{
|
||||
foreach (i, mangle; mangleChar)
|
||||
{
|
||||
if (mangle == char.init)
|
||||
{
|
||||
import core.stdc.stdio;
|
||||
fprintf(stderr, "ty = %u\n", cast(uint)i);
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***********************
|
||||
* Mangle basic type ty to buf.
|
||||
*/
|
||||
void tyToDecoBuffer(ref OutBuffer buf, int ty) @safe
|
||||
{
|
||||
const c = mangleChar[ty];
|
||||
buf.writeByte(c);
|
||||
if (c == 'z')
|
||||
buf.writeByte(ty == Tint128 ? 'i' : 'k');
|
||||
}
|
|
@ -27,6 +27,7 @@ import dmd.errors;
|
|||
import dmd.expression;
|
||||
import dmd.expressionsem;
|
||||
import dmd.func;
|
||||
import dmd.funcsem;
|
||||
import dmd.globals;
|
||||
import dmd.id;
|
||||
import dmd.identifier;
|
||||
|
@ -905,7 +906,7 @@ void buildDtors(AggregateDeclaration ad, Scope* sc)
|
|||
a.addMember(sc, ad); // temporarily add to symbol table
|
||||
}
|
||||
|
||||
sdv.dtor.functionSemantic();
|
||||
functionSemantic(sdv.dtor);
|
||||
|
||||
stc = mergeFuncAttrs(stc, sdv.dtor);
|
||||
if (stc & STC.disable)
|
||||
|
@ -1154,7 +1155,7 @@ private DtorDeclaration buildExternDDtor(AggregateDeclaration ad, Scope* sc)
|
|||
ad.members.push(func);
|
||||
func.addMember(sc2, ad);
|
||||
func.dsymbolSemantic(sc2);
|
||||
func.functionSemantic(); // to infer attributes
|
||||
functionSemantic(func); // to infer attributes
|
||||
|
||||
sc2.pop();
|
||||
return func;
|
||||
|
@ -1336,7 +1337,7 @@ FuncDeclaration buildPostBlit(StructDeclaration sd, Scope* sc)
|
|||
// perform semantic on the member postblit in order to
|
||||
// be able to aggregate it later on with the rest of the
|
||||
// postblits
|
||||
sdv.postblit.functionSemantic();
|
||||
functionSemantic(sdv.postblit);
|
||||
|
||||
stc = mergeFuncAttrs(stc, sdv.postblit);
|
||||
stc = mergeFuncAttrs(stc, sdv.dtor);
|
||||
|
@ -1401,7 +1402,7 @@ FuncDeclaration buildPostBlit(StructDeclaration sd, Scope* sc)
|
|||
*/
|
||||
if (sdv.dtor)
|
||||
{
|
||||
sdv.dtor.functionSemantic();
|
||||
functionSemantic(sdv.dtor);
|
||||
|
||||
// keep a list of fields that need to be destroyed in case
|
||||
// of a future postblit failure
|
||||
|
|
|
@ -755,6 +755,25 @@ struct OutBuffer
|
|||
} while (value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write an array as a string of hexadecimal digits
|
||||
* Params:
|
||||
* data = bytes to write
|
||||
* upperCase = whether to upper case hex digits A-F
|
||||
*/
|
||||
void writeHexString(scope const(ubyte)[] data, bool upperCase) pure nothrow @safe
|
||||
{
|
||||
auto slice = this.allocate(2 * data.length);
|
||||
const a = upperCase ? 'A' : 'a';
|
||||
foreach (i, c; data)
|
||||
{
|
||||
char hi = (c >> 4) & 0xF;
|
||||
slice[i * 2] = cast(char)(hi < 10 ? hi + '0' : hi - 10 + a);
|
||||
char lo = c & 0xF;
|
||||
slice[i * 2 + 1] = cast(char)(lo < 10 ? lo + '0' : lo - 10 + a);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Destructively saves the contents of `this` to `filename`. As an
|
||||
optimization, if the file already has identical contents with the buffer,
|
||||
|
@ -943,3 +962,11 @@ unittest
|
|||
else
|
||||
assert(buf[] == "\nabc\n\n");
|
||||
}
|
||||
|
||||
unittest
|
||||
{
|
||||
OutBuffer buf;
|
||||
buf.writeHexString([0xAA, 0xBB], false);
|
||||
buf.writeHexString([0xCC], true);
|
||||
assert(buf[] == "aabbCC");
|
||||
}
|
||||
|
|
|
@ -548,8 +548,6 @@ extern (C++) final class DebugCondition : DVCondition
|
|||
/// Ditto
|
||||
extern(D) static void addGlobalIdent(const(char)[] ident)
|
||||
{
|
||||
if (!global.debugids)
|
||||
global.debugids = new Identifiers();
|
||||
global.debugids.push(Identifier.idPool(ident));
|
||||
}
|
||||
|
||||
|
@ -579,7 +577,7 @@ extern (C++) final class DebugCondition : DVCondition
|
|||
bool definedInModule = false;
|
||||
if (ident)
|
||||
{
|
||||
if (findCondition(mod.debugids, ident))
|
||||
if (mod.debugids && findCondition(*mod.debugids, ident))
|
||||
{
|
||||
inc = Include.yes;
|
||||
definedInModule = true;
|
||||
|
@ -830,8 +828,6 @@ extern (C++) final class VersionCondition : DVCondition
|
|||
/// Ditto
|
||||
extern(D) static void addPredefinedGlobalIdent(const(char)[] ident)
|
||||
{
|
||||
if (!global.versionids)
|
||||
global.versionids = new Identifiers();
|
||||
global.versionids.push(Identifier.idPool(ident));
|
||||
}
|
||||
|
||||
|
@ -861,7 +857,7 @@ extern (C++) final class VersionCondition : DVCondition
|
|||
bool definedInModule = false;
|
||||
if (ident)
|
||||
{
|
||||
if (findCondition(mod.versionids, ident))
|
||||
if (mod.versionids && findCondition(*mod.versionids, ident))
|
||||
{
|
||||
inc = Include.yes;
|
||||
definedInModule = true;
|
||||
|
@ -983,15 +979,12 @@ extern (C++) final class StaticIfCondition : Condition
|
|||
* Returns:
|
||||
* true if found
|
||||
*/
|
||||
bool findCondition(Identifiers* ids, Identifier ident) @safe nothrow pure
|
||||
bool findCondition(ref Identifiers ids, Identifier ident) @safe nothrow pure
|
||||
{
|
||||
if (ids)
|
||||
foreach (id; ids)
|
||||
{
|
||||
foreach (id; *ids)
|
||||
{
|
||||
if (id == ident)
|
||||
return true;
|
||||
}
|
||||
if (id == ident)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -711,7 +711,7 @@ UnionExp Equal(EXP op, const ref Loc loc, Type type, Expression e1, Expression e
|
|||
cmp = 1; // if dim1 winds up being 0
|
||||
foreach (i; 0 .. dim1)
|
||||
{
|
||||
uinteger_t c = es1.getCodeUnit(i);
|
||||
uinteger_t c = es1.getIndex(i);
|
||||
auto ee2 = es2[i];
|
||||
if (ee2.isConst() != 1)
|
||||
{
|
||||
|
@ -1119,7 +1119,7 @@ UnionExp Index(Type type, Expression e1, Expression e2, bool indexIsInBounds)
|
|||
}
|
||||
else
|
||||
{
|
||||
emplaceExp!(IntegerExp)(&ue, loc, es1.getCodeUnit(cast(size_t) i), type);
|
||||
emplaceExp!(IntegerExp)(&ue, loc, es1.getIndex(cast(size_t) i), type);
|
||||
}
|
||||
}
|
||||
else if (e1.type.toBasetype().ty == Tsarray && e2.op == EXP.int64)
|
||||
|
@ -1282,7 +1282,7 @@ void sliceAssignArrayLiteralFromString(ArrayLiteralExp existingAE, const StringE
|
|||
Type elemType = existingAE.type.nextOf();
|
||||
foreach (j; 0 .. len)
|
||||
{
|
||||
const val = newval.getCodeUnit(j);
|
||||
const val = newval.getIndex(j);
|
||||
(*existingAE.elements)[j + firstIndex] = new IntegerExp(newval.loc, val, elemType);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -568,6 +568,9 @@ StringExp createBlockDuplicatedStringLiteral(UnionExp* pue, const ref Loc loc, T
|
|||
case 4:
|
||||
(cast(dchar*)s)[elemi] = value;
|
||||
break;
|
||||
case 8:
|
||||
(cast(ulong*)s)[elemi] = value;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
@ -1494,7 +1497,7 @@ Expression ctfeIndex(UnionExp* pue, const ref Loc loc, Type type, Expression e1,
|
|||
error(loc, "string index %llu is out of bounds `[0 .. %llu]`", indx, cast(ulong)es1.len);
|
||||
return CTFEExp.cantexp;
|
||||
}
|
||||
emplaceExp!IntegerExp(pue, loc, es1.getCodeUnit(cast(size_t) indx), type);
|
||||
emplaceExp!IntegerExp(pue, loc, es1.getIndex(cast(size_t) indx), type);
|
||||
return pue.exp();
|
||||
}
|
||||
|
||||
|
@ -1704,7 +1707,7 @@ Expression changeArrayLiteralLength(UnionExp* pue, const ref Loc loc, TypeArray
|
|||
void* s = mem.xcalloc(newlen + 1, oldse.sz);
|
||||
const data = oldse.peekData();
|
||||
memcpy(s, data.ptr, copylen * oldse.sz);
|
||||
const defaultValue = cast(uint)defaultElem.toInteger();
|
||||
const defaultValue = cast(ulong)defaultElem.toInteger();
|
||||
foreach (size_t elemi; copylen .. newlen)
|
||||
{
|
||||
switch (oldse.sz)
|
||||
|
@ -1718,6 +1721,9 @@ Expression changeArrayLiteralLength(UnionExp* pue, const ref Loc loc, TypeArray
|
|||
case 4:
|
||||
(cast(dchar*)s)[cast(size_t)(indxlo + elemi)] = cast(dchar)defaultValue;
|
||||
break;
|
||||
case 8:
|
||||
(cast(ulong*)s)[cast(size_t)(indxlo + elemi)] = cast(ulong)defaultValue;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
|
|
@ -123,6 +123,7 @@ extern (C++) struct BaseClass
|
|||
}
|
||||
}
|
||||
|
||||
// These must match the values in druntime/src/object.d
|
||||
enum ClassFlags : uint
|
||||
{
|
||||
none = 0x0,
|
||||
|
@ -135,6 +136,7 @@ enum ClassFlags : uint
|
|||
isAbstract = 0x40,
|
||||
isCPPclass = 0x80,
|
||||
hasDtor = 0x100,
|
||||
hasNameSig = 0x200,
|
||||
}
|
||||
|
||||
/***********************************************************
|
||||
|
|
|
@ -30,6 +30,9 @@ class StructDeclaration;
|
|||
struct IntRange;
|
||||
struct AttributeViolation;
|
||||
|
||||
bool functionSemantic(FuncDeclaration* fd);
|
||||
bool functionSemantic3(FuncDeclaration* fd);
|
||||
|
||||
//enum STC : ulong from astenums.d:
|
||||
|
||||
#define STCundefined 0ULL
|
||||
|
@ -698,14 +701,12 @@ public:
|
|||
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;
|
||||
|
||||
int findVtblIndex(Dsymbols *vtbl, int dim);
|
||||
bool overloadInsert(Dsymbol *s) override;
|
||||
bool inUnittest();
|
||||
MATCH leastAsSpecialized(FuncDeclaration *g, Identifiers *names);
|
||||
static MATCH leastAsSpecialized(FuncDeclaration *f, FuncDeclaration *g, Identifiers *names);
|
||||
LabelDsymbol *searchLabel(Identifier *ident, const Loc &loc);
|
||||
const char *toPrettyChars(bool QualifyTypes = false) override;
|
||||
const char *toFullSignature(); // for diagnostics, e.g. 'int foo(int x, int y) pure'
|
||||
|
|
|
@ -122,91 +122,6 @@ extern (C++) final class EnumDeclaration : ScopeDsymbol
|
|||
return isSpecialEnumIdent(ident) && memtype;
|
||||
}
|
||||
|
||||
Expression getDefaultValue(const ref Loc loc)
|
||||
{
|
||||
Expression handleErrors(){
|
||||
defaultval = ErrorExp.get();
|
||||
return defaultval;
|
||||
}
|
||||
//printf("EnumDeclaration::getDefaultValue() %p %s\n", this, toChars());
|
||||
// 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())
|
||||
return memtype.defaultInit(loc, true);
|
||||
|
||||
if (_scope)
|
||||
dsymbolSemantic(this, _scope);
|
||||
if (errors)
|
||||
return handleErrors();
|
||||
if (!members)
|
||||
{
|
||||
if (isSpecial())
|
||||
{
|
||||
/* Allow these special enums to not need a member list
|
||||
*/
|
||||
return defaultval = memtype.defaultInit(loc);
|
||||
}
|
||||
|
||||
error(loc, "%s `%s` is opaque and has no default initializer", kind, toPrettyChars);
|
||||
return handleErrors();
|
||||
}
|
||||
|
||||
foreach (const i; 0 .. members.length)
|
||||
{
|
||||
EnumMember em = (*members)[i].isEnumMember();
|
||||
if (em)
|
||||
{
|
||||
if (em.semanticRun < PASS.semanticdone)
|
||||
{
|
||||
error(loc, "%s `%s` forward reference of `%s.init`", kind, toPrettyChars, toChars());
|
||||
return handleErrors();
|
||||
}
|
||||
|
||||
defaultval = em.value;
|
||||
return defaultval;
|
||||
}
|
||||
}
|
||||
return handleErrors();
|
||||
}
|
||||
|
||||
Type getMemtype(const ref Loc loc)
|
||||
{
|
||||
if (_scope)
|
||||
{
|
||||
/* Enum is forward referenced. We don't need to resolve the whole thing,
|
||||
* just the base type
|
||||
*/
|
||||
if (memtype)
|
||||
{
|
||||
Loc locx = loc.isValid() ? loc : this.loc;
|
||||
memtype = memtype.typeSemantic(locx, _scope);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Run semantic to get the type from a possible first member value
|
||||
dsymbolSemantic(this, _scope);
|
||||
}
|
||||
}
|
||||
if (!memtype)
|
||||
{
|
||||
if (!isAnonymous() && (members || semanticRun >= PASS.semanticdone))
|
||||
memtype = Type.tint32;
|
||||
else
|
||||
{
|
||||
Loc locx = loc.isValid() ? loc : this.loc;
|
||||
error(locx, "is forward referenced looking for base type");
|
||||
return Type.terror;
|
||||
}
|
||||
}
|
||||
return memtype;
|
||||
}
|
||||
|
||||
override inout(EnumDeclaration) isEnumDeclaration() inout
|
||||
{
|
||||
return this;
|
||||
|
|
|
@ -33,6 +33,7 @@ import dmd.errors;
|
|||
import dmd.expression;
|
||||
import dmd.expressionsem;
|
||||
import dmd.func;
|
||||
import dmd.funcsem;
|
||||
import dmd.globals;
|
||||
import dmd.hdrgen;
|
||||
import dmd.id;
|
||||
|
@ -440,7 +441,7 @@ private Expression interpretFunction(UnionExp* pue, FuncDeclaration fd, InterSta
|
|||
fdError("circular dependency. Functions cannot be interpreted while being compiled");
|
||||
return CTFEExp.cantexp;
|
||||
}
|
||||
if (!fd.functionSemantic3())
|
||||
if (!functionSemantic3(fd))
|
||||
return CTFEExp.cantexp;
|
||||
if (fd.semanticRun < PASS.semantic3done)
|
||||
{
|
||||
|
@ -6097,11 +6098,35 @@ public:
|
|||
result.type = e.to;
|
||||
return;
|
||||
}
|
||||
|
||||
// Disallow array type painting, except for conversions between built-in
|
||||
// types of identical size.
|
||||
if ((e.to.ty == Tsarray || e.to.ty == Tarray) && (e1.type.ty == Tsarray || e1.type.ty == Tarray) && !isSafePointerCast(e1.type.nextOf(), e.to.nextOf()))
|
||||
{
|
||||
auto se = e1.isStringExp();
|
||||
// Allow casting a hex string literal to short[], int[] or long[]
|
||||
if (se && se.hexString && se.postfix == StringExp.NoPostfix)
|
||||
{
|
||||
const sz = cast(size_t) e.to.nextOf().size;
|
||||
if ((se.len % sz) != 0)
|
||||
{
|
||||
error(e.loc, "hex string length %d must be a multiple of %d to cast to `%s`",
|
||||
cast(int) se.len, cast(int) sz, e.to.toChars());
|
||||
result = CTFEExp.cantexp;
|
||||
return;
|
||||
}
|
||||
|
||||
auto str = arrayCastBigEndian((cast(const ubyte[]) se.peekString()), sz);
|
||||
emplaceExp!(StringExp)(pue, e1.loc, str, se.len / sz, cast(ubyte) sz);
|
||||
result = pue.exp();
|
||||
result.type = e.to;
|
||||
return;
|
||||
}
|
||||
error(e.loc, "array cast from `%s` to `%s` is not supported at compile time", e1.type.toChars(), e.to.toChars());
|
||||
if (se && se.hexString && se.postfix != StringExp.NoPostfix)
|
||||
errorSupplemental(e.loc, "perhaps remove postfix `%s` from hex string",
|
||||
(cast(char) se.postfix ~ "\0").ptr);
|
||||
|
||||
result = CTFEExp.cantexp;
|
||||
return;
|
||||
}
|
||||
|
@ -7719,3 +7744,44 @@ private void removeHookTraceImpl(ref CallExp ce, ref FuncDeclaration fd)
|
|||
if (global.params.v.verbose)
|
||||
message("strip %s =>\n %s", oldCE.toChars(), ce.toChars());
|
||||
}
|
||||
|
||||
/**
|
||||
* Cast a `ubyte[]` to an array of larger integers as if we are on a big endian architecture
|
||||
* Params:
|
||||
* data = array with big endian data
|
||||
* size = 1 for ubyte[], 2 for ushort[], 4 for uint[], 8 for ulong[]
|
||||
* Returns: copy of `data`, with bytes shuffled if compiled for `version(LittleEndian)`
|
||||
*/
|
||||
ubyte[] arrayCastBigEndian(const ubyte[] data, size_t size)
|
||||
{
|
||||
ubyte[] impl(T)()
|
||||
{
|
||||
auto result = new T[](data.length / T.sizeof);
|
||||
foreach (i; 0 .. result.length)
|
||||
{
|
||||
result[i] = 0;
|
||||
foreach (j; 0 .. T.sizeof)
|
||||
{
|
||||
result[i] |= T(data[i * T.sizeof + j]) << ((T.sizeof - 1 - j) * 8);
|
||||
}
|
||||
}
|
||||
return cast(ubyte[]) result;
|
||||
}
|
||||
switch (size)
|
||||
{
|
||||
case 1: return data.dup;
|
||||
case 2: return impl!ushort;
|
||||
case 4: return impl!uint;
|
||||
case 8: return impl!ulong;
|
||||
default: assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
unittest
|
||||
{
|
||||
ubyte[] data = [0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22];
|
||||
assert(cast(ulong[]) arrayCastBigEndian(data, 8) == [0xAABBCCDDEEFF1122]);
|
||||
assert(cast(uint[]) arrayCastBigEndian(data, 4) == [0xAABBCCDD, 0xEEFF1122]);
|
||||
assert(cast(ushort[]) arrayCastBigEndian(data, 2) == [0xAABB, 0xCCDD, 0xEEFF, 0x1122]);
|
||||
assert(cast(ubyte[]) arrayCastBigEndian(data, 1) == data);
|
||||
}
|
||||
|
|
|
@ -137,6 +137,7 @@ import core.stdc.string;
|
|||
import dmd.aggregate;
|
||||
import dmd.arraytypes;
|
||||
import dmd.astenums;
|
||||
import dmd.basicmangle;
|
||||
import dmd.dclass;
|
||||
import dmd.declaration;
|
||||
import dmd.dinterpret;
|
||||
|
@ -161,89 +162,6 @@ import dmd.target;
|
|||
import dmd.tokens;
|
||||
import dmd.visitor;
|
||||
|
||||
private immutable char[TMAX] mangleChar =
|
||||
[
|
||||
Tchar : 'a',
|
||||
Tbool : 'b',
|
||||
Tcomplex80 : 'c',
|
||||
Tfloat64 : 'd',
|
||||
Tfloat80 : 'e',
|
||||
Tfloat32 : 'f',
|
||||
Tint8 : 'g',
|
||||
Tuns8 : 'h',
|
||||
Tint32 : 'i',
|
||||
Timaginary80 : 'j',
|
||||
Tuns32 : 'k',
|
||||
Tint64 : 'l',
|
||||
Tuns64 : 'm',
|
||||
Tnull : 'n',
|
||||
Timaginary32 : 'o',
|
||||
Timaginary64 : 'p',
|
||||
Tcomplex32 : 'q',
|
||||
Tcomplex64 : 'r',
|
||||
Tint16 : 's',
|
||||
Tuns16 : 't',
|
||||
Twchar : 'u',
|
||||
Tvoid : 'v',
|
||||
Tdchar : 'w',
|
||||
// x // const
|
||||
// y // immutable
|
||||
Tint128 : 'z', // zi
|
||||
Tuns128 : 'z', // zk
|
||||
|
||||
Tarray : 'A',
|
||||
Ttuple : 'B',
|
||||
Tclass : 'C',
|
||||
Tdelegate : 'D',
|
||||
Tenum : 'E',
|
||||
Tfunction : 'F', // D function
|
||||
Tsarray : 'G',
|
||||
Taarray : 'H',
|
||||
// I // in
|
||||
// J // out
|
||||
// K // ref
|
||||
// L // lazy
|
||||
// M // has this, or scope
|
||||
// N // Nh:vector Ng:wild Nn:noreturn
|
||||
// O // shared
|
||||
Tpointer : 'P',
|
||||
// Q // Type/symbol/identifier backward reference
|
||||
Treference : 'R',
|
||||
Tstruct : 'S',
|
||||
// T // Ttypedef
|
||||
// U // C function
|
||||
// W // Windows function
|
||||
// X // variadic T t...)
|
||||
// Y // variadic T t,...)
|
||||
// Z // not variadic, end of parameters
|
||||
|
||||
// '@' shouldn't appear anywhere in the deco'd names
|
||||
Tnone : '@',
|
||||
Tident : '@',
|
||||
Tinstance : '@',
|
||||
Terror : '@',
|
||||
Ttypeof : '@',
|
||||
Tslice : '@',
|
||||
Treturn : '@',
|
||||
Tvector : '@',
|
||||
Ttraits : '@',
|
||||
Tmixin : '@',
|
||||
Ttag : '@',
|
||||
Tnoreturn : '@', // becomes 'Nn'
|
||||
];
|
||||
|
||||
unittest
|
||||
{
|
||||
foreach (i, mangle; mangleChar)
|
||||
{
|
||||
if (mangle == char.init)
|
||||
{
|
||||
fprintf(stderr, "ty = %u\n", cast(uint)i);
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************
|
||||
* Append the mangling of type `t` to `buf`.
|
||||
* Params:
|
||||
|
@ -584,6 +502,20 @@ public:
|
|||
toBuffer(*buf, id.toString(), s);
|
||||
}
|
||||
|
||||
void mangleInteger(dinteger_t v)
|
||||
{
|
||||
if (cast(sinteger_t) v < 0)
|
||||
{
|
||||
buf.writeByte('N');
|
||||
buf.print(-v);
|
||||
}
|
||||
else
|
||||
{
|
||||
buf.writeByte('i');
|
||||
buf.print(v);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
void mangleDecl(Declaration sthis)
|
||||
{
|
||||
|
@ -991,17 +923,7 @@ public:
|
|||
|
||||
override void visit(IntegerExp e)
|
||||
{
|
||||
const v = e.toInteger();
|
||||
if (cast(sinteger_t)v < 0)
|
||||
{
|
||||
buf.writeByte('N');
|
||||
buf.print(-v);
|
||||
}
|
||||
else
|
||||
{
|
||||
buf.writeByte('i');
|
||||
buf.print(v);
|
||||
}
|
||||
mangleInteger(e.toInteger());
|
||||
}
|
||||
|
||||
override void visit(RealExp e)
|
||||
|
@ -1028,6 +950,7 @@ public:
|
|||
char m;
|
||||
OutBuffer tmp;
|
||||
const(char)[] q;
|
||||
|
||||
/* Write string in UTF-8 format
|
||||
*/
|
||||
switch (e.sz)
|
||||
|
@ -1065,7 +988,15 @@ public:
|
|||
q = tmp[];
|
||||
break;
|
||||
}
|
||||
|
||||
case 8:
|
||||
// String of size 8 has to be hexstring cast to long[], mangle as array literal
|
||||
buf.writeByte('A');
|
||||
buf.print(e.len);
|
||||
foreach (i; 0 .. e.len)
|
||||
{
|
||||
mangleInteger(e.getIndex(i));
|
||||
}
|
||||
return;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
@ -1073,14 +1004,7 @@ public:
|
|||
buf.writeByte(m);
|
||||
buf.print(q.length);
|
||||
buf.writeByte('_'); // nbytes <= 11
|
||||
auto slice = buf.allocate(2 * q.length);
|
||||
foreach (i, c; q)
|
||||
{
|
||||
char hi = (c >> 4) & 0xF;
|
||||
slice[i * 2] = cast(char)(hi < 10 ? hi + '0' : hi - 10 + 'a');
|
||||
char lo = c & 0xF;
|
||||
slice[i * 2 + 1] = cast(char)(lo < 10 ? lo + '0' : lo - 10 + 'a');
|
||||
}
|
||||
buf.writeHexString(cast(const(ubyte)[]) q, false);
|
||||
}
|
||||
|
||||
override void visit(ArrayLiteralExp e)
|
||||
|
@ -1168,6 +1092,7 @@ private struct Backref
|
|||
{
|
||||
if (t.isFunction_Delegate_PtrToFunction())
|
||||
{
|
||||
import dmd.typesem : merge2;
|
||||
t = t.merge2();
|
||||
}
|
||||
}
|
||||
|
@ -1213,19 +1138,6 @@ private struct Backref
|
|||
AssocArray!(Identifier, size_t) idents; /// Identifier => (offset+1) in buf
|
||||
}
|
||||
|
||||
|
||||
/***********************
|
||||
* Mangle basic type ty to buf.
|
||||
*/
|
||||
|
||||
private void tyToDecoBuffer(ref OutBuffer buf, int ty) @safe
|
||||
{
|
||||
const c = mangleChar[ty];
|
||||
buf.writeByte(c);
|
||||
if (c == 'z')
|
||||
buf.writeByte(ty == Tint128 ? 'i' : 'k');
|
||||
}
|
||||
|
||||
/*********************************
|
||||
* Mangling for mod.
|
||||
*/
|
||||
|
|
|
@ -490,7 +490,7 @@ extern (C++) final class Module : Package
|
|||
|
||||
extern (D) static const(char)[] find(const(char)[] filename)
|
||||
{
|
||||
return global.fileManager.lookForSourceFile(filename, global.path ? (*global.path)[] : null);
|
||||
return global.fileManager.lookForSourceFile(filename, global.path[]);
|
||||
}
|
||||
|
||||
extern (C++) static Module load(const ref Loc loc, Identifiers* packages, Identifier ident)
|
||||
|
@ -644,9 +644,9 @@ extern (C++) final class Module : Package
|
|||
{
|
||||
/* Print path
|
||||
*/
|
||||
if (global.path)
|
||||
if (global.path.length)
|
||||
{
|
||||
foreach (i, p; *global.path)
|
||||
foreach (i, p; global.path[])
|
||||
fprintf(stderr, "import path[%llu] = %s\n", cast(ulong)i, p);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -5204,6 +5204,7 @@ void highlightCode2(Scope* sc, Dsymbols* a, ref OutBuffer buf, size_t offset)
|
|||
highlight = "$(D_COMMENT ";
|
||||
break;
|
||||
case TOK.string_:
|
||||
case TOK.interpolated:
|
||||
highlight = "$(D_STRING ";
|
||||
break;
|
||||
default:
|
||||
|
@ -5216,7 +5217,7 @@ void highlightCode2(Scope* sc, Dsymbols* a, ref OutBuffer buf, size_t offset)
|
|||
res.writestring(highlight);
|
||||
size_t o = res.length;
|
||||
highlightCode3(sc, res, tok.ptr, lex.p);
|
||||
if (tok.value == TOK.comment || tok.value == TOK.string_)
|
||||
if (tok.value == TOK.comment || tok.value == TOK.string_ || tok.value == TOK.interpolated)
|
||||
/* https://issues.dlang.org/show_bug.cgi?id=7656
|
||||
* https://issues.dlang.org/show_bug.cgi?id=7715
|
||||
* https://issues.dlang.org/show_bug.cgi?id=10519
|
||||
|
|
|
@ -616,7 +616,7 @@ bool _isZeroInit(Expression exp)
|
|||
|
||||
foreach (i; 0 .. se.len)
|
||||
{
|
||||
if (se.getCodeUnit(i))
|
||||
if (se.getIndex(i) != 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -38,11 +38,13 @@ import dmd.dstruct;
|
|||
import dmd.dsymbol;
|
||||
import dmd.dtemplate;
|
||||
import dmd.dversion;
|
||||
import dmd.enumsem;
|
||||
import dmd.errors;
|
||||
import dmd.escape;
|
||||
import dmd.expression;
|
||||
import dmd.expressionsem;
|
||||
import dmd.func;
|
||||
import dmd.funcsem;
|
||||
import dmd.globals;
|
||||
import dmd.id;
|
||||
import dmd.identifier;
|
||||
|
@ -440,6 +442,15 @@ private bool checkDeprecatedAliasThis(AliasThis at, const ref Loc loc, Scope* sc
|
|||
return false;
|
||||
}
|
||||
|
||||
// Save the scope and defer semantic analysis on the Dsymbol.
|
||||
void deferDsymbolSemantic(Scope* sc, Dsymbol s, Scope *scx)
|
||||
{
|
||||
s._scope = scx ? scx : sc.copy();
|
||||
s._scope.setNoFree();
|
||||
Module.addDeferredSemantic(s);
|
||||
}
|
||||
|
||||
|
||||
private extern(C++) final class DsymbolSemanticVisitor : Visitor
|
||||
{
|
||||
alias visit = Visitor.visit;
|
||||
|
@ -450,14 +461,6 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
|
|||
this.sc = sc;
|
||||
}
|
||||
|
||||
// Save the scope and defer semantic analysis on the Dsymbol.
|
||||
private void deferDsymbolSemantic(Dsymbol s, Scope *scx)
|
||||
{
|
||||
s._scope = scx ? scx : sc.copy();
|
||||
s._scope.setNoFree();
|
||||
Module.addDeferredSemantic(s);
|
||||
}
|
||||
|
||||
override void visit(Dsymbol dsym)
|
||||
{
|
||||
.error(dsym.loc, "%s `%s` %p has no semantic routine", dsym.kind, dsym.toPrettyChars, dsym);
|
||||
|
@ -2301,543 +2304,12 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
|
|||
|
||||
override void visit(EnumDeclaration ed)
|
||||
{
|
||||
//printf("EnumDeclaration::semantic(sd = %p, '%s') %s\n", sc.scopesym, sc.scopesym.toChars(), ed.toChars());
|
||||
//printf("EnumDeclaration::semantic() %p %s\n", ed, ed.toChars());
|
||||
if (ed.semanticRun >= PASS.semanticdone)
|
||||
return; // semantic() already completed
|
||||
if (ed.semanticRun == PASS.semantic)
|
||||
{
|
||||
assert(ed.memtype);
|
||||
error(ed.loc, "circular reference to enum base type `%s`", ed.memtype.toChars());
|
||||
ed.errors = true;
|
||||
ed.semanticRun = PASS.semanticdone;
|
||||
return;
|
||||
}
|
||||
Scope* scx = null;
|
||||
if (ed._scope)
|
||||
{
|
||||
sc = ed._scope;
|
||||
scx = ed._scope; // save so we don't make redundant copies
|
||||
ed._scope = null;
|
||||
}
|
||||
|
||||
if (!sc)
|
||||
return;
|
||||
|
||||
ed.parent = sc.parent;
|
||||
ed.type = ed.type.typeSemantic(ed.loc, sc);
|
||||
|
||||
ed.visibility = sc.visibility;
|
||||
if (sc.stc & STC.deprecated_)
|
||||
ed.isdeprecated = true;
|
||||
ed.userAttribDecl = sc.userAttribDecl;
|
||||
ed.cppnamespace = sc.namespace;
|
||||
|
||||
ed.semanticRun = PASS.semantic;
|
||||
UserAttributeDeclaration.checkGNUABITag(ed, sc.linkage);
|
||||
checkMustUseReserved(ed);
|
||||
|
||||
if (!ed.members && !ed.memtype) // enum ident;
|
||||
{
|
||||
ed.semanticRun = PASS.semanticdone;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ed.symtab)
|
||||
ed.symtab = new DsymbolTable();
|
||||
|
||||
/* The separate, and distinct, cases are:
|
||||
* 1. enum { ... }
|
||||
* 2. enum : memtype { ... }
|
||||
* 3. enum ident { ... }
|
||||
* 4. enum ident : memtype { ... }
|
||||
* 5. enum ident : memtype;
|
||||
* 6. enum ident;
|
||||
*/
|
||||
|
||||
if (ed.memtype)
|
||||
{
|
||||
ed.memtype = ed.memtype.typeSemantic(ed.loc, sc);
|
||||
|
||||
/* Check to see if memtype is forward referenced
|
||||
*/
|
||||
if (auto te = ed.memtype.isTypeEnum())
|
||||
{
|
||||
auto sym = te.toDsymbol(sc).isEnumDeclaration();
|
||||
// Special enums like __c_[u]long[long] are fine to forward reference
|
||||
// see https://issues.dlang.org/show_bug.cgi?id=20599
|
||||
if (!sym.isSpecial() && (!sym.memtype || !sym.members || !sym.symtab || sym._scope))
|
||||
{
|
||||
// memtype is forward referenced, so try again later
|
||||
deferDsymbolSemantic(ed, scx);
|
||||
//printf("\tdeferring %s\n", toChars());
|
||||
ed.semanticRun = PASS.initial;
|
||||
return;
|
||||
}
|
||||
else
|
||||
// Ensure that semantic is run to detect. e.g. invalid forward references
|
||||
sym.dsymbolSemantic(sc);
|
||||
}
|
||||
if (ed.memtype.ty == Tvoid)
|
||||
{
|
||||
.error(ed.loc, "%s `%s` base type must not be `void`", ed.kind, ed.toPrettyChars);
|
||||
ed.memtype = Type.terror;
|
||||
}
|
||||
if (ed.memtype.ty == Terror)
|
||||
{
|
||||
ed.errors = true;
|
||||
// poison all the members
|
||||
ed.members.foreachDsymbol( (s) { s.errors = true; } );
|
||||
ed.semanticRun = PASS.semanticdone;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ed.members) // enum ident : memtype;
|
||||
{
|
||||
ed.semanticRun = PASS.semanticdone;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ed.members.length == 0)
|
||||
{
|
||||
.error(ed.loc, "%s `%s enum `%s` must have at least one member", ed.kind, ed.toPrettyChars, ed.toChars());
|
||||
ed.errors = true;
|
||||
ed.semanticRun = PASS.semanticdone;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(sc.flags & SCOPE.Cfile)) // C enum remains incomplete until members are done
|
||||
ed.semanticRun = PASS.semanticdone;
|
||||
|
||||
version (none)
|
||||
{
|
||||
// @@@DEPRECATED_2.110@@@ https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint
|
||||
// Deprecated in 2.100
|
||||
// Make an error in 2.110
|
||||
if (sc.stc & STC.scope_)
|
||||
deprecation(ed.loc, "`scope` as a type constraint is deprecated. Use `scope` at the usage site.");
|
||||
}
|
||||
|
||||
Scope* sce;
|
||||
if (ed.isAnonymous())
|
||||
sce = sc;
|
||||
else
|
||||
{
|
||||
sce = sc.push(ed);
|
||||
sce.parent = ed;
|
||||
}
|
||||
sce = sce.startCTFE();
|
||||
sce.setNoFree(); // needed for getMaxMinValue()
|
||||
|
||||
/* Each enum member gets the sce scope
|
||||
*/
|
||||
ed.members.foreachDsymbol( (s)
|
||||
{
|
||||
EnumMember em = s.isEnumMember();
|
||||
if (em)
|
||||
em._scope = sce;
|
||||
});
|
||||
|
||||
/* addMember() is not called when the EnumDeclaration appears as a function statement,
|
||||
* so we have to do what addMember() does and install the enum members in the right symbol
|
||||
* table
|
||||
*/
|
||||
addEnumMembersToSymtab(ed, sc, sc.getScopesym());
|
||||
|
||||
if (sc.flags & SCOPE.Cfile)
|
||||
{
|
||||
/* C11 6.7.2.2
|
||||
*/
|
||||
Type commonType = ed.memtype;
|
||||
if (!commonType)
|
||||
commonType = Type.tint32;
|
||||
ulong nextValue = 0; // C11 6.7.2.2-3 first member value defaults to 0
|
||||
|
||||
// C11 6.7.2.2-2 value must be representable as an int.
|
||||
// The sizemask represents all values that int will fit into,
|
||||
// from 0..uint.max. We want to cover int.min..uint.max.
|
||||
IntRange ir = IntRange.fromType(commonType);
|
||||
|
||||
void emSemantic(EnumMember em, ref ulong nextValue)
|
||||
{
|
||||
static void errorReturn(EnumMember em)
|
||||
{
|
||||
em.value = ErrorExp.get();
|
||||
em.errors = true;
|
||||
em.semanticRun = PASS.semanticdone;
|
||||
}
|
||||
|
||||
em.semanticRun = PASS.semantic;
|
||||
em.type = commonType;
|
||||
em._linkage = LINK.c;
|
||||
em.storage_class |= STC.manifest;
|
||||
if (em.value)
|
||||
{
|
||||
Expression e = em.value;
|
||||
assert(e.dyncast() == DYNCAST.expression);
|
||||
|
||||
/* To merge the type of e with commonType, add 0 of type commonType
|
||||
*/
|
||||
if (!ed.memtype)
|
||||
e = new AddExp(em.loc, e, new IntegerExp(em.loc, 0, commonType));
|
||||
|
||||
e = e.expressionSemantic(sc);
|
||||
e = resolveProperties(sc, e);
|
||||
e = e.integralPromotions(sc);
|
||||
e = e.ctfeInterpret();
|
||||
if (e.op == EXP.error)
|
||||
return errorReturn(em);
|
||||
auto ie = e.isIntegerExp();
|
||||
if (!ie)
|
||||
{
|
||||
// C11 6.7.2.2-2
|
||||
.error(em.loc, "%s `%s` enum member must be an integral constant expression, not `%s` of type `%s`", em.kind, em.toPrettyChars, e.toChars(), e.type.toChars());
|
||||
return errorReturn(em);
|
||||
}
|
||||
if (ed.memtype && !ir.contains(getIntRange(ie)))
|
||||
{
|
||||
// C11 6.7.2.2-2
|
||||
.error(em.loc, "%s `%s` enum member value `%s` does not fit in `%s`", em.kind, em.toPrettyChars, e.toChars(), commonType.toChars());
|
||||
return errorReturn(em);
|
||||
}
|
||||
nextValue = ie.toInteger();
|
||||
if (!ed.memtype)
|
||||
commonType = e.type;
|
||||
em.value = new IntegerExp(em.loc, nextValue, commonType);
|
||||
}
|
||||
else
|
||||
{
|
||||
// C11 6.7.2.2-3 add 1 to value of previous enumeration constant
|
||||
bool first = (em == (*em.ed.members)[0]);
|
||||
if (!first)
|
||||
{
|
||||
Expression max = getProperty(commonType, null, em.loc, Id.max, 0);
|
||||
if (nextValue == max.toInteger())
|
||||
{
|
||||
.error(em.loc, "%s `%s` initialization with `%s+1` causes overflow for type `%s`", em.kind, em.toPrettyChars, max.toChars(), commonType.toChars());
|
||||
return errorReturn(em);
|
||||
}
|
||||
nextValue += 1;
|
||||
}
|
||||
em.value = new IntegerExp(em.loc, nextValue, commonType);
|
||||
}
|
||||
em.type = commonType;
|
||||
em.semanticRun = PASS.semanticdone;
|
||||
}
|
||||
|
||||
ed.members.foreachDsymbol( (s)
|
||||
{
|
||||
if (EnumMember em = s.isEnumMember())
|
||||
emSemantic(em, nextValue);
|
||||
});
|
||||
|
||||
if (!ed.memtype)
|
||||
{
|
||||
// cast all members to commonType
|
||||
ed.members.foreachDsymbol( (s)
|
||||
{
|
||||
if (EnumMember em = s.isEnumMember())
|
||||
{
|
||||
em.type = commonType;
|
||||
em.value = em.value.castTo(sc, commonType);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ed.memtype = commonType;
|
||||
ed.semanticRun = PASS.semanticdone;
|
||||
return;
|
||||
}
|
||||
|
||||
ed.members.foreachDsymbol( (s)
|
||||
{
|
||||
if (EnumMember em = s.isEnumMember())
|
||||
em.dsymbolSemantic(em._scope);
|
||||
});
|
||||
//printf("defaultval = %lld\n", defaultval);
|
||||
|
||||
//if (defaultval) printf("defaultval: %s %s\n", defaultval.toChars(), defaultval.type.toChars());
|
||||
//printf("members = %s\n", members.toChars());
|
||||
enumSemantic(sc, ed);
|
||||
}
|
||||
|
||||
override void visit(EnumMember em)
|
||||
{
|
||||
//printf("EnumMember::semantic() %s\n", em.toChars());
|
||||
|
||||
void errorReturn()
|
||||
{
|
||||
em.errors = true;
|
||||
em.semanticRun = PASS.semanticdone;
|
||||
}
|
||||
|
||||
if (em.errors || em.semanticRun >= PASS.semanticdone)
|
||||
return;
|
||||
if (em.semanticRun == PASS.semantic)
|
||||
{
|
||||
.error(em.loc, "%s `%s` circular reference to `enum` member", em.kind, em.toPrettyChars);
|
||||
return errorReturn();
|
||||
}
|
||||
assert(em.ed);
|
||||
|
||||
em.ed.dsymbolSemantic(sc);
|
||||
if (em.ed.errors)
|
||||
return errorReturn();
|
||||
if (em.errors || em.semanticRun >= PASS.semanticdone)
|
||||
return;
|
||||
|
||||
if (em._scope)
|
||||
sc = em._scope;
|
||||
if (!sc)
|
||||
return;
|
||||
|
||||
em.semanticRun = PASS.semantic;
|
||||
|
||||
em.visibility = em.ed.isAnonymous() ? em.ed.visibility : Visibility(Visibility.Kind.public_);
|
||||
em._linkage = LINK.d;
|
||||
em.storage_class |= STC.manifest;
|
||||
|
||||
// https://issues.dlang.org/show_bug.cgi?id=9701
|
||||
if (em.ed.isAnonymous())
|
||||
{
|
||||
if (em.userAttribDecl)
|
||||
em.userAttribDecl.userAttribDecl = em.ed.userAttribDecl;
|
||||
else
|
||||
em.userAttribDecl = em.ed.userAttribDecl;
|
||||
}
|
||||
|
||||
// Eval UDA in this same scope. Issues 19344, 20835, 21122
|
||||
if (em.userAttribDecl)
|
||||
{
|
||||
// Set scope but avoid extra sc.uda attachment inside setScope()
|
||||
auto inneruda = em.userAttribDecl.userAttribDecl;
|
||||
em.userAttribDecl.setScope(sc);
|
||||
em.userAttribDecl.userAttribDecl = inneruda;
|
||||
em.userAttribDecl.dsymbolSemantic(sc);
|
||||
}
|
||||
|
||||
// The first enum member is special
|
||||
bool first = (em == (*em.ed.members)[0]);
|
||||
|
||||
if (em.origType)
|
||||
{
|
||||
em.origType = em.origType.typeSemantic(em.loc, sc);
|
||||
em.type = em.origType;
|
||||
assert(em.value); // "type id;" is not a valid enum member declaration
|
||||
}
|
||||
|
||||
if (em.value)
|
||||
{
|
||||
Expression e = em.value;
|
||||
assert(e.dyncast() == DYNCAST.expression);
|
||||
e = e.expressionSemantic(sc);
|
||||
e = resolveProperties(sc, e);
|
||||
e = e.ctfeInterpret();
|
||||
if (e.op == EXP.error)
|
||||
return errorReturn();
|
||||
if (first && !em.ed.memtype && !em.ed.isAnonymous())
|
||||
{
|
||||
em.ed.memtype = e.type;
|
||||
if (em.ed.memtype.ty == Terror)
|
||||
{
|
||||
em.ed.errors = true;
|
||||
return errorReturn();
|
||||
}
|
||||
if (em.ed.memtype.ty != Terror)
|
||||
{
|
||||
/* https://issues.dlang.org/show_bug.cgi?id=11746
|
||||
* All of named enum members should have same type
|
||||
* with the first member. If the following members were referenced
|
||||
* during the first member semantic, their types should be unified.
|
||||
*/
|
||||
em.ed.members.foreachDsymbol( (s)
|
||||
{
|
||||
EnumMember enm = s.isEnumMember();
|
||||
if (!enm || enm == em || enm.semanticRun < PASS.semanticdone || enm.origType)
|
||||
return;
|
||||
|
||||
//printf("[%d] em = %s, em.semanticRun = %d\n", i, toChars(), em.semanticRun);
|
||||
Expression ev = enm.value;
|
||||
ev = ev.implicitCastTo(sc, em.ed.memtype);
|
||||
ev = ev.ctfeInterpret();
|
||||
ev = ev.castTo(sc, em.ed.type);
|
||||
if (ev.op == EXP.error)
|
||||
em.ed.errors = true;
|
||||
enm.value = ev;
|
||||
});
|
||||
|
||||
if (em.ed.errors)
|
||||
{
|
||||
em.ed.memtype = Type.terror;
|
||||
return errorReturn();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (em.ed.memtype && !em.origType)
|
||||
{
|
||||
e = e.implicitCastTo(sc, em.ed.memtype);
|
||||
e = e.ctfeInterpret();
|
||||
|
||||
// save origValue for better json output
|
||||
em.origValue = e;
|
||||
|
||||
if (!em.ed.isAnonymous())
|
||||
{
|
||||
e = e.castTo(sc, em.ed.type.addMod(e.type.mod)); // https://issues.dlang.org/show_bug.cgi?id=12385
|
||||
e = e.ctfeInterpret();
|
||||
}
|
||||
}
|
||||
else if (em.origType)
|
||||
{
|
||||
e = e.implicitCastTo(sc, em.origType);
|
||||
e = e.ctfeInterpret();
|
||||
assert(em.ed.isAnonymous());
|
||||
|
||||
// save origValue for better json output
|
||||
em.origValue = e;
|
||||
}
|
||||
em.value = e;
|
||||
}
|
||||
else if (first)
|
||||
{
|
||||
Type t;
|
||||
if (em.ed.memtype)
|
||||
t = em.ed.memtype;
|
||||
else
|
||||
{
|
||||
t = Type.tint32;
|
||||
if (!em.ed.isAnonymous())
|
||||
em.ed.memtype = t;
|
||||
}
|
||||
const errors = global.startGagging();
|
||||
Expression e = new IntegerExp(em.loc, 0, t);
|
||||
e = e.ctfeInterpret();
|
||||
if (global.endGagging(errors))
|
||||
{
|
||||
error(em.loc, "cannot generate 0 value of type `%s` for `%s`",
|
||||
t.toChars(), em.toChars());
|
||||
}
|
||||
// save origValue for better json output
|
||||
em.origValue = e;
|
||||
|
||||
if (!em.ed.isAnonymous())
|
||||
{
|
||||
e = e.castTo(sc, em.ed.type);
|
||||
e = e.ctfeInterpret();
|
||||
}
|
||||
em.value = e;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Find the previous enum member,
|
||||
* and set this to be the previous value + 1
|
||||
*/
|
||||
EnumMember emprev = null;
|
||||
em.ed.members.foreachDsymbol( (s)
|
||||
{
|
||||
if (auto enm = s.isEnumMember())
|
||||
{
|
||||
if (enm == em)
|
||||
return 1; // found
|
||||
emprev = enm;
|
||||
}
|
||||
return 0; // continue
|
||||
});
|
||||
|
||||
assert(emprev);
|
||||
if (emprev.semanticRun < PASS.semanticdone) // if forward reference
|
||||
emprev.dsymbolSemantic(emprev._scope); // resolve it
|
||||
if (emprev.errors)
|
||||
return errorReturn();
|
||||
|
||||
auto errors = global.startGagging();
|
||||
Expression eprev = emprev.value;
|
||||
assert(eprev);
|
||||
// .toHeadMutable() due to https://issues.dlang.org/show_bug.cgi?id=18645
|
||||
Type tprev = eprev.type.toHeadMutable().equals(em.ed.type.toHeadMutable())
|
||||
? em.ed.memtype
|
||||
: eprev.type;
|
||||
/*
|
||||
https://issues.dlang.org/show_bug.cgi?id=20777
|
||||
Previously this used getProperty, which doesn't consider anything user defined,
|
||||
this construct does do that and thus fixes the bug.
|
||||
*/
|
||||
Expression emax = DotIdExp.create(em.ed.loc, new TypeExp(em.ed.loc, tprev), Id.max);
|
||||
emax = emax.expressionSemantic(sc);
|
||||
emax = emax.ctfeInterpret();
|
||||
|
||||
// check that (eprev != emax)
|
||||
Expression e = new EqualExp(EXP.equal, em.loc, eprev, emax);
|
||||
e = e.expressionSemantic(sc);
|
||||
e = e.ctfeInterpret();
|
||||
if (global.endGagging(errors))
|
||||
{
|
||||
// display an introductory error before showing what actually failed
|
||||
error(em.loc, "cannot check `%s` value for overflow", em.toPrettyChars());
|
||||
// rerun to show errors
|
||||
Expression e2 = DotIdExp.create(em.ed.loc, new TypeExp(em.ed.loc, tprev), Id.max);
|
||||
e2 = e2.expressionSemantic(sc);
|
||||
e2 = e2.ctfeInterpret();
|
||||
e2 = new EqualExp(EXP.equal, em.loc, eprev, e2);
|
||||
e2 = e2.expressionSemantic(sc);
|
||||
e2 = e2.ctfeInterpret();
|
||||
}
|
||||
// now any errors are for generating a value
|
||||
if (e.toInteger())
|
||||
{
|
||||
auto mt = em.ed.memtype;
|
||||
if (!mt)
|
||||
mt = eprev.type;
|
||||
.error(em.loc, "%s `%s` initialization with `%s.%s+1` causes overflow for type `%s`", em.kind, em.toPrettyChars,
|
||||
emprev.ed.toChars(), emprev.toChars(), mt.toChars());
|
||||
return errorReturn();
|
||||
}
|
||||
errors = global.startGagging();
|
||||
// Now set e to (eprev + 1)
|
||||
e = new AddExp(em.loc, eprev, IntegerExp.literal!1);
|
||||
e = e.expressionSemantic(sc);
|
||||
e = e.castTo(sc, eprev.type);
|
||||
e = e.ctfeInterpret();
|
||||
if (global.endGagging(errors))
|
||||
{
|
||||
error(em.loc, "cannot generate value for `%s`", em.toPrettyChars());
|
||||
// rerun to show errors
|
||||
Expression e2 = new AddExp(em.loc, eprev, IntegerExp.literal!1);
|
||||
e2 = e2.expressionSemantic(sc);
|
||||
e2 = e2.castTo(sc, eprev.type);
|
||||
e2 = e2.ctfeInterpret();
|
||||
}
|
||||
// save origValue (without cast) for better json output
|
||||
if (e.op != EXP.error) // avoid duplicate diagnostics
|
||||
{
|
||||
assert(emprev.origValue);
|
||||
em.origValue = new AddExp(em.loc, emprev.origValue, IntegerExp.literal!1);
|
||||
em.origValue = em.origValue.expressionSemantic(sc);
|
||||
em.origValue = em.origValue.ctfeInterpret();
|
||||
}
|
||||
|
||||
if (e.op == EXP.error)
|
||||
return errorReturn();
|
||||
if (e.type.isfloating())
|
||||
{
|
||||
// Check that e != eprev (not always true for floats)
|
||||
Expression etest = new EqualExp(EXP.equal, em.loc, e, eprev);
|
||||
etest = etest.expressionSemantic(sc);
|
||||
etest = etest.ctfeInterpret();
|
||||
if (etest.toInteger())
|
||||
{
|
||||
.error(em.loc, "%s `%s` has inexact value due to loss of precision", em.kind, em.toPrettyChars);
|
||||
return errorReturn();
|
||||
}
|
||||
}
|
||||
em.value = e;
|
||||
}
|
||||
if (!em.origType)
|
||||
em.type = em.value.type;
|
||||
|
||||
assert(em.origValue);
|
||||
em.semanticRun = PASS.semanticdone;
|
||||
enumMemberSemantic(sc, em);
|
||||
}
|
||||
|
||||
override void visit(TemplateDeclaration tempdecl)
|
||||
|
@ -3026,7 +2498,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
|
|||
if (tm.semanticRun == PASS.initial) // forward reference had occurred
|
||||
{
|
||||
//printf("forward reference - deferring\n");
|
||||
return deferDsymbolSemantic(tm, scx);
|
||||
return deferDsymbolSemantic(sc, tm, scx);
|
||||
}
|
||||
|
||||
tm.inst = tm;
|
||||
|
@ -3740,7 +3212,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
|
|||
continue;
|
||||
if (cbd.parent && cbd.parent.isTemplateInstance())
|
||||
{
|
||||
if (!f2.functionSemantic())
|
||||
if (!functionSemantic(f2))
|
||||
goto Ldone;
|
||||
}
|
||||
may_override = true;
|
||||
|
@ -4945,7 +4417,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
|
|||
sc2.pop();
|
||||
|
||||
if (log) printf("\tdeferring %s\n", sd.toChars());
|
||||
return deferDsymbolSemantic(sd, scx);
|
||||
return deferDsymbolSemantic(sc, sd, scx);
|
||||
}
|
||||
|
||||
/* Look for special member functions.
|
||||
|
@ -5336,7 +4808,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
|
|||
{
|
||||
// Forward referencee of one or more bases, try again later
|
||||
//printf("\tL%d semantic('%s') failed due to forward references\n", __LINE__, toChars());
|
||||
return deferDsymbolSemantic(cldec, scx);
|
||||
return deferDsymbolSemantic(sc, cldec, scx);
|
||||
}
|
||||
cldec.baseok = Baseok.done;
|
||||
|
||||
|
@ -5446,7 +4918,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
|
|||
if (tc.sym._scope)
|
||||
Module.addDeferredSemantic(tc.sym);
|
||||
//printf("\tL%d semantic('%s') failed due to forward references\n", __LINE__, toChars());
|
||||
return deferDsymbolSemantic(cldec, scx);
|
||||
return deferDsymbolSemantic(sc, cldec, scx);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5563,7 +5035,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
|
|||
sc2.pop();
|
||||
|
||||
//printf("\tdeferring %s\n", toChars());
|
||||
return deferDsymbolSemantic(cldec, scx);
|
||||
return deferDsymbolSemantic(sc, cldec, scx);
|
||||
}
|
||||
|
||||
/* Look for special member functions.
|
||||
|
@ -5905,7 +5377,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
|
|||
if (idec.baseok == Baseok.none)
|
||||
{
|
||||
// Forward referencee of one or more bases, try again later
|
||||
return deferDsymbolSemantic(idec, scx);
|
||||
return deferDsymbolSemantic(sc, idec, scx);
|
||||
}
|
||||
idec.baseok = Baseok.done;
|
||||
|
||||
|
@ -5942,7 +5414,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
|
|||
// Forward referencee of one or more bases, try again later
|
||||
if (tc.sym._scope)
|
||||
Module.addDeferredSemantic(tc.sym);
|
||||
return deferDsymbolSemantic(idec, scx);
|
||||
return deferDsymbolSemantic(sc, idec, scx);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6281,7 +5753,7 @@ private extern(C++) class AddMemberVisitor : Visitor
|
|||
}
|
||||
else
|
||||
{
|
||||
if (findCondition(m.debugidsNot, ds.ident))
|
||||
if (m.debugidsNot && findCondition(*m.debugidsNot, ds.ident))
|
||||
{
|
||||
.error(ds.loc, "%s `%s` defined after use", ds.kind, ds.toPrettyChars);
|
||||
ds.errors = true;
|
||||
|
@ -6319,7 +5791,7 @@ private extern(C++) class AddMemberVisitor : Visitor
|
|||
}
|
||||
else
|
||||
{
|
||||
if (findCondition(m.versionidsNot, vs.ident))
|
||||
if (m.versionidsNot && findCondition(*m.versionidsNot, vs.ident))
|
||||
{
|
||||
.error(vs.loc, "%s `%s` defined after use", vs.kind, vs.toPrettyChars);
|
||||
vs.errors = true;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -52,8 +52,6 @@ public:
|
|||
bool isDeprecated() const override; // is Dsymbol deprecated?
|
||||
Visibility visible() override;
|
||||
bool isSpecial() const;
|
||||
Expression *getDefaultValue(const Loc &loc);
|
||||
Type *getMemtype(const Loc &loc);
|
||||
|
||||
EnumDeclaration *isEnumDeclaration() override { return this; }
|
||||
|
||||
|
|
714
gcc/d/dmd/enumsem.d
Normal file
714
gcc/d/dmd/enumsem.d
Normal file
|
@ -0,0 +1,714 @@
|
|||
/**
|
||||
* Does the semantic passes on enums.
|
||||
*
|
||||
* Copyright: Copyright (C) 1999-2024 by The D Language Foundation, All Rights Reserved
|
||||
* Authors: $(LINK2 https://www.digitalmars.com, Walter Bright)
|
||||
* License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
|
||||
* Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/enumsem.d, _enumsem.d)
|
||||
* Documentation: https://dlang.org/phobos/dmd_enumsem.html
|
||||
* Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/enumsem.d
|
||||
*/
|
||||
|
||||
module dmd.enumsem;
|
||||
|
||||
import core.stdc.stdio;
|
||||
import core.stdc.string;
|
||||
|
||||
import dmd.aggregate;
|
||||
import dmd.aliasthis;
|
||||
import dmd.arraytypes;
|
||||
import dmd.astcodegen;
|
||||
import dmd.astenums;
|
||||
import dmd.attrib;
|
||||
import dmd.blockexit;
|
||||
import dmd.clone;
|
||||
import dmd.cond;
|
||||
import dmd.compiler;
|
||||
import dmd.dcast;
|
||||
import dmd.dclass;
|
||||
import dmd.declaration;
|
||||
import dmd.denum;
|
||||
import dmd.dimport;
|
||||
import dmd.dinterpret;
|
||||
import dmd.dmangle;
|
||||
import dmd.dmodule;
|
||||
import dmd.dscope;
|
||||
import dmd.dstruct;
|
||||
import dmd.dsymbol;
|
||||
import dmd.dsymbolsem;
|
||||
import dmd.dtemplate;
|
||||
import dmd.dversion;
|
||||
import dmd.errors;
|
||||
import dmd.escape;
|
||||
import dmd.expression;
|
||||
import dmd.expressionsem;
|
||||
import dmd.func;
|
||||
import dmd.funcsem;
|
||||
import dmd.globals;
|
||||
import dmd.id;
|
||||
import dmd.identifier;
|
||||
import dmd.importc;
|
||||
import dmd.init;
|
||||
import dmd.initsem;
|
||||
import dmd.intrange;
|
||||
import dmd.hdrgen;
|
||||
import dmd.location;
|
||||
import dmd.mtype;
|
||||
import dmd.mustuse;
|
||||
import dmd.nogc;
|
||||
import dmd.nspace;
|
||||
import dmd.objc;
|
||||
import dmd.opover;
|
||||
import dmd.optimize;
|
||||
import dmd.parse;
|
||||
import dmd.root.array;
|
||||
import dmd.root.filename;
|
||||
import dmd.common.outbuffer;
|
||||
import dmd.root.rmem;
|
||||
import dmd.rootobject;
|
||||
import dmd.root.utf;
|
||||
import dmd.semantic2;
|
||||
import dmd.semantic3;
|
||||
import dmd.sideeffect;
|
||||
import dmd.statementsem;
|
||||
import dmd.staticassert;
|
||||
import dmd.tokens;
|
||||
import dmd.utils;
|
||||
import dmd.statement;
|
||||
import dmd.target;
|
||||
import dmd.templateparamsem;
|
||||
import dmd.typesem;
|
||||
import dmd.visitor;
|
||||
|
||||
|
||||
/*********************************
|
||||
* Perform semantic analysis on enum declaration `em`
|
||||
*/
|
||||
void enumSemantic(Scope* sc, EnumDeclaration ed)
|
||||
{
|
||||
//printf("EnumDeclaration::semantic(sd = %p, '%s') %s\n", sc.scopesym, sc.scopesym.toChars(), ed.toChars());
|
||||
//printf("EnumDeclaration::semantic() %p %s\n", ed, ed.toChars());
|
||||
if (ed.semanticRun >= PASS.semanticdone)
|
||||
return; // semantic() already completed
|
||||
if (ed.semanticRun == PASS.semantic)
|
||||
{
|
||||
assert(ed.memtype);
|
||||
error(ed.loc, "circular reference to enum base type `%s`", ed.memtype.toChars());
|
||||
ed.errors = true;
|
||||
ed.semanticRun = PASS.semanticdone;
|
||||
return;
|
||||
}
|
||||
Scope* scx = null;
|
||||
if (ed._scope)
|
||||
{
|
||||
sc = ed._scope;
|
||||
scx = ed._scope; // save so we don't make redundant copies
|
||||
ed._scope = null;
|
||||
}
|
||||
|
||||
if (!sc)
|
||||
return;
|
||||
|
||||
ed.parent = sc.parent;
|
||||
ed.type = ed.type.typeSemantic(ed.loc, sc);
|
||||
|
||||
ed.visibility = sc.visibility;
|
||||
if (sc.stc & STC.deprecated_)
|
||||
ed.isdeprecated = true;
|
||||
ed.userAttribDecl = sc.userAttribDecl;
|
||||
ed.cppnamespace = sc.namespace;
|
||||
|
||||
ed.semanticRun = PASS.semantic;
|
||||
UserAttributeDeclaration.checkGNUABITag(ed, sc.linkage);
|
||||
checkMustUseReserved(ed);
|
||||
|
||||
if (!ed.members && !ed.memtype) // enum ident;
|
||||
{
|
||||
ed.semanticRun = PASS.semanticdone;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ed.symtab)
|
||||
ed.symtab = new DsymbolTable();
|
||||
|
||||
/* The separate, and distinct, cases are:
|
||||
* 1. enum { ... }
|
||||
* 2. enum : memtype { ... }
|
||||
* 3. enum ident { ... }
|
||||
* 4. enum ident : memtype { ... }
|
||||
* 5. enum ident : memtype;
|
||||
* 6. enum ident;
|
||||
*/
|
||||
|
||||
if (ed.memtype)
|
||||
{
|
||||
ed.memtype = ed.memtype.typeSemantic(ed.loc, sc);
|
||||
|
||||
/* Check to see if memtype is forward referenced
|
||||
*/
|
||||
if (auto te = ed.memtype.isTypeEnum())
|
||||
{
|
||||
auto sym = te.toDsymbol(sc).isEnumDeclaration();
|
||||
// Special enums like __c_[u]long[long] are fine to forward reference
|
||||
// see https://issues.dlang.org/show_bug.cgi?id=20599
|
||||
if (!sym.isSpecial() && (!sym.memtype || !sym.members || !sym.symtab || sym._scope))
|
||||
{
|
||||
// memtype is forward referenced, so try again later
|
||||
deferDsymbolSemantic(sc, ed, scx);
|
||||
//printf("\tdeferring %s\n", toChars());
|
||||
ed.semanticRun = PASS.initial;
|
||||
return;
|
||||
}
|
||||
else
|
||||
// Ensure that semantic is run to detect. e.g. invalid forward references
|
||||
sym.dsymbolSemantic(sc);
|
||||
}
|
||||
if (ed.memtype.ty == Tvoid)
|
||||
{
|
||||
.error(ed.loc, "%s `%s` base type must not be `void`", ed.kind, ed.toPrettyChars);
|
||||
ed.memtype = Type.terror;
|
||||
}
|
||||
if (ed.memtype.ty == Terror)
|
||||
{
|
||||
ed.errors = true;
|
||||
// poison all the members
|
||||
ed.members.foreachDsymbol( (s) { s.errors = true; } );
|
||||
ed.semanticRun = PASS.semanticdone;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ed.members) // enum ident : memtype;
|
||||
{
|
||||
ed.semanticRun = PASS.semanticdone;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ed.members.length == 0)
|
||||
{
|
||||
.error(ed.loc, "%s `%s enum `%s` must have at least one member", ed.kind, ed.toPrettyChars, ed.toChars());
|
||||
ed.errors = true;
|
||||
ed.semanticRun = PASS.semanticdone;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(sc.flags & SCOPE.Cfile)) // C enum remains incomplete until members are done
|
||||
ed.semanticRun = PASS.semanticdone;
|
||||
|
||||
version (none)
|
||||
{
|
||||
// @@@DEPRECATED_2.110@@@ https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint
|
||||
// Deprecated in 2.100
|
||||
// Make an error in 2.110
|
||||
if (sc.stc & STC.scope_)
|
||||
deprecation(ed.loc, "`scope` as a type constraint is deprecated. Use `scope` at the usage site.");
|
||||
}
|
||||
|
||||
Scope* sce;
|
||||
if (ed.isAnonymous())
|
||||
sce = sc;
|
||||
else
|
||||
{
|
||||
sce = sc.push(ed);
|
||||
sce.parent = ed;
|
||||
}
|
||||
sce = sce.startCTFE();
|
||||
sce.setNoFree(); // needed for getMaxMinValue()
|
||||
|
||||
/* Each enum member gets the sce scope
|
||||
*/
|
||||
ed.members.foreachDsymbol( (s)
|
||||
{
|
||||
EnumMember em = s.isEnumMember();
|
||||
if (em)
|
||||
em._scope = sce;
|
||||
});
|
||||
|
||||
/* addMember() is not called when the EnumDeclaration appears as a function statement,
|
||||
* so we have to do what addMember() does and install the enum members in the right symbol
|
||||
* table
|
||||
*/
|
||||
addEnumMembersToSymtab(ed, sc, sc.getScopesym());
|
||||
|
||||
if (sc.flags & SCOPE.Cfile)
|
||||
{
|
||||
/* C11 6.7.2.2
|
||||
*/
|
||||
Type commonType = ed.memtype;
|
||||
if (!commonType)
|
||||
commonType = Type.tint32;
|
||||
ulong nextValue = 0; // C11 6.7.2.2-3 first member value defaults to 0
|
||||
|
||||
// C11 6.7.2.2-2 value must be representable as an int.
|
||||
// The sizemask represents all values that int will fit into,
|
||||
// from 0..uint.max. We want to cover int.min..uint.max.
|
||||
IntRange ir = IntRange.fromType(commonType);
|
||||
|
||||
void emSemantic(EnumMember em, ref ulong nextValue)
|
||||
{
|
||||
static void errorReturn(EnumMember em)
|
||||
{
|
||||
em.value = ErrorExp.get();
|
||||
em.errors = true;
|
||||
em.semanticRun = PASS.semanticdone;
|
||||
}
|
||||
|
||||
em.semanticRun = PASS.semantic;
|
||||
em.type = commonType;
|
||||
em._linkage = LINK.c;
|
||||
em.storage_class |= STC.manifest;
|
||||
if (em.value)
|
||||
{
|
||||
Expression e = em.value;
|
||||
assert(e.dyncast() == DYNCAST.expression);
|
||||
|
||||
/* To merge the type of e with commonType, add 0 of type commonType
|
||||
*/
|
||||
if (!ed.memtype)
|
||||
e = new AddExp(em.loc, e, new IntegerExp(em.loc, 0, commonType));
|
||||
|
||||
e = e.expressionSemantic(sc);
|
||||
e = resolveProperties(sc, e);
|
||||
e = e.integralPromotions(sc);
|
||||
e = e.ctfeInterpret();
|
||||
if (e.op == EXP.error)
|
||||
return errorReturn(em);
|
||||
auto ie = e.isIntegerExp();
|
||||
if (!ie)
|
||||
{
|
||||
// C11 6.7.2.2-2
|
||||
.error(em.loc, "%s `%s` enum member must be an integral constant expression, not `%s` of type `%s`", em.kind, em.toPrettyChars, e.toChars(), e.type.toChars());
|
||||
return errorReturn(em);
|
||||
}
|
||||
if (ed.memtype && !ir.contains(getIntRange(ie)))
|
||||
{
|
||||
// C11 6.7.2.2-2
|
||||
.error(em.loc, "%s `%s` enum member value `%s` does not fit in `%s`", em.kind, em.toPrettyChars, e.toChars(), commonType.toChars());
|
||||
return errorReturn(em);
|
||||
}
|
||||
nextValue = ie.toInteger();
|
||||
if (!ed.memtype)
|
||||
commonType = e.type;
|
||||
em.value = new IntegerExp(em.loc, nextValue, commonType);
|
||||
}
|
||||
else
|
||||
{
|
||||
// C11 6.7.2.2-3 add 1 to value of previous enumeration constant
|
||||
bool first = (em == (*em.ed.members)[0]);
|
||||
if (!first)
|
||||
{
|
||||
Expression max = getProperty(commonType, null, em.loc, Id.max, 0);
|
||||
if (nextValue == max.toInteger())
|
||||
{
|
||||
.error(em.loc, "%s `%s` initialization with `%s+1` causes overflow for type `%s`", em.kind, em.toPrettyChars, max.toChars(), commonType.toChars());
|
||||
return errorReturn(em);
|
||||
}
|
||||
nextValue += 1;
|
||||
}
|
||||
em.value = new IntegerExp(em.loc, nextValue, commonType);
|
||||
}
|
||||
em.type = commonType;
|
||||
em.semanticRun = PASS.semanticdone;
|
||||
}
|
||||
|
||||
ed.members.foreachDsymbol( (s)
|
||||
{
|
||||
if (EnumMember em = s.isEnumMember())
|
||||
emSemantic(em, nextValue);
|
||||
});
|
||||
|
||||
if (!ed.memtype)
|
||||
{
|
||||
// cast all members to commonType
|
||||
ed.members.foreachDsymbol( (s)
|
||||
{
|
||||
if (EnumMember em = s.isEnumMember())
|
||||
{
|
||||
em.type = commonType;
|
||||
em.value = em.value.castTo(sc, commonType);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ed.memtype = commonType;
|
||||
ed.semanticRun = PASS.semanticdone;
|
||||
return;
|
||||
}
|
||||
|
||||
ed.members.foreachDsymbol( (s)
|
||||
{
|
||||
if (EnumMember em = s.isEnumMember())
|
||||
em.dsymbolSemantic(em._scope);
|
||||
});
|
||||
//printf("ed.defaultval = %lld\n", ed.defaultval);
|
||||
|
||||
//if (ed.defaultval) printf("ed.defaultval: %s %s\n", ed.defaultval.toChars(), ed.defaultval.type.toChars());
|
||||
//printf("members = %s\n", members.toChars());
|
||||
}
|
||||
|
||||
Expression getDefaultValue(EnumDeclaration ed, const ref Loc loc)
|
||||
{
|
||||
Expression handleErrors(){
|
||||
ed.defaultval = ErrorExp.get();
|
||||
return ed.defaultval;
|
||||
}
|
||||
//printf("EnumDeclaration::getDefaultValue() %p %s\n", this, toChars());
|
||||
// https://issues.dlang.org/show_bug.cgi?id=23904
|
||||
// Return ed.defaultval only if it is not ErrorExp.
|
||||
// A speculative context may set ed.defaultval to ErrorExp;
|
||||
// subsequent non-speculative contexts need to be able
|
||||
// to print the error.
|
||||
if (ed.defaultval && !ed.defaultval.isErrorExp())
|
||||
return ed.defaultval;
|
||||
|
||||
if (ed.isCsymbol())
|
||||
return ed.memtype.defaultInit(loc, true);
|
||||
|
||||
if (ed._scope)
|
||||
dsymbolSemantic(ed, ed._scope);
|
||||
if (ed.errors)
|
||||
return handleErrors();
|
||||
if (!ed.members)
|
||||
{
|
||||
if (ed.isSpecial())
|
||||
{
|
||||
/* Allow these special enums to not need a member list
|
||||
*/
|
||||
return ed.defaultval = ed.memtype.defaultInit(loc);
|
||||
}
|
||||
|
||||
error(loc, "%s `%s` is opaque and has no default initializer", ed.kind, ed.toPrettyChars);
|
||||
return handleErrors();
|
||||
}
|
||||
|
||||
foreach (const i; 0 .. ed.members.length)
|
||||
{
|
||||
EnumMember em = (*ed.members)[i].isEnumMember();
|
||||
if (em)
|
||||
{
|
||||
if (em.semanticRun < PASS.semanticdone)
|
||||
{
|
||||
error(loc, "%s `%s` forward reference of `%s.init`", ed.kind, ed.toPrettyChars, ed.toChars());
|
||||
return handleErrors();
|
||||
}
|
||||
|
||||
ed.defaultval = em.value;
|
||||
return ed.defaultval;
|
||||
}
|
||||
}
|
||||
return handleErrors();
|
||||
}
|
||||
|
||||
Type getMemtype(EnumDeclaration ed, const ref Loc loc)
|
||||
{
|
||||
if (ed._scope)
|
||||
{
|
||||
/* Enum is forward referenced. We don't need to resolve the whole thing,
|
||||
* just the base type
|
||||
*/
|
||||
if (ed.memtype)
|
||||
{
|
||||
Loc locx = loc.isValid() ? loc : ed.loc;
|
||||
ed.memtype = ed.memtype.typeSemantic(locx, ed._scope);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Run semantic to get the type from a possible first member value
|
||||
dsymbolSemantic(ed, ed._scope);
|
||||
}
|
||||
}
|
||||
if (!ed.memtype)
|
||||
{
|
||||
if (!ed.isAnonymous() && (ed.members || ed.semanticRun >= PASS.semanticdone))
|
||||
ed.memtype = Type.tint32;
|
||||
else
|
||||
{
|
||||
Loc locx = loc.isValid() ? loc : ed.loc;
|
||||
error(locx, "is forward referenced looking for base type");
|
||||
return Type.terror;
|
||||
}
|
||||
}
|
||||
return ed.memtype;
|
||||
}
|
||||
|
||||
/*********************************
|
||||
* Perform semantic analysis on enum member `em`
|
||||
*/
|
||||
void enumMemberSemantic(Scope* sc, EnumMember em)
|
||||
{
|
||||
//printf("EnumMember::semantic() %s\n", em.toChars());
|
||||
|
||||
void errorReturn()
|
||||
{
|
||||
em.errors = true;
|
||||
em.semanticRun = PASS.semanticdone;
|
||||
}
|
||||
|
||||
if (em.errors || em.semanticRun >= PASS.semanticdone)
|
||||
return;
|
||||
if (em.semanticRun == PASS.semantic)
|
||||
{
|
||||
.error(em.loc, "%s `%s` circular reference to `enum` member", em.kind, em.toPrettyChars);
|
||||
return errorReturn();
|
||||
}
|
||||
assert(em.ed);
|
||||
|
||||
em.ed.dsymbolSemantic(sc);
|
||||
if (em.ed.errors)
|
||||
return errorReturn();
|
||||
if (em.errors || em.semanticRun >= PASS.semanticdone)
|
||||
return;
|
||||
|
||||
if (em._scope)
|
||||
sc = em._scope;
|
||||
if (!sc)
|
||||
return;
|
||||
|
||||
em.semanticRun = PASS.semantic;
|
||||
|
||||
em.visibility = em.ed.isAnonymous() ? em.ed.visibility : Visibility(Visibility.Kind.public_);
|
||||
em._linkage = LINK.d;
|
||||
em.storage_class |= STC.manifest;
|
||||
|
||||
// https://issues.dlang.org/show_bug.cgi?id=9701
|
||||
if (em.ed.isAnonymous())
|
||||
{
|
||||
if (em.userAttribDecl)
|
||||
em.userAttribDecl.userAttribDecl = em.ed.userAttribDecl;
|
||||
else
|
||||
em.userAttribDecl = em.ed.userAttribDecl;
|
||||
}
|
||||
|
||||
// Eval UDA in this same scope. Issues 19344, 20835, 21122
|
||||
if (em.userAttribDecl)
|
||||
{
|
||||
// Set scope but avoid extra sc.uda attachment inside setScope()
|
||||
auto inneruda = em.userAttribDecl.userAttribDecl;
|
||||
em.userAttribDecl.setScope(sc);
|
||||
em.userAttribDecl.userAttribDecl = inneruda;
|
||||
em.userAttribDecl.dsymbolSemantic(sc);
|
||||
}
|
||||
|
||||
// The first enum member is special
|
||||
bool first = (em == (*em.ed.members)[0]);
|
||||
|
||||
if (em.origType)
|
||||
{
|
||||
em.origType = em.origType.typeSemantic(em.loc, sc);
|
||||
em.type = em.origType;
|
||||
assert(em.value); // "type id;" is not a valid enum member declaration
|
||||
}
|
||||
|
||||
if (em.value)
|
||||
{
|
||||
Expression e = em.value;
|
||||
assert(e.dyncast() == DYNCAST.expression);
|
||||
e = e.expressionSemantic(sc);
|
||||
e = resolveProperties(sc, e);
|
||||
e = e.ctfeInterpret();
|
||||
if (e.op == EXP.error)
|
||||
return errorReturn();
|
||||
if (first && !em.ed.memtype && !em.ed.isAnonymous())
|
||||
{
|
||||
em.ed.memtype = e.type;
|
||||
if (em.ed.memtype.ty == Terror)
|
||||
{
|
||||
em.ed.errors = true;
|
||||
return errorReturn();
|
||||
}
|
||||
if (em.ed.memtype.ty != Terror)
|
||||
{
|
||||
/* https://issues.dlang.org/show_bug.cgi?id=11746
|
||||
* All of named enum members should have same type
|
||||
* with the first member. If the following members were referenced
|
||||
* during the first member semantic, their types should be unified.
|
||||
*/
|
||||
em.ed.members.foreachDsymbol( (s)
|
||||
{
|
||||
EnumMember enm = s.isEnumMember();
|
||||
if (!enm || enm == em || enm.semanticRun < PASS.semanticdone || enm.origType)
|
||||
return;
|
||||
|
||||
//printf("[%d] em = %s, em.semanticRun = %d\n", i, toChars(), em.semanticRun);
|
||||
Expression ev = enm.value;
|
||||
ev = ev.implicitCastTo(sc, em.ed.memtype);
|
||||
ev = ev.ctfeInterpret();
|
||||
ev = ev.castTo(sc, em.ed.type);
|
||||
if (ev.op == EXP.error)
|
||||
em.ed.errors = true;
|
||||
enm.value = ev;
|
||||
});
|
||||
|
||||
if (em.ed.errors)
|
||||
{
|
||||
em.ed.memtype = Type.terror;
|
||||
return errorReturn();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (em.ed.memtype && !em.origType)
|
||||
{
|
||||
e = e.implicitCastTo(sc, em.ed.memtype);
|
||||
e = e.ctfeInterpret();
|
||||
|
||||
// save origValue for better json output
|
||||
em.origValue = e;
|
||||
|
||||
if (!em.ed.isAnonymous())
|
||||
{
|
||||
e = e.castTo(sc, em.ed.type.addMod(e.type.mod)); // https://issues.dlang.org/show_bug.cgi?id=12385
|
||||
e = e.ctfeInterpret();
|
||||
}
|
||||
}
|
||||
else if (em.origType)
|
||||
{
|
||||
e = e.implicitCastTo(sc, em.origType);
|
||||
e = e.ctfeInterpret();
|
||||
assert(em.ed.isAnonymous());
|
||||
|
||||
// save origValue for better json output
|
||||
em.origValue = e;
|
||||
}
|
||||
em.value = e;
|
||||
}
|
||||
else if (first)
|
||||
{
|
||||
Type t;
|
||||
if (em.ed.memtype)
|
||||
t = em.ed.memtype;
|
||||
else
|
||||
{
|
||||
t = Type.tint32;
|
||||
if (!em.ed.isAnonymous())
|
||||
em.ed.memtype = t;
|
||||
}
|
||||
const errors = global.startGagging();
|
||||
Expression e = new IntegerExp(em.loc, 0, t);
|
||||
e = e.ctfeInterpret();
|
||||
if (global.endGagging(errors))
|
||||
{
|
||||
error(em.loc, "cannot generate 0 value of type `%s` for `%s`",
|
||||
t.toChars(), em.toChars());
|
||||
}
|
||||
// save origValue for better json output
|
||||
em.origValue = e;
|
||||
|
||||
if (!em.ed.isAnonymous())
|
||||
{
|
||||
e = e.castTo(sc, em.ed.type);
|
||||
e = e.ctfeInterpret();
|
||||
}
|
||||
em.value = e;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Find the previous enum member,
|
||||
* and set this to be the previous value + 1
|
||||
*/
|
||||
EnumMember emprev = null;
|
||||
em.ed.members.foreachDsymbol( (s)
|
||||
{
|
||||
if (auto enm = s.isEnumMember())
|
||||
{
|
||||
if (enm == em)
|
||||
return 1; // found
|
||||
emprev = enm;
|
||||
}
|
||||
return 0; // continue
|
||||
});
|
||||
|
||||
assert(emprev);
|
||||
if (emprev.semanticRun < PASS.semanticdone) // if forward reference
|
||||
emprev.dsymbolSemantic(emprev._scope); // resolve it
|
||||
if (emprev.errors)
|
||||
return errorReturn();
|
||||
|
||||
auto errors = global.startGagging();
|
||||
Expression eprev = emprev.value;
|
||||
assert(eprev);
|
||||
// .toHeadMutable() due to https://issues.dlang.org/show_bug.cgi?id=18645
|
||||
Type tprev = eprev.type.toHeadMutable().equals(em.ed.type.toHeadMutable())
|
||||
? em.ed.memtype
|
||||
: eprev.type;
|
||||
/*
|
||||
https://issues.dlang.org/show_bug.cgi?id=20777
|
||||
Previously this used getProperty, which doesn't consider anything user defined,
|
||||
this construct does do that and thus fixes the bug.
|
||||
*/
|
||||
Expression emax = DotIdExp.create(em.ed.loc, new TypeExp(em.ed.loc, tprev), Id.max);
|
||||
emax = emax.expressionSemantic(sc);
|
||||
emax = emax.ctfeInterpret();
|
||||
|
||||
// check that (eprev != emax)
|
||||
Expression e = new EqualExp(EXP.equal, em.loc, eprev, emax);
|
||||
e = e.expressionSemantic(sc);
|
||||
e = e.ctfeInterpret();
|
||||
if (global.endGagging(errors))
|
||||
{
|
||||
// display an introductory error before showing what actually failed
|
||||
error(em.loc, "cannot check `%s` value for overflow", em.toPrettyChars());
|
||||
// rerun to show errors
|
||||
Expression e2 = DotIdExp.create(em.ed.loc, new TypeExp(em.ed.loc, tprev), Id.max);
|
||||
e2 = e2.expressionSemantic(sc);
|
||||
e2 = e2.ctfeInterpret();
|
||||
e2 = new EqualExp(EXP.equal, em.loc, eprev, e2);
|
||||
e2 = e2.expressionSemantic(sc);
|
||||
e2 = e2.ctfeInterpret();
|
||||
}
|
||||
// now any errors are for generating a value
|
||||
if (e.toInteger())
|
||||
{
|
||||
auto mt = em.ed.memtype;
|
||||
if (!mt)
|
||||
mt = eprev.type;
|
||||
.error(em.loc, "%s `%s` initialization with `%s.%s+1` causes overflow for type `%s`", em.kind, em.toPrettyChars,
|
||||
emprev.ed.toChars(), emprev.toChars(), mt.toChars());
|
||||
return errorReturn();
|
||||
}
|
||||
errors = global.startGagging();
|
||||
// Now set e to (eprev + 1)
|
||||
e = new AddExp(em.loc, eprev, IntegerExp.literal!1);
|
||||
e = e.expressionSemantic(sc);
|
||||
e = e.castTo(sc, eprev.type);
|
||||
e = e.ctfeInterpret();
|
||||
if (global.endGagging(errors))
|
||||
{
|
||||
error(em.loc, "cannot generate value for `%s`", em.toPrettyChars());
|
||||
// rerun to show errors
|
||||
Expression e2 = new AddExp(em.loc, eprev, IntegerExp.literal!1);
|
||||
e2 = e2.expressionSemantic(sc);
|
||||
e2 = e2.castTo(sc, eprev.type);
|
||||
e2 = e2.ctfeInterpret();
|
||||
}
|
||||
// save origValue (without cast) for better json output
|
||||
if (e.op != EXP.error) // avoid duplicate diagnostics
|
||||
{
|
||||
assert(emprev.origValue);
|
||||
em.origValue = new AddExp(em.loc, emprev.origValue, IntegerExp.literal!1);
|
||||
em.origValue = em.origValue.expressionSemantic(sc);
|
||||
em.origValue = em.origValue.ctfeInterpret();
|
||||
}
|
||||
|
||||
if (e.op == EXP.error)
|
||||
return errorReturn();
|
||||
if (e.type.isfloating())
|
||||
{
|
||||
// Check that e != eprev (not always true for floats)
|
||||
Expression etest = new EqualExp(EXP.equal, em.loc, e, eprev);
|
||||
etest = etest.expressionSemantic(sc);
|
||||
etest = etest.ctfeInterpret();
|
||||
if (etest.toInteger())
|
||||
{
|
||||
.error(em.loc, "%s `%s` has inexact value due to loss of precision", em.kind, em.toPrettyChars);
|
||||
return errorReturn();
|
||||
}
|
||||
}
|
||||
em.value = e;
|
||||
}
|
||||
if (!em.origType)
|
||||
em.type = em.value.type;
|
||||
|
||||
assert(em.origValue);
|
||||
em.semanticRun = PASS.semanticdone;
|
||||
}
|
|
@ -721,6 +721,7 @@ extern (C++) abstract class Expression : ASTNode
|
|||
inout(SuperExp) isSuperExp() { return op == EXP.super_ ? cast(typeof(return))this : null; }
|
||||
inout(NullExp) isNullExp() { return op == EXP.null_ ? cast(typeof(return))this : null; }
|
||||
inout(StringExp) isStringExp() { return op == EXP.string_ ? cast(typeof(return))this : null; }
|
||||
inout(InterpExp) isInterpExp() { return op == EXP.interpolated ? cast(typeof(return))this : null; }
|
||||
inout(TupleExp) isTupleExp() { return op == EXP.tuple ? cast(typeof(return))this : null; }
|
||||
inout(ArrayLiteralExp) isArrayLiteralExp() { return op == EXP.arrayLiteral ? cast(typeof(return))this : null; }
|
||||
inout(AssocArrayLiteralExp) isAssocArrayLiteralExp() { return op == EXP.assocArrayLiteral ? cast(typeof(return))this : null; }
|
||||
|
@ -1499,6 +1500,7 @@ extern (C++) final class StringExp : Expression
|
|||
char* string; // if sz == 1
|
||||
wchar* wstring; // if sz == 2
|
||||
dchar* dstring; // if sz == 4
|
||||
ulong* lstring; // if sz == 8
|
||||
} // (const if ownedByCtfe == OwnedBy.code)
|
||||
size_t len; // number of code units
|
||||
ubyte sz = 1; // 1: char, 2: wchar, 4: dchar
|
||||
|
@ -1661,6 +1663,13 @@ extern (C++) final class StringExp : Expression
|
|||
* code unit at index i
|
||||
*/
|
||||
dchar getCodeUnit(size_t i) const pure
|
||||
{
|
||||
assert(this.sz <= dchar.sizeof);
|
||||
return cast(dchar) getIndex(i);
|
||||
}
|
||||
|
||||
/// Returns: integer at index `i`
|
||||
dinteger_t getIndex(size_t i) const pure
|
||||
{
|
||||
assert(i < len);
|
||||
final switch (sz)
|
||||
|
@ -1671,6 +1680,8 @@ extern (C++) final class StringExp : Expression
|
|||
return wstring[i];
|
||||
case 4:
|
||||
return dstring[i];
|
||||
case 8:
|
||||
return lstring[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1681,6 +1692,11 @@ extern (C++) final class StringExp : Expression
|
|||
* c = code unit to set it to
|
||||
*/
|
||||
extern (D) void setCodeUnit(size_t i, dchar c)
|
||||
{
|
||||
return setIndex(i, c);
|
||||
}
|
||||
|
||||
extern (D) void setIndex(size_t i, long c)
|
||||
{
|
||||
assert(i < len);
|
||||
final switch (sz)
|
||||
|
@ -1692,7 +1708,10 @@ extern (C++) final class StringExp : Expression
|
|||
wstring[i] = cast(wchar)c;
|
||||
break;
|
||||
case 4:
|
||||
dstring[i] = c;
|
||||
dstring[i] = cast(dchar) c;
|
||||
break;
|
||||
case 8:
|
||||
lstring[i] = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1847,6 +1866,28 @@ extern (C++) final class StringExp : Expression
|
|||
}
|
||||
}
|
||||
|
||||
extern (C++) final class InterpExp : Expression
|
||||
{
|
||||
char postfix = NoPostfix; // 'c', 'w', 'd'
|
||||
OwnedBy ownedByCtfe = OwnedBy.code;
|
||||
InterpolatedSet* interpolatedSet;
|
||||
|
||||
enum char NoPostfix = 0;
|
||||
|
||||
extern (D) this(const ref Loc loc, InterpolatedSet* set, char postfix = NoPostfix) scope
|
||||
{
|
||||
super(loc, EXP.interpolated);
|
||||
this.interpolatedSet = set;
|
||||
this.postfix = postfix;
|
||||
}
|
||||
|
||||
override void accept(Visitor v)
|
||||
{
|
||||
v.visit(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************
|
||||
* A sequence of expressions
|
||||
*
|
||||
|
@ -5494,6 +5535,7 @@ private immutable ubyte[EXP.max+1] expSize = [
|
|||
EXP.preMinusMinus: __traits(classInstanceSize, PreExp),
|
||||
EXP.identifier: __traits(classInstanceSize, IdentifierExp),
|
||||
EXP.string_: __traits(classInstanceSize, StringExp),
|
||||
EXP.interpolated: __traits(classInstanceSize, InterpExp),
|
||||
EXP.this_: __traits(classInstanceSize, ThisExp),
|
||||
EXP.super_: __traits(classInstanceSize, SuperExp),
|
||||
EXP.halt: __traits(classInstanceSize, HaltExp),
|
||||
|
|
|
@ -38,6 +38,7 @@ class TemplateDeclaration;
|
|||
class ClassDeclaration;
|
||||
class OverloadSet;
|
||||
class StringExp;
|
||||
class InterpExp;
|
||||
class LoweredAssignExp;
|
||||
#ifdef IN_GCC
|
||||
typedef union tree_node Symbol;
|
||||
|
@ -129,6 +130,7 @@ public:
|
|||
SuperExp* isSuperExp();
|
||||
NullExp* isNullExp();
|
||||
StringExp* isStringExp();
|
||||
InterpExp* isInterpExp();
|
||||
TupleExp* isTupleExp();
|
||||
ArrayLiteralExp* isArrayLiteralExp();
|
||||
AssocArrayLiteralExp* isAssocArrayLiteralExp();
|
||||
|
@ -352,7 +354,7 @@ class StringExp final : public Expression
|
|||
public:
|
||||
utf8_t postfix; // 'c', 'w', 'd'
|
||||
OwnedBy ownedByCtfe;
|
||||
void *string; // char, wchar, or dchar data
|
||||
void *string; // char, wchar, dchar, or long data
|
||||
size_t len; // number of chars, wchars, or dchars
|
||||
unsigned char sz; // 1: char, 2: wchar, 4: dchar
|
||||
d_bool committed; // if type is committed
|
||||
|
@ -362,6 +364,7 @@ public:
|
|||
static StringExp *create(const Loc &loc, const void *s, d_size_t len);
|
||||
bool equals(const RootObject * const o) const override;
|
||||
char32_t getCodeUnit(d_size_t i) const;
|
||||
dinteger_t getIndex(d_size_t i) const;
|
||||
StringExp *toStringExp() override;
|
||||
Optional<bool> toBool() override;
|
||||
bool isLvalue() override;
|
||||
|
@ -370,6 +373,16 @@ public:
|
|||
void writeTo(void* dest, bool zero, int tyto = 0) const;
|
||||
};
|
||||
|
||||
class InterpExp final : public Expression
|
||||
{
|
||||
public:
|
||||
utf8_t postfix; // 'c', 'w', 'd'
|
||||
OwnedBy ownedByCtfe;
|
||||
void* interpolatedSet;
|
||||
|
||||
void accept(Visitor* v) override { v->visit(this); }
|
||||
};
|
||||
|
||||
// Tuple
|
||||
|
||||
class TupleExp final : public Expression
|
||||
|
|
|
@ -42,10 +42,12 @@ import dmd.dsymbolsem;
|
|||
import dmd.dtemplate;
|
||||
import dmd.errors;
|
||||
import dmd.errorsink;
|
||||
import dmd.enumsem;
|
||||
import dmd.escape;
|
||||
import dmd.expression;
|
||||
import dmd.file_manager;
|
||||
import dmd.func;
|
||||
import dmd.funcsem;
|
||||
import dmd.globals;
|
||||
import dmd.hdrgen;
|
||||
import dmd.id;
|
||||
|
@ -1579,7 +1581,7 @@ Lagain:
|
|||
if (auto f = s.isFuncDeclaration())
|
||||
{
|
||||
f = f.toAliasFunc();
|
||||
if (!f.functionSemantic())
|
||||
if (!functionSemantic(f))
|
||||
return ErrorExp.get();
|
||||
|
||||
if (!hasOverloads && f.checkForwardRef(loc))
|
||||
|
@ -2866,7 +2868,7 @@ private bool functionParameters(const ref Loc loc, Scope* sc,
|
|||
// If inferring return type, and semantic3() needs to be run if not already run
|
||||
if (!tf.next && fd.inferRetType)
|
||||
{
|
||||
fd.functionSemantic();
|
||||
functionSemantic(fd);
|
||||
}
|
||||
else if (fd && fd.parent)
|
||||
{
|
||||
|
@ -4145,6 +4147,84 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
result = e;
|
||||
}
|
||||
|
||||
override void visit(InterpExp e)
|
||||
{
|
||||
// the lexer breaks up into an odd/even array of literals and expression code
|
||||
// we need to turn that into:
|
||||
/+
|
||||
tuple(
|
||||
.object.imported!"core.interpolation".InterpolationHeader(),
|
||||
...
|
||||
.object.imported!"core.interpolation".InterpolationFooter()
|
||||
)
|
||||
|
||||
There the ... loops through them all, making the even ones
|
||||
.object.imported!"core.interpolation".InterpolatedLiteral!str()
|
||||
and making the odd ones
|
||||
.object.imported!"core.interpolation".InterpolatedExpression!str(),
|
||||
the code represented by str
|
||||
|
||||
Empty string literals are skipped as they provide no additional information.
|
||||
+/
|
||||
|
||||
if (e.postfix)
|
||||
error(e.loc, "String postfixes on interpolated expression sequences are not allowed.");
|
||||
|
||||
Expression makeNonTemplateItem(Identifier which) {
|
||||
Expression id = new IdentifierExp(e.loc, Id.empty);
|
||||
id = new DotIdExp(e.loc, id, Id.object);
|
||||
auto moduleNameArgs = new Objects();
|
||||
moduleNameArgs.push(new StringExp(e.loc, "core.interpolation"));
|
||||
id = new DotTemplateInstanceExp(e.loc, id, Id.imported, moduleNameArgs);
|
||||
id = new DotIdExp(e.loc, id, which);
|
||||
id = new CallExp(e.loc, id, new Expressions());
|
||||
return id;
|
||||
}
|
||||
|
||||
Expression makeTemplateItem(Identifier which, string arg) {
|
||||
Expression id = new IdentifierExp(e.loc, Id.empty);
|
||||
id = new DotIdExp(e.loc, id, Id.object);
|
||||
auto moduleNameArgs = new Objects();
|
||||
moduleNameArgs.push(new StringExp(e.loc, "core.interpolation"));
|
||||
id = new DotTemplateInstanceExp(e.loc, id, Id.imported, moduleNameArgs);
|
||||
auto tiargs = new Objects();
|
||||
auto templateStringArg = new StringExp(e.loc, arg);
|
||||
// banning those instead of forwarding them
|
||||
// templateStringArg.postfix = e.postfix; // forward the postfix to these literals
|
||||
tiargs.push(templateStringArg);
|
||||
id = new DotTemplateInstanceExp(e.loc, id, which, tiargs);
|
||||
id = new CallExp(e.loc, id, new Expressions());
|
||||
return id;
|
||||
}
|
||||
|
||||
auto arguments = new Expressions();
|
||||
arguments.push(makeNonTemplateItem(Id.InterpolationHeader));
|
||||
|
||||
foreach (idx, str; e.interpolatedSet.parts)
|
||||
{
|
||||
if (idx % 2 == 0)
|
||||
{
|
||||
if (str.length > 0)
|
||||
arguments.push(makeTemplateItem(Id.InterpolatedLiteral, str));
|
||||
}
|
||||
else
|
||||
{
|
||||
arguments.push(makeTemplateItem(Id.InterpolatedExpression, str));
|
||||
Expressions* mix = new Expressions();
|
||||
mix.push(new StringExp(e.loc, str));
|
||||
// FIXME: i'd rather not use MixinExp but idk how to do it lol
|
||||
arguments.push(new MixinExp(e.loc, mix));
|
||||
}
|
||||
}
|
||||
|
||||
arguments.push(makeNonTemplateItem(Id.InterpolationFooter));
|
||||
|
||||
auto loweredTo = new TupleExp(e.loc, arguments);
|
||||
visit(loweredTo);
|
||||
|
||||
result = loweredTo;
|
||||
}
|
||||
|
||||
override void visit(StringExp e)
|
||||
{
|
||||
static if (LOGSEMANTIC)
|
||||
|
@ -5366,7 +5446,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
if (fd)
|
||||
{
|
||||
//printf("L%d fd = %s\n", __LINE__, f.toChars());
|
||||
if (!fd.functionSemantic())
|
||||
if (!functionSemantic(fd))
|
||||
return setError();
|
||||
}
|
||||
|
||||
|
@ -6564,10 +6644,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
.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());
|
||||
.error(exp.loc, "%s `%s` is not callable using argument types `%s`",
|
||||
exp.f.kind(), exp.f.toChars(), buf.peekChars());
|
||||
if (failMessage)
|
||||
errorSupplemental(exp.loc, "%s", failMessage);
|
||||
.errorSupplemental(exp.f.loc, "`%s%s` declared here", exp.f.toPrettyChars(), parametersTypeToChars(tf.parameterList));
|
||||
exp.f = null;
|
||||
}
|
||||
|
||||
|
@ -7549,7 +7630,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
se = se.toUTF8(sc);
|
||||
|
||||
auto namez = se.toStringz();
|
||||
if (!global.filePath)
|
||||
if (!global.filePath.length)
|
||||
{
|
||||
error(e.loc, "need `-J` switch to import text file `%s`", namez.ptr);
|
||||
return setError();
|
||||
|
@ -7580,12 +7661,12 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
return setError();
|
||||
}
|
||||
|
||||
auto resolvedNamez = FileName.searchPath(global.filePath, namez, false);
|
||||
auto resolvedNamez = FileName.searchPath(global.filePath[], namez, false);
|
||||
if (!resolvedNamez)
|
||||
{
|
||||
error(e.loc, "file `%s` cannot be found or not in a path specified with `-J`", se.toChars());
|
||||
errorSupplemental(e.loc, "Path(s) searched (as provided by `-J`):");
|
||||
foreach (idx, path; *global.filePath)
|
||||
foreach (idx, path; global.filePath[])
|
||||
{
|
||||
const attr = FileName.exists(path);
|
||||
const(char)* err = attr == 2 ? "" :
|
||||
|
@ -8170,7 +8251,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
if (FuncDeclaration fd = exp.var.isFuncDeclaration())
|
||||
{
|
||||
// for functions, do checks after overload resolution
|
||||
if (!fd.functionSemantic())
|
||||
if (!functionSemantic(fd))
|
||||
return setError();
|
||||
|
||||
/* https://issues.dlang.org/show_bug.cgi?id=13843
|
||||
|
@ -8937,7 +9018,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
bool err = false;
|
||||
if (cd.dtor)
|
||||
{
|
||||
err |= !cd.dtor.functionSemantic();
|
||||
err |= !functionSemantic(cd.dtor);
|
||||
err |= cd.dtor.checkPurity(exp.loc, sc);
|
||||
err |= cd.dtor.checkSafety(exp.loc, sc);
|
||||
err |= cd.dtor.checkNogc(exp.loc, sc);
|
||||
|
@ -14356,7 +14437,7 @@ Expression dotIdSemanticProp(DotIdExp exp, Scope* sc, bool gag)
|
|||
if (auto f = s.isFuncDeclaration())
|
||||
{
|
||||
//printf("it's a function\n");
|
||||
if (!f.functionSemantic())
|
||||
if (!functionSemantic(f))
|
||||
return ErrorExp.get();
|
||||
Expression e;
|
||||
if (f.needThis())
|
||||
|
|
199
gcc/d/dmd/func.d
199
gcc/d/dmd/func.d
|
@ -39,6 +39,7 @@ import dmd.dtemplate;
|
|||
import dmd.errors;
|
||||
import dmd.escape;
|
||||
import dmd.expression;
|
||||
import dmd.funcsem;
|
||||
import dmd.globals;
|
||||
import dmd.hdrgen;
|
||||
import dmd.id;
|
||||
|
@ -466,103 +467,13 @@ extern (C++) class FuncDeclaration : Declaration
|
|||
return f;
|
||||
}
|
||||
|
||||
/****************************************************
|
||||
* Resolve forward reference of function signature -
|
||||
* parameter types, return type, and attributes.
|
||||
* Returns:
|
||||
* false if any errors exist in the signature.
|
||||
*/
|
||||
final bool functionSemantic()
|
||||
{
|
||||
//printf("functionSemantic() %p %s\n", this, toChars());
|
||||
if (!_scope)
|
||||
return !errors;
|
||||
|
||||
this.cppnamespace = _scope.namespace;
|
||||
|
||||
if (!originalType) // semantic not yet run
|
||||
{
|
||||
TemplateInstance spec = isSpeculative();
|
||||
uint olderrs = global.errors;
|
||||
uint oldgag = global.gag;
|
||||
if (global.gag && !spec)
|
||||
global.gag = 0;
|
||||
dsymbolSemantic(this, _scope);
|
||||
global.gag = oldgag;
|
||||
if (spec && global.errors != olderrs)
|
||||
spec.errors = (global.errors - olderrs != 0);
|
||||
if (olderrs != global.errors) // if errors compiling this function
|
||||
return false;
|
||||
}
|
||||
|
||||
// if inferring return type, sematic3 needs to be run
|
||||
// - When the function body contains any errors, we cannot assume
|
||||
// the inferred return type is valid.
|
||||
// So, the body errors should become the function signature error.
|
||||
if (inferRetType && type && !type.nextOf())
|
||||
return functionSemantic3();
|
||||
|
||||
TemplateInstance ti;
|
||||
if (isInstantiated() && !isVirtualMethod() &&
|
||||
((ti = parent.isTemplateInstance()) is null || ti.isTemplateMixin() || ti.tempdecl.ident == ident))
|
||||
{
|
||||
AggregateDeclaration ad = isMemberLocal();
|
||||
if (ad && ad.sizeok != Sizeok.done)
|
||||
{
|
||||
/* Currently dmd cannot resolve forward references per methods,
|
||||
* then setting SIZOKfwd is too conservative and would break existing code.
|
||||
* So, just stop method attributes inference until ad.dsymbolSemantic() done.
|
||||
*/
|
||||
//ad.sizeok = Sizeok.fwd;
|
||||
}
|
||||
else
|
||||
return functionSemantic3() || !errors;
|
||||
}
|
||||
|
||||
if (storage_class & STC.inference)
|
||||
return functionSemantic3() || !errors;
|
||||
|
||||
return !errors;
|
||||
}
|
||||
|
||||
/****************************************************
|
||||
* Resolve forward reference of function body.
|
||||
* Returns false if any errors exist in the body.
|
||||
*/
|
||||
final bool functionSemantic3()
|
||||
{
|
||||
if (semanticRun < PASS.semantic3 && _scope)
|
||||
{
|
||||
/* Forward reference - we need to run semantic3 on this function.
|
||||
* If errors are gagged, and it's not part of a template instance,
|
||||
* we need to temporarily ungag errors.
|
||||
*/
|
||||
TemplateInstance spec = isSpeculative();
|
||||
uint olderrs = global.errors;
|
||||
uint oldgag = global.gag;
|
||||
if (global.gag && !spec)
|
||||
global.gag = 0;
|
||||
semantic3(this, _scope);
|
||||
global.gag = oldgag;
|
||||
|
||||
// If it is a speculatively-instantiated template, and errors occur,
|
||||
// we need to mark the template as having errors.
|
||||
if (spec && global.errors != olderrs)
|
||||
spec.errors = (global.errors - olderrs != 0);
|
||||
if (olderrs != global.errors) // if errors compiling this function
|
||||
return false;
|
||||
}
|
||||
|
||||
return !errors && !this.hasSemantic3Errors();
|
||||
}
|
||||
|
||||
/****************************************************
|
||||
* Check that this function type is properly resolved.
|
||||
* If not, report "forward reference error" and return true.
|
||||
*/
|
||||
extern (D) final bool checkForwardRef(const ref Loc loc)
|
||||
{
|
||||
if (!functionSemantic())
|
||||
if (!functionSemantic(this))
|
||||
return true;
|
||||
|
||||
/* No deco means the functionSemantic() call could not resolve
|
||||
|
@ -579,72 +490,6 @@ extern (C++) class FuncDeclaration : Declaration
|
|||
return false;
|
||||
}
|
||||
|
||||
// called from semantic3
|
||||
/**
|
||||
* Creates and returns the hidden parameters for this function declaration.
|
||||
*
|
||||
* Hidden parameters include the `this` parameter of a class, struct or
|
||||
* nested function and the selector parameter for Objective-C methods.
|
||||
*/
|
||||
extern (D) final void declareThis(Scope* sc)
|
||||
{
|
||||
const bool dualCtx = (toParent2() != toParentLocal());
|
||||
if (dualCtx)
|
||||
this.hasDualContext = true;
|
||||
auto ad = isThis();
|
||||
if (!dualCtx && !ad && !isNested())
|
||||
{
|
||||
vthis = null;
|
||||
objc.selectorParameter = null;
|
||||
return;
|
||||
}
|
||||
|
||||
Type addModStc(Type t)
|
||||
{
|
||||
return t.addMod(type.mod).addStorageClass(storage_class);
|
||||
}
|
||||
|
||||
if (dualCtx || isNested())
|
||||
{
|
||||
/* The 'this' for a nested function is the link to the
|
||||
* enclosing function's stack frame.
|
||||
* Note that nested functions and member functions are disjoint.
|
||||
*/
|
||||
Type tthis = addModStc(dualCtx ?
|
||||
Type.tvoidptr.sarrayOf(2).pointerTo() :
|
||||
Type.tvoid.pointerTo());
|
||||
vthis = new VarDeclaration(loc, tthis, dualCtx ? Id.this2 : Id.capture, null);
|
||||
vthis.storage_class |= STC.parameter | STC.nodtor;
|
||||
}
|
||||
else if (ad)
|
||||
{
|
||||
Type thandle = addModStc(ad.handleType());
|
||||
vthis = new ThisDeclaration(loc, thandle);
|
||||
vthis.storage_class |= STC.parameter;
|
||||
if (thandle.ty == Tstruct)
|
||||
{
|
||||
vthis.storage_class |= STC.ref_;
|
||||
}
|
||||
}
|
||||
|
||||
if (auto tf = type.isTypeFunction())
|
||||
{
|
||||
if (tf.isreturn)
|
||||
vthis.storage_class |= STC.return_;
|
||||
if (tf.isScopeQual)
|
||||
vthis.storage_class |= STC.scope_;
|
||||
if (tf.isreturnscope)
|
||||
vthis.storage_class |= STC.returnScope;
|
||||
}
|
||||
|
||||
vthis.dsymbolSemantic(sc);
|
||||
if (!sc.insert(vthis))
|
||||
assert(0);
|
||||
vthis.parent = this;
|
||||
if (ad)
|
||||
objc.selectorParameter = .objc.createSelectorParameter(this, sc);
|
||||
}
|
||||
|
||||
override final bool equals(const RootObject o) const
|
||||
{
|
||||
if (this == o)
|
||||
|
@ -1104,20 +949,24 @@ extern (C++) class FuncDeclaration : Declaration
|
|||
}
|
||||
|
||||
/*************************************
|
||||
* Determine partial specialization order of 'this' vs g.
|
||||
* Determine partial specialization order of functions `f` vs `g`.
|
||||
* This is very similar to TemplateDeclaration::leastAsSpecialized().
|
||||
* Params:
|
||||
* f = first function
|
||||
* g = second function
|
||||
* names = names of parameters
|
||||
* Returns:
|
||||
* match 'this' is at least as specialized as g
|
||||
* 0 g is more specialized than 'this'
|
||||
*/
|
||||
final MATCH leastAsSpecialized(FuncDeclaration g, Identifiers* names)
|
||||
static MATCH leastAsSpecialized(FuncDeclaration f, FuncDeclaration g, Identifiers* names)
|
||||
{
|
||||
enum LOG_LEASTAS = 0;
|
||||
static if (LOG_LEASTAS)
|
||||
{
|
||||
import core.stdc.stdio : printf;
|
||||
printf("%s.leastAsSpecialized(%s, %s)\n", toChars(), g.toChars(), names ? names.toChars() : "null");
|
||||
printf("%s, %s\n", type.toChars(), g.type.toChars());
|
||||
printf("leastAsSpecialized(%s, %s, %s)\n", f.toChars(), g.toChars(), names ? names.toChars() : "null");
|
||||
printf("%s, %s\n", f.type.toChars(), g.type.toChars());
|
||||
}
|
||||
|
||||
/* This works by calling g() with f()'s parameters, and
|
||||
|
@ -1125,15 +974,15 @@ extern (C++) class FuncDeclaration : Declaration
|
|||
* as g() is.
|
||||
*/
|
||||
|
||||
TypeFunction tf = type.toTypeFunction();
|
||||
TypeFunction tf = f.type.toTypeFunction();
|
||||
TypeFunction tg = g.type.toTypeFunction();
|
||||
|
||||
/* If both functions have a 'this' pointer, and the mods are not
|
||||
* the same and g's is not const, then this is less specialized.
|
||||
*/
|
||||
if (needThis() && g.needThis() && tf.mod != tg.mod)
|
||||
if (f.needThis() && g.needThis() && tf.mod != tg.mod)
|
||||
{
|
||||
if (isCtorDeclaration())
|
||||
if (f.isCtorDeclaration())
|
||||
{
|
||||
if (!MODimplicitConv(tg.mod, tf.mod))
|
||||
return MATCH.nomatch;
|
||||
|
@ -3037,7 +2886,7 @@ Expression addInvariant(AggregateDeclaration ad, VarDeclaration vthis)
|
|||
// Workaround for https://issues.dlang.org/show_bug.cgi?id=13394
|
||||
// For the correct mangling,
|
||||
// run attribute inference on inv if needed.
|
||||
inv.functionSemantic();
|
||||
functionSemantic(inv);
|
||||
}
|
||||
|
||||
//e = new DsymbolExp(Loc.initial, inv);
|
||||
|
@ -3316,7 +3165,7 @@ FuncDeclaration resolveFuncCall(const ref Loc loc, Scope* sc, Dsymbol s,
|
|||
if (m.count == 1) // exactly one match
|
||||
{
|
||||
if (!(flags & FuncResolveFlag.quiet))
|
||||
m.lastf.functionSemantic();
|
||||
functionSemantic(m.lastf);
|
||||
return m.lastf;
|
||||
}
|
||||
if ((flags & FuncResolveFlag.overloadOnly) && !tthis && m.lastf.needThis())
|
||||
|
@ -3386,12 +3235,18 @@ FuncDeclaration resolveFuncCall(const ref Loc loc, Scope* sc, Dsymbol s,
|
|||
// all of overloads are templates
|
||||
if (td)
|
||||
{
|
||||
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,
|
||||
{
|
||||
.error(loc, "%s `%s` is not callable using argument types `!(%s)%s`",
|
||||
td.kind(), td.ident.toChars(), tiargsBuf.peekChars(), fargsBuf.peekChars());
|
||||
}
|
||||
else
|
||||
{
|
||||
.error(loc, "none of the overloads of %s `%s.%s` are callable using argument types `!(%s)%s`",
|
||||
td.kind(), td.parent.toPrettyChars(), td.ident.toChars(),
|
||||
tiargsBuf.peekChars(), fargsBuf.peekChars());
|
||||
}
|
||||
|
||||
|
||||
if (!global.gag || global.params.v.showGaggedErrors)
|
||||
printCandidates(loc, td, sc.isDeprecated());
|
||||
|
@ -3574,7 +3429,11 @@ if (is(Decl == TemplateDeclaration) || is(Decl == FuncDeclaration))
|
|||
|
||||
if (!print)
|
||||
return true;
|
||||
const tmsg = td.toCharsNoConstraints();
|
||||
OutBuffer buf;
|
||||
HdrGenState hgs;
|
||||
hgs.skipConstraints = true;
|
||||
toCharsMaybeConstraints(td, buf, hgs);
|
||||
const tmsg = buf.peekChars();
|
||||
const cmsg = td.getConstraintEvalError(constraintsTip);
|
||||
|
||||
// add blank space if there are multiple candidates
|
||||
|
|
219
gcc/d/dmd/funcsem.d
Normal file
219
gcc/d/dmd/funcsem.d
Normal file
|
@ -0,0 +1,219 @@
|
|||
/**
|
||||
* Does semantic analysis for functions.
|
||||
*
|
||||
* Specification: $(LINK2 https://dlang.org/spec/function.html, Functions)
|
||||
*
|
||||
* Copyright: Copyright (C) 1999-2024 by The D Language Foundation, All Rights Reserved
|
||||
* Authors: $(LINK2 https://www.digitalmars.com, Walter Bright)
|
||||
* License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
|
||||
* Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/funcsem.d, _funcsem.d)
|
||||
* Documentation: https://dlang.org/phobos/dmd_funcsem.html
|
||||
* Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/funcsem.d
|
||||
*/
|
||||
|
||||
module dmd.funcsem;
|
||||
|
||||
import core.stdc.stdio;
|
||||
|
||||
import dmd.aggregate;
|
||||
import dmd.arraytypes;
|
||||
import dmd.astenums;
|
||||
import dmd.blockexit;
|
||||
import dmd.gluelayer;
|
||||
import dmd.dcast;
|
||||
import dmd.dclass;
|
||||
import dmd.declaration;
|
||||
import dmd.delegatize;
|
||||
import dmd.dinterpret;
|
||||
import dmd.dmodule;
|
||||
import dmd.dscope;
|
||||
import dmd.dstruct;
|
||||
import dmd.dsymbol;
|
||||
import dmd.dsymbolsem;
|
||||
import dmd.dtemplate;
|
||||
import dmd.errors;
|
||||
import dmd.escape;
|
||||
import dmd.expression;
|
||||
import dmd.func;
|
||||
import dmd.globals;
|
||||
import dmd.hdrgen;
|
||||
import dmd.id;
|
||||
import dmd.identifier;
|
||||
import dmd.init;
|
||||
import dmd.location;
|
||||
import dmd.mtype;
|
||||
import dmd.objc;
|
||||
import dmd.root.aav;
|
||||
import dmd.common.outbuffer;
|
||||
import dmd.rootobject;
|
||||
import dmd.root.string;
|
||||
import dmd.root.stringtable;
|
||||
import dmd.semantic2;
|
||||
import dmd.semantic3;
|
||||
import dmd.statement_rewrite_walker;
|
||||
import dmd.statement;
|
||||
import dmd.statementsem;
|
||||
import dmd.tokens;
|
||||
import dmd.visitor;
|
||||
|
||||
/****************************************************
|
||||
* Resolve forward reference of function signature -
|
||||
* parameter types, return type, and attributes.
|
||||
* Params:
|
||||
* fd = function declaration
|
||||
* Returns:
|
||||
* false if any errors exist in the signature.
|
||||
*/
|
||||
public
|
||||
extern (C++)
|
||||
bool functionSemantic(FuncDeclaration fd)
|
||||
{
|
||||
//printf("functionSemantic() %p %s\n", this, toChars());
|
||||
if (!fd._scope)
|
||||
return !fd.errors;
|
||||
|
||||
fd.cppnamespace = fd._scope.namespace;
|
||||
|
||||
if (!fd.originalType) // semantic not yet run
|
||||
{
|
||||
TemplateInstance spec = fd.isSpeculative();
|
||||
uint olderrs = global.errors;
|
||||
uint oldgag = global.gag;
|
||||
if (global.gag && !spec)
|
||||
global.gag = 0;
|
||||
dsymbolSemantic(fd, fd._scope);
|
||||
global.gag = oldgag;
|
||||
if (spec && global.errors != olderrs)
|
||||
spec.errors = (global.errors - olderrs != 0);
|
||||
if (olderrs != global.errors) // if errors compiling this function
|
||||
return false;
|
||||
}
|
||||
|
||||
// if inferring return type, sematic3 needs to be run
|
||||
// - When the function body contains any errors, we cannot assume
|
||||
// the inferred return type is valid.
|
||||
// So, the body errors should become the function signature error.
|
||||
if (fd.inferRetType && fd.type && !fd.type.nextOf())
|
||||
return fd.functionSemantic3();
|
||||
|
||||
TemplateInstance ti;
|
||||
if (fd.isInstantiated() && !fd.isVirtualMethod() &&
|
||||
((ti = fd.parent.isTemplateInstance()) is null || ti.isTemplateMixin() || ti.tempdecl.ident == fd.ident))
|
||||
{
|
||||
AggregateDeclaration ad = fd.isMemberLocal();
|
||||
if (ad && ad.sizeok != Sizeok.done)
|
||||
{
|
||||
/* Currently dmd cannot resolve forward references per methods,
|
||||
* then setting SIZOKfwd is too conservative and would break existing code.
|
||||
* So, just stop method attributes inference until ad.dsymbolSemantic() done.
|
||||
*/
|
||||
//ad.sizeok = Sizeok.fwd;
|
||||
}
|
||||
else
|
||||
return fd.functionSemantic3() || !fd.errors;
|
||||
}
|
||||
|
||||
if (fd.storage_class & STC.inference)
|
||||
return fd.functionSemantic3() || !fd.errors;
|
||||
|
||||
return !fd.errors;
|
||||
}
|
||||
|
||||
/****************************************************
|
||||
* Resolve forward reference of function body.
|
||||
* Returns false if any errors exist in the body.
|
||||
*/
|
||||
public
|
||||
extern (C++)
|
||||
bool functionSemantic3(FuncDeclaration fd)
|
||||
{
|
||||
if (fd.semanticRun < PASS.semantic3 && fd._scope)
|
||||
{
|
||||
/* Forward reference - we need to run semantic3 on this function.
|
||||
* If errors are gagged, and it's not part of a template instance,
|
||||
* we need to temporarily ungag errors.
|
||||
*/
|
||||
TemplateInstance spec = fd.isSpeculative();
|
||||
uint olderrs = global.errors;
|
||||
uint oldgag = global.gag;
|
||||
if (global.gag && !spec)
|
||||
global.gag = 0;
|
||||
semantic3(fd, fd._scope);
|
||||
global.gag = oldgag;
|
||||
|
||||
// If it is a speculatively-instantiated template, and errors occur,
|
||||
// we need to mark the template as having errors.
|
||||
if (spec && global.errors != olderrs)
|
||||
spec.errors = (global.errors - olderrs != 0);
|
||||
if (olderrs != global.errors) // if errors compiling this function
|
||||
return false;
|
||||
}
|
||||
|
||||
return !fd.errors && !fd.hasSemantic3Errors();
|
||||
}
|
||||
|
||||
// called from semantic3
|
||||
/**
|
||||
* Creates and returns the hidden parameters for this function declaration.
|
||||
*
|
||||
* Hidden parameters include the `this` parameter of a class, struct or
|
||||
* nested function and the selector parameter for Objective-C methods.
|
||||
*/
|
||||
extern (D) void declareThis(FuncDeclaration fd, Scope* sc)
|
||||
{
|
||||
const bool dualCtx = (fd.toParent2() != fd.toParentLocal());
|
||||
if (dualCtx)
|
||||
fd.hasDualContext = true;
|
||||
auto ad = fd.isThis();
|
||||
if (!dualCtx && !ad && !fd.isNested())
|
||||
{
|
||||
fd.vthis = null;
|
||||
fd.objc.selectorParameter = null;
|
||||
return;
|
||||
}
|
||||
|
||||
Type addModStc(Type t)
|
||||
{
|
||||
return t.addMod(fd.type.mod).addStorageClass(fd.storage_class);
|
||||
}
|
||||
|
||||
if (dualCtx || fd.isNested())
|
||||
{
|
||||
/* The 'this' for a nested function is the link to the
|
||||
* enclosing function's stack frame.
|
||||
* Note that nested functions and member functions are disjoint.
|
||||
*/
|
||||
Type tthis = addModStc(dualCtx ?
|
||||
Type.tvoidptr.sarrayOf(2).pointerTo() :
|
||||
Type.tvoid.pointerTo());
|
||||
fd.vthis = new VarDeclaration(fd.loc, tthis, dualCtx ? Id.this2 : Id.capture, null);
|
||||
fd.vthis.storage_class |= STC.parameter | STC.nodtor;
|
||||
}
|
||||
else if (ad)
|
||||
{
|
||||
Type thandle = addModStc(ad.handleType());
|
||||
fd.vthis = new ThisDeclaration(fd.loc, thandle);
|
||||
fd.vthis.storage_class |= STC.parameter;
|
||||
if (thandle.ty == Tstruct)
|
||||
{
|
||||
fd.vthis.storage_class |= STC.ref_;
|
||||
}
|
||||
}
|
||||
|
||||
if (auto tf = fd.type.isTypeFunction())
|
||||
{
|
||||
if (tf.isreturn)
|
||||
fd.vthis.storage_class |= STC.return_;
|
||||
if (tf.isScopeQual)
|
||||
fd.vthis.storage_class |= STC.scope_;
|
||||
if (tf.isreturnscope)
|
||||
fd.vthis.storage_class |= STC.returnScope;
|
||||
}
|
||||
|
||||
fd.vthis.dsymbolSemantic(sc);
|
||||
if (!sc.insert(fd.vthis))
|
||||
assert(0);
|
||||
fd.vthis.parent = fd;
|
||||
if (ad)
|
||||
fd.objc.selectorParameter = .objc.createSelectorParameter(fd, sc);
|
||||
}
|
|
@ -219,8 +219,8 @@ extern (C++) struct Param
|
|||
|
||||
const(char)[] argv0; // program name
|
||||
Array!(const(char)*) modFileAliasStrings; // array of char*'s of -I module filename alias strings
|
||||
Array!(const(char)*)* imppath; // array of char*'s of where to look for import modules
|
||||
Array!(const(char)*)* fileImppath; // array of char*'s of where to look for file import modules
|
||||
Array!(const(char)*) imppath; // array of char*'s of where to look for import modules
|
||||
Array!(const(char)*) fileImppath; // array of char*'s of where to look for file import modules
|
||||
const(char)[] objdir; // .obj/.lib file output directory
|
||||
const(char)[] objname; // .obj file output name
|
||||
const(char)[] libname; // .lib file output name
|
||||
|
@ -280,8 +280,8 @@ extern (C++) struct Global
|
|||
string copyright = "Copyright (C) 1999-2024 by The D Language Foundation, All Rights Reserved";
|
||||
string written = "written by Walter Bright";
|
||||
|
||||
Array!(const(char)*)* path; /// Array of char*'s which form the import lookup path
|
||||
Array!(const(char)*)* filePath; /// Array of char*'s which form the file import lookup path
|
||||
Array!(const(char)*) path; /// Array of char*'s which form the import lookup path
|
||||
Array!(const(char)*) filePath; /// Array of char*'s which form the file import lookup path
|
||||
|
||||
private enum string _version = import("VERSION");
|
||||
char[26] datetime; /// string returned by ctime()
|
||||
|
@ -296,8 +296,8 @@ extern (C++) struct Global
|
|||
|
||||
void* console; /// opaque pointer to console for controlling text attributes
|
||||
|
||||
Array!Identifier* versionids; /// command line versions and predefined versions
|
||||
Array!Identifier* debugids; /// command line debug versions and predefined versions
|
||||
Array!Identifier versionids; /// command line versions and predefined versions
|
||||
Array!Identifier debugids; /// command line debug versions and predefined versions
|
||||
|
||||
bool hasMainFunction; /// Whether a main function has already been compiled in (for -main switch)
|
||||
uint varSequenceNumber = 1; /// Relative lifetime of `VarDeclaration` within a function, used for `scope` checks
|
||||
|
|
|
@ -202,8 +202,8 @@ struct Param
|
|||
|
||||
DString argv0; // program name
|
||||
Array<const char *> modFileAliasStrings; // array of char*'s of -I module filename alias strings
|
||||
Array<const char *> *imppath; // array of char*'s of where to look for import modules
|
||||
Array<const char *> *fileImppath; // array of char*'s of where to look for file import modules
|
||||
Array<const char *> imppath; // array of char*'s of where to look for import modules
|
||||
Array<const char *> fileImppath; // array of char*'s of where to look for file import modules
|
||||
DString objdir; // .obj/.lib file output directory
|
||||
DString objname; // .obj file output name
|
||||
DString libname; // .lib file output name
|
||||
|
@ -282,8 +282,8 @@ struct Global
|
|||
|
||||
const DString copyright;
|
||||
const DString written;
|
||||
Array<const char *> *path; // Array of char*'s which form the import lookup path
|
||||
Array<const char *> *filePath; // Array of char*'s which form the file import lookup path
|
||||
Array<const char *> path; // Array of char*'s which form the import lookup path
|
||||
Array<const char *> filePath; // Array of char*'s which form the file import lookup path
|
||||
|
||||
char datetime[26]; /// string returned by ctime()
|
||||
CompileEnv compileEnv;
|
||||
|
@ -297,8 +297,8 @@ struct Global
|
|||
|
||||
void* console; // opaque pointer to console for controlling text attributes
|
||||
|
||||
Array<class Identifier*>* versionids; // command line versions and predefined versions
|
||||
Array<class Identifier*>* debugids; // command line debug versions and predefined versions
|
||||
Array<class Identifier*> versionids; // command line versions and predefined versions
|
||||
Array<class Identifier*> debugids; // command line debug versions and predefined versions
|
||||
|
||||
d_bool hasMainFunction;
|
||||
unsigned varSequenceNumber;
|
||||
|
|
|
@ -60,6 +60,7 @@ struct HdrGenState
|
|||
bool importcHdr; /// true if generating a .di file from an ImportC file
|
||||
bool doFuncBodies; /// include function bodies in output
|
||||
bool vcg_ast; /// write out codegen-ast
|
||||
bool skipConstraints; // skip constraints when doing templates
|
||||
|
||||
bool fullQual; /// fully qualify types when printing
|
||||
int tpltMember;
|
||||
|
@ -1957,6 +1958,47 @@ void toCBuffer(Dsymbol s, ref OutBuffer buf, ref HdrGenState hgs)
|
|||
s.accept(v);
|
||||
}
|
||||
|
||||
// Note: this function is not actually `const`, because iterating the
|
||||
// function parameter list may run dsymbolsemantic on enum types
|
||||
public
|
||||
void toCharsMaybeConstraints(const TemplateDeclaration td, ref OutBuffer buf, ref HdrGenState hgs)
|
||||
{
|
||||
buf.writestring(td.ident == Id.ctor ? "this" : td.ident.toString());
|
||||
buf.writeByte('(');
|
||||
foreach (i, const tp; *td.parameters)
|
||||
{
|
||||
if (i)
|
||||
buf.writestring(", ");
|
||||
toCBuffer(tp, buf, hgs);
|
||||
}
|
||||
buf.writeByte(')');
|
||||
|
||||
if (td.onemember)
|
||||
{
|
||||
if (const fd = td.onemember.isFuncDeclaration())
|
||||
{
|
||||
if (TypeFunction tf = cast(TypeFunction)fd.type.isTypeFunction())
|
||||
{
|
||||
// !! Casted away const
|
||||
buf.writestring(parametersTypeToChars(tf.parameterList));
|
||||
if (tf.mod)
|
||||
{
|
||||
buf.writeByte(' ');
|
||||
buf.MODtoBuffer(tf.mod);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!hgs.skipConstraints &&
|
||||
td.constraint)
|
||||
{
|
||||
buf.writestring(" if (");
|
||||
toCBuffer(td.constraint, buf, hgs);
|
||||
buf.writeByte(')');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*****************************************
|
||||
* Pretty-print a template parameter list to a buffer.
|
||||
|
@ -2234,6 +2276,16 @@ private void expressionPrettyPrint(Expression e, ref OutBuffer buf, ref HdrGenSt
|
|||
|
||||
void visitString(StringExp e)
|
||||
{
|
||||
if (e.hexString || e.sz == 8)
|
||||
{
|
||||
buf.writeByte('x');
|
||||
buf.writeByte('"');
|
||||
buf.writeHexString(e.peekData, true);
|
||||
buf.writeByte('"');
|
||||
if (e.postfix)
|
||||
buf.writeByte(e.postfix);
|
||||
return;
|
||||
}
|
||||
buf.writeByte('"');
|
||||
const o = buf.length;
|
||||
foreach (i; 0 .. e.len)
|
||||
|
@ -2247,6 +2299,37 @@ private void expressionPrettyPrint(Expression e, ref OutBuffer buf, ref HdrGenSt
|
|||
buf.writeByte(e.postfix);
|
||||
}
|
||||
|
||||
void visitInterpolation(InterpExp e)
|
||||
{
|
||||
buf.writeByte('i');
|
||||
buf.writeByte('"');
|
||||
const o = buf.length;
|
||||
|
||||
foreach (idx, str; e.interpolatedSet.parts)
|
||||
{
|
||||
if (idx % 2 == 0)
|
||||
{
|
||||
foreach(ch; str)
|
||||
writeCharLiteral(buf, ch);
|
||||
}
|
||||
else
|
||||
{
|
||||
buf.writeByte('$');
|
||||
buf.writeByte('(');
|
||||
foreach(ch; str)
|
||||
buf.writeByte(ch);
|
||||
buf.writeByte(')');
|
||||
}
|
||||
}
|
||||
|
||||
if (hgs.ddoc)
|
||||
escapeDdocString(buf, o);
|
||||
buf.writeByte('"');
|
||||
if (e.postfix)
|
||||
buf.writeByte(e.postfix);
|
||||
|
||||
}
|
||||
|
||||
void visitArrayLiteral(ArrayLiteralExp e)
|
||||
{
|
||||
buf.writeByte('[');
|
||||
|
@ -2827,6 +2910,7 @@ private void expressionPrettyPrint(Expression e, ref OutBuffer buf, ref HdrGenSt
|
|||
case EXP.super_: return visitSuper(e.isSuperExp());
|
||||
case EXP.null_: return visitNull(e.isNullExp());
|
||||
case EXP.string_: return visitString(e.isStringExp());
|
||||
case EXP.interpolated: return visitInterpolation(e.isInterpExp());
|
||||
case EXP.arrayLiteral: return visitArrayLiteral(e.isArrayLiteralExp());
|
||||
case EXP.assocArrayLiteral: return visitAssocArrayLiteral(e.isAssocArrayLiteralExp());
|
||||
case EXP.structLiteral: return visitStructLiteral(e.isStructLiteralExp());
|
||||
|
|
|
@ -335,6 +335,12 @@ immutable Msgtable[] msgtable =
|
|||
{ "_d_arrayassign_l" },
|
||||
{ "_d_arrayassign_r" },
|
||||
|
||||
{ "imported" },
|
||||
{ "InterpolationHeader" },
|
||||
{ "InterpolationFooter" },
|
||||
{ "InterpolatedLiteral" },
|
||||
{ "InterpolatedExpression" },
|
||||
|
||||
// For pragma's
|
||||
{ "Pinline", "inline" },
|
||||
{ "lib" },
|
||||
|
|
|
@ -873,12 +873,9 @@ public:
|
|||
|
||||
propertyStart("predefinedVersions");
|
||||
arrayStart();
|
||||
if (global.versionids)
|
||||
foreach (const versionid; global.versionids)
|
||||
{
|
||||
foreach (const versionid; *global.versionids)
|
||||
{
|
||||
item(versionid.toString());
|
||||
}
|
||||
item(versionid.toString());
|
||||
}
|
||||
arrayEnd();
|
||||
|
||||
|
@ -905,12 +902,9 @@ public:
|
|||
|
||||
propertyStart("importPaths");
|
||||
arrayStart();
|
||||
if (global.params.imppath)
|
||||
foreach (importPath; global.params.imppath[])
|
||||
{
|
||||
foreach (importPath; *global.params.imppath)
|
||||
{
|
||||
item(importPath.toDString);
|
||||
}
|
||||
item(importPath.toDString);
|
||||
}
|
||||
arrayEnd();
|
||||
|
||||
|
|
|
@ -506,6 +506,29 @@ class Lexer
|
|||
}
|
||||
else
|
||||
goto case_ident;
|
||||
case 'i':
|
||||
if (Ccompile)
|
||||
goto case_ident;
|
||||
if (p[1] == '"')
|
||||
{
|
||||
p++; // skip the i
|
||||
escapeStringConstant(t, true);
|
||||
return;
|
||||
}
|
||||
else if (p[1] == '`')
|
||||
{
|
||||
p++; // skip the i
|
||||
wysiwygStringConstant(t, true);
|
||||
return;
|
||||
}
|
||||
else if (p[1] == 'q' && p[2] == '{')
|
||||
{
|
||||
p += 2; // skip the i and q
|
||||
tokenStringConstant(t, true);
|
||||
return;
|
||||
}
|
||||
else
|
||||
goto case_ident;
|
||||
case '"':
|
||||
escapeStringConstant(t);
|
||||
return;
|
||||
|
@ -517,7 +540,7 @@ class Lexer
|
|||
case 'f':
|
||||
case 'g':
|
||||
case 'h':
|
||||
case 'i':
|
||||
/*case 'i':*/
|
||||
case 'j':
|
||||
case 'k':
|
||||
case 'l':
|
||||
|
@ -1429,9 +1452,18 @@ class Lexer
|
|||
Params:
|
||||
result = pointer to the token that accepts the result
|
||||
*/
|
||||
private void wysiwygStringConstant(Token* result)
|
||||
private void wysiwygStringConstant(Token* result, bool supportInterpolation = false)
|
||||
{
|
||||
result.value = TOK.string_;
|
||||
if (supportInterpolation)
|
||||
{
|
||||
result.value = TOK.interpolated;
|
||||
result.interpolatedSet = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.value = TOK.string_;
|
||||
}
|
||||
|
||||
Loc start = loc();
|
||||
auto terminator = p[0];
|
||||
p++;
|
||||
|
@ -1451,6 +1483,14 @@ class Lexer
|
|||
c = '\n'; // treat EndOfLine as \n character
|
||||
endOfLine();
|
||||
break;
|
||||
case '$':
|
||||
if (!supportInterpolation)
|
||||
goto default;
|
||||
|
||||
if (!handleInterpolatedSegment(result, start))
|
||||
goto default;
|
||||
|
||||
continue;
|
||||
case 0:
|
||||
case 0x1A:
|
||||
error("unterminated string constant starting at %s", start.toChars());
|
||||
|
@ -1461,7 +1501,11 @@ class Lexer
|
|||
default:
|
||||
if (c == terminator)
|
||||
{
|
||||
result.setString(stringbuffer);
|
||||
if (supportInterpolation)
|
||||
result.appendInterpolatedPart(stringbuffer);
|
||||
else
|
||||
result.setString(stringbuffer);
|
||||
|
||||
stringPostfix(result);
|
||||
return;
|
||||
}
|
||||
|
@ -1736,13 +1780,21 @@ class Lexer
|
|||
Params:
|
||||
result = pointer to the token that accepts the result
|
||||
*/
|
||||
private void tokenStringConstant(Token* result)
|
||||
private void tokenStringConstant(Token* result, bool supportInterpolation = false)
|
||||
{
|
||||
result.value = TOK.string_;
|
||||
if (supportInterpolation)
|
||||
{
|
||||
result.value = TOK.interpolated;
|
||||
result.interpolatedSet = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.value = TOK.string_;
|
||||
}
|
||||
|
||||
uint nest = 1;
|
||||
const start = loc();
|
||||
const pstart = ++p;
|
||||
auto pstart = ++p;
|
||||
inTokenStringConstant++;
|
||||
scope(exit) inTokenStringConstant--;
|
||||
while (1)
|
||||
|
@ -1757,10 +1809,28 @@ class Lexer
|
|||
case TOK.rightCurly:
|
||||
if (--nest == 0)
|
||||
{
|
||||
result.setString(pstart, p - 1 - pstart);
|
||||
if (supportInterpolation)
|
||||
result.appendInterpolatedPart(pstart, p - 1 - pstart);
|
||||
else
|
||||
result.setString(pstart, p - 1 - pstart);
|
||||
|
||||
stringPostfix(result);
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
case TOK.dollar:
|
||||
if (!supportInterpolation)
|
||||
goto default;
|
||||
|
||||
stringbuffer.setsize(0);
|
||||
stringbuffer.write(pstart, p - 1 - pstart);
|
||||
if (!handleInterpolatedSegment(result, start))
|
||||
goto default;
|
||||
|
||||
stringbuffer.setsize(0);
|
||||
|
||||
pstart = p;
|
||||
|
||||
continue;
|
||||
case TOK.endOfFile:
|
||||
error("unterminated token string constant starting at %s", start.toChars());
|
||||
|
@ -1772,6 +1842,52 @@ class Lexer
|
|||
}
|
||||
}
|
||||
|
||||
// returns true if it got special treatment as an interpolated segment
|
||||
// otherwise returns false, indicating to treat it as just part of a normal string
|
||||
private bool handleInterpolatedSegment(Token* token, Loc start)
|
||||
{
|
||||
switch(*p)
|
||||
{
|
||||
case '(':
|
||||
// expression, at this level we need to scan until the closing ')'
|
||||
|
||||
// always put the string part in first
|
||||
token.appendInterpolatedPart(stringbuffer);
|
||||
stringbuffer.setsize(0);
|
||||
|
||||
int openParenCount = 1;
|
||||
p++; // skip the first open paren
|
||||
auto pstart = p;
|
||||
while (openParenCount > 0)
|
||||
{
|
||||
// need to scan with the lexer to support embedded strings and other complex cases
|
||||
Token tok;
|
||||
scan(&tok);
|
||||
if (tok.value == TOK.leftParenthesis)
|
||||
openParenCount++;
|
||||
if (tok.value == TOK.rightParenthesis)
|
||||
openParenCount--;
|
||||
if (tok.value == TOK.endOfFile)
|
||||
{
|
||||
// FIXME: make this error better, it spams a lot
|
||||
error("unterminated interpolated string constant starting at %s", start.toChars());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// then put the interpolated string segment
|
||||
token.appendInterpolatedPart(pstart[0 .. p - 1 - pstart]);
|
||||
|
||||
stringbuffer.setsize(0); // make sure this is reset from the last token scan
|
||||
// otherwise something like i"$(func("thing")) stuff" can still include it
|
||||
|
||||
return true;
|
||||
default:
|
||||
// nothing special
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Scan a quoted string while building the processed string value by
|
||||
handling escape sequences. The result is returned in the given `t` token.
|
||||
|
@ -1783,9 +1899,17 @@ class Lexer
|
|||
* D https://dlang.org/spec/lex.html#double_quoted_strings
|
||||
* ImportC C11 6.4.5
|
||||
*/
|
||||
private void escapeStringConstant(Token* t)
|
||||
private void escapeStringConstant(Token* t, bool supportInterpolation = false)
|
||||
{
|
||||
t.value = TOK.string_;
|
||||
if (supportInterpolation)
|
||||
{
|
||||
t.value = TOK.interpolated;
|
||||
t.interpolatedSet = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
t.value = TOK.string_;
|
||||
}
|
||||
|
||||
const start = loc();
|
||||
const tc = *p++; // opening quote
|
||||
|
@ -1813,11 +1937,28 @@ class Lexer
|
|||
c = escapeSequence(c2);
|
||||
stringbuffer.writeUTF8(c);
|
||||
continue;
|
||||
case '$':
|
||||
if (supportInterpolation)
|
||||
{
|
||||
p++; // skip escaped $
|
||||
stringbuffer.writeByte('$');
|
||||
continue;
|
||||
}
|
||||
else
|
||||
goto default;
|
||||
default:
|
||||
c = escapeSequence(c2);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case '$':
|
||||
if (!supportInterpolation)
|
||||
goto default;
|
||||
|
||||
if (!handleInterpolatedSegment(t, start))
|
||||
goto default;
|
||||
|
||||
continue;
|
||||
case '\n':
|
||||
endOfLine();
|
||||
if (Ccompile)
|
||||
|
@ -1835,7 +1976,10 @@ class Lexer
|
|||
case '"':
|
||||
if (c != tc)
|
||||
goto default;
|
||||
t.setString(stringbuffer);
|
||||
if (supportInterpolation)
|
||||
t.appendInterpolatedPart(stringbuffer);
|
||||
else
|
||||
t.setString(stringbuffer);
|
||||
if (!Ccompile)
|
||||
stringPostfix(t);
|
||||
return;
|
||||
|
|
|
@ -27,9 +27,11 @@ import dmd.denum;
|
|||
import dmd.dstruct;
|
||||
import dmd.dsymbol;
|
||||
import dmd.dtemplate;
|
||||
import dmd.enumsem;
|
||||
import dmd.errors;
|
||||
import dmd.expression;
|
||||
import dmd.func;
|
||||
import dmd.funcsem;
|
||||
import dmd.globals;
|
||||
import dmd.hdrgen;
|
||||
import dmd.id;
|
||||
|
@ -516,16 +518,39 @@ extern (C++) abstract class Type : ASTNode
|
|||
Terror
|
||||
];
|
||||
|
||||
static Type merge(Type t)
|
||||
{
|
||||
import dmd.basicmangle : tyToDecoBuffer;
|
||||
|
||||
OutBuffer buf;
|
||||
buf.reserve(3);
|
||||
|
||||
if (t.ty == Tnoreturn)
|
||||
buf.writestring("Nn");
|
||||
else
|
||||
tyToDecoBuffer(buf, t.ty);
|
||||
|
||||
auto sv = t.stringtable.update(buf[]);
|
||||
if (sv.value)
|
||||
return sv.value;
|
||||
else
|
||||
{
|
||||
t.deco = cast(char*)sv.toDchars();
|
||||
sv.value = t;
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; basetab[i] != Terror; i++)
|
||||
{
|
||||
Type t = new TypeBasic(basetab[i]);
|
||||
t = t.merge();
|
||||
t = merge(t);
|
||||
basic[basetab[i]] = t;
|
||||
}
|
||||
basic[Terror] = new TypeError();
|
||||
|
||||
tnoreturn = new TypeNoreturn();
|
||||
tnoreturn.deco = tnoreturn.merge().deco;
|
||||
tnoreturn.deco = merge(tnoreturn).deco;
|
||||
basic[Tnoreturn] = tnoreturn;
|
||||
|
||||
tvoid = basic[Tvoid];
|
||||
|
@ -560,7 +585,7 @@ extern (C++) abstract class Type : ASTNode
|
|||
terror = basic[Terror];
|
||||
tnoreturn = basic[Tnoreturn];
|
||||
tnull = new TypeNull();
|
||||
tnull.deco = tnull.merge().deco;
|
||||
tnull.deco = merge(tnull).deco;
|
||||
|
||||
tvoidptr = tvoid.pointerTo();
|
||||
tstring = tchar.immutableOf().arrayOf();
|
||||
|
@ -601,29 +626,6 @@ extern (C++) abstract class Type : ASTNode
|
|||
return cast(uint)size(Loc.initial);
|
||||
}
|
||||
|
||||
/*************************************
|
||||
* This version does a merge even if the deco is already computed.
|
||||
* Necessary for types that have a deco, but are not merged.
|
||||
*/
|
||||
final Type merge2()
|
||||
{
|
||||
//printf("merge2(%s)\n", toChars());
|
||||
Type t = this;
|
||||
assert(t);
|
||||
if (!t.deco)
|
||||
return t.merge();
|
||||
|
||||
auto sv = stringtable.lookup(t.deco, strlen(t.deco));
|
||||
if (sv && sv.value)
|
||||
{
|
||||
t = sv.value;
|
||||
assert(t.deco);
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
return t;
|
||||
}
|
||||
|
||||
/*********************************
|
||||
* Store this type's modifier name into buf.
|
||||
*/
|
||||
|
@ -1693,7 +1695,7 @@ extern (C++) abstract class Type : ASTNode
|
|||
if (callable)
|
||||
{
|
||||
auto fd = resolveFuncCall(Loc.initial, null, callable, null, this, ArgumentList(), FuncResolveFlag.quiet);
|
||||
if (!fd || fd.errors || !fd.functionSemantic())
|
||||
if (!fd || fd.errors || !functionSemantic(fd))
|
||||
return Type.terror;
|
||||
|
||||
auto t = fd.type.nextOf();
|
||||
|
|
|
@ -233,7 +233,6 @@ public:
|
|||
uinteger_t size();
|
||||
virtual uinteger_t size(const Loc &loc);
|
||||
virtual unsigned alignsize();
|
||||
Type *merge2();
|
||||
void modToBuffer(OutBuffer& buf) const;
|
||||
char *modToChars() const;
|
||||
|
||||
|
@ -909,3 +908,4 @@ Covariant covariant(Type *, Type *, StorageClass * = NULL, bool = false);
|
|||
bool isBaseOf(Type *tthis, Type *t, int *poffset);
|
||||
Type *trySemantic(Type *type, const Loc &loc, Scope *sc);
|
||||
void purityLevel(TypeFunction *type);
|
||||
Type *merge2(Type *type);
|
||||
|
|
|
@ -2015,6 +2015,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
|
|||
case TOK.wcharLiteral:
|
||||
case TOK.dcharLiteral:
|
||||
case TOK.string_:
|
||||
case TOK.interpolated:
|
||||
case TOK.hexadecimalString:
|
||||
case TOK.file:
|
||||
case TOK.fileFullPath:
|
||||
|
@ -5820,6 +5821,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
|
|||
case TOK.true_:
|
||||
case TOK.false_:
|
||||
case TOK.string_:
|
||||
case TOK.interpolated:
|
||||
case TOK.hexadecimalString:
|
||||
case TOK.leftParenthesis:
|
||||
case TOK.cast_:
|
||||
|
@ -7313,6 +7315,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
|
|||
case TOK.wcharLiteral:
|
||||
case TOK.dcharLiteral:
|
||||
case TOK.string_:
|
||||
case TOK.interpolated:
|
||||
case TOK.hexadecimalString:
|
||||
case TOK.file:
|
||||
case TOK.fileFullPath:
|
||||
|
@ -8177,6 +8180,11 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
|
|||
nextToken();
|
||||
break;
|
||||
|
||||
case TOK.interpolated:
|
||||
e = new AST.InterpExp(loc, token.interpolatedSet, token.postfix);
|
||||
nextToken();
|
||||
break;
|
||||
|
||||
case TOK.string_:
|
||||
case TOK.hexadecimalString:
|
||||
const bool hexString = token.value == TOK.hexadecimalString;
|
||||
|
@ -8810,6 +8818,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
|
|||
case TOK.wcharLiteral:
|
||||
case TOK.dcharLiteral:
|
||||
case TOK.string_:
|
||||
case TOK.interpolated:
|
||||
case TOK.function_:
|
||||
case TOK.delegate_:
|
||||
case TOK.typeof_:
|
||||
|
|
|
@ -183,6 +183,7 @@ public:
|
|||
void visit(AST.TypeidExp e) { visit(cast(AST.Expression)e); }
|
||||
void visit(AST.TraitsExp e) { visit(cast(AST.Expression)e); }
|
||||
void visit(AST.StringExp e) { visit(cast(AST.Expression)e); }
|
||||
void visit(AST.InterpExp e) { visit(cast(AST.Expression)e); }
|
||||
void visit(AST.NewExp e) { visit(cast(AST.Expression)e); }
|
||||
void visit(AST.AssocArrayLiteralExp e) { visit(cast(AST.Expression)e); }
|
||||
void visit(AST.ArrayLiteralExp e) { visit(cast(AST.Expression)e); }
|
||||
|
|
|
@ -70,7 +70,7 @@ D_CODE =
|
|||
<div class="code_sample">
|
||||
<div class="dlang">
|
||||
<ol class="code_lines">
|
||||
<li><code class="code">$0</code></li>
|
||||
<li><pre><code class="code">$0</code></pre></li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -81,7 +81,7 @@ OTHER_CODE =
|
|||
<div class="code_sample">
|
||||
<div class="dlang">
|
||||
<ol class="code_lines">
|
||||
<li><code class="code language-$1">$+</code></li>
|
||||
<li><pre><code class="code language-$1">$+</code></pre></li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -517,6 +517,10 @@ DDOC =
|
|||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.ddoc .code_lines pre {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
.ddoc .code_lines li:only-of-type::before {
|
||||
color: rgba(255, 255, 255, 1);
|
||||
content: " ";
|
||||
|
|
|
@ -78,7 +78,7 @@ nothrow:
|
|||
private const(char)[] str;
|
||||
|
||||
///
|
||||
extern (D) this(const(char)[] str) pure
|
||||
extern (D) this(const char[] str) pure
|
||||
{
|
||||
this.str = str.xarraydup;
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ nothrow:
|
|||
}
|
||||
|
||||
/// Ditto
|
||||
extern (D) static bool equals(const(char)[] name1, const(char)[] name2) pure @nogc
|
||||
extern (D) static bool equals(const char[] name1, const char[] name2) pure @nogc
|
||||
{
|
||||
if (name1.length != name2.length)
|
||||
return false;
|
||||
|
@ -125,7 +125,7 @@ nothrow:
|
|||
}
|
||||
|
||||
/// Ditto
|
||||
extern (D) static bool absolute(const(char)[] name) pure @nogc @safe
|
||||
extern (D) static bool absolute(const char[] name) pure @nogc @safe
|
||||
{
|
||||
if (!name.length)
|
||||
return false;
|
||||
|
@ -189,7 +189,7 @@ nothrow:
|
|||
}
|
||||
|
||||
/// Ditto
|
||||
extern (D) static const(char)[] ext(const(char)[] str) nothrow pure @safe @nogc
|
||||
extern (D) static const(char)[] ext(const char[] str) nothrow pure @safe @nogc
|
||||
{
|
||||
foreach_reverse (idx, char e; str)
|
||||
{
|
||||
|
@ -249,7 +249,7 @@ nothrow:
|
|||
}
|
||||
|
||||
/// Ditto
|
||||
extern (D) static const(char)[] removeExt(const(char)[] str)
|
||||
extern (D) static const(char)[] removeExt(const char[] str)
|
||||
{
|
||||
auto e = ext(str);
|
||||
if (e.length)
|
||||
|
@ -278,7 +278,7 @@ nothrow:
|
|||
}
|
||||
|
||||
/// Ditto
|
||||
extern (D) static const(char)[] name(const(char)[] str) pure @nogc @safe
|
||||
extern (D) static const(char)[] name(const char[] str) pure @nogc @safe
|
||||
{
|
||||
foreach_reverse (idx, char e; str)
|
||||
{
|
||||
|
@ -333,7 +333,7 @@ nothrow:
|
|||
}
|
||||
|
||||
/// Ditto
|
||||
extern (D) static const(char)[] path(const(char)[] str)
|
||||
extern (D) static const(char)[] path(const char[] str)
|
||||
{
|
||||
const n = name(str);
|
||||
bool hasTrailingSlash;
|
||||
|
@ -358,7 +358,7 @@ nothrow:
|
|||
/**************************************
|
||||
* Replace filename portion of path.
|
||||
*/
|
||||
extern (D) static const(char)[] replaceName(const(char)[] path, const(char)[] name)
|
||||
extern (D) static const(char)[] replaceName(const char[] path, const char[] name)
|
||||
{
|
||||
if (absolute(name))
|
||||
return name;
|
||||
|
@ -387,7 +387,7 @@ nothrow:
|
|||
}
|
||||
|
||||
/// Ditto
|
||||
extern(D) static const(char)[] combine(const(char)[] path, const(char)[] name)
|
||||
extern(D) static const(char)[] combine(const char[] path, const char[] name)
|
||||
{
|
||||
return !path.length ? name : buildPath(path, name);
|
||||
}
|
||||
|
@ -401,7 +401,7 @@ nothrow:
|
|||
assert(combine("foo/"[], "bar"[]) == "foo/bar");
|
||||
}
|
||||
|
||||
static const(char)[] buildPath(const(char)[][] fragments...)
|
||||
static const(char)[] buildPath(const char[][] fragments...)
|
||||
{
|
||||
size_t size;
|
||||
foreach (f; fragments)
|
||||
|
@ -563,7 +563,7 @@ nothrow:
|
|||
* Returns:
|
||||
* A newly allocated string (free with `FileName.free`)
|
||||
*/
|
||||
extern(D) static char[] addExt(const(char)[] name, const(char)[] ext) pure
|
||||
extern(D) static char[] addExt(const char[] name, const char[] ext) pure
|
||||
{
|
||||
const len = name.length + ext.length + 2;
|
||||
auto s = cast(char*)mem.xmalloc(len);
|
||||
|
@ -584,7 +584,7 @@ nothrow:
|
|||
}
|
||||
|
||||
/// Ditto
|
||||
extern (D) static const(char)[] defaultExt(const(char)[] name, const(char)[] ext)
|
||||
extern (D) static const(char)[] defaultExt(const char[] name, const char[] ext)
|
||||
{
|
||||
auto e = FileName.ext(name);
|
||||
if (e.length) // it already has an extension
|
||||
|
@ -608,7 +608,7 @@ nothrow:
|
|||
}
|
||||
|
||||
/// Ditto
|
||||
extern (D) static const(char)[] forceExt(const(char)[] name, const(char)[] ext)
|
||||
extern (D) static const(char)[] forceExt(const char[] name, const char[] ext)
|
||||
{
|
||||
if (auto e = FileName.ext(name))
|
||||
return addExt(name[0 .. $ - e.length - 1], ext);
|
||||
|
@ -630,7 +630,7 @@ nothrow:
|
|||
}
|
||||
|
||||
/// Ditto
|
||||
extern (D) static bool equalsExt(const(char)[] name, const(char)[] ext) pure @nogc
|
||||
extern (D) static bool equalsExt(const char[] name, const char[] ext) pure @nogc
|
||||
{
|
||||
auto e = FileName.ext(name);
|
||||
if (!e.length && !ext.length)
|
||||
|
@ -665,12 +665,12 @@ nothrow:
|
|||
* Returns:
|
||||
* if found, filename combined with path, otherwise null
|
||||
*/
|
||||
extern (C++) static const(char)* searchPath(Strings* path, const(char)* name, bool cwd)
|
||||
extern (C++) static const(char)* searchPath(const ref Strings path, const char* name, bool cwd)
|
||||
{
|
||||
return searchPath(path, name.toDString, cwd).ptr;
|
||||
return searchPath(path[], name.toDString, cwd).ptr;
|
||||
}
|
||||
|
||||
extern (D) static const(char)[] searchPath(Strings* path, const(char)[] name, bool cwd)
|
||||
extern (D) static const(char)[] searchPath(const char*[] path, const char[] name, bool cwd)
|
||||
{
|
||||
if (absolute(name))
|
||||
{
|
||||
|
@ -681,24 +681,21 @@ nothrow:
|
|||
if (exists(name))
|
||||
return name;
|
||||
}
|
||||
if (path)
|
||||
foreach (p; path)
|
||||
{
|
||||
foreach (p; *path)
|
||||
auto n = combine(p.toDString, name);
|
||||
if (exists(n))
|
||||
return n;
|
||||
//combine might return name
|
||||
if (n.ptr != name.ptr)
|
||||
{
|
||||
auto n = combine(p.toDString, name);
|
||||
if (exists(n))
|
||||
return n;
|
||||
//combine might return name
|
||||
if (n.ptr != name.ptr)
|
||||
{
|
||||
mem.xfree(cast(void*)n.ptr);
|
||||
}
|
||||
mem.xfree(cast(void*)n.ptr);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
extern (D) static const(char)[] searchPath(const(char)* path, const(char)[] name, bool cwd)
|
||||
extern (D) static const(char)[] searchPath(const char* path, const char[] name, bool cwd)
|
||||
{
|
||||
if (absolute(name))
|
||||
{
|
||||
|
@ -738,7 +735,7 @@ nothrow:
|
|||
* Returns:
|
||||
* index of the first reserved character in path if found, size_t.max otherwise
|
||||
*/
|
||||
extern (D) static size_t findReservedChar(const(char)[] name) pure @nogc @safe
|
||||
extern (D) static size_t findReservedChar(const char[] name) pure @nogc @safe
|
||||
{
|
||||
version (Windows)
|
||||
{
|
||||
|
@ -787,7 +784,7 @@ nothrow:
|
|||
* Returns:
|
||||
* true if path contains '..' reference to parent directory
|
||||
*/
|
||||
extern (D) static bool refersToParentDir(const(char)[] name) pure @nogc @safe
|
||||
extern (D) static bool refersToParentDir(const char[] name) pure @nogc @safe
|
||||
{
|
||||
size_t s = 0;
|
||||
foreach (i; 0 .. name.length)
|
||||
|
@ -845,7 +842,7 @@ nothrow:
|
|||
}
|
||||
|
||||
/// Ditto
|
||||
extern (D) static int exists(const(char)[] name)
|
||||
extern (D) static int exists(const char[] name)
|
||||
{
|
||||
if (!name.length)
|
||||
return 0;
|
||||
|
@ -892,7 +889,7 @@ nothrow:
|
|||
Returns:
|
||||
`true` if the directory exists or was successfully created
|
||||
*/
|
||||
extern (D) static bool ensurePathExists(const(char)[] path)
|
||||
extern (D) static bool ensurePathExists(const char[] path)
|
||||
{
|
||||
//printf("FileName::ensurePathExists(%s)\n", path ? path : "");
|
||||
if (!path.length)
|
||||
|
@ -967,7 +964,7 @@ nothrow:
|
|||
}
|
||||
|
||||
/// Ditto
|
||||
extern (D) static const(char)[] canonicalName(const(char)[] name)
|
||||
extern (D) static const(char)[] canonicalName(const char[] name)
|
||||
{
|
||||
version (Posix)
|
||||
{
|
||||
|
@ -1127,7 +1124,7 @@ version(Windows)
|
|||
* References:
|
||||
* https://msdn.microsoft.com/en-us/library/windows/desktop/aa363855(v=vs.85).aspx
|
||||
*/
|
||||
private int _mkdir(const(char)[] path) nothrow
|
||||
private int _mkdir(const char[] path) nothrow
|
||||
{
|
||||
const createRet = path.extendedPathThen!(
|
||||
p => CreateDirectoryW(&p[0], null /*securityAttributes*/));
|
||||
|
@ -1175,7 +1172,7 @@ version(Windows)
|
|||
* Returns:
|
||||
* The result of calling F on the UTF16 version of str.
|
||||
*/
|
||||
private auto toWStringzThen(alias F)(const(char)[] str) nothrow
|
||||
private auto toWStringzThen(alias F)(const char[] str) nothrow
|
||||
{
|
||||
import dmd.common.smallbuffer : SmallBuffer, toWStringz;
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ public:
|
|||
|
||||
bool equalsExt(const char *ext);
|
||||
|
||||
static const char *searchPath(Strings *path, const char *name, bool cwd);
|
||||
static const char *searchPath(Strings& path, const char *name, bool cwd);
|
||||
static int exists(const char *name);
|
||||
static bool ensurePathExists(const char *path);
|
||||
static const char *canonicalName(const char *name);
|
||||
|
|
|
@ -41,6 +41,7 @@ import dmd.escape;
|
|||
import dmd.expression;
|
||||
import dmd.expressionsem;
|
||||
import dmd.func;
|
||||
import dmd.funcsem;
|
||||
import dmd.globals;
|
||||
import dmd.id;
|
||||
import dmd.identifier;
|
||||
|
@ -384,7 +385,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
|
|||
}
|
||||
}
|
||||
|
||||
funcdecl.declareThis(sc2);
|
||||
declareThis(funcdecl, sc2);
|
||||
|
||||
// Reverts: https://issues.dlang.org/show_bug.cgi?id=5710
|
||||
// No compiler supports this, and there was never any spec for it.
|
||||
|
|
|
@ -43,6 +43,7 @@ import dmd.escape;
|
|||
import dmd.expression;
|
||||
import dmd.expressionsem;
|
||||
import dmd.func;
|
||||
import dmd.funcsem;
|
||||
import dmd.globals;
|
||||
import dmd.gluelayer;
|
||||
import dmd.hdrgen;
|
||||
|
@ -1284,7 +1285,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
|
|||
Type tfront;
|
||||
if (auto fd = sfront.isFuncDeclaration())
|
||||
{
|
||||
if (!fd.functionSemantic())
|
||||
if (!functionSemantic(fd))
|
||||
return rangeError();
|
||||
tfront = fd.type;
|
||||
}
|
||||
|
|
1497
gcc/d/dmd/templatesem.d
Normal file
1497
gcc/d/dmd/templatesem.d
Normal file
File diff suppressed because it is too large
Load diff
|
@ -124,6 +124,7 @@ enum TOK : ubyte
|
|||
// Leaf operators
|
||||
identifier,
|
||||
string_,
|
||||
interpolated,
|
||||
hexadecimalString,
|
||||
this_,
|
||||
super_,
|
||||
|
@ -380,6 +381,7 @@ enum EXP : ubyte
|
|||
// Leaf operators
|
||||
identifier,
|
||||
string_,
|
||||
interpolated,
|
||||
this_,
|
||||
super_,
|
||||
halt,
|
||||
|
@ -623,6 +625,10 @@ static immutable TOK[TOK.max + 1] Ckeywords =
|
|||
}
|
||||
} ();
|
||||
|
||||
struct InterpolatedSet {
|
||||
// all strings in the parts are zero terminated at length+1
|
||||
string[] parts;
|
||||
}
|
||||
|
||||
/***********************************************************
|
||||
*/
|
||||
|
@ -645,7 +651,11 @@ extern (C++) struct Token
|
|||
|
||||
struct
|
||||
{
|
||||
const(char)* ustring; // UTF8 string
|
||||
union
|
||||
{
|
||||
const(char)* ustring; // UTF8 string
|
||||
InterpolatedSet* interpolatedSet;
|
||||
}
|
||||
uint len;
|
||||
ubyte postfix; // 'c', 'w', 'd'
|
||||
}
|
||||
|
@ -833,6 +843,7 @@ extern (C++) struct Token
|
|||
// For debugging
|
||||
TOK.error: "error",
|
||||
TOK.string_: "string",
|
||||
TOK.interpolated: "interpolated string",
|
||||
TOK.onScopeExit: "scope(exit)",
|
||||
TOK.onScopeSuccess: "scope(success)",
|
||||
TOK.onScopeFailure: "scope(failure)",
|
||||
|
@ -910,6 +921,24 @@ nothrow:
|
|||
return 0;
|
||||
}
|
||||
|
||||
extern(D) void appendInterpolatedPart(const ref OutBuffer buf) {
|
||||
appendInterpolatedPart(cast(const(char)*)buf[].ptr, buf.length);
|
||||
}
|
||||
extern(D) void appendInterpolatedPart(const(char)[] str) {
|
||||
appendInterpolatedPart(str.ptr, str.length);
|
||||
}
|
||||
extern(D) void appendInterpolatedPart(const(char)* ptr, size_t length) {
|
||||
assert(value == TOK.interpolated);
|
||||
if (interpolatedSet is null)
|
||||
interpolatedSet = new InterpolatedSet;
|
||||
|
||||
auto s = cast(char*)mem.xmalloc_noscan(length + 1);
|
||||
memcpy(s, ptr, length);
|
||||
s[length] = 0;
|
||||
|
||||
interpolatedSet.parts ~= cast(string) s[0 .. length];
|
||||
}
|
||||
|
||||
/****
|
||||
* Set to contents of ptr[0..length]
|
||||
* Params:
|
||||
|
@ -918,6 +947,7 @@ nothrow:
|
|||
*/
|
||||
void setString(const(char)* ptr, size_t length)
|
||||
{
|
||||
value = TOK.string_;
|
||||
auto s = cast(char*)mem.xmalloc_noscan(length + 1);
|
||||
memcpy(s, ptr, length);
|
||||
s[length] = 0;
|
||||
|
@ -941,6 +971,7 @@ nothrow:
|
|||
*/
|
||||
void setString()
|
||||
{
|
||||
value = TOK.string_;
|
||||
ustring = "";
|
||||
len = 0;
|
||||
postfix = 0;
|
||||
|
|
|
@ -133,6 +133,7 @@ enum class TOK : unsigned char
|
|||
// Leaf operators
|
||||
identifier,
|
||||
string_,
|
||||
interpolated,
|
||||
hexadecimalString,
|
||||
this_,
|
||||
super_,
|
||||
|
@ -390,6 +391,7 @@ enum class EXP : unsigned char
|
|||
// Leaf operators
|
||||
identifier,
|
||||
string_,
|
||||
interpolated,
|
||||
this_,
|
||||
super_,
|
||||
halt,
|
||||
|
@ -461,7 +463,12 @@ struct Token
|
|||
real_t floatvalue;
|
||||
|
||||
struct
|
||||
{ utf8_t *ustring; // UTF8 string
|
||||
{
|
||||
union
|
||||
{
|
||||
utf8_t *ustring; // UTF8 string
|
||||
void *interpolatedSet;
|
||||
};
|
||||
unsigned len;
|
||||
unsigned char postfix; // 'c', 'w', 'd'
|
||||
};
|
||||
|
|
|
@ -36,6 +36,7 @@ import dmd.errorsink;
|
|||
import dmd.expression;
|
||||
import dmd.expressionsem;
|
||||
import dmd.func;
|
||||
import dmd.funcsem;
|
||||
import dmd.globals;
|
||||
import dmd.hdrgen;
|
||||
import dmd.id;
|
||||
|
@ -1306,7 +1307,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
|
|||
// attribute inference.
|
||||
if (fd && fd.parent && fd.parent.isTemplateInstance)
|
||||
{
|
||||
fd.functionSemantic3();
|
||||
functionSemantic3(fd);
|
||||
tf = fd.type.isTypeFunction();
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ import dmd.dstruct;
|
|||
import dmd.dsymbol;
|
||||
import dmd.dsymbolsem;
|
||||
import dmd.dtemplate;
|
||||
import dmd.enumsem;
|
||||
import dmd.errors;
|
||||
import dmd.errorsink;
|
||||
import dmd.expression;
|
||||
|
@ -2919,6 +2920,29 @@ extern (C++) Type merge(Type type)
|
|||
return type;
|
||||
}
|
||||
|
||||
/*************************************
|
||||
* This version does a merge even if the deco is already computed.
|
||||
* Necessary for types that have a deco, but are not merged.
|
||||
*/
|
||||
extern(C++) Type merge2(Type type)
|
||||
{
|
||||
//printf("merge2(%s)\n", toChars());
|
||||
Type t = type;
|
||||
assert(t);
|
||||
if (!t.deco)
|
||||
return t.merge();
|
||||
|
||||
auto sv = Type.stringtable.lookup(t.deco, strlen(t.deco));
|
||||
if (sv && sv.value)
|
||||
{
|
||||
t = sv.value;
|
||||
assert(t.deco);
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
return t;
|
||||
}
|
||||
|
||||
/***************************************
|
||||
* Calculate built-in properties which just the type is necessary.
|
||||
*
|
||||
|
@ -5697,7 +5721,7 @@ Type getComplexLibraryType(const ref Loc loc, Scope* sc, TY ty)
|
|||
* Returns:
|
||||
* An enum value of either `Covariant.yes` or a reason it's not covariant.
|
||||
*/
|
||||
extern (C++) Covariant covariant(Type src, Type t, StorageClass* pstc = null, bool cppCovariant = false)
|
||||
extern(C++) Covariant covariant(Type src, Type t, StorageClass* pstc = null, bool cppCovariant = false)
|
||||
{
|
||||
version (none)
|
||||
{
|
||||
|
|
|
@ -65,6 +65,7 @@ extern (C++) bool genTypeInfo(Expression e, const ref Loc loc, Type torig, Scope
|
|||
fatal();
|
||||
}
|
||||
|
||||
import dmd.typesem : merge2;
|
||||
Type t = torig.merge2(); // do this since not all Type's are merge'd
|
||||
bool needsCodegen = false;
|
||||
if (!t.vtinfo)
|
||||
|
|
|
@ -195,6 +195,7 @@ class ThisExp;
|
|||
class SuperExp;
|
||||
class NullExp;
|
||||
class StringExp;
|
||||
class InterpExp;
|
||||
class TupleExp;
|
||||
class ArrayLiteralExp;
|
||||
class AssocArrayLiteralExp;
|
||||
|
@ -480,6 +481,7 @@ public:
|
|||
virtual void visit(TypeidExp *e) { visit((Expression *)e); }
|
||||
virtual void visit(TraitsExp *e) { visit((Expression *)e); }
|
||||
virtual void visit(StringExp *e) { visit((Expression *)e); }
|
||||
virtual void visit(InterpExp *e) { visit((Expression *)e); }
|
||||
virtual void visit(NewExp *e) { visit((Expression *)e); }
|
||||
virtual void visit(AssocArrayLiteralExp *e) { visit((Expression *)e); }
|
||||
virtual void visit(ArrayLiteralExp *e) { visit((Expression *)e); }
|
||||
|
|
|
@ -2495,17 +2495,18 @@ public:
|
|||
|
||||
for (size_t i = 0; i < e->len; i++)
|
||||
{
|
||||
tree value = build_integer_cst (e->getCodeUnit (i), etype);
|
||||
tree value = build_integer_cst (e->getIndex (i), etype);
|
||||
CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
|
||||
}
|
||||
|
||||
tree ctor = build_constructor (type, elms);
|
||||
TREE_CONSTANT (ctor) = 1;
|
||||
this->result_ = ctor;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Copy the string contents to a null terminated string. */
|
||||
/* Copy the string contents to a null terminated STRING_CST. */
|
||||
dinteger_t length = (e->len * e->sz);
|
||||
char *string = XALLOCAVEC (char, length + e->sz);
|
||||
memset (string, 0, length + e->sz);
|
||||
|
@ -2514,7 +2515,18 @@ public:
|
|||
|
||||
/* String value and type includes the null terminator. */
|
||||
tree value = build_string (length + e->sz, string);
|
||||
TREE_TYPE (value) = make_array_type (tb->nextOf (), length + 1);
|
||||
if (e->sz <= 4)
|
||||
TREE_TYPE (value) = make_array_type (tb->nextOf (), length + 1);
|
||||
else
|
||||
{
|
||||
/* Hexadecimal literal strings with an 8-byte character type are
|
||||
just an alternative way to store an array of `ulong'.
|
||||
Treat it as if it were a `uint[]' array instead. */
|
||||
dinteger_t resize = e->sz / 4;
|
||||
TREE_TYPE (value) = make_array_type (Type::tuns32,
|
||||
(length * resize) + resize);
|
||||
}
|
||||
|
||||
value = build_address (value);
|
||||
|
||||
if (tb->ty == TY::Tarray)
|
||||
|
|
|
@ -259,8 +259,9 @@ create_tinfo_types (Module *mod)
|
|||
array_type_node, array_type_node, array_type_node,
|
||||
array_type_node, ptr_type_node, ptr_type_node,
|
||||
ptr_type_node, d_uint_type, ptr_type_node,
|
||||
array_type_node, ptr_type_node, d_ulong_type,
|
||||
d_ulong_type, ptr_type_node, NULL);
|
||||
array_type_node, ptr_type_node, ptr_type_node,
|
||||
d_uint_type, d_uint_type, d_uint_type, d_uint_type,
|
||||
NULL);
|
||||
|
||||
object_module = mod;
|
||||
}
|
||||
|
@ -577,7 +578,7 @@ public:
|
|||
void visit (TypeInfoConstDeclaration *d) final override
|
||||
{
|
||||
Type *tm = d->tinfo->mutableOf ();
|
||||
tm = tm->merge2 ();
|
||||
tm = merge2 (tm);
|
||||
|
||||
/* The vtable for TypeInfo_Const. */
|
||||
this->layout_base (Type::typeinfoconst);
|
||||
|
@ -594,7 +595,7 @@ public:
|
|||
void visit (TypeInfoInvariantDeclaration *d) final override
|
||||
{
|
||||
Type *tm = d->tinfo->mutableOf ();
|
||||
tm = tm->merge2 ();
|
||||
tm = merge2 (tm);
|
||||
|
||||
/* The vtable for TypeInfo_Invariant. */
|
||||
this->layout_base (Type::typeinfoinvariant);
|
||||
|
@ -611,7 +612,7 @@ public:
|
|||
void visit (TypeInfoSharedDeclaration *d) final override
|
||||
{
|
||||
Type *tm = d->tinfo->unSharedOf ();
|
||||
tm = tm->merge2 ();
|
||||
tm = merge2 (tm);
|
||||
|
||||
/* The vtable for TypeInfo_Shared. */
|
||||
this->layout_base (Type::typeinfoshared);
|
||||
|
@ -628,7 +629,7 @@ public:
|
|||
void visit (TypeInfoWildDeclaration *d) final override
|
||||
{
|
||||
Type *tm = d->tinfo->mutableOf ();
|
||||
tm = tm->merge2 ();
|
||||
tm = merge2 (tm);
|
||||
|
||||
/* The vtable for TypeInfo_Inout. */
|
||||
this->layout_base (Type::typeinfowild);
|
||||
|
@ -934,10 +935,6 @@ public:
|
|||
else
|
||||
this->layout_field (null_pointer_node);
|
||||
|
||||
/* ulong[2] nameSig; */
|
||||
this->layout_field (build_zero_cst (d_ulong_type));
|
||||
this->layout_field (build_zero_cst (d_ulong_type));
|
||||
|
||||
/* immutable(void)* m_RTInfo; */
|
||||
if (cd->getRTInfo)
|
||||
this->layout_field (build_expr (cd->getRTInfo, true));
|
||||
|
@ -945,6 +942,12 @@ public:
|
|||
this->layout_field (size_one_node);
|
||||
else
|
||||
this->layout_field (null_pointer_node);
|
||||
|
||||
/* uint[4] nameSig; */
|
||||
this->layout_field (build_zero_cst (d_uint_type));
|
||||
this->layout_field (build_zero_cst (d_uint_type));
|
||||
this->layout_field (build_zero_cst (d_uint_type));
|
||||
this->layout_field (build_zero_cst (d_uint_type));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -985,15 +988,17 @@ public:
|
|||
this->layout_field (null_array_node);
|
||||
this->layout_field (null_pointer_node);
|
||||
|
||||
/* ulong[2] nameSig; */
|
||||
this->layout_field (build_zero_cst (d_ulong_type));
|
||||
this->layout_field (build_zero_cst (d_ulong_type));
|
||||
|
||||
/* immutable(void)* m_RTInfo; */
|
||||
if (cd->getRTInfo)
|
||||
this->layout_field (build_expr (cd->getRTInfo, true));
|
||||
else
|
||||
this->layout_field (null_pointer_node);
|
||||
|
||||
/* uint[4] nameSig; */
|
||||
this->layout_field (build_zero_cst (d_uint_type));
|
||||
this->layout_field (build_zero_cst (d_uint_type));
|
||||
this->layout_field (build_zero_cst (d_uint_type));
|
||||
this->layout_field (build_zero_cst (d_uint_type));
|
||||
}
|
||||
|
||||
/* Put out array of Interfaces. */
|
||||
|
@ -1546,7 +1551,7 @@ create_typeinfo (Type *type, Module *mod, bool generate)
|
|||
create_frontend_tinfo_types ();
|
||||
|
||||
/* Do this since not all Type's are merged. */
|
||||
Type *t = type->merge2 ();
|
||||
Type *t = merge2 (type);
|
||||
Identifier *ident;
|
||||
|
||||
if (!t->vtinfo)
|
||||
|
|
|
@ -36,12 +36,27 @@ static assert((123 ).stringof == "123");
|
|||
static assert((123u ).stringof == "123u");
|
||||
static assert((123L ).stringof == "123L");
|
||||
static assert((123uL).stringof == "123LU");
|
||||
static assert((123.5 ).stringof == "1.235e+2");
|
||||
static assert((123.5f ).stringof == "1.235e+2F");
|
||||
static assert((123.5L ).stringof == "1.235e+2L");
|
||||
static assert((123.5i ).stringof == "1.235e+2i");
|
||||
static assert((123.5fi).stringof == "1.235e+2Fi");
|
||||
static assert((123.5Li).stringof == "1.235e+2Li");
|
||||
static assert((123.5 +5.5i ).stringof == "1.235e+2 + 5.5e+0i");
|
||||
static assert((123.5f+5.5fi).stringof == "1.235e+2F + 5.5e+0Fi");
|
||||
static assert((123.5L+5.5Li).stringof == "1.235e+2L + 5.5e+0Li");
|
||||
version (GNU)
|
||||
{
|
||||
static assert((123.5 ).stringof == "1.235e+2");
|
||||
static assert((123.5f ).stringof == "1.235e+2F");
|
||||
static assert((123.5L ).stringof == "1.235e+2L");
|
||||
static assert((123.5i ).stringof == "1.235e+2i");
|
||||
static assert((123.5fi).stringof == "1.235e+2Fi");
|
||||
static assert((123.5Li).stringof == "1.235e+2Li");
|
||||
static assert((123.5 +5.5i ).stringof == "1.235e+2 + 5.5e+0i");
|
||||
static assert((123.5f+5.5fi).stringof == "1.235e+2F + 5.5e+0Fi");
|
||||
static assert((123.5L+5.5Li).stringof == "1.235e+2L + 5.5e+0Li");
|
||||
}
|
||||
else
|
||||
{
|
||||
static assert((123.5 ).stringof == "123.5");
|
||||
static assert((123.5f ).stringof == "123.5F");
|
||||
static assert((123.5L ).stringof == "123.5L");
|
||||
static assert((123.5i ).stringof == "123.5i");
|
||||
static assert((123.5fi).stringof == "123.5Fi");
|
||||
static assert((123.5Li).stringof == "123.5Li");
|
||||
static assert((123.5 +5.5i ).stringof == "123.5 + 5.5i");
|
||||
static assert((123.5f+5.5fi).stringof == "123.5F + 5.5Fi");
|
||||
static assert((123.5L+5.5Li).stringof == "123.5L + 5.5Li");
|
||||
}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/b19523.d(12): Error: undefined identifier `SomeStruct`
|
||||
fail_compilation/b19523.d(13): Error: function `b19523.foo(int delegate() arg)` is not callable using argument types `(_error_)`
|
||||
fail_compilation/b19523.d(13): cannot pass argument `__lambda2` of type `_error_` to parameter `int delegate() arg`
|
||||
---
|
||||
----
|
||||
fail_compilation/b19523.d(13): Error: undefined identifier `SomeStruct`
|
||||
fail_compilation/b19523.d(14): Error: function `foo` is not callable using argument types `(_error_)`
|
||||
fail_compilation/b19523.d(14): cannot pass argument `__lambda2` of type `_error_` to parameter `int delegate() arg`
|
||||
fail_compilation/b19523.d(19): `b19523.foo(int delegate() arg)` declared here
|
||||
----
|
||||
*/
|
||||
module b19523;
|
||||
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/b20011.d(25): Error: cannot modify expression `S1(cast(ubyte)0u).member` because it is not an lvalue
|
||||
fail_compilation/b20011.d(28): Error: cannot modify expression `S2(null).member` because it is not an lvalue
|
||||
fail_compilation/b20011.d(29): Error: cannot modify expression `S2(null).member` because it is not an lvalue
|
||||
fail_compilation/b20011.d(32): Error: cannot modify expression `U1(cast(ubyte)0u, ).m2` because it is not an lvalue
|
||||
fail_compilation/b20011.d(37): Error: function `b20011.main.assignableByRef(ref ubyte p)` is not callable using argument types `(ubyte)`
|
||||
fail_compilation/b20011.d(37): cannot pass rvalue argument `S1(cast(ubyte)0u).member` of type `ubyte` to parameter `ref ubyte p`
|
||||
fail_compilation/b20011.d(38): Error: function `b20011.main.assignableByOut(out ubyte p)` is not callable using argument types `(ubyte)`
|
||||
fail_compilation/b20011.d(38): cannot pass rvalue argument `S1(cast(ubyte)0u).member` of type `ubyte` to parameter `out ubyte p`
|
||||
fail_compilation/b20011.d(39): Error: function `b20011.main.assignableByConstRef(ref const(ubyte) p)` is not callable using argument types `(ubyte)`
|
||||
fail_compilation/b20011.d(39): cannot pass rvalue argument `S1(cast(ubyte)0u).member` of type `ubyte` to parameter `ref const(ubyte) p`
|
||||
fail_compilation/b20011.d(28): Error: cannot modify expression `S1(cast(ubyte)0u).member` because it is not an lvalue
|
||||
fail_compilation/b20011.d(31): Error: cannot modify expression `S2(null).member` because it is not an lvalue
|
||||
fail_compilation/b20011.d(32): Error: cannot modify expression `S2(null).member` because it is not an lvalue
|
||||
fail_compilation/b20011.d(35): Error: cannot modify expression `U1(cast(ubyte)0u, ).m2` because it is not an lvalue
|
||||
fail_compilation/b20011.d(40): Error: function `assignableByRef` is not callable using argument types `(ubyte)`
|
||||
fail_compilation/b20011.d(40): cannot pass rvalue argument `S1(cast(ubyte)0u).member` of type `ubyte` to parameter `ref ubyte p`
|
||||
fail_compilation/b20011.d(37): `b20011.main.assignableByRef(ref ubyte p)` declared here
|
||||
fail_compilation/b20011.d(41): Error: function `assignableByOut` is not callable using argument types `(ubyte)`
|
||||
fail_compilation/b20011.d(41): cannot pass rvalue argument `S1(cast(ubyte)0u).member` of type `ubyte` to parameter `out ubyte p`
|
||||
fail_compilation/b20011.d(38): `b20011.main.assignableByOut(out ubyte p)` declared here
|
||||
fail_compilation/b20011.d(42): Error: function `assignableByConstRef` is not callable using argument types `(ubyte)`
|
||||
fail_compilation/b20011.d(42): cannot pass rvalue argument `S1(cast(ubyte)0u).member` of type `ubyte` to parameter `ref const(ubyte) p`
|
||||
fail_compilation/b20011.d(39): `b20011.main.assignableByConstRef(ref const(ubyte) p)` declared here
|
||||
---
|
||||
*/
|
||||
module b20011;
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/bug15613.d(16): Error: function `bug15613.f(int...)` is not callable using argument types `(typeof(null))`
|
||||
fail_compilation/bug15613.d(16): cannot pass argument `null` of type `typeof(null)` to parameter `int...`
|
||||
fail_compilation/bug15613.d(17): Error: function `bug15613.g(Object, ...)` is not callable using argument types `(int)`
|
||||
fail_compilation/bug15613.d(17): cannot pass argument `8` of type `int` to parameter `Object`
|
||||
fail_compilation/bug15613.d(18): Error: function `f` is not callable using argument types `(typeof(null))`
|
||||
fail_compilation/bug15613.d(18): cannot pass argument `null` of type `typeof(null)` to parameter `int...`
|
||||
fail_compilation/bug15613.d(13): `bug15613.f(int...)` declared here
|
||||
fail_compilation/bug15613.d(19): Error: function `g` is not callable using argument types `(int)`
|
||||
fail_compilation/bug15613.d(19): cannot pass argument `8` of type `int` to parameter `Object`
|
||||
fail_compilation/bug15613.d(14): `bug15613.g(Object, ...)` declared here
|
||||
---
|
||||
*/
|
||||
|
||||
|
@ -20,8 +22,9 @@ void main()
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/bug15613.d(32): Error: function `bug15613.h(int[]...)` is not callable using argument types `(int, void function(int[]...))`
|
||||
fail_compilation/bug15613.d(32): cannot pass argument `& h` of type `void function(int[]...)` to parameter `int[]...`
|
||||
fail_compilation/bug15613.d(35): Error: function `h` is not callable using argument types `(int, void function(int[]...))`
|
||||
fail_compilation/bug15613.d(35): cannot pass argument `& h` of type `void function(int[]...)` to parameter `int[]...`
|
||||
fail_compilation/bug15613.d(31): `bug15613.h(int[]...)` declared here
|
||||
---
|
||||
*/
|
||||
|
||||
|
|
|
@ -10,9 +10,11 @@ void g()
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/bug16165.d(6): Error: function `bug16165.f(int x, Object y)` is not callable using argument types `(Object, Object, int)`
|
||||
fail_compilation/bug16165.d(6): Error: function `f` is not callable using argument types `(Object, Object, int)`
|
||||
fail_compilation/bug16165.d(6): cannot pass argument `o` of type `object.Object` to parameter `int x`
|
||||
fail_compilation/bug16165.d(7): Error: function `bug16165.f(int x, Object y)` is not callable using argument types `(int, int, int)`
|
||||
fail_compilation/bug16165.d(1): `bug16165.f(int x, Object y)` declared here
|
||||
fail_compilation/bug16165.d(7): Error: function `f` is not callable using argument types `(int, int, int)`
|
||||
fail_compilation/bug16165.d(7): cannot pass argument `6` of type `int` to parameter `Object y`
|
||||
fail_compilation/bug16165.d(1): `bug16165.f(int x, Object y)` declared here
|
||||
---
|
||||
*/
|
||||
|
|
|
@ -62,12 +62,13 @@ void test3()
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/bug9631.d(79): Error: function `bug9631.arg.f(int i, S s)` is not callable using argument types `(int, S)`
|
||||
fail_compilation/bug9631.d(79): cannot pass argument `y` of type `bug9631.tem!().S` to parameter `bug9631.S s`
|
||||
fail_compilation/bug9631.d(80): Error: function literal `__lambda4(S s)` is not callable using argument types `(S)`
|
||||
fail_compilation/bug9631.d(80): cannot pass argument `x` of type `bug9631.S` to parameter `bug9631.tem!().S s`
|
||||
fail_compilation/bug9631.d(86): Error: constructor `bug9631.arg.A.this(S __param_0)` is not callable using argument types `(S)`
|
||||
fail_compilation/bug9631.d(86): cannot pass argument `S(0)` of type `bug9631.tem!().S` to parameter `bug9631.S __param_0`
|
||||
fail_compilation/bug9631.d(80): Error: function `f` is not callable using argument types `(int, S)`
|
||||
fail_compilation/bug9631.d(80): cannot pass argument `y` of type `bug9631.tem!().S` to parameter `bug9631.S s`
|
||||
fail_compilation/bug9631.d(79): `bug9631.arg.f(int i, S s)` declared here
|
||||
fail_compilation/bug9631.d(81): Error: function literal `__lambda4(S s)` is not callable using argument types `(S)`
|
||||
fail_compilation/bug9631.d(81): cannot pass argument `x` of type `bug9631.S` to parameter `bug9631.tem!().S s`
|
||||
fail_compilation/bug9631.d(87): Error: constructor `bug9631.arg.A.this(S __param_0)` is not callable using argument types `(S)`
|
||||
fail_compilation/bug9631.d(87): cannot pass argument `S(0)` of type `bug9631.tem!().S` to parameter `bug9631.S __param_0`
|
||||
---
|
||||
*/
|
||||
void arg()
|
||||
|
@ -89,12 +90,13 @@ void arg()
|
|||
/*
|
||||
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: 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: template `bug9631.targ.ft2` is not callable using argument types `!()(S, int)`
|
||||
fail_compilation/bug9631.d(108): Candidate is: `ft2(T)(S, T)`
|
||||
fail_compilation/bug9631.d(108): Error: function `ft` is not callable using argument types `(S)`
|
||||
fail_compilation/bug9631.d(108): cannot pass argument `x` of type `bug9631.S` to parameter `bug9631.tem!().S __param_0`
|
||||
fail_compilation/bug9631.d(107): `bug9631.targ.ft!().ft(S __param_0)` declared here
|
||||
fail_compilation/bug9631.d(109): Error: template `ft` is not callable using argument types `!()(S)`
|
||||
fail_compilation/bug9631.d(107): Candidate is: `ft()(tem!().S)`
|
||||
fail_compilation/bug9631.d(111): Error: template `ft2` is not callable using argument types `!()(S, int)`
|
||||
fail_compilation/bug9631.d(110): Candidate is: `ft2(T)(S, T)`
|
||||
---
|
||||
*/
|
||||
void targ()
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/callconst.d(13): Error: function `callconst.func(ref X)` is not callable using argument types `(const(X))`
|
||||
fail_compilation/callconst.d(13): cannot pass argument `x` of type `const(X)` to parameter `ref X`
|
||||
fail_compilation/callconst.d(14): Error: function `func` is not callable using argument types `(const(X))`
|
||||
fail_compilation/callconst.d(14): cannot pass argument `x` of type `const(X)` to parameter `ref X`
|
||||
fail_compilation/callconst.d(17): `callconst.func(ref X)` declared here
|
||||
---
|
||||
*/
|
||||
struct X {}
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
EXTRA_FILES: imports/constraints.d
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/constraints_aggr.d(32): Error: template `imports.constraints.C.f` is not callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_aggr.d(32): Error: template `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: template `imports.constraints.C.g` is not callable using argument types `!()()`
|
||||
fail_compilation/constraints_aggr.d(33): Error: template `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: template `imports.constraints.test1` is not callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func1.d(79): Error: template `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: template `imports.constraints.test2` is not callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func1.d(80): Error: template `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: template `imports.constraints.test3` is not callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func1.d(81): Error: template `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: template `imports.constraints.test4` is not callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func1.d(82): Error: template `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: template `imports.constraints.test5` is not callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func1.d(83): Error: template `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: template `imports.constraints.test6` is not callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func1.d(84): Error: template `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: template `imports.constraints.test7` is not callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func1.d(85): Error: template `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: template `imports.constraints.test8` is not callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func1.d(86): Error: template `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: template `imports.constraints.test9` is not callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func1.d(87): Error: template `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: template `imports.constraints.test10` is not callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func1.d(88): Error: template `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: template `imports.constraints.test11` is not callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func1.d(89): Error: template `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: template `imports.constraints.test12` is not callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func1.d(90): Error: template `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: template `imports.constraints.test1` is not callable using argument types `!()(int, int)`
|
||||
fail_compilation/constraints_func1.d(92): Error: template `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: template `imports.constraints.test13` is not callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func2.d(94): Error: template `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: template `imports.constraints.test14` is not callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func2.d(95): Error: template `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: template `imports.constraints.test15` is not callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func2.d(96): Error: template `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: template `imports.constraints.test16` is not callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func2.d(97): Error: template `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: template `imports.constraints.test17` is not callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func2.d(98): Error: template `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: template `imports.constraints.test18` is not callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func2.d(99): Error: template `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: template `imports.constraints.test19` is not callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func2.d(100): Error: template `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: template `imports.constraints.test20` is not callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func2.d(101): Error: template `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: template `imports.constraints.test21` is not callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func2.d(102): Error: template `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: template `imports.constraints.test22` is not callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func2.d(103): Error: template `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: template `imports.constraints.test23` is not callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func2.d(104): Error: template `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: template `imports.constraints.test24` is not callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func2.d(105): Error: template `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: template `imports.constraints.test25` is not callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func2.d(106): Error: template `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: template `imports.constraints.test26` is not callable using argument types `!(float)(int)`
|
||||
fail_compilation/constraints_func2.d(107): Error: template `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`
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
EXTRA_FILES: imports/constraints.d
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
----
|
||||
fail_compilation/constraints_func3.d(53): Error: none of the overloads of template `imports.constraints.overload` are callable using argument types `!()(int)`
|
||||
fail_compilation/imports/constraints.d(39): Candidates are: `overload(T)(T v)`
|
||||
with `T = int`
|
||||
|
@ -23,27 +23,27 @@ 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: template `imports.constraints.variadic` is not callable using argument types `!()()`
|
||||
fail_compilation/constraints_func3.d(56): Error: template `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: template `imports.constraints.variadic` is not callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func3.d(57): Error: template `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: template `imports.constraints.variadic` is not callable using argument types `!()(int, int)`
|
||||
fail_compilation/constraints_func3.d(58): Error: template `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: template `imports.constraints.variadic` is not callable using argument types `!()(int, int, int)`
|
||||
fail_compilation/constraints_func3.d(59): Error: template `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)`
|
||||
must satisfy the following constraint:
|
||||
` N!int`
|
||||
---
|
||||
----
|
||||
*/
|
||||
|
||||
void main()
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
EXTRA_FILES: imports/constraints.d
|
||||
REQUIRED_ARGS: -verrors=context
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
----
|
||||
fail_compilation/constraints_func4.d(90): Error: none of the overloads of template `imports.constraints.overload` are callable using argument types `!()(int)`
|
||||
overload(0);
|
||||
^
|
||||
|
@ -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: template `imports.constraints.variadic` is not callable using argument types `!()()`
|
||||
fail_compilation/constraints_func4.d(93): Error: template `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: template `imports.constraints.variadic` is not callable using argument types `!()(int)`
|
||||
fail_compilation/constraints_func4.d(94): Error: template `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: template `imports.constraints.variadic` is not callable using argument types `!()(int, int)`
|
||||
fail_compilation/constraints_func4.d(95): Error: template `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: template `imports.constraints.variadic` is not callable using argument types `!()(int, int, int)`
|
||||
fail_compilation/constraints_func4.d(96): Error: template `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)`
|
||||
|
@ -80,7 +80,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);
|
||||
^
|
||||
---
|
||||
----
|
||||
*/
|
||||
|
||||
void main()
|
||||
|
|
|
@ -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: template `diag13942.to!double.to` is not callable using argument types `!()()`
|
||||
fail_compilation/diag13942.d(26): Error: template `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: template `diag16977.templ` is not callable using argument types `!()(int)`
|
||||
fail_compilation/diag16977.d(27): Error: template `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: template `diag20268.__lambda4` is not callable using argument types `!()(int)`
|
||||
fail_compilation/diag20268.d(12): Error: template `__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: template `diag23355.ffi1` is not callable using argument types `!()(int[4])`
|
||||
fail_compilation/diag23355.d(4): Error: template `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: template `diag23355.ffi2` is not callable using argument types `!()(int[4])`
|
||||
fail_compilation/diag23355.d(4): Error: template `ffi2` is not callable using argument types `!()(int[4])`
|
||||
fail_compilation/diag23355.d(2): Candidate is: `ffi2()(T[n] s)`
|
||||
---
|
||||
*/
|
||||
|
|
|
@ -1,32 +1,33 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/diag8101.d(61): Error: function `diag8101.f_0(int)` is not callable using argument types `()`
|
||||
fail_compilation/diag8101.d(61): too few arguments, expected 1, got 0
|
||||
fail_compilation/diag8101.d(62): Error: none of the overloads of `f_1` are callable using argument types `()`
|
||||
fail_compilation/diag8101.d(35): Candidates are: `diag8101.f_1(int)`
|
||||
fail_compilation/diag8101.d(36): `diag8101.f_1(int, int)`
|
||||
fail_compilation/diag8101.d(63): Error: none of the overloads of `f_2` are callable using argument types `()`
|
||||
fail_compilation/diag8101.d(38): Candidates are: `diag8101.f_2(int)`
|
||||
fail_compilation/diag8101.d(39): `diag8101.f_2(int, int)`
|
||||
fail_compilation/diag8101.d(40): `diag8101.f_2(int, int, int)`
|
||||
fail_compilation/diag8101.d(41): `diag8101.f_2(int, int, 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: 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)()`
|
||||
fail_compilation/diag8101.d(49): `t_1(T1, T2)()`
|
||||
fail_compilation/diag8101.d(67): Error: none of the overloads of template `diag8101.t_2` are callable using argument types `!()()`
|
||||
fail_compilation/diag8101.d(51): Candidates are: `t_2(T1)()`
|
||||
fail_compilation/diag8101.d(52): `t_2(T1, T2)()`
|
||||
fail_compilation/diag8101.d(53): `t_2(T1, T2, T3)()`
|
||||
fail_compilation/diag8101.d(54): `t_2(T1, T2, T3, T4)()`
|
||||
fail_compilation/diag8101.d(55): `t_2(T1, T2, T3, T4, T5)()`
|
||||
fail_compilation/diag8101.d(56): `t_2(T1, T2, T3, T4, T5, T6)()`
|
||||
fail_compilation/diag8101.d(67): ... (1 more, -v to show) ...
|
||||
fail_compilation/diag8101.d(62): Error: function `f_0` is not callable using argument types `()`
|
||||
fail_compilation/diag8101.d(62): too few arguments, expected 1, got 0
|
||||
fail_compilation/diag8101.d(34): `diag8101.f_0(int)` declared here
|
||||
fail_compilation/diag8101.d(63): Error: none of the overloads of `f_1` are callable using argument types `()`
|
||||
fail_compilation/diag8101.d(36): Candidates are: `diag8101.f_1(int)`
|
||||
fail_compilation/diag8101.d(37): `diag8101.f_1(int, int)`
|
||||
fail_compilation/diag8101.d(64): Error: none of the overloads of `f_2` are callable using argument types `()`
|
||||
fail_compilation/diag8101.d(39): Candidates are: `diag8101.f_2(int)`
|
||||
fail_compilation/diag8101.d(40): `diag8101.f_2(int, int)`
|
||||
fail_compilation/diag8101.d(41): `diag8101.f_2(int, int, int)`
|
||||
fail_compilation/diag8101.d(42): `diag8101.f_2(int, int, int, int)`
|
||||
fail_compilation/diag8101.d(43): `diag8101.f_2(int, int, int, int, int)`
|
||||
fail_compilation/diag8101.d(44): `diag8101.f_2(int, int, int, int, int, int)`
|
||||
fail_compilation/diag8101.d(64): ... (1 more, -v to show) ...
|
||||
fail_compilation/diag8101.d(66): Error: template `t_0` is not callable using argument types `!()()`
|
||||
fail_compilation/diag8101.d(47): Candidate is: `t_0(T1)()`
|
||||
fail_compilation/diag8101.d(67): Error: none of the overloads of template `diag8101.t_1` are callable using argument types `!()()`
|
||||
fail_compilation/diag8101.d(49): Candidates are: `t_1(T1)()`
|
||||
fail_compilation/diag8101.d(50): `t_1(T1, T2)()`
|
||||
fail_compilation/diag8101.d(68): Error: none of the overloads of template `diag8101.t_2` are callable using argument types `!()()`
|
||||
fail_compilation/diag8101.d(52): Candidates are: `t_2(T1)()`
|
||||
fail_compilation/diag8101.d(53): `t_2(T1, T2)()`
|
||||
fail_compilation/diag8101.d(54): `t_2(T1, T2, T3)()`
|
||||
fail_compilation/diag8101.d(55): `t_2(T1, T2, T3, T4)()`
|
||||
fail_compilation/diag8101.d(56): `t_2(T1, T2, T3, T4, T5)()`
|
||||
fail_compilation/diag8101.d(57): `t_2(T1, T2, T3, T4, T5, T6)()`
|
||||
fail_compilation/diag8101.d(68): ... (1 more, -v to show) ...
|
||||
---
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/diag8648.d(18): Error: undefined identifier `X`
|
||||
fail_compilation/diag8648.d(29): Error: template `diag8648.foo` is not callable using argument types `!()(Foo!(int, 1))`
|
||||
fail_compilation/diag8648.d(29): Error: template `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: template `diag8648.bar` is not callable using argument types `!()(Foo!(int, 1))`
|
||||
fail_compilation/diag8648.d(31): Error: template `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: template `diag8648.bar` is not callable using argument types `!()(Foo!(int, f))`
|
||||
fail_compilation/diag8648.d(32): Error: template `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: template `diag9004.bar` is not callable using argument types `!()(Foo!int, int)`
|
||||
fail_compilation/diag9004.d(21): Error: template `bar` is not callable using argument types `!()(Foo!int, int)`
|
||||
fail_compilation/diag9004.d(14): Candidate is: `bar(FooT)(FooT foo, FooT.T x)`
|
||||
---
|
||||
*/
|
||||
|
|
|
@ -2,10 +2,11 @@
|
|||
REQUIRED_ARGS: -preview=in
|
||||
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: template `diagin.foo1` is not callable using argument types `!()(bool[])`
|
||||
fail_compilation/diagin.d(20): Candidate is: `foo1(T)(in T v, string)`
|
||||
fail_compilation/diagin.d(15): Error: function `foo` is not callable using argument types `()`
|
||||
fail_compilation/diagin.d(15): too few arguments, expected 1, got 0
|
||||
fail_compilation/diagin.d(20): `diagin.foo(in int)` declared here
|
||||
fail_compilation/diagin.d(17): Error: template `foo1` is not callable using argument types `!()(bool[])`
|
||||
fail_compilation/diagin.d(21): Candidate is: `foo1(T)(in T v, string)`
|
||||
---
|
||||
*/
|
||||
|
||||
|
|
|
@ -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: template `fail12744.bar12744A` is not callable using argument types `!(foo12744O)(int)`
|
||||
fail_compilation/fail12744.d(67): Error: template `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: template `fail12744.bar12744A` is not callable using argument types `!(foo12744L)(int)`
|
||||
fail_compilation/fail12744.d(68): Error: template `bar12744A` is not callable using argument types `!(foo12744L)(int)`
|
||||
fail_compilation/fail12744.d(41): Candidate is: `bar12744A(alias f)(auto ref PTT12744!f args)`
|
||||
---
|
||||
*/
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation\fail136.d(10): Error: `"\xef\xbb\xbf"` has no effect
|
||||
fail_compilation/fail136.d(10): Error: `x"EFBBBF"` has no effect
|
||||
---
|
||||
*/
|
||||
|
||||
|
|
|
@ -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: template `fail14669.foo2` is not callable using argument types `!()(int)`
|
||||
fail_compilation/fail14669.d(17): Error: template `foo2` is not callable using argument types `!()(int)`
|
||||
fail_compilation/fail14669.d(12): Candidate is: `foo2()(auto int a)`
|
||||
---
|
||||
*/
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail162.d(25): Error: template `fail162.testHelper` is not callable using argument types `!()(string, string)`
|
||||
fail_compilation/fail162.d(25): Error: template `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,8 +3,9 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail19948.d(15): Error: function `fail19948.func(const(X))` is not callable using argument types `(X)`
|
||||
fail_compilation/fail19948.d(15): cannot pass argument `X()` of type `fail19948.main.X` to parameter `const(fail19948.X)`
|
||||
fail_compilation/fail19948.d(16): Error: function `func` is not callable using argument types `(X)`
|
||||
fail_compilation/fail19948.d(16): cannot pass argument `X()` of type `fail19948.main.X` to parameter `const(fail19948.X)`
|
||||
fail_compilation/fail19948.d(19): `fail19948.func(const(X))` declared here
|
||||
---
|
||||
*/
|
||||
// DISABLED: win32
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
/* REQUIRED_ARGS: -preview=dip1000
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail20183.d(1016): Error: function `fail20183.addr(return ref int b)` is not callable using argument types `(int)`
|
||||
fail_compilation/fail20183.d(1016): Error: function `addr` is not callable using argument types `(int)`
|
||||
fail_compilation/fail20183.d(1016): cannot pass rvalue argument `S(0).i` of type `int` to parameter `return ref int b`
|
||||
fail_compilation/fail20183.d(1005): `fail20183.addr(return ref int b)` declared here
|
||||
fail_compilation/fail20183.d(1017): Error: address of struct temporary returned by `s()` assigned to longer lived variable `q`
|
||||
---
|
||||
*/
|
||||
|
|
|
@ -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: template `fail20730b.atomicOp` is not callable using argument types `!("+=")(shared(uint), int)`
|
||||
fail_compilation/fail20730b.d(26): Error: template `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,10 +2,11 @@
|
|||
|
||||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail20800.d(22): Error: function `fail20800.fun(int a)` is not callable using argument types `(string)`
|
||||
fail_compilation/fail20800.d(22): cannot pass argument `(m()).index()` of type `string` to parameter `int a`
|
||||
---
|
||||
----
|
||||
fail_compilation/fail20800.d(23): Error: function `fun` is not callable using argument types `(string)`
|
||||
fail_compilation/fail20800.d(23): cannot pass argument `(m()).index()` of type `string` to parameter `int a`
|
||||
fail_compilation/fail20800.d(19): `fail20800.fun(int a)` declared here
|
||||
----
|
||||
*/
|
||||
|
||||
struct RegexMatch
|
||||
|
|
|
@ -3,8 +3,9 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail22202.d(21): Error: function `fail22202.fun(SystemCopy __param_0)` is not callable using argument types `(SystemCopy)`
|
||||
fail_compilation/fail22202.d(21): `inout ref inout(SystemCopy)(ref inout(SystemCopy) other)` copy constructor cannot be called from a `pure @safe nogc` context
|
||||
fail_compilation/fail22202.d(22): Error: function `fun` is not callable using argument types `(SystemCopy)`
|
||||
fail_compilation/fail22202.d(22): `inout ref inout(SystemCopy)(ref inout(SystemCopy) other)` copy constructor cannot be called from a `pure @safe nogc` context
|
||||
fail_compilation/fail22202.d(17): `fail22202.fun(SystemCopy __param_0)` declared here
|
||||
---
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail236.d(14): Error: undefined identifier `x`
|
||||
fail_compilation/fail236.d(22): Error: template `fail236.Templ2` is not callable using argument types `!()(int)`
|
||||
fail_compilation/fail236.d(22): Error: template `Templ2` is not callable using argument types `!()(int)`
|
||||
fail_compilation/fail236.d(12): Candidate is: `Templ2(alias a)(x)`
|
||||
---
|
||||
*/
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
/+
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail24301.d(18): Error: function `fail24301.fun(S __param_0)` is not callable using argument types `(S)`
|
||||
fail_compilation/fail24301.d(18): `ref S(ref S)` copy constructor cannot be used because it is annotated with `@disable`
|
||||
fail_compilation/fail24301.d(19): Error: function `fun` is not callable using argument types `(S)`
|
||||
fail_compilation/fail24301.d(19): `ref S(ref S)` copy constructor cannot be used because it is annotated with `@disable`
|
||||
fail_compilation/fail24301.d(14): `fail24301.fun(S __param_0)` declared here
|
||||
---
|
||||
+/
|
||||
struct S
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail263.d(19): Error: function `fail263.f(byte* p)` is not callable using argument types `(const(byte)*)`
|
||||
fail_compilation/fail263.d(19): cannot pass argument `cast(const(byte)*)A` of type `const(byte)*` to parameter `byte* p`
|
||||
---
|
||||
----
|
||||
fail_compilation/fail263.d(20): Error: function `f` is not callable using argument types `(const(byte)*)`
|
||||
fail_compilation/fail263.d(20): cannot pass argument `cast(const(byte)*)A` of type `const(byte)*` to parameter `byte* p`
|
||||
fail_compilation/fail263.d(14): `fail263.f(byte* p)` declared here
|
||||
----
|
||||
*/
|
||||
|
||||
// https://issues.dlang.org/show_bug.cgi?id=2766
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail322.d(13): Error: function `fail322.digestToString2(ref char[16] digest)` is not callable using argument types `(string)`
|
||||
fail_compilation/fail322.d(13): cannot pass rvalue argument `"1234567890123456"` of type `string` to parameter `ref char[16] digest`
|
||||
fail_compilation/fail322.d(15): Error: function `fail322.digestToString2(ref char[16] digest)` is not callable using argument types `(const(char[16]))`
|
||||
fail_compilation/fail322.d(15): cannot pass argument `s` of type `const(char[16])` to parameter `ref char[16] digest`
|
||||
---
|
||||
----
|
||||
fail_compilation/fail322.d(15): Error: function `digestToString2` is not callable using argument types `(string)`
|
||||
fail_compilation/fail322.d(15): cannot pass rvalue argument `"1234567890123456"` of type `string` to parameter `ref char[16] digest`
|
||||
fail_compilation/fail322.d(20): `fail322.digestToString2(ref char[16] digest)` declared here
|
||||
fail_compilation/fail322.d(17): Error: function `digestToString2` is not callable using argument types `(const(char[16]))`
|
||||
fail_compilation/fail322.d(17): cannot pass argument `s` of type `const(char[16])` to parameter `ref char[16] digest`
|
||||
fail_compilation/fail322.d(20): `fail322.digestToString2(ref char[16] digest)` declared here
|
||||
----
|
||||
*/
|
||||
|
||||
void main()
|
||||
|
|
|
@ -1,14 +1,18 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail332.d(22): Error: function `fail332.foo(int __param_0, ...)` is not callable using argument types `()`
|
||||
fail_compilation/fail332.d(22): missing argument for parameter #1: `int __param_0`
|
||||
fail_compilation/fail332.d(23): Error: function `fail332.foo(int __param_0, ...)` is not callable using argument types `(typeof(null))`
|
||||
fail_compilation/fail332.d(23): cannot pass argument `null` of type `typeof(null)` to parameter `int __param_0`
|
||||
fail_compilation/fail332.d(25): Error: function `fail332.baz(int[] __param_0...)` is not callable using argument types `(string)`
|
||||
fail_compilation/fail332.d(25): cannot pass argument `""` of type `string` to parameter `int[] __param_0...`
|
||||
fail_compilation/fail332.d(26): Error: function `fail332.baz(int[] __param_0...)` is not callable using argument types `(int, typeof(null))`
|
||||
fail_compilation/fail332.d(26): cannot pass argument `null` of type `typeof(null)` to parameter `int[] __param_0...`
|
||||
fail_compilation/fail332.d(26): Error: function `foo` is not callable using argument types `()`
|
||||
fail_compilation/fail332.d(26): missing argument for parameter #1: `int __param_0`
|
||||
fail_compilation/fail332.d(21): `fail332.foo(int __param_0, ...)` declared here
|
||||
fail_compilation/fail332.d(27): Error: function `foo` is not callable using argument types `(typeof(null))`
|
||||
fail_compilation/fail332.d(27): cannot pass argument `null` of type `typeof(null)` to parameter `int __param_0`
|
||||
fail_compilation/fail332.d(21): `fail332.foo(int __param_0, ...)` declared here
|
||||
fail_compilation/fail332.d(29): Error: function `baz` is not callable using argument types `(string)`
|
||||
fail_compilation/fail332.d(29): cannot pass argument `""` of type `string` to parameter `int[] __param_0...`
|
||||
fail_compilation/fail332.d(22): `fail332.baz(int[] __param_0...)` declared here
|
||||
fail_compilation/fail332.d(30): Error: function `baz` is not callable using argument types `(int, typeof(null))`
|
||||
fail_compilation/fail332.d(30): cannot pass argument `null` of type `typeof(null)` to parameter `int[] __param_0...`
|
||||
fail_compilation/fail332.d(22): `fail332.baz(int[] __param_0...)` declared here
|
||||
---
|
||||
*/
|
||||
|
||||
|
@ -29,18 +33,24 @@ void test()
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail332.d(50): Error: function `fail332.bar(Object, int[2]...)` is not callable using argument types `()`
|
||||
fail_compilation/fail332.d(50): missing argument for parameter #1: `Object`
|
||||
fail_compilation/fail332.d(51): Error: function `fail332.bar(Object, int[2]...)` is not callable using argument types `(int)`
|
||||
fail_compilation/fail332.d(51): cannot pass argument `4` of type `int` to parameter `Object`
|
||||
fail_compilation/fail332.d(52): Error: function `fail332.bar(Object, int[2]...)` is not callable using argument types `(typeof(null))`
|
||||
fail_compilation/fail332.d(52): expected 2 variadic argument(s), not 0
|
||||
fail_compilation/fail332.d(53): Error: function `fail332.bar(Object, int[2]...)` is not callable using argument types `(typeof(null), int)`
|
||||
fail_compilation/fail332.d(53): expected 2 variadic argument(s), not 1
|
||||
fail_compilation/fail332.d(54): Error: function `fail332.bar(Object, int[2]...)` is not callable using argument types `(typeof(null), int, string)`
|
||||
fail_compilation/fail332.d(54): cannot pass argument `""` of type `string` to parameter `int[2]...`
|
||||
fail_compilation/fail332.d(55): Error: function `fail332.bar(Object, int[2]...)` is not callable using argument types `(typeof(null), int, int, int)`
|
||||
fail_compilation/fail332.d(55): expected 2 variadic argument(s), not 3
|
||||
fail_compilation/fail332.d(60): Error: function `bar` is not callable using argument types `()`
|
||||
fail_compilation/fail332.d(60): missing argument for parameter #1: `Object`
|
||||
fail_compilation/fail332.d(56): `fail332.bar(Object, int[2]...)` declared here
|
||||
fail_compilation/fail332.d(61): Error: function `bar` is not callable using argument types `(int)`
|
||||
fail_compilation/fail332.d(61): cannot pass argument `4` of type `int` to parameter `Object`
|
||||
fail_compilation/fail332.d(56): `fail332.bar(Object, int[2]...)` declared here
|
||||
fail_compilation/fail332.d(62): Error: function `bar` is not callable using argument types `(typeof(null))`
|
||||
fail_compilation/fail332.d(62): expected 2 variadic argument(s), not 0
|
||||
fail_compilation/fail332.d(56): `fail332.bar(Object, int[2]...)` declared here
|
||||
fail_compilation/fail332.d(63): Error: function `bar` is not callable using argument types `(typeof(null), int)`
|
||||
fail_compilation/fail332.d(63): expected 2 variadic argument(s), not 1
|
||||
fail_compilation/fail332.d(56): `fail332.bar(Object, int[2]...)` declared here
|
||||
fail_compilation/fail332.d(64): Error: function `bar` is not callable using argument types `(typeof(null), int, string)`
|
||||
fail_compilation/fail332.d(64): cannot pass argument `""` of type `string` to parameter `int[2]...`
|
||||
fail_compilation/fail332.d(56): `fail332.bar(Object, int[2]...)` declared here
|
||||
fail_compilation/fail332.d(65): Error: function `bar` is not callable using argument types `(typeof(null), int, int, int)`
|
||||
fail_compilation/fail332.d(65): expected 2 variadic argument(s), not 3
|
||||
fail_compilation/fail332.d(56): `fail332.bar(Object, int[2]...)` declared here
|
||||
---
|
||||
*/
|
||||
void bar(Object, int[2]...);
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail58.d(26): Error: function `fail58.SomeFunc(dchar[] pText, out int pStopPosn)` is not callable using argument types `(string, int)`
|
||||
fail_compilation/fail58.d(26): cannot pass argument `"123"` of type `string` to parameter `dchar[] pText`
|
||||
fail_compilation/fail58.d(30): Error: function `fail58.SomeFunc(dchar[] pText, out int pStopPosn)` is not callable using argument types `(string, int)`
|
||||
fail_compilation/fail58.d(30): cannot pass argument `""` of type `string` to parameter `dchar[] pText`
|
||||
---
|
||||
----
|
||||
fail_compilation/fail58.d(28): Error: function `SomeFunc` is not callable using argument types `(string, int)`
|
||||
fail_compilation/fail58.d(28): cannot pass argument `"123"` of type `string` to parameter `dchar[] pText`
|
||||
fail_compilation/fail58.d(14): `fail58.SomeFunc(dchar[] pText, out int pStopPosn)` declared here
|
||||
fail_compilation/fail58.d(32): Error: function `SomeFunc` is not callable using argument types `(string, int)`
|
||||
fail_compilation/fail58.d(32): cannot pass argument `""` of type `string` to parameter `dchar[] pText`
|
||||
fail_compilation/fail58.d(14): `fail58.SomeFunc(dchar[] pText, out int pStopPosn)` declared here
|
||||
----
|
||||
*/
|
||||
debug import std.stdio;
|
||||
const int anything = -1000; // Line #2
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail8009.d(9): Error: template `fail8009.filter` is not callable using argument types `!()(void)`
|
||||
fail_compilation/fail8009.d(9): Error: template `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: template `fail95.A` is not callable using argument types `!()(int)`
|
||||
fail_compilation/fail95.d(19): Error: template `A` is not callable using argument types `!()(int)`
|
||||
fail_compilation/fail95.d(11): Candidate is: `A(alias T)(T)`
|
||||
---
|
||||
*/
|
||||
|
|
|
@ -1,18 +1,39 @@
|
|||
/**
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation\hexstring.d(16): Error: cannot implicitly convert expression `"123F"` of type `string` to `immutable(ubyte[])`
|
||||
fail_compilation\hexstring.d(17): Error: cannot implicitly convert expression `"\x12?"c` of type `string` to `immutable(ubyte[])`
|
||||
fail_compilation\hexstring.d(18): Error: cannot implicitly convert expression `"\x12?"` of type `string` to `immutable(ubyte[])`
|
||||
fail_compilation\hexstring.d(15): Error: cannot implicitly convert expression `"\x12?"` of type `string` to `ubyte[]`
|
||||
---
|
||||
*/
|
||||
immutable ubyte[] s0 = x"123F";
|
||||
static assert(s0[0] == 0x12);
|
||||
static assert(s0[1] == 0x3F);
|
||||
immutable byte[] s1 = x"123F";
|
||||
|
||||
ubyte[] f1 = x"123F";
|
||||
immutable ubyte[] f2 = "123F";
|
||||
immutable ubyte[] f3 = x"123F"c;
|
||||
immutable ubyte[] f4 = cast(string) x"123F";
|
||||
/**
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/hexstring.d(29): Error: cannot implicitly convert expression `"123F"` of type `string` to `immutable(ubyte[])`
|
||||
fail_compilation/hexstring.d(30): Error: cannot implicitly convert expression `x"123F"c` of type `string` to `immutable(ubyte[])`
|
||||
fail_compilation/hexstring.d(31): Error: cannot implicitly convert expression `x"123F"` of type `string` to `immutable(ubyte[])`
|
||||
fail_compilation/hexstring.d(33): Error: hex string length 1 must be a multiple of 2 to cast to `immutable(ushort[])`
|
||||
fail_compilation/hexstring.d(34): Error: hex string length 3 must be a multiple of 4 to cast to `immutable(uint[])`
|
||||
fail_compilation/hexstring.d(35): Error: hex string length 5 must be a multiple of 8 to cast to `immutable(ulong[])`
|
||||
fail_compilation/hexstring.d(36): Error: array cast from `wstring` to `immutable(ulong[])` is not supported at compile time
|
||||
fail_compilation/hexstring.d(36): perhaps remove postfix `w` from hex string
|
||||
fail_compilation/hexstring.d(37): Error: array cast from `string` to `immutable(uint[])` is not supported at compile time
|
||||
fail_compilation/hexstring.d(38): Error: array cast from `string` to `immutable(ushort[])` is not supported at compile time
|
||||
fail_compilation/hexstring.d(39): Error: array cast from `string` to `immutable(uint[])` is not supported at compile time
|
||||
fail_compilation/hexstring.d(39): perhaps remove postfix `c` from hex string
|
||||
fail_compilation/hexstring.d(28): Error: cannot implicitly convert expression `x"123F"` of type `string` to `ubyte[]`
|
||||
---
|
||||
*/
|
||||
|
||||
immutable ubyte[] s0 = x"123F";
|
||||
static assert(s0[0] == 0x12);
|
||||
static assert(s0[1] == 0x3F);
|
||||
immutable byte[] s1 = x"123F";
|
||||
|
||||
enum E(X) = cast(X[]) x"AABBCCDD";
|
||||
static assert(E!int[0] == 0xAABBCCDD);
|
||||
|
||||
ubyte[] f1 = x"123F";
|
||||
immutable ubyte[] f2 = "123F";
|
||||
immutable ubyte[] f3 = x"123F"c;
|
||||
immutable ubyte[] f4 = cast(string) x"123F";
|
||||
|
||||
immutable ushort[] f5 = cast(immutable ushort[]) x"11";
|
||||
immutable uint[] f6 = cast(immutable uint[]) x"112233";
|
||||
immutable ulong[] f7 = cast(immutable ulong[]) x"1122334455";
|
||||
immutable ulong[] f8 = cast(immutable ulong[]) x"1122334455"w;
|
||||
immutable uint[] f9 = cast(immutable uint[]) "ABCD";
|
||||
immutable ushort[] f10 = cast(immutable ushort[]) (x"1122" ~ "");
|
||||
immutable uint[] f11 = cast(immutable uint[]) x"AABBCCDD"c;
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/ice10922.d(10): Error: function `ice10922.__lambda4(in uint n)` is not callable using argument types `()`
|
||||
fail_compilation/ice10922.d(10): too few arguments, expected 1, got 0
|
||||
fail_compilation/ice10922.d(11): Error: function `__lambda4` is not callable using argument types `()`
|
||||
fail_compilation/ice10922.d(11): too few arguments, expected 1, got 0
|
||||
fail_compilation/ice10922.d(10): `ice10922.__lambda4(in uint n)` declared here
|
||||
---
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
----
|
||||
fail_compilation/ice11856_1.d(18): Error: no property `g` for `A()` of type `A`
|
||||
fail_compilation/ice11856_1.d(18): the following error occured while looking for a UFCS match
|
||||
fail_compilation/ice11856_1.d(18): Error: template `ice11856_1.g` is not callable using argument types `!()(A)`
|
||||
fail_compilation/ice11856_1.d(18): Error: template `g` is not callable using argument types `!()(A)`
|
||||
fail_compilation/ice11856_1.d(16): Candidate is: `g(T)(T x)`
|
||||
with `T = A`
|
||||
must satisfy the following constraint:
|
||||
` is(typeof(x.f()))`
|
||||
---
|
||||
----
|
||||
*/
|
||||
struct A {}
|
||||
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/ice12501.d(31): Error: function `ice12501.foo(int value)` is not callable using argument types `(int, int)`
|
||||
fail_compilation/ice12501.d(31): expected 1 argument(s), not 2
|
||||
fail_compilation/ice12501.d(31): Error: function `ice12501.foo(int value)` is not callable using argument types `(int, int)`
|
||||
fail_compilation/ice12501.d(31): expected 1 argument(s), not 2
|
||||
fail_compilation/ice12501.d(45): Error: template instance `ice12501.reduce!(foo, foo).reduce!(Tuple!(int, int), int[])` error instantiating
|
||||
---
|
||||
----
|
||||
fail_compilation/ice12501.d(33): Error: function `foo` is not callable using argument types `(int, int)`
|
||||
fail_compilation/ice12501.d(33): expected 1 argument(s), not 2
|
||||
fail_compilation/ice12501.d(40): `ice12501.foo(int value)` declared here
|
||||
fail_compilation/ice12501.d(33): Error: function `foo` is not callable using argument types `(int, int)`
|
||||
fail_compilation/ice12501.d(33): expected 1 argument(s), not 2
|
||||
fail_compilation/ice12501.d(40): `ice12501.foo(int value)` declared here
|
||||
fail_compilation/ice12501.d(47): Error: template instance `ice12501.reduce!(foo, foo).reduce!(Tuple!(int, int), int[])` error instantiating
|
||||
----
|
||||
*/
|
||||
|
||||
struct Tuple(T...)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/ice14130.d(10): Error: undefined identifier `Undef`
|
||||
fail_compilation/ice14130.d(14): Error: template `ice14130.foo` is not callable using argument types `!()(int)`
|
||||
fail_compilation/ice14130.d(14): Error: template `foo` is not callable using argument types `!()(int)`
|
||||
fail_compilation/ice14130.d(10): Candidate is: `foo(R, F = Undef)(R r, F s = 0)`
|
||||
---
|
||||
*/
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
----
|
||||
fail_compilation/ice14907.d(14): Error: struct `ice14907.S(int v = S)` recursive template expansion
|
||||
fail_compilation/ice14907.d(19): while looking for match for `S!()`
|
||||
fail_compilation/ice14907.d(15): Error: template `ice14907.f(int v = f)()` recursive template expansion
|
||||
fail_compilation/ice14907.d(20): while looking for match for `f!()`
|
||||
fail_compilation/ice14907.d(15): Error: template `ice14907.f(int v = f)()` recursive template expansion
|
||||
fail_compilation/ice14907.d(21): Error: template `ice14907.f` is not callable using argument types `!()()`
|
||||
fail_compilation/ice14907.d(21): Error: template `f` is not callable using argument types `!()()`
|
||||
fail_compilation/ice14907.d(15): Candidate is: `f(int v = f)()`
|
||||
---
|
||||
----
|
||||
*/
|
||||
|
||||
struct S(int v = S) {}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/ice14923.d(22): Error: function `ice14923.parse(C a)` is not callable using argument types `(A)`
|
||||
fail_compilation/ice14923.d(22): cannot pass argument `b` of type `ice14923.A` to parameter `C a`
|
||||
fail_compilation/ice14923.d(22): instantiated from here: `bar!((b) => parse(b))`
|
||||
---
|
||||
----
|
||||
fail_compilation/ice14923.d(23): Error: function `parse` is not callable using argument types `(A)`
|
||||
fail_compilation/ice14923.d(23): cannot pass argument `b` of type `ice14923.A` to parameter `C a`
|
||||
fail_compilation/ice14923.d(21): `ice14923.parse(C a)` declared here
|
||||
fail_compilation/ice14923.d(23): instantiated from here: `bar!((b) => parse(b))`
|
||||
----
|
||||
*/
|
||||
|
||||
auto bar(alias fun)()
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue