diff options
Diffstat (limited to 'contrib/llvm-project/clang/include/clang/AST/TemplateName.h')
-rw-r--r-- | contrib/llvm-project/clang/include/clang/AST/TemplateName.h | 169 |
1 files changed, 105 insertions, 64 deletions
diff --git a/contrib/llvm-project/clang/include/clang/AST/TemplateName.h b/contrib/llvm-project/clang/include/clang/AST/TemplateName.h index 010b813dc525..b7732e54ba10 100644 --- a/contrib/llvm-project/clang/include/clang/AST/TemplateName.h +++ b/contrib/llvm-project/clang/include/clang/AST/TemplateName.h @@ -21,19 +21,19 @@ #include "llvm/ADT/PointerUnion.h" #include "llvm/Support/PointerLikeTypeTraits.h" #include <cassert> +#include <optional> namespace clang { class ASTContext; +class Decl; class DependentTemplateName; -class DiagnosticBuilder; class IdentifierInfo; class NamedDecl; class NestedNameSpecifier; enum OverloadedOperatorKind : int; class OverloadedTemplateStorage; class AssumedTemplateStorage; -class PartialDiagnostic; struct PrintingPolicy; class QualifiedTemplateName; class SubstTemplateTemplateParmPackStorage; @@ -41,6 +41,7 @@ class SubstTemplateTemplateParmStorage; class TemplateArgument; class TemplateDecl; class TemplateTemplateParmDecl; +class UsingShadowDecl; /// Implementation class used to describe either a set of overloaded /// template names or an already-substituted template template parameter pack. @@ -54,12 +55,15 @@ protected: }; struct BitsTag { - /// A Kind. + LLVM_PREFERRED_TYPE(Kind) unsigned Kind : 2; - /// The number of stored templates or template arguments, - /// depending on which subclass we have. - unsigned Size : 30; + // The template parameter index. + unsigned Index : 15; + + /// The pack index, or the number of stored templates + /// or template arguments, depending on which subclass we have. + unsigned Data : 15; }; union { @@ -67,14 +71,13 @@ protected: void *PointerAlignment; }; - UncommonTemplateNameStorage(Kind kind, unsigned size) { - Bits.Kind = kind; - Bits.Size = size; + UncommonTemplateNameStorage(Kind Kind, unsigned Index, unsigned Data) { + Bits.Kind = Kind; + Bits.Index = Index; + Bits.Data = Data; } public: - unsigned size() const { return Bits.Size; } - OverloadedTemplateStorage *getAsOverloadedStorage() { return Bits.Kind == Overloaded ? reinterpret_cast<OverloadedTemplateStorage *>(this) @@ -106,7 +109,7 @@ class OverloadedTemplateStorage : public UncommonTemplateNameStorage { friend class ASTContext; OverloadedTemplateStorage(unsigned size) - : UncommonTemplateNameStorage(Overloaded, size) {} + : UncommonTemplateNameStorage(Overloaded, 0, size) {} NamedDecl **getStorage() { return reinterpret_cast<NamedDecl **>(this + 1); @@ -116,13 +119,15 @@ class OverloadedTemplateStorage : public UncommonTemplateNameStorage { } public: + unsigned size() const { return Bits.Data; } + using iterator = NamedDecl *const *; iterator begin() const { return getStorage(); } - iterator end() const { return getStorage() + size(); } + iterator end() const { return getStorage() + Bits.Data; } llvm::ArrayRef<NamedDecl*> decls() const { - return llvm::makeArrayRef(begin(), end()); + return llvm::ArrayRef(begin(), end()); } }; @@ -132,23 +137,29 @@ public: /// This kind of template names occurs when the parameter pack has been /// provided with a template template argument pack in a context where its /// enclosing pack expansion could not be fully expanded. -class SubstTemplateTemplateParmPackStorage - : public UncommonTemplateNameStorage, public llvm::FoldingSetNode -{ - TemplateTemplateParmDecl *Parameter; +class SubstTemplateTemplateParmPackStorage : public UncommonTemplateNameStorage, + public llvm::FoldingSetNode { const TemplateArgument *Arguments; + llvm::PointerIntPair<Decl *, 1, bool> AssociatedDeclAndFinal; public: - SubstTemplateTemplateParmPackStorage(TemplateTemplateParmDecl *Parameter, - unsigned Size, - const TemplateArgument *Arguments) - : UncommonTemplateNameStorage(SubstTemplateTemplateParmPack, Size), - Parameter(Parameter), Arguments(Arguments) {} + SubstTemplateTemplateParmPackStorage(ArrayRef<TemplateArgument> ArgPack, + Decl *AssociatedDecl, unsigned Index, + bool Final); + + /// A template-like entity which owns the whole pattern being substituted. + /// This will own a set of template parameters. + Decl *getAssociatedDecl() const; + + /// Returns the index of the replaced parameter in the associated declaration. + /// This should match the result of `getParameterPack()->getIndex()`. + unsigned getIndex() const { return Bits.Index; } + + // When true the substitution will be 'Final' (subst node won't be placed). + bool getFinal() const; /// Retrieve the template template parameter pack being substituted. - TemplateTemplateParmDecl *getParameterPack() const { - return Parameter; - } + TemplateTemplateParmDecl *getParameterPack() const; /// Retrieve the template template argument pack with which this /// parameter was substituted. @@ -156,10 +167,9 @@ public: void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context); - static void Profile(llvm::FoldingSetNodeID &ID, - ASTContext &Context, - TemplateTemplateParmDecl *Parameter, - const TemplateArgument &ArgPack); + static void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context, + const TemplateArgument &ArgPack, Decl *AssociatedDecl, + unsigned Index, bool Final); }; /// Represents a C++ template name within the type system. @@ -190,8 +200,12 @@ public: /// specifier in the typedef. "apply" is a nested template, and can /// only be understood in the context of class TemplateName { + // NameDecl is either a TemplateDecl or a UsingShadowDecl depending on the + // NameKind. + // !! There is no free low bits in 32-bit builds to discriminate more than 4 + // pointer types in PointerUnion. using StorageType = - llvm::PointerUnion<TemplateDecl *, UncommonTemplateNameStorage *, + llvm::PointerUnion<Decl *, UncommonTemplateNameStorage *, QualifiedTemplateName *, DependentTemplateName *>; StorageType Storage; @@ -226,7 +240,11 @@ public: /// A template template parameter pack that has been substituted for /// a template template argument pack, but has not yet been expanded into /// individual arguments. - SubstTemplateTemplateParmPack + SubstTemplateTemplateParmPack, + + /// A template name that refers to a template declaration found through a + /// specific using shadow declaration. + UsingTemplate, }; TemplateName() = default; @@ -237,6 +255,7 @@ public: explicit TemplateName(SubstTemplateTemplateParmPackStorage *Storage); explicit TemplateName(QualifiedTemplateName *Qual); explicit TemplateName(DependentTemplateName *Dep); + explicit TemplateName(UsingShadowDecl *Using); /// Determine whether this template name is NULL. bool isNull() const; @@ -289,6 +308,10 @@ public: /// structure, if any. DependentTemplateName *getAsDependentTemplateName() const; + /// Retrieve the using shadow declaration through which the underlying + /// template declaration is introduced, if any. + UsingShadowDecl *getAsUsingShadowDecl() const; + TemplateName getUnderlying() const; /// Get the template name to substitute when this template name is used as a @@ -309,16 +332,17 @@ public: /// unexpanded parameter pack (for C++0x variadic templates). bool containsUnexpandedParameterPack() const; + enum class Qualified { None, AsWritten, Fully }; /// Print the template name. /// /// \param OS the output stream to which the template name will be /// printed. /// - /// \param SuppressNNS if true, don't print the - /// nested-name-specifier that precedes the template name (if it has - /// one). + /// \param Qual print the (Qualified::None) simple name, + /// (Qualified::AsWritten) any written (possibly partial) qualifier, or + /// (Qualified::Fully) the fully qualified name. void print(raw_ostream &OS, const PrintingPolicy &Policy, - bool SuppressNNS = false) const; + Qualified Qual = Qualified::AsWritten) const; /// Debugging aid that dumps the template name. void dump(raw_ostream &OS) const; @@ -327,9 +351,7 @@ public: /// error. void dump() const; - void Profile(llvm::FoldingSetNodeID &ID) { - ID.AddPointer(Storage.getOpaqueValue()); - } + void Profile(llvm::FoldingSetNodeID &ID); /// Retrieve the template name as a void pointer. void *getAsVoidPointer() const { return Storage.getOpaqueValue(); } @@ -351,23 +373,41 @@ class SubstTemplateTemplateParmStorage : public UncommonTemplateNameStorage, public llvm::FoldingSetNode { friend class ASTContext; - TemplateTemplateParmDecl *Parameter; TemplateName Replacement; - - SubstTemplateTemplateParmStorage(TemplateTemplateParmDecl *parameter, - TemplateName replacement) - : UncommonTemplateNameStorage(SubstTemplateTemplateParm, 0), - Parameter(parameter), Replacement(replacement) {} + Decl *AssociatedDecl; + + SubstTemplateTemplateParmStorage(TemplateName Replacement, + Decl *AssociatedDecl, unsigned Index, + std::optional<unsigned> PackIndex) + : UncommonTemplateNameStorage(SubstTemplateTemplateParm, Index, + PackIndex ? *PackIndex + 1 : 0), + Replacement(Replacement), AssociatedDecl(AssociatedDecl) { + assert(AssociatedDecl != nullptr); + } public: - TemplateTemplateParmDecl *getParameter() const { return Parameter; } + /// A template-like entity which owns the whole pattern being substituted. + /// This will own a set of template parameters. + Decl *getAssociatedDecl() const { return AssociatedDecl; } + + /// Returns the index of the replaced parameter in the associated declaration. + /// This should match the result of `getParameter()->getIndex()`. + unsigned getIndex() const { return Bits.Index; } + + std::optional<unsigned> getPackIndex() const { + if (Bits.Data == 0) + return std::nullopt; + return Bits.Data - 1; + } + + TemplateTemplateParmDecl *getParameter() const; TemplateName getReplacement() const { return Replacement; } void Profile(llvm::FoldingSetNodeID &ID); - static void Profile(llvm::FoldingSetNodeID &ID, - TemplateTemplateParmDecl *parameter, - TemplateName replacement); + static void Profile(llvm::FoldingSetNodeID &ID, TemplateName Replacement, + Decl *AssociatedDecl, unsigned Index, + std::optional<unsigned> PackIndex); }; inline TemplateName TemplateName::getUnderlying() const { @@ -400,13 +440,19 @@ class QualifiedTemplateName : public llvm::FoldingSetNode { /// this name with DependentTemplateName). llvm::PointerIntPair<NestedNameSpecifier *, 1> Qualifier; - /// The template declaration or set of overloaded function templates - /// that this qualified name refers to. - TemplateDecl *Template; + /// The underlying template name, it is either + /// 1) a Template -- a template declaration that this qualified name refers + /// to. + /// 2) or a UsingTemplate -- a template declaration introduced by a + /// using-shadow declaration. + TemplateName UnderlyingTemplate; QualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword, - TemplateDecl *Template) - : Qualifier(NNS, TemplateKeyword? 1 : 0), Template(Template) {} + TemplateName Template) + : Qualifier(NNS, TemplateKeyword ? 1 : 0), UnderlyingTemplate(Template) { + assert(UnderlyingTemplate.getKind() == TemplateName::Template || + UnderlyingTemplate.getKind() == TemplateName::UsingTemplate); + } public: /// Return the nested name specifier that qualifies this name. @@ -416,23 +462,18 @@ public: /// keyword. bool hasTemplateKeyword() const { return Qualifier.getInt(); } - /// The template declaration that this qualified name refers - /// to. - TemplateDecl *getDecl() const { return Template; } - - /// The template declaration to which this qualified name - /// refers. - TemplateDecl *getTemplateDecl() const { return Template; } + /// Return the underlying template name. + TemplateName getUnderlyingTemplate() const { return UnderlyingTemplate; } void Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, getQualifier(), hasTemplateKeyword(), getTemplateDecl()); + Profile(ID, getQualifier(), hasTemplateKeyword(), UnderlyingTemplate); } static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS, - bool TemplateKeyword, TemplateDecl *Template) { + bool TemplateKeyword, TemplateName TN) { ID.AddPointer(NNS); ID.AddBoolean(TemplateKeyword); - ID.AddPointer(Template); + ID.AddPointer(TN.getAsVoidPointer()); } }; |