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//===----------------------------------------------------------------------===//
14
15#include "clang/AST/ODRHash.h"
16
17#include "clang/AST/DeclVisitor.h"
18#include "clang/AST/NestedNameSpecifier.h"
19#include "clang/AST/TypeVisitor.h"
20
21using namespace clang;
22
23void ODRHash::AddStmt(const Stmt *S) {
24 assert(S && "Expecting non-null pointer.");
25 S->ProcessODRHash(ID, Hash&: *this);
26}
27
28void ODRHash::AddIdentifierInfo(const IdentifierInfo *II) {
29 assert(II && "Expecting non-null pointer.");
30 ID.AddString(String: II->getName());
31}
32
33void ODRHash::AddDeclarationNameInfo(DeclarationNameInfo NameInfo,
34 bool TreatAsDecl) {
35 if (TreatAsDecl)
36 // Matches the NamedDecl check in AddDecl
37 AddBoolean(value: true);
38
39 AddDeclarationNameInfoImpl(NameInfo);
40
41 if (TreatAsDecl)
42 // Matches the ClassTemplateSpecializationDecl check in AddDecl
43 AddBoolean(value: false);
44}
45
46void ODRHash::AddDeclarationNameInfoImpl(DeclarationNameInfo NameInfo) {
47 DeclarationName Name = NameInfo.getName();
48 // Index all DeclarationName and use index numbers to refer to them.
49 auto Result = DeclNameMap.insert(KV: std::make_pair(x&: Name, y: DeclNameMap.size()));
50 ID.AddInteger(I: Result.first->second);
51 if (!Result.second) {
52 // If found in map, the DeclarationName has previously been processed.
53 return;
54 }
55
56 // First time processing each DeclarationName, also process its details.
57 AddBoolean(value: Name.isEmpty());
58 if (Name.isEmpty())
59 return;
60
61 auto Kind = Name.getNameKind();
62 ID.AddInteger(I: Kind);
63 switch (Kind) {
64 case DeclarationName::Identifier:
65 AddIdentifierInfo(II: Name.getAsIdentifierInfo());
66 break;
67 case DeclarationName::ObjCZeroArgSelector:
68 case DeclarationName::ObjCOneArgSelector:
69 case DeclarationName::ObjCMultiArgSelector: {
70 Selector S = Name.getObjCSelector();
71 AddBoolean(value: S.isNull());
72 AddBoolean(value: S.isKeywordSelector());
73 AddBoolean(value: S.isUnarySelector());
74 unsigned NumArgs = S.getNumArgs();
75 ID.AddInteger(I: NumArgs);
76 // Compare all selector slots. For selectors with arguments it means all arg
77 // slots. And if there are no arguments, compare the first-and-only slot.
78 unsigned SlotsToCheck = NumArgs > 0 ? NumArgs : 1;
79 for (unsigned i = 0; i < SlotsToCheck; ++i) {
80 const IdentifierInfo *II = S.getIdentifierInfoForSlot(argIndex: i);
81 AddBoolean(value: II);
82 if (II) {
83 AddIdentifierInfo(II);
84 }
85 }
86 break;
87 }
88 case DeclarationName::CXXConstructorName:
89 case DeclarationName::CXXDestructorName:
90 case DeclarationName::CXXConversionFunctionName:
91 if (auto *TSI = NameInfo.getNamedTypeInfo())
92 AddQualType(T: TSI->getType());
93 else
94 AddQualType(T: Name.getCXXNameType());
95 break;
96 case DeclarationName::CXXOperatorName:
97 ID.AddInteger(I: Name.getCXXOverloadedOperator());
98 break;
99 case DeclarationName::CXXLiteralOperatorName:
100 AddIdentifierInfo(II: Name.getCXXLiteralIdentifier());
101 break;
102 case DeclarationName::CXXUsingDirective:
103 break;
104 case DeclarationName::CXXDeductionGuideName: {
105 auto *Template = Name.getCXXDeductionGuideTemplate();
106 AddBoolean(value: Template);
107 if (Template) {
108 AddDecl(D: Template);
109 }
110 }
111 }
112}
113
114void ODRHash::AddNestedNameSpecifier(NestedNameSpecifier NNS) {
115 auto Kind = NNS.getKind();
116 ID.AddInteger(I: llvm::to_underlying(E: Kind));
117 switch (Kind) {
118 case NestedNameSpecifier::Kind::Namespace: {
119 auto [Namespace, Prefix] = NNS.getAsNamespaceAndPrefix();
120 AddDecl(D: Namespace);
121 AddNestedNameSpecifier(NNS: Prefix);
122 break;
123 }
124 case NestedNameSpecifier::Kind::Type:
125 AddType(T: NNS.getAsType());
126 break;
127 case NestedNameSpecifier::Kind::Null:
128 case NestedNameSpecifier::Kind::Global:
129 case NestedNameSpecifier::Kind::MicrosoftSuper:
130 break;
131 }
132}
133
134void ODRHash::AddDependentTemplateName(const DependentTemplateStorage &Name) {
135 AddNestedNameSpecifier(NNS: Name.getQualifier());
136 if (IdentifierOrOverloadedOperator IO = Name.getName();
137 const IdentifierInfo *II = IO.getIdentifier())
138 AddIdentifierInfo(II);
139 else
140 ID.AddInteger(I: IO.getOperator());
141}
142
143void ODRHash::AddTemplateName(TemplateName Name) {
144 auto Kind = Name.getKind();
145 ID.AddInteger(I: Kind);
146
147 switch (Kind) {
148 case TemplateName::Template:
149 AddDecl(D: Name.getAsTemplateDecl());
150 break;
151 case TemplateName::QualifiedTemplate: {
152 QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName();
153 AddNestedNameSpecifier(NNS: QTN->getQualifier());
154 AddBoolean(value: QTN->hasTemplateKeyword());
155 AddTemplateName(Name: QTN->getUnderlyingTemplate());
156 break;
157 }
158 case TemplateName::DependentTemplate: {
159 AddDependentTemplateName(Name: *Name.getAsDependentTemplateName());
160 break;
161 }
162 case TemplateName::PackIndexingTemplate: {
163 PackIndexingTemplateStorage *PI = Name.getAsPackIndexingTemplate();
164 AddTemplateName(Name: PI->getPattern());
165 AddStmt(S: PI->getIndexExpr());
166 break;
167 }
168 // TODO: Support these cases.
169 case TemplateName::OverloadedTemplate:
170 case TemplateName::AssumedTemplate:
171 case TemplateName::SubstTemplateTemplateParm:
172 case TemplateName::SubstTemplateTemplateParmPack:
173 break;
174 case TemplateName::UsingTemplate:
175 AddDecl(D: Name.getAsUsingShadowDecl()->getTargetDecl());
176 break;
177 case TemplateName::DeducedTemplate:
178 llvm_unreachable("Unexpected DeducedTemplate");
179 }
180}
181
182void ODRHash::AddTemplateArgument(TemplateArgument TA) {
183 const auto Kind = TA.getKind();
184 ID.AddInteger(I: Kind);
185
186 switch (Kind) {
187 case TemplateArgument::Null:
188 llvm_unreachable("Expected valid TemplateArgument");
189 case TemplateArgument::Type:
190 AddQualType(T: TA.getAsType());
191 break;
192 case TemplateArgument::Declaration:
193 AddDecl(D: TA.getAsDecl());
194 break;
195 case TemplateArgument::NullPtr:
196 ID.AddPointer(Ptr: nullptr);
197 break;
198 case TemplateArgument::Integral: {
199 // There are integrals (e.g.: _BitInt(128)) that cannot be represented as
200 // any builtin integral type, so we use the hash of APSInt instead.
201 TA.getAsIntegral().Profile(ID);
202 break;
203 }
204 case TemplateArgument::StructuralValue:
205 AddQualType(T: TA.getStructuralValueType());
206 AddStructuralValue(TA.getAsStructuralValue());
207 break;
208 case TemplateArgument::Template:
209 case TemplateArgument::TemplateExpansion:
210 AddTemplateName(Name: TA.getAsTemplateOrTemplatePattern());
211 break;
212 case TemplateArgument::Expression:
213 AddStmt(S: TA.getAsExpr());
214 break;
215 case TemplateArgument::Pack:
216 ID.AddInteger(I: TA.pack_size());
217 for (auto SubTA : TA.pack_elements()) {
218 AddTemplateArgument(TA: SubTA);
219 }
220 break;
221 }
222}
223
224void ODRHash::AddTemplateParameterList(const TemplateParameterList *TPL) {
225 assert(TPL && "Expecting non-null pointer.");
226
227 ID.AddInteger(I: TPL->size());
228 for (auto *ND : TPL->asArray()) {
229 AddSubDecl(D: ND);
230 }
231
232 const Expr *RequiresClause = TPL->getRequiresClause();
233 AddBoolean(value: RequiresClause);
234 if (RequiresClause)
235 AddStmt(S: RequiresClause);
236}
237
238void ODRHash::clear() {
239 DeclNameMap.clear();
240 Bools.clear();
241 ID.clear();
242}
243
244unsigned ODRHash::CalculateHash() {
245 // Append the bools to the end of the data segment backwards. This allows
246 // for the bools data to be compressed 32 times smaller compared to using
247 // ID.AddBoolean
248 const unsigned unsigned_bits = sizeof(unsigned) * CHAR_BIT;
249 const unsigned size = Bools.size();
250 const unsigned remainder = size % unsigned_bits;
251 const unsigned loops = size / unsigned_bits;
252 auto I = Bools.rbegin();
253 unsigned value = 0;
254 for (unsigned i = 0; i < remainder; ++i) {
255 value <<= 1;
256 value |= *I;
257 ++I;
258 }
259 ID.AddInteger(I: value);
260
261 for (unsigned i = 0; i < loops; ++i) {
262 value = 0;
263 for (unsigned j = 0; j < unsigned_bits; ++j) {
264 value <<= 1;
265 value |= *I;
266 ++I;
267 }
268 ID.AddInteger(I: value);
269 }
270
271 assert(I == Bools.rend());
272 Bools.clear();
273 return ID.computeStableHash();
274}
275
276namespace {
277// Process a Decl pointer. Add* methods call back into ODRHash while Visit*
278// methods process the relevant parts of the Decl.
279class ODRDeclVisitor : public ConstDeclVisitor<ODRDeclVisitor> {
280 typedef ConstDeclVisitor<ODRDeclVisitor> Inherited;
281 llvm::FoldingSetNodeID &ID;
282 ODRHash &Hash;
283
284public:
285 ODRDeclVisitor(llvm::FoldingSetNodeID &ID, ODRHash &Hash)
286 : ID(ID), Hash(Hash) {}
287
288 void AddStmt(const Stmt *S) {
289 Hash.AddBoolean(value: S);
290 if (S) {
291 Hash.AddStmt(S);
292 }
293 }
294
295 void AddIdentifierInfo(const IdentifierInfo *II) {
296 Hash.AddBoolean(value: II);
297 if (II) {
298 Hash.AddIdentifierInfo(II);
299 }
300 }
301
302 void AddQualType(QualType T) {
303 Hash.AddQualType(T);
304 }
305
306 void AddDecl(const Decl *D) {
307 Hash.AddBoolean(value: D);
308 if (D) {
309 Hash.AddDecl(D);
310 }
311 }
312
313 void AddTemplateArgument(TemplateArgument TA) {
314 Hash.AddTemplateArgument(TA);
315 }
316
317 void Visit(const Decl *D) {
318 ID.AddInteger(I: D->getKind());
319 Inherited::Visit(D);
320 }
321
322 void VisitNamedDecl(const NamedDecl *D) {
323 if (const auto *FD = dyn_cast<FunctionDecl>(Val: D))
324 Hash.AddDeclarationNameInfo(NameInfo: FD->getNameInfo());
325 else
326 Hash.AddDeclarationName(Name: D->getDeclName());
327 Inherited::VisitNamedDecl(D);
328 }
329
330 void VisitValueDecl(const ValueDecl *D) {
331 if (auto *DD = dyn_cast<DeclaratorDecl>(Val: D); DD && DD->getTypeSourceInfo())
332 AddQualType(T: DD->getTypeSourceInfo()->getType());
333
334 Inherited::VisitValueDecl(D);
335 }
336
337 void VisitVarDecl(const VarDecl *D) {
338 Hash.AddBoolean(value: D->isStaticLocal());
339 Hash.AddBoolean(value: D->isConstexpr());
340 const bool HasInit = D->hasInit();
341 Hash.AddBoolean(value: HasInit);
342 if (HasInit) {
343 AddStmt(S: D->getInit());
344 }
345 Inherited::VisitVarDecl(D);
346 }
347
348 void VisitParmVarDecl(const ParmVarDecl *D) {
349 // TODO: Handle default arguments.
350 Inherited::VisitParmVarDecl(D);
351 }
352
353 void VisitAccessSpecDecl(const AccessSpecDecl *D) {
354 ID.AddInteger(I: D->getAccess());
355 Inherited::VisitAccessSpecDecl(D);
356 }
357
358 void VisitStaticAssertDecl(const StaticAssertDecl *D) {
359 AddStmt(S: D->getAssertExpr());
360 AddStmt(S: D->getMessage());
361
362 Inherited::VisitStaticAssertDecl(D);
363 }
364
365 void VisitFieldDecl(const FieldDecl *D) {
366 const bool IsBitfield = D->isBitField();
367 Hash.AddBoolean(value: IsBitfield);
368
369 if (IsBitfield) {
370 AddStmt(S: D->getBitWidth());
371 }
372
373 Hash.AddBoolean(value: D->isMutable());
374 AddStmt(S: D->getInClassInitializer());
375
376 Inherited::VisitFieldDecl(D);
377 }
378
379 void VisitObjCIvarDecl(const ObjCIvarDecl *D) {
380 ID.AddInteger(I: D->getCanonicalAccessControl());
381 Inherited::VisitObjCIvarDecl(D);
382 }
383
384 void VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
385 ID.AddInteger(I: D->getPropertyAttributes());
386 ID.AddInteger(I: D->getPropertyImplementation());
387 AddQualType(T: D->getTypeSourceInfo()->getType());
388 AddDecl(D);
389
390 Inherited::VisitObjCPropertyDecl(D);
391 }
392
393 void VisitFunctionDecl(const FunctionDecl *D) {
394 // Handled by the ODRHash for FunctionDecl
395 ID.AddInteger(I: D->getODRHash());
396
397 Inherited::VisitFunctionDecl(D);
398 }
399
400 void VisitCXXMethodDecl(const CXXMethodDecl *D) {
401 // Handled by the ODRHash for FunctionDecl
402
403 Inherited::VisitCXXMethodDecl(D);
404 }
405
406 void VisitObjCMethodDecl(const ObjCMethodDecl *Method) {
407 ID.AddInteger(I: Method->getDeclKind());
408 Hash.AddBoolean(value: Method->isInstanceMethod()); // false if class method
409 Hash.AddBoolean(value: Method->isVariadic());
410 Hash.AddBoolean(value: Method->isSynthesizedAccessorStub());
411 Hash.AddBoolean(value: Method->isDefined());
412 Hash.AddBoolean(value: Method->isDirectMethod());
413 Hash.AddBoolean(value: Method->isThisDeclarationADesignatedInitializer());
414 Hash.AddBoolean(value: Method->hasSkippedBody());
415
416 ID.AddInteger(I: llvm::to_underlying(E: Method->getImplementationControl()));
417 ID.AddInteger(I: Method->getMethodFamily());
418 ImplicitParamDecl *Cmd = Method->getCmdDecl();
419 Hash.AddBoolean(value: Cmd);
420 if (Cmd)
421 ID.AddInteger(I: llvm::to_underlying(E: Cmd->getParameterKind()));
422
423 ImplicitParamDecl *Self = Method->getSelfDecl();
424 Hash.AddBoolean(value: Self);
425 if (Self)
426 ID.AddInteger(I: llvm::to_underlying(E: Self->getParameterKind()));
427
428 AddDecl(D: Method);
429
430 if (Method->getReturnTypeSourceInfo())
431 AddQualType(T: Method->getReturnTypeSourceInfo()->getType());
432
433 ID.AddInteger(I: Method->param_size());
434 for (auto Param : Method->parameters())
435 Hash.AddSubDecl(D: Param);
436
437 if (Method->hasBody()) {
438 const bool IsDefinition = Method->isThisDeclarationADefinition();
439 Hash.AddBoolean(value: IsDefinition);
440 if (IsDefinition) {
441 Stmt *Body = Method->getBody();
442 Hash.AddBoolean(value: Body);
443 if (Body)
444 AddStmt(S: Body);
445
446 // Filter out sub-Decls which will not be processed in order to get an
447 // accurate count of Decl's.
448 llvm::SmallVector<const Decl *, 16> Decls;
449 for (Decl *SubDecl : Method->decls())
450 if (ODRHash::isSubDeclToBeProcessed(D: SubDecl, Parent: Method))
451 Decls.push_back(Elt: SubDecl);
452
453 ID.AddInteger(I: Decls.size());
454 for (auto SubDecl : Decls)
455 Hash.AddSubDecl(D: SubDecl);
456 }
457 } else {
458 Hash.AddBoolean(value: false);
459 }
460
461 Inherited::VisitObjCMethodDecl(D: Method);
462 }
463
464 void VisitTypedefNameDecl(const TypedefNameDecl *D) {
465 AddQualType(T: D->getUnderlyingType());
466
467 Inherited::VisitTypedefNameDecl(D);
468 }
469
470 void VisitTypedefDecl(const TypedefDecl *D) {
471 Inherited::VisitTypedefDecl(D);
472 }
473
474 void VisitTypeAliasDecl(const TypeAliasDecl *D) {
475 Inherited::VisitTypeAliasDecl(D);
476 }
477
478 void VisitFriendDecl(const FriendDecl *D) {
479 TypeSourceInfo *TSI = D->getFriendType();
480 Hash.AddBoolean(value: TSI);
481 if (TSI) {
482 AddQualType(T: TSI->getType());
483 } else {
484 AddDecl(D: D->getFriendDecl());
485 }
486 Hash.AddBoolean(value: D->isPackExpansion());
487 }
488
489 void VisitFriendTemplateDecl(const FriendTemplateDecl *D) {
490 for (const TemplateParameterList *TPL : D->getTemplateParameterLists())
491 Hash.AddTemplateParameterList(TPL);
492
493 bool IsTemplateFriend =
494 D->getFriendKind() ==
495 FriendTemplateDecl::FriendTemplateEntityKind::Template;
496 Hash.AddBoolean(value: !IsTemplateFriend);
497 if (!IsTemplateFriend) {
498 VisitFriendDecl(D);
499 if (D->getFriendKind() ==
500 FriendTemplateDecl::FriendTemplateEntityKind::Type &&
501 !D->getFriendTemplateName().isNull())
502 Hash.AddTemplateName(Name: D->getFriendTemplateName());
503 } else {
504 Hash.AddTemplateName(Name: D->getFriendTemplateName());
505 Hash.AddBoolean(value: D->isPackExpansion());
506 }
507 }
508
509 void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
510 // Only care about default arguments as part of the definition.
511 const bool hasDefaultArgument =
512 D->hasDefaultArgument() && !D->defaultArgumentWasInherited();
513 Hash.AddBoolean(value: hasDefaultArgument);
514 if (hasDefaultArgument) {
515 AddTemplateArgument(TA: D->getDefaultArgument().getArgument());
516 }
517 Hash.AddBoolean(value: D->isParameterPack());
518
519 const TypeConstraint *TC = D->getTypeConstraint();
520 Hash.AddBoolean(value: TC != nullptr);
521 if (TC)
522 AddStmt(S: TC->getImmediatelyDeclaredConstraint());
523
524 Inherited::VisitTemplateTypeParmDecl(D);
525 }
526
527 void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
528 // Only care about default arguments as part of the definition.
529 const bool hasDefaultArgument =
530 D->hasDefaultArgument() && !D->defaultArgumentWasInherited();
531 Hash.AddBoolean(value: hasDefaultArgument);
532 if (hasDefaultArgument) {
533 AddTemplateArgument(TA: D->getDefaultArgument().getArgument());
534 }
535 Hash.AddBoolean(value: D->isParameterPack());
536
537 Inherited::VisitNonTypeTemplateParmDecl(D);
538 }
539
540 void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D) {
541 // Only care about default arguments as part of the definition.
542 const bool hasDefaultArgument =
543 D->hasDefaultArgument() && !D->defaultArgumentWasInherited();
544 Hash.AddBoolean(value: hasDefaultArgument);
545 if (hasDefaultArgument) {
546 AddTemplateArgument(TA: D->getDefaultArgument().getArgument());
547 }
548 Hash.AddBoolean(value: D->isParameterPack());
549
550 Inherited::VisitTemplateTemplateParmDecl(D);
551 }
552
553 void VisitTemplateDecl(const TemplateDecl *D) {
554 Hash.AddTemplateParameterList(TPL: D->getTemplateParameters());
555
556 Inherited::VisitTemplateDecl(D);
557 }
558
559 void VisitRedeclarableTemplateDecl(const RedeclarableTemplateDecl *D) {
560 Hash.AddBoolean(value: D->isMemberSpecialization());
561 Inherited::VisitRedeclarableTemplateDecl(D);
562 }
563
564 void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
565 AddDecl(D: D->getTemplatedDecl());
566 ID.AddInteger(I: D->getTemplatedDecl()->getODRHash());
567 Inherited::VisitFunctionTemplateDecl(D);
568 }
569
570 void VisitEnumConstantDecl(const EnumConstantDecl *D) {
571 AddStmt(S: D->getInitExpr());
572 Inherited::VisitEnumConstantDecl(D);
573 }
574};
575} // namespace
576
577// Only allow a small portion of Decl's to be processed. Remove this once
578// all Decl's can be handled.
579bool ODRHash::isSubDeclToBeProcessed(const Decl *D, const DeclContext *Parent) {
580 if (D->isImplicit()) return false;
581 if (D->getDeclContext() != Parent) return false;
582
583 switch (D->getKind()) {
584 default:
585 return false;
586 case Decl::AccessSpec:
587 case Decl::CXXConstructor:
588 case Decl::CXXDestructor:
589 case Decl::CXXMethod:
590 case Decl::EnumConstant: // Only found in EnumDecl's.
591 case Decl::Field:
592 case Decl::Friend:
593 case Decl::FriendTemplate:
594 case Decl::FunctionTemplate:
595 case Decl::StaticAssert:
596 case Decl::TypeAlias:
597 case Decl::Typedef:
598 case Decl::Var:
599 case Decl::ObjCMethod:
600 case Decl::ObjCIvar:
601 case Decl::ObjCProperty:
602 return true;
603 }
604}
605
606void ODRHash::AddSubDecl(const Decl *D) {
607 assert(D && "Expecting non-null pointer.");
608
609 ODRDeclVisitor(ID, *this).Visit(D);
610}
611
612void ODRHash::AddCXXRecordDecl(const CXXRecordDecl *Record) {
613 assert(Record && Record->hasDefinition() &&
614 "Expected non-null record to be a definition.");
615
616 const DeclContext *DC = Record;
617 while (DC) {
618 if (isa<ClassTemplateSpecializationDecl>(Val: DC)) {
619 return;
620 }
621 DC = DC->getParent();
622 }
623
624 AddDecl(D: Record);
625
626 // Filter out sub-Decls which will not be processed in order to get an
627 // accurate count of Decl's.
628 llvm::SmallVector<const Decl *, 16> Decls;
629 for (Decl *SubDecl : Record->decls()) {
630 if (isSubDeclToBeProcessed(D: SubDecl, Parent: Record)) {
631 Decls.push_back(Elt: SubDecl);
632 if (auto *Function = dyn_cast<FunctionDecl>(Val: SubDecl)) {
633 // Compute/Preload ODRHash into FunctionDecl.
634 Function->getODRHash();
635 }
636 }
637 }
638
639 ID.AddInteger(I: Decls.size());
640 for (auto SubDecl : Decls) {
641 AddSubDecl(D: SubDecl);
642 }
643
644 const ClassTemplateDecl *TD = Record->getDescribedClassTemplate();
645 AddBoolean(value: TD);
646 if (TD) {
647 AddTemplateParameterList(TPL: TD->getTemplateParameters());
648 }
649
650 ID.AddInteger(I: Record->getNumBases());
651 auto Bases = Record->bases();
652 for (const auto &Base : Bases) {
653 AddQualType(T: Base.getTypeSourceInfo()->getType());
654 ID.AddInteger(I: Base.isVirtual());
655 ID.AddInteger(I: Base.getAccessSpecifierAsWritten());
656 }
657}
658
659void ODRHash::AddRecordDecl(const RecordDecl *Record) {
660 assert(!isa<CXXRecordDecl>(Record) &&
661 "For CXXRecordDecl should call AddCXXRecordDecl.");
662 AddDecl(D: Record);
663
664 // Filter out sub-Decls which will not be processed in order to get an
665 // accurate count of Decl's.
666 llvm::SmallVector<const Decl *, 16> Decls;
667 for (Decl *SubDecl : Record->decls()) {
668 if (isSubDeclToBeProcessed(D: SubDecl, Parent: Record))
669 Decls.push_back(Elt: SubDecl);
670 }
671
672 ID.AddInteger(I: Decls.size());
673 for (const Decl *SubDecl : Decls)
674 AddSubDecl(D: SubDecl);
675}
676
677void ODRHash::AddObjCInterfaceDecl(const ObjCInterfaceDecl *IF) {
678 AddDecl(D: IF);
679
680 auto *SuperClass = IF->getSuperClass();
681 AddBoolean(value: SuperClass);
682 if (SuperClass)
683 ID.AddInteger(I: SuperClass->getODRHash());
684
685 // Hash referenced protocols.
686 ID.AddInteger(I: IF->getReferencedProtocols().size());
687 for (const ObjCProtocolDecl *RefP : IF->protocols()) {
688 // Hash the name only as a referenced protocol can be a forward declaration.
689 AddDeclarationName(Name: RefP->getDeclName());
690 }
691
692 // Filter out sub-Decls which will not be processed in order to get an
693 // accurate count of Decl's.
694 llvm::SmallVector<const Decl *, 16> Decls;
695 for (Decl *SubDecl : IF->decls())
696 if (isSubDeclToBeProcessed(D: SubDecl, Parent: IF))
697 Decls.push_back(Elt: SubDecl);
698
699 ID.AddInteger(I: Decls.size());
700 for (auto *SubDecl : Decls)
701 AddSubDecl(D: SubDecl);
702}
703
704void ODRHash::AddFunctionDecl(const FunctionDecl *Function,
705 bool SkipBody) {
706 assert(Function && "Expecting non-null pointer.");
707
708 // Skip functions that are specializations or in specialization context.
709 const DeclContext *DC = Function;
710 while (DC) {
711 if (isa<ClassTemplateSpecializationDecl>(Val: DC)) return;
712 if (auto *F = dyn_cast<FunctionDecl>(Val: DC)) {
713 if (F->isFunctionTemplateSpecialization()) {
714 if (!isa<CXXMethodDecl>(Val: DC)) return;
715 if (DC->getLexicalParent()->isFileContext()) return;
716 // Skip class scope explicit function template specializations,
717 // as they have not yet been instantiated.
718 if (F->getDependentSpecializationInfo())
719 return;
720 // Inline method specializations are the only supported
721 // specialization for now.
722 }
723 }
724 DC = DC->getParent();
725 }
726
727 ID.AddInteger(I: Function->getDeclKind());
728
729 const auto *SpecializationArgs = Function->getTemplateSpecializationArgs();
730 AddBoolean(value: SpecializationArgs);
731 if (SpecializationArgs) {
732 ID.AddInteger(I: SpecializationArgs->size());
733 for (const TemplateArgument &TA : SpecializationArgs->asArray()) {
734 AddTemplateArgument(TA);
735 }
736 }
737
738 if (const auto *Method = dyn_cast<CXXMethodDecl>(Val: Function)) {
739 AddBoolean(value: Method->isConst());
740 AddBoolean(value: Method->isVolatile());
741 }
742
743 ID.AddInteger(I: Function->getStorageClass());
744 AddBoolean(value: Function->isInlineSpecified());
745 AddBoolean(value: Function->isVirtualAsWritten());
746 AddBoolean(value: Function->isPureVirtual());
747 AddBoolean(value: Function->isDeletedAsWritten());
748 AddBoolean(value: Function->isExplicitlyDefaulted());
749
750 StringLiteral *DeletedMessage = Function->getDeletedMessage();
751 AddBoolean(value: DeletedMessage);
752
753 if (DeletedMessage)
754 ID.AddString(String: DeletedMessage->getBytes());
755
756 AddDecl(D: Function);
757
758 AddQualType(T: Function->getReturnType());
759
760 ID.AddInteger(I: Function->param_size());
761 for (auto *Param : Function->parameters())
762 AddSubDecl(D: Param);
763
764 if (SkipBody) {
765 AddBoolean(value: false);
766 return;
767 }
768
769 const bool HasBody = Function->isThisDeclarationADefinition() &&
770 !Function->isDefaulted() && !Function->isDeleted() &&
771 !Function->isLateTemplateParsed();
772 AddBoolean(value: HasBody);
773 if (!HasBody) {
774 return;
775 }
776
777 auto *Body = Function->getBody();
778 AddBoolean(value: Body);
779 if (Body)
780 AddStmt(S: Body);
781
782 // Filter out sub-Decls which will not be processed in order to get an
783 // accurate count of Decl's.
784 llvm::SmallVector<const Decl *, 16> Decls;
785 for (Decl *SubDecl : Function->decls()) {
786 if (isSubDeclToBeProcessed(D: SubDecl, Parent: Function)) {
787 Decls.push_back(Elt: SubDecl);
788 }
789 }
790
791 ID.AddInteger(I: Decls.size());
792 for (auto SubDecl : Decls) {
793 AddSubDecl(D: SubDecl);
794 }
795}
796
797void ODRHash::AddEnumDecl(const EnumDecl *Enum) {
798 assert(Enum);
799 AddDeclarationName(Name: Enum->getDeclName());
800
801 AddBoolean(value: Enum->isScoped());
802 if (Enum->isScoped())
803 AddBoolean(value: Enum->isScopedUsingClassTag());
804
805 if (Enum->getIntegerTypeSourceInfo())
806 AddQualType(T: Enum->getIntegerType().getCanonicalType());
807
808 // Filter out sub-Decls which will not be processed in order to get an
809 // accurate count of Decl's.
810 llvm::SmallVector<const Decl *, 16> Decls;
811 for (Decl *SubDecl : Enum->decls()) {
812 if (isSubDeclToBeProcessed(D: SubDecl, Parent: Enum)) {
813 assert(isa<EnumConstantDecl>(SubDecl) && "Unexpected Decl");
814 Decls.push_back(Elt: SubDecl);
815 }
816 }
817
818 ID.AddInteger(I: Decls.size());
819 for (auto SubDecl : Decls) {
820 AddSubDecl(D: SubDecl);
821 }
822
823}
824
825void ODRHash::AddObjCProtocolDecl(const ObjCProtocolDecl *P) {
826 AddDecl(D: P);
827
828 // Hash referenced protocols.
829 ID.AddInteger(I: P->getReferencedProtocols().size());
830 for (const ObjCProtocolDecl *RefP : P->protocols()) {
831 // Hash the name only as a referenced protocol can be a forward declaration.
832 AddDeclarationName(Name: RefP->getDeclName());
833 }
834
835 // Filter out sub-Decls which will not be processed in order to get an
836 // accurate count of Decl's.
837 llvm::SmallVector<const Decl *, 16> Decls;
838 for (Decl *SubDecl : P->decls()) {
839 if (isSubDeclToBeProcessed(D: SubDecl, Parent: P)) {
840 Decls.push_back(Elt: SubDecl);
841 }
842 }
843
844 ID.AddInteger(I: Decls.size());
845 for (auto *SubDecl : Decls) {
846 AddSubDecl(D: SubDecl);
847 }
848}
849
850void ODRHash::AddDecl(const Decl *D) {
851 assert(D && "Expecting non-null pointer.");
852 D = D->getCanonicalDecl();
853
854 const NamedDecl *ND = dyn_cast<NamedDecl>(Val: D);
855 AddBoolean(value: ND);
856 if (!ND) {
857 ID.AddInteger(I: D->getKind());
858 return;
859 }
860
861 if (auto *FD = dyn_cast<FunctionDecl>(Val: D))
862 AddDeclarationNameInfo(NameInfo: FD->getNameInfo());
863 else
864 AddDeclarationName(Name: ND->getDeclName());
865
866 // If this was a specialization we should take into account its template
867 // arguments. This helps to reduce collisions coming when visiting template
868 // specialization types (eg. when processing type template arguments).
869 ArrayRef<TemplateArgument> Args;
870 if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(Val: D))
871 Args = CTSD->getTemplateArgs().asArray();
872 else if (auto *VTSD = dyn_cast<VarTemplateSpecializationDecl>(Val: D))
873 Args = VTSD->getTemplateArgs().asArray();
874 else if (auto *FD = dyn_cast<FunctionDecl>(Val: D))
875 if (FD->getTemplateSpecializationArgs())
876 Args = FD->getTemplateSpecializationArgs()->asArray();
877
878 for (auto &TA : Args)
879 AddTemplateArgument(TA);
880}
881
882namespace {
883// Process a Type pointer. Add* methods call back into ODRHash while Visit*
884// methods process the relevant parts of the Type.
885class ODRTypeVisitor : public TypeVisitor<ODRTypeVisitor> {
886 typedef TypeVisitor<ODRTypeVisitor> Inherited;
887 llvm::FoldingSetNodeID &ID;
888 ODRHash &Hash;
889
890public:
891 ODRTypeVisitor(llvm::FoldingSetNodeID &ID, ODRHash &Hash)
892 : ID(ID), Hash(Hash) {}
893
894 void AddStmt(Stmt *S) {
895 Hash.AddBoolean(value: S);
896 if (S) {
897 Hash.AddStmt(S);
898 }
899 }
900
901 void AddDecl(const Decl *D) {
902 Hash.AddBoolean(value: D);
903 if (D) {
904 Hash.AddDecl(D);
905 }
906 }
907
908 void AddQualType(QualType T) {
909 Hash.AddQualType(T);
910 }
911
912 void AddType(const Type *T) {
913 Hash.AddBoolean(value: T);
914 if (T) {
915 Hash.AddType(T);
916 }
917 }
918
919 void AddNestedNameSpecifier(NestedNameSpecifier NNS) {
920 Hash.AddNestedNameSpecifier(NNS);
921 }
922
923 void AddIdentifierInfo(const IdentifierInfo *II) {
924 Hash.AddBoolean(value: II);
925 if (II) {
926 Hash.AddIdentifierInfo(II);
927 }
928 }
929
930 void VisitQualifiers(Qualifiers Quals) {
931 ID.AddInteger(I: Quals.getAsOpaqueValue());
932 }
933
934 // Handle typedefs which only strip away a keyword.
935 bool handleTypedef(const Type *T) {
936 const auto *TypedefT = dyn_cast<TypedefType>(Val: T);
937 if (!TypedefT)
938 return false;
939
940 QualType UnderlyingType = TypedefT->desugar();
941
942 if (UnderlyingType.hasLocalQualifiers())
943 return false;
944
945 const auto *TagT = dyn_cast<TagType>(Val&: UnderlyingType);
946 if (!TagT || TagT->getQualifier())
947 return false;
948
949 if (TypedefT->getDecl()->getIdentifier() !=
950 TagT->getDecl()->getIdentifier())
951 return false;
952
953 ID.AddInteger(I: TagT->getTypeClass());
954 VisitTagType(T: TagT, /*ElaboratedOverride=*/TypedefT);
955 return true;
956 }
957
958 void Visit(const Type *T) {
959 if (handleTypedef(T))
960 return;
961 ID.AddInteger(I: T->getTypeClass());
962 Inherited::Visit(T);
963 }
964
965 void VisitType(const Type *T) {}
966
967 void VisitAdjustedType(const AdjustedType *T) {
968 AddQualType(T: T->getOriginalType());
969
970 VisitType(T);
971 }
972
973 void VisitDecayedType(const DecayedType *T) {
974 // getDecayedType and getPointeeType are derived from getAdjustedType
975 // and don't need to be separately processed.
976 VisitAdjustedType(T);
977 }
978
979 void VisitArrayType(const ArrayType *T) {
980 AddQualType(T: T->getElementType());
981 ID.AddInteger(I: llvm::to_underlying(E: T->getSizeModifier()));
982 VisitQualifiers(Quals: T->getIndexTypeQualifiers());
983 VisitType(T);
984 }
985 void VisitConstantArrayType(const ConstantArrayType *T) {
986 T->getSize().Profile(id&: ID);
987 VisitArrayType(T);
988 }
989
990 void VisitArrayParameterType(const ArrayParameterType *T) {
991 VisitConstantArrayType(T);
992 }
993
994 void VisitDependentSizedArrayType(const DependentSizedArrayType *T) {
995 AddStmt(S: T->getSizeExpr());
996 VisitArrayType(T);
997 }
998
999 void VisitIncompleteArrayType(const IncompleteArrayType *T) {
1000 VisitArrayType(T);
1001 }
1002
1003 void VisitVariableArrayType(const VariableArrayType *T) {
1004 AddStmt(S: T->getSizeExpr());
1005 VisitArrayType(T);
1006 }
1007
1008 void VisitAttributedType(const AttributedType *T) {
1009 ID.AddInteger(I: T->getAttrKind());
1010 AddQualType(T: T->getModifiedType());
1011
1012 VisitType(T);
1013 }
1014
1015 void VisitBlockPointerType(const BlockPointerType *T) {
1016 AddQualType(T: T->getPointeeType());
1017 VisitType(T);
1018 }
1019
1020 void VisitBuiltinType(const BuiltinType *T) {
1021 ID.AddInteger(I: T->getKind());
1022 VisitType(T);
1023 }
1024
1025 void VisitComplexType(const ComplexType *T) {
1026 AddQualType(T: T->getElementType());
1027 VisitType(T);
1028 }
1029
1030 void VisitDecltypeType(const DecltypeType *T) {
1031 Hash.AddStmt(S: T->getUnderlyingExpr());
1032 VisitType(T);
1033 }
1034
1035 void VisitDependentDecltypeType(const DependentDecltypeType *T) {
1036 VisitDecltypeType(T);
1037 }
1038
1039 void VisitDeducedType(const DeducedType *T) {
1040 AddQualType(T: T->getDeducedType());
1041 VisitType(T);
1042 }
1043
1044 void VisitAutoType(const AutoType *T) {
1045 ID.AddInteger(I: (unsigned)T->getKeyword());
1046 ID.AddInteger(I: T->isConstrained());
1047 if (T->isConstrained()) {
1048 Hash.AddTemplateName(Name: T->getTypeConstraintConcept());
1049 ID.AddInteger(I: T->getTypeConstraintArguments().size());
1050 for (const auto &TA : T->getTypeConstraintArguments())
1051 Hash.AddTemplateArgument(TA);
1052 }
1053 VisitDeducedType(T);
1054 }
1055
1056 void VisitDeducedTemplateSpecializationType(
1057 const DeducedTemplateSpecializationType *T) {
1058 Hash.AddTemplateName(Name: T->getTemplateName());
1059 VisitDeducedType(T);
1060 }
1061
1062 void VisitDependentAddressSpaceType(const DependentAddressSpaceType *T) {
1063 AddQualType(T: T->getPointeeType());
1064 AddStmt(S: T->getAddrSpaceExpr());
1065 VisitType(T);
1066 }
1067
1068 void VisitDependentSizedExtVectorType(const DependentSizedExtVectorType *T) {
1069 AddQualType(T: T->getElementType());
1070 AddStmt(S: T->getSizeExpr());
1071 VisitType(T);
1072 }
1073
1074 void VisitFunctionType(const FunctionType *T) {
1075 AddQualType(T: T->getReturnType());
1076 T->getExtInfo().Profile(ID);
1077 Hash.AddBoolean(value: T->isConst());
1078 Hash.AddBoolean(value: T->isVolatile());
1079 Hash.AddBoolean(value: T->isRestrict());
1080 VisitType(T);
1081 }
1082
1083 void VisitFunctionNoProtoType(const FunctionNoProtoType *T) {
1084 VisitFunctionType(T);
1085 }
1086
1087 void VisitFunctionProtoType(const FunctionProtoType *T) {
1088 ID.AddInteger(I: T->getNumParams());
1089 for (auto ParamType : T->getParamTypes())
1090 AddQualType(T: ParamType);
1091
1092 VisitFunctionType(T);
1093 }
1094
1095 void VisitInjectedClassNameType(const InjectedClassNameType *T) {
1096 AddDecl(D: T->getDecl()->getDefinitionOrSelf());
1097 VisitType(T);
1098 }
1099
1100 void VisitMemberPointerType(const MemberPointerType *T) {
1101 AddQualType(T: T->getPointeeType());
1102 AddNestedNameSpecifier(NNS: T->getQualifier());
1103 VisitType(T);
1104 }
1105
1106 void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
1107 AddQualType(T: T->getPointeeType());
1108 VisitType(T);
1109 }
1110
1111 void VisitObjCObjectType(const ObjCObjectType *T) {
1112 AddDecl(D: T->getInterface());
1113
1114 auto TypeArgs = T->getTypeArgsAsWritten();
1115 ID.AddInteger(I: TypeArgs.size());
1116 for (auto Arg : TypeArgs) {
1117 AddQualType(T: Arg);
1118 }
1119
1120 auto Protocols = T->getProtocols();
1121 ID.AddInteger(I: Protocols.size());
1122 for (auto *Protocol : Protocols) {
1123 AddDecl(D: Protocol);
1124 }
1125
1126 Hash.AddBoolean(value: T->isKindOfType());
1127
1128 VisitType(T);
1129 }
1130
1131 void VisitObjCInterfaceType(const ObjCInterfaceType *T) {
1132 // This type is handled by the parent type ObjCObjectType.
1133 VisitObjCObjectType(T);
1134 }
1135
1136 void VisitObjCTypeParamType(const ObjCTypeParamType *T) {
1137 AddDecl(D: T->getDecl());
1138 auto Protocols = T->getProtocols();
1139 ID.AddInteger(I: Protocols.size());
1140 for (auto *Protocol : Protocols) {
1141 AddDecl(D: Protocol);
1142 }
1143
1144 VisitType(T);
1145 }
1146
1147 void VisitPackExpansionType(const PackExpansionType *T) {
1148 AddQualType(T: T->getPattern());
1149 VisitType(T);
1150 }
1151
1152 void VisitParenType(const ParenType *T) {
1153 AddQualType(T: T->getInnerType());
1154 VisitType(T);
1155 }
1156
1157 void VisitPipeType(const PipeType *T) {
1158 AddQualType(T: T->getElementType());
1159 Hash.AddBoolean(value: T->isReadOnly());
1160 VisitType(T);
1161 }
1162
1163 void VisitPointerType(const PointerType *T) {
1164 AddQualType(T: T->getPointeeType());
1165 VisitType(T);
1166 }
1167
1168 void VisitReferenceType(const ReferenceType *T) {
1169 AddQualType(T: T->getPointeeTypeAsWritten());
1170 VisitType(T);
1171 }
1172
1173 void VisitLValueReferenceType(const LValueReferenceType *T) {
1174 VisitReferenceType(T);
1175 }
1176
1177 void VisitRValueReferenceType(const RValueReferenceType *T) {
1178 VisitReferenceType(T);
1179 }
1180
1181 void
1182 VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T) {
1183 AddDecl(D: T->getAssociatedDecl());
1184 Hash.AddTemplateArgument(TA: T->getArgumentPack());
1185 VisitType(T);
1186 }
1187
1188 void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
1189 AddDecl(D: T->getAssociatedDecl());
1190 AddQualType(T: T->getReplacementType());
1191 VisitType(T);
1192 }
1193
1194 void VisitTagType(const TagType *T,
1195 const TypedefType *ElaboratedOverride = nullptr) {
1196 ID.AddInteger(I: llvm::to_underlying(
1197 E: ElaboratedOverride ? ElaboratedTypeKeyword::None : T->getKeyword()));
1198 AddNestedNameSpecifier(NNS: ElaboratedOverride
1199 ? ElaboratedOverride->getQualifier()
1200 : T->getQualifier());
1201 AddDecl(D: T->getDecl()->getDefinitionOrSelf());
1202 VisitType(T);
1203 }
1204
1205 void VisitTemplateSpecializationType(const TemplateSpecializationType *T) {
1206 ID.AddInteger(I: T->template_arguments().size());
1207 for (const auto &TA : T->template_arguments()) {
1208 Hash.AddTemplateArgument(TA);
1209 }
1210 Hash.AddTemplateName(Name: T->getTemplateName());
1211 VisitType(T);
1212 }
1213
1214 void VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
1215 ID.AddInteger(I: T->getDepth());
1216 ID.AddInteger(I: T->getIndex());
1217 Hash.AddBoolean(value: T->isParameterPack());
1218 AddDecl(D: T->getDecl());
1219 }
1220
1221 void VisitTypedefType(const TypedefType *T) {
1222 ID.AddInteger(I: llvm::to_underlying(E: T->getKeyword()));
1223 AddNestedNameSpecifier(NNS: T->getQualifier());
1224 AddDecl(D: T->getDecl());
1225 VisitType(T);
1226 }
1227
1228 void VisitTypeOfExprType(const TypeOfExprType *T) {
1229 AddStmt(S: T->getUnderlyingExpr());
1230 Hash.AddBoolean(value: T->isSugared());
1231
1232 VisitType(T);
1233 }
1234 void VisitTypeOfType(const TypeOfType *T) {
1235 AddQualType(T: T->getUnmodifiedType());
1236 VisitType(T);
1237 }
1238
1239 void VisitTypeWithKeyword(const TypeWithKeyword *T) {
1240 ID.AddInteger(I: llvm::to_underlying(E: T->getKeyword()));
1241 VisitType(T);
1242 };
1243
1244 void VisitDependentNameType(const DependentNameType *T) {
1245 AddNestedNameSpecifier(NNS: T->getQualifier());
1246 AddIdentifierInfo(II: T->getIdentifier());
1247 VisitTypeWithKeyword(T);
1248 }
1249
1250 void VisitUnaryTransformType(const UnaryTransformType *T) {
1251 AddQualType(T: T->getUnderlyingType());
1252 AddQualType(T: T->getBaseType());
1253 VisitType(T);
1254 }
1255
1256 void VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
1257 AddDecl(D: T->getDecl());
1258 VisitType(T);
1259 }
1260
1261 void VisitVectorType(const VectorType *T) {
1262 AddQualType(T: T->getElementType());
1263 ID.AddInteger(I: T->getNumElements());
1264 ID.AddInteger(I: llvm::to_underlying(E: T->getVectorKind()));
1265 VisitType(T);
1266 }
1267
1268 void VisitExtVectorType(const ExtVectorType * T) {
1269 VisitVectorType(T);
1270 }
1271};
1272} // namespace
1273
1274void ODRHash::AddType(const Type *T) {
1275 assert(T && "Expecting non-null pointer.");
1276 ODRTypeVisitor(ID, *this).Visit(T);
1277}
1278
1279void ODRHash::AddQualType(QualType T) {
1280 AddBoolean(value: T.isNull());
1281 if (T.isNull())
1282 return;
1283 SplitQualType split = T.split();
1284 ID.AddInteger(I: split.Quals.getAsOpaqueValue());
1285 AddType(T: split.Ty);
1286}
1287
1288void ODRHash::AddBoolean(bool Value) {
1289 Bools.push_back(Elt: Value);
1290}
1291
1292void ODRHash::AddStructuralValue(const APValue &Value) {
1293 ID.AddInteger(I: Value.getKind());
1294
1295 // 'APValue::Profile' uses pointer values to make hash for LValue and
1296 // MemberPointer, but they differ from one compiler invocation to another.
1297 // So, handle them explicitly here.
1298
1299 switch (Value.getKind()) {
1300 case APValue::LValue: {
1301 const APValue::LValueBase &Base = Value.getLValueBase();
1302 if (!Base) {
1303 ID.AddInteger(I: Value.getLValueOffset().getQuantity());
1304 break;
1305 }
1306
1307 assert(Base.is<const ValueDecl *>());
1308 AddDecl(D: Base.get<const ValueDecl *>());
1309 ID.AddInteger(I: Value.getLValueOffset().getQuantity());
1310
1311 bool OnePastTheEnd = Value.isLValueOnePastTheEnd();
1312 if (Value.hasLValuePath()) {
1313 QualType TypeSoFar = Base.getType();
1314 for (APValue::LValuePathEntry E : Value.getLValuePath()) {
1315 if (const auto *AT = TypeSoFar->getAsArrayTypeUnsafe()) {
1316 if (const auto *CAT = dyn_cast<ConstantArrayType>(Val: AT))
1317 OnePastTheEnd |= CAT->getSize() == E.getAsArrayIndex();
1318 TypeSoFar = AT->getElementType();
1319 } else {
1320 const Decl *D = E.getAsBaseOrMember().getPointer();
1321 if (const auto *FD = dyn_cast<FieldDecl>(Val: D)) {
1322 if (FD->getParent()->isUnion())
1323 ID.AddInteger(I: FD->getFieldIndex());
1324 TypeSoFar = FD->getType();
1325 } else {
1326 TypeSoFar =
1327 D->getASTContext().getCanonicalTagType(TD: cast<CXXRecordDecl>(Val: D));
1328 }
1329 }
1330 }
1331 }
1332 unsigned Val = 0;
1333 if (Value.isNullPointer())
1334 Val |= 1 << 0;
1335 if (OnePastTheEnd)
1336 Val |= 1 << 1;
1337 if (Value.hasLValuePath())
1338 Val |= 1 << 2;
1339 ID.AddInteger(I: Val);
1340 break;
1341 }
1342 case APValue::MemberPointer: {
1343 const ValueDecl *D = Value.getMemberPointerDecl();
1344 assert(D);
1345 AddDecl(D);
1346 ID.AddInteger(
1347 I: D->getASTContext().getMemberPointerPathAdjustment(MP: Value).getQuantity());
1348 break;
1349 }
1350 default:
1351 Value.Profile(ID);
1352 }
1353}
1354