aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/include/clang/AST/TemplateName.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/include/clang/AST/TemplateName.h')
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/TemplateName.h169
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());
}
};