/* Compiler implementation of the D programming language * Copyright (C) 1999-2019 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. * http://www.boost.org/LICENSE_1_0.txt * https://github.com/D-Programming-Language/dmd/blob/master/src/version.c */ #include "root/dsystem.h" #include "root/root.h" #include "identifier.h" #include "dsymbol.h" #include "cond.h" #include "version.h" #include "module.h" void checkReserved(Loc loc, const char *ident); /* ================================================== */ /* DebugSymbol's happen for statements like: * debug = identifier; * debug = integer; */ DebugSymbol::DebugSymbol(Loc loc, Identifier *ident) : Dsymbol(ident) { this->loc = loc; } DebugSymbol::DebugSymbol(Loc loc, unsigned level) : Dsymbol() { this->level = level; this->loc = loc; } const char *DebugSymbol::toChars() { if (ident) return ident->toChars(); else { OutBuffer buf; buf.printf("%d", level); return buf.extractString(); } } Dsymbol *DebugSymbol::syntaxCopy(Dsymbol *s) { assert(!s); DebugSymbol *ds = new DebugSymbol(loc, ident); ds->level = level; return ds; } void DebugSymbol::addMember(Scope *, ScopeDsymbol *sds) { //printf("DebugSymbol::addMember('%s') %s\n", sds->toChars(), toChars()); Module *m = sds->isModule(); // Do not add the member to the symbol table, // just make sure subsequent debug declarations work. if (ident) { if (!m) { error("declaration must be at module level"); errors = true; } else { if (findCondition(m->debugidsNot, ident)) { error("defined after use"); errors = true; } if (!m->debugids) m->debugids = new Strings(); m->debugids->push(ident->toChars()); } } else { if (!m) { error("level declaration must be at module level"); errors = true; } else m->debuglevel = level; } } void DebugSymbol::semantic(Scope *) { //printf("DebugSymbol::semantic() %s\n", toChars()); if (semanticRun < PASSsemanticdone) semanticRun = PASSsemanticdone; } const char *DebugSymbol::kind() const { return "debug"; } /* ================================================== */ /* VersionSymbol's happen for statements like: * version = identifier; * version = integer; */ VersionSymbol::VersionSymbol(Loc loc, Identifier *ident) : Dsymbol(ident) { this->loc = loc; } VersionSymbol::VersionSymbol(Loc loc, unsigned level) : Dsymbol() { this->level = level; this->loc = loc; } const char *VersionSymbol::toChars() { if (ident) return ident->toChars(); else { OutBuffer buf; buf.printf("%d", level); return buf.extractString(); } } Dsymbol *VersionSymbol::syntaxCopy(Dsymbol *s) { assert(!s); VersionSymbol *ds = ident ? new VersionSymbol(loc, ident) : new VersionSymbol(loc, level); return ds; } void VersionSymbol::addMember(Scope *, ScopeDsymbol *sds) { //printf("VersionSymbol::addMember('%s') %s\n", sds->toChars(), toChars()); Module *m = sds->isModule(); // Do not add the member to the symbol table, // just make sure subsequent debug declarations work. if (ident) { checkReserved(loc, ident->toChars()); if (!m) { error("declaration must be at module level"); errors = true; } else { if (findCondition(m->versionidsNot, ident)) { error("defined after use"); errors = true; } if (!m->versionids) m->versionids = new Strings(); m->versionids->push(ident->toChars()); } } else { if (!m) { error("level declaration must be at module level"); errors = true; } else m->versionlevel = level; } } void VersionSymbol::semantic(Scope *) { if (semanticRun < PASSsemanticdone) semanticRun = PASSsemanticdone; } const char *VersionSymbol::kind() const { return "version"; }