aboutsummaryrefslogtreecommitdiff
path: root/gcc/d
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2024-02-12 16:46:33 +0100
committerIain Buclaw <ibuclaw@gdcproject.org>2024-02-12 16:55:33 +0100
commit2dde675ff48600188d3e892d191a2345bad2e6ae (patch)
treebbef7d663cf48cc8d2238aa0098732a14321a0e9 /gcc/d
parent3c57b1c12a8e34d50bdf6aaf44146760db6d1b33 (diff)
downloadgcc-2dde675ff48600188d3e892d191a2345bad2e6ae.zip
gcc-2dde675ff48600188d3e892d191a2345bad2e6ae.tar.gz
gcc-2dde675ff48600188d3e892d191a2345bad2e6ae.tar.bz2
d: Merge dmd, druntime 11240a9663
D front-end changes: - Import latest fixes from dmd v2.107.0. D runtime changes: - Import latest fixes from druntime v2.107.0. Included in the merge are the fix for PR113772, and new testsuite directives to enable fixing PR104739. PR d/113772 gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd 11240a9663. * d-builtins.cc (build_frontend_type): Update for new front-end interface. * types.cc (same_type_p): Likewise. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime 11240a9663.
Diffstat (limited to 'gcc/d')
-rw-r--r--gcc/d/d-builtins.cc31
-rw-r--r--gcc/d/dmd/MERGE2
-rw-r--r--gcc/d/dmd/aggregate.d2
-rw-r--r--gcc/d/dmd/aggregate.h1
-rw-r--r--gcc/d/dmd/astcodegen.d1
-rw-r--r--gcc/d/dmd/astenums.d2
-rw-r--r--gcc/d/dmd/clone.d17
-rw-r--r--gcc/d/dmd/constfold.d2
-rw-r--r--gcc/d/dmd/dcast.d87
-rw-r--r--gcc/d/dmd/declaration.d4
-rw-r--r--gcc/d/dmd/declaration.h2
-rw-r--r--gcc/d/dmd/dinterpret.d2
-rw-r--r--gcc/d/dmd/dsymbol.h2
-rw-r--r--gcc/d/dmd/dsymbolsem.d2
-rw-r--r--gcc/d/dmd/errors.h2
-rw-r--r--gcc/d/dmd/expression.h10
-rw-r--r--gcc/d/dmd/expressionsem.d34
-rw-r--r--gcc/d/dmd/func.d11
-rw-r--r--gcc/d/dmd/hdrgen.h8
-rw-r--r--gcc/d/dmd/init.h1
-rw-r--r--gcc/d/dmd/mtype.d112
-rw-r--r--gcc/d/dmd/mtype.h6
-rw-r--r--gcc/d/dmd/parse.d2
-rw-r--r--gcc/d/dmd/statement.h5
-rw-r--r--gcc/d/dmd/template.h3
-rw-r--r--gcc/d/dmd/typesem.d112
-rw-r--r--gcc/d/types.cc2
27 files changed, 281 insertions, 184 deletions
diff --git a/gcc/d/d-builtins.cc b/gcc/d/d-builtins.cc
index 4ed8751..24ac456 100644
--- a/gcc/d/d-builtins.cc
+++ b/gcc/d/d-builtins.cc
@@ -97,12 +97,15 @@ build_frontend_type (tree type)
{
/* Check for char * first. Needs to be done for chars/string. */
if (TYPE_MAIN_VARIANT (TREE_TYPE (type)) == char_type_node)
- return Type::tchar->addMod (dtype->mod)->pointerTo ()->addMod (mod);
+ {
+ dtype = addMod (Type::tchar, dtype->mod);
+ return addMod (dtype->pointerTo (), mod);
+ }
if (dtype->ty == TY::Tfunction)
- return (TypePointer::create (dtype))->addMod (mod);
+ return addMod (TypePointer::create (dtype), mod);
- return dtype->pointerTo ()->addMod (mod);
+ return addMod (dtype->pointerTo (), mod);
}
break;
@@ -113,7 +116,7 @@ build_frontend_type (tree type)
/* Want to assign ctype directly so that the REFERENCE_TYPE code
can be turned into as an `inout' argument. Can't use pointerTo(),
because the returned Type is shared. */
- dtype = (TypePointer::create (dtype))->addMod (mod);
+ dtype = addMod (TypePointer::create (dtype), mod);
dtype->ctype = type;
builtin_converted_decls.safe_push (builtin_data (dtype, type));
return dtype;
@@ -122,7 +125,7 @@ build_frontend_type (tree type)
case BOOLEAN_TYPE:
/* Should be no need for size checking. */
- return Type::tbool->addMod (mod);
+ return addMod (Type::tbool, mod);
case INTEGER_TYPE:
{
@@ -140,7 +143,7 @@ build_frontend_type (tree type)
|| size != dtype->size ())
continue;
- return dtype->addMod (mod);
+ return addMod (dtype, mod);
}
break;
}
@@ -157,7 +160,7 @@ build_frontend_type (tree type)
if (dtype->size () != size)
continue;
- return dtype->addMod (mod);
+ return addMod (dtype, mod);
}
break;
}
@@ -174,13 +177,13 @@ build_frontend_type (tree type)
if (dtype->size () != size)
continue;
- return dtype->addMod (mod);
+ return addMod (dtype, mod);
}
break;
}
case VOID_TYPE:
- return Type::tvoid->addMod (mod);
+ return addMod (Type::tvoid, mod);
case ARRAY_TYPE:
dtype = build_frontend_type (TREE_TYPE (type));
@@ -194,7 +197,7 @@ build_frontend_type (tree type)
length = size_binop (PLUS_EXPR, size_one_node,
convert (sizetype, length));
- dtype = dtype->sarrayOf (TREE_INT_CST_LOW (length))->addMod (mod);
+ dtype = addMod (dtype->sarrayOf (TREE_INT_CST_LOW (length)), mod);
builtin_converted_decls.safe_push (builtin_data (dtype, type));
return dtype;
}
@@ -210,11 +213,11 @@ build_frontend_type (tree type)
if (!dtype)
break;
- dtype = dtype->sarrayOf (nunits)->addMod (mod);
+ dtype = addMod (dtype->sarrayOf (nunits), mod);
if (target.isVectorTypeSupported (dtype->size (), dtype->nextOf ()))
break;
- dtype = (TypeVector::create (dtype))->addMod (mod);
+ dtype = addMod (TypeVector::create (dtype), mod);
builtin_converted_decls.safe_push (builtin_data (dtype, type));
return dtype;
}
@@ -238,7 +241,7 @@ build_frontend_type (tree type)
sdecl->alignsize = TYPE_ALIGN_UNIT (type);
sdecl->alignment.setDefault ();
sdecl->sizeok = Sizeok::done;
- sdecl->type = (TypeStruct::create (sdecl))->addMod (mod);
+ sdecl->type = addMod (TypeStruct::create (sdecl), mod);
sdecl->type->ctype = type;
merge2 (sdecl->type);
@@ -331,7 +334,7 @@ build_frontend_type (tree type)
if (args->length != 0 || varargs_p == VARARGnone)
{
dtype = TypeFunction::create (args, dtype, varargs_p, LINK::c);
- return dtype->addMod (mod);
+ return addMod (dtype, mod);
}
}
break;
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 57ac2dc..74c1945 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-a6f10836997d0b5526c8c363d781b4029c77f09f
+11240a96635074b2f79d908b9348e9c0fbc3c7dc
The first line of this file holds the git revision number of the last
merge done from the dlang/dmd repository.
diff --git a/gcc/d/dmd/aggregate.d b/gcc/d/dmd/aggregate.d
index 2d32042..2c7622a 100644
--- a/gcc/d/dmd/aggregate.d
+++ b/gcc/d/dmd/aggregate.d
@@ -37,7 +37,7 @@ import dmd.identifier;
import dmd.location;
import dmd.mtype;
import dmd.tokens;
-import dmd.typesem : defaultInit;
+import dmd.typesem : defaultInit, addMod;
import dmd.visitor;
/**
diff --git a/gcc/d/dmd/aggregate.h b/gcc/d/dmd/aggregate.h
index f466ba6..6a86400 100644
--- a/gcc/d/dmd/aggregate.h
+++ b/gcc/d/dmd/aggregate.h
@@ -42,6 +42,7 @@ enum class Baseok : uint8_t
};
FuncDeclaration *search_toString(StructDeclaration *sd);
+void semanticTypeInfoMembers(StructDeclaration *sd);
enum class ClassKind : uint8_t
{
diff --git a/gcc/d/dmd/astcodegen.d b/gcc/d/dmd/astcodegen.d
index f179077..fd8387a 100644
--- a/gcc/d/dmd/astcodegen.d
+++ b/gcc/d/dmd/astcodegen.d
@@ -82,6 +82,7 @@ struct ASTCodegen
alias Tcomplex64 = dmd.mtype.Tcomplex64;
alias Tcomplex80 = dmd.mtype.Tcomplex80;
+ alias ModToStc = dmd.mtype.ModToStc;
alias ParameterList = dmd.mtype.ParameterList;
alias VarArg = dmd.mtype.VarArg;
alias STC = dmd.declaration.STC;
diff --git a/gcc/d/dmd/astenums.d b/gcc/d/dmd/astenums.d
index 77940b8..4fc1514 100644
--- a/gcc/d/dmd/astenums.d
+++ b/gcc/d/dmd/astenums.d
@@ -152,7 +152,7 @@ bool isRefReturnScope(const ulong stc)
/* This is different from the one in declaration.d, make that fix a separate PR */
static if (0)
-extern (C++) __gshared const(StorageClass) STCStorageClass =
+__gshared const(StorageClass) STCStorageClass =
(STC.auto_ | STC.scope_ | STC.static_ | STC.extern_ | STC.const_ | STC.final_ |
STC.abstract_ | STC.synchronized_ | STC.deprecated_ | STC.override_ | STC.lazy_ |
STC.alias_ | STC.out_ | STC.in_ | STC.manifest | STC.immutable_ | STC.shared_ |
diff --git a/gcc/d/dmd/clone.d b/gcc/d/dmd/clone.d
index 46470ee..2e4833e 100644
--- a/gcc/d/dmd/clone.d
+++ b/gcc/d/dmd/clone.d
@@ -327,10 +327,19 @@ FuncDeclaration buildOpAssign(StructDeclaration sd, Scope* sc)
auto e2 = new BlitExp(loc, new VarExp(loc, swap), new ThisExp(loc));
auto e3 = new BlitExp(loc, new ThisExp(loc), new IdentifierExp(loc, Id.p));
- /* Instead of running the destructor on s, run it
- * on swap. This avoids needing to copy swap back in to s.
- */
- auto e4 = new CallExp(loc, new DotVarExp(loc, new VarExp(loc, swap), sd.dtor, false));
+ Expression e4;
+ if (target.isCalleeDestroyingArgs(tf))
+ { /* callee destroys s
+ * Instead of running the destructor on s, run it
+ * on swap.
+ */
+ e4 = new CallExp(loc, new DotVarExp(loc, new VarExp(loc, swap), sd.dtor, false));
+ }
+ else
+ { /* caller destroys s, so copy contents of swap back into s
+ */
+ e4 = new BlitExp(loc, new IdentifierExp(loc, Id.p), new VarExp(loc, swap));
+ }
e = Expression.combine(e1, e2, e3, e4);
}
diff --git a/gcc/d/dmd/constfold.d b/gcc/d/dmd/constfold.d
index f5d2b60..0686e1b 100644
--- a/gcc/d/dmd/constfold.d
+++ b/gcc/d/dmd/constfold.d
@@ -36,6 +36,7 @@ import dmd.root.utf;
import dmd.sideeffect;
import dmd.target;
import dmd.tokens;
+import dmd.typesem : toDsymbol, equivalent;
private enum LOG = false;
@@ -1038,7 +1039,6 @@ UnionExp Cast(const ref Loc loc, Type type, Type to, Expression e1)
else if (tb.ty == Tstruct && e1.op == EXP.int64)
{
// Struct = 0;
- import dmd.typesem : toDsymbol;
StructDeclaration sd = tb.toDsymbol(null).isStructDeclaration();
assert(sd);
auto elements = new Expressions();
diff --git a/gcc/d/dmd/dcast.d b/gcc/d/dmd/dcast.d
index 9ee8e8c..a49bd57 100644
--- a/gcc/d/dmd/dcast.d
+++ b/gcc/d/dmd/dcast.d
@@ -235,7 +235,7 @@ Expression implicitCastTo(Expression e, Scope* sc, Type t)
* Returns:
* The `MATCH` level between `e.type` and `t`.
*/
-extern(C++) MATCH implicitConvTo(Expression e, Type t)
+MATCH implicitConvTo(Expression e, Type t)
{
MATCH visit(Expression e)
{
@@ -2848,7 +2848,7 @@ private bool isVoidArrayLiteral(Expression e, Type other)
*/
Type typeMerge(Scope* sc, EXP op, ref Expression pe1, ref Expression pe2)
{
- //printf("typeMerge() %s op %s\n", e1.toChars(), e2.toChars());
+ //printf("typeMerge() %s op %s\n", pe1.toChars(), pe2.toChars());
Expression e1 = pe1;
Expression e2 = pe2;
@@ -3165,6 +3165,9 @@ Lagain:
goto Lagain;
}
+LmergeClassTypes:
+ /* Merge different type modifiers on classes
+ */
if (t1.ty == Tclass && t2.ty == Tclass)
{
if (t1.mod != t2.mod)
@@ -3233,9 +3236,23 @@ Lagain:
if (t1.ty == Tclass && t2.ty == Tclass)
{
+ /* t1 cannot be converted to t2, and vice versa
+ */
TypeClass tc1 = t1.isTypeClass();
TypeClass tc2 = t2.isTypeClass();
+ //if (tc1.sym.interfaces.length || tc2.sym.interfaces.length)
+ if (tc1.sym.isInterfaceDeclaration() ||
+ tc2.sym.isInterfaceDeclaration())
+ {
+ ClassDeclaration cd = findClassCommonRoot(tc1.sym, tc2.sym);
+ if (!cd)
+ return null; // no common root
+ t1 = cd.type.castMod(t1.mod);
+ t2 = cd.type.castMod(t2.mod);
+ goto LmergeClassTypes; // deal with mod differences
+ }
+
/* Pick 'tightest' type
*/
ClassDeclaration cd1 = tc1.sym.baseClass;
@@ -3251,6 +3268,7 @@ Lagain:
t2 = cd2.type;
else
return null;
+ goto LmergeClassTypes;
}
else if (t1.ty == Tstruct && t1.isTypeStruct().sym.aliasthis)
{
@@ -3582,6 +3600,71 @@ LmodCompare:
return null;
}
+/**********************************
+ * Find common root that both cd1 and cd2 can be implicitly converted to.
+ * Params:
+ * cd1 = first class
+ * cd2 = second class
+ * Returns:
+ * common base that both can implicitly convert to, null if none or
+ * multiple matches
+ */
+private
+ClassDeclaration findClassCommonRoot(ClassDeclaration cd1, ClassDeclaration cd2)
+{
+ enum log = false;
+ if (log) printf("findClassCommonRoot(%s, %s)\n", cd1.toChars(), cd2.toChars());
+ /* accumulate results in this */
+ static struct Root
+ {
+ ClassDeclaration cd;
+ bool error;
+
+ /* merge cd into results */
+ void accumulate(ClassDeclaration cd)
+ {
+ if (log) printf(" accumulate(r.cd: %s r.error: %d cd: %s)\n", this.cd ? this.cd.toChars() : "null", error, cd ? cd.toChars() : null);
+ if (this.cd is cd)
+ {
+ }
+ else if (!this.cd)
+ this.cd = cd;
+ else
+ error = true;
+ }
+ }
+
+ /* Find common root of cd1 and cd2. Accumulate results in r. depth is nesting level */
+ void findCommonRoot(ClassDeclaration cd1, ClassDeclaration cd2, ref Root r)
+ {
+ if (log) printf("findCommonRoot(cd1: %s cd2: %s)\n", cd1.toChars(), cd2.toChars());
+ /* Warning: quadratic time function
+ */
+ if (cd1 is cd2)
+ {
+ r.accumulate(cd1);
+ return;
+ }
+
+ foreach (b1; (*cd1.baseclasses)[])
+ {
+ if (b1.sym != r.cd)
+ findCommonRoot(cd2, b1.sym, r);
+ }
+ foreach (b2; (*cd2.baseclasses)[])
+ {
+ if (b2.sym != r.cd)
+ findCommonRoot(cd1, b2.sym, r);
+ }
+ }
+
+ Root r;
+ findCommonRoot(cd1, cd2, r);
+ if (!r.cd || r.error)
+ return null; // no common root
+ return r.cd;
+}
+
/************************************
* Bring leaves to common type.
* Returns:
diff --git a/gcc/d/dmd/declaration.d b/gcc/d/dmd/declaration.d
index 93ef63f..3f9769d 100644
--- a/gcc/d/dmd/declaration.d
+++ b/gcc/d/dmd/declaration.d
@@ -213,7 +213,7 @@ bool modifyFieldVar(Loc loc, Scope* sc, VarDeclaration var, Expression e1)
/******************************************
*/
-extern (C++) void ObjectNotFound(Identifier id)
+void ObjectNotFound(Identifier id)
{
error(Loc.initial, "`%s` not found. object.d may be incorrectly installed or corrupt.", id.toChars());
fatal();
@@ -1380,7 +1380,7 @@ extern (C++) class VarDeclaration : Declaration
*/
final bool needsScopeDtor()
{
- //printf("VarDeclaration::needsScopeDtor() %s\n", toChars());
+ //printf("VarDeclaration::needsScopeDtor() %s %d\n", toChars(), edtor && !(storage_class & STC.nodtor));
return edtor && !(storage_class & STC.nodtor);
}
diff --git a/gcc/d/dmd/declaration.h b/gcc/d/dmd/declaration.h
index afbb997..a393da8 100644
--- a/gcc/d/dmd/declaration.h
+++ b/gcc/d/dmd/declaration.h
@@ -107,8 +107,6 @@ bool functionSemantic3(FuncDeclaration* fd);
#define STC_TYPECTOR (STCconst | STCimmutable | STCshared | STCwild)
#define STC_FUNCATTR (STCref | STCnothrow | STCnogc | STCpure | STCproperty | STCsafe | STCtrusted | STCsystem)
-void ObjectNotFound(Identifier *id);
-
/**************************************************************/
class Declaration : public Dsymbol
diff --git a/gcc/d/dmd/dinterpret.d b/gcc/d/dmd/dinterpret.d
index b078542..c3395a5 100644
--- a/gcc/d/dmd/dinterpret.d
+++ b/gcc/d/dmd/dinterpret.d
@@ -50,7 +50,7 @@ import dmd.rootobject;
import dmd.root.utf;
import dmd.statement;
import dmd.tokens;
-import dmd.typesem : mutableOf;
+import dmd.typesem : mutableOf, equivalent;
import dmd.utils : arrayCastBigEndian;
import dmd.visitor;
diff --git a/gcc/d/dmd/dsymbol.h b/gcc/d/dmd/dsymbol.h
index e463d3d..db23627 100644
--- a/gcc/d/dmd/dsymbol.h
+++ b/gcc/d/dmd/dsymbol.h
@@ -427,7 +427,5 @@ public:
void addMember(Dsymbol *dsym, Scope *sc, ScopeDsymbol *sds);
Dsymbol *search(Dsymbol *d, const Loc &loc, Identifier *ident, SearchOptFlags flags = (SearchOptFlags)SearchOpt::localsOnly);
-bool checkDeprecated(Dsymbol *d, const Loc &loc, Scope *sc);
void setScope(Dsymbol *d, Scope *sc);
void importAll(Dsymbol *d, Scope *sc);
-void setFieldOffset(Dsymbol *d, AggregateDeclaration *ad, FieldState& fieldState, bool isunion);
diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d
index 33a397a..4a4d82f 100644
--- a/gcc/d/dmd/dsymbolsem.d
+++ b/gcc/d/dmd/dsymbolsem.d
@@ -6907,7 +6907,7 @@ extern(C++) class ImportAllVisitor : Visitor
override void visit(StaticForeachDeclaration _) {}
}
-extern(C++) void setFieldOffset(Dsymbol d, AggregateDeclaration ad, FieldState* fieldState, bool isunion)
+void setFieldOffset(Dsymbol d, AggregateDeclaration ad, FieldState* fieldState, bool isunion)
{
scope v = new SetFieldOffsetVisitor(ad, fieldState, isunion);
d.accept(v);
diff --git a/gcc/d/dmd/errors.h b/gcc/d/dmd/errors.h
index 308e81e..a47b5aa 100644
--- a/gcc/d/dmd/errors.h
+++ b/gcc/d/dmd/errors.h
@@ -24,8 +24,6 @@ enum class ErrorKind
message = 4,
};
-bool isConsoleColorSupported();
-
#if defined(__GNUC__)
#define D_ATTRIBUTE_FORMAT(m, n) __attribute__((format(printf, m, n))) __attribute__((nonnull (m)))
#else
diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h
index f713d25..8dbb4a6 100644
--- a/gcc/d/dmd/expression.h
+++ b/gcc/d/dmd/expression.h
@@ -46,15 +46,15 @@ typedef union tree_node Symbol;
struct Symbol; // back end symbol
#endif
+// in expressionsem.d
+Expression *expressionSemantic(Expression *e, Scope *sc);
+// in typesem.d
+Expression *defaultInit(Type *mt, const Loc &loc, const bool isCfile = false);
+
// Entry point for CTFE.
// A compile-time result is required. Give an error if not possible
Expression *ctfeInterpret(Expression *e);
void expandTuples(Expressions *exps, Identifiers *names = nullptr);
-StringExp *toUTF8(StringExp *se, Scope *sc);
-Expression *resolveLoc(Expression *exp, const Loc &loc, Scope *sc);
-MATCH implicitConvTo(Expression *e, Type *t);
-Expression *toLvalue(Expression *_this, Scope *sc, const char* action);
-Expression *modifiableLvalue(Expression* exp, Scope *sc);
Expression *optimize(Expression *exp, int result, bool keepLvalue = false);
typedef unsigned char OwnedBy;
diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d
index d7377db..9028ba1 100644
--- a/gcc/d/dmd/expressionsem.d
+++ b/gcc/d/dmd/expressionsem.d
@@ -2523,7 +2523,7 @@ private bool checkRightThis(Expression e, Scope* sc)
return false;
}
-extern (C++) Expression resolveProperties(Scope* sc, Expression e)
+Expression resolveProperties(Scope* sc, Expression e)
{
//printf("resolveProperties(%s)\n", e.toChars());
e = resolvePropertiesX(sc, e);
@@ -3464,12 +3464,12 @@ private bool functionParameters(const ref Loc loc, Scope* sc,
eprefix = ae.expressionSemantic(sc);
}
- for (ptrdiff_t i = 0; i != nargs; i++)
+ foreach (ptrdiff_t i; 0 .. nargs)
{
Expression arg = (*arguments)[i];
//printf("arg[%d]: %s\n", cast(int)i, arg.toChars());
- Parameter parameter = (i >= nparams ? null : tf.parameterList[i]);
+ Parameter parameter = i < nparams ? tf.parameterList[i] : null;
const bool isRef = parameter && parameter.isReference();
const bool isLazy = parameter && parameter.isLazy();
@@ -3485,7 +3485,7 @@ private bool functionParameters(const ref Loc loc, Scope* sc,
* 'eprefix' will therefore finally contain all args up to and including 'lastPrefix',
* excluding all lazy parameters.
*/
- if (needsPrefix && (lastPrefix - i) >= 0)
+ if (needsPrefix && i <= lastPrefix)
{
const bool needsDtor = !isRef && arg.type.needsDestruction() &&
// Problem 3: last throwing arg doesn't require dtor patching
@@ -3494,9 +3494,9 @@ private bool functionParameters(const ref Loc loc, Scope* sc,
/* Declare temporary 'auto __pfx = arg' (needsDtor) or 'auto __pfy = arg' (!needsDtor)
*/
auto tmp = copyToTemp(
- (parameter ? parameter.storageClass : tf.parameterList.stc) & (STC.scope_),
+ (parameter ? parameter.storageClass : tf.parameterList.stc) & (STC.return_ | STC.scope_),
needsDtor ? "__pfx" : "__pfy",
- !isRef ? arg : arg.addressOf());
+ isRef ? arg.addressOf() : arg);
tmp.dsymbolSemantic(sc);
if (callerDestroysArgs)
@@ -3511,15 +3511,7 @@ private bool functionParameters(const ref Loc loc, Scope* sc,
/* Problem 2: Modify the destructor so it only runs if gate==false,
* i.e., only if there was a throw while constructing the args
*/
- if (!needsDtor)
- {
- if (tmp.edtor)
- {
- assert(i == lastPrefix);
- tmp.edtor = null;
- }
- }
- else
+ if (needsDtor)
{
// edtor => (__gate || edtor)
assert(tmp.edtor);
@@ -3528,6 +3520,14 @@ private bool functionParameters(const ref Loc loc, Scope* sc,
tmp.edtor = e.expressionSemantic(sc);
//printf("edtor: %s\n", tmp.edtor.toChars());
}
+ else
+ {
+ if (tmp.edtor)
+ {
+ assert(i == lastPrefix);
+ tmp.edtor = null;
+ }
+ }
}
// eprefix => (eprefix, auto __pfx/y = arg)
@@ -15534,7 +15534,7 @@ Expression addDtorHook(Expression e, Scope* sc)
* action = for error messages, what the lvalue is needed for (e.g. take address of for `&x`, modify for `x++`)
* Returns: converted expression, or `ErrorExp` on error
*/
-extern(C++) Expression toLvalue(Expression _this, Scope* sc, const(char)* action)
+Expression toLvalue(Expression _this, Scope* sc, const(char)* action)
{
return toLvalueImpl(_this, sc, action, _this);
}
@@ -15955,7 +15955,7 @@ Modifiable checkModifiable(Expression exp, Scope* sc, ModifyFlags flag = ModifyF
* sc = scope
* Returns: `_this` converted to an lvalue, or an `ErrorExp`
*/
-extern(C++) Expression modifiableLvalue(Expression _this, Scope* sc)
+Expression modifiableLvalue(Expression _this, Scope* sc)
{
return modifiableLvalueImpl(_this, sc, _this);
}
diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d
index ddf21a2..4881ad6 100644
--- a/gcc/d/dmd/func.d
+++ b/gcc/d/dmd/func.d
@@ -60,6 +60,7 @@ import dmd.statement;
import dmd.statementsem;
import dmd.templatesem;
import dmd.tokens;
+import dmd.typesem;
import dmd.visitor;
version (IN_GCC) {}
@@ -518,7 +519,6 @@ extern (C++) class FuncDeclaration : Declaration
int result = 0;
if (fd.ident == ident)
{
- import dmd.typesem : covariant;
const cov = type.covariant(fd.type);
if (cov != Covariant.distinct)
{
@@ -625,7 +625,6 @@ extern (C++) class FuncDeclaration : Declaration
*/
if (t.ty == Tfunction)
{
- import dmd.typesem : covariant;
auto tf = cast(TypeFunction)f.type;
if (tf.covariant(t) == Covariant.yes &&
tf.nextOf().implicitConvTo(t.nextOf()) >= MATCH.constant)
@@ -840,7 +839,6 @@ extern (C++) class FuncDeclaration : Declaration
args.push(e);
}
- import dmd.typesem : callMatch;
MATCH m = tg.callMatch(null, ArgumentList(&args, names), 1);
if (m > MATCH.nomatch)
{
@@ -1151,7 +1149,6 @@ extern (C++) class FuncDeclaration : Declaration
{
//printf("FuncDeclaration::isPure() '%s'\n", toChars());
- import dmd.typesem : purityLevel;
TypeFunction tf = type.toTypeFunction();
if (purityInprocess)
@@ -1464,7 +1461,6 @@ extern (C++) class FuncDeclaration : Declaration
case Tstruct:
/* Drill down and check the struct's fields
*/
- import dmd.typesem : toDsymbol;
auto sym = t.toDsymbol(null).isStructDeclaration();
const tName = t.toChars.toDString;
const entry = parentTypes.insert(tName, t);
@@ -1546,7 +1542,6 @@ extern (C++) class FuncDeclaration : Declaration
case Tstruct:
/* Drill down and check the struct's fields
*/
- import dmd.typesem : toDsymbol;
auto sym = tp.toDsymbol(null).isStructDeclaration();
foreach (v; sym.fields)
{
@@ -2411,7 +2406,6 @@ extern (C++) class FuncDeclaration : Declaration
{
Type t1 = fdv.type.nextOf().toBasetype();
Type t2 = this.type.nextOf().toBasetype();
- import dmd.typesem : isBaseOf;
if (t1.isBaseOf(t2, null))
{
/* Making temporary reference variable is necessary
@@ -3325,7 +3319,6 @@ if (is(Decl == TemplateDeclaration) || is(Decl == FuncDeclaration))
*/
Type getIndirection(Type t)
{
- import dmd.typesem : hasPointers;
t = t.baseElemOf();
if (t.ty == Tarray || t.ty == Tpointer)
return t.nextOf().toBasetype();
@@ -3372,7 +3365,6 @@ private bool traverseIndirections(Type ta, Type tb)
static bool traverse(Type ta, Type tb, ref scope AssocArray!(const(char)*, bool) table, bool reversePass)
{
- import dmd.typesem : hasPointers;
//printf("traverse(%s, %s)\n", ta.toChars(), tb.toChars());
ta = ta.baseElemOf();
tb = tb.baseElemOf();
@@ -3409,7 +3401,6 @@ private bool traverseIndirections(Type ta, Type tb)
else
*found = true;
- import dmd.typesem : toDsymbol;
AggregateDeclaration sym = tb.toDsymbol(null).isAggregateDeclaration();
foreach (v; sym.fields)
{
diff --git a/gcc/d/dmd/hdrgen.h b/gcc/d/dmd/hdrgen.h
index e38ca56..e0a2046 100644
--- a/gcc/d/dmd/hdrgen.h
+++ b/gcc/d/dmd/hdrgen.h
@@ -13,9 +13,17 @@
#include "globals.h"
#include "mtype.h"
+class Expression;
+class Initializer;
class Module;
+class Statement;
void genhdrfile(Module *m, bool doFuncBodies, OutBuffer &buf);
void genCppHdrFiles(Modules &ms);
void moduleToBuffer(OutBuffer& buf, bool vcg_ast, Module *m);
const char *parametersTypeToChars(ParameterList pl);
+
+const char* toChars(const Expression* const e);
+const char* toChars(const Initializer* const i);
+const char* toChars(const Statement* const s);
+const char* toChars(const Type* const t);
diff --git a/gcc/d/dmd/init.h b/gcc/d/dmd/init.h
index b4e15e3..cccd3c9 100644
--- a/gcc/d/dmd/init.h
+++ b/gcc/d/dmd/init.h
@@ -125,3 +125,4 @@ public:
};
Expression *initializerToExpression(Initializer *init, Type *t = NULL, const bool isCfile = false);
+Initializer *initializerSemantic(Initializer *init, Scope *sc, Type *&tx, NeedInterpret needInterpret);
diff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d
index c46f560..4f8ed75 100644
--- a/gcc/d/dmd/mtype.d
+++ b/gcc/d/dmd/mtype.d
@@ -444,11 +444,6 @@ extern (C++) abstract class Type : ASTNode
return false;
}
- final bool equivalent(Type t)
- {
- return immutableOf(this).equals(t.immutableOf());
- }
-
// kludge for template.isType()
override final DYNCAST dyncast() const
{
@@ -1192,111 +1187,6 @@ extern (C++) abstract class Type : ASTNode
}
/************************************
- * Add MODxxxx bits to existing type.
- * We're adding, not replacing, so adding const to
- * a shared type => "shared const"
- */
- final Type addMod(MOD mod)
- {
- /* Add anything to immutable, and it remains immutable
- */
- Type t = this;
- if (!t.isImmutable())
- {
- //printf("addMod(%x) %s\n", mod, toChars());
- switch (mod)
- {
- case 0:
- break;
-
- case MODFlags.const_:
- if (isShared())
- {
- if (isWild())
- t = this.sharedWildConstOf();
- else
- t = this.sharedConstOf();
- }
- else
- {
- if (this.isWild())
- t = this.wildConstOf();
- else
- t = t.constOf();
- }
- break;
-
- case MODFlags.wild:
- if (isShared())
- {
- if (isConst())
- t = this.sharedWildConstOf();
- else
- t = this.sharedWildOf();
- }
- else
- {
- if (isConst())
- t = this.wildConstOf();
- else
- t = this.wildOf();
- }
- break;
-
- case MODFlags.wildconst:
- if (isShared())
- t = this.sharedWildConstOf();
- else
- t = this.wildConstOf();
- break;
-
- case MODFlags.shared_:
- if (isWild())
- {
- if (isConst())
- t = this.sharedWildConstOf();
- else
- t = this.sharedWildOf();
- }
- else
- {
- if (isConst())
- t = this.sharedConstOf();
- else
- t = this.sharedOf();
- }
- break;
-
- case MODFlags.shared_ | MODFlags.const_:
- if (isWild())
- t = this.sharedWildConstOf();
- else
- t = this.sharedConstOf();
- break;
-
- case MODFlags.shared_ | MODFlags.wild:
- if (isConst())
- t = this.sharedWildConstOf();
- else
- t = this.sharedWildOf();
- break;
-
- case MODFlags.shared_ | MODFlags.wildconst:
- t = this.sharedWildConstOf();
- break;
-
- case MODFlags.immutable_:
- t = this.immutableOf();
- break;
-
- default:
- assert(0);
- }
- }
- return t;
- }
-
- /************************************
* Add storage class modifiers to type.
*/
Type addStorageClass(StorageClass stc)
@@ -1315,7 +1205,7 @@ extern (C++) abstract class Type : ASTNode
if (stc & STC.shared_)
mod |= MODFlags.shared_;
}
- return addMod(mod);
+ return this.addMod(mod);
}
final Type pointerTo()
diff --git a/gcc/d/dmd/mtype.h b/gcc/d/dmd/mtype.h
index a7a41c6..df8cc4d 100644
--- a/gcc/d/dmd/mtype.h
+++ b/gcc/d/dmd/mtype.h
@@ -39,7 +39,6 @@ typedef union tree_node type;
typedef struct TYPE type;
#endif
-extern const char* toChars(const Type* const t);
Type *typeSemantic(Type *t, const Loc &loc, Scope *sc);
Type *merge(Type *type);
@@ -218,7 +217,6 @@ public:
Type *copy() const;
virtual Type *syntaxCopy();
bool equals(const RootObject * const o) const override;
- bool equivalent(Type *t);
// kludge for template.isType()
DYNCAST dyncast() const override final { return DYNCAST_TYPE; }
size_t getUniqueID() const;
@@ -253,7 +251,6 @@ public:
bool isSharedWild() const { return (mod & (MODshared | MODwild)) == (MODshared | MODwild); }
bool isNaked() const { return mod == 0; }
Type *nullAttributes() const;
- Type *addMod(MOD mod);
virtual Type *addStorageClass(StorageClass stc);
Type *pointerTo();
Type *referenceTo();
@@ -889,10 +886,10 @@ AggregateDeclaration *isAggregate(Type *t);
bool hasPointers(Type *t);
// return the symbol to which type t resolves
Dsymbol *toDsymbol(Type *t, Scope *sc);
+bool equivalent(Type *src, Type *t);
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);
Type *constOf(Type *type);
Type *immutableOf(Type *type);
@@ -905,3 +902,4 @@ Type *wildConstOf(Type *type);
Type *sharedWildOf(Type *type);
Type *sharedWildConstOf(Type *type);
Type *castMod(Type *type, MOD mod);
+Type *addMod(Type *type, MOD mod);
diff --git a/gcc/d/dmd/parse.d b/gcc/d/dmd/parse.d
index 0dc54ff..2d2e6fd 100644
--- a/gcc/d/dmd/parse.d
+++ b/gcc/d/dmd/parse.d
@@ -8730,7 +8730,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
else
{
AST.Type t = parseType(); // cast( type )
- t = t.addMod(m); // cast( const type )
+ t = t.addSTC(AST.ModToStc(m)); // cast( const type )
check(TOK.rightParenthesis);
e = parseUnaryExp();
e = new AST.CastExp(loc, e, t);
diff --git a/gcc/d/dmd/statement.h b/gcc/d/dmd/statement.h
index ee03d49..8a6bf3d 100644
--- a/gcc/d/dmd/statement.h
+++ b/gcc/d/dmd/statement.h
@@ -701,7 +701,12 @@ public:
void accept(Visitor *v) override { v->visit(this); }
};
+// in statementsem.d
+Statement* statementSemantic(Statement *s, Scope *sc);
+// in iasm.d
Statement* asmSemantic(AsmStatement *s, Scope *sc);
+// in iasmgcc.d
+Statement *gccAsmSemantic(GccAsmStatement *s, Scope *sc);
class AsmStatement : public Statement
{
diff --git a/gcc/d/dmd/template.h b/gcc/d/dmd/template.h
index 153eb4e..c80f28b 100644
--- a/gcc/d/dmd/template.h
+++ b/gcc/d/dmd/template.h
@@ -317,6 +317,9 @@ public:
void accept(Visitor *v) override { v->visit(this); }
};
+// in templateparamsem.d
+bool tpsemantic(TemplateParameter *tp, Scope *sc, TemplateParameters *parameters);
+
Expression *isExpression(RootObject *o);
Dsymbol *isDsymbol(RootObject *o);
Type *isType(RootObject *o);
diff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d
index b1ca92d..19c6912 100644
--- a/gcc/d/dmd/typesem.d
+++ b/gcc/d/dmd/typesem.d
@@ -520,7 +520,7 @@ int mutabilityOfType(bool isref, Type t)
* Set 'purity' field of 'typeFunction'.
* Do this lazily, as the parameter types might be forward referenced.
*/
-extern(C++) void purityLevel(TypeFunction typeFunction)
+void purityLevel(TypeFunction typeFunction)
{
TypeFunction tf = typeFunction;
if (tf.purity != PURE.fwdref)
@@ -6106,6 +6106,11 @@ extern(C++) bool isBaseOf(Type tthis, Type t, int* poffset)
return false;
}
+extern(C++) bool equivalent(Type src, Type t)
+{
+ return immutableOf(src).equals(t.immutableOf());
+}
+
/********************************
* Convert to 'const'.
*/
@@ -6405,6 +6410,111 @@ extern(C++) Type castMod(Type type, MOD mod)
return t;
}
+/************************************
+ * Add MODxxxx bits to existing type.
+ * We're adding, not replacing, so adding const to
+ * a shared type => "shared const"
+ */
+extern(C++) Type addMod(Type type, MOD mod)
+{
+ /* Add anything to immutable, and it remains immutable
+ */
+ Type t = type;
+ if (!t.isImmutable())
+ {
+ //printf("addMod(%x) %s\n", mod, toChars());
+ switch (mod)
+ {
+ case 0:
+ break;
+
+ case MODFlags.const_:
+ if (type.isShared())
+ {
+ if (type.isWild())
+ t = type.sharedWildConstOf();
+ else
+ t = type.sharedConstOf();
+ }
+ else
+ {
+ if (type.isWild())
+ t = type.wildConstOf();
+ else
+ t = t.constOf();
+ }
+ break;
+
+ case MODFlags.wild:
+ if (type.isShared())
+ {
+ if (type.isConst())
+ t = type.sharedWildConstOf();
+ else
+ t = type.sharedWildOf();
+ }
+ else
+ {
+ if (type.isConst())
+ t = type.wildConstOf();
+ else
+ t = type.wildOf();
+ }
+ break;
+
+ case MODFlags.wildconst:
+ if (type.isShared())
+ t = type.sharedWildConstOf();
+ else
+ t = type.wildConstOf();
+ break;
+
+ case MODFlags.shared_:
+ if (type.isWild())
+ {
+ if (type.isConst())
+ t = type.sharedWildConstOf();
+ else
+ t = type.sharedWildOf();
+ }
+ else
+ {
+ if (type.isConst())
+ t = type.sharedConstOf();
+ else
+ t = type.sharedOf();
+ }
+ break;
+
+ case MODFlags.shared_ | MODFlags.const_:
+ if (type.isWild())
+ t = type.sharedWildConstOf();
+ else
+ t = type.sharedConstOf();
+ break;
+
+ case MODFlags.shared_ | MODFlags.wild:
+ if (type.isConst())
+ t = type.sharedWildConstOf();
+ else
+ t = type.sharedWildOf();
+ break;
+
+ case MODFlags.shared_ | MODFlags.wildconst:
+ t = type.sharedWildConstOf();
+ break;
+
+ case MODFlags.immutable_:
+ t = type.immutableOf();
+ break;
+
+ default:
+ assert(0);
+ }
+ }
+ return t;
+}
+
/******************************* Private *****************************************/
private:
diff --git a/gcc/d/types.cc b/gcc/d/types.cc
index 4e14b15..af9aad8 100644
--- a/gcc/d/types.cc
+++ b/gcc/d/types.cc
@@ -144,7 +144,7 @@ same_type_p (Type *t1, Type *t2)
return true;
/* Types are mutably the same type. */
- if (tb1->ty == tb2->ty && tb1->equivalent (tb2))
+ if (tb1->ty == tb2->ty && equivalent (tb1, tb2))
return true;
return false;