Home | History | Annotate | Line # | Download | only in dmd
      1      1.1  mrg 
      2      1.1  mrg /* Compiler implementation of the D programming language
      3  1.1.1.2  mrg  * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
      4      1.1  mrg  * written by Walter Bright
      5  1.1.1.2  mrg  * https://www.digitalmars.com
      6      1.1  mrg  * Distributed under the Boost Software License, Version 1.0.
      7  1.1.1.2  mrg  * https://www.boost.org/LICENSE_1_0.txt
      8      1.1  mrg  * https://github.com/dlang/dmd/blob/master/src/dmd/template.h
      9      1.1  mrg  */
     10      1.1  mrg 
     11      1.1  mrg #pragma once
     12      1.1  mrg 
     13      1.1  mrg #include "arraytypes.h"
     14      1.1  mrg #include "dsymbol.h"
     15      1.1  mrg 
     16      1.1  mrg class Identifier;
     17      1.1  mrg class TemplateInstance;
     18      1.1  mrg class TemplateParameter;
     19      1.1  mrg class TemplateTypeParameter;
     20      1.1  mrg class TemplateThisParameter;
     21      1.1  mrg class TemplateValueParameter;
     22      1.1  mrg class TemplateAliasParameter;
     23      1.1  mrg class TemplateTupleParameter;
     24      1.1  mrg class Type;
     25      1.1  mrg class TypeQualified;
     26      1.1  mrg struct Scope;
     27      1.1  mrg class Expression;
     28      1.1  mrg class FuncDeclaration;
     29      1.1  mrg class Parameter;
     30      1.1  mrg 
     31      1.1  mrg class Tuple : public RootObject
     32      1.1  mrg {
     33      1.1  mrg public:
     34      1.1  mrg     Objects objects;
     35      1.1  mrg 
     36      1.1  mrg     // kludge for template.isType()
     37  1.1.1.2  mrg     DYNCAST dyncast() const { return DYNCAST_TUPLE; }
     38      1.1  mrg 
     39  1.1.1.2  mrg     const char *toChars() const { return objects.toChars(); }
     40      1.1  mrg };
     41      1.1  mrg 
     42      1.1  mrg struct TemplatePrevious
     43      1.1  mrg {
     44      1.1  mrg     TemplatePrevious *prev;
     45      1.1  mrg     Scope *sc;
     46      1.1  mrg     Objects *dedargs;
     47      1.1  mrg };
     48      1.1  mrg 
     49      1.1  mrg class TemplateDeclaration : public ScopeDsymbol
     50      1.1  mrg {
     51      1.1  mrg public:
     52      1.1  mrg     TemplateParameters *parameters;     // array of TemplateParameter's
     53      1.1  mrg 
     54      1.1  mrg     TemplateParameters *origParameters; // originals for Ddoc
     55      1.1  mrg     Expression *constraint;
     56      1.1  mrg 
     57      1.1  mrg     // Hash table to look up TemplateInstance's of this TemplateDeclaration
     58      1.1  mrg     void *instances;
     59      1.1  mrg 
     60      1.1  mrg     TemplateDeclaration *overnext;      // next overloaded TemplateDeclaration
     61      1.1  mrg     TemplateDeclaration *overroot;      // first in overnext list
     62      1.1  mrg     FuncDeclaration *funcroot;          // first function in unified overload list
     63      1.1  mrg 
     64      1.1  mrg     Dsymbol *onemember;         // if !=NULL then one member of this template
     65      1.1  mrg 
     66      1.1  mrg     bool literal;               // this template declaration is a literal
     67      1.1  mrg     bool ismixin;               // template declaration is only to be used as a mixin
     68      1.1  mrg     bool isstatic;              // this is static template declaration
     69  1.1.1.2  mrg     bool isTrivialAliasSeq;     // matches `template AliasSeq(T...) { alias AliasSeq = T; }
     70  1.1.1.2  mrg     bool isTrivialAlias;        // matches pattern `template Alias(T) { alias Alias = qualifiers(T); }`
     71  1.1.1.2  mrg     bool deprecated_;           // this template declaration is deprecated
     72  1.1.1.2  mrg     Visibility visibility;
     73  1.1.1.2  mrg     int inuse;                  // for recursive expansion detection
     74      1.1  mrg 
     75      1.1  mrg     TemplatePrevious *previous;         // threaded list of previous instantiation attempts on stack
     76      1.1  mrg 
     77  1.1.1.2  mrg     TemplateDeclaration *syntaxCopy(Dsymbol *);
     78      1.1  mrg     bool overloadInsert(Dsymbol *s);
     79      1.1  mrg     bool hasStaticCtorOrDtor();
     80      1.1  mrg     const char *kind() const;
     81  1.1.1.2  mrg     const char *toChars() const;
     82      1.1  mrg 
     83  1.1.1.2  mrg     Visibility visible();
     84      1.1  mrg 
     85      1.1  mrg     MATCH leastAsSpecialized(Scope *sc, TemplateDeclaration *td2, Expressions *fargs);
     86      1.1  mrg     RootObject *declareParameter(Scope *sc, TemplateParameter *tp, RootObject *o);
     87      1.1  mrg 
     88      1.1  mrg     TemplateDeclaration *isTemplateDeclaration() { return this; }
     89      1.1  mrg 
     90      1.1  mrg     TemplateTupleParameter *isVariadic();
     91  1.1.1.2  mrg     bool isDeprecated() const;
     92  1.1.1.2  mrg     bool isOverloadable() const;
     93      1.1  mrg 
     94      1.1  mrg     void accept(Visitor *v) { v->visit(this); }
     95      1.1  mrg };
     96      1.1  mrg 
     97      1.1  mrg /* For type-parameter:
     98      1.1  mrg  *  template Foo(ident)             // specType is set to NULL
     99      1.1  mrg  *  template Foo(ident : specType)
    100      1.1  mrg  * For value-parameter:
    101      1.1  mrg  *  template Foo(valType ident)     // specValue is set to NULL
    102      1.1  mrg  *  template Foo(valType ident : specValue)
    103      1.1  mrg  * For alias-parameter:
    104      1.1  mrg  *  template Foo(alias ident)
    105      1.1  mrg  * For this-parameter:
    106      1.1  mrg  *  template Foo(this ident)
    107      1.1  mrg  */
    108  1.1.1.2  mrg class TemplateParameter : public ASTNode
    109      1.1  mrg {
    110      1.1  mrg public:
    111      1.1  mrg     Loc loc;
    112      1.1  mrg     Identifier *ident;
    113      1.1  mrg 
    114      1.1  mrg     /* True if this is a part of precedent parameter specialization pattern.
    115      1.1  mrg      *
    116      1.1  mrg      *  template A(T : X!TL, alias X, TL...) {}
    117      1.1  mrg      *  // X and TL are dependent template parameter
    118      1.1  mrg      *
    119      1.1  mrg      * A dependent template parameter should return MATCHexact in matchArg()
    120      1.1  mrg      * to respect the match level of the corresponding precedent parameter.
    121      1.1  mrg      */
    122      1.1  mrg     bool dependent;
    123      1.1  mrg 
    124      1.1  mrg     virtual TemplateTypeParameter  *isTemplateTypeParameter();
    125      1.1  mrg     virtual TemplateValueParameter *isTemplateValueParameter();
    126      1.1  mrg     virtual TemplateAliasParameter *isTemplateAliasParameter();
    127      1.1  mrg     virtual TemplateThisParameter *isTemplateThisParameter();
    128      1.1  mrg     virtual TemplateTupleParameter *isTemplateTupleParameter();
    129      1.1  mrg 
    130      1.1  mrg     virtual TemplateParameter *syntaxCopy() = 0;
    131      1.1  mrg     virtual bool declareParameter(Scope *sc) = 0;
    132      1.1  mrg     virtual void print(RootObject *oarg, RootObject *oded) = 0;
    133      1.1  mrg     virtual RootObject *specialization() = 0;
    134  1.1.1.2  mrg     virtual RootObject *defaultArg(const Loc &instLoc, Scope *sc) = 0;
    135      1.1  mrg     virtual bool hasDefaultArg() = 0;
    136      1.1  mrg 
    137      1.1  mrg     /* Create dummy argument based on parameter.
    138      1.1  mrg      */
    139  1.1.1.2  mrg     virtual RootObject *dummyArg() = 0;
    140  1.1.1.2  mrg     void accept(Visitor *v) { v->visit(this); }
    141      1.1  mrg };
    142      1.1  mrg 
    143      1.1  mrg /* Syntax:
    144      1.1  mrg  *  ident : specType = defaultType
    145      1.1  mrg  */
    146      1.1  mrg class TemplateTypeParameter : public TemplateParameter
    147      1.1  mrg {
    148      1.1  mrg public:
    149      1.1  mrg     Type *specType;     // type parameter: if !=NULL, this is the type specialization
    150      1.1  mrg     Type *defaultType;
    151      1.1  mrg 
    152      1.1  mrg     TemplateTypeParameter *isTemplateTypeParameter();
    153  1.1.1.2  mrg     TemplateTypeParameter *syntaxCopy();
    154      1.1  mrg     bool declareParameter(Scope *sc);
    155      1.1  mrg     void print(RootObject *oarg, RootObject *oded);
    156      1.1  mrg     RootObject *specialization();
    157  1.1.1.2  mrg     RootObject *defaultArg(const Loc &instLoc, Scope *sc);
    158      1.1  mrg     bool hasDefaultArg();
    159  1.1.1.2  mrg     RootObject *dummyArg();
    160      1.1  mrg     void accept(Visitor *v) { v->visit(this); }
    161      1.1  mrg };
    162      1.1  mrg 
    163      1.1  mrg /* Syntax:
    164      1.1  mrg  *  this ident : specType = defaultType
    165      1.1  mrg  */
    166      1.1  mrg class TemplateThisParameter : public TemplateTypeParameter
    167      1.1  mrg {
    168      1.1  mrg public:
    169      1.1  mrg     TemplateThisParameter *isTemplateThisParameter();
    170  1.1.1.2  mrg     TemplateThisParameter *syntaxCopy();
    171      1.1  mrg     void accept(Visitor *v) { v->visit(this); }
    172      1.1  mrg };
    173      1.1  mrg 
    174      1.1  mrg /* Syntax:
    175      1.1  mrg  *  valType ident : specValue = defaultValue
    176      1.1  mrg  */
    177      1.1  mrg class TemplateValueParameter : public TemplateParameter
    178      1.1  mrg {
    179      1.1  mrg public:
    180      1.1  mrg     Type *valType;
    181      1.1  mrg     Expression *specValue;
    182      1.1  mrg     Expression *defaultValue;
    183      1.1  mrg 
    184      1.1  mrg     TemplateValueParameter *isTemplateValueParameter();
    185  1.1.1.2  mrg     TemplateValueParameter *syntaxCopy();
    186      1.1  mrg     bool declareParameter(Scope *sc);
    187      1.1  mrg     void print(RootObject *oarg, RootObject *oded);
    188      1.1  mrg     RootObject *specialization();
    189  1.1.1.2  mrg     RootObject *defaultArg(const Loc &instLoc, Scope *sc);
    190      1.1  mrg     bool hasDefaultArg();
    191  1.1.1.2  mrg     RootObject *dummyArg();
    192      1.1  mrg     void accept(Visitor *v) { v->visit(this); }
    193      1.1  mrg };
    194      1.1  mrg 
    195      1.1  mrg /* Syntax:
    196      1.1  mrg  *  specType ident : specAlias = defaultAlias
    197      1.1  mrg  */
    198      1.1  mrg class TemplateAliasParameter : public TemplateParameter
    199      1.1  mrg {
    200      1.1  mrg public:
    201      1.1  mrg     Type *specType;
    202      1.1  mrg     RootObject *specAlias;
    203      1.1  mrg     RootObject *defaultAlias;
    204      1.1  mrg 
    205      1.1  mrg     TemplateAliasParameter *isTemplateAliasParameter();
    206  1.1.1.2  mrg     TemplateAliasParameter *syntaxCopy();
    207      1.1  mrg     bool declareParameter(Scope *sc);
    208      1.1  mrg     void print(RootObject *oarg, RootObject *oded);
    209      1.1  mrg     RootObject *specialization();
    210  1.1.1.2  mrg     RootObject *defaultArg(const Loc &instLoc, Scope *sc);
    211      1.1  mrg     bool hasDefaultArg();
    212  1.1.1.2  mrg     RootObject *dummyArg();
    213      1.1  mrg     void accept(Visitor *v) { v->visit(this); }
    214      1.1  mrg };
    215      1.1  mrg 
    216      1.1  mrg /* Syntax:
    217      1.1  mrg  *  ident ...
    218      1.1  mrg  */
    219      1.1  mrg class TemplateTupleParameter : public TemplateParameter
    220      1.1  mrg {
    221      1.1  mrg public:
    222      1.1  mrg     TemplateTupleParameter *isTemplateTupleParameter();
    223  1.1.1.2  mrg     TemplateTupleParameter *syntaxCopy();
    224      1.1  mrg     bool declareParameter(Scope *sc);
    225      1.1  mrg     void print(RootObject *oarg, RootObject *oded);
    226      1.1  mrg     RootObject *specialization();
    227  1.1.1.2  mrg     RootObject *defaultArg(const Loc &instLoc, Scope *sc);
    228      1.1  mrg     bool hasDefaultArg();
    229  1.1.1.2  mrg     RootObject *dummyArg();
    230      1.1  mrg     void accept(Visitor *v) { v->visit(this); }
    231      1.1  mrg };
    232      1.1  mrg 
    233      1.1  mrg /* Given:
    234      1.1  mrg  *  foo!(args) =>
    235      1.1  mrg  *      name = foo
    236      1.1  mrg  *      tiargs = args
    237      1.1  mrg  */
    238      1.1  mrg class TemplateInstance : public ScopeDsymbol
    239      1.1  mrg {
    240      1.1  mrg public:
    241      1.1  mrg     Identifier *name;
    242      1.1  mrg 
    243      1.1  mrg     // Array of Types/Expressions of template
    244      1.1  mrg     // instance arguments [int*, char, 10*10]
    245      1.1  mrg     Objects *tiargs;
    246      1.1  mrg 
    247      1.1  mrg     // Array of Types/Expressions corresponding
    248      1.1  mrg     // to TemplateDeclaration.parameters
    249      1.1  mrg     // [int, char, 100]
    250      1.1  mrg     Objects tdtypes;
    251      1.1  mrg 
    252  1.1.1.2  mrg     // Modules imported by this template instance
    253  1.1.1.2  mrg     Modules importedModules;
    254  1.1.1.2  mrg 
    255      1.1  mrg     Dsymbol *tempdecl;                  // referenced by foo.bar.abc
    256      1.1  mrg     Dsymbol *enclosing;                 // if referencing local symbols, this is the context
    257      1.1  mrg     Dsymbol *aliasdecl;                 // !=NULL if instance is an alias for its sole member
    258      1.1  mrg     TemplateInstance *inst;             // refer to existing instance
    259      1.1  mrg     ScopeDsymbol *argsym;               // argument symbol table
    260      1.1  mrg     hash_t hash;                        // cached result of toHash()
    261      1.1  mrg     Expressions *fargs;                 // for function template, these are the function arguments
    262      1.1  mrg 
    263      1.1  mrg     TemplateInstances* deferred;
    264      1.1  mrg 
    265      1.1  mrg     Module *memberOf;                   // if !null, then this TemplateInstance appears in memberOf.members[]
    266      1.1  mrg 
    267      1.1  mrg     // Used to determine the instance needs code generation.
    268      1.1  mrg     // Note that these are inaccurate until semantic analysis phase completed.
    269      1.1  mrg     TemplateInstance *tinst;            // enclosing template instance
    270      1.1  mrg     TemplateInstance *tnext;            // non-first instantiated instances
    271      1.1  mrg     Module *minst;                      // the top module that instantiated this instance
    272      1.1  mrg 
    273  1.1.1.2  mrg private:
    274  1.1.1.2  mrg     unsigned short _nest;                // for recursive pretty printing detection, 3 MSBs reserved for flags
    275  1.1.1.2  mrg public:
    276  1.1.1.2  mrg     unsigned char inuse;                 // for recursive expansion detection
    277  1.1.1.2  mrg 
    278  1.1.1.2  mrg     TemplateInstance *syntaxCopy(Dsymbol *);
    279      1.1  mrg     Dsymbol *toAlias();                 // resolve real symbol
    280      1.1  mrg     const char *kind() const;
    281      1.1  mrg     bool oneMember(Dsymbol **ps, Identifier *ident);
    282  1.1.1.2  mrg     const char *toChars() const;
    283      1.1  mrg     const char* toPrettyCharsHelper();
    284      1.1  mrg     Identifier *getIdent();
    285      1.1  mrg     hash_t toHash();
    286      1.1  mrg 
    287  1.1.1.2  mrg     bool isDiscardable();
    288      1.1  mrg     bool needsCodegen();
    289      1.1  mrg 
    290      1.1  mrg     TemplateInstance *isTemplateInstance() { return this; }
    291      1.1  mrg     void accept(Visitor *v) { v->visit(this); }
    292      1.1  mrg };
    293      1.1  mrg 
    294      1.1  mrg class TemplateMixin : public TemplateInstance
    295      1.1  mrg {
    296      1.1  mrg public:
    297      1.1  mrg     TypeQualified *tqual;
    298      1.1  mrg 
    299  1.1.1.2  mrg     TemplateMixin *syntaxCopy(Dsymbol *s);
    300      1.1  mrg     const char *kind() const;
    301      1.1  mrg     bool oneMember(Dsymbol **ps, Identifier *ident);
    302      1.1  mrg     bool hasPointers();
    303  1.1.1.2  mrg     void setFieldOffset(AggregateDeclaration *ad, FieldState& fieldState, bool isunion);
    304  1.1.1.2  mrg     const char *toChars() const;
    305      1.1  mrg 
    306      1.1  mrg     TemplateMixin *isTemplateMixin() { return this; }
    307      1.1  mrg     void accept(Visitor *v) { v->visit(this); }
    308      1.1  mrg };
    309      1.1  mrg 
    310      1.1  mrg Expression *isExpression(RootObject *o);
    311      1.1  mrg Dsymbol *isDsymbol(RootObject *o);
    312      1.1  mrg Type *isType(RootObject *o);
    313      1.1  mrg Tuple *isTuple(RootObject *o);
    314      1.1  mrg Parameter *isParameter(RootObject *o);
    315  1.1.1.2  mrg TemplateParameter *isTemplateParameter(RootObject *o);
    316  1.1.1.2  mrg bool isError(const RootObject *const o);
    317  1.1.1.2  mrg void printTemplateStats();
    318