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