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