Mercurial > hg > CbC > CbC_gcc
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);