diff options
Diffstat (limited to 'gcc/d/dmd/templateparamsem.c')
-rw-r--r-- | gcc/d/dmd/templateparamsem.c | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/gcc/d/dmd/templateparamsem.c b/gcc/d/dmd/templateparamsem.c new file mode 100644 index 0000000..11cd52e --- /dev/null +++ b/gcc/d/dmd/templateparamsem.c @@ -0,0 +1,116 @@ + +/* Compiler implementation of the D programming language + * Copyright (C) 1999-2021 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 + */ + +#include "template.h" +#include "mtype.h" +#include "scope.h" +#include "visitor.h" + +bool reliesOnTident(Type *t, TemplateParameters *tparams = NULL, size_t iStart = 0); + +class TemplateParameterSemanticVisitor : public Visitor +{ +public: + Scope *sc; + TemplateParameters *parameters; + bool result; + + TemplateParameterSemanticVisitor(Scope *sc, TemplateParameters *parameters) + { + this->sc = sc; + this->parameters = parameters; + this->result = false; + } + + void visit(TemplateTypeParameter *ttp) + { + //printf("TemplateTypeParameter::semantic('%s')\n", ident->toChars()); + if (ttp->specType && !reliesOnTident(ttp->specType, parameters)) + { + ttp->specType = typeSemantic(ttp->specType, ttp->loc, sc); + } + result = !(ttp->specType && isError(ttp->specType)); + } + + void visit(TemplateValueParameter *tvp) + { + tvp->valType = typeSemantic(tvp->valType, tvp->loc, sc); + + result = !isError(tvp->valType); + } + + void visit(TemplateAliasParameter *tap) + { + if (tap->specType && !reliesOnTident(tap->specType, parameters)) + { + tap->specType = typeSemantic(tap->specType, tap->loc, sc); + } + tap->specAlias = aliasParameterSemantic(tap->loc, sc, tap->specAlias, parameters); + result = !(tap->specType && isError(tap->specType)) && + !(tap->specAlias && isError(tap->specAlias)); + } + + void visit(TemplateTupleParameter *) + { + result = true; + } +}; + +/************************************************ + * Performs semantic on TemplateParameter AST nodes. + * + * Params: + * tp = element of `parameters` to be semantically analyzed + * sc = context + * parameters = array of `TemplateParameters` supplied to the `TemplateDeclaration` + * Returns: + * `true` if no errors + */ +bool tpsemantic(TemplateParameter *tp, Scope *sc, TemplateParameters *parameters) +{ + TemplateParameterSemanticVisitor v(sc, parameters); + tp->accept(&v); + return v.result; +} + +/*********************************************** + * Support function for performing semantic analysis on `TemplateAliasParameter`. + * + * Params: + * loc = location (for error messages) + * sc = context + * o = object to run semantic() on, the `TemplateAliasParameter`s `specAlias` or `defaultAlias` + * parameters = array of `TemplateParameters` supplied to the `TemplateDeclaration` + * Returns: + * object resulting from running `semantic` on `o` + */ +RootObject *aliasParameterSemantic(Loc loc, Scope *sc, RootObject *o, TemplateParameters *parameters) +{ + if (o) + { + Expression *ea = isExpression(o); + Type *ta = isType(o); + if (ta && (!parameters || !reliesOnTident(ta, parameters))) + { + Dsymbol *s = ta->toDsymbol(sc); + if (s) + o = s; + else + o = typeSemantic(ta, loc, sc); + } + else if (ea) + { + sc = sc->startCTFE(); + ea = expressionSemantic(ea, sc); + sc = sc->endCTFE(); + o = ea->ctfeInterpret(); + } + } + return o; +} |