aboutsummaryrefslogtreecommitdiff
path: root/gcc/d
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2020-04-29 10:19:55 +0200
committerIain Buclaw <ibuclaw@gdcproject.org>2020-04-29 10:36:00 +0200
commit75f758a703924184fc07b01a138bb6f0028d077c (patch)
tree9b90b2c92161b246f7acd4494c5b1a2a3e4f1d09 /gcc/d
parentd81bc2af7d2700888e414eb5a322ff5f5b0df0bb (diff)
downloadgcc-75f758a703924184fc07b01a138bb6f0028d077c.zip
gcc-75f758a703924184fc07b01a138bb6f0028d077c.tar.gz
gcc-75f758a703924184fc07b01a138bb6f0028d077c.tar.bz2
d: Merge bug fix from upstream dmd 06160ccae
Adds classKind information to the front-end AST, which in turn allows us to fix code generation of type names for extern(C) and extern(C++) structs and classes. Inspecting such types inside a debugger now just works without the need to 'cast(module_name.cxx_type)'. gcc/d/ChangeLog: * d-codegen.cc (d_decl_context): Don't include module in the name of class and struct types that aren't extern(D).
Diffstat (limited to 'gcc/d')
-rw-r--r--gcc/d/ChangeLog5
-rw-r--r--gcc/d/d-codegen.cc4
-rw-r--r--gcc/d/dmd/MERGE2
-rw-r--r--gcc/d/dmd/aggregate.h17
-rw-r--r--gcc/d/dmd/dclass.c32
-rw-r--r--gcc/d/dmd/declaration.c2
-rw-r--r--gcc/d/dmd/dstruct.c4
-rw-r--r--gcc/d/dmd/func.c4
-rw-r--r--gcc/d/dmd/opover.c2
-rw-r--r--gcc/d/dmd/traits.c24
10 files changed, 69 insertions, 27 deletions
diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog
index 3b5fc12..9550a6d 100644
--- a/gcc/d/ChangeLog
+++ b/gcc/d/ChangeLog
@@ -1,3 +1,8 @@
+2020-04-29 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * d-codegen.cc (d_decl_context): Don't include module in the name of
+ class and struct types that aren't extern(D).
+
2020-04-27 Iain Buclaw <ibuclaw@gdcproject.org>
PR d/94777
diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc
index 12c6f13..b4927a2 100644
--- a/gcc/d/d-codegen.cc
+++ b/gcc/d/d-codegen.cc
@@ -66,6 +66,7 @@ d_decl_context (Dsymbol *dsym)
{
Dsymbol *parent = dsym;
Declaration *decl = dsym->isDeclaration ();
+ AggregateDeclaration *ad = dsym->isAggregateDeclaration ();
while ((parent = parent->toParent2 ()))
{
@@ -74,7 +75,8 @@ d_decl_context (Dsymbol *dsym)
but only for extern(D) symbols. */
if (parent->isModule ())
{
- if (decl != NULL && decl->linkage != LINKd)
+ if ((decl != NULL && decl->linkage != LINKd)
+ || (ad != NULL && ad->classKind != ClassKind::d))
return NULL_TREE;
return build_import_decl (parent);
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index f933cf1..a2699d3 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-f8a1a515346b16ebbd9da56a908540cbef1ee582
+06160ccaed7af7955d169024f417c43beb7a8f9f
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.h b/gcc/d/dmd/aggregate.h
index 881be58..da4a039 100644
--- a/gcc/d/dmd/aggregate.h
+++ b/gcc/d/dmd/aggregate.h
@@ -71,6 +71,19 @@ FuncDeclaration *buildDtor(AggregateDeclaration *ad, Scope *sc);
FuncDeclaration *buildInv(AggregateDeclaration *ad, Scope *sc);
FuncDeclaration *search_toString(StructDeclaration *sd);
+struct ClassKind
+{
+ enum Type
+ {
+ /// the class is a d(efault) class
+ d,
+ /// the class is a C++ interface
+ cpp,
+ /// the class is an Objective-C class/interface
+ objc,
+ };
+};
+
class AggregateDeclaration : public ScopeDsymbol
{
public:
@@ -84,6 +97,8 @@ public:
Dsymbol *deferred; // any deferred semantic2() or semantic3() symbol
bool isdeprecated; // true if deprecated
+ ClassKind::Type classKind; // specifies the linkage type
+
/* !=NULL if is nested
* pointing to the dsymbol that directly enclosing it.
* 1. The function that enclosing it (nested struct and class)
@@ -274,8 +289,6 @@ public:
TypeInfoClassDeclaration *vclassinfo; // the ClassInfo object for this ClassDeclaration
bool com; // true if this is a COM class (meaning it derives from IUnknown)
- bool cpp; // true if this is a C++ interface
- bool isobjc; // true if this is an Objective-C class/interface
bool isscope; // true if this is a scope class
Abstract isabstract; // 0: fwdref, 1: is abstract class, 2: not abstract
int inuse; // to prevent recursive attempts
diff --git a/gcc/d/dmd/dclass.c b/gcc/d/dmd/dclass.c
index 4609d6a..a2009a6 100644
--- a/gcc/d/dmd/dclass.c
+++ b/gcc/d/dmd/dclass.c
@@ -240,12 +240,10 @@ ClassDeclaration::ClassDeclaration(Loc loc, Identifier *id, BaseClasses *basecla
}
com = false;
- cpp = false;
isscope = false;
isabstract = ABSfwdref;
inuse = 0;
baseok = BASEOKnone;
- isobjc = false;
cpp_type_info_ptr_sym = NULL;
}
@@ -389,7 +387,7 @@ void ClassDeclaration::semantic(Scope *sc)
userAttribDecl = sc->userAttribDecl;
if (sc->linkage == LINKcpp)
- cpp = true;
+ classKind = ClassKind::cpp;
if (sc->linkage == LINKobjc)
objc()->setObjc(this);
}
@@ -555,7 +553,7 @@ void ClassDeclaration::semantic(Scope *sc)
baseok = BASEOKdone;
// If no base class, and this is not an Object, use Object as base class
- if (!baseClass && ident != Id::Object && !cpp)
+ if (!baseClass && ident != Id::Object && !isCPPclass())
{
if (!object || object->errors)
badObjectDotD(this);
@@ -583,7 +581,7 @@ void ClassDeclaration::semantic(Scope *sc)
if (baseClass->isCOMclass())
com = true;
if (baseClass->isCPPclass())
- cpp = true;
+ classKind = ClassKind::cpp;
if (baseClass->isscope)
isscope = true;
enclosing = baseClass->enclosing;
@@ -600,7 +598,7 @@ void ClassDeclaration::semantic(Scope *sc)
// then this is a COM interface too.
if (b->sym->isCOMinterface())
com = true;
- if (cpp && !b->sym->isCPPinterface())
+ if (isCPPclass() && !b->sym->isCPPinterface())
{
::error(loc, "C++ class '%s' cannot implement D interface '%s'",
toPrettyChars(), b->sym->toPrettyChars());
@@ -675,7 +673,7 @@ Lancestorsdone:
// initialize vtbl
if (baseClass)
{
- if (cpp && baseClass->vtbl.dim == 0)
+ if (isCPPclass() && baseClass->vtbl.dim == 0)
{
error("C++ base class %s needs at least one virtual function", baseClass->toChars());
}
@@ -1087,7 +1085,7 @@ void ClassDeclaration::finalizeSize()
alignsize = baseClass->alignsize;
structsize = baseClass->structsize;
- if (cpp && global.params.isWindows)
+ if (isCPPclass() && global.params.isWindows)
structsize = (structsize + alignsize - 1) & ~(alignsize - 1);
}
else if (isInterfaceDeclaration())
@@ -1102,7 +1100,7 @@ void ClassDeclaration::finalizeSize()
{
alignsize = Target::ptrsize;
structsize = Target::ptrsize; // allow room for __vptr
- if (!cpp)
+ if (!isCPPclass())
structsize += Target::ptrsize; // allow room for __monitor
}
@@ -1299,7 +1297,7 @@ bool ClassDeclaration::isCOMinterface() const
bool ClassDeclaration::isCPPclass() const
{
- return cpp;
+ return classKind == ClassKind::cpp;
}
bool ClassDeclaration::isCPPinterface() const
@@ -1378,7 +1376,7 @@ bool ClassDeclaration::isAbstract()
int ClassDeclaration::vtblOffset() const
{
- return cpp ? 0 : 1;
+ return classKind == ClassKind::cpp ? 0 : 1;
}
/****************************************
@@ -1405,7 +1403,7 @@ InterfaceDeclaration::InterfaceDeclaration(Loc loc, Identifier *id, BaseClasses
if (id == Id::IUnknown) // IUnknown is the root of all COM interfaces
{
com = true;
- cpp = true; // IUnknown is also a C++ interface
+ classKind = ClassKind::cpp; // IUnknown is also a C++ interface
}
}
@@ -1422,9 +1420,9 @@ Scope *InterfaceDeclaration::newScope(Scope *sc)
Scope *sc2 = ClassDeclaration::newScope(sc);
if (com)
sc2->linkage = LINKwindows;
- else if (cpp)
+ else if (classKind == ClassKind::cpp)
sc2->linkage = LINKcpp;
- else if (isobjc)
+ else if (classKind == ClassKind::objc)
sc2->linkage = LINKobjc;
return sc2;
}
@@ -1523,7 +1521,7 @@ void InterfaceDeclaration::semantic(Scope *sc)
}
if (!baseclasses->dim && sc->linkage == LINKcpp)
- cpp = true;
+ classKind = ClassKind::cpp;
if (sc->linkage == LINKobjc)
objc()->setObjc(this);
@@ -1605,7 +1603,7 @@ void InterfaceDeclaration::semantic(Scope *sc)
if (b->sym->isCOMinterface())
com = true;
if (b->sym->isCPPinterface())
- cpp = true;
+ classKind = ClassKind::cpp;
}
interfaceSemantic(sc);
@@ -1817,7 +1815,7 @@ bool InterfaceDeclaration::isCOMinterface() const
bool InterfaceDeclaration::isCPPinterface() const
{
- return cpp;
+ return classKind == ClassKind::cpp;
}
/*******************************************
diff --git a/gcc/d/dmd/declaration.c b/gcc/d/dmd/declaration.c
index 806e29d..2ad6af2 100644
--- a/gcc/d/dmd/declaration.c
+++ b/gcc/d/dmd/declaration.c
@@ -2174,7 +2174,7 @@ Expression *VarDeclaration::callScopeDtor(Scope *)
// Destroying C++ scope classes crashes currently. Since C++ class dtors are not currently supported, simply do not run dtors for them.
// See https://issues.dlang.org/show_bug.cgi?id=13182
- if (cd->cpp)
+ if (cd->isCPPclass())
{
break;
}
diff --git a/gcc/d/dmd/dstruct.c b/gcc/d/dmd/dstruct.c
index 10771c95..0a33cc2 100644
--- a/gcc/d/dmd/dstruct.c
+++ b/gcc/d/dmd/dstruct.c
@@ -194,6 +194,7 @@ AggregateDeclaration::AggregateDeclaration(Loc loc, Identifier *id)
sizeok = SIZEOKnone; // size not determined yet
deferred = NULL;
isdeprecated = false;
+ classKind = ClassKind::d;
inv = NULL;
aggNew = NULL;
aggDelete = NULL;
@@ -1071,6 +1072,9 @@ void StructDeclaration::semantic(Scope *sc)
if (storage_class & STCabstract)
error("structs, unions cannot be abstract");
userAttribDecl = sc->userAttribDecl;
+
+ if (sc->linkage == LINKcpp)
+ classKind = ClassKind::cpp;
}
else if (symtab && !scx)
{
diff --git a/gcc/d/dmd/func.c b/gcc/d/dmd/func.c
index ab74dc5..621405e 100644
--- a/gcc/d/dmd/func.c
+++ b/gcc/d/dmd/func.c
@@ -876,7 +876,7 @@ void FuncDeclaration::semantic(Scope *sc)
/* These quirky conditions mimic what VC++ appears to do
*/
- if (global.params.mscoff && cd->cpp &&
+ if (global.params.mscoff && cd->isCPPclass() &&
cd->baseClass && cd->baseClass->vtbl.dim)
{
/* if overriding an interface function, then this is not
@@ -902,7 +902,7 @@ void FuncDeclaration::semantic(Scope *sc)
{
//printf("\tintroducing function %s\n", toChars());
introducing = 1;
- if (cd->cpp && Target::reverseCppOverloads)
+ if (cd->isCPPclass() && Target::reverseCppOverloads)
{
// with dmc, overloaded functions are grouped and in reverse order
vtblIndex = (int)cd->vtbl.dim;
diff --git a/gcc/d/dmd/opover.c b/gcc/d/dmd/opover.c
index b3ea6cf..e1ff5e9 100644
--- a/gcc/d/dmd/opover.c
+++ b/gcc/d/dmd/opover.c
@@ -962,7 +962,7 @@ Expression *op_overload(Expression *e, Scope *sc)
ClassDeclaration *cd1 = t1->isClassHandle();
ClassDeclaration *cd2 = t2->isClassHandle();
- if (!(cd1->cpp || cd2->cpp))
+ if (!(cd1->isCPPclass() || cd2->isCPPclass()))
{
/* Rewrite as:
* .object.opEquals(e1, e2)
diff --git a/gcc/d/dmd/traits.c b/gcc/d/dmd/traits.c
index 04726c3..535893f 100644
--- a/gcc/d/dmd/traits.c
+++ b/gcc/d/dmd/traits.c
@@ -1135,12 +1135,32 @@ Expression *semanticTraits(TraitsExp *e, Scope *sc)
{
Dsymbol *s = getDsymbol(o);
Declaration *d = NULL;
- if (!s || (d = s->isDeclaration()) == NULL)
+ AggregateDeclaration *ad = NULL;
+ if (!s || ((d = s->isDeclaration()) == NULL
+ && (ad = s->isAggregateDeclaration()) == NULL))
{
e->error("argument to `__traits(getLinkage, %s)` is not a declaration", o->toChars());
return new ErrorExp();
}
- link = d->linkage;
+ if (d != NULL)
+ link = d->linkage;
+ else
+ {
+ switch (ad->classKind)
+ {
+ case ClassKind::d:
+ link = LINKd;
+ break;
+ case ClassKind::cpp:
+ link = LINKcpp;
+ break;
+ case ClassKind::objc:
+ link = LINKobjc;
+ break;
+ default:
+ assert(0);
+ }
+ }
}
const char *linkage = linkageToChars(link);
StringExp *se = new StringExp(e->loc, const_cast<char *>(linkage));