diff gcc/d/dmd/template.h @ 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/template.h	Thu Feb 13 11:34:05 2020 +0900
@@ -0,0 +1,397 @@
+
+/* 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/dlang/dmd/blob/master/src/dmd/template.h
+ */
+
+#pragma once
+
+#include "root/root.h"
+#include "arraytypes.h"
+#include "dsymbol.h"
+
+
+struct OutBuffer;
+class Identifier;
+class TemplateInstance;
+class TemplateParameter;
+class TemplateTypeParameter;
+class TemplateThisParameter;
+class TemplateValueParameter;
+class TemplateAliasParameter;
+class TemplateTupleParameter;
+class Type;
+class TypeQualified;
+class TypeTypeof;
+struct Scope;
+class Expression;
+class AliasDeclaration;
+class FuncDeclaration;
+class Parameter;
+enum MATCH;
+enum PASS;
+
+class Tuple : public RootObject
+{
+public:
+    Objects objects;
+
+    // kludge for template.isType()
+    int dyncast() const { return DYNCAST_TUPLE; }
+
+    const char *toChars() { return objects.toChars(); }
+};
+
+struct TemplatePrevious
+{
+    TemplatePrevious *prev;
+    Scope *sc;
+    Objects *dedargs;
+};
+
+class TemplateDeclaration : public ScopeDsymbol
+{
+public:
+    TemplateParameters *parameters;     // array of TemplateParameter's
+
+    TemplateParameters *origParameters; // originals for Ddoc
+    Expression *constraint;
+
+    // Hash table to look up TemplateInstance's of this TemplateDeclaration
+    void *instances;
+
+    TemplateDeclaration *overnext;      // next overloaded TemplateDeclaration
+    TemplateDeclaration *overroot;      // first in overnext list
+    FuncDeclaration *funcroot;          // first function in unified overload list
+
+    Dsymbol *onemember;         // if !=NULL then one member of this template
+
+    bool literal;               // this template declaration is a literal
+    bool ismixin;               // template declaration is only to be used as a mixin
+    bool isstatic;              // this is static template declaration
+    Prot protection;
+
+    TemplatePrevious *previous;         // threaded list of previous instantiation attempts on stack
+
+    TemplateDeclaration(Loc loc, Identifier *id, TemplateParameters *parameters,
+        Expression *constraint, Dsymbols *decldefs, bool ismixin = false, bool literal = false);
+    Dsymbol *syntaxCopy(Dsymbol *);
+    void semantic(Scope *sc);
+    bool overloadInsert(Dsymbol *s);
+    bool hasStaticCtorOrDtor();
+    const char *kind() const;
+    const char *toChars();
+
+    Prot prot();
+
+    bool evaluateConstraint(TemplateInstance *ti, Scope *sc, Scope *paramscope, Objects *dedtypes, FuncDeclaration *fd);
+
+    MATCH matchWithInstance(Scope *sc, TemplateInstance *ti, Objects *atypes, Expressions *fargs, int flag);
+    MATCH leastAsSpecialized(Scope *sc, TemplateDeclaration *td2, Expressions *fargs);
+
+    MATCH deduceFunctionTemplateMatch(TemplateInstance *ti, Scope *sc, FuncDeclaration *&fd, Type *tthis, Expressions *fargs);
+    RootObject *declareParameter(Scope *sc, TemplateParameter *tp, RootObject *o);
+    FuncDeclaration *doHeaderInstantiation(TemplateInstance *ti, Scope *sc, FuncDeclaration *fd, Type *tthis, Expressions *fargs);
+    TemplateInstance *findExistingInstance(TemplateInstance *tithis, Expressions *fargs);
+    TemplateInstance *addInstance(TemplateInstance *ti);
+    void removeInstance(TemplateInstance *handle);
+
+    TemplateDeclaration *isTemplateDeclaration() { return this; }
+
+    TemplateTupleParameter *isVariadic();
+    bool isOverloadable();
+
+    void accept(Visitor *v) { v->visit(this); }
+};
+
+/* For type-parameter:
+ *  template Foo(ident)             // specType is set to NULL
+ *  template Foo(ident : specType)
+ * For value-parameter:
+ *  template Foo(valType ident)     // specValue is set to NULL
+ *  template Foo(valType ident : specValue)
+ * For alias-parameter:
+ *  template Foo(alias ident)
+ * For this-parameter:
+ *  template Foo(this ident)
+ */
+class TemplateParameter
+{
+public:
+    Loc loc;
+    Identifier *ident;
+
+    /* True if this is a part of precedent parameter specialization pattern.
+     *
+     *  template A(T : X!TL, alias X, TL...) {}
+     *  // X and TL are dependent template parameter
+     *
+     * A dependent template parameter should return MATCHexact in matchArg()
+     * to respect the match level of the corresponding precedent parameter.
+     */
+    bool dependent;
+
+    TemplateParameter(Loc loc, Identifier *ident);
+
+    virtual TemplateTypeParameter  *isTemplateTypeParameter();
+    virtual TemplateValueParameter *isTemplateValueParameter();
+    virtual TemplateAliasParameter *isTemplateAliasParameter();
+    virtual TemplateThisParameter *isTemplateThisParameter();
+    virtual TemplateTupleParameter *isTemplateTupleParameter();
+
+    virtual TemplateParameter *syntaxCopy() = 0;
+    virtual bool declareParameter(Scope *sc) = 0;
+    virtual bool semantic(Scope *sc, TemplateParameters *parameters) = 0;
+    virtual void print(RootObject *oarg, RootObject *oded) = 0;
+    virtual RootObject *specialization() = 0;
+    virtual RootObject *defaultArg(Loc instLoc, Scope *sc) = 0;
+    virtual bool hasDefaultArg() = 0;
+
+    /* Match actual argument against parameter.
+     */
+    virtual MATCH matchArg(Loc instLoc, Scope *sc, Objects *tiargs, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
+    virtual MATCH matchArg(Scope *sc, RootObject *oarg, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam) = 0;
+
+    /* Create dummy argument based on parameter.
+     */
+    virtual void *dummyArg() = 0;
+    virtual void accept(Visitor *v) { v->visit(this); }
+};
+
+/* Syntax:
+ *  ident : specType = defaultType
+ */
+class TemplateTypeParameter : public TemplateParameter
+{
+    using TemplateParameter::matchArg;
+public:
+    Type *specType;     // type parameter: if !=NULL, this is the type specialization
+    Type *defaultType;
+
+    static Type *tdummy;
+
+    TemplateTypeParameter(Loc loc, Identifier *ident, Type *specType, Type *defaultType);
+
+    TemplateTypeParameter *isTemplateTypeParameter();
+    TemplateParameter *syntaxCopy();
+    bool declareParameter(Scope *sc);
+    bool semantic(Scope *sc, TemplateParameters *parameters);
+    void print(RootObject *oarg, RootObject *oded);
+    RootObject *specialization();
+    RootObject *defaultArg(Loc instLoc, Scope *sc);
+    bool hasDefaultArg();
+    MATCH matchArg(Scope *sc, RootObject *oarg, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
+    void *dummyArg();
+    void accept(Visitor *v) { v->visit(this); }
+};
+
+/* Syntax:
+ *  this ident : specType = defaultType
+ */
+class TemplateThisParameter : public TemplateTypeParameter
+{
+public:
+    TemplateThisParameter(Loc loc, Identifier *ident, Type *specType, Type *defaultType);
+
+    TemplateThisParameter *isTemplateThisParameter();
+    TemplateParameter *syntaxCopy();
+    void accept(Visitor *v) { v->visit(this); }
+};
+
+/* Syntax:
+ *  valType ident : specValue = defaultValue
+ */
+class TemplateValueParameter : public TemplateParameter
+{
+    using TemplateParameter::matchArg;
+public:
+    Type *valType;
+    Expression *specValue;
+    Expression *defaultValue;
+
+    static AA *edummies;
+
+    TemplateValueParameter(Loc loc, Identifier *ident, Type *valType, Expression *specValue, Expression *defaultValue);
+
+    TemplateValueParameter *isTemplateValueParameter();
+    TemplateParameter *syntaxCopy();
+    bool declareParameter(Scope *sc);
+    bool semantic(Scope *sc, TemplateParameters *parameters);
+    void print(RootObject *oarg, RootObject *oded);
+    RootObject *specialization();
+    RootObject *defaultArg(Loc instLoc, Scope *sc);
+    bool hasDefaultArg();
+    MATCH matchArg(Scope *sc, RootObject *oarg, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
+    void *dummyArg();
+    void accept(Visitor *v) { v->visit(this); }
+};
+
+/* Syntax:
+ *  specType ident : specAlias = defaultAlias
+ */
+class TemplateAliasParameter : public TemplateParameter
+{
+    using TemplateParameter::matchArg;
+public:
+    Type *specType;
+    RootObject *specAlias;
+    RootObject *defaultAlias;
+
+    static Dsymbol *sdummy;
+
+    TemplateAliasParameter(Loc loc, Identifier *ident, Type *specType, RootObject *specAlias, RootObject *defaultAlias);
+
+    TemplateAliasParameter *isTemplateAliasParameter();
+    TemplateParameter *syntaxCopy();
+    bool declareParameter(Scope *sc);
+    bool semantic(Scope *sc, TemplateParameters *parameters);
+    void print(RootObject *oarg, RootObject *oded);
+    RootObject *specialization();
+    RootObject *defaultArg(Loc instLoc, Scope *sc);
+    bool hasDefaultArg();
+    MATCH matchArg(Scope *sc, RootObject *oarg, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
+    void *dummyArg();
+    void accept(Visitor *v) { v->visit(this); }
+};
+
+/* Syntax:
+ *  ident ...
+ */
+class TemplateTupleParameter : public TemplateParameter
+{
+public:
+    TemplateTupleParameter(Loc loc, Identifier *ident);
+
+    TemplateTupleParameter *isTemplateTupleParameter();
+    TemplateParameter *syntaxCopy();
+    bool declareParameter(Scope *sc);
+    bool semantic(Scope *sc, TemplateParameters *parameters);
+    void print(RootObject *oarg, RootObject *oded);
+    RootObject *specialization();
+    RootObject *defaultArg(Loc instLoc, Scope *sc);
+    bool hasDefaultArg();
+    MATCH matchArg(Loc loc, Scope *sc, Objects *tiargs, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
+    MATCH matchArg(Scope *sc, RootObject *oarg, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
+    void *dummyArg();
+    void accept(Visitor *v) { v->visit(this); }
+};
+
+/* Given:
+ *  foo!(args) =>
+ *      name = foo
+ *      tiargs = args
+ */
+class TemplateInstance : public ScopeDsymbol
+{
+public:
+    Identifier *name;
+
+    // Array of Types/Expressions of template
+    // instance arguments [int*, char, 10*10]
+    Objects *tiargs;
+
+    // Array of Types/Expressions corresponding
+    // to TemplateDeclaration.parameters
+    // [int, char, 100]
+    Objects tdtypes;
+
+    Dsymbol *tempdecl;                  // referenced by foo.bar.abc
+    Dsymbol *enclosing;                 // if referencing local symbols, this is the context
+    Dsymbol *aliasdecl;                 // !=NULL if instance is an alias for its sole member
+    TemplateInstance *inst;             // refer to existing instance
+    ScopeDsymbol *argsym;               // argument symbol table
+    int inuse;                          // for recursive expansion detection
+    int nest;                           // for recursive pretty printing detection
+    bool semantictiargsdone;            // has semanticTiargs() been done?
+    bool havetempdecl;                  // if used second constructor
+    bool gagged;                        // if the instantiation is done with error gagging
+    hash_t hash;                        // cached result of toHash()
+    Expressions *fargs;                 // for function template, these are the function arguments
+
+    TemplateInstances* deferred;
+
+    Module *memberOf;                   // if !null, then this TemplateInstance appears in memberOf.members[]
+
+    // Used to determine the instance needs code generation.
+    // Note that these are inaccurate until semantic analysis phase completed.
+    TemplateInstance *tinst;            // enclosing template instance
+    TemplateInstance *tnext;            // non-first instantiated instances
+    Module *minst;                      // the top module that instantiated this instance
+
+    TemplateInstance(Loc loc, Identifier *temp_id);
+    TemplateInstance(Loc loc, TemplateDeclaration *tempdecl, Objects *tiargs);
+    static Objects *arraySyntaxCopy(Objects *objs);
+    Dsymbol *syntaxCopy(Dsymbol *);
+    void semantic(Scope *sc, Expressions *fargs);
+    void semantic(Scope *sc);
+    void semantic2(Scope *sc);
+    void semantic3(Scope *sc);
+    Dsymbol *toAlias();                 // resolve real symbol
+    const char *kind() const;
+    bool oneMember(Dsymbol **ps, Identifier *ident);
+    const char *toChars();
+    const char* toPrettyCharsHelper();
+    void printInstantiationTrace();
+    Identifier *getIdent();
+    int compare(RootObject *o);
+    hash_t toHash();
+
+    bool needsCodegen();
+
+    // Internal
+    bool findTempDecl(Scope *sc, WithScopeSymbol **pwithsym);
+    bool updateTempDecl(Scope *sc, Dsymbol *s);
+    static bool semanticTiargs(Loc loc, Scope *sc, Objects *tiargs, int flags);
+    bool semanticTiargs(Scope *sc);
+    bool findBestMatch(Scope *sc, Expressions *fargs);
+    bool needsTypeInference(Scope *sc, int flag = 0);
+    bool hasNestedArgs(Objects *tiargs, bool isstatic);
+    Dsymbols *appendToModuleMember();
+    void declareParameters(Scope *sc);
+    Identifier *genIdent(Objects *args);
+    void expandMembers(Scope *sc);
+    void tryExpandMembers(Scope *sc);
+    void trySemantic3(Scope *sc2);
+
+    TemplateInstance *isTemplateInstance() { return this; }
+    void accept(Visitor *v) { v->visit(this); }
+};
+
+class TemplateMixin : public TemplateInstance
+{
+public:
+    TypeQualified *tqual;
+
+    TemplateMixin(Loc loc, Identifier *ident, TypeQualified *tqual, Objects *tiargs);
+    Dsymbol *syntaxCopy(Dsymbol *s);
+    void semantic(Scope *sc);
+    void semantic2(Scope *sc);
+    void semantic3(Scope *sc);
+    const char *kind() const;
+    bool oneMember(Dsymbol **ps, Identifier *ident);
+    int apply(Dsymbol_apply_ft_t fp, void *param);
+    bool hasPointers();
+    void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion);
+    const char *toChars();
+
+    bool findTempDecl(Scope *sc);
+
+    TemplateMixin *isTemplateMixin() { return this; }
+    void accept(Visitor *v) { v->visit(this); }
+};
+
+Expression *isExpression(RootObject *o);
+Dsymbol *isDsymbol(RootObject *o);
+Type *isType(RootObject *o);
+Tuple *isTuple(RootObject *o);
+Parameter *isParameter(RootObject *o);
+bool arrayObjectIsError(Objects *args);
+bool isError(RootObject *o);
+Type *getType(RootObject *o);
+Dsymbol *getDsymbol(RootObject *o);
+
+RootObject *objectSyntaxCopy(RootObject *o);