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
DebugSymbol(Loc loc,Identifier * ident)29 DebugSymbol::DebugSymbol(Loc loc, Identifier *ident)
30 : Dsymbol(ident)
31 {
32 this->loc = loc;
33 }
34
DebugSymbol(Loc loc,unsigned level)35 DebugSymbol::DebugSymbol(Loc loc, unsigned level)
36 : Dsymbol()
37 {
38 this->level = level;
39 this->loc = loc;
40 }
41
toChars()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
syntaxCopy(Dsymbol * s)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
addMember(Scope *,ScopeDsymbol * sds)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
semantic(Scope *)100 void DebugSymbol::semantic(Scope *)
101 {
102 //printf("DebugSymbol::semantic() %s\n", toChars());
103 if (semanticRun < PASSsemanticdone)
104 semanticRun = PASSsemanticdone;
105 }
106
kind()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
VersionSymbol(Loc loc,Identifier * ident)119 VersionSymbol::VersionSymbol(Loc loc, Identifier *ident)
120 : Dsymbol(ident)
121 {
122 this->loc = loc;
123 }
124
VersionSymbol(Loc loc,unsigned level)125 VersionSymbol::VersionSymbol(Loc loc, unsigned level)
126 : Dsymbol()
127 {
128 this->level = level;
129 this->loc = loc;
130 }
131
toChars()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
syntaxCopy(Dsymbol * s)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
addMember(Scope *,ScopeDsymbol * sds)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
semantic(Scope *)191 void VersionSymbol::semantic(Scope *)
192 {
193 if (semanticRun < PASSsemanticdone)
194 semanticRun = PASSsemanticdone;
195 }
196
kind()197 const char *VersionSymbol::kind() const
198 {
199 return "version";
200 }
201