17#include "llvm/ADT/FoldingSet.h"
18#include "llvm/Support/TimeProfiler.h"
24class TemplateArgumentHasher {
25 llvm::FoldingSetNodeID ID;
28 TemplateArgumentHasher() =
default;
30 void AddTemplateArgument(TemplateArgument TA);
32 void AddInteger(
unsigned V) { ID.AddInteger(
V); }
34 unsigned getValue() {
return ID.computeStableHash(); }
36 void AddType(
const Type *
T);
37 void AddQualType(QualType
T);
38 void AddDecl(
const Decl *D);
39 void AddStructuralValue(
const APValue &);
41 void AddDeclarationName(DeclarationName Name);
42 void AddIdentifierInfo(
const IdentifierInfo *II);
61 ID.AddPointer(
nullptr);
85 AddTemplateArgument(SubTA);
91void TemplateArgumentHasher::AddStructuralValue(
const APValue &
Value) {
106void TemplateArgumentHasher::AddTemplateName(
TemplateName Name) {
137void TemplateArgumentHasher::AddIdentifierInfo(
const IdentifierInfo *II) {
138 assert(II &&
"Expecting non-null pointer.");
142void TemplateArgumentHasher::AddDeclarationName(DeclarationName Name) {
176void TemplateArgumentHasher::AddDecl(
const Decl *D) {
177 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
187 ArrayRef<TemplateArgument> Args;
188 if (
auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D))
189 Args = CTSD->getTemplateArgs().asArray();
190 else if (
auto *VTSD = dyn_cast<VarTemplateSpecializationDecl>(D))
191 Args = VTSD->getTemplateArgs().asArray();
192 else if (
auto *FD = dyn_cast<FunctionDecl>(D))
193 if (FD->getTemplateSpecializationArgs())
194 Args = FD->getTemplateSpecializationArgs()->asArray();
196 for (
auto &TA : Args)
197 AddTemplateArgument(TA);
200void TemplateArgumentHasher::AddQualType(QualType
T) {
204 SplitQualType split =
T.split();
211class TypeVisitorHelper :
public TypeVisitor<TypeVisitorHelper> {
212 typedef TypeVisitor<TypeVisitorHelper> Inherited;
213 llvm::FoldingSetNodeID &
ID;
214 TemplateArgumentHasher &Hash;
217 TypeVisitorHelper(llvm::FoldingSetNodeID &ID, TemplateArgumentHasher &Hash)
218 :
ID(
ID), Hash(Hash) {}
220 void AddDecl(
const Decl *D) {
227 void AddQualType(QualType
T) { Hash.AddQualType(
T); }
229 void AddType(
const Type *
T) {
236 void VisitQualifiers(Qualifiers Quals) {
240 void Visit(
const Type *
T) { Inherited::Visit(
T); }
242 void VisitAdjustedType(
const AdjustedType *
T) {
243 AddQualType(
T->getOriginalType());
246 void VisitDecayedType(
const DecayedType *
T) {
249 VisitAdjustedType(
T);
252 void VisitArrayType(
const ArrayType *
T) {
253 AddQualType(
T->getElementType());
254 Hash.AddInteger(llvm::to_underlying(
T->getSizeModifier()));
255 VisitQualifiers(
T->getIndexTypeQualifiers());
257 void VisitConstantArrayType(
const ConstantArrayType *
T) {
262 void VisitAttributedType(
const AttributedType *
T) {
263 Hash.AddInteger(
T->getAttrKind());
264 AddQualType(
T->getModifiedType());
267 void VisitBuiltinType(
const BuiltinType *
T) { Hash.AddInteger(
T->getKind()); }
269 void VisitComplexType(
const ComplexType *
T) {
270 AddQualType(
T->getElementType());
273 void VisitDecltypeType(
const DecltypeType *
T) {
274 AddQualType(
T->getUnderlyingType());
277 void VisitDeducedType(
const DeducedType *
T) {
278 AddQualType(
T->getDeducedType());
281 void VisitAutoType(
const AutoType *
T) { VisitDeducedType(
T); }
283 void VisitDeducedTemplateSpecializationType(
284 const DeducedTemplateSpecializationType *
T) {
285 Hash.AddTemplateName(
T->getTemplateName());
289 void VisitFunctionType(
const FunctionType *
T) {
297 void VisitFunctionNoProtoType(
const FunctionNoProtoType *
T) {
298 VisitFunctionType(
T);
301 void VisitFunctionProtoType(
const FunctionProtoType *
T) {
304 AddQualType(ParamType);
306 VisitFunctionType(
T);
309 void VisitMemberPointerType(
const MemberPointerType *
T) {
311 AddType(
T->getQualifier().getAsType());
312 if (
auto *RD =
T->getMostRecentCXXRecordDecl())
313 AddDecl(RD->getCanonicalDecl());
316 void VisitPackExpansionType(
const PackExpansionType *
T) {
317 AddQualType(
T->getPattern());
320 void VisitParenType(
const ParenType *
T) { AddQualType(
T->getInnerType()); }
322 void VisitPointerType(
const PointerType *
T) {
326 void VisitReferenceType(
const ReferenceType *
T) {
327 AddQualType(
T->getPointeeTypeAsWritten());
330 void VisitLValueReferenceType(
const LValueReferenceType *
T) {
331 VisitReferenceType(
T);
334 void VisitRValueReferenceType(
const RValueReferenceType *
T) {
335 VisitReferenceType(
T);
339 VisitSubstTemplateTypeParmPackType(
const SubstTemplateTypeParmPackType *
T) {
340 AddDecl(
T->getAssociatedDecl());
341 Hash.AddTemplateArgument(
T->getArgumentPack());
344 void VisitSubstTemplateTypeParmType(
const SubstTemplateTypeParmType *
T) {
345 AddDecl(
T->getAssociatedDecl());
346 AddQualType(
T->getReplacementType());
349 void VisitTagType(
const TagType *
T) { AddDecl(
T->getDecl()); }
351 void VisitRecordType(
const RecordType *
T) { VisitTagType(
T); }
352 void VisitEnumType(
const EnumType *
T) { VisitTagType(
T); }
354 void VisitTemplateSpecializationType(
const TemplateSpecializationType *
T) {
355 Hash.AddInteger(
T->template_arguments().size());
356 for (
const auto &TA :
T->template_arguments()) {
357 Hash.AddTemplateArgument(TA);
359 Hash.AddTemplateName(
T->getTemplateName());
362 void VisitTemplateTypeParmType(
const TemplateTypeParmType *
T) {
363 Hash.AddInteger(
T->getDepth());
364 Hash.AddInteger(
T->getIndex());
365 Hash.AddInteger(
T->isParameterPack());
368 void VisitTypedefType(
const TypedefType *
T) { AddDecl(
T->getDecl()); }
370 void VisitUnaryTransformType(
const UnaryTransformType *
T) {
371 AddQualType(
T->getUnderlyingType());
372 AddQualType(
T->getBaseType());
375 void VisitVectorType(
const VectorType *
T) {
376 AddQualType(
T->getElementType());
377 Hash.AddInteger(
T->getNumElements());
378 Hash.AddInteger(llvm::to_underlying(
T->getVectorKind()));
381 void VisitExtVectorType(
const ExtVectorType *
T) { VisitVectorType(
T); }
384void TemplateArgumentHasher::AddType(
const Type *
T) {
385 assert(
T &&
"Expecting non-null pointer.");
386 TypeVisitorHelper(ID, *
this).Visit(
T);
393 llvm::TimeTraceScope TimeScope(
"Stable Hash for Template Arguments");
394 TemplateArgumentHasher Hasher;
395 Hasher.AddInteger(Args.size());
397 Hasher.AddTemplateArgument(Arg);
398 return Hasher.getValue();
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
TemplateDecl * getCXXDeductionGuideTemplate() const
If this name is the name of a C++ deduction guide, return the template associated with that name.
const IdentifierInfo * getCXXLiteralIdentifier() const
If this name is the name of a literal operator, retrieve the identifier associated with it.
OverloadedOperatorKind getCXXOverloadedOperator() const
If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...
@ CXXConversionFunctionName
QualType getCXXNameType() const
If this name is one of the C++ names (of a constructor, destructor, or conversion function),...
NameKind getNameKind() const
Determine what kind of name this is.
bool isEmpty() const
Evaluates true when this declaration name is empty.
TemplateName getUnderlying() const
unsigned getNumParams() const
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx)
ArrayRef< QualType > getParamTypes() const
void Profile(llvm::FoldingSetNodeID &ID) const
ExtInfo getExtInfo() const
QualType getReturnType() const
StringRef getName() const
Return the actual identifier string.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
TemplateName getPattern() const
TemplateName getUnderlyingTemplate() const
Return the underlying template name.
uint64_t getAsOpaqueValue() const
Represents a template argument.
QualType getStructuralValueType() const
Get the type of a StructuralValue.
QualType getAsType() const
Retrieve the type for a type template argument.
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
unsigned pack_size() const
The number of template arguments in the given template argument pack.
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
ArrayRef< TemplateArgument > pack_elements() const
Iterator range referencing all of the elements of a template argument pack.
@ Declaration
The template argument is a declaration that was provided for a pointer, reference,...
@ Template
The template argument is a template name that was provided for a template template parameter.
@ StructuralValue
The template argument is a non-type template argument that can't be represented by the special-case D...
@ Pack
The template argument is actually a parameter pack.
@ TemplateExpansion
The template argument is a pack expansion of a template name that was provided for a template templat...
@ NullPtr
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
@ Type
The template argument is a type.
@ Null
Represents an empty template argument, e.g., one that has not been deduced.
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
ArgKind getKind() const
Return the kind of stored template argument.
TemplateName getAsTemplateOrTemplatePattern() const
Retrieve the template argument as a template name; if the argument is a pack expansion,...
const APValue & getAsStructuralValue() const
Get the value of a StructuralValue.
TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const
Retrieve the underlying template declaration that this template name refers to, if known.
DeducedTemplateStorage * getAsDeducedTemplateName() const
Retrieve the deduced template info, if any.
QualifiedTemplateName * getAsQualifiedTemplateName() const
Retrieve the underlying qualified template name structure, if any.
@ UsingTemplate
A template name that refers to a template declaration found through a specific using shadow declarati...
@ OverloadedTemplate
A set of overloaded template declarations.
@ PackIndexingTemplate
A pack-index-template-name.
@ Template
A single template declaration.
@ DependentTemplate
A dependent template name that has not been resolved to a template (or set of templates).
@ SubstTemplateTemplateParm
A template template parameter that has been substituted for some other template name.
@ SubstTemplateTemplateParmPack
A template template parameter pack that has been substituted for a template template argument pack,...
@ DeducedTemplate
A template name that refers to another TemplateName with deduced default arguments.
@ QualifiedTemplate
A qualified template name, where the qualification is kept to describe the source code as written.
@ AssumedTemplate
An unqualified-id that has been assumed to name a function template that will be found by ADL.
UsingShadowDecl * getAsUsingShadowDecl() const
Retrieve the using shadow declaration through which the underlying template declaration is introduced...
PackIndexingTemplateStorage * getAsPackIndexingTemplate() const
Retrieve the pack-index-template-name storage, if any.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
NamedDecl * getTargetDecl() const
Gets the underlying declaration which has been brought into the local scope.
unsigned StableHashForTemplateArguments(llvm::ArrayRef< TemplateArgument > Args)
Calculate a stable hash value for template arguments.
Top level wrappers for InstallAPI frontend operations.
@ TemplateName
The identifier is a template name. FIXME: Add an annotation for that.
const FunctionProtoType * T
@ Template
We are parsing a template declaration.
@ Type
The name was classified as a type.
const Type * Ty
The locally-unqualified type.
Qualifiers Quals
The local qualifiers.