| |
| /* 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; |
| } |