aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2022-05-27 19:36:06 +0200
committerIain Buclaw <ibuclaw@gdcproject.org>2022-05-27 20:19:02 +0200
commit610d789832b57e9ab0158b330865e24b9b699040 (patch)
tree0b42094ea5f69e9fd0257dd578589a60ef6b736a /gcc
parentd822f4bbd714c6595f70cc68888dcebecfb6662d (diff)
downloadgcc-610d789832b57e9ab0158b330865e24b9b699040.zip
gcc-610d789832b57e9ab0158b330865e24b9b699040.tar.gz
gcc-610d789832b57e9ab0158b330865e24b9b699040.tar.bz2
d: Merge upstream dmd 4d07f22f2, druntime f89da313, phobos d46814c86.
D front-end changes: - `scope' semantics are now enforced in `@safe' code on pointers to stack memory, but only as deprecation warnings. - Overriding virtual functions are now marked with the `override' and `final' in the generated headers of `-fdump-c++-spec='. - `-fpreview=fiximmmutableconv` has been added that disallows implicitly converting a return value with indirections to immutable if it determines the result must be unique. D runtime changes: - Posix (excluding Darwin): Switch default GC signals from SIGUSR1/2 to SIGRTMIN/SIGRTMIN+1 Phobos changes: - Import latest bug fixes to mainline. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd 4d07f22f2 * d-lang.cc (d_handle_option): Handle OPT_fpreview_fiximmutableconv. * lang.opt (fpreview=fiximmutableconv): New option. * runtime.def (ARRAYAPPENDT): Remove. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime f89da313. * src/MERGE: Merge upstream phobos d46814c86. Signed-off-by: Iain Buclaw <ibuclaw@gdcproject.org>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/d/d-lang.cc5
-rw-r--r--gcc/d/dmd/MERGE2
-rw-r--r--gcc/d/dmd/aggregate.h80
-rw-r--r--gcc/d/dmd/aliasthis.h10
-rw-r--r--gcc/d/dmd/attrib.h212
-rw-r--r--gcc/d/dmd/cond.h34
-rw-r--r--gcc/d/dmd/cparse.d156
-rw-r--r--gcc/d/dmd/ctfe.h20
-rw-r--r--gcc/d/dmd/dcast.d21
-rw-r--r--gcc/d/dmd/declaration.h396
-rw-r--r--gcc/d/dmd/dmodule.d33
-rw-r--r--gcc/d/dmd/dsymbol.d23
-rw-r--r--gcc/d/dmd/dsymbol.h64
-rw-r--r--gcc/d/dmd/dsymbolsem.d20
-rw-r--r--gcc/d/dmd/dtemplate.d2
-rw-r--r--gcc/d/dmd/dtoh.d28
-rw-r--r--gcc/d/dmd/enum.h34
-rw-r--r--gcc/d/dmd/escape.d231
-rw-r--r--gcc/d/dmd/expression.d22
-rw-r--r--gcc/d/dmd/expression.h732
-rw-r--r--gcc/d/dmd/expressionsem.d59
-rw-r--r--gcc/d/dmd/func.d102
-rw-r--r--gcc/d/dmd/globals.d3
-rw-r--r--gcc/d/dmd/globals.h4
-rw-r--r--gcc/d/dmd/hdrgen.d18
-rw-r--r--gcc/d/dmd/id.d2
-rw-r--r--gcc/d/dmd/identifier.h7
-rw-r--r--gcc/d/dmd/import.h26
-rw-r--r--gcc/d/dmd/init.d2
-rw-r--r--gcc/d/dmd/init.h30
-rw-r--r--gcc/d/dmd/initsem.d5
-rw-r--r--gcc/d/dmd/lexer.d60
-rw-r--r--gcc/d/dmd/module.h27
-rw-r--r--gcc/d/dmd/mtype.d109
-rw-r--r--gcc/d/dmd/mtype.h540
-rw-r--r--gcc/d/dmd/nspace.h20
-rw-r--r--gcc/d/dmd/parsetimevisitor.d4
-rw-r--r--gcc/d/dmd/root/object.h4
-rw-r--r--gcc/d/dmd/safe.d19
-rw-r--r--gcc/d/dmd/sideeffect.d29
-rw-r--r--gcc/d/dmd/statement.d2
-rw-r--r--gcc/d/dmd/statement.h318
-rw-r--r--gcc/d/dmd/statementsem.d13
-rw-r--r--gcc/d/dmd/staticassert.h12
-rw-r--r--gcc/d/dmd/template.h154
-rw-r--r--gcc/d/dmd/transitivevisitor.d14
-rw-r--r--gcc/d/dmd/typesem.d20
-rw-r--r--gcc/d/dmd/version.h28
-rw-r--r--gcc/d/dmd/visitor.h6
-rw-r--r--gcc/d/lang.opt4
-rw-r--r--gcc/d/runtime.def4
-rw-r--r--gcc/testsuite/gdc.test/compilable/dtoh_ClassDeclaration.d10
-rw-r--r--gcc/testsuite/gdc.test/compilable/dtoh_TemplateDeclaration.d2
-rw-r--r--gcc/testsuite/gdc.test/compilable/test22865.d35
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/dip1000_deprecation.d59
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/dip25.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail12390.d3
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail22351.d20
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail23135.d17
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail_scope.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fix22108.d13
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fix23138.d16
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test15660.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test18484.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test20881.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable_cxx/extra-files/test22351.cpp46
-rw-r--r--gcc/testsuite/gdc.test/runnable_cxx/extra-files/test23135.cpp52
-rw-r--r--gcc/testsuite/gdc.test/runnable_cxx/test22351.d55
-rw-r--r--gcc/testsuite/gdc.test/runnable_cxx/test23135.d38
69 files changed, 2432 insertions, 1714 deletions
diff --git a/gcc/d/d-lang.cc b/gcc/d/d-lang.cc
index d1f4959..ef0fe0b 100644
--- a/gcc/d/d-lang.cc
+++ b/gcc/d/d-lang.cc
@@ -581,6 +581,7 @@ d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
global.params.rvalueRefParam = FeatureState::enabled;
global.params.inclusiveInContracts = value;
global.params.shortenedMethods = value;
+ global.params.fixImmutableConv = value;
break;
case OPT_fpreview_bitfields:
@@ -615,6 +616,10 @@ d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
global.params.fixAliasThis = value;
break;
+ case OPT_fpreview_fiximmutableconv:
+ global.params.fixImmutableConv = value;
+ break;
+
case OPT_fpreview_in:
global.params.previewIn = value;
break;
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index b4d42ec..c37da05 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-a6c5224b2d6b61fa3856aa8a3369581f7c949b68
+4d07f22f29d098869ad937f0499d8895df089a71
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 bdeb38e..f27ca07 100644
--- a/gcc/d/dmd/aggregate.h
+++ b/gcc/d/dmd/aggregate.h
@@ -120,20 +120,20 @@ public:
Sizeok sizeok; // set when structsize contains valid data
virtual Scope *newScope(Scope *sc);
- void setScope(Scope *sc);
+ void setScope(Scope *sc) override final;
size_t nonHiddenFields();
bool determineSize(const Loc &loc);
virtual void finalizeSize() = 0;
- uinteger_t size(const Loc &loc);
+ uinteger_t size(const Loc &loc) override final;
bool fill(const Loc &loc, Expressions *elements, bool ctorinit);
- Type *getType();
- bool isDeprecated() const; // is aggregate deprecated?
+ Type *getType() override final;
+ bool isDeprecated() const override final; // is aggregate deprecated?
void setDeprecated();
bool isNested() const;
- bool isExport() const;
+ bool isExport() const override final;
Dsymbol *searchCtor();
- Visibility visible();
+ Visibility visible() override final;
// 'this' type
Type *handleType() { return type; }
@@ -143,8 +143,8 @@ public:
// Back end
void *sinit;
- AggregateDeclaration *isAggregateDeclaration() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ AggregateDeclaration *isAggregateDeclaration() override final { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
struct StructFlags
@@ -186,28 +186,28 @@ public:
TypeTuple *argTypes;
static StructDeclaration *create(const Loc &loc, Identifier *id, bool inObject);
- StructDeclaration *syntaxCopy(Dsymbol *s);
- Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);
- const char *kind() const;
- void finalizeSize();
+ StructDeclaration *syntaxCopy(Dsymbol *s) override;
+ Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly) override final;
+ const char *kind() const override;
+ void finalizeSize() override final;
bool isPOD();
- StructDeclaration *isStructDeclaration() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ StructDeclaration *isStructDeclaration() override final { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
unsigned numArgTypes() const;
Type *argType(unsigned index);
bool hasRegularCtor(bool checkDisabled = false);
};
-class UnionDeclaration : public StructDeclaration
+class UnionDeclaration final : public StructDeclaration
{
public:
- UnionDeclaration *syntaxCopy(Dsymbol *s);
- const char *kind() const;
+ UnionDeclaration *syntaxCopy(Dsymbol *s) override;
+ const char *kind() const override;
- UnionDeclaration *isUnionDeclaration() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ UnionDeclaration *isUnionDeclaration() override { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
struct BaseClass
@@ -279,9 +279,9 @@ public:
Symbol *cpp_type_info_ptr_sym; // cached instance of class Id.cpp_type_info_ptr
static ClassDeclaration *create(const Loc &loc, Identifier *id, BaseClasses *baseclasses, Dsymbols *members, bool inObject);
- const char *toPrettyChars(bool QualifyTypes = false);
- ClassDeclaration *syntaxCopy(Dsymbol *s);
- Scope *newScope(Scope *sc);
+ const char *toPrettyChars(bool QualifyTypes = false) override;
+ ClassDeclaration *syntaxCopy(Dsymbol *s) override;
+ Scope *newScope(Scope *sc) override;
bool isBaseOf2(ClassDeclaration *cd);
#define OFFSET_RUNTIME 0x76543210
@@ -289,9 +289,9 @@ public:
virtual bool isBaseOf(ClassDeclaration *cd, int *poffset);
bool isBaseInfoComplete();
- Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);
+ Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly) override final;
ClassDeclaration *searchBase(Identifier *ident);
- void finalizeSize();
+ void finalizeSize() override;
bool hasMonitor();
bool isFuncHidden(FuncDeclaration *fd);
FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf);
@@ -301,30 +301,30 @@ public:
virtual bool isCPPinterface() const;
bool isAbstract();
virtual int vtblOffset() const;
- const char *kind() const;
+ const char *kind() const override;
- void addLocalClass(ClassDeclarations *);
- void addObjcSymbols(ClassDeclarations *classes, ClassDeclarations *categories);
+ void addLocalClass(ClassDeclarations *) override final;
+ void addObjcSymbols(ClassDeclarations *classes, ClassDeclarations *categories) override final;
// Back end
Dsymbol *vtblsym;
Dsymbol *vtblSymbol();
- ClassDeclaration *isClassDeclaration() { return (ClassDeclaration *)this; }
- void accept(Visitor *v) { v->visit(this); }
+ ClassDeclaration *isClassDeclaration() override final { return (ClassDeclaration *)this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class InterfaceDeclaration : public ClassDeclaration
+class InterfaceDeclaration final : public ClassDeclaration
{
public:
- InterfaceDeclaration *syntaxCopy(Dsymbol *s);
- Scope *newScope(Scope *sc);
- bool isBaseOf(ClassDeclaration *cd, int *poffset);
- const char *kind() const;
- int vtblOffset() const;
- bool isCPPinterface() const;
- bool isCOMinterface() const;
-
- InterfaceDeclaration *isInterfaceDeclaration() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ InterfaceDeclaration *syntaxCopy(Dsymbol *s) override;
+ Scope *newScope(Scope *sc) override;
+ bool isBaseOf(ClassDeclaration *cd, int *poffset) override;
+ const char *kind() const override;
+ int vtblOffset() const override;
+ bool isCPPinterface() const override;
+ bool isCOMinterface() const override;
+
+ InterfaceDeclaration *isInterfaceDeclaration() override { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
diff --git a/gcc/d/dmd/aliasthis.h b/gcc/d/dmd/aliasthis.h
index 3b67903..c63d717 100644
--- a/gcc/d/dmd/aliasthis.h
+++ b/gcc/d/dmd/aliasthis.h
@@ -15,7 +15,7 @@
/**************************************************************/
-class AliasThis : public Dsymbol
+class AliasThis final : public Dsymbol
{
public:
// alias Identifier this;
@@ -23,9 +23,9 @@ public:
Dsymbol *sym;
bool isDeprecated_;
- AliasThis *syntaxCopy(Dsymbol *);
- const char *kind() const;
+ AliasThis *syntaxCopy(Dsymbol *) override;
+ const char *kind() const override;
AliasThis *isAliasThis() { return this; }
- void accept(Visitor *v) { v->visit(this); }
- bool isDeprecated() const { return this->isDeprecated_; }
+ void accept(Visitor *v) override { v->visit(this); }
+ bool isDeprecated() const override { return this->isDeprecated_; }
};
diff --git a/gcc/d/dmd/attrib.h b/gcc/d/dmd/attrib.h
index 812729b..1fe33a6 100644
--- a/gcc/d/dmd/attrib.h
+++ b/gcc/d/dmd/attrib.h
@@ -26,20 +26,20 @@ public:
virtual Dsymbols *include(Scope *sc);
virtual Scope *newScope(Scope *sc);
- void addMember(Scope *sc, ScopeDsymbol *sds);
- void setScope(Scope *sc);
- void importAll(Scope *sc);
- void addComment(const utf8_t *comment);
- const char *kind() const;
- bool oneMember(Dsymbol **ps, Identifier *ident);
- void setFieldOffset(AggregateDeclaration *ad, FieldState& fieldState, bool isunion);
- bool hasPointers();
- bool hasStaticCtorOrDtor();
- void checkCtorConstInit();
- void addLocalClass(ClassDeclarations *);
- AttribDeclaration *isAttribDeclaration() { return this; }
-
- void accept(Visitor *v) { v->visit(this); }
+ void addMember(Scope *sc, ScopeDsymbol *sds) override;
+ void setScope(Scope *sc) override;
+ void importAll(Scope *sc) override;
+ void addComment(const utf8_t *comment) override;
+ const char *kind() const override;
+ bool oneMember(Dsymbol **ps, Identifier *ident) override;
+ void setFieldOffset(AggregateDeclaration *ad, FieldState& fieldState, bool isunion) override;
+ bool hasPointers() override final;
+ bool hasStaticCtorOrDtor() override final;
+ void checkCtorConstInit() override final;
+ void addLocalClass(ClassDeclarations *) override final;
+ AttribDeclaration *isAttribDeclaration() override final { return this; }
+
+ void accept(Visitor *v) override { v->visit(this); }
};
class StorageClassDeclaration : public AttribDeclaration
@@ -47,90 +47,90 @@ class StorageClassDeclaration : public AttribDeclaration
public:
StorageClass stc;
- StorageClassDeclaration *syntaxCopy(Dsymbol *s);
- Scope *newScope(Scope *sc);
- bool oneMember(Dsymbol **ps, Identifier *ident);
- void addMember(Scope *sc, ScopeDsymbol *sds);
- StorageClassDeclaration *isStorageClassDeclaration() { return this; }
+ StorageClassDeclaration *syntaxCopy(Dsymbol *s) override;
+ Scope *newScope(Scope *sc) override;
+ bool oneMember(Dsymbol **ps, Identifier *ident) override final;
+ void addMember(Scope *sc, ScopeDsymbol *sds) override;
+ StorageClassDeclaration *isStorageClassDeclaration() override { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class DeprecatedDeclaration : public StorageClassDeclaration
+class DeprecatedDeclaration final : public StorageClassDeclaration
{
public:
Expression *msg;
const char *msgstr;
- DeprecatedDeclaration *syntaxCopy(Dsymbol *s);
- Scope *newScope(Scope *sc);
- void setScope(Scope *sc);
- void accept(Visitor *v) { v->visit(this); }
+ DeprecatedDeclaration *syntaxCopy(Dsymbol *s) override;
+ Scope *newScope(Scope *sc) override;
+ void setScope(Scope *sc) override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class LinkDeclaration : public AttribDeclaration
+class LinkDeclaration final : public AttribDeclaration
{
public:
LINK linkage;
static LinkDeclaration *create(const Loc &loc, LINK p, Dsymbols *decl);
- LinkDeclaration *syntaxCopy(Dsymbol *s);
- Scope *newScope(Scope *sc);
- const char *toChars() const;
- void accept(Visitor *v) { v->visit(this); }
+ LinkDeclaration *syntaxCopy(Dsymbol *s) override;
+ Scope *newScope(Scope *sc) override;
+ const char *toChars() const override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class CPPMangleDeclaration : public AttribDeclaration
+class CPPMangleDeclaration final : public AttribDeclaration
{
public:
CPPMANGLE cppmangle;
- CPPMangleDeclaration *syntaxCopy(Dsymbol *s);
- Scope *newScope(Scope *sc);
- void setScope(Scope *sc);
- const char *toChars() const;
- void accept(Visitor *v) { v->visit(this); }
+ CPPMangleDeclaration *syntaxCopy(Dsymbol *s) override;
+ Scope *newScope(Scope *sc) override;
+ void setScope(Scope *sc) override;
+ const char *toChars() const override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class CPPNamespaceDeclaration : public AttribDeclaration
+class CPPNamespaceDeclaration final : public AttribDeclaration
{
public:
Expression *exp;
- CPPNamespaceDeclaration *syntaxCopy(Dsymbol *s);
- Scope *newScope(Scope *sc);
- const char *toChars() const;
- void accept(Visitor *v) { v->visit(this); }
+ CPPNamespaceDeclaration *syntaxCopy(Dsymbol *s) override;
+ Scope *newScope(Scope *sc) override;
+ const char *toChars() const override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class VisibilityDeclaration : public AttribDeclaration
+class VisibilityDeclaration final : public AttribDeclaration
{
public:
Visibility visibility;
DArray<Identifier*> pkg_identifiers;
- VisibilityDeclaration *syntaxCopy(Dsymbol *s);
- Scope *newScope(Scope *sc);
- void addMember(Scope *sc, ScopeDsymbol *sds);
- const char *kind() const;
- const char *toPrettyChars(bool unused);
- VisibilityDeclaration *isVisibilityDeclaration() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ VisibilityDeclaration *syntaxCopy(Dsymbol *s) override;
+ Scope *newScope(Scope *sc) override;
+ void addMember(Scope *sc, ScopeDsymbol *sds) override;
+ const char *kind() const override;
+ const char *toPrettyChars(bool unused) override;
+ VisibilityDeclaration *isVisibilityDeclaration() override { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class AlignDeclaration : public AttribDeclaration
+class AlignDeclaration final : public AttribDeclaration
{
public:
Expressions *alignExps;
structalign_t salign;
AlignDeclaration(const Loc &loc, Expression *ealign, Dsymbols *decl);
- AlignDeclaration *syntaxCopy(Dsymbol *s);
- Scope *newScope(Scope *sc);
- void accept(Visitor *v) { v->visit(this); }
+ AlignDeclaration *syntaxCopy(Dsymbol *s) override;
+ Scope *newScope(Scope *sc) override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class AnonDeclaration : public AttribDeclaration
+class AnonDeclaration final : public AttribDeclaration
{
public:
bool isunion;
@@ -139,24 +139,24 @@ public:
unsigned anonstructsize; // size of anonymous struct
unsigned anonalignsize; // size of anonymous struct for alignment purposes
- AnonDeclaration *syntaxCopy(Dsymbol *s);
- void setScope(Scope *sc);
- void setFieldOffset(AggregateDeclaration *ad, FieldState& fieldState, bool isunion);
- const char *kind() const;
- AnonDeclaration *isAnonDeclaration() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ AnonDeclaration *syntaxCopy(Dsymbol *s) override;
+ void setScope(Scope *sc) override;
+ void setFieldOffset(AggregateDeclaration *ad, FieldState& fieldState, bool isunion) override;
+ const char *kind() const override;
+ AnonDeclaration *isAnonDeclaration() override { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class PragmaDeclaration : public AttribDeclaration
+class PragmaDeclaration final : public AttribDeclaration
{
public:
Expressions *args; // array of Expression's
- PragmaDeclaration *syntaxCopy(Dsymbol *s);
- Scope *newScope(Scope *sc);
+ PragmaDeclaration *syntaxCopy(Dsymbol *s) override;
+ Scope *newScope(Scope *sc) override;
PINLINE evalPragmaInline(Scope* sc);
- const char *kind() const;
- void accept(Visitor *v) { v->visit(this); }
+ const char *kind() const override;
+ void accept(Visitor *v) override { v->visit(this); }
};
class ConditionalDeclaration : public AttribDeclaration
@@ -165,31 +165,31 @@ public:
Condition *condition;
Dsymbols *elsedecl; // array of Dsymbol's for else block
- ConditionalDeclaration *syntaxCopy(Dsymbol *s);
- bool oneMember(Dsymbol **ps, Identifier *ident);
- Dsymbols *include(Scope *sc);
- void addComment(const utf8_t *comment);
- void setScope(Scope *sc);
- void accept(Visitor *v) { v->visit(this); }
+ ConditionalDeclaration *syntaxCopy(Dsymbol *s) override;
+ bool oneMember(Dsymbol **ps, Identifier *ident) override final;
+ Dsymbols *include(Scope *sc) override;
+ void addComment(const utf8_t *comment) override final;
+ void setScope(Scope *sc) override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class StaticIfDeclaration : public ConditionalDeclaration
+class StaticIfDeclaration final : public ConditionalDeclaration
{
public:
ScopeDsymbol *scopesym;
bool addisdone;
bool onStack;
- StaticIfDeclaration *syntaxCopy(Dsymbol *s);
- Dsymbols *include(Scope *sc);
- void addMember(Scope *sc, ScopeDsymbol *sds);
- void setScope(Scope *sc);
- void importAll(Scope *sc);
- const char *kind() const;
- void accept(Visitor *v) { v->visit(this); }
+ StaticIfDeclaration *syntaxCopy(Dsymbol *s) override;
+ Dsymbols *include(Scope *sc) override;
+ void addMember(Scope *sc, ScopeDsymbol *sds) override;
+ void setScope(Scope *sc) override;
+ void importAll(Scope *sc) override;
+ const char *kind() const override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class StaticForeachDeclaration : public AttribDeclaration
+class StaticForeachDeclaration final : public AttribDeclaration
{
public:
StaticForeach *sfe;
@@ -198,31 +198,31 @@ public:
bool cached;
Dsymbols *cache;
- StaticForeachDeclaration *syntaxCopy(Dsymbol *s);
- bool oneMember(Dsymbol **ps, Identifier *ident);
- Dsymbols *include(Scope *sc);
- void addMember(Scope *sc, ScopeDsymbol *sds);
- void addComment(const utf8_t *comment);
- void setScope(Scope *sc);
- void importAll(Scope *sc);
- const char *kind() const;
- void accept(Visitor *v) { v->visit(this); }
+ StaticForeachDeclaration *syntaxCopy(Dsymbol *s) override;
+ bool oneMember(Dsymbol **ps, Identifier *ident) override;
+ Dsymbols *include(Scope *sc) override;
+ void addMember(Scope *sc, ScopeDsymbol *sds) override;
+ void addComment(const utf8_t *comment) override;
+ void setScope(Scope *sc) override;
+ void importAll(Scope *sc) override;
+ const char *kind() const override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class ForwardingAttribDeclaration : public AttribDeclaration
+class ForwardingAttribDeclaration final : public AttribDeclaration
{
public:
ForwardingScopeDsymbol *sym;
- Scope *newScope(Scope *sc);
- void addMember(Scope *sc, ScopeDsymbol *sds);
- ForwardingAttribDeclaration *isForwardingAttribDeclaration() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ Scope *newScope(Scope *sc) override;
+ void addMember(Scope *sc, ScopeDsymbol *sds) override;
+ ForwardingAttribDeclaration *isForwardingAttribDeclaration() override { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
// Mixin declarations
-class CompileDeclaration : public AttribDeclaration
+class CompileDeclaration final : public AttribDeclaration
{
public:
Expressions *exps;
@@ -230,26 +230,26 @@ public:
ScopeDsymbol *scopesym;
bool compiled;
- CompileDeclaration *syntaxCopy(Dsymbol *s);
- void addMember(Scope *sc, ScopeDsymbol *sds);
- void setScope(Scope *sc);
- const char *kind() const;
- void accept(Visitor *v) { v->visit(this); }
+ CompileDeclaration *syntaxCopy(Dsymbol *s) override;
+ void addMember(Scope *sc, ScopeDsymbol *sds) override;
+ void setScope(Scope *sc) override;
+ const char *kind() const override;
+ void accept(Visitor *v) override { v->visit(this); }
};
/**
* User defined attributes look like:
* @(args, ...)
*/
-class UserAttributeDeclaration : public AttribDeclaration
+class UserAttributeDeclaration final : public AttribDeclaration
{
public:
Expressions *atts;
- UserAttributeDeclaration *syntaxCopy(Dsymbol *s);
- Scope *newScope(Scope *sc);
- void setScope(Scope *sc);
+ UserAttributeDeclaration *syntaxCopy(Dsymbol *s) override;
+ Scope *newScope(Scope *sc) override;
+ void setScope(Scope *sc) override;
Expressions *getAttributes();
- const char *kind() const;
- void accept(Visitor *v) { v->visit(this); }
+ const char *kind() const override;
+ void accept(Visitor *v) override { v->visit(this); }
};
diff --git a/gcc/d/dmd/cond.h b/gcc/d/dmd/cond.h
index d69c13e..b33f288 100644
--- a/gcc/d/dmd/cond.h
+++ b/gcc/d/dmd/cond.h
@@ -35,14 +35,16 @@ public:
Loc loc;
Include inc;
+ DYNCAST dyncast() const override final { return DYNCAST_CONDITION; }
+
virtual Condition *syntaxCopy() = 0;
virtual int include(Scope *sc) = 0;
virtual DebugCondition *isDebugCondition() { return NULL; }
virtual VersionCondition *isVersionCondition() { return NULL; }
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class StaticForeach
+class StaticForeach final : public RootObject
{
public:
Loc loc;
@@ -62,37 +64,37 @@ public:
Identifier *ident;
Module *mod;
- DVCondition *syntaxCopy();
- void accept(Visitor *v) { v->visit(this); }
+ DVCondition *syntaxCopy() override final;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class DebugCondition : public DVCondition
+class DebugCondition final : public DVCondition
{
public:
static void addGlobalIdent(const char *ident);
- int include(Scope *sc);
- DebugCondition *isDebugCondition() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ int include(Scope *sc) override;
+ DebugCondition *isDebugCondition() override { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class VersionCondition : public DVCondition
+class VersionCondition final : public DVCondition
{
public:
static void addGlobalIdent(const char *ident);
static void addPredefinedGlobalIdent(const char *ident);
- int include(Scope *sc);
- VersionCondition *isVersionCondition() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ int include(Scope *sc) override;
+ VersionCondition *isVersionCondition() override { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class StaticIfCondition : public Condition
+class StaticIfCondition final : public Condition
{
public:
Expression *exp;
- StaticIfCondition *syntaxCopy();
- int include(Scope *sc);
- void accept(Visitor *v) { v->visit(this); }
+ StaticIfCondition *syntaxCopy() override;
+ int include(Scope *sc) override;
+ void accept(Visitor *v) override { v->visit(this); }
};
diff --git a/gcc/d/dmd/cparse.d b/gcc/d/dmd/cparse.d
index fde0648..344933a 100644
--- a/gcc/d/dmd/cparse.d
+++ b/gcc/d/dmd/cparse.d
@@ -59,8 +59,16 @@ final class CParser(AST) : Parser!AST
*/
Array!(void*) typedefTab; /// Array of AST.Type[Identifier], typedef's indexed by Identifier
+ /* This is passed in as a list of #define lines, as generated by the C preprocessor with the
+ * appropriate switch to emit them. We append to it any #define's and #undef's encountered in the source
+ * file, as cpp with the -dD embeds them in the preprocessed output file.
+ * Once the file is parsed, then the #define's are converted to D symbols and appended to the array
+ * of Dsymbols returned by parseModule().
+ */
+ OutBuffer* defines;
+
extern (D) this(TARGET)(AST.Module _module, const(char)[] input, bool doDocComment,
- const ref TARGET target)
+ const ref TARGET target, OutBuffer* defines)
{
super(_module, input, doDocComment);
@@ -69,6 +77,7 @@ final class CParser(AST) : Parser!AST
linkage = LINK.c;
Ccompile = true;
this.packalign.setDefault();
+ this.defines = defines;
// Configure sizes for C `long`, `long double`, `wchar_t`, ...
this.boolsize = target.boolsize;
@@ -104,6 +113,8 @@ final class CParser(AST) : Parser!AST
{
if (token.value == TOK.endOfFile)
{
+ addDefines(); // convert #define's to Dsymbols
+
// wrap the symbols in `extern (C) { symbols }`
auto wrap = new AST.Dsymbols();
auto ld = new AST.LinkDeclaration(token.loc, LINK.c, symbols);
@@ -976,16 +987,19 @@ final class CParser(AST) : Parser!AST
// ( type-name )
e = new AST.TypeExp(loc, t);
}
- e = new AST.DotIdExp(loc, e, Id.__sizeof);
- break;
}
- // must be an expression
- e = cparsePrimaryExp();
- e = new AST.DotIdExp(loc, e, Id.__sizeof);
- break;
+ else
+ {
+ // must be an expression
+ e = cparseUnaryExp();
+ }
+ }
+ else
+ {
+ //C11 6.5.3
+ e = cparseUnaryExp();
}
- e = cparseUnaryExp();
e = new AST.DotIdExp(loc, e, Id.__sizeof);
break;
}
@@ -1697,7 +1711,7 @@ final class CParser(AST) : Parser!AST
while (1)
{
Identifier id;
- AST.Expression asmname;
+ AST.StringExp asmName;
auto dt = cparseDeclarator(DTR.xdirect, tspec, id, specifier);
if (!dt)
{
@@ -1719,7 +1733,7 @@ final class CParser(AST) : Parser!AST
case TOK.asm_:
case TOK.__attribute__:
if (token.value == TOK.asm_)
- asmname = cparseSimpleAsmExpr();
+ asmName = cparseSimpleAsmExpr();
if (token.value == TOK.__attribute__)
{
cparseGnuAttributes(specifier);
@@ -1876,14 +1890,26 @@ final class CParser(AST) : Parser!AST
s = new AST.LinkDeclaration(s.loc, linkage, decls);
}
// Saw `asm("name")` in the function, type, or variable definition.
- // This maps directly to `pragma(mangle, "name")`
- if (asmname)
+ // This is equivalent to `pragma(mangle, "name")` in D
+ if (asmName)
{
- auto args = new AST.Expressions(1);
- (*args)[0] = asmname;
- auto decls = new AST.Dsymbols(1);
- (*decls)[0] = s;
- s = new AST.PragmaDeclaration(asmname.loc, Id.mangle, args, decls);
+ /*
+ https://issues.dlang.org/show_bug.cgi?id=23012
+ Ideally this would be translated to a pragma(mangle)
+ decl. This is not possible because ImportC symbols are
+ (currently) merged before semantic analysis is performed,
+ so the pragma(mangle) never effects any change on the declarations
+ it pertains too.
+
+ Writing to mangleOverride directly avoids this, and is possible
+ because C only a StringExp is allowed unlike a full fat pragma(mangle)
+ which is more liberal.
+ */
+ if (auto p = s.isDeclaration())
+ {
+ auto str = asmName.peekString();
+ p.mangleOverride = str;
+ }
}
symbols.push(s);
}
@@ -3062,7 +3088,7 @@ final class CParser(AST) : Parser!AST
* asm-string-literal:
* string-literal
*/
- private AST.Expression cparseSimpleAsmExpr()
+ private AST.StringExp cparseSimpleAsmExpr()
{
nextToken(); // move past asm
check(TOK.leftParenthesis);
@@ -3070,7 +3096,7 @@ final class CParser(AST) : Parser!AST
error("string literal expected");
auto label = cparsePrimaryExp();
check(TOK.rightParenthesis);
- return label;
+ return cast(AST.StringExp) label;
}
/*************************
@@ -4250,12 +4276,21 @@ final class CParser(AST) : Parser!AST
case TOK._Bool:
//case TOK._Imaginary: // ? missing in Spec
case TOK._Complex:
-
- // typedef-name
- case TOK.identifier: // will not know until semantic if typedef
t = peek(t);
break;
+ case TOK.identifier:
+ // Use typedef table to disambiguate
+ if (isTypedef(t.ident))
+ {
+ t = peek(t);
+ break;
+ }
+ else
+ {
+ return false;
+ }
+
// struct-or-union-specifier
// enum-specifier
case TOK.struct_:
@@ -4891,6 +4926,17 @@ final class CParser(AST) : Parser!AST
poundLine(n, false);
return true;
}
+ else if (defines && (n.ident == Id.define || n.ident == Id.undef))
+ {
+ /* Append this line to `defines`.
+ * Not canonicalizing it - assume it already is
+ */
+ defines.writeByte('#');
+ defines.writestring(n.ident.toString());
+ skipToNextLine(defines);
+ defines.writeByte('\n');
+ return true;
+ }
else if (n.ident == Id.__pragma)
{
pragmaDirective(scanloc);
@@ -5078,4 +5124,70 @@ final class CParser(AST) : Parser!AST
}
//}
+
+ /******************************************************************************/
+ /********************************* #define Parser *****************************/
+ //{
+
+ /**
+ * Go through the #define's in the defines buffer and see what we can convert
+ * to Dsymbols, which are then appended to symbols[]
+ */
+ void addDefines()
+ {
+ if (!defines || defines.length < 10) // minimum length of a #define line
+ return;
+ const length = defines.length;
+ auto slice = defines.peekChars()[0 .. length];
+ resetDefineLines(slice); // reset lexer
+
+ const(char)* endp = &slice[length - 7];
+
+ Token n;
+
+ while (p < endp)
+ {
+ if (p[0 .. 7] == "#define")
+ {
+ p += 7;
+ scan(&n);
+ //printf("%s\n", n.toChars());
+ if (n.value == TOK.identifier)
+ {
+ auto id = n.ident;
+ scan(&n);
+ if (n.value == TOK.endOfLine) // #define identifier
+ {
+ nextDefineLine();
+ continue;
+ }
+ if (n.value == TOK.int32Literal)
+ {
+ const value = n.intvalue;
+ scan(&n);
+ if (n.value == TOK.endOfLine)
+ {
+ /* Declare manifest constant:
+ * enum id = value;
+ */
+ AST.Expression e = new AST.IntegerExp(scanloc, value, AST.Type.tint32);
+ auto v = new AST.VarDeclaration(scanloc, AST.Type.tint32, id, new AST.ExpInitializer(scanloc, e), STC.manifest);
+ symbols.push(v);
+ nextDefineLine();
+ continue;
+ }
+ }
+ }
+ skipToNextLine();
+ }
+ else if (n.value != TOK.endOfLine)
+ {
+ skipToNextLine();
+ }
+ nextDefineLine();
+ assert(p - slice.ptr <= length);
+ }
+ }
+
+ //}
}
diff --git a/gcc/d/dmd/ctfe.h b/gcc/d/dmd/ctfe.h
index 5979aa7..ab022ff 100644
--- a/gcc/d/dmd/ctfe.h
+++ b/gcc/d/dmd/ctfe.h
@@ -17,7 +17,7 @@
A reference to a class, or an interface. We need this when we
point to a base class (we must record what the type is).
*/
-class ClassReferenceExp : public Expression
+class ClassReferenceExp final : public Expression
{
public:
StructLiteralExp *value;
@@ -26,39 +26,39 @@ public:
/// Return index of the field, or -1 if not found
/// Same as getFieldIndex, but checks for a direct match with the VarDeclaration
int findFieldIndexByName(VarDeclaration *v);
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
/**
An uninitialized value
*/
-class VoidInitExp : public Expression
+class VoidInitExp final : public Expression
{
public:
VarDeclaration *var;
- const char *toChars() const;
- void accept(Visitor *v) { v->visit(this); }
+ const char *toChars() const override;
+ void accept(Visitor *v) override { v->visit(this); }
};
/**
Fake class which holds the thrown exception.
Used for implementing exception handling.
*/
-class ThrownExceptionExp : public Expression
+class ThrownExceptionExp final : public Expression
{
public:
ClassReferenceExp *thrown; // the thing being tossed
- const char *toChars() const;
- void accept(Visitor *v) { v->visit(this); }
+ const char *toChars() const override;
+ void accept(Visitor *v) override { v->visit(this); }
};
/****************************************************************/
// This type is only used by the interpreter.
-class CTFEExp : public Expression
+class CTFEExp final : public Expression
{
public:
- const char *toChars() const;
+ const char *toChars() const override;
};
diff --git a/gcc/d/dmd/dcast.d b/gcc/d/dmd/dcast.d
index c0a86f5..4607d6f 100644
--- a/gcc/d/dmd/dcast.d
+++ b/gcc/d/dmd/dcast.d
@@ -824,9 +824,8 @@ MATCH implicitConvTo(Expression e, Type t)
* convert to immutable
*/
if (e.f &&
- // lots of legacy code breaks with the following purity check
- (global.params.useDIP1000 != FeatureState.enabled || e.f.isPure() >= PURE.const_) &&
- e.f.isReturnIsolated() // check isReturnIsolated last, because it is potentially expensive.
+ (!global.params.fixImmutableConv || e.f.isPure() >= PURE.const_) &&
+ e.f.isReturnIsolated() // check isReturnIsolated last, because it is potentially expensive.
)
{
result = e.type.immutableOf().implicitConvTo(t);
@@ -2768,16 +2767,14 @@ Expression scaleFactor(BinExp be, Scope* sc)
else
assert(0);
- if (sc.func && !sc.intypeof)
+
+ eoff = eoff.optimize(WANTvalue);
+ if (eoff.op == EXP.int64 && eoff.toInteger() == 0)
{
- eoff = eoff.optimize(WANTvalue);
- if (eoff.op == EXP.int64 && eoff.toInteger() == 0)
- {
- }
- else if (sc.func.setUnsafe(false, be.loc, "pointer arithmetic not allowed in @safe functions"))
- {
- return ErrorExp.get();
- }
+ }
+ else if (sc.setUnsafe(false, be.loc, "pointer arithmetic not allowed in @safe functions"))
+ {
+ return ErrorExp.get();
}
return be;
diff --git a/gcc/d/dmd/declaration.h b/gcc/d/dmd/declaration.h
index 0bde33d..2c7d381 100644
--- a/gcc/d/dmd/declaration.h
+++ b/gcc/d/dmd/declaration.h
@@ -122,10 +122,10 @@ public:
Symbol* isym; // import version of csym
DString mangleOverride; // overridden symbol with pragma(mangle, "...")
- const char *kind() const;
- uinteger_t size(const Loc &loc);
+ const char *kind() const override;
+ uinteger_t size(const Loc &loc) override final;
- Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);
+ Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly) override final;
bool isStatic() const { return (storage_class & STCstatic) != 0; }
LINK resolvedLinkage() const; // returns the linkage, resolving the target-specific `System` one
@@ -142,7 +142,7 @@ public:
bool isScope() const { return (storage_class & STCscope) != 0; }
bool isSynchronized() const { return (storage_class & STCsynchronized) != 0; }
bool isParameter() const { return (storage_class & STCparameter) != 0; }
- bool isDeprecated() const { return (storage_class & STCdeprecated) != 0; }
+ bool isDeprecated() const override final { return (storage_class & STCdeprecated) != 0; }
bool isOverride() const { return (storage_class & STCoverride) != 0; }
bool isResult() const { return (storage_class & STCresult) != 0; }
bool isField() const { return (storage_class & STCfield) != 0; }
@@ -154,15 +154,15 @@ public:
bool isFuture() const { return (storage_class & STCfuture) != 0; }
- Visibility visible();
+ Visibility visible() override final;
- Declaration *isDeclaration() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ Declaration *isDeclaration() override final { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
/**************************************************************/
-class TupleDeclaration : public Declaration
+class TupleDeclaration final : public Declaration
{
public:
Objects *objects;
@@ -170,19 +170,19 @@ public:
TypeTuple *tupletype; // !=NULL if this is a type tuple
- TupleDeclaration *syntaxCopy(Dsymbol *);
- const char *kind() const;
- Type *getType();
- Dsymbol *toAlias2();
- bool needThis();
+ TupleDeclaration *syntaxCopy(Dsymbol *) override;
+ const char *kind() const override;
+ Type *getType() override;
+ Dsymbol *toAlias2() override;
+ bool needThis() override;
- TupleDeclaration *isTupleDeclaration() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ TupleDeclaration *isTupleDeclaration() override { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
/**************************************************************/
-class AliasDeclaration : public Declaration
+class AliasDeclaration final : public Declaration
{
public:
Dsymbol *aliassym;
@@ -190,36 +190,36 @@ public:
Dsymbol *_import; // !=NULL if unresolved internal alias for selective import
static AliasDeclaration *create(const Loc &loc, Identifier *id, Type *type);
- AliasDeclaration *syntaxCopy(Dsymbol *);
- bool overloadInsert(Dsymbol *s);
- const char *kind() const;
- Type *getType();
- Dsymbol *toAlias();
- Dsymbol *toAlias2();
- bool isOverloadable() const;
+ AliasDeclaration *syntaxCopy(Dsymbol *) override;
+ bool overloadInsert(Dsymbol *s) override;
+ const char *kind() const override;
+ Type *getType() override;
+ Dsymbol *toAlias() override;
+ Dsymbol *toAlias2() override;
+ bool isOverloadable() const override;
- AliasDeclaration *isAliasDeclaration() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ AliasDeclaration *isAliasDeclaration() override { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
/**************************************************************/
-class OverDeclaration : public Declaration
+class OverDeclaration final : public Declaration
{
public:
Dsymbol *overnext; // next in overload list
Dsymbol *aliassym;
- const char *kind() const;
- bool equals(const RootObject *o) const;
- bool overloadInsert(Dsymbol *s);
+ const char *kind() const override;
+ bool equals(const RootObject *o) const override;
+ bool overloadInsert(Dsymbol *s) override;
- Dsymbol *toAlias();
+ Dsymbol *toAlias() override;
Dsymbol *isUnique();
- bool isOverloadable() const;
+ bool isOverloadable() const override;
- OverDeclaration *isOverDeclaration() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ OverDeclaration *isOverDeclaration() override { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
/**************************************************************/
@@ -271,26 +271,26 @@ public:
bool isArgDtorVar() const; // temporary created to handle scope destruction of a function argument
bool isArgDtorVar(bool v);
static VarDeclaration *create(const Loc &loc, Type *t, Identifier *id, Initializer *init, StorageClass storage_class = STCundefined);
- VarDeclaration *syntaxCopy(Dsymbol *);
- void setFieldOffset(AggregateDeclaration *ad, FieldState& fieldState, bool isunion);
- const char *kind() const;
- AggregateDeclaration *isThis();
- bool needThis();
- bool isExport() const;
- bool isImportedSymbol() const;
+ VarDeclaration *syntaxCopy(Dsymbol *) override;
+ void setFieldOffset(AggregateDeclaration *ad, FieldState& fieldState, bool isunion) override final;
+ const char *kind() const override;
+ AggregateDeclaration *isThis() override final;
+ bool needThis() override final;
+ bool isExport() const override final;
+ bool isImportedSymbol() const override final;
bool isCtorinit() const;
- bool isDataseg();
- bool isThreadlocal();
+ bool isDataseg() override final;
+ bool isThreadlocal() override final;
bool isCTFE();
bool isOverlappedWith(VarDeclaration *v);
- bool hasPointers();
+ bool hasPointers() override final;
bool canTakeAddressOf();
bool needsScopeDtor();
- void checkCtorConstInit();
- Dsymbol *toAlias();
+ void checkCtorConstInit() override final;
+ Dsymbol *toAlias() override final;
// Eliminate need for dynamic_cast
- VarDeclaration *isVarDeclaration() { return (VarDeclaration *)this; }
- void accept(Visitor *v) { v->visit(this); }
+ VarDeclaration *isVarDeclaration() override final { return (VarDeclaration *)this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
/**************************************************************/
@@ -303,23 +303,23 @@ public:
unsigned fieldWidth;
unsigned bitOffset;
- BitFieldDeclaration *syntaxCopy(Dsymbol*);
- BitFieldDeclaration *isBitFieldDeclaration() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ BitFieldDeclaration *syntaxCopy(Dsymbol *) override;
+ BitFieldDeclaration *isBitFieldDeclaration() override final { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
/**************************************************************/
// This is a shell around a back end symbol
-class SymbolDeclaration : public Declaration
+class SymbolDeclaration final : public Declaration
{
public:
AggregateDeclaration *dsym;
// Eliminate need for dynamic_cast
- SymbolDeclaration *isSymbolDeclaration() { return (SymbolDeclaration *)this; }
- void accept(Visitor *v) { v->visit(this); }
+ SymbolDeclaration *isSymbolDeclaration() override { return (SymbolDeclaration *)this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
class TypeInfoDeclaration : public VarDeclaration
@@ -328,149 +328,149 @@ public:
Type *tinfo;
static TypeInfoDeclaration *create(Type *tinfo);
- TypeInfoDeclaration *syntaxCopy(Dsymbol *);
- const char *toChars() const;
+ TypeInfoDeclaration *syntaxCopy(Dsymbol *) override final;
+ const char *toChars() const override final;
- TypeInfoDeclaration *isTypeInfoDeclaration() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ TypeInfoDeclaration *isTypeInfoDeclaration() override final { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TypeInfoStructDeclaration : public TypeInfoDeclaration
+class TypeInfoStructDeclaration final : public TypeInfoDeclaration
{
public:
static TypeInfoStructDeclaration *create(Type *tinfo);
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TypeInfoClassDeclaration : public TypeInfoDeclaration
+class TypeInfoClassDeclaration final : public TypeInfoDeclaration
{
public:
static TypeInfoClassDeclaration *create(Type *tinfo);
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TypeInfoInterfaceDeclaration : public TypeInfoDeclaration
+class TypeInfoInterfaceDeclaration final : public TypeInfoDeclaration
{
public:
static TypeInfoInterfaceDeclaration *create(Type *tinfo);
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TypeInfoPointerDeclaration : public TypeInfoDeclaration
+class TypeInfoPointerDeclaration final : public TypeInfoDeclaration
{
public:
static TypeInfoPointerDeclaration *create(Type *tinfo);
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TypeInfoArrayDeclaration : public TypeInfoDeclaration
+class TypeInfoArrayDeclaration final : public TypeInfoDeclaration
{
public:
static TypeInfoArrayDeclaration *create(Type *tinfo);
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TypeInfoStaticArrayDeclaration : public TypeInfoDeclaration
+class TypeInfoStaticArrayDeclaration final : public TypeInfoDeclaration
{
public:
static TypeInfoStaticArrayDeclaration *create(Type *tinfo);
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TypeInfoAssociativeArrayDeclaration : public TypeInfoDeclaration
+class TypeInfoAssociativeArrayDeclaration final : public TypeInfoDeclaration
{
public:
static TypeInfoAssociativeArrayDeclaration *create(Type *tinfo);
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TypeInfoEnumDeclaration : public TypeInfoDeclaration
+class TypeInfoEnumDeclaration final : public TypeInfoDeclaration
{
public:
static TypeInfoEnumDeclaration *create(Type *tinfo);
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TypeInfoFunctionDeclaration : public TypeInfoDeclaration
+class TypeInfoFunctionDeclaration final : public TypeInfoDeclaration
{
public:
static TypeInfoFunctionDeclaration *create(Type *tinfo);
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TypeInfoDelegateDeclaration : public TypeInfoDeclaration
+class TypeInfoDelegateDeclaration final : public TypeInfoDeclaration
{
public:
static TypeInfoDelegateDeclaration *create(Type *tinfo);
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TypeInfoTupleDeclaration : public TypeInfoDeclaration
+class TypeInfoTupleDeclaration final : public TypeInfoDeclaration
{
public:
static TypeInfoTupleDeclaration *create(Type *tinfo);
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TypeInfoConstDeclaration : public TypeInfoDeclaration
+class TypeInfoConstDeclaration final : public TypeInfoDeclaration
{
public:
static TypeInfoConstDeclaration *create(Type *tinfo);
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TypeInfoInvariantDeclaration : public TypeInfoDeclaration
+class TypeInfoInvariantDeclaration final : public TypeInfoDeclaration
{
public:
static TypeInfoInvariantDeclaration *create(Type *tinfo);
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TypeInfoSharedDeclaration : public TypeInfoDeclaration
+class TypeInfoSharedDeclaration final : public TypeInfoDeclaration
{
public:
static TypeInfoSharedDeclaration *create(Type *tinfo);
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TypeInfoWildDeclaration : public TypeInfoDeclaration
+class TypeInfoWildDeclaration final : public TypeInfoDeclaration
{
public:
static TypeInfoWildDeclaration *create(Type *tinfo);
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TypeInfoVectorDeclaration : public TypeInfoDeclaration
+class TypeInfoVectorDeclaration final : public TypeInfoDeclaration
{
public:
static TypeInfoVectorDeclaration *create(Type *tinfo);
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
/**************************************************************/
-class ThisDeclaration : public VarDeclaration
+class ThisDeclaration final : public VarDeclaration
{
public:
- ThisDeclaration *syntaxCopy(Dsymbol *);
- ThisDeclaration *isThisDeclaration() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ ThisDeclaration *syntaxCopy(Dsymbol *) override;
+ ThisDeclaration *isThisDeclaration() override { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
enum class ILS : unsigned char
@@ -614,9 +614,7 @@ public:
FuncDeclarations *inlinedNestedCallees;
-private:
AttributeViolation* safetyViolation;
-public:
unsigned flags; // FUNCFLAGxxxxx
@@ -625,31 +623,31 @@ public:
ObjcFuncDeclaration objc;
static FuncDeclaration *create(const Loc &loc, const Loc &endloc, Identifier *id, StorageClass storage_class, Type *type, bool noreturn = false);
- FuncDeclaration *syntaxCopy(Dsymbol *);
+ FuncDeclaration *syntaxCopy(Dsymbol *) override;
bool functionSemantic();
bool functionSemantic3();
- bool equals(const RootObject *o) const;
+ bool equals(const RootObject *o) const override final;
int overrides(FuncDeclaration *fd);
int findVtblIndex(Dsymbols *vtbl, int dim);
BaseClass *overrideInterface();
- bool overloadInsert(Dsymbol *s);
+ bool overloadInsert(Dsymbol *s) override;
bool inUnittest();
MATCH leastAsSpecialized(FuncDeclaration *g);
LabelDsymbol *searchLabel(Identifier *ident, const Loc &loc);
int getLevel(FuncDeclaration *fd, int intypeof); // lexical nesting level difference
int getLevelAndCheck(const Loc &loc, Scope *sc, FuncDeclaration *fd);
- const char *toPrettyChars(bool QualifyTypes = false);
+ const char *toPrettyChars(bool QualifyTypes = false) override;
const char *toFullSignature(); // for diagnostics, e.g. 'int foo(int x, int y) pure'
bool isMain() const;
bool isCMain() const;
bool isWinMain() const;
bool isDllMain() const;
- bool isExport() const;
- bool isImportedSymbol() const;
- bool isCodeseg() const;
- bool isOverloadable() const;
- bool isAbstract();
+ bool isExport() const override final;
+ bool isImportedSymbol() const override final;
+ bool isCodeseg() const override final;
+ bool isOverloadable() const override final;
+ bool isAbstract() override final;
PURE isPure();
PURE isPureBypassingInference();
bool isSafe();
@@ -676,14 +674,14 @@ public:
void isCrtDtor(bool v);
virtual bool isNested() const;
- AggregateDeclaration *isThis();
- bool needThis();
+ AggregateDeclaration *isThis() override;
+ bool needThis() override final;
bool isVirtualMethod();
virtual bool isVirtual() const;
bool isFinalFunc() const;
virtual bool addPreInvariant();
virtual bool addPostInvariant();
- const char *kind() const;
+ const char *kind() const override;
bool isUnique();
bool needsClosure();
bool hasNestedFrameRefs();
@@ -694,26 +692,26 @@ public:
bool checkNRVO();
- FuncDeclaration *isFuncDeclaration() { return this; }
+ FuncDeclaration *isFuncDeclaration() override final { return this; }
virtual FuncDeclaration *toAliasFunc() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class FuncAliasDeclaration : public FuncDeclaration
+class FuncAliasDeclaration final : public FuncDeclaration
{
public:
FuncDeclaration *funcalias;
bool hasOverloads;
- FuncAliasDeclaration *isFuncAliasDeclaration() { return this; }
- const char *kind() const;
+ FuncAliasDeclaration *isFuncAliasDeclaration() override { return this; }
+ const char *kind() const override;
- FuncDeclaration *toAliasFunc();
- void accept(Visitor *v) { v->visit(this); }
+ FuncDeclaration *toAliasFunc() override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class FuncLiteralDeclaration : public FuncDeclaration
+class FuncLiteralDeclaration final : public FuncDeclaration
{
public:
TOK tok; // TOKfunction or TOKdelegate
@@ -722,85 +720,85 @@ public:
// backend
bool deferToObj;
- FuncLiteralDeclaration *syntaxCopy(Dsymbol *);
- bool isNested() const;
- AggregateDeclaration *isThis();
- bool isVirtual() const;
- bool addPreInvariant();
- bool addPostInvariant();
+ FuncLiteralDeclaration *syntaxCopy(Dsymbol *) override;
+ bool isNested() const override;
+ AggregateDeclaration *isThis() override;
+ bool isVirtual() const override;
+ bool addPreInvariant() override;
+ bool addPostInvariant() override;
void modifyReturns(Scope *sc, Type *tret);
- FuncLiteralDeclaration *isFuncLiteralDeclaration() { return this; }
- const char *kind() const;
- const char *toPrettyChars(bool QualifyTypes = false);
- void accept(Visitor *v) { v->visit(this); }
+ FuncLiteralDeclaration *isFuncLiteralDeclaration() override { return this; }
+ const char *kind() const override;
+ const char *toPrettyChars(bool QualifyTypes = false) override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class CtorDeclaration : public FuncDeclaration
+class CtorDeclaration final : public FuncDeclaration
{
public:
bool isCpCtor;
- CtorDeclaration *syntaxCopy(Dsymbol *);
- const char *kind() const;
- const char *toChars() const;
- bool isVirtual() const;
- bool addPreInvariant();
- bool addPostInvariant();
+ CtorDeclaration *syntaxCopy(Dsymbol *) override;
+ const char *kind() const override;
+ const char *toChars() const override;
+ bool isVirtual() const override;
+ bool addPreInvariant() override;
+ bool addPostInvariant() override;
- CtorDeclaration *isCtorDeclaration() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ CtorDeclaration *isCtorDeclaration() override { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class PostBlitDeclaration : public FuncDeclaration
+class PostBlitDeclaration final : public FuncDeclaration
{
public:
- PostBlitDeclaration *syntaxCopy(Dsymbol *);
- bool isVirtual() const;
- bool addPreInvariant();
- bool addPostInvariant();
- bool overloadInsert(Dsymbol *s);
+ PostBlitDeclaration *syntaxCopy(Dsymbol *) override;
+ bool isVirtual() const override;
+ bool addPreInvariant() override;
+ bool addPostInvariant() override;
+ bool overloadInsert(Dsymbol *s) override;
- PostBlitDeclaration *isPostBlitDeclaration() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ PostBlitDeclaration *isPostBlitDeclaration() override { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class DtorDeclaration : public FuncDeclaration
+class DtorDeclaration final : public FuncDeclaration
{
public:
- DtorDeclaration *syntaxCopy(Dsymbol *);
- const char *kind() const;
- const char *toChars() const;
- bool isVirtual() const;
- bool addPreInvariant();
- bool addPostInvariant();
- bool overloadInsert(Dsymbol *s);
+ DtorDeclaration *syntaxCopy(Dsymbol *) override;
+ const char *kind() const override;
+ const char *toChars() const override;
+ bool isVirtual() const override;
+ bool addPreInvariant() override;
+ bool addPostInvariant() override;
+ bool overloadInsert(Dsymbol *s) override;
- DtorDeclaration *isDtorDeclaration() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ DtorDeclaration *isDtorDeclaration() override { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
class StaticCtorDeclaration : public FuncDeclaration
{
public:
- StaticCtorDeclaration *syntaxCopy(Dsymbol *);
- AggregateDeclaration *isThis();
- bool isVirtual() const;
- bool addPreInvariant();
- bool addPostInvariant();
- bool hasStaticCtorOrDtor();
+ StaticCtorDeclaration *syntaxCopy(Dsymbol *) override;
+ AggregateDeclaration *isThis() override final;
+ bool isVirtual() const override final;
+ bool addPreInvariant() override final;
+ bool addPostInvariant() override final;
+ bool hasStaticCtorOrDtor() override final;
- StaticCtorDeclaration *isStaticCtorDeclaration() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ StaticCtorDeclaration *isStaticCtorDeclaration() override final { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class SharedStaticCtorDeclaration : public StaticCtorDeclaration
+class SharedStaticCtorDeclaration final : public StaticCtorDeclaration
{
public:
- SharedStaticCtorDeclaration *syntaxCopy(Dsymbol *);
+ SharedStaticCtorDeclaration *syntaxCopy(Dsymbol *) override;
- SharedStaticCtorDeclaration *isSharedStaticCtorDeclaration() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ SharedStaticCtorDeclaration *isSharedStaticCtorDeclaration() override { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
class StaticDtorDeclaration : public FuncDeclaration
@@ -808,39 +806,39 @@ class StaticDtorDeclaration : public FuncDeclaration
public:
VarDeclaration *vgate; // 'gate' variable
- StaticDtorDeclaration *syntaxCopy(Dsymbol *);
- AggregateDeclaration *isThis();
- bool isVirtual() const;
- bool hasStaticCtorOrDtor();
- bool addPreInvariant();
- bool addPostInvariant();
+ StaticDtorDeclaration *syntaxCopy(Dsymbol *) override;
+ AggregateDeclaration *isThis() override final;
+ bool isVirtual() const override final;
+ bool hasStaticCtorOrDtor() override final;
+ bool addPreInvariant() override final;
+ bool addPostInvariant() override final;
- StaticDtorDeclaration *isStaticDtorDeclaration() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ StaticDtorDeclaration *isStaticDtorDeclaration() override final { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class SharedStaticDtorDeclaration : public StaticDtorDeclaration
+class SharedStaticDtorDeclaration final : public StaticDtorDeclaration
{
public:
- SharedStaticDtorDeclaration *syntaxCopy(Dsymbol *);
+ SharedStaticDtorDeclaration *syntaxCopy(Dsymbol *) override;
- SharedStaticDtorDeclaration *isSharedStaticDtorDeclaration() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ SharedStaticDtorDeclaration *isSharedStaticDtorDeclaration() override { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class InvariantDeclaration : public FuncDeclaration
+class InvariantDeclaration final : public FuncDeclaration
{
public:
- InvariantDeclaration *syntaxCopy(Dsymbol *);
- bool isVirtual() const;
- bool addPreInvariant();
- bool addPostInvariant();
+ InvariantDeclaration *syntaxCopy(Dsymbol *) override;
+ bool isVirtual() const override;
+ bool addPreInvariant() override;
+ bool addPostInvariant() override;
- InvariantDeclaration *isInvariantDeclaration() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ InvariantDeclaration *isInvariantDeclaration() override { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class UnitTestDeclaration : public FuncDeclaration
+class UnitTestDeclaration final : public FuncDeclaration
{
public:
char *codedoc; /** For documented unittest. */
@@ -848,25 +846,25 @@ public:
// toObjFile() these nested functions after this one
FuncDeclarations deferredNested;
- UnitTestDeclaration *syntaxCopy(Dsymbol *);
- AggregateDeclaration *isThis();
- bool isVirtual() const;
- bool addPreInvariant();
- bool addPostInvariant();
+ UnitTestDeclaration *syntaxCopy(Dsymbol *) override;
+ AggregateDeclaration *isThis() override;
+ bool isVirtual() const override;
+ bool addPreInvariant() override;
+ bool addPostInvariant() override;
- UnitTestDeclaration *isUnitTestDeclaration() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ UnitTestDeclaration *isUnitTestDeclaration() override { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class NewDeclaration : public FuncDeclaration
+class NewDeclaration final : public FuncDeclaration
{
public:
- NewDeclaration *syntaxCopy(Dsymbol *);
- const char *kind() const;
- bool isVirtual() const;
- bool addPreInvariant();
- bool addPostInvariant();
+ NewDeclaration *syntaxCopy(Dsymbol *) override;
+ const char *kind() const override;
+ bool isVirtual() const override;
+ bool addPreInvariant() override;
+ bool addPostInvariant() override;
- NewDeclaration *isNewDeclaration() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ NewDeclaration *isNewDeclaration() override { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
diff --git a/gcc/d/dmd/dmodule.d b/gcc/d/dmd/dmodule.d
index 26a0ff0..f8e5073a 100644
--- a/gcc/d/dmd/dmodule.d
+++ b/gcc/d/dmd/dmodule.d
@@ -363,6 +363,9 @@ extern (C++) final class Module : Package
int selfimports; // 0: don't know, 1: does not, 2: does
Dsymbol[void*] tagSymTab; /// ImportC: tag symbols that conflict with other symbols used as the index
+ private OutBuffer defines; // collect all the #define lines here
+
+
/*************************************
* Return true if module imports itself.
*/
@@ -677,33 +680,7 @@ extern (C++) final class Module : Package
FileName.equalsExt(srcfile.toString(), c_ext) &&
FileName.exists(srcfile.toString()))
{
- /* Look for "importc.h" by searching along import path.
- * It should be in the same place as "object.d"
- */
- const(char)* importc_h;
-
- foreach (entry; (global.path ? (*global.path)[] : null))
- {
- auto f = FileName.combine(entry, "importc.h");
- if (FileName.exists(f) == 1)
- {
- importc_h = f;
- break;
- }
- FileName.free(f);
- }
-
- if (importc_h)
- {
- if (global.params.verbose)
- message("include %s", importc_h);
- }
- else
- {
- error("cannot find \"importc.h\" along import path");
- fatal();
- }
- filename = global.preprocess(srcfile, importc_h, global.params.cppswitches, ifile); // run C preprocessor
+ filename = global.preprocess(srcfile, loc, global.params.cppswitches, ifile, &defines); // run C preprocessor
}
if (auto result = global.fileManager.lookup(filename))
@@ -1001,7 +978,7 @@ extern (C++) final class Module : Package
{
filetype = FileType.c;
- scope p = new CParser!AST(this, buf, cast(bool) docfile, target.c);
+ scope p = new CParser!AST(this, buf, cast(bool) docfile, target.c, &defines);
p.nextToken();
checkCompiledImport();
members = p.parseModule();
diff --git a/gcc/d/dmd/dsymbol.d b/gcc/d/dmd/dsymbol.d
index b006940..3b3a527 100644
--- a/gcc/d/dmd/dsymbol.d
+++ b/gcc/d/dmd/dsymbol.d
@@ -1978,8 +1978,9 @@ extern (C++) final class ArrayScopeSymbol : ScopeDsymbol
}
const DYNCAST kind = arrayContent.dyncast();
- if (kind == DYNCAST.dsymbol)
+ switch (kind) with (DYNCAST)
{
+ case dsymbol:
TupleDeclaration td = cast(TupleDeclaration) arrayContent;
/* $ gives the number of elements in the tuple
*/
@@ -1989,10 +1990,10 @@ extern (C++) final class ArrayScopeSymbol : ScopeDsymbol
v.storage_class |= STC.temp | STC.static_ | STC.const_;
v.dsymbolSemantic(sc);
return v;
- }
- if (kind == DYNCAST.type)
- {
+ case type:
return dollarFromTypeTuple(loc, cast(TypeTuple) arrayContent, sc);
+ default:
+ break;
}
Expression exp = cast(Expression) arrayContent;
if (auto ie = exp.isIndexExp())
@@ -2531,6 +2532,16 @@ Dsymbol handleSymbolRedeclarations(ref Scope sc, Dsymbol s, Dsymbol s2, ScopeDsy
if (log) printf(" collision\n");
return null;
}
+ /*
+ Handle merging declarations with asm("foo") and their definitions
+ */
+ static void mangleWrangle(Declaration oldDecl, Declaration newDecl)
+ {
+ if (oldDecl && newDecl)
+ {
+ newDecl.mangleOverride = oldDecl.mangleOverride ? oldDecl.mangleOverride : null;
+ }
+ }
auto vd = s.isVarDeclaration(); // new declaration
auto vd2 = s2.isVarDeclaration(); // existing declaration
@@ -2548,6 +2559,8 @@ Dsymbol handleSymbolRedeclarations(ref Scope sc, Dsymbol s, Dsymbol s2, ScopeDsy
if (i1 && i2)
return collision(); // can't both have initializers
+ mangleWrangle(vd2, vd);
+
if (i1) // vd is the definition
{
vd2.storage_class |= STC.extern_; // so toObjFile() won't emit it
@@ -2593,6 +2606,8 @@ Dsymbol handleSymbolRedeclarations(ref Scope sc, Dsymbol s, Dsymbol s2, ScopeDsy
if (fd.fbody && fd2.fbody)
return collision(); // can't both have bodies
+ mangleWrangle(fd2, fd);
+
if (fd.fbody) // fd is the definition
{
if (log) printf(" replace existing with new\n");
diff --git a/gcc/d/dmd/dsymbol.h b/gcc/d/dmd/dsymbol.h
index 35500af..23a2c77 100644
--- a/gcc/d/dmd/dsymbol.h
+++ b/gcc/d/dmd/dsymbol.h
@@ -185,11 +185,11 @@ public:
UserAttributeDeclaration *userAttribDecl; // user defined attributes
static Dsymbol *create(Identifier *);
- const char *toChars() const;
+ const char *toChars() const override;
virtual const char *toPrettyCharsHelper(); // helper to print fully qualified (template) arguments
Loc getLoc();
const char *locToChars();
- bool equals(const RootObject *o) const;
+ bool equals(const RootObject *o) const override;
bool isAnonymous() const;
void error(const Loc &loc, const char *format, ...);
void error(const char *format, ...);
@@ -211,7 +211,7 @@ public:
Ungag ungagSpeculative();
// kludge for template.isSymbol()
- DYNCAST dyncast() const { return DYNCAST_DSYMBOL; }
+ DYNCAST dyncast() const override final { return DYNCAST_DSYMBOL; }
virtual Identifier *getIdent();
virtual const char *toPrettyChars(bool QualifyTypes = false);
@@ -310,7 +310,7 @@ public:
virtual OverloadSet *isOverloadSet() { return NULL; }
virtual CompileDeclaration *isCompileDeclaration() { return NULL; }
virtual StaticAssert *isStaticAssert() { return NULL; }
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
// Dsymbol that generates a scope
@@ -329,89 +329,89 @@ private:
BitArray accessiblePackages, privateAccessiblePackages;
public:
- ScopeDsymbol *syntaxCopy(Dsymbol *s);
- Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);
+ ScopeDsymbol *syntaxCopy(Dsymbol *s) override;
+ Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly) override;
virtual void importScope(Dsymbol *s, Visibility visibility);
virtual bool isPackageAccessible(Package *p, Visibility visibility, int flags = 0);
- bool isforwardRef();
+ bool isforwardRef() override final;
static void multiplyDefined(const Loc &loc, Dsymbol *s1, Dsymbol *s2);
- const char *kind() const;
+ const char *kind() const override;
FuncDeclaration *findGetMembers();
virtual Dsymbol *symtabInsert(Dsymbol *s);
virtual Dsymbol *symtabLookup(Dsymbol *s, Identifier *id);
- bool hasStaticCtorOrDtor();
+ bool hasStaticCtorOrDtor() override;
- ScopeDsymbol *isScopeDsymbol() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ ScopeDsymbol *isScopeDsymbol() override final { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
// With statement scope
-class WithScopeSymbol : public ScopeDsymbol
+class WithScopeSymbol final : public ScopeDsymbol
{
public:
WithStatement *withstate;
- Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);
+ Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly) override;
- WithScopeSymbol *isWithScopeSymbol() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ WithScopeSymbol *isWithScopeSymbol() override { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
// Array Index/Slice scope
-class ArrayScopeSymbol : public ScopeDsymbol
+class ArrayScopeSymbol final : public ScopeDsymbol
{
private:
RootObject *arrayContent;
public:
Scope *sc;
- Dsymbol *search(const Loc &loc, Identifier *ident, int flags = IgnoreNone);
+ Dsymbol *search(const Loc &loc, Identifier *ident, int flags = IgnoreNone) override;
- ArrayScopeSymbol *isArrayScopeSymbol() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ ArrayScopeSymbol *isArrayScopeSymbol() override { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
// Overload Sets
-class OverloadSet : public Dsymbol
+class OverloadSet final : public Dsymbol
{
public:
Dsymbols a; // array of Dsymbols
void push(Dsymbol *s);
- OverloadSet *isOverloadSet() { return this; }
- const char *kind() const;
- void accept(Visitor *v) { v->visit(this); }
+ OverloadSet *isOverloadSet() override { return this; }
+ const char *kind() const override;
+ void accept(Visitor *v) override { v->visit(this); }
};
// Forwarding ScopeDsymbol
-class ForwardingScopeDsymbol : public ScopeDsymbol
+class ForwardingScopeDsymbol final : public ScopeDsymbol
{
public:
ScopeDsymbol *forward;
- Dsymbol *symtabInsert(Dsymbol *s);
- Dsymbol *symtabLookup(Dsymbol *s, Identifier *id);
- void importScope(Dsymbol *s, Visibility visibility);
- const char *kind() const;
+ Dsymbol *symtabInsert(Dsymbol *s) override;
+ Dsymbol *symtabLookup(Dsymbol *s, Identifier *id) override;
+ void importScope(Dsymbol *s, Visibility visibility) override;
+ const char *kind() const override;
- ForwardingScopeDsymbol *isForwardingScopeDsymbol() { return this; }
+ ForwardingScopeDsymbol *isForwardingScopeDsymbol() override { return this; }
};
-class ExpressionDsymbol : public Dsymbol
+class ExpressionDsymbol final : public Dsymbol
{
public:
Expression *exp;
- ExpressionDsymbol *isExpressionDsymbol() { return this; }
+ ExpressionDsymbol *isExpressionDsymbol() override { return this; }
};
// Table of Dsymbol's
-class DsymbolTable : public RootObject
+class DsymbolTable final : public RootObject
{
public:
AA *tab;
diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d
index 5d88056..e491272 100644
--- a/gcc/d/dmd/dsymbolsem.d
+++ b/gcc/d/dmd/dsymbolsem.d
@@ -468,12 +468,9 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
dsym.type.checkComplexTransition(dsym.loc, sc);
// Calculate type size + safety checks
- if (sc.func && !sc.intypeof)
+ if (dsym.storage_class & STC.gshared && !dsym.isMember())
{
- if (dsym.storage_class & STC.gshared && !dsym.isMember())
- {
- sc.func.setUnsafe(false, dsym.loc, "__gshared not allowed in safe functions; use shared");
- }
+ sc.setUnsafe(false, dsym.loc, "__gshared not allowed in safe functions; use shared");
}
Dsymbol parent = dsym.toParent();
@@ -857,23 +854,23 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
}
// Calculate type size + safety checks
- if (sc.func && !sc.intypeof)
+ if (1)
{
if (dsym._init && dsym._init.isVoidInitializer() &&
(dsym.type.hasPointers() || dsym.type.hasInvariant())) // also computes type size
{
if (dsym.type.hasPointers())
- sc.func.setUnsafe(false, dsym.loc,
+ sc.setUnsafe(false, dsym.loc,
"`void` initializers for pointers not allowed in safe functions");
else
- sc.func.setUnsafe(false, dsym.loc,
+ sc.setUnsafe(false, dsym.loc,
"`void` initializers for structs with invariants are not allowed in safe functions");
}
else if (!dsym._init &&
!(dsym.storage_class & (STC.static_ | STC.extern_ | STC.gshared | STC.manifest | STC.field | STC.parameter)) &&
dsym.type.hasVoidInitPointers())
{
- sc.func.setUnsafe(false, dsym.loc, "`void` initializers for pointers not allowed in safe functions");
+ sc.setUnsafe(false, dsym.loc, "`void` initializers for pointers not allowed in safe functions");
}
}
@@ -3595,6 +3592,11 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
break;
}
+ auto vtf = getFunctionType(fdv);
+ if (vtf.trust > TRUST.system && f.trust == TRUST.system)
+ funcdecl.error("cannot override `@safe` method `%s` with a `@system` attribute",
+ fdv.toPrettyChars);
+
if (fdc.toParent() == parent)
{
//printf("vi = %d,\tthis = %p %s %s @ [%s]\n\tfdc = %p %s %s @ [%s]\n\tfdv = %p %s %s @ [%s]\n",
diff --git a/gcc/d/dmd/dtemplate.d b/gcc/d/dmd/dtemplate.d
index ed0126e..a450ea5 100644
--- a/gcc/d/dmd/dtemplate.d
+++ b/gcc/d/dmd/dtemplate.d
@@ -5352,7 +5352,7 @@ extern (C++) class TemplateParameter : ASTNode
return this.ident.toChars();
}
- override DYNCAST dyncast() const pure @nogc nothrow @safe
+ override DYNCAST dyncast() const
{
return DYNCAST.templateparameter;
}
diff --git a/gcc/d/dmd/dtoh.d b/gcc/d/dmd/dtoh.d
index 55f7c72..9afcc7f 100644
--- a/gcc/d/dmd/dtoh.d
+++ b/gcc/d/dmd/dtoh.d
@@ -801,26 +801,22 @@ public:
if (adparent && fd.isDisabled && global.params.cplusplus < CppStdRevision.cpp11)
writeProtection(AST.Visibility.Kind.private_);
funcToBuffer(tf, fd);
- // FIXME: How to determine if fd is const without tf?
- if (adparent && tf && (tf.isConst() || tf.isImmutable()))
+ if (adparent)
{
- bool fdOverridesAreConst = true;
- foreach (fdv; fd.foverrides)
+ if (tf && (tf.isConst() || tf.isImmutable()))
+ buf.writestring(" const");
+ if (global.params.cplusplus >= CppStdRevision.cpp11)
{
- auto tfv = cast(AST.TypeFunction)fdv.type;
- if (!tfv.isConst() && !tfv.isImmutable())
- {
- fdOverridesAreConst = false;
- break;
- }
+ if (fd.vtblIndex != -1 && !(adparent.storage_class & AST.STC.final_) && fd.isFinalFunc())
+ buf.writestring(" final");
+ if (fd.isOverride())
+ buf.writestring(" override");
}
-
- buf.writestring(fdOverridesAreConst ? " const" : " /* const */");
+ if (fd.isAbstract())
+ buf.writestring(" = 0");
+ else if (global.params.cplusplus >= CppStdRevision.cpp11 && fd.isDisabled())
+ buf.writestring(" = delete");
}
- if (adparent && fd.isAbstract())
- buf.writestring(" = 0");
- if (adparent && fd.isDisabled && global.params.cplusplus >= CppStdRevision.cpp11)
- buf.writestring(" = delete");
buf.writestringln(";");
if (adparent && fd.isDisabled && global.params.cplusplus < CppStdRevision.cpp11)
writeProtection(AST.Visibility.Kind.public_);
diff --git a/gcc/d/dmd/enum.h b/gcc/d/dmd/enum.h
index ab80c8b..9ec1300 100644
--- a/gcc/d/dmd/enum.h
+++ b/gcc/d/dmd/enum.h
@@ -17,7 +17,7 @@ class Identifier;
class Type;
class Expression;
-class EnumDeclaration : public ScopeDsymbol
+class EnumDeclaration final : public ScopeDsymbol
{
public:
/* The separate, and distinct, cases are:
@@ -40,27 +40,27 @@ public:
bool added;
int inuse;
- EnumDeclaration *syntaxCopy(Dsymbol *s);
- void addMember(Scope *sc, ScopeDsymbol *sds);
- void setScope(Scope *sc);
- bool oneMember(Dsymbol **ps, Identifier *ident);
- Type *getType();
- const char *kind() const;
- Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);
- bool isDeprecated() const; // is Dsymbol deprecated?
- Visibility visible();
+ EnumDeclaration *syntaxCopy(Dsymbol *s) override;
+ void addMember(Scope *sc, ScopeDsymbol *sds) override;
+ void setScope(Scope *sc) override;
+ bool oneMember(Dsymbol **ps, Identifier *ident) override;
+ Type *getType() override;
+ const char *kind() const override;
+ Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly) override;
+ 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() { return this; }
+ EnumDeclaration *isEnumDeclaration() override { return this; }
Symbol *sinit;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class EnumMember : public VarDeclaration
+class EnumMember final : public VarDeclaration
{
public:
/* Can take the following forms:
@@ -78,9 +78,9 @@ public:
EnumDeclaration *ed;
- EnumMember *syntaxCopy(Dsymbol *s);
- const char *kind() const;
+ EnumMember *syntaxCopy(Dsymbol *s) override;
+ const char *kind() const override;
- EnumMember *isEnumMember() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ EnumMember *isEnumMember() override { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
diff --git a/gcc/d/dmd/escape.d b/gcc/d/dmd/escape.d
index 3f41c29..97a6552 100644
--- a/gcc/d/dmd/escape.d
+++ b/gcc/d/dmd/escape.d
@@ -145,7 +145,7 @@ bool checkMutableArguments(Scope* sc, FuncDeclaration fd, TypeFunction tf,
refs = true;
auto var = outerVars[i - (len - outerVars.length)];
eb.isMutable = var.type.isMutable();
- eb.er.byref.push(var);
+ eb.er.pushRef(var, false);
continue;
}
@@ -165,7 +165,7 @@ bool checkMutableArguments(Scope* sc, FuncDeclaration fd, TypeFunction tf,
if (!(eb.isMutable || eb2.isMutable))
return;
- if (!(global.params.useDIP1000 == FeatureState.enabled && sc.func.setUnsafe()))
+ if (!(global.params.useDIP1000 == FeatureState.enabled && sc.setUnsafe()))
return;
if (!gag)
@@ -1185,6 +1185,8 @@ private bool checkReturnEscapeImpl(Scope* sc, Expression e, bool refs, bool gag)
if (v.isDataseg())
continue;
+ const vsr = buildScopeRef(v.storage_class);
+
Dsymbol p = v.toParent2();
if ((v.isScope() || (v.storage_class & STC.maybescope)) &&
@@ -1200,8 +1202,13 @@ private bool checkReturnEscapeImpl(Scope* sc, Expression e, bool refs, bool gag)
if (v.isScope())
{
- if (v.storage_class & STC.return_)
+ /* If `return scope` applies to v.
+ */
+ if (vsr == ScopeRef.ReturnScope ||
+ vsr == ScopeRef.Ref_ReturnScope)
+ {
continue;
+ }
auto pfunc = p.isFuncDeclaration();
if (pfunc &&
@@ -1245,7 +1252,7 @@ private bool checkReturnEscapeImpl(Scope* sc, Expression e, bool refs, bool gag)
}
}
- foreach (VarDeclaration v; er.byref)
+ foreach (i, VarDeclaration v; er.byref[])
{
if (log)
{
@@ -1281,9 +1288,16 @@ private bool checkReturnEscapeImpl(Scope* sc, Expression e, bool refs, bool gag)
}
else
{
- if (!gag)
- previewErrorFunc(sc.isDeprecated(), featureState)(e.loc, msg, e.toChars(), v.toChars());
- result = true;
+ if (er.refRetRefTransition[i])
+ {
+ result |= sc.setUnsafeDIP1000(gag, e.loc, msg, e, v);
+ }
+ else
+ {
+ if (!gag)
+ previewErrorFunc(sc.isDeprecated(), featureState)(e.loc, msg, e.toChars(), v.toChars());
+ result = true;
+ }
}
}
@@ -1374,14 +1388,21 @@ private bool checkReturnEscapeImpl(Scope* sc, Expression e, bool refs, bool gag)
}
}
- foreach (Expression ee; er.byexp)
+ foreach (i, Expression ee; er.byexp[])
{
if (log) printf("byexp %s\n", ee.toChars());
- if (!gag)
- error(ee.loc, "escaping reference to stack allocated value returned by `%s`", ee.toChars());
- result = true;
+ if (er.expRetRefTransition[i])
+ {
+ result |= sc.setUnsafeDIP1000(gag, ee.loc,
+ "escaping reference to stack allocated value returned by `%s`", ee);
+ }
+ else
+ {
+ if (!gag)
+ error(ee.loc, "escaping reference to stack allocated value returned by `%s`", ee.toChars());
+ result = true;
+ }
}
-
return result;
}
@@ -1449,8 +1470,9 @@ private void inferReturn(FuncDeclaration fd, VarDeclaration v, bool returnScope)
* e = expression to be returned by value
* er = where to place collected data
* live = if @live semantics apply, i.e. expressions `p`, `*p`, `**p`, etc., all return `p`.
+ * retRefTransition = if `e` is returned through a `return ref scope` function call
*/
-void escapeByValue(Expression e, EscapeByResults* er, bool live = false)
+void escapeByValue(Expression e, EscapeByResults* er, bool live = false, bool retRefTransition = false)
{
//printf("[%s] escapeByValue, e: %s\n", e.loc.toChars(), e.toChars());
@@ -1465,14 +1487,14 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false)
* but it'll be placed in static data so no need to check it.
*/
if (e.e1.op != EXP.structLiteral)
- escapeByRef(e.e1, er, live);
+ escapeByRef(e.e1, er, live, retRefTransition);
}
void visitSymOff(SymOffExp e)
{
VarDeclaration v = e.var.isVarDeclaration();
if (v)
- er.byref.push(v);
+ er.pushRef(v, retRefTransition);
}
void visitVar(VarExp e)
@@ -1494,7 +1516,7 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false)
void visitPtr(PtrExp e)
{
if (live && e.type.hasPointers())
- escapeByValue(e.e1, er, live);
+ escapeByValue(e.e1, er, live, retRefTransition);
}
void visitDotVar(DotVarExp e)
@@ -1502,7 +1524,7 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false)
auto t = e.e1.type.toBasetype();
if (e.type.hasPointers() && (live || t.ty == Tstruct))
{
- escapeByValue(e.e1, er, live);
+ escapeByValue(e.e1, er, live, retRefTransition);
}
}
@@ -1510,9 +1532,9 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false)
{
Type t = e.e1.type.toBasetype();
if (t.ty == Tclass || t.ty == Tpointer)
- escapeByValue(e.e1, er, live);
+ escapeByValue(e.e1, er, live, retRefTransition);
else
- escapeByRef(e.e1, er, live);
+ escapeByRef(e.e1, er, live, retRefTransition);
er.byfunc.push(e.func);
}
@@ -1533,11 +1555,11 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false)
if (tb.ty == Tsarray || tb.ty == Tarray)
{
if (e.basis)
- escapeByValue(e.basis, er, live);
+ escapeByValue(e.basis, er, live, retRefTransition);
foreach (el; *e.elements)
{
if (el)
- escapeByValue(el, er, live);
+ escapeByValue(el, er, live, retRefTransition);
}
}
}
@@ -1549,7 +1571,7 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false)
foreach (ex; *e.elements)
{
if (ex)
- escapeByValue(ex, er, live);
+ escapeByValue(ex, er, live, retRefTransition);
}
}
}
@@ -1562,7 +1584,7 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false)
foreach (ex; *e.arguments)
{
if (ex)
- escapeByValue(ex, er, live);
+ escapeByValue(ex, er, live, retRefTransition);
}
}
}
@@ -1574,10 +1596,10 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false)
Type tb = e.type.toBasetype();
if (tb.ty == Tarray && e.e1.type.toBasetype().ty == Tsarray)
{
- escapeByRef(e.e1, er, live);
+ escapeByRef(e.e1, er, live, retRefTransition);
}
else
- escapeByValue(e.e1, er, live);
+ escapeByValue(e.e1, er, live, retRefTransition);
}
void visitSlice(SliceExp e)
@@ -1602,10 +1624,10 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false)
{
Type tb = e.type.toBasetype();
if (tb.ty != Tsarray)
- escapeByRef(e.e1, er, live);
+ escapeByRef(e.e1, er, live, retRefTransition);
}
else
- escapeByValue(e.e1, er, live);
+ escapeByValue(e.e1, er, live, retRefTransition);
}
void visitIndex(IndexExp e)
@@ -1613,7 +1635,7 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false)
if (e.e1.type.toBasetype().ty == Tsarray ||
live && e.type.hasPointers())
{
- escapeByValue(e.e1, er, live);
+ escapeByValue(e.e1, er, live, retRefTransition);
}
}
@@ -1622,30 +1644,30 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false)
Type tb = e.type.toBasetype();
if (tb.ty == Tpointer)
{
- escapeByValue(e.e1, er, live);
- escapeByValue(e.e2, er, live);
+ escapeByValue(e.e1, er, live, retRefTransition);
+ escapeByValue(e.e2, er, live, retRefTransition);
}
}
void visitBinAssign(BinAssignExp e)
{
- escapeByValue(e.e1, er, live);
+ escapeByValue(e.e1, er, live, retRefTransition);
}
void visitAssign(AssignExp e)
{
- escapeByValue(e.e1, er, live);
+ escapeByValue(e.e1, er, live, retRefTransition);
}
void visitComma(CommaExp e)
{
- escapeByValue(e.e2, er, live);
+ escapeByValue(e.e2, er, live, retRefTransition);
}
void visitCond(CondExp e)
{
- escapeByValue(e.e1, er, live);
- escapeByValue(e.e2, er, live);
+ escapeByValue(e.e1, er, live, retRefTransition);
+ escapeByValue(e.e2, er, live, retRefTransition);
}
void visitCall(CallExp e)
@@ -1686,7 +1708,7 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false)
const stc = tf.parameterStorageClass(null, p);
ScopeRef psr = buildScopeRef(stc);
if (psr == ScopeRef.ReturnScope || psr == ScopeRef.Ref_ReturnScope)
- escapeByValue(arg, er, live);
+ escapeByValue(arg, er, live, retRefTransition);
else if (psr == ScopeRef.ReturnRef || psr == ScopeRef.ReturnRef_Scope)
{
if (tf.isref)
@@ -1696,10 +1718,10 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false)
* as:
* p;
*/
- escapeByValue(arg, er, live);
+ escapeByValue(arg, er, live, retRefTransition);
}
else
- escapeByRef(arg, er, live);
+ escapeByRef(arg, er, live, retRefTransition);
}
}
}
@@ -1709,7 +1731,7 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false)
{
DotVarExp dve = e.e1.isDotVarExp();
FuncDeclaration fd = dve.var.isFuncDeclaration();
- if (global.params.useDIP1000 == FeatureState.enabled)
+ if (1)
{
if (fd && fd.isThis())
{
@@ -1741,7 +1763,7 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false)
const psr = buildScopeRef(getThisStorageClass(fd));
if (psr == ScopeRef.ReturnScope || psr == ScopeRef.Ref_ReturnScope)
- escapeByValue(dve.e1, er, live);
+ escapeByValue(dve.e1, er, live, retRefTransition);
else if (psr == ScopeRef.ReturnRef || psr == ScopeRef.ReturnRef_Scope)
{
if (tf.isref)
@@ -1751,10 +1773,10 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false)
* as:
* this;
*/
- escapeByValue(dve.e1, er, live);
+ escapeByValue(dve.e1, er, live, retRefTransition);
}
else
- escapeByRef(dve.e1, er, live);
+ escapeByRef(dve.e1, er, live, psr == ScopeRef.ReturnRef_Scope);
}
}
}
@@ -1767,16 +1789,16 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false)
const psr = buildScopeRef(stc);
if (psr == ScopeRef.ReturnScope || psr == ScopeRef.Ref_ReturnScope)
- escapeByValue(dve.e1, er, live);
+ escapeByValue(dve.e1, er, live, retRefTransition);
else if (psr == ScopeRef.ReturnRef || psr == ScopeRef.ReturnRef_Scope)
- escapeByRef(dve.e1, er, live);
+ escapeByRef(dve.e1, er, live, retRefTransition);
}
// If it's also a nested function that is 'return scope'
if (fd && fd.isNested())
{
if (tf.isreturn && tf.isScopeQual)
- er.byexp.push(e);
+ er.pushExp(e, false);
}
}
@@ -1786,7 +1808,7 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false)
if (dg)
{
if (tf.isreturn)
- escapeByValue(e.e1, er, live);
+ escapeByValue(e.e1, er, live, retRefTransition);
}
/* If it's a nested function that is 'return scope'
@@ -1797,7 +1819,7 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false)
if (fd && fd.isNested())
{
if (tf.isreturn && tf.isScopeQual)
- er.byexp.push(e);
+ er.pushExp(e, false);
}
}
}
@@ -1852,10 +1874,11 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false)
* e = expression to be returned by 'ref'
* er = where to place collected data
* live = if @live semantics apply, i.e. expressions `p`, `*p`, `**p`, etc., all return `p`.
+ * retRefTransition = if `e` is returned through a `return ref scope` function call
*/
-void escapeByRef(Expression e, EscapeByResults* er, bool live = false)
+void escapeByRef(Expression e, EscapeByResults* er, bool live = false, bool retRefTransition = false)
{
- //printf("[%s] escapeByRef, e: %s\n", e.loc.toChars(), e.toChars());
+ //printf("[%s] escapeByRef, e: %s, retRefTransition: %d\n", e.loc.toChars(), e.toChars(), retRefTransition);
void visit(Expression e)
{
}
@@ -1874,27 +1897,27 @@ void escapeByRef(Expression e, EscapeByResults* er, bool live = false)
if (ExpInitializer ez = v._init.isExpInitializer())
{
if (auto ce = ez.exp.isConstructExp())
- escapeByRef(ce.e2, er, live);
+ escapeByRef(ce.e2, er, live, retRefTransition);
else
- escapeByRef(ez.exp, er, live);
+ escapeByRef(ez.exp, er, live, retRefTransition);
}
}
else
- er.byref.push(v);
+ er.pushRef(v, retRefTransition);
}
}
void visitThis(ThisExp e)
{
if (e.var && e.var.toParent2().isFuncDeclaration().hasDualContext())
- escapeByValue(e, er, live);
+ escapeByValue(e, er, live, retRefTransition);
else if (e.var)
- er.byref.push(e.var);
+ er.pushRef(e.var, retRefTransition);
}
void visitPtr(PtrExp e)
{
- escapeByValue(e.e1, er, live);
+ escapeByValue(e.e1, er, live, retRefTransition);
}
void visitIndex(IndexExp e)
@@ -1907,18 +1930,18 @@ void escapeByRef(Expression e, EscapeByResults* er, bool live = false)
{
if (v && v.storage_class & STC.variadic)
{
- er.byref.push(v);
+ er.pushRef(v, retRefTransition);
return;
}
}
}
if (tb.ty == Tsarray)
{
- escapeByRef(e.e1, er, live);
+ escapeByRef(e.e1, er, live, retRefTransition);
}
else if (tb.ty == Tarray)
{
- escapeByValue(e.e1, er, live);
+ escapeByValue(e.e1, er, live, retRefTransition);
}
}
@@ -1929,40 +1952,40 @@ void escapeByRef(Expression e, EscapeByResults* er, bool live = false)
foreach (ex; *e.elements)
{
if (ex)
- escapeByRef(ex, er, live);
+ escapeByRef(ex, er, live, retRefTransition);
}
}
- er.byexp.push(e);
+ er.pushExp(e, retRefTransition);
}
void visitDotVar(DotVarExp e)
{
Type t1b = e.e1.type.toBasetype();
if (t1b.ty == Tclass)
- escapeByValue(e.e1, er, live);
+ escapeByValue(e.e1, er, live, retRefTransition);
else
- escapeByRef(e.e1, er, live);
+ escapeByRef(e.e1, er, live, retRefTransition);
}
void visitBinAssign(BinAssignExp e)
{
- escapeByRef(e.e1, er, live);
+ escapeByRef(e.e1, er, live, retRefTransition);
}
void visitAssign(AssignExp e)
{
- escapeByRef(e.e1, er, live);
+ escapeByRef(e.e1, er, live, retRefTransition);
}
void visitComma(CommaExp e)
{
- escapeByRef(e.e2, er, live);
+ escapeByRef(e.e2, er, live, retRefTransition);
}
void visitCond(CondExp e)
{
- escapeByRef(e.e1, er, live);
- escapeByRef(e.e2, er, live);
+ escapeByRef(e.e1, er, live, retRefTransition);
+ escapeByRef(e.e2, er, live, retRefTransition);
}
void visitCall(CallExp e)
@@ -1997,16 +2020,16 @@ void escapeByRef(Expression e, EscapeByResults* er, bool live = false)
const stc = tf.parameterStorageClass(null, p);
ScopeRef psr = buildScopeRef(stc);
if (psr == ScopeRef.ReturnRef || psr == ScopeRef.ReturnRef_Scope)
- escapeByRef(arg, er, live);
+ escapeByRef(arg, er, live, retRefTransition);
else if (psr == ScopeRef.ReturnScope || psr == ScopeRef.Ref_ReturnScope)
{
if (auto de = arg.isDelegateExp())
{
if (de.func.isNested())
- er.byexp.push(de);
+ er.pushExp(de, false);
}
else
- escapeByValue(arg, er, live);
+ escapeByValue(arg, er, live, retRefTransition);
}
}
}
@@ -2019,7 +2042,7 @@ void escapeByRef(Expression e, EscapeByResults* er, bool live = false)
// https://issues.dlang.org/show_bug.cgi?id=20149#c10
if (dve.var.isCtorDeclaration())
{
- er.byexp.push(e);
+ er.pushExp(e, false);
return;
}
@@ -2035,23 +2058,23 @@ void escapeByRef(Expression e, EscapeByResults* er, bool live = false)
const psr = buildScopeRef(stc);
if (psr == ScopeRef.ReturnRef || psr == ScopeRef.ReturnRef_Scope)
- escapeByRef(dve.e1, er, live);
+ escapeByRef(dve.e1, er, live, psr == ScopeRef.ReturnRef_Scope);
else if (psr == ScopeRef.ReturnScope || psr == ScopeRef.Ref_ReturnScope)
- escapeByValue(dve.e1, er, live);
+ escapeByValue(dve.e1, er, live, retRefTransition);
// If it's also a nested function that is 'return ref'
if (FuncDeclaration fd = dve.var.isFuncDeclaration())
{
if (fd.isNested() && tf.isreturn)
{
- er.byexp.push(e);
+ er.pushExp(e, false);
}
}
}
// If it's a delegate, check it too
if (e.e1.op == EXP.variable && t1.ty == Tdelegate)
{
- escapeByValue(e.e1, er, live);
+ escapeByValue(e.e1, er, live, retRefTransition);
}
/* If it's a nested function that is 'return ref'
@@ -2062,12 +2085,12 @@ void escapeByRef(Expression e, EscapeByResults* er, bool live = false)
if (fd && fd.isNested())
{
if (tf.isreturn)
- er.byexp.push(e);
+ er.pushExp(e, false);
}
}
}
else
- er.byexp.push(e);
+ er.pushExp(e, retRefTransition);
}
switch (e.op)
@@ -2091,7 +2114,6 @@ void escapeByRef(Expression e, EscapeByResults* er, bool live = false)
}
}
-
/************************************
* Aggregate the data collected by the escapeBy??() functions.
*/
@@ -2099,8 +2121,23 @@ struct EscapeByResults
{
VarDeclarations byref; // array into which variables being returned by ref are inserted
VarDeclarations byvalue; // array into which variables with values containing pointers are inserted
- FuncDeclarations byfunc; // nested functions that are turned into delegates
- Expressions byexp; // array into which temporaries being returned by ref are inserted
+ private FuncDeclarations byfunc; // nested functions that are turned into delegates
+ private Expressions byexp; // array into which temporaries being returned by ref are inserted
+
+ import dmd.root.array: Array;
+
+ /**
+ * Whether the variable / expression went through a `return ref scope` function call
+ *
+ * This is needed for the dip1000 by default transition, since the rules for
+ * disambiguating `return scope ref` have changed. Therefore, functions in legacy code
+ * can be mistakenly treated as `return ref` making the compiler believe stack variables
+ * are being escaped, which is an error even in `@system` code. By keeping track of this
+ * information, variables escaped through `return ref` can be treated as a deprecation instead
+ * of error, see test/fail_compilation/dip1000_deprecation.d
+ */
+ private Array!bool refRetRefTransition;
+ private Array!bool expRetRefTransition;
/** Reset arrays so the storage can be used again
*/
@@ -2110,6 +2147,33 @@ struct EscapeByResults
byvalue.setDim(0);
byfunc.setDim(0);
byexp.setDim(0);
+
+ refRetRefTransition.setDim(0);
+ expRetRefTransition.setDim(0);
+ }
+
+ /**
+ * Escape variable `v` by reference
+ * Params:
+ * v = variable to escape
+ * retRefTransition = `v` is escaped through a `return ref scope` function call
+ */
+ void pushRef(VarDeclaration v, bool retRefTransition)
+ {
+ byref.push(v);
+ refRetRefTransition.push(retRefTransition);
+ }
+
+ /**
+ * Escape a reference to expression `e`
+ * Params:
+ * e = expression to escape
+ * retRefTransition = `e` is escaped through a `return ref scope` function call
+ */
+ void pushExp(Expression e, bool retRefTransition)
+ {
+ byexp.push(e);
+ expRetRefTransition.push(retRefTransition);
}
}
@@ -2438,7 +2502,7 @@ private bool setUnsafePreview(Scope* sc, FeatureState fs, bool gag, Loc loc, con
}
else if (fs == FeatureState.enabled)
{
- return sc.func.setUnsafe(gag, loc, msg, arg0, arg1);
+ return sc.setUnsafe(gag, loc, msg, arg0, arg1);
}
else
{
@@ -2449,6 +2513,11 @@ private bool setUnsafePreview(Scope* sc, FeatureState fs, bool gag, Loc loc, con
loc, msg, arg0 ? arg0.toChars() : "", arg1 ? arg1.toChars() : ""
);
}
+ else if (!sc.func.safetyViolation)
+ {
+ import dmd.func : AttributeViolation;
+ sc.func.safetyViolation = new AttributeViolation(loc, msg, arg0, arg1);
+ }
return false;
}
}
diff --git a/gcc/d/dmd/expression.d b/gcc/d/dmd/expression.d
index 0872356..4d17105 100644
--- a/gcc/d/dmd/expression.d
+++ b/gcc/d/dmd/expression.d
@@ -1370,7 +1370,7 @@ extern (C++) abstract class Expression : ASTNode
*/
if (v.storage_class & STC.gshared)
{
- if (sc.func.setUnsafe(false, this.loc,
+ if (sc.setUnsafe(false, this.loc,
"`@safe` function `%s` cannot access `__gshared` data `%s`", sc.func, v))
{
err = true;
@@ -1419,7 +1419,7 @@ extern (C++) abstract class Expression : ASTNode
error("`@safe` %s `%s` cannot call `@system` %s `%s`",
sc.func.kind(), sc.func.toPrettyChars(), f.kind(),
prettyChars);
- f.errorSupplementalInferredSafety(/*max depth*/ 10);
+ f.errorSupplementalInferredSafety(/*max depth*/ 10, /*deprecation*/ false);
.errorSupplemental(f.loc, "`%s` is declared here", prettyChars);
checkOverridenDtor(sc, f, dd => dd.type.toTypeFunction().trust > TRUST.system, "@system");
@@ -1427,6 +1427,20 @@ extern (C++) abstract class Expression : ASTNode
return true;
}
}
+ else if (f.isSafe() && f.safetyViolation)
+ {
+ // for dip1000 by default transition, print deprecations for calling functions that will become `@system`
+ if (sc.func.isSafeBypassingInference())
+ {
+ .deprecation(this.loc, "`@safe` function `%s` calling `%s`", sc.func.toChars(), f.toChars());
+ errorSupplementalInferredSafety(f, 10, true);
+ }
+ else if (!sc.func.safetyViolation)
+ {
+ import dmd.func : AttributeViolation;
+ sc.func.safetyViolation = new AttributeViolation(this.loc, null, f, null);
+ }
+ }
return false;
}
@@ -5761,7 +5775,7 @@ extern (C++) final class DelegatePtrExp : UnaExp
override Expression modifiableLvalue(Scope* sc, Expression e)
{
- if (sc.func.setUnsafe(false, this.loc, "cannot modify delegate pointer in `@safe` code `%s`", this))
+ if (sc.setUnsafe(false, this.loc, "cannot modify delegate pointer in `@safe` code `%s`", this))
{
return ErrorExp.get();
}
@@ -5799,7 +5813,7 @@ extern (C++) final class DelegateFuncptrExp : UnaExp
override Expression modifiableLvalue(Scope* sc, Expression e)
{
- if (sc.func.setUnsafe(false, this.loc, "cannot modify delegate function pointer in `@safe` code `%s`", this))
+ if (sc.setUnsafe(false, this.loc, "cannot modify delegate function pointer in `@safe` code `%s`", this))
{
return ErrorExp.get();
}
diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h
index 330dcdb..9ab1cab 100644
--- a/gcc/d/dmd/expression.h
+++ b/gcc/d/dmd/expression.h
@@ -90,9 +90,9 @@ public:
virtual Expression *syntaxCopy();
// kludge for template.isExpression()
- DYNCAST dyncast() const { return DYNCAST_EXPRESSION; }
+ DYNCAST dyncast() const override final { return DYNCAST_EXPRESSION; }
- const char *toChars() const;
+ const char *toChars() const override;
void error(const char *format, ...) const;
void warning(const char *format, ...) const;
void deprecation(const char *format, ...) const;
@@ -206,6 +206,8 @@ public:
ShrAssignExp* isShrAssignExp();
UshrAssignExp* isUshrAssignExp();
CatAssignExp* isCatAssignExp();
+ CatElemAssignExp* isCatElemAssignExp();
+ CatDcharAssignExp* isCatDcharAssignExp();
AddExp* isAddExp();
MinExp* isMinExp();
CatExp* isCatExp();
@@ -238,71 +240,71 @@ public:
BinExp* isBinExp();
BinAssignExp* isBinAssignExp();
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class IntegerExp : public Expression
+class IntegerExp final : public Expression
{
public:
dinteger_t value;
static IntegerExp *create(const Loc &loc, dinteger_t value, Type *type);
static void emplace(UnionExp *pue, const Loc &loc, dinteger_t value, Type *type);
- bool equals(const RootObject *o) const;
- dinteger_t toInteger();
- real_t toReal();
- real_t toImaginary();
- complex_t toComplex();
- Optional<bool> toBool();
- Expression *toLvalue(Scope *sc, Expression *e);
- void accept(Visitor *v) { v->visit(this); }
+ bool equals(const RootObject *o) const override;
+ dinteger_t toInteger() override;
+ real_t toReal() override;
+ real_t toImaginary() override;
+ complex_t toComplex() override;
+ Optional<bool> toBool() override;
+ Expression *toLvalue(Scope *sc, Expression *e) override;
+ void accept(Visitor *v) override { v->visit(this); }
dinteger_t getInteger() { return value; }
void setInteger(dinteger_t value);
template<int v>
static IntegerExp literal();
};
-class ErrorExp : public Expression
+class ErrorExp final : public Expression
{
public:
- Expression *toLvalue(Scope *sc, Expression *e);
- void accept(Visitor *v) { v->visit(this); }
+ Expression *toLvalue(Scope *sc, Expression *e) override;
+ void accept(Visitor *v) override { v->visit(this); }
static ErrorExp *errorexp; // handy shared value
};
-class RealExp : public Expression
+class RealExp final : public Expression
{
public:
real_t value;
static RealExp *create(const Loc &loc, real_t value, Type *type);
static void emplace(UnionExp *pue, const Loc &loc, real_t value, Type *type);
- bool equals(const RootObject *o) const;
- dinteger_t toInteger();
- uinteger_t toUInteger();
- real_t toReal();
- real_t toImaginary();
- complex_t toComplex();
- Optional<bool> toBool();
- void accept(Visitor *v) { v->visit(this); }
+ bool equals(const RootObject *o) const override;
+ dinteger_t toInteger() override;
+ uinteger_t toUInteger() override;
+ real_t toReal() override;
+ real_t toImaginary() override;
+ complex_t toComplex() override;
+ Optional<bool> toBool() override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class ComplexExp : public Expression
+class ComplexExp final : public Expression
{
public:
complex_t value;
static ComplexExp *create(const Loc &loc, complex_t value, Type *type);
static void emplace(UnionExp *pue, const Loc &loc, complex_t value, Type *type);
- bool equals(const RootObject *o) const;
- dinteger_t toInteger();
- uinteger_t toUInteger();
- real_t toReal();
- real_t toImaginary();
- complex_t toComplex();
- Optional<bool> toBool();
- void accept(Visitor *v) { v->visit(this); }
+ bool equals(const RootObject *o) const override;
+ dinteger_t toInteger() override;
+ uinteger_t toUInteger() override;
+ real_t toReal() override;
+ real_t toImaginary() override;
+ complex_t toComplex() override;
+ Optional<bool> toBool() override;
+ void accept(Visitor *v) override { v->visit(this); }
};
class IdentifierExp : public Expression
@@ -311,27 +313,27 @@ public:
Identifier *ident;
static IdentifierExp *create(const Loc &loc, Identifier *ident);
- bool isLvalue();
- Expression *toLvalue(Scope *sc, Expression *e);
- void accept(Visitor *v) { v->visit(this); }
+ bool isLvalue() override final;
+ Expression *toLvalue(Scope *sc, Expression *e) override final;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class DollarExp : public IdentifierExp
+class DollarExp final : public IdentifierExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class DsymbolExp : public Expression
+class DsymbolExp final : public Expression
{
public:
Dsymbol *s;
bool hasOverloads;
- DsymbolExp *syntaxCopy();
- bool isLvalue();
- Expression *toLvalue(Scope *sc, Expression *e);
- void accept(Visitor *v) { v->visit(this); }
+ DsymbolExp *syntaxCopy() override;
+ bool isLvalue() override;
+ Expression *toLvalue(Scope *sc, Expression *e) override;
+ void accept(Visitor *v) override { v->visit(this); }
};
class ThisExp : public Expression
@@ -339,30 +341,30 @@ class ThisExp : public Expression
public:
VarDeclaration *var;
- ThisExp *syntaxCopy();
- Optional<bool> toBool();
- bool isLvalue();
- Expression *toLvalue(Scope *sc, Expression *e);
+ ThisExp *syntaxCopy() override;
+ Optional<bool> toBool() override;
+ bool isLvalue() override final;
+ Expression *toLvalue(Scope *sc, Expression *e) override final;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class SuperExp : public ThisExp
+class SuperExp final : public ThisExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class NullExp : public Expression
+class NullExp final : public Expression
{
public:
- bool equals(const RootObject *o) const;
- Optional<bool> toBool();
- StringExp *toStringExp();
- void accept(Visitor *v) { v->visit(this); }
+ bool equals(const RootObject *o) const override;
+ Optional<bool> toBool() override;
+ StringExp *toStringExp() override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class StringExp : public Expression
+class StringExp final : public Expression
{
public:
void *string; // char, wchar, or dchar data
@@ -375,23 +377,23 @@ public:
static StringExp *create(const Loc &loc, const char *s);
static StringExp *create(const Loc &loc, const void *s, d_size_t len);
static void emplace(UnionExp *pue, const Loc &loc, const char *s);
- bool equals(const RootObject *o) const;
+ bool equals(const RootObject *o) const override;
char32_t getCodeUnit(d_size_t i) const;
void setCodeUnit(d_size_t i, char32_t c);
- StringExp *toStringExp();
+ StringExp *toStringExp() override;
StringExp *toUTF8(Scope *sc);
- Optional<bool> toBool();
- bool isLvalue();
- Expression *toLvalue(Scope *sc, Expression *e);
- Expression *modifiableLvalue(Scope *sc, Expression *e);
- void accept(Visitor *v) { v->visit(this); }
+ Optional<bool> toBool() override;
+ bool isLvalue() override;
+ Expression *toLvalue(Scope *sc, Expression *e) override;
+ Expression *modifiableLvalue(Scope *sc, Expression *e) override;
+ void accept(Visitor *v) override { v->visit(this); }
size_t numberOfCodeUnits(int tynto = 0) const;
void writeTo(void* dest, bool zero, int tyto = 0) const;
};
// Tuple
-class TupleExp : public Expression
+class TupleExp final : public Expression
{
public:
Expression *e0; // side-effect part
@@ -405,13 +407,13 @@ public:
Expressions *exps;
static TupleExp *create(const Loc &loc, Expressions *exps);
- TupleExp *syntaxCopy();
- bool equals(const RootObject *o) const;
+ TupleExp *syntaxCopy() override;
+ bool equals(const RootObject *o) const override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class ArrayLiteralExp : public Expression
+class ArrayLiteralExp final : public Expression
{
public:
Expression *basis;
@@ -420,31 +422,31 @@ public:
static ArrayLiteralExp *create(const Loc &loc, Expressions *elements);
static void emplace(UnionExp *pue, const Loc &loc, Expressions *elements);
- ArrayLiteralExp *syntaxCopy();
- bool equals(const RootObject *o) const;
+ ArrayLiteralExp *syntaxCopy() override;
+ bool equals(const RootObject *o) const override;
Expression *getElement(d_size_t i); // use opIndex instead
Expression *opIndex(d_size_t i);
- Optional<bool> toBool();
- StringExp *toStringExp();
+ Optional<bool> toBool() override;
+ StringExp *toStringExp() override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class AssocArrayLiteralExp : public Expression
+class AssocArrayLiteralExp final : public Expression
{
public:
Expressions *keys;
Expressions *values;
OwnedBy ownedByCtfe;
- bool equals(const RootObject *o) const;
- AssocArrayLiteralExp *syntaxCopy();
- Optional<bool> toBool();
+ bool equals(const RootObject *o) const override;
+ AssocArrayLiteralExp *syntaxCopy() override;
+ Optional<bool> toBool() override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class StructLiteralExp : public Expression
+class StructLiteralExp final : public Expression
{
public:
StructDeclaration *sd; // which aggregate this is for
@@ -475,50 +477,50 @@ public:
OwnedBy ownedByCtfe;
static StructLiteralExp *create(const Loc &loc, StructDeclaration *sd, void *elements, Type *stype = NULL);
- bool equals(const RootObject *o) const;
- StructLiteralExp *syntaxCopy();
+ bool equals(const RootObject *o) const override;
+ StructLiteralExp *syntaxCopy() override;
Expression *getField(Type *type, unsigned offset);
int getFieldIndex(Type *type, unsigned offset);
- Expression *addDtorHook(Scope *sc);
- Expression *toLvalue(Scope *sc, Expression *e);
+ Expression *addDtorHook(Scope *sc) override;
+ Expression *toLvalue(Scope *sc, Expression *e) override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TypeExp : public Expression
+class TypeExp final : public Expression
{
public:
- TypeExp *syntaxCopy();
- bool checkType();
- bool checkValue();
- void accept(Visitor *v) { v->visit(this); }
+ TypeExp *syntaxCopy() override;
+ bool checkType() override;
+ bool checkValue() override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class ScopeExp : public Expression
+class ScopeExp final : public Expression
{
public:
ScopeDsymbol *sds;
- ScopeExp *syntaxCopy();
- bool checkType();
- bool checkValue();
- void accept(Visitor *v) { v->visit(this); }
+ ScopeExp *syntaxCopy() override;
+ bool checkType() override;
+ bool checkValue() override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TemplateExp : public Expression
+class TemplateExp final : public Expression
{
public:
TemplateDeclaration *td;
FuncDeclaration *fd;
- bool isLvalue();
- Expression *toLvalue(Scope *sc, Expression *e);
- bool checkType();
- bool checkValue();
- void accept(Visitor *v) { v->visit(this); }
+ bool isLvalue() override;
+ Expression *toLvalue(Scope *sc, Expression *e) override;
+ bool checkType() override;
+ bool checkValue() override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class NewExp : public Expression
+class NewExp final : public Expression
{
public:
/* newtype(arguments)
@@ -534,12 +536,12 @@ public:
bool thrownew; // this NewExp is the expression of a ThrowStatement
static NewExp *create(const Loc &loc, Expression *thisexp, Type *newtype, Expressions *arguments);
- NewExp *syntaxCopy();
+ NewExp *syntaxCopy() override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class NewAnonClassExp : public Expression
+class NewAnonClassExp final : public Expression
{
public:
/* class baseclasses { } (arguments)
@@ -548,8 +550,8 @@ public:
ClassDeclaration *cd; // class being instantiated
Expressions *arguments; // Array of Expression's to call class constructor
- NewAnonClassExp *syntaxCopy();
- void accept(Visitor *v) { v->visit(this); }
+ NewAnonClassExp *syntaxCopy() override;
+ void accept(Visitor *v) override { v->visit(this); }
};
class SymbolExp : public Expression
@@ -559,64 +561,64 @@ public:
Dsymbol *originalScope;
bool hasOverloads;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
// Offset from symbol
-class SymOffExp : public SymbolExp
+class SymOffExp final : public SymbolExp
{
public:
dinteger_t offset;
- Optional<bool> toBool();
+ Optional<bool> toBool() override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
// Variable
-class VarExp : public SymbolExp
+class VarExp final : public SymbolExp
{
public:
bool delegateWasExtracted;
static VarExp *create(const Loc &loc, Declaration *var, bool hasOverloads = true);
- bool equals(const RootObject *o) const;
- bool isLvalue();
- Expression *toLvalue(Scope *sc, Expression *e);
- Expression *modifiableLvalue(Scope *sc, Expression *e);
+ bool equals(const RootObject *o) const override;
+ bool isLvalue() override;
+ Expression *toLvalue(Scope *sc, Expression *e) override;
+ Expression *modifiableLvalue(Scope *sc, Expression *e) override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
// Overload Set
-class OverExp : public Expression
+class OverExp final : public Expression
{
public:
OverloadSet *vars;
- bool isLvalue();
- Expression *toLvalue(Scope *sc, Expression *e);
- void accept(Visitor *v) { v->visit(this); }
+ bool isLvalue() override;
+ Expression *toLvalue(Scope *sc, Expression *e) override;
+ void accept(Visitor *v) override { v->visit(this); }
};
// Function/Delegate literal
-class FuncExp : public Expression
+class FuncExp final : public Expression
{
public:
FuncLiteralDeclaration *fd;
TemplateDeclaration *td;
TOK tok;
- bool equals(const RootObject *o) const;
- FuncExp *syntaxCopy();
- const char *toChars() const;
- bool checkType();
- bool checkValue();
+ bool equals(const RootObject *o) const override;
+ FuncExp *syntaxCopy() override;
+ const char *toChars() const override;
+ bool checkType() override;
+ bool checkValue() override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
// Declaration of a symbol
@@ -624,44 +626,44 @@ public:
// D grammar allows declarations only as statements. However in AST representation
// it can be part of any expression. This is used, for example, during internal
// syntax re-writes to inject hidden symbols.
-class DeclarationExp : public Expression
+class DeclarationExp final : public Expression
{
public:
Dsymbol *declaration;
- DeclarationExp *syntaxCopy();
+ DeclarationExp *syntaxCopy() override;
- bool hasCode();
+ bool hasCode() override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TypeidExp : public Expression
+class TypeidExp final : public Expression
{
public:
RootObject *obj;
- TypeidExp *syntaxCopy();
- void accept(Visitor *v) { v->visit(this); }
+ TypeidExp *syntaxCopy() override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TraitsExp : public Expression
+class TraitsExp final : public Expression
{
public:
Identifier *ident;
Objects *args;
- TraitsExp *syntaxCopy();
- void accept(Visitor *v) { v->visit(this); }
+ TraitsExp *syntaxCopy() override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class HaltExp : public Expression
+class HaltExp final : public Expression
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class IsExp : public Expression
+class IsExp final : public Expression
{
public:
/* is(targ id tok tspec)
@@ -674,8 +676,8 @@ public:
TOK tok; // ':' or '=='
TOK tok2; // 'struct', 'union', etc.
- IsExp *syntaxCopy();
- void accept(Visitor *v) { v->visit(this); }
+ IsExp *syntaxCopy() override;
+ void accept(Visitor *v) override { v->visit(this); }
};
/****************************************************************/
@@ -686,11 +688,11 @@ public:
Expression *e1;
Type *att1; // Save alias this type to detect recursion
- UnaExp *syntaxCopy();
+ UnaExp *syntaxCopy() override;
Expression *incompatibleTypes();
- Expression *resolveLoc(const Loc &loc, Scope *sc);
+ Expression *resolveLoc(const Loc &loc, Scope *sc) override final;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
class BinExp : public Expression
@@ -702,56 +704,56 @@ public:
Type *att1; // Save alias this type to detect recursion
Type *att2; // Save alias this type to detect recursion
- BinExp *syntaxCopy();
+ BinExp *syntaxCopy() override;
Expression *incompatibleTypes();
Expression *reorderSettingAAElem(Scope *sc);
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
class BinAssignExp : public BinExp
{
public:
- bool isLvalue();
- Expression *toLvalue(Scope *sc, Expression *ex);
- Expression *modifiableLvalue(Scope *sc, Expression *e);
- void accept(Visitor *v) { v->visit(this); }
+ bool isLvalue() override final;
+ Expression *toLvalue(Scope *sc, Expression *ex) override final;
+ Expression *modifiableLvalue(Scope *sc, Expression *e) override final;
+ void accept(Visitor *v) override { v->visit(this); }
};
/****************************************************************/
-class MixinExp : public UnaExp
+class MixinExp final : public UnaExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class ImportExp : public UnaExp
+class ImportExp final : public UnaExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class AssertExp : public UnaExp
+class AssertExp final : public UnaExp
{
public:
Expression *msg;
- AssertExp *syntaxCopy();
+ AssertExp *syntaxCopy() override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class ThrowExp : public UnaExp
+class ThrowExp final : public UnaExp
{
public:
- ThrowExp *syntaxCopy();
+ ThrowExp *syntaxCopy() override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class DotIdExp : public UnaExp
+class DotIdExp final : public UnaExp
{
public:
Identifier *ident;
@@ -760,44 +762,44 @@ public:
bool arrow; // ImportC: if -> instead of .
static DotIdExp *create(const Loc &loc, Expression *e, Identifier *ident);
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class DotTemplateExp : public UnaExp
+class DotTemplateExp final : public UnaExp
{
public:
TemplateDeclaration *td;
- bool checkType();
- bool checkValue();
- void accept(Visitor *v) { v->visit(this); }
+ bool checkType() override;
+ bool checkValue() override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class DotVarExp : public UnaExp
+class DotVarExp final : public UnaExp
{
public:
Declaration *var;
bool hasOverloads;
- bool isLvalue();
- Expression *toLvalue(Scope *sc, Expression *e);
- Expression *modifiableLvalue(Scope *sc, Expression *e);
- void accept(Visitor *v) { v->visit(this); }
+ bool isLvalue() override;
+ Expression *toLvalue(Scope *sc, Expression *e) override;
+ Expression *modifiableLvalue(Scope *sc, Expression *e) override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class DotTemplateInstanceExp : public UnaExp
+class DotTemplateInstanceExp final : public UnaExp
{
public:
TemplateInstance *ti;
- DotTemplateInstanceExp *syntaxCopy();
+ DotTemplateInstanceExp *syntaxCopy() override;
bool findTempDecl(Scope *sc);
- bool checkType();
- bool checkValue();
- void accept(Visitor *v) { v->visit(this); }
+ bool checkType() override;
+ bool checkValue() override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class DelegateExp : public UnaExp
+class DelegateExp final : public UnaExp
{
public:
FuncDeclaration *func;
@@ -805,18 +807,18 @@ public:
VarDeclaration *vthis2; // container for multi-context
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class DotTypeExp : public UnaExp
+class DotTypeExp final : public UnaExp
{
public:
Dsymbol *sym; // symbol that represents a type
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class CallExp : public UnaExp
+class CallExp final : public UnaExp
{
public:
Expressions *arguments; // function arguments
@@ -831,76 +833,76 @@ public:
static CallExp *create(const Loc &loc, Expression *e, Expression *earg1);
static CallExp *create(const Loc &loc, FuncDeclaration *fd, Expression *earg1);
- CallExp *syntaxCopy();
- bool isLvalue();
- Expression *toLvalue(Scope *sc, Expression *e);
- Expression *addDtorHook(Scope *sc);
+ CallExp *syntaxCopy() override;
+ bool isLvalue() override;
+ Expression *toLvalue(Scope *sc, Expression *e) override;
+ Expression *addDtorHook(Scope *sc) override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class AddrExp : public UnaExp
+class AddrExp final : public UnaExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class PtrExp : public UnaExp
+class PtrExp final : public UnaExp
{
public:
- bool isLvalue();
- Expression *toLvalue(Scope *sc, Expression *e);
- Expression *modifiableLvalue(Scope *sc, Expression *e);
+ bool isLvalue() override;
+ Expression *toLvalue(Scope *sc, Expression *e) override;
+ Expression *modifiableLvalue(Scope *sc, Expression *e) override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class NegExp : public UnaExp
+class NegExp final : public UnaExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class UAddExp : public UnaExp
+class UAddExp final : public UnaExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class ComExp : public UnaExp
+class ComExp final : public UnaExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class NotExp : public UnaExp
+class NotExp final : public UnaExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class DeleteExp : public UnaExp
+class DeleteExp final : public UnaExp
{
public:
bool isRAII;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class CastExp : public UnaExp
+class CastExp final : public UnaExp
{
public:
// Possible to cast to one type while painting to another type
Type *to; // type to cast to
unsigned char mod; // MODxxxxx
- CastExp *syntaxCopy();
- bool isLvalue();
- Expression *toLvalue(Scope *sc, Expression *e);
+ CastExp *syntaxCopy() override;
+ bool isLvalue() override;
+ Expression *toLvalue(Scope *sc, Expression *e) override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class VectorExp : public UnaExp
+class VectorExp final : public UnaExp
{
public:
TypeVector *to; // the target vector type before semantic()
@@ -909,19 +911,19 @@ public:
static VectorExp *create(const Loc &loc, Expression *e, Type *t);
static void emplace(UnionExp *pue, const Loc &loc, Expression *e, Type *t);
- VectorExp *syntaxCopy();
- void accept(Visitor *v) { v->visit(this); }
+ VectorExp *syntaxCopy() override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class VectorArrayExp : public UnaExp
+class VectorArrayExp final : public UnaExp
{
public:
- bool isLvalue();
- Expression *toLvalue(Scope *sc, Expression *e);
- void accept(Visitor *v) { v->visit(this); }
+ bool isLvalue() override;
+ Expression *toLvalue(Scope *sc, Expression *e) override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class SliceExp : public UnaExp
+class SliceExp final : public UnaExp
{
public:
Expression *upr; // NULL if implicit 0
@@ -931,115 +933,115 @@ public:
bool lowerIsLessThanUpper; // true if lwr <= upr
bool arrayop; // an array operation, rather than a slice
- SliceExp *syntaxCopy();
- bool isLvalue();
- Expression *toLvalue(Scope *sc, Expression *e);
- Expression *modifiableLvalue(Scope *sc, Expression *e);
- Optional<bool> toBool();
+ SliceExp *syntaxCopy() override;
+ bool isLvalue() override;
+ Expression *toLvalue(Scope *sc, Expression *e) override;
+ Expression *modifiableLvalue(Scope *sc, Expression *e) override;
+ Optional<bool> toBool() override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class ArrayLengthExp : public UnaExp
+class ArrayLengthExp final : public UnaExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class IntervalExp : public Expression
+class IntervalExp final : public Expression
{
public:
Expression *lwr;
Expression *upr;
- IntervalExp *syntaxCopy();
- void accept(Visitor *v) { v->visit(this); }
+ IntervalExp *syntaxCopy() override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class DelegatePtrExp : public UnaExp
+class DelegatePtrExp final : public UnaExp
{
public:
- bool isLvalue();
- Expression *toLvalue(Scope *sc, Expression *e);
- Expression *modifiableLvalue(Scope *sc, Expression *e);
- void accept(Visitor *v) { v->visit(this); }
+ bool isLvalue() override;
+ Expression *toLvalue(Scope *sc, Expression *e) override;
+ Expression *modifiableLvalue(Scope *sc, Expression *e) override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class DelegateFuncptrExp : public UnaExp
+class DelegateFuncptrExp final : public UnaExp
{
public:
- bool isLvalue();
- Expression *toLvalue(Scope *sc, Expression *e);
- Expression *modifiableLvalue(Scope *sc, Expression *e);
- void accept(Visitor *v) { v->visit(this); }
+ bool isLvalue() override;
+ Expression *toLvalue(Scope *sc, Expression *e) override;
+ Expression *modifiableLvalue(Scope *sc, Expression *e) override;
+ void accept(Visitor *v) override { v->visit(this); }
};
// e1[a0,a1,a2,a3,...]
-class ArrayExp : public UnaExp
+class ArrayExp final : public UnaExp
{
public:
Expressions *arguments; // Array of Expression's
size_t currentDimension; // for opDollar
VarDeclaration *lengthVar;
- ArrayExp *syntaxCopy();
- bool isLvalue();
- Expression *toLvalue(Scope *sc, Expression *e);
+ ArrayExp *syntaxCopy() override;
+ bool isLvalue() override;
+ Expression *toLvalue(Scope *sc, Expression *e) override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
/****************************************************************/
-class DotExp : public BinExp
+class DotExp final : public BinExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class CommaExp : public BinExp
+class CommaExp final : public BinExp
{
public:
bool isGenerated;
bool allowCommaExp;
- bool isLvalue();
- Expression *toLvalue(Scope *sc, Expression *e);
- Expression *modifiableLvalue(Scope *sc, Expression *e);
- Optional<bool> toBool();
- Expression *addDtorHook(Scope *sc);
- void accept(Visitor *v) { v->visit(this); }
+ bool isLvalue() override;
+ Expression *toLvalue(Scope *sc, Expression *e) override;
+ Expression *modifiableLvalue(Scope *sc, Expression *e) override;
+ Optional<bool> toBool() override;
+ Expression *addDtorHook(Scope *sc) override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class IndexExp : public BinExp
+class IndexExp final : public BinExp
{
public:
VarDeclaration *lengthVar;
bool modifiable;
bool indexIsInBounds; // true if 0 <= e2 && e2 <= e1.length - 1
- IndexExp *syntaxCopy();
- bool isLvalue();
- Expression *toLvalue(Scope *sc, Expression *e);
- Expression *modifiableLvalue(Scope *sc, Expression *e);
+ IndexExp *syntaxCopy() override;
+ bool isLvalue() override;
+ Expression *toLvalue(Scope *sc, Expression *e) override;
+ Expression *modifiableLvalue(Scope *sc, Expression *e) override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
/* For both i++ and i--
*/
-class PostExp : public BinExp
+class PostExp final : public BinExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
/* For both ++i and --i
*/
-class PreExp : public UnaExp
+class PreExp final : public UnaExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
enum class MemorySet
@@ -1054,245 +1056,257 @@ class AssignExp : public BinExp
public:
MemorySet memset;
- bool isLvalue();
- Expression *toLvalue(Scope *sc, Expression *ex);
+ bool isLvalue() override final;
+ Expression *toLvalue(Scope *sc, Expression *ex) override final;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class ConstructExp : public AssignExp
+class ConstructExp final : public AssignExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class BlitExp : public AssignExp
+class BlitExp final : public AssignExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class AddAssignExp : public BinAssignExp
+class AddAssignExp final : public BinAssignExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class MinAssignExp : public BinAssignExp
+class MinAssignExp final : public BinAssignExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class MulAssignExp : public BinAssignExp
+class MulAssignExp final : public BinAssignExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class DivAssignExp : public BinAssignExp
+class DivAssignExp final : public BinAssignExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class ModAssignExp : public BinAssignExp
+class ModAssignExp final : public BinAssignExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class AndAssignExp : public BinAssignExp
+class AndAssignExp final : public BinAssignExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class OrAssignExp : public BinAssignExp
+class OrAssignExp final : public BinAssignExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class XorAssignExp : public BinAssignExp
+class XorAssignExp final : public BinAssignExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class PowAssignExp : public BinAssignExp
+class PowAssignExp final : public BinAssignExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class ShlAssignExp : public BinAssignExp
+class ShlAssignExp final : public BinAssignExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class ShrAssignExp : public BinAssignExp
+class ShrAssignExp final : public BinAssignExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class UshrAssignExp : public BinAssignExp
+class UshrAssignExp final : public BinAssignExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
class CatAssignExp : public BinAssignExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class AddExp : public BinExp
+class CatElemAssignExp final : public CatAssignExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class MinExp : public BinExp
+class CatDcharAssignExp final : public CatAssignExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class CatExp : public BinExp
+class AddExp final : public BinExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class MulExp : public BinExp
+class MinExp final : public BinExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class DivExp : public BinExp
+class CatExp final : public BinExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class ModExp : public BinExp
+class MulExp final : public BinExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class PowExp : public BinExp
+class DivExp final : public BinExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class ShlExp : public BinExp
+class ModExp final : public BinExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class ShrExp : public BinExp
+class PowExp final : public BinExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class UshrExp : public BinExp
+class ShlExp final : public BinExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class AndExp : public BinExp
+class ShrExp final : public BinExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class OrExp : public BinExp
+class UshrExp final : public BinExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class XorExp : public BinExp
+class AndExp final : public BinExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class LogicalExp : public BinExp
+class OrExp final : public BinExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class CmpExp : public BinExp
+class XorExp final : public BinExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class InExp : public BinExp
+class LogicalExp final : public BinExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class RemoveExp : public BinExp
+class CmpExp final : public BinExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
+};
+
+class InExp final : public BinExp
+{
+public:
+ void accept(Visitor *v) override { v->visit(this); }
+};
+
+class RemoveExp final : public BinExp
+{
+public:
+ void accept(Visitor *v) override { v->visit(this); }
};
// == and !=
-class EqualExp : public BinExp
+class EqualExp final : public BinExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
// is and !is
-class IdentityExp : public BinExp
+class IdentityExp final : public BinExp
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
/****************************************************************/
-class CondExp : public BinExp
+class CondExp final : public BinExp
{
public:
Expression *econd;
- CondExp *syntaxCopy();
- bool isLvalue();
- Expression *toLvalue(Scope *sc, Expression *e);
- Expression *modifiableLvalue(Scope *sc, Expression *e);
+ CondExp *syntaxCopy() override;
+ bool isLvalue() override;
+ Expression *toLvalue(Scope *sc, Expression *e) override;
+ Expression *modifiableLvalue(Scope *sc, Expression *e) override;
void hookDtors(Scope *sc);
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class GenericExp : Expression
+class GenericExp final : Expression
{
Expression *cntlExp;
Types *types;
Expressions *exps;
- GenericExp *syntaxCopy();
+ GenericExp *syntaxCopy() override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
/****************************************************************/
@@ -1300,42 +1314,42 @@ class GenericExp : Expression
class DefaultInitExp : public Expression
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class FileInitExp : public DefaultInitExp
+class FileInitExp final : public DefaultInitExp
{
public:
- Expression *resolveLoc(const Loc &loc, Scope *sc);
- void accept(Visitor *v) { v->visit(this); }
+ Expression *resolveLoc(const Loc &loc, Scope *sc) override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class LineInitExp : public DefaultInitExp
+class LineInitExp final : public DefaultInitExp
{
public:
- Expression *resolveLoc(const Loc &loc, Scope *sc);
- void accept(Visitor *v) { v->visit(this); }
+ Expression *resolveLoc(const Loc &loc, Scope *sc) override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class ModuleInitExp : public DefaultInitExp
+class ModuleInitExp final : public DefaultInitExp
{
public:
- Expression *resolveLoc(const Loc &loc, Scope *sc);
- void accept(Visitor *v) { v->visit(this); }
+ Expression *resolveLoc(const Loc &loc, Scope *sc) override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class FuncInitExp : public DefaultInitExp
+class FuncInitExp final : public DefaultInitExp
{
public:
- Expression *resolveLoc(const Loc &loc, Scope *sc);
- void accept(Visitor *v) { v->visit(this); }
+ Expression *resolveLoc(const Loc &loc, Scope *sc) override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class PrettyFuncInitExp : public DefaultInitExp
+class PrettyFuncInitExp final : public DefaultInitExp
{
public:
- Expression *resolveLoc(const Loc &loc, Scope *sc);
- void accept(Visitor *v) { v->visit(this); }
+ Expression *resolveLoc(const Loc &loc, Scope *sc) override;
+ void accept(Visitor *v) override { v->visit(this); }
};
/****************************************************************/
@@ -1396,10 +1410,10 @@ private:
/****************************************************************/
-class ObjcClassReferenceExp : public Expression
+class ObjcClassReferenceExp final : public Expression
{
public:
ClassDeclaration* classDeclaration;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d
index b65b0ed..cb72027 100644
--- a/gcc/d/dmd/expressionsem.d
+++ b/gcc/d/dmd/expressionsem.d
@@ -4989,7 +4989,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
sc.func.kind(), sc.func.toPrettyChars(), p, exp.e1.toChars());
err = true;
}
- if (tf.trust <= TRUST.system && sc.func.setUnsafe())
+ if (tf.trust <= TRUST.system && sc.setUnsafe())
{
exp.error("`@safe` %s `%s` cannot call `@system` %s `%s`",
sc.func.kind(), sc.func.toPrettyChars(), p, exp.e1.toChars());
@@ -5995,7 +5995,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
auto idxReserved = FileName.findReservedChar(namez);
if (idxReserved != size_t.max)
{
- e.error("`%s` is not a valid filename on this platform", se.toChars());
+ e.error("`%s` is not a valid filename on this platform", se.toChars());
e.errorSupplemental("Character `'%c'` is reserved and cannot be used", namez[idxReserved]);
return setError();
}
@@ -6543,8 +6543,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
RootObject o = (*tup.objects)[i];
Expression e;
Declaration var;
- if (o.dyncast() == DYNCAST.expression)
+ switch (o.dyncast()) with (DYNCAST)
{
+ case expression:
e = cast(Expression)o;
if (auto se = e.isDsymbolExp())
var = se.s.isDeclaration();
@@ -6553,9 +6554,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
// Exempt functions for backwards compatibility reasons.
// See: https://issues.dlang.org/show_bug.cgi?id=20470#c1
var = ve.var;
- }
- else if (o.dyncast() == DYNCAST.dsymbol)
- {
+ break;
+ case dsymbol:
Dsymbol s = cast(Dsymbol) o;
Declaration d = s.isDeclaration();
if (!d || d.isFuncDeclaration())
@@ -6564,13 +6564,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
e = new DsymbolExp(exp.loc, s);
else
var = d;
- }
- else if (o.dyncast() == DYNCAST.type)
- {
+ break;
+ case type:
e = new TypeExp(exp.loc, cast(Type)o);
- }
- else
- {
+ break;
+ default:
exp.error("`%s` is not an expression", o.toChars());
return setError();
}
@@ -6894,9 +6892,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
* because it might end up being a pointer to undefined
* memory.
*/
- if (sc.func && !sc.intypeof && !(sc.flags & SCOPE.debug_))
+ if (1)
{
- if (sc.func.setUnsafe(false, exp.loc,
+ if (sc.setUnsafe(false, exp.loc,
"cannot take address of lazy parameter `%s` in `@safe` function `%s`", ve, sc.func))
{
setError();
@@ -7045,7 +7043,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
if (sc.func && !sc.intypeof && !(sc.flags & SCOPE.debug_))
{
- sc.func.setUnsafe(false, exp.loc,
+ sc.setUnsafe(false, exp.loc,
"`this` reference necessary to take address of member `%s` in `@safe` function `%s`",
f, sc.func);
}
@@ -7552,10 +7550,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
// Check for unsafe casts
- if (!sc.intypeof &&
- !(sc.flags & SCOPE.debug_) &&
- !isSafeCast(ex, t1b, tob) &&
- (!sc.func && sc.stc & STC.safe || sc.func && sc.func.setUnsafe()))
+ if (!isSafeCast(ex, t1b, tob) &&
+ (!sc.func && sc.stc & STC.safe || sc.setUnsafe()))
{
exp.error("cast from `%s` to `%s` not allowed in safe code", exp.e1.type.toChars(), exp.to.toChars());
return setError();
@@ -7816,11 +7812,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
return setError();
}
- if (sc.func && !sc.intypeof && !(sc.flags & SCOPE.debug_))
- {
- if (sc.func.setUnsafe(false, exp.loc, "pointer slicing not allowed in safe functions"))
- return setError();
- }
+ if (sc.setUnsafe(false, exp.loc, "pointer slicing not allowed in safe functions"))
+ return setError();
}
else if (t1b.ty == Tarray)
{
@@ -8328,11 +8321,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (exp.e2.op == EXP.int64 && exp.e2.toInteger() == 0)
{
}
- else if (sc.func && !(sc.flags & SCOPE.debug_))
+ else if (sc.setUnsafe(false, exp.loc, "`@safe` function `%s` cannot index pointer `%s`", sc.func, exp.e1))
{
- if (sc.func.setUnsafe(false, exp.loc,
- "`@safe` function `%s` cannot index pointer `%s`", sc.func, exp.e1))
- return setError();
+ return setError();
}
exp.type = (cast(TypeNext)t1b).next;
break;
@@ -9729,11 +9720,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
if (t1n.toBasetype.ty == Tvoid && t2n.toBasetype.ty == Tvoid)
{
- if (!sc.intypeof && sc.func && !(sc.flags & SCOPE.debug_))
- {
- if (sc.func.setUnsafe(false, exp.loc, "cannot copy `void[]` to `void[]` in `@safe` code"))
- return setError();
- }
+ if (sc.setUnsafe(false, exp.loc, "cannot copy `void[]` to `void[]` in `@safe` code"))
+ return setError();
}
}
else
@@ -13089,9 +13077,8 @@ bool checkAddressVar(Scope* sc, Expression exp, VarDeclaration v)
v.storage_class &= ~STC.maybescope;
v.doNotInferScope = true;
if (global.params.useDIP1000 != FeatureState.enabled &&
- !(sc.flags & SCOPE.debug_) &&
!(v.storage_class & STC.temp) &&
- sc.func.setUnsafe())
+ sc.setUnsafe())
{
exp.error("cannot take address of %s `%s` in `@safe` function `%s`", p, v.toChars(), sc.func.toChars());
return false;
@@ -13304,7 +13291,7 @@ private bool fit(StructDeclaration sd, const ref Loc loc, Scope* sc, Expressions
{
if ((!stype.alignment.isDefault() && stype.alignment.get() < target.ptrsize ||
(v.offset & (target.ptrsize - 1))) &&
- (sc.func && sc.func.setUnsafe(false, loc,
+ (sc.setUnsafe(false, loc,
"field `%s.%s` cannot assign to misaligned pointers in `@safe` code", sd, v)))
{
return false;
diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d
index e53a540..0403948 100644
--- a/gcc/d/dmd/func.d
+++ b/gcc/d/dmd/func.d
@@ -346,7 +346,7 @@ extern (C++) class FuncDeclaration : Declaration
/// In case of failed `@safe` inference, store the error that made the function `@system` for
/// better diagnostics
- private AttributeViolation* safetyViolation;
+ AttributeViolation* safetyViolation;
/// Function flags: A collection of boolean packed for memory efficiency
/// See the `FUNCFLAG` enum
@@ -713,6 +713,44 @@ extern (C++) class FuncDeclaration : Declaration
}
}
}
+ if (_linkage == LINK.cpp && bestvi != -1)
+ {
+ StorageClass stc = 0;
+ FuncDeclaration fdv = (*vtbl)[bestvi].isFuncDeclaration();
+ assert(fdv && fdv.ident == ident);
+ if (type.covariant(fdv.type, &stc, /*cppCovariant=*/true) == Covariant.no)
+ {
+ /* https://issues.dlang.org/show_bug.cgi?id=22351
+ * Under D rules, `type` and `fdv.type` are covariant, but under C++ rules, they are not.
+ * For now, continue to allow D covariant rules to apply when `override` has been used,
+ * but issue a deprecation warning that this behaviour will change in the future.
+ * Otherwise, follow the C++ covariant rules, which will create a new vtable entry.
+ */
+ if (isOverride())
+ {
+ /* @@@DEPRECATED_2.110@@@
+ * After deprecation period has ended, be sure to remove this entire `LINK.cpp` branch,
+ * but also the `cppCovariant` parameter from Type.covariant, and update the function
+ * so that both `LINK.cpp` covariant conditions within are always checked.
+ */
+ .deprecation(loc, "overriding `extern(C++)` function `%s%s` with `const` qualified function `%s%s%s` is deprecated",
+ fdv.toPrettyChars(), fdv.type.toTypeFunction().parameterList.parametersTypeToChars(),
+ toPrettyChars(), type.toTypeFunction().parameterList.parametersTypeToChars(), type.modToChars());
+
+ const char* where = type.isNaked() ? "parameters" : "type";
+ deprecationSupplemental(loc, "Either remove `override`, or adjust the `const` qualifiers of the "
+ ~ "overriding function %s", where);
+ }
+ else
+ {
+ // Treat as if Covariant.no
+ mismatchvi = bestvi;
+ mismatchstc = stc;
+ mismatch = fdv;
+ bestvi = -1;
+ }
+ }
+ }
if (bestvi == -1 && mismatch)
{
//type.print();
@@ -1447,7 +1485,7 @@ extern (C++) class FuncDeclaration : Declaration
{
flags &= ~FUNCFLAG.safetyInprocess;
type.toTypeFunction().trust = TRUST.system;
- if (!gag && !safetyViolation && (fmt || arg0))
+ if (fmt || arg0)
safetyViolation = new AttributeViolation(loc, fmt, arg0, arg1);
if (fes)
@@ -4321,6 +4359,50 @@ extern (C++) final class NewDeclaration : FuncDeclaration
}
}
+/**************************************
+ * A statement / expression in this scope is not `@safe`,
+ * so mark the enclosing function as `@system`
+ *
+ * Params:
+ * sc = scope that the unsafe statement / expression is in
+ * gag = surpress error message (used in escape.d)
+ * loc = location of error
+ * fmt = printf-style format string
+ * arg0 = (optional) argument for first %s format specifier
+ * arg1 = (optional) argument for second %s format specifier
+ * Returns: whether there's a safe error
+ */
+bool setUnsafe(Scope* sc,
+ bool gag = false, Loc loc = Loc.init, const(char)* fmt = null, RootObject arg0 = null, RootObject arg1 = null)
+{
+ // TODO:
+ // For @system variables, unsafe initializers at global scope should mark
+ // the variable @system, see https://dlang.org/dips/1035
+
+ if (!sc.func)
+ return false;
+
+ if (sc.intypeof)
+ return false; // typeof(cast(int*)0) is safe
+
+ if (sc.flags & SCOPE.debug_) // debug {} scopes are permissive
+ return false;
+
+ if (sc.flags & SCOPE.compile) // __traits(compiles, x)
+ {
+ if (sc.func.isSafeBypassingInference())
+ {
+ // Message wil be gagged, but still call error() to update global.errors and for
+ // -verrors=spec
+ .error(loc, fmt, arg0 ? arg0.toChars() : "", arg1 ? arg1.toChars() : "");
+ return true;
+ }
+ return false;
+ }
+
+ return sc.func.setUnsafe(gag, loc, fmt, arg0, arg1);
+}
+
/// Stores a reason why a function failed to infer a function attribute like `@safe` or `pure`
///
/// Has two modes:
@@ -4329,7 +4411,7 @@ extern (C++) final class NewDeclaration : FuncDeclaration
/// that function might recursively also have a `AttributeViolation`. This way, in case
/// of a big call stack, the error can go down all the way to the root cause.
/// The `FunctionDeclaration` is then stored in `arg0` and `fmtStr` must be `null`.
-private struct AttributeViolation
+struct AttributeViolation
{
/// location of error
Loc loc = Loc.init;
@@ -4345,21 +4427,25 @@ private struct AttributeViolation
/// Params:
/// fd = function to check
/// maxDepth = up to how many functions deep to report errors
-void errorSupplementalInferredSafety(FuncDeclaration fd, int maxDepth)
+/// deprecation = print deprecations instead of errors
+void errorSupplementalInferredSafety(FuncDeclaration fd, int maxDepth, bool deprecation)
{
+ auto errorFunc = deprecation ? &deprecationSupplemental : &errorSupplemental;
if (auto s = fd.safetyViolation)
{
if (s.fmtStr)
{
- errorSupplemental(s.loc, "which was inferred `@system` because of:");
- errorSupplemental(s.loc, s.fmtStr, s.arg0 ? s.arg0.toChars() : "", s.arg1 ? s.arg1.toChars() : "");
+ errorFunc(s.loc, deprecation ?
+ "which would be `@system` because of:" :
+ "which was inferred `@system` because of:");
+ errorFunc(s.loc, s.fmtStr, s.arg0 ? s.arg0.toChars() : "", s.arg1 ? s.arg1.toChars() : "");
}
else if (FuncDeclaration fd2 = cast(FuncDeclaration) s.arg0)
{
if (maxDepth > 0)
{
- errorSupplemental(s.loc, "which calls `%s`", fd2.toPrettyChars());
- errorSupplementalInferredSafety(fd2, maxDepth - 1);
+ errorFunc(s.loc, "which calls `%s`", fd2.toPrettyChars());
+ errorSupplementalInferredSafety(fd2, maxDepth - 1, deprecation);
}
}
}
diff --git a/gcc/d/dmd/globals.d b/gcc/d/dmd/globals.d
index ba4ccbe..3766a0b 100644
--- a/gcc/d/dmd/globals.d
+++ b/gcc/d/dmd/globals.d
@@ -118,6 +118,7 @@ extern (C++) struct Param
bool useInline = false; // inline expand functions
FeatureState useDIP25; // implement https://wiki.dlang.org/DIP25
FeatureState useDIP1000; // implement https://dlang.org/spec/memory-safe-d.html#scope-return-params
+ bool fixImmutableConv; // error on unsound immutable conversion - https://github.com/dlang/dmd/pull/14070
bool useDIP1021; // implement https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1021.md
bool release; // build release version
bool preservePaths; // true means don't strip path from source file
@@ -298,7 +299,7 @@ extern (C++) struct Global
enum recursionLimit = 500; /// number of recursive template expansions before abort
- extern (C++) FileName function(FileName, const(char)* importc_h, ref Array!(const(char)*) cppswitches, out bool) preprocess;
+ extern (C++) FileName function(FileName, ref const Loc, ref Array!(const(char)*) cppswitches, out bool, OutBuffer* defines) preprocess;
nothrow:
diff --git a/gcc/d/dmd/globals.h b/gcc/d/dmd/globals.h
index 5c164fd..07298dd 100644
--- a/gcc/d/dmd/globals.h
+++ b/gcc/d/dmd/globals.h
@@ -20,6 +20,7 @@
template <typename TYPE> struct Array;
class FileManager;
+struct Loc;
typedef unsigned char Diagnostic;
enum
@@ -117,6 +118,7 @@ struct Param
bool useInline; // inline expand functions
FeatureState useDIP25; // implement https://wiki.dlang.org/DIP25
FeatureState useDIP1000; // implement https://dlang.org/spec/memory-safe-d.html#scope-return-params
+ bool fixImmutableConv;
bool useDIP1021; // implement https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1021.md
bool release; // build release version
bool preservePaths; // true means don't strip path from source file
@@ -270,7 +272,7 @@ struct Global
FileManager* fileManager;
- FileName (*preprocess)(FileName, const char*, Array<const char *>& cppswitches, bool&);
+ FileName (*preprocess)(FileName, const Loc&, Array<const char *>& cppswitches, bool&, OutBuffer&);
/* Start gagging. Return the current number of gagged errors
*/
diff --git a/gcc/d/dmd/hdrgen.d b/gcc/d/dmd/hdrgen.d
index fd35e1c..fcc9b61 100644
--- a/gcc/d/dmd/hdrgen.d
+++ b/gcc/d/dmd/hdrgen.d
@@ -3835,26 +3835,24 @@ private void typeToBufferx(Type t, OutBuffer* buf, HdrGenState* hgs)
{
foreach (id; t.idents)
{
- if (id.dyncast() == DYNCAST.dsymbol)
+ switch (id.dyncast()) with (DYNCAST)
{
+ case dsymbol:
buf.writeByte('.');
TemplateInstance ti = cast(TemplateInstance)id;
ti.dsymbolToBuffer(buf, hgs);
- }
- else if (id.dyncast() == DYNCAST.expression)
- {
+ break;
+ case expression:
buf.writeByte('[');
(cast(Expression)id).expressionToBuffer(buf, hgs);
buf.writeByte(']');
- }
- else if (id.dyncast() == DYNCAST.type)
- {
+ break;
+ case type:
buf.writeByte('[');
typeToBufferx(cast(Type)id, buf, hgs);
buf.writeByte(']');
- }
- else
- {
+ break;
+ default:
buf.writeByte('.');
buf.writestring(id.toString());
}
diff --git a/gcc/d/dmd/id.d b/gcc/d/dmd/id.d
index ab9528a..4993a9e 100644
--- a/gcc/d/dmd/id.d
+++ b/gcc/d/dmd/id.d
@@ -523,6 +523,8 @@ immutable Msgtable[] msgtable =
{ "show" },
{ "push" },
{ "pop" },
+ { "define" },
+ { "undef" },
];
diff --git a/gcc/d/dmd/identifier.h b/gcc/d/dmd/identifier.h
index 4c748be..fa7a25a 100644
--- a/gcc/d/dmd/identifier.h
+++ b/gcc/d/dmd/identifier.h
@@ -13,7 +13,7 @@
#include "root/dcompat.h"
#include "root/object.h"
-class Identifier : public RootObject
+class Identifier final : public RootObject
{
private:
int value;
@@ -22,12 +22,11 @@ private:
public:
static Identifier* create(const char *string);
- bool equals(const RootObject *o) const;
- const char *toChars() const;
+ const char *toChars() const override;
int getValue() const;
bool isAnonymous() const;
const char *toHChars2() const;
- DYNCAST dyncast() const;
+ DYNCAST dyncast() const override;
static Identifier *generateId(const char *prefix, size_t length, size_t suffix);
static Identifier *idPool(const char *s, unsigned len);
diff --git a/gcc/d/dmd/import.h b/gcc/d/dmd/import.h
index 5e7550e..f749ef5 100644
--- a/gcc/d/dmd/import.h
+++ b/gcc/d/dmd/import.h
@@ -17,7 +17,7 @@ struct Scope;
class Module;
class Package;
-class Import : public Dsymbol
+class Import final : public Dsymbol
{
public:
/* static import aliasId = pkg1.pkg2.id : alias1 = name1, alias2 = name2;
@@ -38,17 +38,17 @@ public:
AliasDeclarations aliasdecls; // corresponding AliasDeclarations for alias=name pairs
- const char *kind() const;
- Visibility visible();
- Import *syntaxCopy(Dsymbol *s); // copy only syntax trees
+ const char *kind() const override;
+ Visibility visible() override;
+ Import *syntaxCopy(Dsymbol *s) override; // copy only syntax trees
void load(Scope *sc);
- void importAll(Scope *sc);
- Dsymbol *toAlias();
- void addMember(Scope *sc, ScopeDsymbol *sds);
- void setScope(Scope* sc);
- Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);
- bool overloadInsert(Dsymbol *s);
-
- Import *isImport() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ void importAll(Scope *sc) override;
+ Dsymbol *toAlias() override;
+ void addMember(Scope *sc, ScopeDsymbol *sds) override;
+ void setScope(Scope* sc) override;
+ Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly) override;
+ bool overloadInsert(Dsymbol *s) override;
+
+ Import *isImport() override { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
diff --git a/gcc/d/dmd/init.d b/gcc/d/dmd/init.d
index 179e0b6..164a5f3 100644
--- a/gcc/d/dmd/init.d
+++ b/gcc/d/dmd/init.d
@@ -44,7 +44,7 @@ extern (C++) class Initializer : ASTNode
Loc loc;
InitKind kind;
- override DYNCAST dyncast() const nothrow pure
+ override DYNCAST dyncast() const
{
return DYNCAST.initializer;
}
diff --git a/gcc/d/dmd/init.h b/gcc/d/dmd/init.h
index 73dc4bb..296c31d 100644
--- a/gcc/d/dmd/init.h
+++ b/gcc/d/dmd/init.h
@@ -33,7 +33,9 @@ public:
Loc loc;
unsigned char kind;
- const char *toChars() const;
+ DYNCAST dyncast() const override { return DYNCAST_INITIALIZER; }
+
+ const char *toChars() const override final;
ErrorInitializer *isErrorInitializer();
VoidInitializer *isVoidInitializer();
@@ -42,33 +44,33 @@ public:
ExpInitializer *isExpInitializer();
CInitializer *isCInitializer();
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class VoidInitializer : public Initializer
+class VoidInitializer final : public Initializer
{
public:
Type *type; // type that this will initialize to
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class ErrorInitializer : public Initializer
+class ErrorInitializer final : public Initializer
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class StructInitializer : public Initializer
+class StructInitializer final : public Initializer
{
public:
Identifiers field; // of Identifier *'s
Initializers value; // parallel array of Initializer *'s
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class ArrayInitializer : public Initializer
+class ArrayInitializer final : public Initializer
{
public:
Expressions index; // indices
@@ -80,16 +82,16 @@ public:
bool isAssociativeArray() const;
Expression *toAssocArrayLiteral();
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class ExpInitializer : public Initializer
+class ExpInitializer final : public Initializer
{
public:
bool expandTuples;
Expression *exp;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
struct Designator
@@ -104,14 +106,14 @@ struct DesigInit
Initializer *initializer;
};
-class CInitializer : public Initializer
+class CInitializer final : public Initializer
{
public:
DesigInits initializerList;
Type *type; // type that array will be used to initialize
bool sem; // true if semantic() is run
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
Expression *initializerToExpression(Initializer *init, Type *t = NULL, const bool isCfile = false);
diff --git a/gcc/d/dmd/initsem.d b/gcc/d/dmd/initsem.d
index 2cddd28..a1963da 100644
--- a/gcc/d/dmd/initsem.d
+++ b/gcc/d/dmd/initsem.d
@@ -197,10 +197,9 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
if (vd.type.hasPointers)
{
if ((!t.alignment.isDefault() && t.alignment.get() < target.ptrsize ||
- (vd.offset & (target.ptrsize - 1))) &&
- sc.func)
+ (vd.offset & (target.ptrsize - 1))))
{
- if (sc.func.setUnsafe(false, i.value[j].loc,
+ if (sc.setUnsafe(false, i.value[j].loc,
"field `%s.%s` cannot assign to misaligned pointers in `@safe` code", sd, vd))
{
errors = true;
diff --git a/gcc/d/dmd/lexer.d b/gcc/d/dmd/lexer.d
index 5945da3..ef918e2 100644
--- a/gcc/d/dmd/lexer.d
+++ b/gcc/d/dmd/lexer.d
@@ -146,6 +146,36 @@ class Lexer
}
}
+ /******************
+ * Used for unittests for a mock Lexer
+ */
+ this() { }
+
+ /**************************************
+ * Reset lexer to lex #define's
+ */
+ final void resetDefineLines(const(char)[] slice)
+ {
+ base = slice.ptr;
+ end = base + slice.length;
+ assert(*end == 0);
+ p = base;
+ line = p;
+ tokenizeNewlines = true;
+ inTokenStringConstant = 0;
+ lastDocLine = 0;
+ scanloc = Loc("#defines", 1, 1);
+ }
+
+ /**********************************
+ * Set up for next #define line.
+ * p should be at start of next line.
+ */
+ final void nextDefineLine()
+ {
+ tokenizeNewlines = true;
+ }
+
version (DMDLIB)
{
this(const(char)* filename, const(char)* base, size_t begoffset, size_t endoffset,
@@ -1184,7 +1214,7 @@ class Lexer
* Returns:
* the escape sequence as a single character
*/
- private static dchar escapeSequence(const ref Loc loc, ref const(char)* sequence, bool Ccompile)
+ private dchar escapeSequence(const ref Loc loc, ref const(char)* sequence, bool Ccompile)
{
const(char)* p = sequence; // cache sequence reference on stack
scope(exit) sequence = p;
@@ -1268,13 +1298,13 @@ class Lexer
break;
if (!ishex(cast(char)c))
{
- .error(loc, "escape hex sequence has %d hex digits instead of %d", n, ndigits);
+ error(loc, "escape hex sequence has %d hex digits instead of %d", n, ndigits);
break;
}
}
if (ndigits != 2 && !utf_isValidDchar(v))
{
- .error(loc, "invalid UTF character \\U%08x", v);
+ error(loc, "invalid UTF character \\U%08x", v);
v = '?'; // recover with valid UTF character
}
}
@@ -1282,7 +1312,7 @@ class Lexer
}
else
{
- .error(loc, "undefined escape hex sequence \\%c%c", sequence[0], c);
+ error(loc, "undefined escape hex sequence \\%c%c", sequence[0], c);
p++;
}
break;
@@ -1299,7 +1329,7 @@ class Lexer
c = HtmlNamedEntity(idstart, p - idstart);
if (c == ~0)
{
- .error(loc, "unnamed character entity &%.*s;", cast(int)(p - idstart), idstart);
+ error(loc, "unnamed character entity &%.*s;", cast(int)(p - idstart), idstart);
c = '?';
}
p++;
@@ -1307,7 +1337,7 @@ class Lexer
default:
if (isalpha(*p) || (p != idstart && isdigit(*p)))
continue;
- .error(loc, "unterminated named entity &%.*s;", cast(int)(p - idstart + 1), idstart);
+ error(loc, "unterminated named entity &%.*s;", cast(int)(p - idstart + 1), idstart);
c = '?';
break;
}
@@ -1332,11 +1362,11 @@ class Lexer
while (++n < 3 && isoctal(cast(char)c));
c = v;
if (c > 0xFF)
- .error(loc, "escape octal sequence \\%03o is larger than \\377", c);
+ error(loc, "escape octal sequence \\%03o is larger than \\377", c);
}
else
{
- .error(loc, "undefined escape sequence \\%c", c);
+ error(loc, "undefined escape sequence \\%c", c);
p++;
}
break;
@@ -2732,8 +2762,10 @@ class Lexer
/***************************************
* Scan forward to start of next line.
+ * Params:
+ * defines = send characters to `defines`
*/
- final void skipToNextLine()
+ final void skipToNextLine(OutBuffer* defines = null)
{
while (1)
{
@@ -2754,7 +2786,9 @@ class Lexer
break;
default:
- if (*p & 0x80)
+ if (defines)
+ defines.writeByte(*p); // don't care about Unicode line endings for C
+ else if (*p & 0x80)
{
const u = decodeUTF();
if (u == PS || u == LS)
@@ -3146,7 +3180,8 @@ unittest
static void test(T)(string sequence, T expected, bool Ccompile = false)
{
auto p = cast(const(char)*)sequence.ptr;
- assert(expected == Lexer.escapeSequence(Loc.initial, p, Ccompile));
+ Lexer lexer = new Lexer();
+ assert(expected == lexer.escapeSequence(Loc.initial, p, Ccompile));
assert(p == sequence.ptr + sequence.length);
}
@@ -3212,7 +3247,8 @@ unittest
gotError = false;
expected = expectedError;
auto p = cast(const(char)*)sequence.ptr;
- auto actualReturnValue = Lexer.escapeSequence(Loc.initial, p, Ccompile);
+ Lexer lexer = new Lexer();
+ auto actualReturnValue = lexer.escapeSequence(Loc.initial, p, Ccompile);
assert(gotError);
assert(expectedReturnValue == actualReturnValue);
diff --git a/gcc/d/dmd/module.h b/gcc/d/dmd/module.h
index 048b3a0..5808c28 100644
--- a/gcc/d/dmd/module.h
+++ b/gcc/d/dmd/module.h
@@ -35,21 +35,21 @@ public:
unsigned tag; // auto incremented tag, used to mask package tree in scopes
Module *mod; // != NULL if isPkgMod == PKGmodule
- const char *kind() const;
+ const char *kind() const override;
- bool equals(const RootObject *o) const;
+ bool equals(const RootObject *o) const override;
- Package *isPackage() { return this; }
+ Package *isPackage() override final { return this; }
bool isAncestorPackageOf(const Package * const pkg) const;
- Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);
- void accept(Visitor *v) { v->visit(this); }
+ Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly) override;
+ void accept(Visitor *v) override { v->visit(this); }
Module *isPackageMod();
};
-class Module : public Package
+class Module final : public Package
{
public:
static Module *rootModule;
@@ -82,6 +82,7 @@ public:
int needmoduleinfo;
int selfimports; // 0: don't know, 1: does not, 2: does
void* tagSymTab; // ImportC: tag symbols that conflict with other symbols used as the index
+ OutBuffer defines; // collect all the #define lines here
bool selfImports(); // returns true if module imports itself
int rootimports; // 0: don't know, 1: does not, 2: does
@@ -119,14 +120,14 @@ public:
static Module *load(const Loc &loc, Identifiers *packages, Identifier *ident);
- const char *kind() const;
+ const char *kind() const override;
bool read(const Loc &loc); // read file, returns 'true' if succeed, 'false' otherwise.
Module *parse(); // syntactic parse
- void importAll(Scope *sc);
+ void importAll(Scope *sc) override;
int needModuleInfo();
- Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);
- bool isPackageAccessible(Package *p, Visibility visibility, int flags = 0);
- Dsymbol *symtabInsert(Dsymbol *s);
+ Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly) override;
+ bool isPackageAccessible(Package *p, Visibility visibility, int flags = 0) override;
+ Dsymbol *symtabInsert(Dsymbol *s) override;
void deleteObjFile();
static void runDeferredSemantic();
static void runDeferredSemantic2();
@@ -155,8 +156,8 @@ public:
void *ctfe_cov; // stores coverage information from ctfe
- Module *isModule() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ Module *isModule() override { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
diff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d
index be17ab3..052c23d 100644
--- a/gcc/d/dmd/mtype.d
+++ b/gcc/d/dmd/mtype.d
@@ -525,10 +525,12 @@ extern (C++) abstract class Type : ASTNode
* Params:
* t = type 'this' is covariant with
* pstc = if not null, store STCxxxx which would make it covariant
+ * cppCovariant = true if extern(C++) function types should follow C++ covariant rules
* Returns:
* An enum value of either `Covariant.yes` or a reason it's not covariant.
*/
- final Covariant covariant(Type t, StorageClass* pstc = null)
+ extern (D)
+ final Covariant covariant(Type t, StorageClass* pstc = null, bool cppCovariant = false)
{
version (none)
{
@@ -563,11 +565,11 @@ extern (C++) abstract class Type : ASTNode
foreach (i, fparam1; t1.parameterList)
{
Parameter fparam2 = t2.parameterList[i];
+ Type tp1 = fparam1.type;
+ Type tp2 = fparam2.type;
- if (!fparam1.type.equals(fparam2.type))
+ if (!tp1.equals(tp2))
{
- Type tp1 = fparam1.type;
- Type tp2 = fparam2.type;
if (tp1.ty == tp2.ty)
{
if (auto tc1 = tp1.isTypeClass())
@@ -600,6 +602,16 @@ extern (C++) abstract class Type : ASTNode
}
Lcov:
notcovariant |= !fparam1.isCovariant(t1.isref, fparam2);
+
+ /* https://issues.dlang.org/show_bug.cgi?id=23135
+ * extern(C++) mutable parameters are not covariant with const.
+ */
+ if (t1.linkage == LINK.cpp && cppCovariant)
+ {
+ notcovariant |= tp1.isNaked() != tp2.isNaked();
+ if (auto tpn1 = tp1.nextOf())
+ notcovariant |= tpn1.isNaked() != tp2.nextOf().isNaked();
+ }
}
}
else if (t1.parameterList.parameters != t2.parameterList.parameters)
@@ -701,6 +713,12 @@ extern (C++) abstract class Type : ASTNode
else if (t1.isreturn && !t2.isreturn)
goto Lnotcovariant;
+ /* https://issues.dlang.org/show_bug.cgi?id=23135
+ * extern(C++) mutable member functions are not covariant with const.
+ */
+ if (t1.linkage == LINK.cpp && cppCovariant && t1.isNaked() != t2.isNaked())
+ goto Lnotcovariant;
+
/* Can convert mutable to const
*/
if (!MODimplicitConv(t2.mod, t1.mod))
@@ -3237,7 +3255,7 @@ extern (C++) final class TypeBasic : Type
return this;
}
- override uinteger_t size(const ref Loc loc) const
+ override uinteger_t size(const ref Loc loc)
{
uint size;
//printf("TypeBasic::size()\n");
@@ -3325,32 +3343,32 @@ extern (C++) final class TypeBasic : Type
return (flags & TFlags.integral) != 0;
}
- override bool isfloating() const
+ override bool isfloating()
{
return (flags & TFlags.floating) != 0;
}
- override bool isreal() const
+ override bool isreal()
{
return (flags & TFlags.real_) != 0;
}
- override bool isimaginary() const
+ override bool isimaginary()
{
return (flags & TFlags.imaginary) != 0;
}
- override bool iscomplex() const
+ override bool iscomplex()
{
return (flags & TFlags.complex) != 0;
}
- override bool isscalar() const
+ override bool isscalar()
{
return (flags & (TFlags.integral | TFlags.floating)) != 0;
}
- override bool isunsigned() const
+ override bool isunsigned()
{
return (flags & TFlags.unsigned) != 0;
}
@@ -3447,7 +3465,7 @@ extern (C++) final class TypeBasic : Type
return MATCH.convert;
}
- override bool isZeroInit(const ref Loc loc) const
+ override bool isZeroInit(const ref Loc loc)
{
switch (ty)
{
@@ -3543,7 +3561,7 @@ extern (C++) final class TypeVector : Type
return basetype.nextOf().isunsigned();
}
- override bool isBoolean() const
+ override bool isBoolean()
{
return false;
}
@@ -3860,13 +3878,13 @@ extern (C++) final class TypeDArray : TypeArray
return result;
}
- override uinteger_t size(const ref Loc loc) const
+ override uinteger_t size(const ref Loc loc)
{
//printf("TypeDArray::size()\n");
return target.ptrsize * 2;
}
- override uint alignsize() const
+ override uint alignsize()
{
// A DArray consists of two ptr-sized values, so align it on pointer size
// boundary
@@ -3879,12 +3897,12 @@ extern (C++) final class TypeDArray : TypeArray
return nty.isSomeChar;
}
- override bool isZeroInit(const ref Loc loc) const
+ override bool isZeroInit(const ref Loc loc)
{
return true;
}
- override bool isBoolean() const
+ override bool isBoolean()
{
return true;
}
@@ -3918,7 +3936,7 @@ extern (C++) final class TypeDArray : TypeArray
return Type.implicitConvTo(to);
}
- override bool hasPointers() const
+ override bool hasPointers()
{
return true;
}
@@ -3964,22 +3982,22 @@ extern (C++) final class TypeAArray : TypeArray
return result;
}
- override uinteger_t size(const ref Loc loc) const
+ override uinteger_t size(const ref Loc loc)
{
return target.ptrsize;
}
- override bool isZeroInit(const ref Loc loc) const
+ override bool isZeroInit(const ref Loc loc)
{
return true;
}
- override bool isBoolean() const
+ override bool isBoolean()
{
return true;
}
- override bool hasPointers() const
+ override bool hasPointers()
{
return true;
}
@@ -4056,7 +4074,7 @@ extern (C++) final class TypePointer : TypeNext
return result;
}
- override uinteger_t size(const ref Loc loc) const
+ override uinteger_t size(const ref Loc loc)
{
return target.ptrsize;
}
@@ -4112,17 +4130,17 @@ extern (C++) final class TypePointer : TypeNext
return TypeNext.constConv(to);
}
- override bool isscalar() const
+ override bool isscalar()
{
return true;
}
- override bool isZeroInit(const ref Loc loc) const
+ override bool isZeroInit(const ref Loc loc)
{
return true;
}
- override bool hasPointers() const
+ override bool hasPointers()
{
return true;
}
@@ -4159,12 +4177,12 @@ extern (C++) final class TypeReference : TypeNext
return result;
}
- override uinteger_t size(const ref Loc loc) const
+ override uinteger_t size(const ref Loc loc)
{
return target.ptrsize;
}
- override bool isZeroInit(const ref Loc loc) const
+ override bool isZeroInit(const ref Loc loc)
{
return true;
}
@@ -4760,7 +4778,7 @@ extern (C++) final class TypeFunction : TypeNext
char[] s;
if (!f.isPure && sc.func.setImpure())
s ~= "pure ";
- if (!f.isSafe() && !f.isTrusted() && sc.func.setUnsafe())
+ if (!f.isSafe() && !f.isTrusted() && sc.setUnsafe())
s ~= "@safe ";
if (!f.isNogc && sc.func.setGC())
s ~= "nogc ";
@@ -5156,12 +5174,12 @@ extern (C++) final class TypeDelegate : TypeNext
return t;
}
- override uinteger_t size(const ref Loc loc) const
+ override uinteger_t size(const ref Loc loc)
{
return target.ptrsize * 2;
}
- override uint alignsize() const
+ override uint alignsize()
{
return target.ptrsize;
}
@@ -5189,17 +5207,17 @@ extern (C++) final class TypeDelegate : TypeNext
return MATCH.nomatch;
}
- override bool isZeroInit(const ref Loc loc) const
+ override bool isZeroInit(const ref Loc loc)
{
return true;
}
- override bool isBoolean() const
+ override bool isBoolean()
{
return true;
}
- override bool hasPointers() const
+ override bool hasPointers()
{
return true;
}
@@ -5748,12 +5766,12 @@ extern (C++) final class TypeStruct : Type
return assignable;
}
- override bool isBoolean() const
+ override bool isBoolean()
{
return false;
}
- override bool needsDestruction() const
+ override bool needsDestruction()
{
return sym.dtor !is null;
}
@@ -5985,6 +6003,7 @@ extern (C++) final class TypeEnum : Type
{
return sym.getMemtype(loc);
}
+
override uint alignsize()
{
Type t = memType();
@@ -6143,7 +6162,7 @@ extern (C++) final class TypeClass : Type
return "class";
}
- override uinteger_t size(const ref Loc loc) const
+ override uinteger_t size(const ref Loc loc)
{
return target.ptrsize;
}
@@ -6268,22 +6287,22 @@ extern (C++) final class TypeClass : Type
return this;
}
- override bool isZeroInit(const ref Loc loc) const
+ override bool isZeroInit(const ref Loc loc)
{
return true;
}
- override bool isscope() const
+ override bool isscope()
{
return sym.stack;
}
- override bool isBoolean() const
+ override bool isBoolean()
{
return true;
}
- override bool hasPointers() const
+ override bool hasPointers()
{
return true;
}
@@ -6538,12 +6557,12 @@ extern (C++) final class TypeNull : Type
return true;
}
- override bool isBoolean() const
+ override bool isBoolean()
{
return true;
}
- override uinteger_t size(const ref Loc loc) const
+ override uinteger_t size(const ref Loc loc)
{
return tvoidptr.size(loc);
}
@@ -6597,12 +6616,12 @@ extern (C++) final class TypeNoreturn : Type
return this.implicitConvTo(to);
}
- override bool isBoolean() const
+ override bool isBoolean()
{
return true; // bottom type can be implicitly converted to any other type
}
- override uinteger_t size(const ref Loc loc) const
+ override uinteger_t size(const ref Loc loc)
{
return 0;
}
diff --git a/gcc/d/dmd/mtype.h b/gcc/d/dmd/mtype.h
index d2b1364..3565913 100644
--- a/gcc/d/dmd/mtype.h
+++ b/gcc/d/dmd/mtype.h
@@ -119,14 +119,6 @@ enum MODFlags
};
typedef unsigned char MOD;
-enum class Covariant
-{
- distinct = 0,
- yes = 1,
- no = 2,
- fwdref = 3,
-};
-
enum VarArgValues
{
VARARGnone = 0, /// fixed number of arguments
@@ -221,13 +213,12 @@ public:
virtual const char *kind();
Type *copy() const;
virtual Type *syntaxCopy();
- bool equals(const RootObject *o) const;
+ bool equals(const RootObject *o) const override;
bool equivalent(Type *t);
// kludge for template.isType()
- DYNCAST dyncast() const { return DYNCAST_TYPE; }
+ DYNCAST dyncast() const override final { return DYNCAST_TYPE; }
size_t getUniqueID() const;
- Covariant covariant(Type *t, StorageClass *pstc = NULL);
- const char *toChars() const;
+ const char *toChars() const override;
char *toPrettyChars(bool QualifyTypes = false);
static void _init();
@@ -306,7 +297,7 @@ public:
virtual ClassDeclaration *isClassHandle();
virtual structalign_t alignment();
virtual Expression *defaultInitLiteral(const Loc &loc);
- virtual bool isZeroInit(const Loc &loc = Loc()); // if initializer is 0
+ virtual bool isZeroInit(const Loc &loc = Loc()); // if initializer is 0
Identifier *getTypeInfoIdent();
virtual int hasWild() const;
virtual bool hasPointers();
@@ -349,18 +340,18 @@ public:
TypeNoreturn *isTypeNoreturn();
TypeTag *isTypeTag();
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TypeError : public Type
+class TypeError final : public Type
{
public:
- const char *kind();
- TypeError *syntaxCopy();
+ const char *kind() override;
+ TypeError *syntaxCopy() override;
- uinteger_t size(const Loc &loc);
- Expression *defaultInitLiteral(const Loc &loc);
- void accept(Visitor *v) { v->visit(this); }
+ uinteger_t size(const Loc &loc) override;
+ Expression *defaultInitLiteral(const Loc &loc) override;
+ void accept(Visitor *v) override { v->visit(this); }
};
class TypeNext : public Type
@@ -368,164 +359,164 @@ class TypeNext : public Type
public:
Type *next;
- void checkDeprecated(const Loc &loc, Scope *sc);
- int hasWild() const;
- Type *nextOf();
- Type *makeConst();
- Type *makeImmutable();
- Type *makeShared();
- Type *makeSharedConst();
- Type *makeWild();
- Type *makeWildConst();
- Type *makeSharedWild();
- Type *makeSharedWildConst();
- Type *makeMutable();
- MATCH constConv(Type *to);
- unsigned char deduceWild(Type *t, bool isRef);
+ void checkDeprecated(const Loc &loc, Scope *sc) override final;
+ int hasWild() const override final;
+ Type *nextOf() override final;
+ Type *makeConst() override final;
+ Type *makeImmutable() override final;
+ Type *makeShared() override final;
+ Type *makeSharedConst() override final;
+ Type *makeWild() override final;
+ Type *makeWildConst() override final;
+ Type *makeSharedWild() override final;
+ Type *makeSharedWildConst() override final;
+ Type *makeMutable() override final;
+ MATCH constConv(Type *to) override;
+ unsigned char deduceWild(Type *t, bool isRef) override final;
void transitive();
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TypeBasic : public Type
+class TypeBasic final : public Type
{
public:
const char *dstring;
unsigned flags;
- const char *kind();
- TypeBasic *syntaxCopy();
- uinteger_t size(const Loc &loc) /*const*/;
- unsigned alignsize();
- bool isintegral();
- bool isfloating() /*const*/;
- bool isreal() /*const*/;
- bool isimaginary() /*const*/;
- bool iscomplex() /*const*/;
- bool isscalar() /*const*/;
- bool isunsigned() /*const*/;
- MATCH implicitConvTo(Type *to);
- bool isZeroInit(const Loc &loc) /*const*/;
+ const char *kind() override;
+ TypeBasic *syntaxCopy() override;
+ uinteger_t size(const Loc &loc) override;
+ unsigned alignsize() override;
+ bool isintegral() override;
+ bool isfloating() override;
+ bool isreal() override;
+ bool isimaginary() override;
+ bool iscomplex() override;
+ bool isscalar() override;
+ bool isunsigned() override;
+ MATCH implicitConvTo(Type *to) override;
+ bool isZeroInit(const Loc &loc) override;
// For eliminating dynamic_cast
- TypeBasic *isTypeBasic();
- void accept(Visitor *v) { v->visit(this); }
+ TypeBasic *isTypeBasic() override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TypeVector : public Type
+class TypeVector final : public Type
{
public:
Type *basetype;
static TypeVector *create(Type *basetype);
- const char *kind();
- TypeVector *syntaxCopy();
- uinteger_t size(const Loc &loc);
- unsigned alignsize();
- bool isintegral();
- bool isfloating();
- bool isscalar();
- bool isunsigned();
- bool isBoolean() /*const*/;
- MATCH implicitConvTo(Type *to);
- Expression *defaultInitLiteral(const Loc &loc);
+ const char *kind() override;
+ TypeVector *syntaxCopy() override;
+ uinteger_t size(const Loc &loc) override;
+ unsigned alignsize() override;
+ bool isintegral() override;
+ bool isfloating() override;
+ bool isscalar() override;
+ bool isunsigned() override;
+ bool isBoolean() override;
+ MATCH implicitConvTo(Type *to) override;
+ Expression *defaultInitLiteral(const Loc &loc) override;
TypeBasic *elementType();
- bool isZeroInit(const Loc &loc);
+ bool isZeroInit(const Loc &loc) override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
class TypeArray : public TypeNext
{
public:
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
// Static array, one with a fixed dimension
-class TypeSArray : public TypeArray
+class TypeSArray final : public TypeArray
{
public:
Expression *dim;
- const char *kind();
- TypeSArray *syntaxCopy();
+ const char *kind() override;
+ TypeSArray *syntaxCopy() override;
bool isIncomplete();
- uinteger_t size(const Loc &loc);
- unsigned alignsize();
- bool isString();
- bool isZeroInit(const Loc &loc);
- structalign_t alignment();
- MATCH constConv(Type *to);
- MATCH implicitConvTo(Type *to);
- Expression *defaultInitLiteral(const Loc &loc);
- bool hasPointers();
- bool hasInvariant();
- bool needsDestruction();
- bool needsCopyOrPostblit();
- bool needsNested();
-
- void accept(Visitor *v) { v->visit(this); }
+ uinteger_t size(const Loc &loc) override;
+ unsigned alignsize() override;
+ bool isString() override;
+ bool isZeroInit(const Loc &loc) override;
+ structalign_t alignment() override;
+ MATCH constConv(Type *to) override;
+ MATCH implicitConvTo(Type *to) override;
+ Expression *defaultInitLiteral(const Loc &loc) override;
+ bool hasPointers() override;
+ bool hasInvariant() override;
+ bool needsDestruction() override;
+ bool needsCopyOrPostblit() override;
+ bool needsNested() override;
+
+ void accept(Visitor *v) override { v->visit(this); }
};
// Dynamic array, no dimension
-class TypeDArray : public TypeArray
+class TypeDArray final : public TypeArray
{
public:
- const char *kind();
- TypeDArray *syntaxCopy();
- uinteger_t size(const Loc &loc) /*const*/;
- unsigned alignsize() /*const*/;
- bool isString();
- bool isZeroInit(const Loc &loc) /*const*/;
- bool isBoolean() /*const*/;
- MATCH implicitConvTo(Type *to);
- bool hasPointers() /*const*/;
+ const char *kind() override;
+ TypeDArray *syntaxCopy() override;
+ uinteger_t size(const Loc &loc) override;
+ unsigned alignsize() override;
+ bool isString() override;
+ bool isZeroInit(const Loc &loc) override;
+ bool isBoolean() override;
+ MATCH implicitConvTo(Type *to) override;
+ bool hasPointers() override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TypeAArray : public TypeArray
+class TypeAArray final : public TypeArray
{
public:
Type *index; // key type
Loc loc;
static TypeAArray *create(Type *t, Type *index);
- const char *kind();
- TypeAArray *syntaxCopy();
- uinteger_t size(const Loc &loc);
- bool isZeroInit(const Loc &loc) /*const*/;
- bool isBoolean() /*const*/;
- bool hasPointers() /*const*/;
- MATCH implicitConvTo(Type *to);
- MATCH constConv(Type *to);
+ const char *kind() override;
+ TypeAArray *syntaxCopy() override;
+ uinteger_t size(const Loc &loc) override;
+ bool isZeroInit(const Loc &loc) override;
+ bool isBoolean() override;
+ bool hasPointers() override;
+ MATCH implicitConvTo(Type *to) override;
+ MATCH constConv(Type *to) override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TypePointer : public TypeNext
+class TypePointer final : public TypeNext
{
public:
static TypePointer *create(Type *t);
- const char *kind();
- TypePointer *syntaxCopy();
- uinteger_t size(const Loc &loc) /*const*/;
- MATCH implicitConvTo(Type *to);
- MATCH constConv(Type *to);
- bool isscalar() /*const*/;
- bool isZeroInit(const Loc &loc) /*const*/;
- bool hasPointers() /*const*/;
+ const char *kind() override;
+ TypePointer *syntaxCopy() override;
+ uinteger_t size(const Loc &loc) override;
+ MATCH implicitConvTo(Type *to) override;
+ MATCH constConv(Type *to) override;
+ bool isscalar() override;
+ bool isZeroInit(const Loc &loc) override;
+ bool hasPointers() override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TypeReference : public TypeNext
+class TypeReference final : public TypeNext
{
public:
- const char *kind();
- TypeReference *syntaxCopy();
- uinteger_t size(const Loc &loc) /*const*/;
- bool isZeroInit(const Loc &loc) /*const*/;
- void accept(Visitor *v) { v->visit(this); }
+ const char *kind() override;
+ TypeReference *syntaxCopy() override;
+ uinteger_t size(const Loc &loc) override;
+ bool isZeroInit(const Loc &loc) override;
+ void accept(Visitor *v) override { v->visit(this); }
};
enum RET
@@ -556,7 +547,7 @@ enum class PURE : unsigned char
const_ = 3, // parameters are values or const
};
-class Parameter : public ASTNode
+class Parameter final : public ASTNode
{
public:
StorageClass storageClass;
@@ -570,12 +561,12 @@ public:
Parameter *syntaxCopy();
Type *isLazyArray();
// kludge for template.isType()
- DYNCAST dyncast() const { return DYNCAST_PARAMETER; }
- void accept(Visitor *v) { v->visit(this); }
+ DYNCAST dyncast() const override { return DYNCAST_PARAMETER; }
+ void accept(Visitor *v) override { v->visit(this); }
static size_t dim(Parameters *parameters);
static Parameter *getNth(Parameters *parameters, d_size_t nth);
- const char *toChars() const;
+ const char *toChars() const override;
bool isCovariant(bool returnByRef, const Parameter *p, bool previewIn) const;
};
@@ -590,7 +581,7 @@ struct ParameterList
Parameter *operator[](size_t i) { return Parameter::getNth(parameters, i); }
};
-class TypeFunction : public TypeNext
+class TypeFunction final : public TypeNext
{
public:
// .next is the return type
@@ -604,16 +595,16 @@ public:
Expressions *fargs; // function arguments
static TypeFunction *create(Parameters *parameters, Type *treturn, VarArg varargs, LINK linkage, StorageClass stc = 0);
- const char *kind();
- TypeFunction *syntaxCopy();
+ const char *kind() override;
+ TypeFunction *syntaxCopy() override;
void purityLevel();
bool hasLazyParameters();
bool isDstyleVariadic() const;
StorageClass parameterStorageClass(Parameter *p);
- Type *addStorageClass(StorageClass stc);
+ Type *addStorageClass(StorageClass stc) override;
- Type *substWildTo(unsigned mod);
- MATCH constConv(Type *to);
+ Type *substWildTo(unsigned mod) override;
+ MATCH constConv(Type *to) override;
bool isnothrow() const;
void isnothrow(bool v);
@@ -643,29 +634,29 @@ public:
void isInOutQual(bool v);
bool iswild() const;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TypeDelegate : public TypeNext
+class TypeDelegate final : public TypeNext
{
public:
// .next is a TypeFunction
static TypeDelegate *create(TypeFunction *t);
- const char *kind();
- TypeDelegate *syntaxCopy();
- Type *addStorageClass(StorageClass stc);
- uinteger_t size(const Loc &loc) /*const*/;
- unsigned alignsize() /*const*/;
- MATCH implicitConvTo(Type *to);
- bool isZeroInit(const Loc &loc) /*const*/;
- bool isBoolean() /*const*/;
- bool hasPointers() /*const*/;
+ const char *kind() override;
+ TypeDelegate *syntaxCopy() override;
+ Type *addStorageClass(StorageClass stc) override;
+ uinteger_t size(const Loc &loc) override;
+ unsigned alignsize() override;
+ MATCH implicitConvTo(Type *to) override;
+ bool isZeroInit(const Loc &loc) override;
+ bool isBoolean() override;
+ bool hasPointers() override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TypeTraits : public Type
+class TypeTraits final : public Type
{
Loc loc;
/// The expression to resolve as type or symbol.
@@ -673,23 +664,23 @@ class TypeTraits : public Type
/// Cached type/symbol after semantic analysis.
RootObject *obj;
- const char *kind();
- TypeTraits *syntaxCopy();
- uinteger_t size(const Loc &loc);
- Dsymbol *toDsymbol(Scope *sc);
- void accept(Visitor *v) { v->visit(this); }
+ const char *kind() override;
+ TypeTraits *syntaxCopy() override;
+ uinteger_t size(const Loc &loc) override;
+ Dsymbol *toDsymbol(Scope *sc) override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TypeMixin : public Type
+class TypeMixin final : public Type
{
Loc loc;
Expressions *exps;
RootObject *obj;
- const char *kind();
- TypeMixin *syntaxCopy();
- Dsymbol *toDsymbol(Scope *sc);
- void accept(Visitor *v) { v->visit(this); }
+ const char *kind() override;
+ TypeMixin *syntaxCopy() override;
+ Dsymbol *toDsymbol(Scope *sc) override;
+ void accept(Visitor *v) override { v->visit(this); }
};
class TypeQualified : public Type
@@ -704,57 +695,57 @@ public:
void addIdent(Identifier *ident);
void addInst(TemplateInstance *inst);
void addIndex(RootObject *expr);
- uinteger_t size(const Loc &loc);
+ uinteger_t size(const Loc &loc) override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TypeIdentifier : public TypeQualified
+class TypeIdentifier final : public TypeQualified
{
public:
Identifier *ident;
Dsymbol *originalSymbol; // The symbol representing this identifier, before alias resolution
static TypeIdentifier *create(const Loc &loc, Identifier *ident);
- const char *kind();
- TypeIdentifier *syntaxCopy();
- Dsymbol *toDsymbol(Scope *sc);
- void accept(Visitor *v) { v->visit(this); }
+ const char *kind() override;
+ TypeIdentifier *syntaxCopy() override;
+ Dsymbol *toDsymbol(Scope *sc) override;
+ void accept(Visitor *v) override { v->visit(this); }
};
/* Similar to TypeIdentifier, but with a TemplateInstance as the root
*/
-class TypeInstance : public TypeQualified
+class TypeInstance final : public TypeQualified
{
public:
TemplateInstance *tempinst;
- const char *kind();
- TypeInstance *syntaxCopy();
- Dsymbol *toDsymbol(Scope *sc);
- void accept(Visitor *v) { v->visit(this); }
+ const char *kind() override;
+ TypeInstance *syntaxCopy() override;
+ Dsymbol *toDsymbol(Scope *sc) override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TypeTypeof : public TypeQualified
+class TypeTypeof final : public TypeQualified
{
public:
Expression *exp;
int inuse;
- const char *kind();
- TypeTypeof *syntaxCopy();
- Dsymbol *toDsymbol(Scope *sc);
- uinteger_t size(const Loc &loc);
- void accept(Visitor *v) { v->visit(this); }
+ const char *kind() override;
+ TypeTypeof *syntaxCopy() override;
+ Dsymbol *toDsymbol(Scope *sc) override;
+ uinteger_t size(const Loc &loc) override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TypeReturn : public TypeQualified
+class TypeReturn final : public TypeQualified
{
public:
- const char *kind();
- TypeReturn *syntaxCopy();
- Dsymbol *toDsymbol(Scope *sc);
- void accept(Visitor *v) { v->visit(this); }
+ const char *kind() override;
+ TypeReturn *syntaxCopy() override;
+ Dsymbol *toDsymbol(Scope *sc) override;
+ void accept(Visitor *v) override { v->visit(this); }
};
// Whether alias this dependency is recursive or not.
@@ -769,7 +760,7 @@ enum AliasThisRec
RECtracingDT = 0x8 // mark in progress of deduceType
};
-class TypeStruct : public Type
+class TypeStruct final : public Type
{
public:
StructDeclaration *sym;
@@ -777,91 +768,91 @@ public:
bool inuse;
static TypeStruct *create(StructDeclaration *sym);
- const char *kind();
- uinteger_t size(const Loc &loc);
- unsigned alignsize();
- TypeStruct *syntaxCopy();
- Dsymbol *toDsymbol(Scope *sc);
- structalign_t alignment();
- Expression *defaultInitLiteral(const Loc &loc);
- bool isZeroInit(const Loc &loc);
- bool isAssignable();
- bool isBoolean() /*const*/;
- bool needsDestruction() /*const*/;
- bool needsCopyOrPostblit();
- bool needsNested();
- bool hasPointers();
- bool hasVoidInitPointers();
- bool hasInvariant();
- MATCH implicitConvTo(Type *to);
- MATCH constConv(Type *to);
- unsigned char deduceWild(Type *t, bool isRef);
- Type *toHeadMutable();
-
- void accept(Visitor *v) { v->visit(this); }
-};
-
-class TypeEnum : public Type
+ const char *kind() override;
+ uinteger_t size(const Loc &loc) override;
+ unsigned alignsize() override;
+ TypeStruct *syntaxCopy() override;
+ Dsymbol *toDsymbol(Scope *sc) override;
+ structalign_t alignment() override;
+ Expression *defaultInitLiteral(const Loc &loc) override;
+ bool isZeroInit(const Loc &loc) override;
+ bool isAssignable() override;
+ bool isBoolean() override;
+ bool needsDestruction() override;
+ bool needsCopyOrPostblit() override;
+ bool needsNested() override;
+ bool hasPointers() override;
+ bool hasVoidInitPointers() override;
+ bool hasInvariant() override;
+ MATCH implicitConvTo(Type *to) override;
+ MATCH constConv(Type *to) override;
+ unsigned char deduceWild(Type *t, bool isRef) override;
+ Type *toHeadMutable() override;
+
+ void accept(Visitor *v) override { v->visit(this); }
+};
+
+class TypeEnum final : public Type
{
public:
EnumDeclaration *sym;
- const char *kind();
- TypeEnum *syntaxCopy();
- uinteger_t size(const Loc &loc);
- unsigned alignsize();
+ const char *kind() override;
+ TypeEnum *syntaxCopy() override;
+ uinteger_t size(const Loc &loc) override;
+ unsigned alignsize() override;
Type *memType(const Loc &loc = Loc());
- Dsymbol *toDsymbol(Scope *sc);
- bool isintegral();
- bool isfloating();
- bool isreal();
- bool isimaginary();
- bool iscomplex();
- bool isscalar();
- bool isunsigned();
- bool isBoolean();
- bool isString();
- bool isAssignable();
- bool needsDestruction();
- bool needsCopyOrPostblit();
- bool needsNested();
- MATCH implicitConvTo(Type *to);
- MATCH constConv(Type *to);
- bool isZeroInit(const Loc &loc);
- bool hasPointers();
- bool hasVoidInitPointers();
- bool hasInvariant();
- Type *nextOf();
-
- void accept(Visitor *v) { v->visit(this); }
-};
-
-class TypeClass : public Type
+ Dsymbol *toDsymbol(Scope *sc) override;
+ bool isintegral() override;
+ bool isfloating() override;
+ bool isreal() override;
+ bool isimaginary() override;
+ bool iscomplex() override;
+ bool isscalar() override;
+ bool isunsigned() override;
+ bool isBoolean() override;
+ bool isString() override;
+ bool isAssignable() override;
+ bool needsDestruction() override;
+ bool needsCopyOrPostblit() override;
+ bool needsNested() override;
+ MATCH implicitConvTo(Type *to) override;
+ MATCH constConv(Type *to) override;
+ bool isZeroInit(const Loc &loc) override;
+ bool hasPointers() override;
+ bool hasVoidInitPointers() override;
+ bool hasInvariant() override;
+ Type *nextOf() override;
+
+ void accept(Visitor *v) override { v->visit(this); }
+};
+
+class TypeClass final : public Type
{
public:
ClassDeclaration *sym;
AliasThisRec att;
CPPMANGLE cppmangle;
- const char *kind();
- uinteger_t size(const Loc &loc) /*const*/;
- TypeClass *syntaxCopy();
- Dsymbol *toDsymbol(Scope *sc);
- ClassDeclaration *isClassHandle();
- bool isBaseOf(Type *t, int *poffset);
- MATCH implicitConvTo(Type *to);
- MATCH constConv(Type *to);
- unsigned char deduceWild(Type *t, bool isRef);
- Type *toHeadMutable();
- bool isZeroInit(const Loc &loc) /*const*/;
- bool isscope() /*const*/;
- bool isBoolean() /*const*/;
- bool hasPointers() /*const*/;
+ const char *kind() override;
+ uinteger_t size(const Loc &loc) override;
+ TypeClass *syntaxCopy() override;
+ Dsymbol *toDsymbol(Scope *sc) override;
+ ClassDeclaration *isClassHandle() override;
+ bool isBaseOf(Type *t, int *poffset) override;
+ MATCH implicitConvTo(Type *to) override;
+ MATCH constConv(Type *to) override;
+ unsigned char deduceWild(Type *t, bool isRef) override;
+ Type *toHeadMutable() override;
+ bool isZeroInit(const Loc &loc) override;
+ bool isscope() override;
+ bool isBoolean() override;
+ bool hasPointers() override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TypeTuple : public Type
+class TypeTuple final : public Type
{
public:
// 'logically immutable' cached global - don't modify (neither pointer nor pointee)!
@@ -873,56 +864,57 @@ public:
static TypeTuple *create();
static TypeTuple *create(Type *t1);
static TypeTuple *create(Type *t1, Type *t2);
- const char *kind();
- TypeTuple *syntaxCopy();
- bool equals(const RootObject *o) const;
- void accept(Visitor *v) { v->visit(this); }
+ const char *kind() override;
+ TypeTuple *syntaxCopy() override;
+ bool equals(const RootObject *o) const override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TypeSlice : public TypeNext
+class TypeSlice final : public TypeNext
{
public:
Expression *lwr;
Expression *upr;
- const char *kind();
- TypeSlice *syntaxCopy();
- void accept(Visitor *v) { v->visit(this); }
+ const char *kind() override;
+ TypeSlice *syntaxCopy() override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TypeNull : public Type
+class TypeNull final : public Type
{
public:
- const char *kind();
+ const char *kind() override;
- TypeNull *syntaxCopy();
- MATCH implicitConvTo(Type *to);
- bool isBoolean() /*const*/;
+ TypeNull *syntaxCopy() override;
+ MATCH implicitConvTo(Type *to) override;
+ bool hasPointers() override;
+ bool isBoolean() override;
- uinteger_t size(const Loc &loc) /*const*/;
- void accept(Visitor *v) { v->visit(this); }
+ uinteger_t size(const Loc &loc) override;
+ void accept(Visitor *v) override { v->visit(this); }
};
class TypeNoreturn final : public Type
{
public:
- const char *kind();
- TypeNoreturn *syntaxCopy();
- MATCH implicitConvTo(Type* to);
- MATCH constConv(Type* to);
- bool isBoolean() /* const */;
- uinteger_t size(const Loc& loc) /* const */;
- unsigned alignsize();
+ const char *kind() override;
+ TypeNoreturn *syntaxCopy() override;
+ MATCH implicitConvTo(Type* to) override;
+ MATCH constConv(Type* to) override;
+ bool isBoolean() override;
+ uinteger_t size(const Loc& loc) override;
+ unsigned alignsize() override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
class TypeTag final : public Type
{
public:
- TypeTag *syntaxCopy();
+ TypeTag *syntaxCopy() override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
/**************************************************************/
diff --git a/gcc/d/dmd/nspace.h b/gcc/d/dmd/nspace.h
index 7d6f65d..9dbbdf2 100644
--- a/gcc/d/dmd/nspace.h
+++ b/gcc/d/dmd/nspace.h
@@ -16,17 +16,17 @@
* Implies extern(C++).
*/
-class Nspace : public ScopeDsymbol
+class Nspace final : public ScopeDsymbol
{
public:
Expression *identExp;
- Nspace *syntaxCopy(Dsymbol *s);
- void addMember(Scope *sc, ScopeDsymbol *sds);
- void setScope(Scope *sc);
- Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);
- bool hasPointers();
- void setFieldOffset(AggregateDeclaration *ad, FieldState& fieldState, bool isunion);
- const char *kind() const;
- Nspace *isNspace() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ Nspace *syntaxCopy(Dsymbol *s) override;
+ void addMember(Scope *sc, ScopeDsymbol *sds) override;
+ void setScope(Scope *sc) override;
+ Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly) override;
+ bool hasPointers() override;
+ void setFieldOffset(AggregateDeclaration *ad, FieldState& fieldState, bool isunion) override;
+ const char *kind() const override;
+ Nspace *isNspace() override { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
diff --git a/gcc/d/dmd/parsetimevisitor.d b/gcc/d/dmd/parsetimevisitor.d
index 7d5e19d..387b28c 100644
--- a/gcc/d/dmd/parsetimevisitor.d
+++ b/gcc/d/dmd/parsetimevisitor.d
@@ -272,6 +272,10 @@ public:
void visit(AST.UshrAssignExp e) { visit(cast(AST.BinAssignExp)e); }
void visit(AST.CatAssignExp e) { visit(cast(AST.BinAssignExp)e); }
+ // CatAssignExp
+ void visit(AST.CatElemAssignExp e) { visit(cast(AST.CatAssignExp)e); }
+ void visit(AST.CatDcharAssignExp e) { visit(cast(AST.CatAssignExp)e); }
+
//===============================================================================
// TemplateParameter
void visit(AST.TemplateAliasParameter tp) { visit(cast(AST.TemplateParameter)tp); }
diff --git a/gcc/d/dmd/root/object.h b/gcc/d/dmd/root/object.h
index 609e763..0c92a9a 100644
--- a/gcc/d/dmd/root/object.h
+++ b/gcc/d/dmd/root/object.h
@@ -26,7 +26,9 @@ enum DYNCAST
DYNCAST_TUPLE,
DYNCAST_PARAMETER,
DYNCAST_STATEMENT,
- DYNCAST_TEMPLATEPARAMETER
+ DYNCAST_CONDITION,
+ DYNCAST_TEMPLATEPARAMETER,
+ DYNCAST_INITIALIZER
};
/*
diff --git a/gcc/d/dmd/safe.d b/gcc/d/dmd/safe.d
index 1c5275b..4446b5e 100644
--- a/gcc/d/dmd/safe.d
+++ b/gcc/d/dmd/safe.d
@@ -26,7 +26,7 @@ import dmd.identifier;
import dmd.mtype;
import dmd.target;
import dmd.tokens;
-
+import dmd.func : setUnsafe;
/*************************************************************
* Check for unsafe access in @safe code:
@@ -66,7 +66,7 @@ bool checkUnsafeAccess(Scope* sc, Expression e, bool readonly, bool printmsg)
{
if (v.overlapped)
{
- if (sc.func.setUnsafe(!printmsg, e.loc,
+ if (sc.setUnsafe(!printmsg, e.loc,
"field `%s.%s` cannot access pointers in `@safe` code that overlap other fields", ad, v))
return true;
}
@@ -76,7 +76,7 @@ bool checkUnsafeAccess(Scope* sc, Expression e, bool readonly, bool printmsg)
{
if (v.overlapped)
{
- if (sc.func.setUnsafe(!printmsg, e.loc,
+ if (sc.setUnsafe(!printmsg, e.loc,
"field `%s.%s` cannot access structs with invariants in `@safe` code that overlap other fields",
ad, v))
return true;
@@ -91,7 +91,7 @@ bool checkUnsafeAccess(Scope* sc, Expression e, bool readonly, bool printmsg)
if ((!ad.type.alignment.isDefault() && ad.type.alignment.get() < target.ptrsize ||
(v.offset & (target.ptrsize - 1))))
{
- if (sc.func.setUnsafe(!printmsg, e.loc,
+ if (sc.setUnsafe(!printmsg, e.loc,
"field `%s.%s` cannot modify misaligned pointers in `@safe` code", ad, v))
return true;
}
@@ -99,7 +99,7 @@ bool checkUnsafeAccess(Scope* sc, Expression e, bool readonly, bool printmsg)
if (v.overlapUnsafe)
{
- if (sc.func.setUnsafe(!printmsg, e.loc,
+ if (sc.setUnsafe(!printmsg, e.loc,
"field `%s.%s` cannot modify fields in `@safe` code that overlap fields with other storage classes",
ad, v))
{
@@ -211,15 +211,12 @@ bool isSafeCast(Expression e, Type tfrom, Type tto)
*/
bool checkUnsafeDotExp(Scope* sc, Expression e, Identifier id, int flag)
{
- if (!(flag & DotExpFlag.noDeref) && // this use is attempting a dereference
- sc.func && // inside a function
- !sc.intypeof && // allow unsafe code in typeof expressions
- !(sc.flags & SCOPE.debug_)) // allow unsafe code in debug statements
+ if (!(flag & DotExpFlag.noDeref)) // this use is attempting a dereference
{
if (id == Id.ptr)
- return sc.func.setUnsafe(false, e.loc, "`%s.ptr` cannot be used in `@safe` code, use `&%s[0]` instead", e, e);
+ return sc.setUnsafe(false, e.loc, "`%s.ptr` cannot be used in `@safe` code, use `&%s[0]` instead", e, e);
else
- return sc.func.setUnsafe(false, e.loc, "`%s.%s` cannot be used in `@safe` code", e, id);
+ return sc.setUnsafe(false, e.loc, "`%s.%s` cannot be used in `@safe` code", e, id);
}
return false;
}
diff --git a/gcc/d/dmd/sideeffect.d b/gcc/d/dmd/sideeffect.d
index 5691f3b..f7a3836 100644
--- a/gcc/d/dmd/sideeffect.d
+++ b/gcc/d/dmd/sideeffect.d
@@ -203,10 +203,9 @@ private bool lambdaHasSideEffect(Expression e, bool assumeImpureCalls = false)
Type t = ce.e1.type.toBasetype();
if (t.ty == Tdelegate)
t = (cast(TypeDelegate)t).next;
- if (t.ty == Tfunction && (ce.f ? callSideEffectLevel(ce.f) : callSideEffectLevel(ce.e1.type)) > 0)
- {
- }
- else
+
+ const level = t.ty == Tfunction && (ce.f ? callSideEffectLevel(ce.f) : callSideEffectLevel(ce.e1.type));
+ if (level == 0) // 0 means the function has a side effect
return true;
}
break;
@@ -251,8 +250,9 @@ bool discardValue(Expression e)
}
break; // complain
}
+ // Assumption that error => no side effect
case EXP.error:
- return false;
+ return true;
case EXP.variable:
{
VarDeclaration v = (cast(VarExp)e).var.isVarDeclaration();
@@ -356,6 +356,25 @@ bool discardValue(Expression e)
if (!hasSideEffect(e))
break;
return false;
+ case EXP.identity, EXP.notIdentity:
+ case EXP.equal, EXP.notEqual:
+ /*
+ `[side effect] == 0`
+ Technically has a side effect but is clearly wrong;
+ */
+ BinExp tmp = e.isBinExp();
+ assert(tmp);
+
+ e.error("the result of the equality expression `%s` is discarded", e.toChars());
+ bool seenSideEffect = false;
+ foreach(expr; [tmp.e1, tmp.e2])
+ {
+ if (hasSideEffect(expr)) {
+ expr.errorSupplemental("note that `%s` may have a side effect", expr.toChars());
+ seenSideEffect |= true;
+ }
+ }
+ return !seenSideEffect;
default:
break;
}
diff --git a/gcc/d/dmd/statement.d b/gcc/d/dmd/statement.d
index 7171324..0654625 100644
--- a/gcc/d/dmd/statement.d
+++ b/gcc/d/dmd/statement.d
@@ -696,7 +696,7 @@ extern (C++) final class UnrolledLoopStatement : Statement
/***********************************************************
*/
-extern (C++) class ScopeStatement : Statement
+extern (C++) final class ScopeStatement : Statement
{
Statement statement;
Loc endloc; // location of closing curly bracket
diff --git a/gcc/d/dmd/statement.h b/gcc/d/dmd/statement.h
index 66eddd8..681b481 100644
--- a/gcc/d/dmd/statement.h
+++ b/gcc/d/dmd/statement.h
@@ -109,9 +109,11 @@ public:
Loc loc;
STMT stmt;
+ DYNCAST dyncast() const override final { return DYNCAST_STATEMENT; }
+
virtual Statement *syntaxCopy();
- const char *toChars() const;
+ const char *toChars() const override final;
void error(const char *format, ...);
void warning(const char *format, ...);
@@ -159,26 +161,26 @@ public:
ForeachRangeStatement *isForeachRangeStatement() { return stmt == STMTforeachRange ? (ForeachRangeStatement*)this : NULL; }
CompoundDeclarationStatement *isCompoundDeclarationStatement() { return stmt == STMTcompoundDeclaration ? (CompoundDeclarationStatement*)this : NULL; }
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
/** Any Statement that fails semantic() or has a component that is an ErrorExp or
* a TypeError should return an ErrorStatement from semantic().
*/
-class ErrorStatement : public Statement
+class ErrorStatement final : public Statement
{
public:
- ErrorStatement *syntaxCopy();
+ ErrorStatement *syntaxCopy() override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class PeelStatement : public Statement
+class PeelStatement final : public Statement
{
public:
Statement *s;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
class ExpStatement : public Statement
@@ -187,12 +189,12 @@ public:
Expression *exp;
static ExpStatement *create(const Loc &loc, Expression *exp);
- ExpStatement *syntaxCopy();
+ ExpStatement *syntaxCopy() override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class DtorExpStatement : public ExpStatement
+class DtorExpStatement final : public ExpStatement
{
public:
/* Wraps an expression that is the destruction of 'var'
@@ -200,17 +202,17 @@ public:
VarDeclaration *var;
- DtorExpStatement *syntaxCopy();
- void accept(Visitor *v) { v->visit(this); }
+ DtorExpStatement *syntaxCopy() override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class CompileStatement : public Statement
+class CompileStatement final : public Statement
{
public:
Expressions *exps;
- CompileStatement *syntaxCopy();
- void accept(Visitor *v) { v->visit(this); }
+ CompileStatement *syntaxCopy() override;
+ void accept(Visitor *v) override { v->visit(this); }
};
class CompoundStatement : public Statement
@@ -219,60 +221,60 @@ public:
Statements *statements;
static CompoundStatement *create(const Loc &loc, Statement *s1, Statement *s2);
- CompoundStatement *syntaxCopy();
- ReturnStatement *endsWithReturnStatement();
- Statement *last();
+ CompoundStatement *syntaxCopy() override;
+ ReturnStatement *endsWithReturnStatement() override final;
+ Statement *last() override final;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class CompoundDeclarationStatement : public CompoundStatement
+class CompoundDeclarationStatement final : public CompoundStatement
{
public:
- CompoundDeclarationStatement *syntaxCopy();
- void accept(Visitor *v) { v->visit(this); }
+ CompoundDeclarationStatement *syntaxCopy() override;
+ void accept(Visitor *v) override { v->visit(this); }
};
/* The purpose of this is so that continue will go to the next
* of the statements, and break will go to the end of the statements.
*/
-class UnrolledLoopStatement : public Statement
+class UnrolledLoopStatement final : public Statement
{
public:
Statements *statements;
- UnrolledLoopStatement *syntaxCopy();
- bool hasBreak() const;
- bool hasContinue() const;
+ UnrolledLoopStatement *syntaxCopy() override;
+ bool hasBreak() const override;
+ bool hasContinue() const override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class ScopeStatement : public Statement
+class ScopeStatement final : public Statement
{
public:
Statement *statement;
Loc endloc; // location of closing curly bracket
- ScopeStatement *syntaxCopy();
- ReturnStatement *endsWithReturnStatement();
- bool hasBreak() const;
- bool hasContinue() const;
+ ScopeStatement *syntaxCopy() override;
+ ReturnStatement *endsWithReturnStatement() override;
+ bool hasBreak() const override;
+ bool hasContinue() const override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class ForwardingStatement : public Statement
+class ForwardingStatement final : public Statement
{
public:
ForwardingScopeDsymbol *sym;
Statement *statement;
- ForwardingStatement *syntaxCopy();
- void accept(Visitor *v) { v->visit(this); }
+ ForwardingStatement *syntaxCopy() override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class WhileStatement : public Statement
+class WhileStatement final : public Statement
{
public:
Parameter *param;
@@ -280,28 +282,28 @@ public:
Statement *_body;
Loc endloc; // location of closing curly bracket
- WhileStatement *syntaxCopy();
- bool hasBreak() const;
- bool hasContinue() const;
+ WhileStatement *syntaxCopy() override;
+ bool hasBreak() const override;
+ bool hasContinue() const override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class DoStatement : public Statement
+class DoStatement final : public Statement
{
public:
Statement *_body;
Expression *condition;
Loc endloc; // location of ';' after while
- DoStatement *syntaxCopy();
- bool hasBreak() const;
- bool hasContinue() const;
+ DoStatement *syntaxCopy() override;
+ bool hasBreak() const override;
+ bool hasContinue() const override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class ForStatement : public Statement
+class ForStatement final : public Statement
{
public:
Statement *_init;
@@ -315,15 +317,15 @@ public:
// treat that label as referring to this loop.
Statement *relatedLabeled;
- ForStatement *syntaxCopy();
- Statement *getRelatedLabeled() { return relatedLabeled ? relatedLabeled : this; }
- bool hasBreak() const;
- bool hasContinue() const;
+ ForStatement *syntaxCopy() override;
+ Statement *getRelatedLabeled() override { return relatedLabeled ? relatedLabeled : this; }
+ bool hasBreak() const override;
+ bool hasContinue() const override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class ForeachStatement : public Statement
+class ForeachStatement final : public Statement
{
public:
TOK op; // TOKforeach or TOKforeach_reverse
@@ -340,14 +342,14 @@ public:
Statements *cases; // put breaks, continues, gotos and returns here
ScopeStatements *gotos; // forward referenced goto's go here
- ForeachStatement *syntaxCopy();
- bool hasBreak() const;
- bool hasContinue() const;
+ ForeachStatement *syntaxCopy() override;
+ bool hasBreak() const override;
+ bool hasContinue() const override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class ForeachRangeStatement : public Statement
+class ForeachRangeStatement final : public Statement
{
public:
TOK op; // TOKforeach or TOKforeach_reverse
@@ -359,14 +361,14 @@ public:
VarDeclaration *key;
- ForeachRangeStatement *syntaxCopy();
- bool hasBreak() const;
- bool hasContinue() const;
+ ForeachRangeStatement *syntaxCopy() override;
+ bool hasBreak() const override;
+ bool hasContinue() const override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class IfStatement : public Statement
+class IfStatement final : public Statement
{
public:
Parameter *prm;
@@ -376,56 +378,56 @@ public:
VarDeclaration *match; // for MatchExpression results
Loc endloc; // location of closing curly bracket
- IfStatement *syntaxCopy();
+ IfStatement *syntaxCopy() override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class ConditionalStatement : public Statement
+class ConditionalStatement final : public Statement
{
public:
Condition *condition;
Statement *ifbody;
Statement *elsebody;
- ConditionalStatement *syntaxCopy();
+ ConditionalStatement *syntaxCopy() override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class StaticForeachStatement : public Statement
+class StaticForeachStatement final : public Statement
{
public:
StaticForeach *sfe;
- StaticForeachStatement *syntaxCopy();
+ StaticForeachStatement *syntaxCopy() override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class PragmaStatement : public Statement
+class PragmaStatement final : public Statement
{
public:
Identifier *ident;
Expressions *args; // array of Expression's
Statement *_body;
- PragmaStatement *syntaxCopy();
+ PragmaStatement *syntaxCopy() override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class StaticAssertStatement : public Statement
+class StaticAssertStatement final : public Statement
{
public:
StaticAssert *sa;
- StaticAssertStatement *syntaxCopy();
+ StaticAssertStatement *syntaxCopy() override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class SwitchStatement : public Statement
+class SwitchStatement final : public Statement
{
public:
Expression *condition;
@@ -441,13 +443,13 @@ public:
int hasVars; // !=0 if has variable case values
VarDeclaration *lastVar;
- SwitchStatement *syntaxCopy();
- bool hasBreak() const;
+ SwitchStatement *syntaxCopy() override;
+ bool hasBreak() const override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class CaseStatement : public Statement
+class CaseStatement final : public Statement
{
public:
Expression *exp;
@@ -457,110 +459,110 @@ public:
VarDeclaration *lastVar;
void* extra; // for use by Statement_toIR()
- CaseStatement *syntaxCopy();
+ CaseStatement *syntaxCopy() override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class CaseRangeStatement : public Statement
+class CaseRangeStatement final : public Statement
{
public:
Expression *first;
Expression *last;
Statement *statement;
- CaseRangeStatement *syntaxCopy();
- void accept(Visitor *v) { v->visit(this); }
+ CaseRangeStatement *syntaxCopy() override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class DefaultStatement : public Statement
+class DefaultStatement final : public Statement
{
public:
Statement *statement;
VarDeclaration *lastVar;
- DefaultStatement *syntaxCopy();
+ DefaultStatement *syntaxCopy() override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class GotoDefaultStatement : public Statement
+class GotoDefaultStatement final : public Statement
{
public:
SwitchStatement *sw;
- GotoDefaultStatement *syntaxCopy();
+ GotoDefaultStatement *syntaxCopy() override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class GotoCaseStatement : public Statement
+class GotoCaseStatement final : public Statement
{
public:
Expression *exp; // NULL, or which case to goto
CaseStatement *cs; // case statement it resolves to
- GotoCaseStatement *syntaxCopy();
+ GotoCaseStatement *syntaxCopy() override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class SwitchErrorStatement : public Statement
+class SwitchErrorStatement final : public Statement
{
public:
Expression *exp;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class ReturnStatement : public Statement
+class ReturnStatement final : public Statement
{
public:
Expression *exp;
size_t caseDim;
- ReturnStatement *syntaxCopy();
+ ReturnStatement *syntaxCopy() override;
- ReturnStatement *endsWithReturnStatement() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ ReturnStatement *endsWithReturnStatement() override { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class BreakStatement : public Statement
+class BreakStatement final : public Statement
{
public:
Identifier *ident;
- BreakStatement *syntaxCopy();
+ BreakStatement *syntaxCopy() override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class ContinueStatement : public Statement
+class ContinueStatement final : public Statement
{
public:
Identifier *ident;
- ContinueStatement *syntaxCopy();
+ ContinueStatement *syntaxCopy() override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class SynchronizedStatement : public Statement
+class SynchronizedStatement final : public Statement
{
public:
Expression *exp;
Statement *_body;
- SynchronizedStatement *syntaxCopy();
- bool hasBreak() const;
- bool hasContinue() const;
+ SynchronizedStatement *syntaxCopy() override;
+ bool hasBreak() const override;
+ bool hasContinue() const override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class WithStatement : public Statement
+class WithStatement final : public Statement
{
public:
Expression *exp;
@@ -568,12 +570,12 @@ public:
VarDeclaration *wthis;
Loc endloc;
- WithStatement *syntaxCopy();
+ WithStatement *syntaxCopy() override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TryCatchStatement : public Statement
+class TryCatchStatement final : public Statement
{
public:
Statement *_body;
@@ -581,13 +583,13 @@ public:
Statement *tryBody; /// set to enclosing TryCatchStatement or TryFinallyStatement if in _body portion
- TryCatchStatement *syntaxCopy();
- bool hasBreak() const;
+ TryCatchStatement *syntaxCopy() override;
+ bool hasBreak() const override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class Catch : public RootObject
+class Catch final : public RootObject
{
public:
Loc loc;
@@ -606,7 +608,7 @@ public:
Catch *syntaxCopy();
};
-class TryFinallyStatement : public Statement
+class TryFinallyStatement final : public Statement
{
public:
Statement *_body;
@@ -616,25 +618,25 @@ public:
bool bodyFallsThru; // true if _body falls through to finally
static TryFinallyStatement *create(const Loc &loc, Statement *body, Statement *finalbody);
- TryFinallyStatement *syntaxCopy();
- bool hasBreak() const;
- bool hasContinue() const;
+ TryFinallyStatement *syntaxCopy() override;
+ bool hasBreak() const override;
+ bool hasContinue() const override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class ScopeGuardStatement : public Statement
+class ScopeGuardStatement final : public Statement
{
public:
TOK tok;
Statement *statement;
- ScopeGuardStatement *syntaxCopy();
+ ScopeGuardStatement *syntaxCopy() override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class ThrowStatement : public Statement
+class ThrowStatement final : public Statement
{
public:
Expression *exp;
@@ -642,21 +644,21 @@ public:
// wasn't present in source code
bool internalThrow;
- ThrowStatement *syntaxCopy();
+ ThrowStatement *syntaxCopy() override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class DebugStatement : public Statement
+class DebugStatement final : public Statement
{
public:
Statement *statement;
- DebugStatement *syntaxCopy();
- void accept(Visitor *v) { v->visit(this); }
+ DebugStatement *syntaxCopy() override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class GotoStatement : public Statement
+class GotoStatement final : public Statement
{
public:
Identifier *ident;
@@ -666,12 +668,12 @@ public:
ScopeGuardStatement *os;
VarDeclaration *lastVar;
- GotoStatement *syntaxCopy();
+ GotoStatement *syntaxCopy() override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class LabelStatement : public Statement
+class LabelStatement final : public Statement
{
public:
Identifier *ident;
@@ -684,12 +686,12 @@ public:
void* extra; // used by Statement_toIR()
bool breaks; // someone did a 'break ident'
- LabelStatement *syntaxCopy();
+ LabelStatement *syntaxCopy() override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class LabelDsymbol : public Dsymbol
+class LabelDsymbol final : public Dsymbol
{
public:
LabelStatement *statement;
@@ -698,8 +700,8 @@ public:
bool iasm; // set if used by inline assembler
static LabelDsymbol *create(Identifier *ident);
- LabelDsymbol *isLabel();
- void accept(Visitor *v) { v->visit(this); }
+ LabelDsymbol *isLabel() override;
+ void accept(Visitor *v) override { v->visit(this); }
};
Statement* asmSemantic(AsmStatement *s, Scope *sc);
@@ -709,11 +711,11 @@ class AsmStatement : public Statement
public:
Token *tokens;
- AsmStatement *syntaxCopy();
- void accept(Visitor *v) { v->visit(this); }
+ AsmStatement *syntaxCopy() override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class InlineAsmStatement : public AsmStatement
+class InlineAsmStatement final : public AsmStatement
{
public:
code *asmcode;
@@ -722,12 +724,12 @@ public:
bool refparam; // true if function parameter is referenced
bool naked; // true if function is to be naked
- InlineAsmStatement *syntaxCopy();
- void accept(Visitor *v) { v->visit(this); }
+ InlineAsmStatement *syntaxCopy() override;
+ void accept(Visitor *v) override { v->visit(this); }
};
// A GCC asm statement - assembler instructions with D expression operands
-class GccAsmStatement : public AsmStatement
+class GccAsmStatement final : public AsmStatement
{
public:
StorageClass stc; // attributes of the asm {} block
@@ -740,27 +742,27 @@ public:
Identifiers *labels; // list of goto labels
GotoStatements *gotos; // of the goto labels, the equivalent statements they represent
- GccAsmStatement *syntaxCopy();
- void accept(Visitor *v) { v->visit(this); }
+ GccAsmStatement *syntaxCopy() override;
+ void accept(Visitor *v) override { v->visit(this); }
};
// a complete asm {} block
-class CompoundAsmStatement : public CompoundStatement
+class CompoundAsmStatement final : public CompoundStatement
{
public:
StorageClass stc; // postfix attributes like nothrow/pure/@trusted
- CompoundAsmStatement *syntaxCopy();
+ CompoundAsmStatement *syntaxCopy() override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class ImportStatement : public Statement
+class ImportStatement final : public Statement
{
public:
Dsymbols *imports; // Array of Import's
- ImportStatement *syntaxCopy();
+ ImportStatement *syntaxCopy() override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
diff --git a/gcc/d/dmd/statementsem.d b/gcc/d/dmd/statementsem.d
index a7ad84f..ed47b91 100644
--- a/gcc/d/dmd/statementsem.d
+++ b/gcc/d/dmd/statementsem.d
@@ -1616,9 +1616,8 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
static FuncExp foreachBodyToFunction(Scope* sc, ForeachStatement fs, TypeFunction tfld)
{
auto params = new Parameters();
- foreach (i; 0 .. fs.parameters.dim)
+ foreach (i, p; *fs.parameters)
{
- Parameter p = (*fs.parameters)[i];
StorageClass stc = STC.ref_ | (p.storageClass & STC.scope_);
Identifier id;
@@ -3929,7 +3928,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
cas.error("`asm` statement is assumed to use the GC - mark it with `@nogc` if it does not");
if (!(cas.stc & (STC.trusted | STC.safe)))
{
- sc.func.setUnsafe(false, cas.loc, "`asm` statement is assumed to be `@system` - mark it with `@trusted` if it is not");
+ sc.setUnsafe(false, cas.loc, "`asm` statement is assumed to be `@system` - mark it with `@trusted` if it is not");
}
sc.pop();
@@ -4034,9 +4033,9 @@ void catchSemantic(Catch c, Scope* sc)
error(c.loc, "catching C++ class objects not supported for this target");
c.errors = true;
}
- if (sc.func && !sc.intypeof && !c.internalCatch)
+ if (!c.internalCatch)
{
- if (sc.func.setUnsafe(false, c.loc, "cannot catch C++ class objects in `@safe` code"))
+ if (sc.setUnsafe(false, c.loc, "cannot catch C++ class objects in `@safe` code"))
c.errors = true;
}
}
@@ -4045,9 +4044,9 @@ void catchSemantic(Catch c, Scope* sc)
error(c.loc, "can only catch class objects derived from `Throwable`, not `%s`", c.type.toChars());
c.errors = true;
}
- else if (sc.func && !sc.intypeof && !c.internalCatch && ClassDeclaration.exception &&
+ else if (!c.internalCatch && ClassDeclaration.exception &&
cd != ClassDeclaration.exception && !ClassDeclaration.exception.isBaseOf(cd, null) &&
- sc.func.setUnsafe(false, c.loc,
+ sc.setUnsafe(false, c.loc,
"can only catch class objects derived from `Exception` in `@safe` code, not `%s`", c.type))
{
c.errors = true;
diff --git a/gcc/d/dmd/staticassert.h b/gcc/d/dmd/staticassert.h
index 38142bc..d938990 100644
--- a/gcc/d/dmd/staticassert.h
+++ b/gcc/d/dmd/staticassert.h
@@ -20,10 +20,10 @@ public:
Expression *exp;
Expression *msg;
- StaticAssert *syntaxCopy(Dsymbol *s);
- void addMember(Scope *sc, ScopeDsymbol *sds);
- bool oneMember(Dsymbol **ps, Identifier *ident);
- const char *kind() const;
- StaticAssert *isStaticAssert() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ StaticAssert *syntaxCopy(Dsymbol *s) override;
+ void addMember(Scope *sc, ScopeDsymbol *sds) override;
+ bool oneMember(Dsymbol **ps, Identifier *ident) override;
+ const char *kind() const override;
+ StaticAssert *isStaticAssert() override { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
diff --git a/gcc/d/dmd/template.h b/gcc/d/dmd/template.h
index 8686376..9ad027a 100644
--- a/gcc/d/dmd/template.h
+++ b/gcc/d/dmd/template.h
@@ -28,15 +28,15 @@ class Expression;
class FuncDeclaration;
class Parameter;
-class Tuple : public RootObject
+class Tuple final : public RootObject
{
public:
Objects objects;
// kludge for template.isType()
- DYNCAST dyncast() const { return DYNCAST_TUPLE; }
+ DYNCAST dyncast() const override { return DYNCAST_TUPLE; }
- const char *toChars() const { return objects.toChars(); }
+ const char *toChars() const override { return objects.toChars(); }
};
struct TemplatePrevious
@@ -46,7 +46,7 @@ struct TemplatePrevious
Objects *dedargs;
};
-class TemplateDeclaration : public ScopeDsymbol
+class TemplateDeclaration final : public ScopeDsymbol
{
public:
TemplateParameters *parameters; // array of TemplateParameter's
@@ -74,24 +74,24 @@ public:
TemplatePrevious *previous; // threaded list of previous instantiation attempts on stack
- TemplateDeclaration *syntaxCopy(Dsymbol *);
- bool overloadInsert(Dsymbol *s);
- bool hasStaticCtorOrDtor();
- const char *kind() const;
- const char *toChars() const;
+ TemplateDeclaration *syntaxCopy(Dsymbol *) override;
+ bool overloadInsert(Dsymbol *s) override;
+ bool hasStaticCtorOrDtor() override;
+ const char *kind() const override;
+ const char *toChars() const override;
- Visibility visible();
+ Visibility visible() override;
MATCH leastAsSpecialized(Scope *sc, TemplateDeclaration *td2, Expressions *fargs);
RootObject *declareParameter(Scope *sc, TemplateParameter *tp, RootObject *o);
- TemplateDeclaration *isTemplateDeclaration() { return this; }
+ TemplateDeclaration *isTemplateDeclaration() override { return this; }
TemplateTupleParameter *isVariadic();
- bool isDeprecated() const;
- bool isOverloadable() const;
+ bool isDeprecated() const override;
+ bool isOverloadable() const override;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
/* For type-parameter:
@@ -134,10 +134,12 @@ public:
virtual RootObject *defaultArg(const Loc &instLoc, Scope *sc) = 0;
virtual bool hasDefaultArg() = 0;
+ DYNCAST dyncast() const override { return DYNCAST_TEMPLATEPARAMETER; }
+
/* Create dummy argument based on parameter.
*/
virtual RootObject *dummyArg() = 0;
- void accept(Visitor *v) { v->visit(this); }
+ void accept(Visitor *v) override { v->visit(this); }
};
/* Syntax:
@@ -149,85 +151,85 @@ public:
Type *specType; // type parameter: if !=NULL, this is the type specialization
Type *defaultType;
- TemplateTypeParameter *isTemplateTypeParameter();
- TemplateTypeParameter *syntaxCopy();
- bool declareParameter(Scope *sc);
- void print(RootObject *oarg, RootObject *oded);
- RootObject *specialization();
- RootObject *defaultArg(const Loc &instLoc, Scope *sc);
- bool hasDefaultArg();
- RootObject *dummyArg();
- void accept(Visitor *v) { v->visit(this); }
+ TemplateTypeParameter *isTemplateTypeParameter() override final;
+ TemplateTypeParameter *syntaxCopy() override;
+ bool declareParameter(Scope *sc) override final;
+ void print(RootObject *oarg, RootObject *oded) override final;
+ RootObject *specialization() override final;
+ RootObject *defaultArg(const Loc &instLoc, Scope *sc) override final;
+ bool hasDefaultArg() override final;
+ RootObject *dummyArg() override final;
+ void accept(Visitor *v) override { v->visit(this); }
};
/* Syntax:
* this ident : specType = defaultType
*/
-class TemplateThisParameter : public TemplateTypeParameter
+class TemplateThisParameter final : public TemplateTypeParameter
{
public:
- TemplateThisParameter *isTemplateThisParameter();
- TemplateThisParameter *syntaxCopy();
- void accept(Visitor *v) { v->visit(this); }
+ TemplateThisParameter *isTemplateThisParameter() override;
+ TemplateThisParameter *syntaxCopy() override;
+ void accept(Visitor *v) override { v->visit(this); }
};
/* Syntax:
* valType ident : specValue = defaultValue
*/
-class TemplateValueParameter : public TemplateParameter
+class TemplateValueParameter final : public TemplateParameter
{
public:
Type *valType;
Expression *specValue;
Expression *defaultValue;
- TemplateValueParameter *isTemplateValueParameter();
- TemplateValueParameter *syntaxCopy();
- bool declareParameter(Scope *sc);
- void print(RootObject *oarg, RootObject *oded);
- RootObject *specialization();
- RootObject *defaultArg(const Loc &instLoc, Scope *sc);
- bool hasDefaultArg();
- RootObject *dummyArg();
- void accept(Visitor *v) { v->visit(this); }
+ TemplateValueParameter *isTemplateValueParameter() override;
+ TemplateValueParameter *syntaxCopy() override;
+ bool declareParameter(Scope *sc) override;
+ void print(RootObject *oarg, RootObject *oded) override;
+ RootObject *specialization() override;
+ RootObject *defaultArg(const Loc &instLoc, Scope *sc) override;
+ bool hasDefaultArg() override;
+ RootObject *dummyArg() override;
+ void accept(Visitor *v) override { v->visit(this); }
};
/* Syntax:
* specType ident : specAlias = defaultAlias
*/
-class TemplateAliasParameter : public TemplateParameter
+class TemplateAliasParameter final : public TemplateParameter
{
public:
Type *specType;
RootObject *specAlias;
RootObject *defaultAlias;
- TemplateAliasParameter *isTemplateAliasParameter();
- TemplateAliasParameter *syntaxCopy();
- bool declareParameter(Scope *sc);
- void print(RootObject *oarg, RootObject *oded);
- RootObject *specialization();
- RootObject *defaultArg(const Loc &instLoc, Scope *sc);
- bool hasDefaultArg();
- RootObject *dummyArg();
- void accept(Visitor *v) { v->visit(this); }
+ TemplateAliasParameter *isTemplateAliasParameter() override;
+ TemplateAliasParameter *syntaxCopy() override;
+ bool declareParameter(Scope *sc) override;
+ void print(RootObject *oarg, RootObject *oded) override;
+ RootObject *specialization() override;
+ RootObject *defaultArg(const Loc &instLoc, Scope *sc) override;
+ bool hasDefaultArg() override;
+ RootObject *dummyArg() override;
+ void accept(Visitor *v) override { v->visit(this); }
};
/* Syntax:
* ident ...
*/
-class TemplateTupleParameter : public TemplateParameter
+class TemplateTupleParameter final : public TemplateParameter
{
public:
- TemplateTupleParameter *isTemplateTupleParameter();
- TemplateTupleParameter *syntaxCopy();
- bool declareParameter(Scope *sc);
- void print(RootObject *oarg, RootObject *oded);
- RootObject *specialization();
- RootObject *defaultArg(const Loc &instLoc, Scope *sc);
- bool hasDefaultArg();
- RootObject *dummyArg();
- void accept(Visitor *v) { v->visit(this); }
+ TemplateTupleParameter *isTemplateTupleParameter() override;
+ TemplateTupleParameter *syntaxCopy() override;
+ bool declareParameter(Scope *sc) override;
+ void print(RootObject *oarg, RootObject *oded) override;
+ RootObject *specialization() override;
+ RootObject *defaultArg(const Loc &instLoc, Scope *sc) override;
+ bool hasDefaultArg() override;
+ RootObject *dummyArg() override;
+ void accept(Visitor *v) override { v->visit(this); }
};
/* Given:
@@ -275,36 +277,36 @@ private:
public:
unsigned char inuse; // for recursive expansion detection
- TemplateInstance *syntaxCopy(Dsymbol *);
- Dsymbol *toAlias(); // resolve real symbol
- const char *kind() const;
- bool oneMember(Dsymbol **ps, Identifier *ident);
- const char *toChars() const;
- const char* toPrettyCharsHelper();
- Identifier *getIdent();
+ TemplateInstance *syntaxCopy(Dsymbol *) override;
+ Dsymbol *toAlias() override final; // resolve real symbol
+ const char *kind() const override;
+ bool oneMember(Dsymbol **ps, Identifier *ident) override;
+ const char *toChars() const override;
+ const char* toPrettyCharsHelper() override final;
+ Identifier *getIdent() override final;
hash_t toHash();
bool isDiscardable();
bool needsCodegen();
- TemplateInstance *isTemplateInstance() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ TemplateInstance *isTemplateInstance() override final { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
-class TemplateMixin : public TemplateInstance
+class TemplateMixin final : public TemplateInstance
{
public:
TypeQualified *tqual;
- TemplateMixin *syntaxCopy(Dsymbol *s);
- const char *kind() const;
- bool oneMember(Dsymbol **ps, Identifier *ident);
- bool hasPointers();
- void setFieldOffset(AggregateDeclaration *ad, FieldState& fieldState, bool isunion);
- const char *toChars() const;
+ TemplateMixin *syntaxCopy(Dsymbol *s) override;
+ const char *kind() const override;
+ bool oneMember(Dsymbol **ps, Identifier *ident) override;
+ bool hasPointers() override;
+ void setFieldOffset(AggregateDeclaration *ad, FieldState& fieldState, bool isunion) override;
+ const char *toChars() const override;
- TemplateMixin *isTemplateMixin() { return this; }
- void accept(Visitor *v) { v->visit(this); }
+ TemplateMixin *isTemplateMixin() override { return this; }
+ void accept(Visitor *v) override { v->visit(this); }
};
Expression *isExpression(RootObject *o);
diff --git a/gcc/d/dmd/transitivevisitor.d b/gcc/d/dmd/transitivevisitor.d
index 0acad6a..25dee7f 100644
--- a/gcc/d/dmd/transitivevisitor.d
+++ b/gcc/d/dmd/transitivevisitor.d
@@ -423,12 +423,20 @@ package mixin template ParseVisitMethods(AST)
//printf("Visiting TypeQualified\n");
foreach (id; t.idents)
{
- if (id.dyncast() == DYNCAST.dsymbol)
+ switch(id.dyncast()) with(DYNCAST)
+ {
+ case dsymbol:
(cast(AST.TemplateInstance)id).accept(this);
- else if (id.dyncast() == DYNCAST.expression)
+ break;
+ case expression:
(cast(AST.Expression)id).accept(this);
- else if (id.dyncast() == DYNCAST.type)
+ break;
+ case type:
(cast(AST.Type)id).accept(this);
+ break;
+ default:
+ break;
+ }
}
}
diff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d
index ac4c23b..4c9ca28f 100644
--- a/gcc/d/dmd/typesem.d
+++ b/gcc/d/dmd/typesem.d
@@ -239,9 +239,10 @@ private void resolveHelper(TypeQualified mt, const ref Loc loc, Scope* sc, Dsymb
for (size_t i = 0; i < mt.idents.dim; i++)
{
RootObject id = mt.idents[i];
- if (id.dyncast() == DYNCAST.expression ||
- id.dyncast() == DYNCAST.type)
+ switch (id.dyncast()) with (DYNCAST)
{
+ case expression:
+ case type:
Type tx;
Expression ex;
Dsymbol sx;
@@ -259,6 +260,8 @@ private void resolveHelper(TypeQualified mt, const ref Loc loc, Scope* sc, Dsymb
ex = ex.expressionSemantic(sc);
resolveExp(ex, pt, pe, ps);
return;
+ default:
+ break;
}
Type t = s.getType(); // type symbol, type alias, or type tuple?
@@ -2799,21 +2802,20 @@ void resolve(Type mt, const ref Loc loc, Scope* sc, out Expression pe, out Type
}
RootObject o = (*tup.objects)[cast(size_t)d];
- if (o.dyncast() == DYNCAST.dsymbol)
+ switch (o.dyncast()) with (DYNCAST)
{
+ case dsymbol:
return returnSymbol(cast(Dsymbol)o);
- }
- if (o.dyncast() == DYNCAST.expression)
- {
+ case expression:
Expression e = cast(Expression)o;
if (e.op == EXP.dSymbol)
return returnSymbol(e.isDsymbolExp().s);
else
return returnExp(e);
- }
- if (o.dyncast() == DYNCAST.type)
- {
+ case type:
return returnType((cast(Type)o).addMod(mt.mod));
+ default:
+ break;
}
/* Create a new TupleDeclaration which
diff --git a/gcc/d/dmd/version.h b/gcc/d/dmd/version.h
index afc4557..b76393bc 100644
--- a/gcc/d/dmd/version.h
+++ b/gcc/d/dmd/version.h
@@ -12,30 +12,30 @@
#include "dsymbol.h"
-class DebugSymbol : public Dsymbol
+class DebugSymbol final : public Dsymbol
{
public:
unsigned level;
- DebugSymbol *syntaxCopy(Dsymbol *);
+ DebugSymbol *syntaxCopy(Dsymbol *) override;
- const char *toChars() const;
- void addMember(Scope *sc, ScopeDsymbol *sds);
- const char *kind() const;
- DebugSymbol *isDebugSymbol();
- void accept(Visitor *v) { v->visit(this); }
+ const char *toChars() const override;
+ void addMember(Scope *sc, ScopeDsymbol *sds) override;
+ const char *kind() const override;
+ DebugSymbol *isDebugSymbol() override;
+ void accept(Visitor *v) override { v->visit(this); }
};
-class VersionSymbol : public Dsymbol
+class VersionSymbol final : public Dsymbol
{
public:
unsigned level;
- VersionSymbol *syntaxCopy(Dsymbol *);
+ VersionSymbol *syntaxCopy(Dsymbol *) override;
- const char *toChars() const;
- void addMember(Scope *sc, ScopeDsymbol *sds);
- const char *kind() const;
- VersionSymbol *isVersionSymbol();
- void accept(Visitor *v) { v->visit(this); }
+ const char *toChars() const override;
+ void addMember(Scope *sc, ScopeDsymbol *sds) override;
+ const char *kind() const override;
+ VersionSymbol *isVersionSymbol() override;
+ void accept(Visitor *v) override { v->visit(this); }
};
diff --git a/gcc/d/dmd/visitor.h b/gcc/d/dmd/visitor.h
index 5d6b94c..b45ef79 100644
--- a/gcc/d/dmd/visitor.h
+++ b/gcc/d/dmd/visitor.h
@@ -265,6 +265,8 @@ class ShlAssignExp;
class ShrAssignExp;
class UshrAssignExp;
class CatAssignExp;
+class CatElemAssignExp;
+class CatDcharAssignExp;
class AddExp;
class MinExp;
class CatExp;
@@ -564,6 +566,10 @@ public:
virtual void visit(UshrAssignExp *e) { visit((BinAssignExp *)e); }
virtual void visit(CatAssignExp *e) { visit((BinAssignExp *)e); }
+ // CatAssignExp
+ virtual void visit(CatElemAssignExp *e) { visit((CatAssignExp *)e); }
+ virtual void visit(CatDcharAssignExp *e) { visit((CatAssignExp *)e); }
+
// TemplateParameter
virtual void visit(TemplateAliasParameter *tp) { visit((TemplateParameter *)tp); }
virtual void visit(TemplateTypeParameter *tp) { visit((TemplateParameter *)tp); }
diff --git a/gcc/d/lang.opt b/gcc/d/lang.opt
index c263582..954eb9a 100644
--- a/gcc/d/lang.opt
+++ b/gcc/d/lang.opt
@@ -372,6 +372,10 @@ fpreview=fixaliasthis
D RejectNegative
When a symbol is resolved, check `alias this' scope before going to upper scopes.
+fpreview=fiximmutableconv
+D RejectNegative
+Disallow unsound immutable conversions that were formerly incorrectly permitted.
+
fpreview=in
D RejectNegative
Implement 'in' parameters to mean scope const.
diff --git a/gcc/d/runtime.def b/gcc/d/runtime.def
index 534f866..1ad0369 100644
--- a/gcc/d/runtime.def
+++ b/gcc/d/runtime.def
@@ -145,10 +145,6 @@ DEF_D_RUNTIME (ARRAYAPPENDCD, "_d_arrayappendcd", RT(ARRAY_VOID),
DEF_D_RUNTIME (ARRAYAPPENDWD, "_d_arrayappendwd", RT(ARRAY_VOID),
P2(ARRAYPTR_BYTE, DCHAR), 0)
-/* Used for appending an existing array to another. */
-DEF_D_RUNTIME (ARRAYAPPENDT, "_d_arrayappendT", RT(ARRAY_VOID),
- P3(TYPEINFO, ARRAYPTR_BYTE, ARRAY_BYTE), 0)
-
/* Used for allocating a new associative array. */
DEF_D_RUNTIME (ASSOCARRAYLITERALTX, "_d_assocarrayliteralTX", RT(VOIDPTR),
P3(CONST_TYPEINFO, ARRAY_VOID, ARRAY_VOID), 0)
diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_ClassDeclaration.d b/gcc/testsuite/gdc.test/compilable/dtoh_ClassDeclaration.d
index de4c7ba..169b7b1 100644
--- a/gcc/testsuite/gdc.test/compilable/dtoh_ClassDeclaration.d
+++ b/gcc/testsuite/gdc.test/compilable/dtoh_ClassDeclaration.d
@@ -142,8 +142,8 @@ class B : public A, public I1, public I2
{
public:
using A::bar;
- void foo();
- void bar();
+ void foo() final override;
+ void bar() override;
};
class Parent
@@ -157,7 +157,7 @@ public:
class Child final : public Parent
{
public:
- void foo() /* const */;
+ void foo() override;
};
class VisitorBase
@@ -289,7 +289,7 @@ interface I2 : I1
class B : A, I1, I2
{
alias bar = A.bar;
- override void foo() {}
+ override final void foo() {}
override void bar() {}
}
@@ -303,7 +303,7 @@ class Parent
final class Child : Parent
{
extern(D) override void over() {}
- override void foo() const {}
+ override void foo() {}
}
class VisitorBase
diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_TemplateDeclaration.d b/gcc/testsuite/gdc.test/compilable/dtoh_TemplateDeclaration.d
index 35c4ed7..1e2be90 100644
--- a/gcc/testsuite/gdc.test/compilable/dtoh_TemplateDeclaration.d
+++ b/gcc/testsuite/gdc.test/compilable/dtoh_TemplateDeclaration.d
@@ -160,7 +160,7 @@ class Child final : public Parent<T >
{
public:
T childMember;
- void parentVirtual();
+ void parentVirtual() override;
T childFinal();
};
diff --git a/gcc/testsuite/gdc.test/compilable/test22865.d b/gcc/testsuite/gdc.test/compilable/test22865.d
new file mode 100644
index 0000000..0f40262
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test22865.d
@@ -0,0 +1,35 @@
+// https://issues.dlang.org/show_bug.cgi?id=22865
+
+// Test that safety errors inside speculative scopes don't affect attribute inference
+
+void main() @safe
+{
+ foo();
+}
+
+__gshared int g;
+
+auto foo()
+{
+ alias x0 = typeof(g++);
+ alias x1 = typeof(cast(int*) 0);
+
+ auto x2 = __traits(compiles, g++);
+ enum x3 = __traits(compiles, (cast(int*) 0));
+
+ debug
+ {
+ g++;
+ const x4 = cast(int*) 0;
+ asm { }
+ }
+}
+
+// Test that safety violations still occur if the function is inside the __traits(compiles)
+
+static assert(!__traits(compiles, {
+ void f() @safe
+ {
+ g++;
+ }
+}));
diff --git a/gcc/testsuite/gdc.test/fail_compilation/dip1000_deprecation.d b/gcc/testsuite/gdc.test/fail_compilation/dip1000_deprecation.d
new file mode 100644
index 0000000..bf51363
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/dip1000_deprecation.d
@@ -0,0 +1,59 @@
+/*
+REQUIRED_ARGS: -de
+TEST_OUTPUT:
+---
+fail_compilation/dip1000_deprecation.d(20): Deprecation: `@safe` function `main` calling `inferred`
+fail_compilation/dip1000_deprecation.d(28): which would be `@system` because of:
+fail_compilation/dip1000_deprecation.d(28): scope variable `x0` may not be returned
+fail_compilation/dip1000_deprecation.d(22): Deprecation: `@safe` function `main` calling `inferredC`
+fail_compilation/dip1000_deprecation.d(39): which calls `dip1000_deprecation.inferred`
+fail_compilation/dip1000_deprecation.d(28): which would be `@system` because of:
+fail_compilation/dip1000_deprecation.d(28): scope variable `x0` may not be returned
+fail_compilation/dip1000_deprecation.d(54): Deprecation: escaping reference to stack allocated value returned by `S(null)`
+fail_compilation/dip1000_deprecation.d(55): Deprecation: escaping reference to stack allocated value returned by `createS()`
+fail_compilation/dip1000_deprecation.d(58): Deprecation: returning `s.incorrectReturnRef()` escapes a reference to local variable `s`
+---
+*/
+
+void main() @safe
+{
+ inferred();
+ inferredB(); // no deprecation, trusted
+ inferredC(); // nested deprecation
+}
+
+auto inferred()
+{
+ scope int* x0;
+ return x0;
+}
+
+auto inferredB() @trusted
+{
+ scope int* x1;
+ return x1;
+}
+
+auto inferredC()
+{
+ return inferred(); // no deprecation, inferredC is not explicit `@safe`
+}
+
+@safe:
+
+struct S
+{
+ int* ptr;
+ int* incorrectReturnRef() scope return @trusted {return ptr;}
+}
+
+S createS() { return S.init; }
+
+int* escape()
+{
+ return S().incorrectReturnRef();
+ return createS().incorrectReturnRef();
+
+ S s;
+ return s.incorrectReturnRef();
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/dip25.d b/gcc/testsuite/gdc.test/fail_compilation/dip25.d
index 41bfe49..02f3140 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/dip25.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/dip25.d
@@ -19,7 +19,7 @@ struct Data
}
ref int identity(return ref int x) @safe { return x; }
-ref int fun(return int x) { return identity(x); }
+ref int fun(return int x) @safe { return identity(x); }
ref int fun2(ref int x) @safe { return identity(x); }
void main()
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail12390.d b/gcc/testsuite/gdc.test/fail_compilation/fail12390.d
index dd28163..5c852a1 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail12390.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail12390.d
@@ -1,7 +1,8 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail12390.d(14): Error: `fun().i == 4` has no effect
+fail_compilation/fail12390.d(15): Error: the result of the equality expression `fun().i == 4` is discarded
+fail_compilation/fail12390.d(15): note that `fun().i` may have a side effect
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail22351.d b/gcc/testsuite/gdc.test/fail_compilation/fail22351.d
new file mode 100644
index 0000000..405ab55
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail22351.d
@@ -0,0 +1,20 @@
+/* https://issues.dlang.org/show_bug.cgi?id=22351
+REQUIRED_ARGS: -de
+TEST_OUTPUT:
+---
+fail_compilation/fail22351.d(18): Deprecation: overriding `extern(C++)` function `fail22351.C22351.func(int*)` with `const` qualified function `fail22351.Fail22351.func(const(int*))` is deprecated
+fail_compilation/fail22351.d(18): Either remove `override`, or adjust the `const` qualifiers of the overriding function parameters
+fail_compilation/fail22351.d(19): Error: function `extern (C++) void fail22351.Fail22351.func(const(int*)**)` does not override any function, did you mean to override `extern (C++) void fail22351.C22351.func(int*)`?
+---
+*/
+extern(C++) class C22351
+{
+ void func(int*) { }
+ void func(int***) { }
+}
+
+extern(C++) final class Fail22351 : C22351
+{
+ override void func(const int*) { }
+ override void func(const(int*)**) { }
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail23135.d b/gcc/testsuite/gdc.test/fail_compilation/fail23135.d
new file mode 100644
index 0000000..d32c6ae
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail23135.d
@@ -0,0 +1,17 @@
+/* https://issues.dlang.org/show_bug.cgi?id=23135
+REQUIRED_ARGS: -de
+TEST_OUTPUT:
+---
+fail_compilation/fail23135.d(16): Deprecation: overriding `extern(C++)` function `fail23135.C23135.func()` with `const` qualified function `fail23135.Fail23135.func() const` is deprecated
+fail_compilation/fail23135.d(16): Either remove `override`, or adjust the `const` qualifiers of the overriding function type
+---
+*/
+extern(C++) class C23135
+{
+ void func() { }
+}
+
+extern(C++) final class Fail23135 : C23135
+{
+ override void func() const { }
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail_scope.d b/gcc/testsuite/gdc.test/fail_compilation/fail_scope.d
index 153e90b..3e7637f 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail_scope.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail_scope.d
@@ -13,7 +13,7 @@ fail_compilation/fail_scope.d(82): Error: returning `& string` escapes a referen
fail_compilation/fail_scope.d(92): Error: returning `cast(int[])a` escapes a reference to local variable `a`
fail_compilation/fail_scope.d(100): Error: returning `cast(int[])a` escapes a reference to local variable `a`
fail_compilation/fail_scope.d(108): Deprecation: escaping reference to outer local variable `x`
-fail_compilation/fail_scope.d(127): Error: returning `s.bar()` escapes a reference to local variable `s`
+fail_compilation/fail_scope.d(127): Deprecation: returning `s.bar()` escapes a reference to local variable `s`
fail_compilation/fail_scope.d(137): Error: returning `foo16226(i)` escapes a reference to local variable `i`
---
//fail_compilation/fail_scope.d(30): Error: scope variable `da` may not be returned
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fix22108.d b/gcc/testsuite/gdc.test/fail_compilation/fix22108.d
new file mode 100644
index 0000000..149beba
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fix22108.d
@@ -0,0 +1,13 @@
+/* REQUIRED_ARGS: -preview=dip1000
+TEST_OUTPUT:
+---
+fail_compilation/fix22108.d(12): Error: scope variable `p` may not be returned
+---
+*/
+
+// https://issues.dlang.org/show_bug.cgi?id=22108
+
+@safe ref int test(ref scope return int* p)
+{
+ return *p;
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fix23138.d b/gcc/testsuite/gdc.test/fail_compilation/fix23138.d
new file mode 100644
index 0000000..58766c8
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fix23138.d
@@ -0,0 +1,16 @@
+/* TEST_OUTPUT:
+---
+fail_compilation/fix23138.d(14): Error: function `fix23138.C2.foo` cannot override `@safe` method `fix23138.C1.foo` with a `@system` attribute
+---
+ */
+
+class C1 {
+ void foo() @safe
+ {}
+}
+
+class C2 : C1
+{
+ override void foo() @system
+ {}
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test15660.d b/gcc/testsuite/gdc.test/fail_compilation/test15660.d
index be244d7..ae573b2 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test15660.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test15660.d
@@ -1,4 +1,4 @@
-/* REQUIRED_ARGS: -preview=dip1000
+/* REQUIRED_ARGS: -preview=fixImmutableConv
TEST_OUTPUT:
---
fail_compilation/test15660.d(20): Error: cannot implicitly convert expression `f(v)` of type `int[]` to `immutable(int[])`
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test18484.d b/gcc/testsuite/gdc.test/fail_compilation/test18484.d
index d604f38..e51647b 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test18484.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test18484.d
@@ -19,7 +19,7 @@ int* test1() @safe
auto x = S(); return x.bar(); // error
}
-int* test2()
+int* test2() @safe
{
return S().bar(); // error
}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test20881.d b/gcc/testsuite/gdc.test/fail_compilation/test20881.d
index 7282635..d4c5f07 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test20881.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test20881.d
@@ -2,6 +2,7 @@
REQUIRED_ARGS: -preview=dip1000
TEST_OUTPUT:
---
+fail_compilation/test20881.d(20): Error: scope variable `this` may not be returned
fail_compilation/test20881.d(27): Error: address of variable `s` assigned to `global` with longer lifetime
fail_compilation/test20881.d(28): Error: address of variable `s` assigned to `global` with longer lifetime
fail_compilation/test20881.d(29): Error: address of variable `s` assigned to `global` with longer lifetime
@@ -10,7 +11,6 @@ fail_compilation/test20881.d(29): Error: address of variable `s` assigned to `gl
@safe:
// https://issues.dlang.org/show_bug.cgi?id=20881
-
struct S
{
int* ptr;
diff --git a/gcc/testsuite/gdc.test/runnable_cxx/extra-files/test22351.cpp b/gcc/testsuite/gdc.test/runnable_cxx/extra-files/test22351.cpp
new file mode 100644
index 0000000..ad70d0a
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable_cxx/extra-files/test22351.cpp
@@ -0,0 +1,46 @@
+#include <assert.h>
+
+class A22351
+{
+public:
+ virtual int f();
+ virtual int g(int *);
+ virtual int h();
+ virtual int h() const;
+};
+
+class B22351 : public A22351
+{
+public:
+ virtual int f() const;
+ virtual int g(const int *);
+ int h() const override;
+};
+
+B22351 *createB();
+
+int main()
+{
+ // mutable A calls functions in A vtable
+ A22351 *a = createB();
+ assert(a->f() == 1);
+ assert(a->g(0) == 3);
+ assert(a->h() == 5);
+
+ // cast to B calls functions in B vtable
+ B22351 *b = (B22351 *)a;
+ assert(b->f() == 2);
+ assert(b->g(0) == 4);
+ assert(b->h() == 6);
+
+ // cast to const calls B override function
+ const A22351 *ca = a;
+ assert(ca->h() == 6);
+
+ // const B calls functions in B vtable
+ const B22351 *cb = createB();
+ assert(cb->f() == 2);
+ assert(cb->h() == 6);
+
+ return 0;
+}
diff --git a/gcc/testsuite/gdc.test/runnable_cxx/extra-files/test23135.cpp b/gcc/testsuite/gdc.test/runnable_cxx/extra-files/test23135.cpp
new file mode 100644
index 0000000..d4193c9
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable_cxx/extra-files/test23135.cpp
@@ -0,0 +1,52 @@
+class Mutable
+{
+public:
+ virtual ~Mutable();
+ virtual void func();
+};
+
+Mutable::~Mutable()
+{
+}
+
+class DeriveMutable final : public Mutable
+{
+public:
+ virtual ~DeriveMutable();
+ void func() override;
+};
+
+DeriveMutable::~DeriveMutable()
+{
+}
+
+class Const
+{
+public:
+ virtual ~Const();
+ virtual void func() const;
+};
+
+Const::~Const()
+{
+}
+
+class DeriveConst final : public Const
+{
+public:
+ virtual ~DeriveConst();
+ void func() const override;
+};
+
+DeriveConst::~DeriveConst()
+{
+}
+
+void test23135()
+{
+ DeriveMutable mut;
+ mut.func();
+
+ DeriveConst cst;
+ cst.func();
+}
diff --git a/gcc/testsuite/gdc.test/runnable_cxx/test22351.d b/gcc/testsuite/gdc.test/runnable_cxx/test22351.d
new file mode 100644
index 0000000..1c930b6
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable_cxx/test22351.d
@@ -0,0 +1,55 @@
+// https://issues.dlang.org/show_bug.cgi?id=22351
+// EXTRA_CPP_SOURCES: test22351.cpp
+// REQUIRED_ARGS: -extern-std=c++11
+// CXXFLAGS: -std=c++11
+// DISABLED: win32
+
+extern(C++) class A22351
+{
+ int f()
+ {
+ return 1;
+ }
+
+ int g(int*)
+ {
+ return 3;
+ }
+
+ int h()
+ {
+ return 5;
+ }
+
+ int h() const
+ {
+ return 7;
+ }
+}
+
+extern(C++) class B22351 : A22351
+{
+ alias f = A22351.f;
+ alias g = A22351.g;
+ alias h = A22351.h;
+
+ int f() const
+ {
+ return 2;
+ }
+
+ int g(const(int)*)
+ {
+ return 4;
+ }
+
+ override int h() const
+ {
+ return 6;
+ }
+}
+
+extern(C++) B22351 createB()
+{
+ return new B22351;
+}
diff --git a/gcc/testsuite/gdc.test/runnable_cxx/test23135.d b/gcc/testsuite/gdc.test/runnable_cxx/test23135.d
new file mode 100644
index 0000000..4a184bb
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable_cxx/test23135.d
@@ -0,0 +1,38 @@
+// https://issues.dlang.org/show_bug.cgi?id=23135
+// EXTRA_CPP_SOURCES: test23135.cpp
+// REQUIRED_ARGS: -extern-std=c++11
+// CXXFLAGS: -std=c++11
+// DISABLED: win32
+
+void main()
+{
+ test23135();
+}
+
+extern(C++):
+
+void test23135();
+
+class Mutable
+{
+ ~this();
+ void func() { }
+}
+
+final class DeriveMutable : Mutable
+{
+ ~this();
+ override void func() { }
+}
+
+class Const
+{
+ ~this();
+ void func() const { }
+}
+
+final class DeriveConst : Const
+{
+ ~this();
+ override void func() const { }
+}