17#include "llvm/ADT/FoldingSet.h"
18#include "llvm/Support/TimeProfiler.h"
24class TemplateArgumentHasher {
33 bool BailedOut =
false;
34 static constexpr unsigned BailedOutValue = 0x12345678;
36 llvm::FoldingSetNodeID ID;
39 TemplateArgumentHasher() =
default;
41 void AddTemplateArgument(TemplateArgument TA);
43 void AddInteger(
unsigned V) { ID.AddInteger(
V); }
47 return BailedOutValue;
49 return ID.computeStableHash();
52 void setBailedOut() { BailedOut =
true; }
54 void AddType(
const Type *
T);
55 void AddQualType(QualType
T);
56 void AddDecl(
const Decl *D);
57 void AddStructuralValue(
const APValue &);
59 void AddDeclarationName(DeclarationName Name);
60 void AddIdentifierInfo(
const IdentifierInfo *II);
79 ID.AddPointer(
nullptr);
104 AddTemplateArgument(SubTA);
110void TemplateArgumentHasher::AddStructuralValue(
const APValue &
Value) {
126void TemplateArgumentHasher::AddTemplateName(
TemplateName Name) {
157void TemplateArgumentHasher::AddIdentifierInfo(
const IdentifierInfo *II) {
158 assert(II &&
"Expecting non-null pointer.");
162void TemplateArgumentHasher::AddDeclarationName(DeclarationName Name) {
197void TemplateArgumentHasher::AddDecl(
const Decl *D) {
198 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
207void TemplateArgumentHasher::AddQualType(QualType
T) {
212 SplitQualType split =
T.split();
220class TypeVisitorHelper :
public TypeVisitor<TypeVisitorHelper> {
221 typedef TypeVisitor<TypeVisitorHelper> Inherited;
222 llvm::FoldingSetNodeID &
ID;
223 TemplateArgumentHasher &Hash;
226 TypeVisitorHelper(llvm::FoldingSetNodeID &ID, TemplateArgumentHasher &Hash)
227 :
ID(
ID), Hash(Hash) {}
229 void AddDecl(
const Decl *D) {
236 void AddQualType(QualType
T) { Hash.AddQualType(
T); }
238 void AddType(
const Type *
T) {
245 void VisitQualifiers(Qualifiers Quals) {
249 void Visit(
const Type *
T) { Inherited::Visit(
T); }
252 void VisitType(
const Type *
T) { Hash.setBailedOut(); }
254 void VisitAdjustedType(
const AdjustedType *
T) {
255 AddQualType(
T->getOriginalType());
258 void VisitDecayedType(
const DecayedType *
T) {
261 VisitAdjustedType(
T);
264 void VisitArrayType(
const ArrayType *
T) {
265 AddQualType(
T->getElementType());
266 Hash.AddInteger(llvm::to_underlying(
T->getSizeModifier()));
267 VisitQualifiers(
T->getIndexTypeQualifiers());
269 void VisitConstantArrayType(
const ConstantArrayType *
T) {
274 void VisitAttributedType(
const AttributedType *
T) {
275 Hash.AddInteger(
T->getAttrKind());
276 AddQualType(
T->getModifiedType());
279 void VisitBuiltinType(
const BuiltinType *
T) { Hash.AddInteger(
T->getKind()); }
281 void VisitComplexType(
const ComplexType *
T) {
282 AddQualType(
T->getElementType());
285 void VisitDecltypeType(
const DecltypeType *
T) {
286 AddQualType(
T->getUnderlyingType());
289 void VisitDeducedType(
const DeducedType *
T) {
290 AddQualType(
T->getDeducedType());
293 void VisitAutoType(
const AutoType *
T) { VisitDeducedType(
T); }
295 void VisitDeducedTemplateSpecializationType(
296 const DeducedTemplateSpecializationType *
T) {
297 Hash.AddTemplateName(
T->getTemplateName());
301 void VisitFunctionType(
const FunctionType *
T) {
309 void VisitFunctionNoProtoType(
const FunctionNoProtoType *
T) {
310 VisitFunctionType(
T);
313 void VisitFunctionProtoType(
const FunctionProtoType *
T) {
316 AddQualType(ParamType);
318 VisitFunctionType(
T);
321 void VisitMemberPointerType(
const MemberPointerType *
T) {
323 AddType(
T->getQualifier().getAsType());
324 if (
auto *RD =
T->getMostRecentCXXRecordDecl())
325 AddDecl(RD->getCanonicalDecl());
328 void VisitPackExpansionType(
const PackExpansionType *
T) {
329 AddQualType(
T->getPattern());
332 void VisitParenType(
const ParenType *
T) { AddQualType(
T->getInnerType()); }
334 void VisitPointerType(
const PointerType *
T) {
338 void VisitReferenceType(
const ReferenceType *
T) {
339 AddQualType(
T->getPointeeTypeAsWritten());
342 void VisitLValueReferenceType(
const LValueReferenceType *
T) {
343 VisitReferenceType(
T);
346 void VisitRValueReferenceType(
const RValueReferenceType *
T) {
347 VisitReferenceType(
T);
351 VisitSubstTemplateTypeParmPackType(
const SubstTemplateTypeParmPackType *
T) {
352 AddDecl(
T->getAssociatedDecl());
353 Hash.AddTemplateArgument(
T->getArgumentPack());
356 void VisitSubstTemplateTypeParmType(
const SubstTemplateTypeParmType *
T) {
357 AddDecl(
T->getAssociatedDecl());
358 AddQualType(
T->getReplacementType());
361 void VisitTagType(
const TagType *
T) { AddDecl(
T->getOriginalDecl()); }
363 void VisitRecordType(
const RecordType *
T) { VisitTagType(
T); }
364 void VisitEnumType(
const EnumType *
T) { VisitTagType(
T); }
366 void VisitTemplateSpecializationType(
const TemplateSpecializationType *
T) {
367 Hash.AddInteger(
T->template_arguments().size());
368 for (
const auto &TA :
T->template_arguments()) {
369 Hash.AddTemplateArgument(TA);
371 Hash.AddTemplateName(
T->getTemplateName());
374 void VisitTemplateTypeParmType(
const TemplateTypeParmType *
T) {
375 Hash.AddInteger(
T->getDepth());
376 Hash.AddInteger(
T->getIndex());
377 Hash.AddInteger(
T->isParameterPack());
380 void VisitTypedefType(
const TypedefType *
T) { AddDecl(
T->getDecl()); }
382 void VisitUnaryTransformType(
const UnaryTransformType *
T) {
383 AddQualType(
T->getUnderlyingType());
384 AddQualType(
T->getBaseType());
387 void VisitVectorType(
const VectorType *
T) {
388 AddQualType(
T->getElementType());
389 Hash.AddInteger(
T->getNumElements());
390 Hash.AddInteger(llvm::to_underlying(
T->getVectorKind()));
393 void VisitExtVectorType(
const ExtVectorType *
T) { VisitVectorType(
T); }
396void TemplateArgumentHasher::AddType(
const Type *
T) {
397 assert(
T &&
"Expecting non-null pointer.");
398 TypeVisitorHelper(ID, *
this).Visit(
T);
405 llvm::TimeTraceScope TimeScope(
"Stable Hash for Template Arguments");
406 TemplateArgumentHasher Hasher;
407 Hasher.AddInteger(Args.size());
409 Hasher.AddTemplateArgument(Arg);
410 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.