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;
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);
56 void AddDecl(
const Decl *
D);
57 void AddStructuralValue(
const APValue &);
79 ID.AddPointer(
nullptr);
104 AddTemplateArgument(SubTA);
110void TemplateArgumentHasher::AddStructuralValue(
const APValue &
Value) {
126void TemplateArgumentHasher::AddTemplateName(
TemplateName Name) {
127 switch (Name.getKind()) {
129 AddDecl(Name.getAsTemplateDecl());
152 AddTemplateName(Name.getAsDeducedTemplateName()->getUnderlying());
157void TemplateArgumentHasher::AddIdentifierInfo(
const IdentifierInfo *II) {
158 assert(II &&
"Expecting non-null pointer.");
166 switch (Name.getNameKind()) {
168 AddIdentifierInfo(Name.getAsIdentifierInfo());
177 AddQualType(Name.getCXXNameType());
180 AddInteger(Name.getCXXOverloadedOperator());
183 AddIdentifierInfo(Name.getCXXLiteralIdentifier());
186 AddQualType(Name.getCXXNameType());
191 if (
auto *
Template = Name.getCXXDeductionGuideTemplate())
197void TemplateArgumentHasher::AddDecl(
const Decl *
D) {
207void TemplateArgumentHasher::AddQualType(
QualType T) {
220class TypeVisitorHelper :
public TypeVisitor<TypeVisitorHelper> {
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) {
255 AddQualType(
T->getOriginalType());
261 VisitAdjustedType(
T);
265 AddQualType(
T->getElementType());
266 Hash.AddInteger(llvm::to_underlying(
T->getSizeModifier()));
267 VisitQualifiers(
T->getIndexTypeQualifiers());
275 Hash.AddInteger(
T->getAttrKind());
276 AddQualType(
T->getModifiedType());
279 void VisitBuiltinType(
const BuiltinType *
T) { Hash.AddInteger(
T->getKind()); }
282 AddQualType(
T->getElementType());
286 AddQualType(
T->getUnderlyingType());
290 AddQualType(
T->getDeducedType());
293 void VisitAutoType(
const AutoType *
T) { VisitDeducedType(
T); }
295 void VisitDeducedTemplateSpecializationType(
297 Hash.AddTemplateName(
T->getTemplateName());
310 VisitFunctionType(
T);
316 AddQualType(ParamType);
318 VisitFunctionType(
T);
323 AddType(
T->getQualifier().getAsType());
324 if (
auto *RD =
T->getMostRecentCXXRecordDecl())
325 AddDecl(RD->getCanonicalDecl());
329 AddQualType(
T->getPattern());
332 void VisitParenType(
const ParenType *
T) { AddQualType(
T->getInnerType()); }
339 AddQualType(
T->getPointeeTypeAsWritten());
343 VisitReferenceType(
T);
347 VisitReferenceType(
T);
352 AddDecl(
T->getAssociatedDecl());
353 Hash.AddTemplateArgument(
T->getArgumentPack());
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); }
367 Hash.AddInteger(
T->template_arguments().size());
368 for (
const auto &TA :
T->template_arguments()) {
369 Hash.AddTemplateArgument(TA);
371 Hash.AddTemplateName(
T->getTemplateName());
375 Hash.AddInteger(
T->getDepth());
376 Hash.AddInteger(
T->getIndex());
377 Hash.AddInteger(
T->isParameterPack());
380 void VisitTypedefType(
const TypedefType *
T) { AddDecl(
T->getDecl()); }
383 AddQualType(
T->getUnderlyingType());
384 AddQualType(
T->getBaseType());
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.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Represents a type which was implicitly adjusted by the semantic engine for arbitrary reasons.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
An attributed type is a type to which a type attribute has been applied.
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
This class is used for builtin types like 'int'.
Complex values, per C99 6.2.5p11.
Represents the canonical version of C arrays with a specified constant size.
Represents a pointer type decayed from an array or function type.
Decl - This represents one declaration (or definition), e.g.
The name of a declaration.
@ CXXConversionFunctionName
Represents the type decltype(expr) (C++11).
Represents a C++17 deduced template specialization type.
Common base class for placeholders for types that get replaced by placeholder type deduction: C++11 a...
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
ExtVectorType - Extended vector type.
Represents a K&R-style 'int foo()' function, which has no information available about its arguments.
Represents a prototype with parameter type info, e.g.
unsigned getNumParams() const
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx)
ArrayRef< QualType > getParamTypes() const
void Profile(llvm::FoldingSetNodeID &ID) const
FunctionType - C99 6.7.5.3 - Function Declarators.
ExtInfo getExtInfo() const
QualType getReturnType() const
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
An lvalue reference type, per C++11 [dcl.ref].
A pointer to member type per C++ 8.3.3 - Pointers to members.
This represents a decl that may have a name.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Represents a pack expansion of types.
Sugar for parentheses used when specifying types.
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
Represents a template name as written in source code.
TemplateName getUnderlyingTemplate() const
Return the underlying template name.
The collection of all-type qualifiers we support.
uint64_t getAsOpaqueValue() const
An rvalue reference type, per C++11 [dcl.ref].
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Base for LValueReferenceType and RValueReferenceType.
Represents the result of substituting a set of types for a template type parameter pack.
Represents the result of substituting a type for a template type parameter.
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.
Represents a C++ template name within the type system.
@ 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.
Represents a type template specialization; the template must be a class template, a type alias templa...
RetTy Visit(const Type *T)
Performs the operation associated with this visitor object.
RetTy VisitType(const Type *)
Method called if ImpClass doesn't provide specific handler for some type class.
The base class of the type hierarchy.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
NamedDecl * getTargetDecl() const
Gets the underlying declaration which has been brought into the local scope.
Represents a GCC generic vector type.
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.
@ Template
We are parsing a template declaration.
const FunctionProtoType * T
A std::pair-like structure for storing a qualified type split into its local qualifiers and its local...
const Type * Ty
The locally-unqualified type.
Qualifiers Quals
The local qualifiers.