]>
git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/d/dmd/cond.c
2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2018 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/cond.c
13 #include <string.h> // strcmp()
18 #include "declaration.h"
19 #include "identifier.h"
20 #include "expression.h"
26 #include "arraytypes.h"
29 Expression
*semantic(Expression
*e
, Scope
*sc
);
30 bool evalStaticCondition(Scope
*sc
, Expression
*exp
, Expression
*e
, bool &errors
);
32 int findCondition(Strings
*ids
, Identifier
*ident
)
36 for (size_t i
= 0; i
< ids
->dim
; i
++)
38 const char *id
= (*ids
)[i
];
40 if (strcmp(id
, ident
->toChars()) == 0)
48 /* ============================================================ */
50 Condition::Condition(Loc loc
)
56 /* ============================================================ */
58 DVCondition::DVCondition(Module
*mod
, unsigned level
, Identifier
*ident
)
66 Condition
*DVCondition::syntaxCopy()
68 return this; // don't need to copy
71 /* ============================================================ */
73 void DebugCondition::setGlobalLevel(unsigned level
)
75 global
.params
.debuglevel
= level
;
78 void DebugCondition::addGlobalIdent(const char *ident
)
80 if (!global
.params
.debugids
)
81 global
.params
.debugids
= new Strings();
82 global
.params
.debugids
->push(ident
);
86 DebugCondition::DebugCondition(Module
*mod
, unsigned level
, Identifier
*ident
)
87 : DVCondition(mod
, level
, ident
)
91 // Helper for printing dependency information
92 void printDepsConditional(Scope
*sc
, DVCondition
* condition
, const char* depType
)
94 if (!global
.params
.moduleDeps
|| global
.params
.moduleDepsFile
)
96 OutBuffer
*ob
= global
.params
.moduleDeps
;
97 Module
* imod
= sc
? sc
->instantiatingModule() : condition
->mod
;
100 ob
->writestring(depType
);
101 ob
->writestring(imod
->toPrettyChars());
102 ob
->writestring(" (");
103 escapePath(ob
, imod
->srcfile
->toChars());
104 ob
->writestring(") : ");
105 if (condition
->ident
)
106 ob
->printf("%s\n", condition
->ident
->toChars());
108 ob
->printf("%d\n", condition
->level
);
112 int DebugCondition::include(Scope
*sc
, ScopeDsymbol
*)
114 //printf("DebugCondition::include() level = %d, debuglevel = %d\n", level, global.params.debuglevel);
118 bool definedInModule
= false;
121 if (findCondition(mod
->debugids
, ident
))
124 definedInModule
= true;
126 else if (findCondition(global
.params
.debugids
, ident
))
129 { if (!mod
->debugidsNot
)
130 mod
->debugidsNot
= new Strings();
131 mod
->debugidsNot
->push(ident
->toChars());
134 else if (level
<= global
.params
.debuglevel
|| level
<= mod
->debuglevel
)
136 if (!definedInModule
)
137 printDepsConditional(sc
, this, "depsDebug ");
142 /* ============================================================ */
144 void VersionCondition::setGlobalLevel(unsigned level
)
146 global
.params
.versionlevel
= level
;
149 static bool isReserved(const char *ident
)
151 static const char* reserved
[] =
221 "CRuntime_Digitalmars",
223 "CRuntime_Microsoft",
227 "D_InlineAsm_X86_64",
243 for (unsigned i
= 0; reserved
[i
]; i
++)
245 if (strcmp(ident
, reserved
[i
]) == 0)
249 if (ident
[0] == 'D' && ident
[1] == '_')
254 void checkReserved(Loc loc
, const char *ident
)
256 if (isReserved(ident
))
257 error(loc
, "version identifier '%s' is reserved and cannot be set", ident
);
260 void VersionCondition::addGlobalIdent(const char *ident
)
262 checkReserved(Loc(), ident
);
263 addPredefinedGlobalIdent(ident
);
266 void VersionCondition::addPredefinedGlobalIdent(const char *ident
)
268 if (!global
.params
.versionids
)
269 global
.params
.versionids
= new Strings();
270 global
.params
.versionids
->push(ident
);
274 VersionCondition::VersionCondition(Module
*mod
, unsigned level
, Identifier
*ident
)
275 : DVCondition(mod
, level
, ident
)
279 int VersionCondition::include(Scope
*sc
, ScopeDsymbol
*)
281 //printf("VersionCondition::include() level = %d, versionlevel = %d\n", level, global.params.versionlevel);
282 //if (ident) printf("\tident = '%s'\n", ident->toChars());
286 bool definedInModule
=false;
289 if (findCondition(mod
->versionids
, ident
))
292 definedInModule
= true;
294 else if (findCondition(global
.params
.versionids
, ident
))
298 if (!mod
->versionidsNot
)
299 mod
->versionidsNot
= new Strings();
300 mod
->versionidsNot
->push(ident
->toChars());
303 else if (level
<= global
.params
.versionlevel
|| level
<= mod
->versionlevel
)
305 if (!definedInModule
&& (!ident
|| (!isReserved(ident
->toChars()) && ident
!= Id::_unittest
&& ident
!= Id::_assert
)))
306 printDepsConditional(sc
, this, "depsVersion ");
311 /**************************** StaticIfCondition *******************************/
313 StaticIfCondition::StaticIfCondition(Loc loc
, Expression
*exp
)
320 Condition
*StaticIfCondition::syntaxCopy()
322 return new StaticIfCondition(loc
, exp
->syntaxCopy());
325 int StaticIfCondition::include(Scope
*sc
, ScopeDsymbol
*sds
)
329 if (exp
->op
== TOKerror
|| nest
> 100)
331 error(loc
, (nest
> 1000) ? "unresolvable circular static if expression"
332 : "error evaluating static if expression");
338 error(loc
, "static if conditional cannot be at global scope");
344 sc
= sc
->push(sc
->scopesym
);
345 sc
->sds
= sds
; // sds gets any addMember()
348 bool result
= evalStaticCondition(sc
, exp
, exp
, errors
);
352 // Prevent repeated condition evaluation.
353 // See: fail_compilation/fail7815.d
367 inc
= 2; // so we don't see the error message again