aboutsummaryrefslogtreecommitdiff
path: root/gcc/d/dmd/templateparamsem.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/d/dmd/templateparamsem.c')
-rw-r--r--gcc/d/dmd/templateparamsem.c116
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;
+}