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) {
134void TemplateArgumentHasher::AddIdentifierInfo(
const IdentifierInfo *II) {
135 assert(II &&
"Expecting non-null pointer.");
139void TemplateArgumentHasher::AddDeclarationName(DeclarationName Name) {
173void TemplateArgumentHasher::AddDecl(
const Decl *D) {
174 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
184 ArrayRef<TemplateArgument> Args;
185 if (
auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D))
186 Args = CTSD->getTemplateArgs().asArray();
187 else if (
auto *VTSD = dyn_cast<VarTemplateSpecializationDecl>(D))
188 Args = VTSD->getTemplateArgs().asArray();
189 else if (
auto *FD = dyn_cast<FunctionDecl>(D))
190 if (FD->getTemplateSpecializationArgs())
191 Args = FD->getTemplateSpecializationArgs()->asArray();
193 for (
auto &TA : Args)
194 AddTemplateArgument(TA);
197void TemplateArgumentHasher::AddQualType(QualType
T) {
201 SplitQualType split =
T.split();
208class TypeVisitorHelper :
public TypeVisitor<TypeVisitorHelper> {
209 typedef TypeVisitor<TypeVisitorHelper> Inherited;
210 llvm::FoldingSetNodeID &
ID;
211 TemplateArgumentHasher &Hash;
214 TypeVisitorHelper(llvm::FoldingSetNodeID &ID, TemplateArgumentHasher &Hash)
215 :
ID(
ID), Hash(Hash) {}
217 void AddDecl(
const Decl *D) {
224 void AddQualType(QualType
T) { Hash.AddQualType(
T); }
226 void AddType(
const Type *
T) {
233 void VisitQualifiers(Qualifiers Quals) {
237 void Visit(
const Type *
T) { Inherited::Visit(
T); }
239 void VisitAdjustedType(
const AdjustedType *
T) {
240 AddQualType(
T->getOriginalType());
243 void VisitDecayedType(
const DecayedType *
T) {
246 VisitAdjustedType(
T);
249 void VisitArrayType(
const ArrayType *
T) {
250 AddQualType(
T->getElementType());
251 Hash.AddInteger(llvm::to_underlying(
T->getSizeModifier()));
252 VisitQualifiers(
T->getIndexTypeQualifiers());
254 void VisitConstantArrayType(
const ConstantArrayType *
T) {
259 void VisitAttributedType(
const AttributedType *
T) {
260 Hash.AddInteger(
T->getAttrKind());
261 AddQualType(
T->getModifiedType());
264 void VisitBuiltinType(
const BuiltinType *
T) { Hash.AddInteger(
T->getKind()); }
266 void VisitComplexType(
const ComplexType *
T) {
267 AddQualType(
T->getElementType());
270 void VisitDecltypeType(
const DecltypeType *
T) {
271 AddQualType(
T->getUnderlyingType());
274 void VisitDeducedType(
const DeducedType *
T) {
275 AddQualType(
T->getDeducedType());
278 void VisitAutoType(
const AutoType *
T) { VisitDeducedType(
T); }
280 void VisitDeducedTemplateSpecializationType(
281 const DeducedTemplateSpecializationType *
T) {
282 Hash.AddTemplateName(
T->getTemplateName());
286 void VisitFunctionType(
const FunctionType *
T) {
294 void VisitFunctionNoProtoType(
const FunctionNoProtoType *
T) {
295 VisitFunctionType(
T);
298 void VisitFunctionProtoType(
const FunctionProtoType *
T) {
301 AddQualType(ParamType);
303 VisitFunctionType(
T);
306 void VisitMemberPointerType(
const MemberPointerType *
T) {
308 AddType(
T->getQualifier().getAsType());
309 if (
auto *RD =
T->getMostRecentCXXRecordDecl())
310 AddDecl(RD->getCanonicalDecl());
313 void VisitPackExpansionType(
const PackExpansionType *
T) {
314 AddQualType(
T->getPattern());
317 void VisitParenType(
const ParenType *
T) { AddQualType(
T->getInnerType()); }
319 void VisitPointerType(
const PointerType *
T) {
323 void VisitReferenceType(
const ReferenceType *
T) {
324 AddQualType(
T->getPointeeTypeAsWritten());
327 void VisitLValueReferenceType(
const LValueReferenceType *
T) {
328 VisitReferenceType(
T);
331 void VisitRValueReferenceType(
const RValueReferenceType *
T) {
332 VisitReferenceType(
T);
336 VisitSubstTemplateTypeParmPackType(
const SubstTemplateTypeParmPackType *
T) {
337 AddDecl(
T->getAssociatedDecl());
338 Hash.AddTemplateArgument(
T->getArgumentPack());
341 void VisitSubstTemplateTypeParmType(
const SubstTemplateTypeParmType *
T) {
342 AddDecl(
T->getAssociatedDecl());
343 AddQualType(
T->getReplacementType());
346 void VisitTagType(
const TagType *
T) { AddDecl(
T->getDecl()); }
348 void VisitRecordType(
const RecordType *
T) { VisitTagType(
T); }
349 void VisitEnumType(
const EnumType *
T) { VisitTagType(
T); }
351 void VisitTemplateSpecializationType(
const TemplateSpecializationType *
T) {
352 Hash.AddInteger(
T->template_arguments().size());
353 for (
const auto &TA :
T->template_arguments()) {
354 Hash.AddTemplateArgument(TA);
356 Hash.AddTemplateName(
T->getTemplateName());
359 void VisitTemplateTypeParmType(
const TemplateTypeParmType *
T) {
360 Hash.AddInteger(
T->getDepth());
361 Hash.AddInteger(
T->getIndex());
362 Hash.AddInteger(
T->isParameterPack());
365 void VisitTypedefType(
const TypedefType *
T) { AddDecl(
T->getDecl()); }
367 void VisitUnaryTransformType(
const UnaryTransformType *
T) {
368 AddQualType(
T->getUnderlyingType());
369 AddQualType(
T->getBaseType());
372 void VisitVectorType(
const VectorType *
T) {
373 AddQualType(
T->getElementType());
374 Hash.AddInteger(
T->getNumElements());
375 Hash.AddInteger(llvm::to_underlying(
T->getVectorKind()));
378 void VisitExtVectorType(
const ExtVectorType *
T) { VisitVectorType(
T); }
381void TemplateArgumentHasher::AddType(
const Type *
T) {
382 assert(
T &&
"Expecting non-null pointer.");
383 TypeVisitorHelper(ID, *
this).Visit(
T);
390 llvm::TimeTraceScope TimeScope(
"Stable Hash for Template Arguments");
391 TemplateArgumentHasher Hasher;
392 Hasher.AddInteger(Args.size());
394 Hasher.AddTemplateArgument(Arg);
395 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 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.
@ 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...
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.
The JSON file list parser is used to communicate input to InstallAPI.
@ 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.