diff options
Diffstat (limited to 'gcc/d/dmd/attrib.c')
-rw-r--r-- | gcc/d/dmd/attrib.c | 471 |
1 files changed, 8 insertions, 463 deletions
diff --git a/gcc/d/dmd/attrib.c b/gcc/d/dmd/attrib.c index 5445b9e..56b8ce8 100644 --- a/gcc/d/dmd/attrib.c +++ b/gcc/d/dmd/attrib.c @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 1999-2020 by The D Language Foundation, All Rights Reserved + * Copyright (C) 1999-2021 by The D Language Foundation, All Rights Reserved * written by Walter Bright * http://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. @@ -29,8 +29,6 @@ #include "mtype.h" bool definitelyValueParameter(Expression *e); -Expression *semantic(Expression *e, Scope *sc); -StringExp *semanticString(Scope *sc, Expression *exp, const char *s); Dsymbols *makeTupleForeachStaticDecl(Scope *sc, ForeachStatement *fs, Dsymbols *dbody, bool needExpansion); /********************************* AttribDeclaration ****************************/ @@ -169,68 +167,6 @@ void AttribDeclaration::importAll(Scope *sc) } } -void AttribDeclaration::semantic(Scope *sc) -{ - if (semanticRun != PASSinit) - return; - semanticRun = PASSsemantic; - Dsymbols *d = include(sc); - - //printf("\tAttribDeclaration::semantic '%s', d = %p\n",toChars(), d); - if (d) - { - Scope *sc2 = newScope(sc); - - for (size_t i = 0; i < d->length; i++) - { - Dsymbol *s = (*d)[i]; - s->semantic(sc2); - } - - if (sc2 != sc) - sc2->pop(); - } - semanticRun = PASSsemanticdone; -} - -void AttribDeclaration::semantic2(Scope *sc) -{ - Dsymbols *d = include(sc); - - if (d) - { - Scope *sc2 = newScope(sc); - - for (size_t i = 0; i < d->length; i++) - { - Dsymbol *s = (*d)[i]; - s->semantic2(sc2); - } - - if (sc2 != sc) - sc2->pop(); - } -} - -void AttribDeclaration::semantic3(Scope *sc) -{ - Dsymbols *d = include(sc); - - if (d) - { - Scope *sc2 = newScope(sc); - - for (size_t i = 0; i < d->length; i++) - { - Dsymbol *s = (*d)[i]; - s->semantic3(sc2); - } - - if (sc2 != sc) - sc2->pop(); - } -} - void AttribDeclaration::addComment(const utf8_t *comment) { //printf("AttribDeclaration::addComment %s\n", comment); @@ -474,22 +410,6 @@ void DeprecatedDeclaration::setScope(Scope *sc) return AttribDeclaration::setScope(sc); } -/** - * Run the DeprecatedDeclaration's semantic2 phase then its members. - * - * The message set via a `DeprecatedDeclaration` can be either of: - * - a string literal - * - an enum - * - a static immutable - * So we need to call ctfe to resolve it. - * Afterward forwards to the members' semantic2. - */ -void DeprecatedDeclaration::semantic2(Scope *sc) -{ - getMessage(); - StorageClassDeclaration::semantic2(sc); -} - const char *DeprecatedDeclaration::getMessage() { if (Scope *sc = _scope) @@ -497,7 +417,7 @@ const char *DeprecatedDeclaration::getMessage() _scope = NULL; sc = sc->startCTFE(); - msg = ::semantic(msg, sc); + msg = expressionSemantic(msg, sc); msg = resolveProperties(sc, msg); sc = sc->endCTFE(); msg = msg->ctfeInterpret(); @@ -505,7 +425,7 @@ const char *DeprecatedDeclaration::getMessage() if (StringExp *se = msg->toStringExp()) msgstr = (char *)se->string; else - msg->error("compile time constant expected, not '%s'", msg->toChars()); + msg->error("compile time constant expected, not `%s`", msg->toChars()); } return msgstr; } @@ -613,7 +533,7 @@ Dsymbol *ProtDeclaration::syntaxCopy(Dsymbol *s) Scope *ProtDeclaration::newScope(Scope *sc) { if (pkg_identifiers) - semantic(sc); + dsymbolSemantic(this, sc); return createNewScope(sc, sc->stc, sc->linkage, sc->cppmangle, this->protection, 1, sc->aligndecl, sc->inlining); @@ -634,7 +554,7 @@ void ProtDeclaration::addMember(Scope *sc, ScopeDsymbol *sds) Module *m = sc->_module; Package* pkg = m->parent ? m->parent->isPackage() : NULL; if (!pkg || !protection.pkg->isAncestorPackageOf(pkg)) - error("does not bind to one of ancestor packages of module '%s'", + error("does not bind to one of ancestor packages of module `%s`", m->toPrettyChars(true)); } @@ -682,12 +602,6 @@ Scope *AlignDeclaration::newScope(Scope *sc) sc->inlining); } -void AlignDeclaration::semantic2(Scope *sc) -{ - getAlignment(sc); - AttribDeclaration::semantic2(sc); -} - structalign_t AlignDeclaration::getAlignment(Scope *sc) { if (salign != 0) @@ -697,7 +611,7 @@ structalign_t AlignDeclaration::getAlignment(Scope *sc) return salign = STRUCTALIGN_DEFAULT; sc = sc->startCTFE(); - ealign = ::semantic(ealign, sc); + ealign = expressionSemantic(ealign, sc); ealign = resolveProperties(sc, ealign); sc = sc->endCTFE(); ealign = ealign->ctfeInterpret(); @@ -744,38 +658,6 @@ void AnonDeclaration::setScope(Scope *sc) AttribDeclaration::setScope(sc); } -void AnonDeclaration::semantic(Scope *sc) -{ - //printf("\tAnonDeclaration::semantic %s %p\n", isunion ? "union" : "struct", this); - - assert(sc->parent); - - Dsymbol *p = sc->parent->pastMixin(); - AggregateDeclaration *ad = p->isAggregateDeclaration(); - if (!ad) - { - ::error(loc, "%s can only be a part of an aggregate, not %s %s", - kind(), p->kind(), p->toChars()); - errors = true; - return; - } - - if (decl) - { - sc = sc->push(); - sc->stc &= ~(STCauto | STCscope | STCstatic | STCtls | STCgshared); - sc->inunion = isunion; - sc->flags = 0; - - for (size_t i = 0; i < decl->length; i++) - { - Dsymbol *s = (*decl)[i]; - s->semantic(sc); - } - sc = sc->pop(); - } -} - void AnonDeclaration::setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion) { //printf("\tAnonDeclaration::setFieldOffset %s %p\n", isunion ? "union" : "struct", this); @@ -916,269 +798,6 @@ Scope *PragmaDeclaration::newScope(Scope *sc) return sc; } -static unsigned setMangleOverride(Dsymbol *s, char *sym) -{ - AttribDeclaration *ad = s->isAttribDeclaration(); - - if (ad) - { - Dsymbols *decls = ad->include(NULL); - unsigned nestedCount = 0; - - if (decls && decls->length) - for (size_t i = 0; i < decls->length; ++i) - nestedCount += setMangleOverride((*decls)[i], sym); - - return nestedCount; - } - else if (s->isFuncDeclaration() || s->isVarDeclaration()) - { - s->isDeclaration()->mangleOverride = sym; - return 1; - } - else - return 0; -} - -void PragmaDeclaration::semantic(Scope *sc) -{ - // Should be merged with PragmaStatement - - //printf("\tPragmaDeclaration::semantic '%s'\n",toChars()); - if (ident == Id::msg) - { - if (args) - { - for (size_t i = 0; i < args->length; i++) - { - Expression *e = (*args)[i]; - - sc = sc->startCTFE(); - e = ::semantic(e, sc); - e = resolveProperties(sc, e); - sc = sc->endCTFE(); - - // pragma(msg) is allowed to contain types as well as expressions - e = ctfeInterpretForPragmaMsg(e); - if (e->op == TOKerror) - { - errorSupplemental(loc, "while evaluating pragma(msg, %s)", (*args)[i]->toChars()); - return; - } - StringExp *se = e->toStringExp(); - if (se) - { - se = se->toUTF8(sc); - fprintf(stderr, "%.*s", (int)se->len, (char *)se->string); - } - else - fprintf(stderr, "%s", e->toChars()); - } - fprintf(stderr, "\n"); - } - goto Lnodecl; - } - else if (ident == Id::lib) - { - if (!args || args->length != 1) - error("string expected for library name"); - else - { - StringExp *se = semanticString(sc, (*args)[0], "library name"); - if (!se) - goto Lnodecl; - (*args)[0] = se; - - char *name = (char *)mem.xmalloc(se->len + 1); - memcpy(name, se->string, se->len); - name[se->len] = 0; - if (global.params.verbose) - message("library %s", name); - if (global.params.moduleDeps && !global.params.moduleDepsFile.length) - { - OutBuffer *ob = global.params.moduleDeps; - Module *imod = sc->instantiatingModule(); - ob->writestring("depsLib "); - ob->writestring(imod->toPrettyChars()); - ob->writestring(" ("); - escapePath(ob, imod->srcfile->toChars()); - ob->writestring(") : "); - ob->writestring((char *) name); - ob->writenl(); - } - mem.xfree(name); - } - goto Lnodecl; - } - else if (ident == Id::startaddress) - { - if (!args || args->length != 1) - error("function name expected for start address"); - else - { - /* Bugzilla 11980: - * resolveProperties and ctfeInterpret call are not necessary. - */ - Expression *e = (*args)[0]; - - sc = sc->startCTFE(); - e = ::semantic(e, sc); - sc = sc->endCTFE(); - - (*args)[0] = e; - Dsymbol *sa = getDsymbol(e); - if (!sa || !sa->isFuncDeclaration()) - error("function name expected for start address, not '%s'", e->toChars()); - } - goto Lnodecl; - } - else if (ident == Id::Pinline) - { - goto Ldecl; - } - else if (ident == Id::mangle) - { - if (!args) - args = new Expressions(); - if (args->length != 1) - { - error("string expected for mangled name"); - args->setDim(1); - (*args)[0] = new ErrorExp(); // error recovery - goto Ldecl; - } - - StringExp *se = semanticString(sc, (*args)[0], "mangled name"); - if (!se) - goto Ldecl; - (*args)[0] = se; // Will be used for later - - if (!se->len) - { - error("zero-length string not allowed for mangled name"); - goto Ldecl; - } - if (se->sz != 1) - { - error("mangled name characters can only be of type char"); - goto Ldecl; - } - - /* Note: D language specification should not have any assumption about backend - * implementation. Ideally pragma(mangle) can accept a string of any content. - * - * Therefore, this validation is compiler implementation specific. - */ - for (size_t i = 0; i < se->len; ) - { - utf8_t *p = (utf8_t *)se->string; - dchar_t c = p[i]; - if (c < 0x80) - { - if ((c >= 'A' && c <= 'Z') || - (c >= 'a' && c <= 'z') || - (c >= '0' && c <= '9') || - (c != 0 && strchr("$%().:?@[]_", c))) - { - ++i; - continue; - } - else - { - error("char 0x%02x not allowed in mangled name", c); - break; - } - } - - if (const char* msg = utf_decodeChar((utf8_t *)se->string, se->len, &i, &c)) - { - error("%s", msg); - break; - } - - if (!isUniAlpha(c)) - { - error("char 0x%04x not allowed in mangled name", c); - break; - } - } - } - else if (global.params.ignoreUnsupportedPragmas) - { - if (global.params.verbose) - { - /* Print unrecognized pragmas - */ - OutBuffer buf; - buf.writestring(ident->toChars()); - if (args) - { - for (size_t i = 0; i < args->length; i++) - { - Expression *e = (*args)[i]; - - sc = sc->startCTFE(); - e = ::semantic(e, sc); - e = resolveProperties(sc, e); - sc = sc->endCTFE(); - - e = e->ctfeInterpret(); - if (i == 0) - buf.writestring(" ("); - else - buf.writeByte(','); - buf.writestring(e->toChars()); - } - if (args->length) - buf.writeByte(')'); - } - message("pragma %s", buf.peekChars()); - } - goto Lnodecl; - } - else - error("unrecognized pragma(%s)", ident->toChars()); - -Ldecl: - if (decl) - { - Scope *sc2 = newScope(sc); - - for (size_t i = 0; i < decl->length; i++) - { - Dsymbol *s = (*decl)[i]; - - s->semantic(sc2); - - if (ident == Id::mangle) - { - assert(args && args->length == 1); - if (StringExp *se = (*args)[0]->toStringExp()) - { - char *name = (char *)mem.xmalloc(se->len + 1); - memcpy(name, se->string, se->len); - name[se->len] = 0; - - unsigned cnt = setMangleOverride(s, name); - if (cnt > 1) - error("can only apply to a single declaration"); - } - } - } - - if (sc2 != sc) - sc2->pop(); - } - return; - -Lnodecl: - if (decl) - { - error("pragma is missing closing ';'"); - goto Ldecl; // do them anyway, to avoid segfaults. - } -} - const char *PragmaDeclaration::kind() const { return "pragma"; @@ -1374,11 +993,6 @@ void StaticIfDeclaration::setScope(Scope *sc) Dsymbol::setScope(sc); } -void StaticIfDeclaration::semantic(Scope *sc) -{ - AttribDeclaration::semantic(sc); -} - const char *StaticIfDeclaration::kind() const { return "static if"; @@ -1491,11 +1105,6 @@ void StaticForeachDeclaration::importAll(Scope *) // do not evaluate aggregate before semantic pass } -void StaticForeachDeclaration::semantic(Scope *sc) -{ - AttribDeclaration::semantic(sc); -} - const char *StaticForeachDeclaration::kind() const { return "static foreach"; @@ -1582,50 +1191,6 @@ void CompileDeclaration::setScope(Scope *sc) Dsymbol::setScope(sc); } -void CompileDeclaration::compileIt(Scope *sc) -{ - //printf("CompileDeclaration::compileIt(loc = %d) %s\n", loc.linnum, exp->toChars()); - StringExp *se = semanticString(sc, exp, "argument to mixin"); - if (!se) - return; - se = se->toUTF8(sc); - - unsigned errors = global.errors; - Parser p(loc, sc->_module, (utf8_t *)se->string, se->len, 0); - p.nextToken(); - - decl = p.parseDeclDefs(0); - if (p.token.value != TOKeof) - exp->error("incomplete mixin declaration (%s)", se->toChars()); - if (p.errors) - { - assert(global.errors != errors); - decl = NULL; - } -} - -void CompileDeclaration::semantic(Scope *sc) -{ - //printf("CompileDeclaration::semantic()\n"); - - if (!compiled) - { - compileIt(sc); - AttribDeclaration::addMember(sc, scopesym); - compiled = true; - - if (_scope && decl) - { - for (size_t i = 0; i < decl->length; i++) - { - Dsymbol *s = (*decl)[i]; - s->setScope(_scope); - } - } - } - AttribDeclaration::semantic(sc); -} - const char *CompileDeclaration::kind() const { return "mixin"; @@ -1670,23 +1235,14 @@ void UserAttributeDeclaration::setScope(Scope *sc) return AttribDeclaration::setScope(sc); } -void UserAttributeDeclaration::semantic(Scope *sc) -{ - //printf("UserAttributeDeclaration::semantic() %p\n", this); - if (decl && !_scope) - Dsymbol::setScope(sc); // for function local symbols - - return AttribDeclaration::semantic(sc); -} - -static void udaExpressionEval(Scope *sc, Expressions *exps) +void udaExpressionEval(Scope *sc, Expressions *exps) { for (size_t i = 0; i < exps->length; i++) { Expression *e = (*exps)[i]; if (e) { - e = ::semantic(e, sc); + e = expressionSemantic(e, sc); if (definitelyValueParameter(e)) e = e->ctfeInterpret(); if (e->op == TOKtuple) @@ -1699,17 +1255,6 @@ static void udaExpressionEval(Scope *sc, Expressions *exps) } } -void UserAttributeDeclaration::semantic2(Scope *sc) -{ - if (decl && atts && atts->length && _scope) - { - _scope = NULL; - udaExpressionEval(sc, atts); - } - - AttribDeclaration::semantic2(sc); -} - Expressions *UserAttributeDeclaration::concat(Expressions *udas1, Expressions *udas2) { Expressions *udas; |