using System; using System.Collections.Generic; using System.Linq; namespace CppSharp.AST { public class TemplateTemplateParameter : Template { /// /// Whether this template template parameter is a template parameter pack. /// template<template<class T> ...MetaFunctions> struct Apply; /// public bool IsParameterPack { get; set; } /// /// Whether this parameter pack is a pack expansion. /// A template template parameter pack is a pack expansion if its template parameter list contains an unexpanded parameter pack. /// public bool IsPackExpansion { get; set; } /// /// Whether this parameter is a template template parameter pack that has a known list of different template parameter lists at different positions. /// A parameter pack is an expanded parameter pack when the original parameter pack's template parameter list was itself a pack expansion, and that expansion has already been expanded. For exampe, given: /// /// template<typename...Types> struct Outer { template<template<Types> class...Templates> struct Inner; }; /// /// The parameter pack Templates is a pack expansion, which expands the pack Types.When Types is supplied with template arguments by instantiating Outer, the instantiation of Templates is an expanded parameter pack. /// public bool IsExpandedParameterPack { get; set; } public override T Visit(IDeclVisitor visitor) { return visitor.VisitTemplateTemplateParameterDecl(this); } } /// /// Represents a type template parameter. /// public class TypeTemplateParameter : Declaration { /// /// Get the nesting depth of the template parameter. /// public uint Depth { get; set; } /// /// Get the index of the template parameter within its parameter list. /// public uint Index { get; set; } /// /// Whether this parameter is a non-type template parameter pack. /// /// If the parameter is a parameter pack, the type may be a PackExpansionType.In the following example, the Dims parameter is a parameter pack (whose type is 'unsigned'). /// template<typename T, unsigned...Dims> struct multi_array; /// /// public bool IsParameterPack { get; set; } // Generic type constraint public string Constraint; public QualifiedType DefaultArgument { get; set; } public override T Visit(IDeclVisitor visitor) { return visitor.VisitTemplateParameterDecl(this); } } /// /// Represents a non-type template parameter. /// public class NonTypeTemplateParameter : Declaration { /// /// Get the nesting depth of the template parameter. /// public uint Depth { get; set; } /// /// Get the index of the template parameter within its parameter list. /// public uint Index { get; set; } /// /// Whether this parameter is a non-type template parameter pack. /// /// If the parameter is a parameter pack, the type may be a PackExpansionType.In the following example, the Dims parameter is a parameter pack (whose type is 'unsigned'). /// template<typename T, unsigned...Dims> struct multi_array; /// /// public bool IsParameterPack { get; set; } public ExpressionObsolete DefaultArgument { get; set; } /// /// Get the position of the template parameter within its parameter list. /// public uint Position { get; set; } /// /// Whether this parameter pack is a pack expansion. /// /// A non-type template parameter pack is a pack expansion if its type contains an unexpanded parameter pack.In this case, we will have built a PackExpansionType wrapping the type. /// /// public bool IsPackExpansion { get; set; } /// /// Whether this parameter is a non-type template parameter pack that has a known list of different types at different positions. /// A parameter pack is an expanded parameter pack when the original parameter pack's type was itself a pack expansion, and that expansion has already been expanded. For example, given: /// /// template<typename...Types> /// struct X { /// template<Types...Values> /// struct Y { /* ... */ }; /// }; /// /// The parameter pack Values has a PackExpansionType as its type, which expands Types.When Types is supplied with template arguments by instantiating X, /// the instantiation of Values becomes an expanded parameter pack.For example, instantiating X<int, unsigned int> /// results in Values being an expanded parameter pack with expansion types int and unsigned int. /// public bool IsExpandedParameterPack { get; set; } public override T Visit(IDeclVisitor visitor) { return visitor.VisitNonTypeTemplateParameterDecl(this); } } /// /// The base class of all kinds of template declarations /// (e.g., class, function, etc.). /// public abstract class Template : Declaration { // Name of the declaration. public override string Name { get => TemplatedDecl != null ? TemplatedDecl.Name : base.Name; set { base.Name = value; if (TemplatedDecl != null) TemplatedDecl.Name = value; } } protected Template() { Parameters = new List(); } protected Template(Declaration decl) { TemplatedDecl = decl; Parameters = new List(); } public Declaration TemplatedDecl; public readonly List Parameters; public override string ToString() { return TemplatedDecl.ToString(); } } /// /// Declaration of a type alias template. /// public class TypeAliasTemplate : Template { public override T Visit(IDeclVisitor visitor) { return visitor.VisitTypeAliasTemplateDecl(this); } } /// /// Declaration of a class template. /// public class ClassTemplate : Template { public readonly List Specializations; public Class TemplatedClass => TemplatedDecl as Class; public ClassTemplate() { Specializations = new List(); } public ClassTemplate(Declaration decl) : base(decl) { Specializations = new List(); } public override T Visit(IDeclVisitor visitor) { return visitor.VisitClassTemplateDecl(this); } public override string Name { get => TemplatedDecl != null ? TemplatedClass.Name : base.Name; set { if (TemplatedDecl != null) TemplatedClass.Name = value; else base.Name = value; } } public override string OriginalName { get => TemplatedDecl != null ? TemplatedClass.OriginalName : base.OriginalName; set { if (TemplatedDecl != null) TemplatedClass.OriginalName = value; else base.OriginalName = value; } } public ClassTemplateSpecialization FindSpecializationByUSR(string usr) { return Specializations.FirstOrDefault(spec => spec.USR == usr); } public ClassTemplatePartialSpecialization FindPartialSpecializationByUSR(string usr) { return FindSpecializationByUSR(usr) as ClassTemplatePartialSpecialization; } } /// /// Describes the kind of template specialization that a particular /// template specialization declaration represents. /// public enum TemplateSpecializationKind { /// This template specialization was formed from a template-id but has /// not yet been declared, defined, or instantiated. Undeclared, /// This template specialization was implicitly instantiated from a /// template. ImplicitInstantiation, /// This template specialization was declared or defined by an explicit /// specialization or partial specialization. ExplicitSpecialization, /// This template specialization was instantiated from a template due /// to an explicit instantiation declaration request. ExplicitInstantiationDeclaration, /// This template specialization was instantiated from a template due /// to an explicit instantiation definition request. ExplicitInstantiationDefinition } /// /// Represents a class template specialization, which refers to a class /// template with a given set of template arguments. /// public class ClassTemplateSpecialization : Class { public ClassTemplate TemplatedDecl; public readonly List Arguments; public TemplateSpecializationKind SpecializationKind; public ClassTemplateSpecialization() { Arguments = new List(); } public override T Visit(IDeclVisitor visitor) { return visitor.VisitClassTemplateSpecializationDecl(this); } public override string ToString() { var args = string.Join(", ", Arguments.Select(a => a.ToString())); return $"{OriginalName}<{args}> [{SpecializationKind}]"; } } /// /// Represents a class template partial specialization, which refers to /// a class template with a given partial set of template arguments. /// public class ClassTemplatePartialSpecialization : ClassTemplateSpecialization { } /// /// Declaration of a template function. /// public class FunctionTemplate : Template { public readonly List Specializations; public FunctionTemplate() { Specializations = new List(); } public FunctionTemplate(Declaration decl) : base(decl) { Specializations = new List(); } public Function TemplatedFunction => TemplatedDecl as Function; public override T Visit(IDeclVisitor visitor) { return visitor.VisitFunctionTemplateDecl(this); } } /// /// Represents a function template specialization, which refers to a function /// template with a given set of template arguments. /// public class FunctionTemplateSpecialization { public FunctionTemplate Template; public readonly List Arguments; public Function SpecializedFunction; public TemplateSpecializationKind SpecializationKind; public FunctionTemplateSpecialization() { Arguments = new List(); } public FunctionTemplateSpecialization(FunctionTemplateSpecialization fts) { Template = fts.Template; Arguments = new List(); Arguments.AddRange(fts.Arguments); SpecializedFunction = fts.SpecializedFunction; SpecializationKind = fts.SpecializationKind; } public T Visit(IDeclVisitor visitor) { return visitor.VisitFunctionTemplateSpecializationDecl(this); } } /// /// Represents a declaration of a variable template. /// public class VarTemplate : Template { public readonly List Specializations; public Variable TemplatedVariable => TemplatedDecl as Variable; public VarTemplate() { Specializations = new List(); } public VarTemplate(Variable var) : base(var) { Specializations = new List(); } public override T Visit(IDeclVisitor visitor) { return visitor.VisitVarTemplateDecl(this); } } /// /// Represents a var template specialization, which refers to a var /// template with a given set of template arguments. /// public class VarTemplateSpecialization : Variable { public VarTemplate TemplatedDecl; public readonly List Arguments; public TemplateSpecializationKind SpecializationKind; public VarTemplateSpecialization() { Arguments = new List(); } } /// /// Represents a variable template partial specialization, which refers to /// a variable template with a given partial set of template arguments. /// public class VarTemplatePartialSpecialization : VarTemplateSpecialization { } /// /// Represents a dependent using declaration which was marked with typename. /// public class UnresolvedUsingTypename : Declaration { //public TypeAliasTemplate DescribedAliasTemplate { get; set; } public override T Visit(IDeclVisitor visitor) { return visitor.VisitUnresolvedUsingDecl(this); } } }