diff options
Diffstat (limited to 'include/clang/AST/TemplateBase.h')
-rw-r--r-- | include/clang/AST/TemplateBase.h | 55 |
1 files changed, 44 insertions, 11 deletions
diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h index 93ec35bebe..a4e074e083 100644 --- a/include/clang/AST/TemplateBase.h +++ b/include/clang/AST/TemplateBase.h @@ -80,8 +80,14 @@ private: const TemplateArgument *Args; unsigned NumArgs; } Args; + struct { + void *Name; + unsigned NumExpansions; + } TemplateArg; }; + TemplateArgument(TemplateName, bool); // DO NOT USE + public: /// \brief Construct an empty, invalid template argument. TemplateArgument() : Kind(Null), TypeOrValue(0) { } @@ -107,8 +113,7 @@ public: Integer.Type = Type.getAsOpaquePtr(); } - /// \brief Construct a template argument that is a template or a pack - /// expansion of templates. + /// \brief Construct a template argument that is a template. /// /// This form of template argument is generally used for template template /// parameters. However, the template name could be a dependent template @@ -116,13 +121,33 @@ public: /// is taken. /// /// \param Name The template name. - /// \param PackExpansion Whether this template argument is a pack expansion. - TemplateArgument(TemplateName Name, bool PackExpansion = false) - : Kind(PackExpansion? TemplateExpansion : Template) + TemplateArgument(TemplateName Name) : Kind(Template) { - TypeOrValue = reinterpret_cast<uintptr_t>(Name.getAsVoidPointer()); + TemplateArg.Name = Name.getAsVoidPointer(); + TemplateArg.NumExpansions = 0; } - + + /// \brief Construct a template argument that is a template pack expansion. + /// + /// This form of template argument is generally used for template template + /// parameters. However, the template name could be a dependent template + /// name that ends up being instantiated to a function template whose address + /// is taken. + /// + /// \param Name The template name. + /// + /// \param NumExpansions The number of expansions that will be generated by + /// instantiating + TemplateArgument(TemplateName Name, llvm::Optional<unsigned> NumExpansions) + : Kind(TemplateExpansion) + { + TemplateArg.Name = Name.getAsVoidPointer(); + if (NumExpansions) + TemplateArg.NumExpansions = *NumExpansions + 1; + else + TemplateArg.NumExpansions = 0; + } + /// \brief Construct a template argument that is an expression. /// /// This form of template argument only occurs in template argument @@ -151,6 +176,9 @@ public: } else if (Kind == Pack) { Args.NumArgs = Other.Args.NumArgs; Args.Args = Other.Args.Args; + } else if (Kind == Template || Kind == TemplateExpansion) { + TemplateArg.Name = Other.TemplateArg.Name; + TemplateArg.NumExpansions = Other.TemplateArg.NumExpansions; } else TypeOrValue = Other.TypeOrValue; } @@ -177,6 +205,9 @@ public: } else if (Other.Kind == Pack) { Args.NumArgs = Other.Args.NumArgs; Args.Args = Other.Args.Args; + } else if (Kind == Template || Kind == TemplateExpansion) { + TemplateArg.Name = Other.TemplateArg.Name; + TemplateArg.NumExpansions = Other.TemplateArg.NumExpansions; } else { TypeOrValue = Other.TypeOrValue; } @@ -234,8 +265,7 @@ public: if (Kind != Template) return TemplateName(); - return TemplateName::getFromVoidPointer( - reinterpret_cast<void*>(TypeOrValue)); + return TemplateName::getFromVoidPointer(TemplateArg.Name); } /// \brief Retrieve the template argument as a template name; if the argument @@ -244,10 +274,13 @@ public: if (Kind != Template && Kind != TemplateExpansion) return TemplateName(); - return TemplateName::getFromVoidPointer( - reinterpret_cast<void*>(TypeOrValue)); + return TemplateName::getFromVoidPointer(TemplateArg.Name); } + /// \brief Retrieve the number of expansions that a template template argument + /// expansion will produce, if known. + llvm::Optional<unsigned> getNumTemplateExpansions() const; + /// \brief Retrieve the template argument as an integral value. llvm::APSInt *getAsIntegral() { if (Kind != Integral) |