blob: d3e9b2390e924c1f5ae09c6605f33ae507ad9adb [file] [log] [blame]
/* 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;
}