Mercurial > hg > CbC > CbC_gcc
comparison gcc/d/dmd/staticcond.c @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
131:84e7813d76e9 | 145:1830386684a0 |
---|---|
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/staticcond.c | |
9 */ | |
10 | |
11 #include "mars.h" | |
12 #include "expression.h" | |
13 #include "mtype.h" | |
14 #include "scope.h" | |
15 | |
16 Expression *semantic(Expression *e, Scope *sc); | |
17 | |
18 /******************************************** | |
19 * Semantically analyze and then evaluate a static condition at compile time. | |
20 * This is special because short circuit operators &&, || and ?: at the top | |
21 * level are not semantically analyzed if the result of the expression is not | |
22 * necessary. | |
23 * Params: | |
24 * exp = original expression, for error messages | |
25 * Returns: | |
26 * true if evaluates to true | |
27 */ | |
28 | |
29 bool evalStaticCondition(Scope *sc, Expression *exp, Expression *e, bool &errors) | |
30 { | |
31 if (e->op == TOKandand) | |
32 { | |
33 AndAndExp *aae = (AndAndExp *)e; | |
34 bool result = evalStaticCondition(sc, exp, aae->e1, errors); | |
35 if (errors || !result) | |
36 return false; | |
37 result = evalStaticCondition(sc, exp, aae->e2, errors); | |
38 return !errors && result; | |
39 } | |
40 | |
41 if (e->op == TOKoror) | |
42 { | |
43 OrOrExp *ooe = (OrOrExp *)e; | |
44 bool result = evalStaticCondition(sc, exp, ooe->e1, errors); | |
45 if (errors) | |
46 return false; | |
47 if (result) | |
48 return true; | |
49 result = evalStaticCondition(sc, exp, ooe->e2, errors); | |
50 return !errors && result; | |
51 } | |
52 | |
53 if (e->op == TOKquestion) | |
54 { | |
55 CondExp *ce = (CondExp *)e; | |
56 bool result = evalStaticCondition(sc, exp, ce->econd, errors); | |
57 if (errors) | |
58 return false; | |
59 Expression *leg = result ? ce->e1 : ce->e2; | |
60 result = evalStaticCondition(sc, exp, leg, errors); | |
61 return !errors && result; | |
62 } | |
63 | |
64 unsigned nerrors = global.errors; | |
65 | |
66 sc = sc->startCTFE(); | |
67 sc->flags |= SCOPEcondition; | |
68 | |
69 e = semantic(e, sc); | |
70 e = resolveProperties(sc, e); | |
71 | |
72 sc = sc->endCTFE(); | |
73 e = e->optimize(WANTvalue); | |
74 | |
75 if (nerrors != global.errors || | |
76 e->op == TOKerror || | |
77 e->type->toBasetype() == Type::terror) | |
78 { | |
79 errors = true; | |
80 return false; | |
81 } | |
82 | |
83 if (!e->type->isBoolean()) | |
84 { | |
85 exp->error("expression %s of type %s does not have a boolean value", exp->toChars(), e->type->toChars()); | |
86 errors = true; | |
87 return false; | |
88 } | |
89 | |
90 e = e->ctfeInterpret(); | |
91 | |
92 if (e->isBool(true)) | |
93 return true; | |
94 else if (e->isBool(false)) | |
95 return false; | |
96 | |
97 e->error("expression %s is not constant", e->toChars()); | |
98 errors = true; | |
99 return false; | |
100 } |