From f42cc3b4d8b55a4dc3e75eb97e73ea82b8696f34 Mon Sep 17 00:00:00 2001 From: Walter Bright Date: Thu, 14 Jan 2016 18:21:13 -0800 Subject: [PATCH] fix Issue 15565 - Forward reference error with namespaces --- src/nspace.d | 62 ++++++++++++++++++++++++++----------- test/compilable/test15565.d | 3 ++ 2 files changed, 47 insertions(+), 18 deletions(-) create mode 100644 test/compilable/test15565.d diff --git a/src/nspace.d b/src/nspace.d index 8a9d52137fa9..60299edac95d 100644 --- a/src/nspace.d +++ b/src/nspace.d @@ -41,21 +41,9 @@ public: return ScopeDsymbol.syntaxCopy(ns); } - override void semantic(Scope* sc) + override void addMember(Scope* sc, ScopeDsymbol sds) { - if (semanticRun >= PASSsemantic) - return; - semanticRun = PASSsemantic; - static if (LOG) - { - printf("+Nspace::semantic('%s')\n", toChars()); - } - if (_scope) - { - sc = _scope; - _scope = null; - } - parent = sc.parent; + ScopeDsymbol.addMember(sc, sds); if (members) { if (!symtab) @@ -63,26 +51,64 @@ public: // The namespace becomes 'imported' into the enclosing scope for (Scope* sce = sc; 1; sce = sce.enclosing) { - ScopeDsymbol sds = cast(ScopeDsymbol)sce.scopesym; - if (sds) + ScopeDsymbol sds2 = cast(ScopeDsymbol)sce.scopesym; + if (sds2) { - sds.importScope(this, Prot(PROTpublic)); + sds2.importScope(this, Prot(PROTpublic)); break; } } assert(sc); sc = sc.push(this); - sc.linkage = LINKcpp; // note that namespaces imply C++ linkage + sc.linkage = LINKcpp; // namespaces default to C++ linkage sc.parent = this; foreach (s; *members) { //printf("add %s to scope %s\n", s->toChars(), toChars()); s.addMember(sc, this); } + sc.pop(); + } + } + + override void setScope(Scope* sc) + { + ScopeDsymbol.setScope(sc); + if (members) + { + assert(sc); + sc = sc.push(this); + sc.linkage = LINKcpp; // namespaces default to C++ linkage + sc.parent = this; foreach (s; *members) { s.setScope(sc); } + sc.pop(); + } + } + + override void semantic(Scope* sc) + { + if (semanticRun >= PASSsemantic) + return; + semanticRun = PASSsemantic; + static if (LOG) + { + printf("+Nspace::semantic('%s')\n", toChars()); + } + if (_scope) + { + sc = _scope; + _scope = null; + } + parent = sc.parent; + if (members) + { + assert(sc); + sc = sc.push(this); + sc.linkage = LINKcpp; // note that namespaces imply C++ linkage + sc.parent = this; foreach (s; *members) { s.importAll(sc); diff --git a/test/compilable/test15565.d b/test/compilable/test15565.d new file mode 100644 index 000000000000..4beb900d977d --- /dev/null +++ b/test/compilable/test15565.d @@ -0,0 +1,3 @@ +alias X2 = X; +extern (C++, ns) struct X {} +