Mercurial > hg > CbC > CbC_gcc
diff gcc/d/dmd/staticcond.c @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gcc/d/dmd/staticcond.c Thu Feb 13 11:34:05 2020 +0900 @@ -0,0 +1,100 @@ + +/* Compiler implementation of the D programming language + * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved + * written by Walter Bright + * http://www.digitalmars.com + * Distributed under the Boost Software License, Version 1.0. + * http://www.boost.org/LICENSE_1_0.txt + * https://github.com/D-Programming-Language/dmd/blob/master/src/staticcond.c + */ + +#include "mars.h" +#include "expression.h" +#include "mtype.h" +#include "scope.h" + +Expression *semantic(Expression *e, Scope *sc); + +/******************************************** + * Semantically analyze and then evaluate a static condition at compile time. + * This is special because short circuit operators &&, || and ?: at the top + * level are not semantically analyzed if the result of the expression is not + * necessary. + * Params: + * exp = original expression, for error messages + * Returns: + * true if evaluates to true + */ + +bool evalStaticCondition(Scope *sc, Expression *exp, Expression *e, bool &errors) +{ + if (e->op == TOKandand) + { + AndAndExp *aae = (AndAndExp *)e; + bool result = evalStaticCondition(sc, exp, aae->e1, errors); + if (errors || !result) + return false; + result = evalStaticCondition(sc, exp, aae->e2, errors); + return !errors && result; + } + + if (e->op == TOKoror) + { + OrOrExp *ooe = (OrOrExp *)e; + bool result = evalStaticCondition(sc, exp, ooe->e1, errors); + if (errors) + return false; + if (result) + return true; + result = evalStaticCondition(sc, exp, ooe->e2, errors); + return !errors && result; + } + + if (e->op == TOKquestion) + { + CondExp *ce = (CondExp *)e; + bool result = evalStaticCondition(sc, exp, ce->econd, errors); + if (errors) + return false; + Expression *leg = result ? ce->e1 : ce->e2; + result = evalStaticCondition(sc, exp, leg, errors); + return !errors && result; + } + + unsigned nerrors = global.errors; + + sc = sc->startCTFE(); + sc->flags |= SCOPEcondition; + + e = semantic(e, sc); + e = resolveProperties(sc, e); + + sc = sc->endCTFE(); + e = e->optimize(WANTvalue); + + if (nerrors != global.errors || + e->op == TOKerror || + e->type->toBasetype() == Type::terror) + { + errors = true; + return false; + } + + if (!e->type->isBoolean()) + { + exp->error("expression %s of type %s does not have a boolean value", exp->toChars(), e->type->toChars()); + errors = true; + return false; + } + + e = e->ctfeInterpret(); + + if (e->isBool(true)) + return true; + else if (e->isBool(false)) + return false; + + e->error("expression %s is not constant", e->toChars()); + errors = true; + return false; +}