]>
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-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/cond.c
11 #include "root/dsystem.h" // strcmp()
16 #include "declaration.h"
17 #include "identifier.h"
18 #include "expression.h"
24 #include "arraytypes.h"
27 Expression
*semantic(Expression
*e
, Scope
*sc
);
28 bool evalStaticCondition(Scope
*sc
, Expression
*exp
, Expression
*e
, bool &errors
);
30 int findCondition(Strings
*ids
, Identifier
*ident
)
34 for (size_t i
= 0; i
< ids
->dim
; i
++)
36 const char *id
= (*ids
)[i
];
38 if (strcmp(id
, ident
->toChars()) == 0)
46 /* ============================================================ */
48 Condition::Condition(Loc loc
)
54 /* ============================================================ */
56 DVCondition::DVCondition(Module
*mod
, unsigned level
, Identifier
*ident
)
64 Condition
*DVCondition::syntaxCopy()
66 return this; // don't need to copy
69 /* ============================================================ */
71 void DebugCondition::setGlobalLevel(unsigned level
)
73 global
.params
.debuglevel
= level
;
76 void DebugCondition::addGlobalIdent(const char *ident
)
78 if (!global
.params
.debugids
)
79 global
.params
.debugids
= new Strings();
80 global
.params
.debugids
->push(ident
);
84 DebugCondition::DebugCondition(Module
*mod
, unsigned level
, Identifier
*ident
)
85 : DVCondition(mod
, level
, ident
)
89 // Helper for printing dependency information
90 void printDepsConditional(Scope
*sc
, DVCondition
* condition
, const char* depType
)
92 if (!global
.params
.moduleDeps
|| global
.params
.moduleDepsFile
)
94 OutBuffer
*ob
= global
.params
.moduleDeps
;
95 Module
* imod
= sc
? sc
->instantiatingModule() : condition
->mod
;
98 ob
->writestring(depType
);
99 ob
->writestring(imod
->toPrettyChars());
100 ob
->writestring(" (");
101 escapePath(ob
, imod
->srcfile
->toChars());
102 ob
->writestring(") : ");
103 if (condition
->ident
)
104 ob
->printf("%s\n", condition
->ident
->toChars());
106 ob
->printf("%d\n", condition
->level
);
110 int DebugCondition::include(Scope
*sc
, ScopeDsymbol
*)
112 //printf("DebugCondition::include() level = %d, debuglevel = %d\n", level, global.params.debuglevel);
116 bool definedInModule
= false;
119 if (findCondition(mod
->debugids
, ident
))
122 definedInModule
= true;
124 else if (findCondition(global
.params
.debugids
, ident
))
127 { if (!mod
->debugidsNot
)
128 mod
->debugidsNot
= new Strings();
129 mod
->debugidsNot
->push(ident
->toChars());
132 else if (level
<= global
.params
.debuglevel
|| level
<= mod
->debuglevel
)
134 if (!definedInModule
)
135 printDepsConditional(sc
, this, "depsDebug ");
140 /* ============================================================ */
142 void VersionCondition::setGlobalLevel(unsigned level
)
144 global
.params
.versionlevel
= level
;
147 static bool isReserved(const char *ident
)
149 static const char* reserved
[] =
219 "CRuntime_Digitalmars",
221 "CRuntime_Microsoft",
225 "D_InlineAsm_X86_64",
241 for (unsigned i
= 0; reserved
[i
]; i
++)
243 if (strcmp(ident
, reserved
[i
]) == 0)
247 if (ident
[0] == 'D' && ident
[1] == '_')
252 void checkReserved(Loc loc
, const char *ident
)
254 if (isReserved(ident
))
255 error(loc
, "version identifier '%s' is reserved and cannot be set", ident
);
258 void VersionCondition::addGlobalIdent(const char *ident
)
260 checkReserved(Loc(), ident
);
261 addPredefinedGlobalIdent(ident
);
264 void VersionCondition::addPredefinedGlobalIdent(const char *ident
)
266 if (!global
.params
.versionids
)
267 global
.params
.versionids
= new Strings();
268 global
.params
.versionids
->push(ident
);
272 VersionCondition::VersionCondition(Module
*mod
, unsigned level
, Identifier
*ident
)
273 : DVCondition(mod
, level
, ident
)
277 int VersionCondition::include(Scope
*sc
, ScopeDsymbol
*)
279 //printf("VersionCondition::include() level = %d, versionlevel = %d\n", level, global.params.versionlevel);
280 //if (ident) printf("\tident = '%s'\n", ident->toChars());
284 bool definedInModule
=false;
287 if (findCondition(mod
->versionids
, ident
))
290 definedInModule
= true;
292 else if (findCondition(global
.params
.versionids
, ident
))
296 if (!mod
->versionidsNot
)
297 mod
->versionidsNot
= new Strings();
298 mod
->versionidsNot
->push(ident
->toChars());
301 else if (level
<= global
.params
.versionlevel
|| level
<= mod
->versionlevel
)
303 if (!definedInModule
&& (!ident
|| (!isReserved(ident
->toChars()) && ident
!= Id::_unittest
&& ident
!= Id::_assert
)))
304 printDepsConditional(sc
, this, "depsVersion ");
309 /**************************** StaticIfCondition *******************************/
311 StaticIfCondition::StaticIfCondition(Loc loc
, Expression
*exp
)
318 Condition
*StaticIfCondition::syntaxCopy()
320 return new StaticIfCondition(loc
, exp
->syntaxCopy());
323 int StaticIfCondition::include(Scope
*sc
, ScopeDsymbol
*sds
)
327 if (exp
->op
== TOKerror
|| nest
> 100)
329 error(loc
, (nest
> 1000) ? "unresolvable circular static if expression"
330 : "error evaluating static if expression");
336 error(loc
, "static if conditional cannot be at global scope");
342 sc
= sc
->push(sc
->scopesym
);
343 sc
->sds
= sds
; // sds gets any addMember()
346 bool result
= evalStaticCondition(sc
, exp
, exp
, errors
);
350 // Prevent repeated condition evaluation.
351 // See: fail_compilation/fail7815.d
365 inc
= 2; // so we don't see the error message again