1 2 /* Compiler implementation of the D programming language 3 * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved 4 * written by Walter Bright 5 * http://www.digitalmars.com 6 * Distributed under the Boost Software License, Version 1.0. 7 * http://www.boost.org/LICENSE_1_0.txt 8 * https://github.com/D-Programming-Language/dmd/blob/master/src/version.c 9 */ 10 11 #include "root/dsystem.h" 12 #include "root/root.h" 13 14 #include "identifier.h" 15 #include "dsymbol.h" 16 #include "cond.h" 17 #include "version.h" 18 #include "module.h" 19 20 void checkReserved(Loc loc, const char *ident); 21 22 /* ================================================== */ 23 24 /* DebugSymbol's happen for statements like: 25 * debug = identifier; 26 * debug = integer; 27 */ 28 29 DebugSymbol::DebugSymbol(Loc loc, Identifier *ident) 30 : Dsymbol(ident) 31 { 32 this->loc = loc; 33 } 34 35 DebugSymbol::DebugSymbol(Loc loc, unsigned level) 36 : Dsymbol() 37 { 38 this->level = level; 39 this->loc = loc; 40 } 41 42 const char *DebugSymbol::toChars() 43 { 44 if (ident) 45 return ident->toChars(); 46 else 47 { 48 OutBuffer buf; 49 buf.printf("%d", level); 50 return buf.extractString(); 51 } 52 } 53 54 Dsymbol *DebugSymbol::syntaxCopy(Dsymbol *s) 55 { 56 assert(!s); 57 DebugSymbol *ds = new DebugSymbol(loc, ident); 58 ds->level = level; 59 return ds; 60 } 61 62 void DebugSymbol::addMember(Scope *, ScopeDsymbol *sds) 63 { 64 //printf("DebugSymbol::addMember('%s') %s\n", sds->toChars(), toChars()); 65 Module *m = sds->isModule(); 66 67 // Do not add the member to the symbol table, 68 // just make sure subsequent debug declarations work. 69 if (ident) 70 { 71 if (!m) 72 { 73 error("declaration must be at module level"); 74 errors = true; 75 } 76 else 77 { 78 if (findCondition(m->debugidsNot, ident)) 79 { 80 error("defined after use"); 81 errors = true; 82 } 83 if (!m->debugids) 84 m->debugids = new Strings(); 85 m->debugids->push(ident->toChars()); 86 } 87 } 88 else 89 { 90 if (!m) 91 { 92 error("level declaration must be at module level"); 93 errors = true; 94 } 95 else 96 m->debuglevel = level; 97 } 98 } 99 100 void DebugSymbol::semantic(Scope *) 101 { 102 //printf("DebugSymbol::semantic() %s\n", toChars()); 103 if (semanticRun < PASSsemanticdone) 104 semanticRun = PASSsemanticdone; 105 } 106 107 const char *DebugSymbol::kind() const 108 { 109 return "debug"; 110 } 111 112 /* ================================================== */ 113 114 /* VersionSymbol's happen for statements like: 115 * version = identifier; 116 * version = integer; 117 */ 118 119 VersionSymbol::VersionSymbol(Loc loc, Identifier *ident) 120 : Dsymbol(ident) 121 { 122 this->loc = loc; 123 } 124 125 VersionSymbol::VersionSymbol(Loc loc, unsigned level) 126 : Dsymbol() 127 { 128 this->level = level; 129 this->loc = loc; 130 } 131 132 const char *VersionSymbol::toChars() 133 { 134 if (ident) 135 return ident->toChars(); 136 else 137 { 138 OutBuffer buf; 139 buf.printf("%d", level); 140 return buf.extractString(); 141 } 142 } 143 144 Dsymbol *VersionSymbol::syntaxCopy(Dsymbol *s) 145 { 146 assert(!s); 147 VersionSymbol *ds = ident ? new VersionSymbol(loc, ident) 148 : new VersionSymbol(loc, level); 149 return ds; 150 } 151 152 void VersionSymbol::addMember(Scope *, ScopeDsymbol *sds) 153 { 154 //printf("VersionSymbol::addMember('%s') %s\n", sds->toChars(), toChars()); 155 Module *m = sds->isModule(); 156 157 // Do not add the member to the symbol table, 158 // just make sure subsequent debug declarations work. 159 if (ident) 160 { 161 checkReserved(loc, ident->toChars()); 162 if (!m) 163 { 164 error("declaration must be at module level"); 165 errors = true; 166 } 167 else 168 { 169 if (findCondition(m->versionidsNot, ident)) 170 { 171 error("defined after use"); 172 errors = true; 173 } 174 if (!m->versionids) 175 m->versionids = new Strings(); 176 m->versionids->push(ident->toChars()); 177 } 178 } 179 else 180 { 181 if (!m) 182 { 183 error("level declaration must be at module level"); 184 errors = true; 185 } 186 else 187 m->versionlevel = level; 188 } 189 } 190 191 void VersionSymbol::semantic(Scope *) 192 { 193 if (semanticRun < PASSsemanticdone) 194 semanticRun = PASSsemanticdone; 195 } 196 197 const char *VersionSymbol::kind() const 198 { 199 return "version"; 200 } 201