[clang-tidy][NFC]remove deps of clang in clang tidy test (#116588)
[llvm-project.git] / clang / lib / AST / ODRHash.cpp
blob645ca6f0e7b715bf6424115ebfe6f2ac17e4e42a
1 //===-- ODRHash.cpp - Hashing to diagnose ODR failures ----------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// This file implements the ODRHash class, which calculates a hash based
11 /// on AST nodes, which is stable across different runs.
12 ///
13 //===----------------------------------------------------------------------===//
15 #include "clang/AST/ODRHash.h"
17 #include "clang/AST/DeclVisitor.h"
18 #include "clang/AST/NestedNameSpecifier.h"
19 #include "clang/AST/TypeVisitor.h"
21 using namespace clang;
23 void ODRHash::AddStmt(const Stmt *S) {
24 assert(S && "Expecting non-null pointer.");
25 S->ProcessODRHash(ID, *this);
28 void ODRHash::AddIdentifierInfo(const IdentifierInfo *II) {
29 assert(II && "Expecting non-null pointer.");
30 ID.AddString(II->getName());
33 void ODRHash::AddDeclarationName(DeclarationName Name, bool TreatAsDecl) {
34 if (TreatAsDecl)
35 // Matches the NamedDecl check in AddDecl
36 AddBoolean(true);
38 AddDeclarationNameImpl(Name);
40 if (TreatAsDecl)
41 // Matches the ClassTemplateSpecializationDecl check in AddDecl
42 AddBoolean(false);
45 void ODRHash::AddDeclarationNameImpl(DeclarationName Name) {
46 // Index all DeclarationName and use index numbers to refer to them.
47 auto Result = DeclNameMap.insert(std::make_pair(Name, DeclNameMap.size()));
48 ID.AddInteger(Result.first->second);
49 if (!Result.second) {
50 // If found in map, the DeclarationName has previously been processed.
51 return;
54 // First time processing each DeclarationName, also process its details.
55 AddBoolean(Name.isEmpty());
56 if (Name.isEmpty())
57 return;
59 auto Kind = Name.getNameKind();
60 ID.AddInteger(Kind);
61 switch (Kind) {
62 case DeclarationName::Identifier:
63 AddIdentifierInfo(Name.getAsIdentifierInfo());
64 break;
65 case DeclarationName::ObjCZeroArgSelector:
66 case DeclarationName::ObjCOneArgSelector:
67 case DeclarationName::ObjCMultiArgSelector: {
68 Selector S = Name.getObjCSelector();
69 AddBoolean(S.isNull());
70 AddBoolean(S.isKeywordSelector());
71 AddBoolean(S.isUnarySelector());
72 unsigned NumArgs = S.getNumArgs();
73 ID.AddInteger(NumArgs);
74 // Compare all selector slots. For selectors with arguments it means all arg
75 // slots. And if there are no arguments, compare the first-and-only slot.
76 unsigned SlotsToCheck = NumArgs > 0 ? NumArgs : 1;
77 for (unsigned i = 0; i < SlotsToCheck; ++i) {
78 const IdentifierInfo *II = S.getIdentifierInfoForSlot(i);
79 AddBoolean(II);
80 if (II) {
81 AddIdentifierInfo(II);
84 break;
86 case DeclarationName::CXXConstructorName:
87 case DeclarationName::CXXDestructorName:
88 AddQualType(Name.getCXXNameType());
89 break;
90 case DeclarationName::CXXOperatorName:
91 ID.AddInteger(Name.getCXXOverloadedOperator());
92 break;
93 case DeclarationName::CXXLiteralOperatorName:
94 AddIdentifierInfo(Name.getCXXLiteralIdentifier());
95 break;
96 case DeclarationName::CXXConversionFunctionName:
97 AddQualType(Name.getCXXNameType());
98 break;
99 case DeclarationName::CXXUsingDirective:
100 break;
101 case DeclarationName::CXXDeductionGuideName: {
102 auto *Template = Name.getCXXDeductionGuideTemplate();
103 AddBoolean(Template);
104 if (Template) {
105 AddDecl(Template);
111 void ODRHash::AddNestedNameSpecifier(const NestedNameSpecifier *NNS) {
112 assert(NNS && "Expecting non-null pointer.");
113 const auto *Prefix = NNS->getPrefix();
114 AddBoolean(Prefix);
115 if (Prefix) {
116 AddNestedNameSpecifier(Prefix);
118 auto Kind = NNS->getKind();
119 ID.AddInteger(Kind);
120 switch (Kind) {
121 case NestedNameSpecifier::Identifier:
122 AddIdentifierInfo(NNS->getAsIdentifier());
123 break;
124 case NestedNameSpecifier::Namespace:
125 AddDecl(NNS->getAsNamespace());
126 break;
127 case NestedNameSpecifier::NamespaceAlias:
128 AddDecl(NNS->getAsNamespaceAlias());
129 break;
130 case NestedNameSpecifier::TypeSpec:
131 case NestedNameSpecifier::TypeSpecWithTemplate:
132 AddType(NNS->getAsType());
133 break;
134 case NestedNameSpecifier::Global:
135 case NestedNameSpecifier::Super:
136 break;
140 void ODRHash::AddTemplateName(TemplateName Name) {
141 auto Kind = Name.getKind();
142 ID.AddInteger(Kind);
144 switch (Kind) {
145 case TemplateName::Template:
146 AddDecl(Name.getAsTemplateDecl());
147 break;
148 case TemplateName::QualifiedTemplate: {
149 QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName();
150 if (NestedNameSpecifier *NNS = QTN->getQualifier())
151 AddNestedNameSpecifier(NNS);
152 AddBoolean(QTN->hasTemplateKeyword());
153 AddTemplateName(QTN->getUnderlyingTemplate());
154 break;
156 // TODO: Support these cases.
157 case TemplateName::OverloadedTemplate:
158 case TemplateName::AssumedTemplate:
159 case TemplateName::DependentTemplate:
160 case TemplateName::SubstTemplateTemplateParm:
161 case TemplateName::SubstTemplateTemplateParmPack:
162 case TemplateName::UsingTemplate:
163 break;
164 case TemplateName::DeducedTemplate:
165 llvm_unreachable("Unexpected DeducedTemplate");
169 void ODRHash::AddTemplateArgument(TemplateArgument TA) {
170 const auto Kind = TA.getKind();
171 ID.AddInteger(Kind);
173 switch (Kind) {
174 case TemplateArgument::Null:
175 llvm_unreachable("Expected valid TemplateArgument");
176 case TemplateArgument::Type:
177 AddQualType(TA.getAsType());
178 break;
179 case TemplateArgument::Declaration:
180 AddDecl(TA.getAsDecl());
181 break;
182 case TemplateArgument::NullPtr:
183 ID.AddPointer(nullptr);
184 break;
185 case TemplateArgument::Integral: {
186 // There are integrals (e.g.: _BitInt(128)) that cannot be represented as
187 // any builtin integral type, so we use the hash of APSInt instead.
188 TA.getAsIntegral().Profile(ID);
189 break;
191 case TemplateArgument::StructuralValue:
192 AddQualType(TA.getStructuralValueType());
193 AddStructuralValue(TA.getAsStructuralValue());
194 break;
195 case TemplateArgument::Template:
196 case TemplateArgument::TemplateExpansion:
197 AddTemplateName(TA.getAsTemplateOrTemplatePattern());
198 break;
199 case TemplateArgument::Expression:
200 AddStmt(TA.getAsExpr());
201 break;
202 case TemplateArgument::Pack:
203 ID.AddInteger(TA.pack_size());
204 for (auto SubTA : TA.pack_elements()) {
205 AddTemplateArgument(SubTA);
207 break;
211 void ODRHash::AddTemplateParameterList(const TemplateParameterList *TPL) {
212 assert(TPL && "Expecting non-null pointer.");
214 ID.AddInteger(TPL->size());
215 for (auto *ND : TPL->asArray()) {
216 AddSubDecl(ND);
220 void ODRHash::clear() {
221 DeclNameMap.clear();
222 Bools.clear();
223 ID.clear();
226 unsigned ODRHash::CalculateHash() {
227 // Append the bools to the end of the data segment backwards. This allows
228 // for the bools data to be compressed 32 times smaller compared to using
229 // ID.AddBoolean
230 const unsigned unsigned_bits = sizeof(unsigned) * CHAR_BIT;
231 const unsigned size = Bools.size();
232 const unsigned remainder = size % unsigned_bits;
233 const unsigned loops = size / unsigned_bits;
234 auto I = Bools.rbegin();
235 unsigned value = 0;
236 for (unsigned i = 0; i < remainder; ++i) {
237 value <<= 1;
238 value |= *I;
239 ++I;
241 ID.AddInteger(value);
243 for (unsigned i = 0; i < loops; ++i) {
244 value = 0;
245 for (unsigned j = 0; j < unsigned_bits; ++j) {
246 value <<= 1;
247 value |= *I;
248 ++I;
250 ID.AddInteger(value);
253 assert(I == Bools.rend());
254 Bools.clear();
255 return ID.computeStableHash();
258 namespace {
259 // Process a Decl pointer. Add* methods call back into ODRHash while Visit*
260 // methods process the relevant parts of the Decl.
261 class ODRDeclVisitor : public ConstDeclVisitor<ODRDeclVisitor> {
262 typedef ConstDeclVisitor<ODRDeclVisitor> Inherited;
263 llvm::FoldingSetNodeID &ID;
264 ODRHash &Hash;
266 public:
267 ODRDeclVisitor(llvm::FoldingSetNodeID &ID, ODRHash &Hash)
268 : ID(ID), Hash(Hash) {}
270 void AddStmt(const Stmt *S) {
271 Hash.AddBoolean(S);
272 if (S) {
273 Hash.AddStmt(S);
277 void AddIdentifierInfo(const IdentifierInfo *II) {
278 Hash.AddBoolean(II);
279 if (II) {
280 Hash.AddIdentifierInfo(II);
284 void AddQualType(QualType T) {
285 Hash.AddQualType(T);
288 void AddDecl(const Decl *D) {
289 Hash.AddBoolean(D);
290 if (D) {
291 Hash.AddDecl(D);
295 void AddTemplateArgument(TemplateArgument TA) {
296 Hash.AddTemplateArgument(TA);
299 void Visit(const Decl *D) {
300 ID.AddInteger(D->getKind());
301 Inherited::Visit(D);
304 void VisitNamedDecl(const NamedDecl *D) {
305 Hash.AddDeclarationName(D->getDeclName());
306 Inherited::VisitNamedDecl(D);
309 void VisitValueDecl(const ValueDecl *D) {
310 if (auto *DD = dyn_cast<DeclaratorDecl>(D); DD && DD->getTypeSourceInfo())
311 AddQualType(DD->getTypeSourceInfo()->getType());
313 Inherited::VisitValueDecl(D);
316 void VisitVarDecl(const VarDecl *D) {
317 Hash.AddBoolean(D->isStaticLocal());
318 Hash.AddBoolean(D->isConstexpr());
319 const bool HasInit = D->hasInit();
320 Hash.AddBoolean(HasInit);
321 if (HasInit) {
322 AddStmt(D->getInit());
324 Inherited::VisitVarDecl(D);
327 void VisitParmVarDecl(const ParmVarDecl *D) {
328 // TODO: Handle default arguments.
329 Inherited::VisitParmVarDecl(D);
332 void VisitAccessSpecDecl(const AccessSpecDecl *D) {
333 ID.AddInteger(D->getAccess());
334 Inherited::VisitAccessSpecDecl(D);
337 void VisitStaticAssertDecl(const StaticAssertDecl *D) {
338 AddStmt(D->getAssertExpr());
339 AddStmt(D->getMessage());
341 Inherited::VisitStaticAssertDecl(D);
344 void VisitFieldDecl(const FieldDecl *D) {
345 const bool IsBitfield = D->isBitField();
346 Hash.AddBoolean(IsBitfield);
348 if (IsBitfield) {
349 AddStmt(D->getBitWidth());
352 Hash.AddBoolean(D->isMutable());
353 AddStmt(D->getInClassInitializer());
355 Inherited::VisitFieldDecl(D);
358 void VisitObjCIvarDecl(const ObjCIvarDecl *D) {
359 ID.AddInteger(D->getCanonicalAccessControl());
360 Inherited::VisitObjCIvarDecl(D);
363 void VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
364 ID.AddInteger(D->getPropertyAttributes());
365 ID.AddInteger(D->getPropertyImplementation());
366 AddQualType(D->getTypeSourceInfo()->getType());
367 AddDecl(D);
369 Inherited::VisitObjCPropertyDecl(D);
372 void VisitFunctionDecl(const FunctionDecl *D) {
373 // Handled by the ODRHash for FunctionDecl
374 ID.AddInteger(D->getODRHash());
376 Inherited::VisitFunctionDecl(D);
379 void VisitCXXMethodDecl(const CXXMethodDecl *D) {
380 // Handled by the ODRHash for FunctionDecl
382 Inherited::VisitCXXMethodDecl(D);
385 void VisitObjCMethodDecl(const ObjCMethodDecl *Method) {
386 ID.AddInteger(Method->getDeclKind());
387 Hash.AddBoolean(Method->isInstanceMethod()); // false if class method
388 Hash.AddBoolean(Method->isVariadic());
389 Hash.AddBoolean(Method->isSynthesizedAccessorStub());
390 Hash.AddBoolean(Method->isDefined());
391 Hash.AddBoolean(Method->isDirectMethod());
392 Hash.AddBoolean(Method->isThisDeclarationADesignatedInitializer());
393 Hash.AddBoolean(Method->hasSkippedBody());
395 ID.AddInteger(llvm::to_underlying(Method->getImplementationControl()));
396 ID.AddInteger(Method->getMethodFamily());
397 ImplicitParamDecl *Cmd = Method->getCmdDecl();
398 Hash.AddBoolean(Cmd);
399 if (Cmd)
400 ID.AddInteger(llvm::to_underlying(Cmd->getParameterKind()));
402 ImplicitParamDecl *Self = Method->getSelfDecl();
403 Hash.AddBoolean(Self);
404 if (Self)
405 ID.AddInteger(llvm::to_underlying(Self->getParameterKind()));
407 AddDecl(Method);
409 if (Method->getReturnTypeSourceInfo())
410 AddQualType(Method->getReturnTypeSourceInfo()->getType());
412 ID.AddInteger(Method->param_size());
413 for (auto Param : Method->parameters())
414 Hash.AddSubDecl(Param);
416 if (Method->hasBody()) {
417 const bool IsDefinition = Method->isThisDeclarationADefinition();
418 Hash.AddBoolean(IsDefinition);
419 if (IsDefinition) {
420 Stmt *Body = Method->getBody();
421 Hash.AddBoolean(Body);
422 if (Body)
423 AddStmt(Body);
425 // Filter out sub-Decls which will not be processed in order to get an
426 // accurate count of Decl's.
427 llvm::SmallVector<const Decl *, 16> Decls;
428 for (Decl *SubDecl : Method->decls())
429 if (ODRHash::isSubDeclToBeProcessed(SubDecl, Method))
430 Decls.push_back(SubDecl);
432 ID.AddInteger(Decls.size());
433 for (auto SubDecl : Decls)
434 Hash.AddSubDecl(SubDecl);
436 } else {
437 Hash.AddBoolean(false);
440 Inherited::VisitObjCMethodDecl(Method);
443 void VisitTypedefNameDecl(const TypedefNameDecl *D) {
444 AddQualType(D->getUnderlyingType());
446 Inherited::VisitTypedefNameDecl(D);
449 void VisitTypedefDecl(const TypedefDecl *D) {
450 Inherited::VisitTypedefDecl(D);
453 void VisitTypeAliasDecl(const TypeAliasDecl *D) {
454 Inherited::VisitTypeAliasDecl(D);
457 void VisitFriendDecl(const FriendDecl *D) {
458 TypeSourceInfo *TSI = D->getFriendType();
459 Hash.AddBoolean(TSI);
460 if (TSI) {
461 AddQualType(TSI->getType());
462 } else {
463 AddDecl(D->getFriendDecl());
465 Hash.AddBoolean(D->isPackExpansion());
468 void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
469 // Only care about default arguments as part of the definition.
470 const bool hasDefaultArgument =
471 D->hasDefaultArgument() && !D->defaultArgumentWasInherited();
472 Hash.AddBoolean(hasDefaultArgument);
473 if (hasDefaultArgument) {
474 AddTemplateArgument(D->getDefaultArgument().getArgument());
476 Hash.AddBoolean(D->isParameterPack());
478 const TypeConstraint *TC = D->getTypeConstraint();
479 Hash.AddBoolean(TC != nullptr);
480 if (TC)
481 AddStmt(TC->getImmediatelyDeclaredConstraint());
483 Inherited::VisitTemplateTypeParmDecl(D);
486 void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
487 // Only care about default arguments as part of the definition.
488 const bool hasDefaultArgument =
489 D->hasDefaultArgument() && !D->defaultArgumentWasInherited();
490 Hash.AddBoolean(hasDefaultArgument);
491 if (hasDefaultArgument) {
492 AddTemplateArgument(D->getDefaultArgument().getArgument());
494 Hash.AddBoolean(D->isParameterPack());
496 Inherited::VisitNonTypeTemplateParmDecl(D);
499 void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D) {
500 // Only care about default arguments as part of the definition.
501 const bool hasDefaultArgument =
502 D->hasDefaultArgument() && !D->defaultArgumentWasInherited();
503 Hash.AddBoolean(hasDefaultArgument);
504 if (hasDefaultArgument) {
505 AddTemplateArgument(D->getDefaultArgument().getArgument());
507 Hash.AddBoolean(D->isParameterPack());
509 Inherited::VisitTemplateTemplateParmDecl(D);
512 void VisitTemplateDecl(const TemplateDecl *D) {
513 Hash.AddTemplateParameterList(D->getTemplateParameters());
515 Inherited::VisitTemplateDecl(D);
518 void VisitRedeclarableTemplateDecl(const RedeclarableTemplateDecl *D) {
519 Hash.AddBoolean(D->isMemberSpecialization());
520 Inherited::VisitRedeclarableTemplateDecl(D);
523 void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
524 AddDecl(D->getTemplatedDecl());
525 ID.AddInteger(D->getTemplatedDecl()->getODRHash());
526 Inherited::VisitFunctionTemplateDecl(D);
529 void VisitEnumConstantDecl(const EnumConstantDecl *D) {
530 AddStmt(D->getInitExpr());
531 Inherited::VisitEnumConstantDecl(D);
534 } // namespace
536 // Only allow a small portion of Decl's to be processed. Remove this once
537 // all Decl's can be handled.
538 bool ODRHash::isSubDeclToBeProcessed(const Decl *D, const DeclContext *Parent) {
539 if (D->isImplicit()) return false;
540 if (D->getDeclContext() != Parent) return false;
542 switch (D->getKind()) {
543 default:
544 return false;
545 case Decl::AccessSpec:
546 case Decl::CXXConstructor:
547 case Decl::CXXDestructor:
548 case Decl::CXXMethod:
549 case Decl::EnumConstant: // Only found in EnumDecl's.
550 case Decl::Field:
551 case Decl::Friend:
552 case Decl::FunctionTemplate:
553 case Decl::StaticAssert:
554 case Decl::TypeAlias:
555 case Decl::Typedef:
556 case Decl::Var:
557 case Decl::ObjCMethod:
558 case Decl::ObjCIvar:
559 case Decl::ObjCProperty:
560 return true;
564 void ODRHash::AddSubDecl(const Decl *D) {
565 assert(D && "Expecting non-null pointer.");
567 ODRDeclVisitor(ID, *this).Visit(D);
570 void ODRHash::AddCXXRecordDecl(const CXXRecordDecl *Record) {
571 assert(Record && Record->hasDefinition() &&
572 "Expected non-null record to be a definition.");
574 const DeclContext *DC = Record;
575 while (DC) {
576 if (isa<ClassTemplateSpecializationDecl>(DC)) {
577 return;
579 DC = DC->getParent();
582 AddDecl(Record);
584 // Filter out sub-Decls which will not be processed in order to get an
585 // accurate count of Decl's.
586 llvm::SmallVector<const Decl *, 16> Decls;
587 for (Decl *SubDecl : Record->decls()) {
588 if (isSubDeclToBeProcessed(SubDecl, Record)) {
589 Decls.push_back(SubDecl);
590 if (auto *Function = dyn_cast<FunctionDecl>(SubDecl)) {
591 // Compute/Preload ODRHash into FunctionDecl.
592 Function->getODRHash();
597 ID.AddInteger(Decls.size());
598 for (auto SubDecl : Decls) {
599 AddSubDecl(SubDecl);
602 const ClassTemplateDecl *TD = Record->getDescribedClassTemplate();
603 AddBoolean(TD);
604 if (TD) {
605 AddTemplateParameterList(TD->getTemplateParameters());
608 ID.AddInteger(Record->getNumBases());
609 auto Bases = Record->bases();
610 for (const auto &Base : Bases) {
611 AddQualType(Base.getTypeSourceInfo()->getType());
612 ID.AddInteger(Base.isVirtual());
613 ID.AddInteger(Base.getAccessSpecifierAsWritten());
617 void ODRHash::AddRecordDecl(const RecordDecl *Record) {
618 assert(!isa<CXXRecordDecl>(Record) &&
619 "For CXXRecordDecl should call AddCXXRecordDecl.");
620 AddDecl(Record);
622 // Filter out sub-Decls which will not be processed in order to get an
623 // accurate count of Decl's.
624 llvm::SmallVector<const Decl *, 16> Decls;
625 for (Decl *SubDecl : Record->decls()) {
626 if (isSubDeclToBeProcessed(SubDecl, Record))
627 Decls.push_back(SubDecl);
630 ID.AddInteger(Decls.size());
631 for (const Decl *SubDecl : Decls)
632 AddSubDecl(SubDecl);
635 void ODRHash::AddObjCInterfaceDecl(const ObjCInterfaceDecl *IF) {
636 AddDecl(IF);
638 auto *SuperClass = IF->getSuperClass();
639 AddBoolean(SuperClass);
640 if (SuperClass)
641 ID.AddInteger(SuperClass->getODRHash());
643 // Hash referenced protocols.
644 ID.AddInteger(IF->getReferencedProtocols().size());
645 for (const ObjCProtocolDecl *RefP : IF->protocols()) {
646 // Hash the name only as a referenced protocol can be a forward declaration.
647 AddDeclarationName(RefP->getDeclName());
650 // Filter out sub-Decls which will not be processed in order to get an
651 // accurate count of Decl's.
652 llvm::SmallVector<const Decl *, 16> Decls;
653 for (Decl *SubDecl : IF->decls())
654 if (isSubDeclToBeProcessed(SubDecl, IF))
655 Decls.push_back(SubDecl);
657 ID.AddInteger(Decls.size());
658 for (auto *SubDecl : Decls)
659 AddSubDecl(SubDecl);
662 void ODRHash::AddFunctionDecl(const FunctionDecl *Function,
663 bool SkipBody) {
664 assert(Function && "Expecting non-null pointer.");
666 // Skip functions that are specializations or in specialization context.
667 const DeclContext *DC = Function;
668 while (DC) {
669 if (isa<ClassTemplateSpecializationDecl>(DC)) return;
670 if (auto *F = dyn_cast<FunctionDecl>(DC)) {
671 if (F->isFunctionTemplateSpecialization()) {
672 if (!isa<CXXMethodDecl>(DC)) return;
673 if (DC->getLexicalParent()->isFileContext()) return;
674 // Skip class scope explicit function template specializations,
675 // as they have not yet been instantiated.
676 if (F->getDependentSpecializationInfo())
677 return;
678 // Inline method specializations are the only supported
679 // specialization for now.
682 DC = DC->getParent();
685 ID.AddInteger(Function->getDeclKind());
687 const auto *SpecializationArgs = Function->getTemplateSpecializationArgs();
688 AddBoolean(SpecializationArgs);
689 if (SpecializationArgs) {
690 ID.AddInteger(SpecializationArgs->size());
691 for (const TemplateArgument &TA : SpecializationArgs->asArray()) {
692 AddTemplateArgument(TA);
696 if (const auto *Method = dyn_cast<CXXMethodDecl>(Function)) {
697 AddBoolean(Method->isConst());
698 AddBoolean(Method->isVolatile());
701 ID.AddInteger(Function->getStorageClass());
702 AddBoolean(Function->isInlineSpecified());
703 AddBoolean(Function->isVirtualAsWritten());
704 AddBoolean(Function->isPureVirtual());
705 AddBoolean(Function->isDeletedAsWritten());
706 AddBoolean(Function->isExplicitlyDefaulted());
708 StringLiteral *DeletedMessage = Function->getDeletedMessage();
709 AddBoolean(DeletedMessage);
711 if (DeletedMessage)
712 ID.AddString(DeletedMessage->getBytes());
714 AddDecl(Function);
716 AddQualType(Function->getReturnType());
718 ID.AddInteger(Function->param_size());
719 for (auto *Param : Function->parameters())
720 AddSubDecl(Param);
722 if (SkipBody) {
723 AddBoolean(false);
724 return;
727 const bool HasBody = Function->isThisDeclarationADefinition() &&
728 !Function->isDefaulted() && !Function->isDeleted() &&
729 !Function->isLateTemplateParsed();
730 AddBoolean(HasBody);
731 if (!HasBody) {
732 return;
735 auto *Body = Function->getBody();
736 AddBoolean(Body);
737 if (Body)
738 AddStmt(Body);
740 // Filter out sub-Decls which will not be processed in order to get an
741 // accurate count of Decl's.
742 llvm::SmallVector<const Decl *, 16> Decls;
743 for (Decl *SubDecl : Function->decls()) {
744 if (isSubDeclToBeProcessed(SubDecl, Function)) {
745 Decls.push_back(SubDecl);
749 ID.AddInteger(Decls.size());
750 for (auto SubDecl : Decls) {
751 AddSubDecl(SubDecl);
755 void ODRHash::AddEnumDecl(const EnumDecl *Enum) {
756 assert(Enum);
757 AddDeclarationName(Enum->getDeclName());
759 AddBoolean(Enum->isScoped());
760 if (Enum->isScoped())
761 AddBoolean(Enum->isScopedUsingClassTag());
763 if (Enum->getIntegerTypeSourceInfo())
764 AddQualType(Enum->getIntegerType().getCanonicalType());
766 // Filter out sub-Decls which will not be processed in order to get an
767 // accurate count of Decl's.
768 llvm::SmallVector<const Decl *, 16> Decls;
769 for (Decl *SubDecl : Enum->decls()) {
770 if (isSubDeclToBeProcessed(SubDecl, Enum)) {
771 assert(isa<EnumConstantDecl>(SubDecl) && "Unexpected Decl");
772 Decls.push_back(SubDecl);
776 ID.AddInteger(Decls.size());
777 for (auto SubDecl : Decls) {
778 AddSubDecl(SubDecl);
783 void ODRHash::AddObjCProtocolDecl(const ObjCProtocolDecl *P) {
784 AddDecl(P);
786 // Hash referenced protocols.
787 ID.AddInteger(P->getReferencedProtocols().size());
788 for (const ObjCProtocolDecl *RefP : P->protocols()) {
789 // Hash the name only as a referenced protocol can be a forward declaration.
790 AddDeclarationName(RefP->getDeclName());
793 // Filter out sub-Decls which will not be processed in order to get an
794 // accurate count of Decl's.
795 llvm::SmallVector<const Decl *, 16> Decls;
796 for (Decl *SubDecl : P->decls()) {
797 if (isSubDeclToBeProcessed(SubDecl, P)) {
798 Decls.push_back(SubDecl);
802 ID.AddInteger(Decls.size());
803 for (auto *SubDecl : Decls) {
804 AddSubDecl(SubDecl);
808 void ODRHash::AddDecl(const Decl *D) {
809 assert(D && "Expecting non-null pointer.");
810 D = D->getCanonicalDecl();
812 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
813 AddBoolean(ND);
814 if (!ND) {
815 ID.AddInteger(D->getKind());
816 return;
819 AddDeclarationName(ND->getDeclName());
821 const auto *Specialization =
822 dyn_cast<ClassTemplateSpecializationDecl>(D);
823 AddBoolean(Specialization);
824 if (Specialization) {
825 const TemplateArgumentList &List = Specialization->getTemplateArgs();
826 ID.AddInteger(List.size());
827 for (const TemplateArgument &TA : List.asArray())
828 AddTemplateArgument(TA);
832 namespace {
833 // Process a Type pointer. Add* methods call back into ODRHash while Visit*
834 // methods process the relevant parts of the Type.
835 class ODRTypeVisitor : public TypeVisitor<ODRTypeVisitor> {
836 typedef TypeVisitor<ODRTypeVisitor> Inherited;
837 llvm::FoldingSetNodeID &ID;
838 ODRHash &Hash;
840 public:
841 ODRTypeVisitor(llvm::FoldingSetNodeID &ID, ODRHash &Hash)
842 : ID(ID), Hash(Hash) {}
844 void AddStmt(Stmt *S) {
845 Hash.AddBoolean(S);
846 if (S) {
847 Hash.AddStmt(S);
851 void AddDecl(const Decl *D) {
852 Hash.AddBoolean(D);
853 if (D) {
854 Hash.AddDecl(D);
858 void AddQualType(QualType T) {
859 Hash.AddQualType(T);
862 void AddType(const Type *T) {
863 Hash.AddBoolean(T);
864 if (T) {
865 Hash.AddType(T);
869 void AddNestedNameSpecifier(const NestedNameSpecifier *NNS) {
870 Hash.AddBoolean(NNS);
871 if (NNS) {
872 Hash.AddNestedNameSpecifier(NNS);
876 void AddIdentifierInfo(const IdentifierInfo *II) {
877 Hash.AddBoolean(II);
878 if (II) {
879 Hash.AddIdentifierInfo(II);
883 void VisitQualifiers(Qualifiers Quals) {
884 ID.AddInteger(Quals.getAsOpaqueValue());
887 // Return the RecordType if the typedef only strips away a keyword.
888 // Otherwise, return the original type.
889 static const Type *RemoveTypedef(const Type *T) {
890 const auto *TypedefT = dyn_cast<TypedefType>(T);
891 if (!TypedefT) {
892 return T;
895 const TypedefNameDecl *D = TypedefT->getDecl();
896 QualType UnderlyingType = D->getUnderlyingType();
898 if (UnderlyingType.hasLocalQualifiers()) {
899 return T;
902 const auto *ElaboratedT = dyn_cast<ElaboratedType>(UnderlyingType);
903 if (!ElaboratedT) {
904 return T;
907 if (ElaboratedT->getQualifier() != nullptr) {
908 return T;
911 QualType NamedType = ElaboratedT->getNamedType();
912 if (NamedType.hasLocalQualifiers()) {
913 return T;
916 const auto *RecordT = dyn_cast<RecordType>(NamedType);
917 if (!RecordT) {
918 return T;
921 const IdentifierInfo *TypedefII = TypedefT->getDecl()->getIdentifier();
922 const IdentifierInfo *RecordII = RecordT->getDecl()->getIdentifier();
923 if (!TypedefII || !RecordII ||
924 TypedefII->getName() != RecordII->getName()) {
925 return T;
928 return RecordT;
931 void Visit(const Type *T) {
932 T = RemoveTypedef(T);
933 ID.AddInteger(T->getTypeClass());
934 Inherited::Visit(T);
937 void VisitType(const Type *T) {}
939 void VisitAdjustedType(const AdjustedType *T) {
940 AddQualType(T->getOriginalType());
942 VisitType(T);
945 void VisitDecayedType(const DecayedType *T) {
946 // getDecayedType and getPointeeType are derived from getAdjustedType
947 // and don't need to be separately processed.
948 VisitAdjustedType(T);
951 void VisitArrayType(const ArrayType *T) {
952 AddQualType(T->getElementType());
953 ID.AddInteger(llvm::to_underlying(T->getSizeModifier()));
954 VisitQualifiers(T->getIndexTypeQualifiers());
955 VisitType(T);
957 void VisitConstantArrayType(const ConstantArrayType *T) {
958 T->getSize().Profile(ID);
959 VisitArrayType(T);
962 void VisitArrayParameterType(const ArrayParameterType *T) {
963 VisitConstantArrayType(T);
966 void VisitDependentSizedArrayType(const DependentSizedArrayType *T) {
967 AddStmt(T->getSizeExpr());
968 VisitArrayType(T);
971 void VisitIncompleteArrayType(const IncompleteArrayType *T) {
972 VisitArrayType(T);
975 void VisitVariableArrayType(const VariableArrayType *T) {
976 AddStmt(T->getSizeExpr());
977 VisitArrayType(T);
980 void VisitAttributedType(const AttributedType *T) {
981 ID.AddInteger(T->getAttrKind());
982 AddQualType(T->getModifiedType());
984 VisitType(T);
987 void VisitBlockPointerType(const BlockPointerType *T) {
988 AddQualType(T->getPointeeType());
989 VisitType(T);
992 void VisitBuiltinType(const BuiltinType *T) {
993 ID.AddInteger(T->getKind());
994 VisitType(T);
997 void VisitComplexType(const ComplexType *T) {
998 AddQualType(T->getElementType());
999 VisitType(T);
1002 void VisitDecltypeType(const DecltypeType *T) {
1003 AddStmt(T->getUnderlyingExpr());
1004 VisitType(T);
1007 void VisitDependentDecltypeType(const DependentDecltypeType *T) {
1008 VisitDecltypeType(T);
1011 void VisitDeducedType(const DeducedType *T) {
1012 AddQualType(T->getDeducedType());
1013 VisitType(T);
1016 void VisitAutoType(const AutoType *T) {
1017 ID.AddInteger((unsigned)T->getKeyword());
1018 ID.AddInteger(T->isConstrained());
1019 if (T->isConstrained()) {
1020 AddDecl(T->getTypeConstraintConcept());
1021 ID.AddInteger(T->getTypeConstraintArguments().size());
1022 for (const auto &TA : T->getTypeConstraintArguments())
1023 Hash.AddTemplateArgument(TA);
1025 VisitDeducedType(T);
1028 void VisitDeducedTemplateSpecializationType(
1029 const DeducedTemplateSpecializationType *T) {
1030 Hash.AddTemplateName(T->getTemplateName());
1031 VisitDeducedType(T);
1034 void VisitDependentAddressSpaceType(const DependentAddressSpaceType *T) {
1035 AddQualType(T->getPointeeType());
1036 AddStmt(T->getAddrSpaceExpr());
1037 VisitType(T);
1040 void VisitDependentSizedExtVectorType(const DependentSizedExtVectorType *T) {
1041 AddQualType(T->getElementType());
1042 AddStmt(T->getSizeExpr());
1043 VisitType(T);
1046 void VisitFunctionType(const FunctionType *T) {
1047 AddQualType(T->getReturnType());
1048 T->getExtInfo().Profile(ID);
1049 Hash.AddBoolean(T->isConst());
1050 Hash.AddBoolean(T->isVolatile());
1051 Hash.AddBoolean(T->isRestrict());
1052 VisitType(T);
1055 void VisitFunctionNoProtoType(const FunctionNoProtoType *T) {
1056 VisitFunctionType(T);
1059 void VisitFunctionProtoType(const FunctionProtoType *T) {
1060 ID.AddInteger(T->getNumParams());
1061 for (auto ParamType : T->getParamTypes())
1062 AddQualType(ParamType);
1064 VisitFunctionType(T);
1067 void VisitInjectedClassNameType(const InjectedClassNameType *T) {
1068 AddDecl(T->getDecl());
1069 VisitType(T);
1072 void VisitMemberPointerType(const MemberPointerType *T) {
1073 AddQualType(T->getPointeeType());
1074 AddType(T->getClass());
1075 VisitType(T);
1078 void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
1079 AddQualType(T->getPointeeType());
1080 VisitType(T);
1083 void VisitObjCObjectType(const ObjCObjectType *T) {
1084 AddDecl(T->getInterface());
1086 auto TypeArgs = T->getTypeArgsAsWritten();
1087 ID.AddInteger(TypeArgs.size());
1088 for (auto Arg : TypeArgs) {
1089 AddQualType(Arg);
1092 auto Protocols = T->getProtocols();
1093 ID.AddInteger(Protocols.size());
1094 for (auto *Protocol : Protocols) {
1095 AddDecl(Protocol);
1098 Hash.AddBoolean(T->isKindOfType());
1100 VisitType(T);
1103 void VisitObjCInterfaceType(const ObjCInterfaceType *T) {
1104 // This type is handled by the parent type ObjCObjectType.
1105 VisitObjCObjectType(T);
1108 void VisitObjCTypeParamType(const ObjCTypeParamType *T) {
1109 AddDecl(T->getDecl());
1110 auto Protocols = T->getProtocols();
1111 ID.AddInteger(Protocols.size());
1112 for (auto *Protocol : Protocols) {
1113 AddDecl(Protocol);
1116 VisitType(T);
1119 void VisitPackExpansionType(const PackExpansionType *T) {
1120 AddQualType(T->getPattern());
1121 VisitType(T);
1124 void VisitParenType(const ParenType *T) {
1125 AddQualType(T->getInnerType());
1126 VisitType(T);
1129 void VisitPipeType(const PipeType *T) {
1130 AddQualType(T->getElementType());
1131 Hash.AddBoolean(T->isReadOnly());
1132 VisitType(T);
1135 void VisitPointerType(const PointerType *T) {
1136 AddQualType(T->getPointeeType());
1137 VisitType(T);
1140 void VisitReferenceType(const ReferenceType *T) {
1141 AddQualType(T->getPointeeTypeAsWritten());
1142 VisitType(T);
1145 void VisitLValueReferenceType(const LValueReferenceType *T) {
1146 VisitReferenceType(T);
1149 void VisitRValueReferenceType(const RValueReferenceType *T) {
1150 VisitReferenceType(T);
1153 void
1154 VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T) {
1155 AddDecl(T->getAssociatedDecl());
1156 Hash.AddTemplateArgument(T->getArgumentPack());
1157 VisitType(T);
1160 void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
1161 AddDecl(T->getAssociatedDecl());
1162 AddQualType(T->getReplacementType());
1163 VisitType(T);
1166 void VisitTagType(const TagType *T) {
1167 AddDecl(T->getDecl());
1168 VisitType(T);
1171 void VisitRecordType(const RecordType *T) { VisitTagType(T); }
1172 void VisitEnumType(const EnumType *T) { VisitTagType(T); }
1174 void VisitTemplateSpecializationType(const TemplateSpecializationType *T) {
1175 ID.AddInteger(T->template_arguments().size());
1176 for (const auto &TA : T->template_arguments()) {
1177 Hash.AddTemplateArgument(TA);
1179 Hash.AddTemplateName(T->getTemplateName());
1180 VisitType(T);
1183 void VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
1184 ID.AddInteger(T->getDepth());
1185 ID.AddInteger(T->getIndex());
1186 Hash.AddBoolean(T->isParameterPack());
1187 AddDecl(T->getDecl());
1190 void VisitTypedefType(const TypedefType *T) {
1191 AddDecl(T->getDecl());
1192 VisitType(T);
1195 void VisitTypeOfExprType(const TypeOfExprType *T) {
1196 AddStmt(T->getUnderlyingExpr());
1197 Hash.AddBoolean(T->isSugared());
1199 VisitType(T);
1201 void VisitTypeOfType(const TypeOfType *T) {
1202 AddQualType(T->getUnmodifiedType());
1203 VisitType(T);
1206 void VisitTypeWithKeyword(const TypeWithKeyword *T) {
1207 ID.AddInteger(llvm::to_underlying(T->getKeyword()));
1208 VisitType(T);
1211 void VisitDependentNameType(const DependentNameType *T) {
1212 AddNestedNameSpecifier(T->getQualifier());
1213 AddIdentifierInfo(T->getIdentifier());
1214 VisitTypeWithKeyword(T);
1217 void VisitDependentTemplateSpecializationType(
1218 const DependentTemplateSpecializationType *T) {
1219 AddIdentifierInfo(T->getIdentifier());
1220 AddNestedNameSpecifier(T->getQualifier());
1221 ID.AddInteger(T->template_arguments().size());
1222 for (const auto &TA : T->template_arguments()) {
1223 Hash.AddTemplateArgument(TA);
1225 VisitTypeWithKeyword(T);
1228 void VisitElaboratedType(const ElaboratedType *T) {
1229 AddNestedNameSpecifier(T->getQualifier());
1230 AddQualType(T->getNamedType());
1231 VisitTypeWithKeyword(T);
1234 void VisitUnaryTransformType(const UnaryTransformType *T) {
1235 AddQualType(T->getUnderlyingType());
1236 AddQualType(T->getBaseType());
1237 VisitType(T);
1240 void VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
1241 AddDecl(T->getDecl());
1242 VisitType(T);
1245 void VisitVectorType(const VectorType *T) {
1246 AddQualType(T->getElementType());
1247 ID.AddInteger(T->getNumElements());
1248 ID.AddInteger(llvm::to_underlying(T->getVectorKind()));
1249 VisitType(T);
1252 void VisitExtVectorType(const ExtVectorType * T) {
1253 VisitVectorType(T);
1256 } // namespace
1258 void ODRHash::AddType(const Type *T) {
1259 assert(T && "Expecting non-null pointer.");
1260 ODRTypeVisitor(ID, *this).Visit(T);
1263 void ODRHash::AddQualType(QualType T) {
1264 AddBoolean(T.isNull());
1265 if (T.isNull())
1266 return;
1267 SplitQualType split = T.split();
1268 ID.AddInteger(split.Quals.getAsOpaqueValue());
1269 AddType(split.Ty);
1272 void ODRHash::AddBoolean(bool Value) {
1273 Bools.push_back(Value);
1276 void ODRHash::AddStructuralValue(const APValue &Value) {
1277 ID.AddInteger(Value.getKind());
1279 // 'APValue::Profile' uses pointer values to make hash for LValue and
1280 // MemberPointer, but they differ from one compiler invocation to another.
1281 // So, handle them explicitly here.
1283 switch (Value.getKind()) {
1284 case APValue::LValue: {
1285 const APValue::LValueBase &Base = Value.getLValueBase();
1286 if (!Base) {
1287 ID.AddInteger(Value.getLValueOffset().getQuantity());
1288 break;
1291 assert(Base.is<const ValueDecl *>());
1292 AddDecl(Base.get<const ValueDecl *>());
1293 ID.AddInteger(Value.getLValueOffset().getQuantity());
1295 bool OnePastTheEnd = Value.isLValueOnePastTheEnd();
1296 if (Value.hasLValuePath()) {
1297 QualType TypeSoFar = Base.getType();
1298 for (APValue::LValuePathEntry E : Value.getLValuePath()) {
1299 if (const auto *AT = TypeSoFar->getAsArrayTypeUnsafe()) {
1300 if (const auto *CAT = dyn_cast<ConstantArrayType>(AT))
1301 OnePastTheEnd |= CAT->getSize() == E.getAsArrayIndex();
1302 TypeSoFar = AT->getElementType();
1303 } else {
1304 const Decl *D = E.getAsBaseOrMember().getPointer();
1305 if (const auto *FD = dyn_cast<FieldDecl>(D)) {
1306 if (FD->getParent()->isUnion())
1307 ID.AddInteger(FD->getFieldIndex());
1308 TypeSoFar = FD->getType();
1309 } else {
1310 TypeSoFar =
1311 D->getASTContext().getRecordType(cast<CXXRecordDecl>(D));
1316 unsigned Val = 0;
1317 if (Value.isNullPointer())
1318 Val |= 1 << 0;
1319 if (OnePastTheEnd)
1320 Val |= 1 << 1;
1321 if (Value.hasLValuePath())
1322 Val |= 1 << 2;
1323 ID.AddInteger(Val);
1324 break;
1326 case APValue::MemberPointer: {
1327 const ValueDecl *D = Value.getMemberPointerDecl();
1328 assert(D);
1329 AddDecl(D);
1330 ID.AddInteger(
1331 D->getASTContext().getMemberPointerPathAdjustment(Value).getQuantity());
1332 break;
1334 default:
1335 Value.Profile(ID);