clang 24.0.0git
ODRHash.cpp
Go to the documentation of this file.
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
20
21using namespace clang;
22
23void ODRHash::AddStmt(const Stmt *S) {
24 assert(S && "Expecting non-null pointer.");
25 S->ProcessODRHash(ID, *this);
26}
27
29 assert(II && "Expecting non-null pointer.");
30 ID.AddString(II->getName());
31}
32
34 bool TreatAsDecl) {
35 if (TreatAsDecl)
36 // Matches the NamedDecl check in AddDecl
37 AddBoolean(true);
38
39 AddDeclarationNameInfoImpl(NameInfo);
40
41 if (TreatAsDecl)
42 // Matches the ClassTemplateSpecializationDecl check in AddDecl
43 AddBoolean(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(std::make_pair(Name, DeclNameMap.size()));
50 ID.AddInteger(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(Name.isEmpty());
58 if (Name.isEmpty())
59 return;
60
61 auto Kind = Name.getNameKind();
62 ID.AddInteger(Kind);
63 switch (Kind) {
66 break;
70 Selector S = Name.getObjCSelector();
71 AddBoolean(S.isNull());
74 unsigned NumArgs = S.getNumArgs();
75 ID.AddInteger(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) {
81 AddBoolean(II);
82 if (II) {
84 }
85 }
86 break;
87 }
91 if (auto *TSI = NameInfo.getNamedTypeInfo())
92 AddQualType(TSI->getType());
93 else
95 break;
97 ID.AddInteger(Name.getCXXOverloadedOperator());
98 break;
101 break;
103 break;
107 if (Template) {
109 }
110 }
111 }
112}
113
115 auto Kind = NNS.getKind();
116 ID.AddInteger(llvm::to_underlying(Kind));
117 switch (Kind) {
119 auto [Namespace, Prefix] = NNS.getAsNamespaceAndPrefix();
120 AddDecl(Namespace);
122 break;
123 }
125 AddType(NNS.getAsType());
126 break;
130 break;
131 }
132}
133
137 const IdentifierInfo *II = IO.getIdentifier())
139 else
140 ID.AddInteger(IO.getOperator());
141}
142
144 auto Kind = Name.getKind();
145 ID.AddInteger(Kind);
146
147 switch (Kind) {
150 break;
156 break;
157 }
160 break;
161 }
165 AddStmt(PI->getIndexExpr());
166 break;
167 }
168 // TODO: Support these cases.
173 break;
176 break;
178 llvm_unreachable("Unexpected DeducedTemplate");
179 }
180}
181
183 const auto Kind = TA.getKind();
184 ID.AddInteger(Kind);
185
186 switch (Kind) {
188 llvm_unreachable("Expected valid TemplateArgument");
191 break;
193 AddDecl(TA.getAsDecl());
194 break;
196 ID.AddPointer(nullptr);
197 break;
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 }
207 break;
211 break;
213 AddStmt(TA.getAsExpr());
214 break;
216 ID.AddInteger(TA.pack_size());
217 for (auto SubTA : TA.pack_elements()) {
218 AddTemplateArgument(SubTA);
219 }
220 break;
221 }
222}
223
225 assert(TPL && "Expecting non-null pointer.");
226
227 ID.AddInteger(TPL->size());
228 for (auto *ND : TPL->asArray()) {
229 AddSubDecl(ND);
230 }
231
232 const Expr *RequiresClause = TPL->getRequiresClause();
233 AddBoolean(RequiresClause);
234 if (RequiresClause)
235 AddStmt(RequiresClause);
236}
237
239 DeclNameMap.clear();
240 Bools.clear();
241 ID.clear();
242}
243
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(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(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(S);
290 if (S) {
291 Hash.AddStmt(S);
292 }
293 }
294
295 void AddIdentifierInfo(const IdentifierInfo *II) {
296 Hash.AddBoolean(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(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(D->getKind());
319 Inherited::Visit(D);
320 }
321
322 void VisitNamedDecl(const NamedDecl *D) {
323 if (const auto *FD = dyn_cast<FunctionDecl>(D))
324 Hash.AddDeclarationNameInfo(FD->getNameInfo());
325 else
327 Inherited::VisitNamedDecl(D);
328 }
329
330 void VisitValueDecl(const ValueDecl *D) {
331 if (auto *DD = dyn_cast<DeclaratorDecl>(D); DD && DD->getTypeSourceInfo())
332 AddQualType(DD->getTypeSourceInfo()->getType());
333
334 Inherited::VisitValueDecl(D);
335 }
336
337 void VisitVarDecl(const VarDecl *D) {
338 Hash.AddBoolean(D->isStaticLocal());
339 Hash.AddBoolean(D->isConstexpr());
340 const bool HasInit = D->hasInit();
341 Hash.AddBoolean(HasInit);
342 if (HasInit) {
343 AddStmt(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(D->getAccess());
355 Inherited::VisitAccessSpecDecl(D);
356 }
357
358 void VisitStaticAssertDecl(const StaticAssertDecl *D) {
359 AddStmt(D->getAssertExpr());
360 AddStmt(D->getMessage());
361
362 Inherited::VisitStaticAssertDecl(D);
363 }
364
365 void VisitFieldDecl(const FieldDecl *D) {
366 const bool IsBitfield = D->isBitField();
367 Hash.AddBoolean(IsBitfield);
368
369 if (IsBitfield) {
370 AddStmt(D->getBitWidth());
371 }
372
373 Hash.AddBoolean(D->isMutable());
374 AddStmt(D->getInClassInitializer());
375
376 Inherited::VisitFieldDecl(D);
377 }
378
379 void VisitObjCIvarDecl(const ObjCIvarDecl *D) {
380 ID.AddInteger(D->getCanonicalAccessControl());
381 Inherited::VisitObjCIvarDecl(D);
382 }
383
384 void VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
385 ID.AddInteger(D->getPropertyAttributes());
386 ID.AddInteger(D->getPropertyImplementation());
387 AddQualType(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(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(Method->getDeclKind());
408 Hash.AddBoolean(Method->isInstanceMethod()); // false if class method
409 Hash.AddBoolean(Method->isVariadic());
410 Hash.AddBoolean(Method->isSynthesizedAccessorStub());
411 Hash.AddBoolean(Method->isDefined());
412 Hash.AddBoolean(Method->isDirectMethod());
413 Hash.AddBoolean(Method->isThisDeclarationADesignatedInitializer());
414 Hash.AddBoolean(Method->hasSkippedBody());
415
416 ID.AddInteger(llvm::to_underlying(Method->getImplementationControl()));
417 ID.AddInteger(Method->getMethodFamily());
418 ImplicitParamDecl *Cmd = Method->getCmdDecl();
419 Hash.AddBoolean(Cmd);
420 if (Cmd)
421 ID.AddInteger(llvm::to_underlying(Cmd->getParameterKind()));
422
423 ImplicitParamDecl *Self = Method->getSelfDecl();
424 Hash.AddBoolean(Self);
425 if (Self)
426 ID.AddInteger(llvm::to_underlying(Self->getParameterKind()));
427
428 AddDecl(Method);
429
430 if (Method->getReturnTypeSourceInfo())
431 AddQualType(Method->getReturnTypeSourceInfo()->getType());
432
433 ID.AddInteger(Method->param_size());
434 for (auto Param : Method->parameters())
435 Hash.AddSubDecl(Param);
436
437 if (Method->hasBody()) {
438 const bool IsDefinition = Method->isThisDeclarationADefinition();
439 Hash.AddBoolean(IsDefinition);
440 if (IsDefinition) {
441 Stmt *Body = Method->getBody();
442 Hash.AddBoolean(Body);
443 if (Body)
444 AddStmt(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())
451 Decls.push_back(SubDecl);
452
453 ID.AddInteger(Decls.size());
454 for (auto SubDecl : Decls)
455 Hash.AddSubDecl(SubDecl);
456 }
457 } else {
458 Hash.AddBoolean(false);
459 }
460
461 Inherited::VisitObjCMethodDecl(Method);
462 }
463
464 void VisitTypedefNameDecl(const TypedefNameDecl *D) {
465 AddQualType(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(TSI);
481 if (TSI) {
482 AddQualType(TSI->getType());
483 } else {
484 AddDecl(D->getFriendDecl());
485 }
486 Hash.AddBoolean(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(!IsTemplateFriend);
497 if (!IsTemplateFriend) {
498 VisitFriendDecl(D);
499 if (D->getFriendKind() ==
500 FriendTemplateDecl::FriendTemplateEntityKind::Type &&
503 } else {
505 Hash.AddBoolean(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 =
513 Hash.AddBoolean(hasDefaultArgument);
514 if (hasDefaultArgument) {
515 AddTemplateArgument(D->getDefaultArgument().getArgument());
516 }
517 Hash.AddBoolean(D->isParameterPack());
518
519 const TypeConstraint *TC = D->getTypeConstraint();
520 Hash.AddBoolean(TC != nullptr);
521 if (TC)
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 =
531 Hash.AddBoolean(hasDefaultArgument);
532 if (hasDefaultArgument) {
533 AddTemplateArgument(D->getDefaultArgument().getArgument());
534 }
535 Hash.AddBoolean(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 =
544 Hash.AddBoolean(hasDefaultArgument);
545 if (hasDefaultArgument) {
546 AddTemplateArgument(D->getDefaultArgument().getArgument());
547 }
548 Hash.AddBoolean(D->isParameterPack());
549
550 Inherited::VisitTemplateTemplateParmDecl(D);
551 }
552
553 void VisitTemplateDecl(const TemplateDecl *D) {
555
556 Inherited::VisitTemplateDecl(D);
557 }
558
559 void VisitRedeclarableTemplateDecl(const RedeclarableTemplateDecl *D) {
561 Inherited::VisitRedeclarableTemplateDecl(D);
562 }
563
564 void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
565 AddDecl(D->getTemplatedDecl());
566 ID.AddInteger(D->getTemplatedDecl()->getODRHash());
567 Inherited::VisitFunctionTemplateDecl(D);
568 }
569
570 void VisitEnumConstantDecl(const EnumConstantDecl *D) {
571 AddStmt(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
613 assert(Record && Record->hasDefinition() &&
614 "Expected non-null record to be a definition.");
615
616 const DeclContext *DC = Record;
617 while (DC) {
619 return;
620 }
621 DC = DC->getParent();
622 }
623
625
626 // Filter out sub-Decls which will not be processed in order to get an
627 // accurate count of Decl's.
629 for (Decl *SubDecl : Record->decls()) {
630 if (isSubDeclToBeProcessed(SubDecl, Record)) {
631 Decls.push_back(SubDecl);
632 if (auto *Function = dyn_cast<FunctionDecl>(SubDecl)) {
633 // Compute/Preload ODRHash into FunctionDecl.
634 Function->getODRHash();
635 }
636 }
637 }
638
639 ID.AddInteger(Decls.size());
640 for (auto SubDecl : Decls) {
641 AddSubDecl(SubDecl);
642 }
643
644 const ClassTemplateDecl *TD = Record->getDescribedClassTemplate();
645 AddBoolean(TD);
646 if (TD) {
648 }
649
650 ID.AddInteger(Record->getNumBases());
651 auto Bases = Record->bases();
652 for (const auto &Base : Bases) {
653 AddQualType(Base.getTypeSourceInfo()->getType());
654 ID.AddInteger(Base.isVirtual());
655 ID.AddInteger(Base.getAccessSpecifierAsWritten());
656 }
657}
658
660 assert(!isa<CXXRecordDecl>(Record) &&
661 "For CXXRecordDecl should call AddCXXRecordDecl.");
663
664 // Filter out sub-Decls which will not be processed in order to get an
665 // accurate count of Decl's.
667 for (Decl *SubDecl : Record->decls()) {
668 if (isSubDeclToBeProcessed(SubDecl, Record))
669 Decls.push_back(SubDecl);
670 }
671
672 ID.AddInteger(Decls.size());
673 for (const Decl *SubDecl : Decls)
674 AddSubDecl(SubDecl);
675}
676
678 AddDecl(IF);
679
680 auto *SuperClass = IF->getSuperClass();
681 AddBoolean(SuperClass);
682 if (SuperClass)
683 ID.AddInteger(SuperClass->getODRHash());
684
685 // Hash referenced protocols.
686 ID.AddInteger(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(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.
695 for (Decl *SubDecl : IF->decls())
696 if (isSubDeclToBeProcessed(SubDecl, IF))
697 Decls.push_back(SubDecl);
698
699 ID.AddInteger(Decls.size());
700 for (auto *SubDecl : Decls)
701 AddSubDecl(SubDecl);
702}
703
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) {
712 if (auto *F = dyn_cast<FunctionDecl>(DC)) {
713 if (F->isFunctionTemplateSpecialization()) {
714 if (!isa<CXXMethodDecl>(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(Function->getDeclKind());
728
729 const auto *SpecializationArgs = Function->getTemplateSpecializationArgs();
730 AddBoolean(SpecializationArgs);
731 if (SpecializationArgs) {
732 ID.AddInteger(SpecializationArgs->size());
733 for (const TemplateArgument &TA : SpecializationArgs->asArray()) {
735 }
736 }
737
738 if (const auto *Method = dyn_cast<CXXMethodDecl>(Function)) {
739 AddBoolean(Method->isConst());
740 AddBoolean(Method->isVolatile());
741 }
742
743 ID.AddInteger(Function->getStorageClass());
744 AddBoolean(Function->isInlineSpecified());
745 AddBoolean(Function->isVirtualAsWritten());
746 AddBoolean(Function->isPureVirtual());
747 AddBoolean(Function->isDeletedAsWritten());
748 AddBoolean(Function->isExplicitlyDefaulted());
749
750 StringLiteral *DeletedMessage = Function->getDeletedMessage();
751 AddBoolean(DeletedMessage);
752
753 if (DeletedMessage)
754 ID.AddString(DeletedMessage->getBytes());
755
757
758 AddQualType(Function->getReturnType());
759
760 ID.AddInteger(Function->param_size());
761 for (auto *Param : Function->parameters())
762 AddSubDecl(Param);
763
764 if (SkipBody) {
765 AddBoolean(false);
766 return;
767 }
768
769 const bool HasBody = Function->isThisDeclarationADefinition() &&
770 !Function->isDefaulted() && !Function->isDeleted() &&
771 !Function->isLateTemplateParsed();
772 AddBoolean(HasBody);
773 if (!HasBody) {
774 return;
775 }
776
777 auto *Body = Function->getBody();
778 AddBoolean(Body);
779 if (Body)
780 AddStmt(Body);
781
782 // Filter out sub-Decls which will not be processed in order to get an
783 // accurate count of Decl's.
785 for (Decl *SubDecl : Function->decls()) {
786 if (isSubDeclToBeProcessed(SubDecl, Function)) {
787 Decls.push_back(SubDecl);
788 }
789 }
790
791 ID.AddInteger(Decls.size());
792 for (auto SubDecl : Decls) {
793 AddSubDecl(SubDecl);
794 }
795}
796
798 assert(Enum);
799 AddDeclarationName(Enum->getDeclName());
800
801 AddBoolean(Enum->isScoped());
802 if (Enum->isScoped())
803 AddBoolean(Enum->isScopedUsingClassTag());
804
805 if (Enum->getIntegerTypeSourceInfo())
806 AddQualType(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.
811 for (Decl *SubDecl : Enum->decls()) {
812 if (isSubDeclToBeProcessed(SubDecl, Enum)) {
813 assert(isa<EnumConstantDecl>(SubDecl) && "Unexpected Decl");
814 Decls.push_back(SubDecl);
815 }
816 }
817
818 ID.AddInteger(Decls.size());
819 for (auto SubDecl : Decls) {
820 AddSubDecl(SubDecl);
821 }
822
823}
824
826 AddDecl(P);
827
828 // Hash referenced protocols.
829 ID.AddInteger(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(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.
838 for (Decl *SubDecl : P->decls()) {
839 if (isSubDeclToBeProcessed(SubDecl, P)) {
840 Decls.push_back(SubDecl);
841 }
842 }
843
844 ID.AddInteger(Decls.size());
845 for (auto *SubDecl : Decls) {
846 AddSubDecl(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>(D);
855 AddBoolean(ND);
856 if (!ND) {
857 ID.AddInteger(D->getKind());
858 return;
859 }
860
861 if (auto *FD = dyn_cast<FunctionDecl>(D))
862 AddDeclarationNameInfo(FD->getNameInfo());
863 else
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).
870 if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D))
871 Args = CTSD->getTemplateArgs().asArray();
872 else if (auto *VTSD = dyn_cast<VarTemplateSpecializationDecl>(D))
873 Args = VTSD->getTemplateArgs().asArray();
874 else if (auto *FD = dyn_cast<FunctionDecl>(D))
875 if (FD->getTemplateSpecializationArgs())
876 Args = FD->getTemplateSpecializationArgs()->asArray();
877
878 for (auto &TA : Args)
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(S);
896 if (S) {
897 Hash.AddStmt(S);
898 }
899 }
900
901 void AddDecl(const Decl *D) {
902 Hash.AddBoolean(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(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(II);
925 if (II) {
926 Hash.AddIdentifierInfo(II);
927 }
928 }
929
930 void VisitQualifiers(Qualifiers Quals) {
931 ID.AddInteger(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>(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>(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(TagT->getTypeClass());
954 VisitTagType(TagT, /*ElaboratedOverride=*/TypedefT);
955 return true;
956 }
957
958 void Visit(const Type *T) {
959 if (handleTypedef(T))
960 return;
961 ID.AddInteger(T->getTypeClass());
962 Inherited::Visit(T);
963 }
964
965 void VisitType(const Type *T) {}
966
967 void VisitAdjustedType(const AdjustedType *T) {
968 AddQualType(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->getElementType());
981 ID.AddInteger(llvm::to_underlying(T->getSizeModifier()));
982 VisitQualifiers(T->getIndexTypeQualifiers());
983 VisitType(T);
984 }
985 void VisitConstantArrayType(const ConstantArrayType *T) {
986 T->getSize().Profile(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(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(T->getSizeExpr());
1005 VisitArrayType(T);
1006 }
1007
1008 void VisitAttributedType(const AttributedType *T) {
1009 ID.AddInteger(T->getAttrKind());
1010 AddQualType(T->getModifiedType());
1011
1012 VisitType(T);
1013 }
1014
1015 void VisitBlockPointerType(const BlockPointerType *T) {
1016 AddQualType(T->getPointeeType());
1017 VisitType(T);
1018 }
1019
1020 void VisitBuiltinType(const BuiltinType *T) {
1021 ID.AddInteger(T->getKind());
1022 VisitType(T);
1023 }
1024
1025 void VisitComplexType(const ComplexType *T) {
1026 AddQualType(T->getElementType());
1027 VisitType(T);
1028 }
1029
1030 void VisitDecltypeType(const DecltypeType *T) {
1031 Hash.AddStmt(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->getDeducedType());
1041 VisitType(T);
1042 }
1043
1044 void VisitAutoType(const AutoType *T) {
1045 ID.AddInteger((unsigned)T->getKeyword());
1046 ID.AddInteger(T->isConstrained());
1047 if (T->isConstrained()) {
1048 Hash.AddTemplateName(T->getTypeConstraintConcept());
1049 ID.AddInteger(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(T->getTemplateName());
1059 VisitDeducedType(T);
1060 }
1061
1062 void VisitDependentAddressSpaceType(const DependentAddressSpaceType *T) {
1063 AddQualType(T->getPointeeType());
1064 AddStmt(T->getAddrSpaceExpr());
1065 VisitType(T);
1066 }
1067
1068 void VisitDependentSizedExtVectorType(const DependentSizedExtVectorType *T) {
1069 AddQualType(T->getElementType());
1070 AddStmt(T->getSizeExpr());
1071 VisitType(T);
1072 }
1073
1074 void VisitFunctionType(const FunctionType *T) {
1075 AddQualType(T->getReturnType());
1076 T->getExtInfo().Profile(ID);
1077 Hash.AddBoolean(T->isConst());
1078 Hash.AddBoolean(T->isVolatile());
1079 Hash.AddBoolean(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(T->getNumParams());
1089 for (auto ParamType : T->getParamTypes())
1090 AddQualType(ParamType);
1091
1092 VisitFunctionType(T);
1093 }
1094
1095 void VisitInjectedClassNameType(const InjectedClassNameType *T) {
1096 AddDecl(T->getDecl()->getDefinitionOrSelf());
1097 VisitType(T);
1098 }
1099
1100 void VisitMemberPointerType(const MemberPointerType *T) {
1101 AddQualType(T->getPointeeType());
1102 AddNestedNameSpecifier(T->getQualifier());
1103 VisitType(T);
1104 }
1105
1106 void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
1107 AddQualType(T->getPointeeType());
1108 VisitType(T);
1109 }
1110
1111 void VisitObjCObjectType(const ObjCObjectType *T) {
1112 AddDecl(T->getInterface());
1113
1114 auto TypeArgs = T->getTypeArgsAsWritten();
1115 ID.AddInteger(TypeArgs.size());
1116 for (auto Arg : TypeArgs) {
1117 AddQualType(Arg);
1118 }
1119
1120 auto Protocols = T->getProtocols();
1121 ID.AddInteger(Protocols.size());
1122 for (auto *Protocol : Protocols) {
1123 AddDecl(Protocol);
1124 }
1125
1126 Hash.AddBoolean(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(T->getDecl());
1138 auto Protocols = T->getProtocols();
1139 ID.AddInteger(Protocols.size());
1140 for (auto *Protocol : Protocols) {
1141 AddDecl(Protocol);
1142 }
1143
1144 VisitType(T);
1145 }
1146
1147 void VisitPackExpansionType(const PackExpansionType *T) {
1148 AddQualType(T->getPattern());
1149 VisitType(T);
1150 }
1151
1152 void VisitParenType(const ParenType *T) {
1153 AddQualType(T->getInnerType());
1154 VisitType(T);
1155 }
1156
1157 void VisitPipeType(const PipeType *T) {
1158 AddQualType(T->getElementType());
1159 Hash.AddBoolean(T->isReadOnly());
1160 VisitType(T);
1161 }
1162
1163 void VisitPointerType(const PointerType *T) {
1164 AddQualType(T->getPointeeType());
1165 VisitType(T);
1166 }
1167
1168 void VisitReferenceType(const ReferenceType *T) {
1169 AddQualType(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(T->getAssociatedDecl());
1184 Hash.AddTemplateArgument(T->getArgumentPack());
1185 VisitType(T);
1186 }
1187
1188 void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
1189 AddDecl(T->getAssociatedDecl());
1190 AddQualType(T->getReplacementType());
1191 VisitType(T);
1192 }
1193
1194 void VisitTagType(const TagType *T,
1195 const TypedefType *ElaboratedOverride = nullptr) {
1196 ID.AddInteger(llvm::to_underlying(
1197 ElaboratedOverride ? ElaboratedTypeKeyword::None : T->getKeyword()));
1198 AddNestedNameSpecifier(ElaboratedOverride
1199 ? ElaboratedOverride->getQualifier()
1200 : T->getQualifier());
1201 AddDecl(T->getDecl()->getDefinitionOrSelf());
1202 VisitType(T);
1203 }
1204
1205 void VisitTemplateSpecializationType(const TemplateSpecializationType *T) {
1206 ID.AddInteger(T->template_arguments().size());
1207 for (const auto &TA : T->template_arguments()) {
1208 Hash.AddTemplateArgument(TA);
1209 }
1210 Hash.AddTemplateName(T->getTemplateName());
1211 VisitType(T);
1212 }
1213
1214 void VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
1215 ID.AddInteger(T->getDepth());
1216 ID.AddInteger(T->getIndex());
1217 Hash.AddBoolean(T->isParameterPack());
1218 AddDecl(T->getDecl());
1219 }
1220
1221 void VisitTypedefType(const TypedefType *T) {
1222 ID.AddInteger(llvm::to_underlying(T->getKeyword()));
1223 AddNestedNameSpecifier(T->getQualifier());
1224 AddDecl(T->getDecl());
1225 VisitType(T);
1226 }
1227
1228 void VisitTypeOfExprType(const TypeOfExprType *T) {
1229 AddStmt(T->getUnderlyingExpr());
1230 Hash.AddBoolean(T->isSugared());
1231
1232 VisitType(T);
1233 }
1234 void VisitTypeOfType(const TypeOfType *T) {
1235 AddQualType(T->getUnmodifiedType());
1236 VisitType(T);
1237 }
1238
1239 void VisitTypeWithKeyword(const TypeWithKeyword *T) {
1240 ID.AddInteger(llvm::to_underlying(T->getKeyword()));
1241 VisitType(T);
1242 };
1243
1244 void VisitDependentNameType(const DependentNameType *T) {
1245 AddNestedNameSpecifier(T->getQualifier());
1246 AddIdentifierInfo(T->getIdentifier());
1247 VisitTypeWithKeyword(T);
1248 }
1249
1250 void VisitUnaryTransformType(const UnaryTransformType *T) {
1251 AddQualType(T->getUnderlyingType());
1252 AddQualType(T->getBaseType());
1253 VisitType(T);
1254 }
1255
1256 void VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
1257 AddDecl(T->getDecl());
1258 VisitType(T);
1259 }
1260
1261 void VisitVectorType(const VectorType *T) {
1262 AddQualType(T->getElementType());
1263 ID.AddInteger(T->getNumElements());
1264 ID.AddInteger(llvm::to_underlying(T->getVectorKind()));
1265 VisitType(T);
1266 }
1267
1268 void VisitExtVectorType(const ExtVectorType * T) {
1269 VisitVectorType(T);
1270 }
1271};
1272} // namespace
1273
1275 assert(T && "Expecting non-null pointer.");
1276 ODRTypeVisitor(ID, *this).Visit(T);
1277}
1278
1280 AddBoolean(T.isNull());
1281 if (T.isNull())
1282 return;
1283 SplitQualType split = T.split();
1284 ID.AddInteger(split.Quals.getAsOpaqueValue());
1285 AddType(split.Ty);
1286}
1287
1289 Bools.push_back(Value);
1290}
1291
1293 ID.AddInteger(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(Value.getLValueOffset().getQuantity());
1304 break;
1305 }
1306
1307 assert(Base.is<const ValueDecl *>());
1308 AddDecl(Base.get<const ValueDecl *>());
1309 ID.AddInteger(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>(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>(D)) {
1322 if (FD->getParent()->isUnion())
1323 ID.AddInteger(FD->getFieldIndex());
1324 TypeSoFar = FD->getType();
1325 } else {
1326 TypeSoFar =
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(Val);
1340 break;
1341 }
1343 const ValueDecl *D = Value.getMemberPointerDecl();
1344 assert(D);
1345 AddDecl(D);
1346 ID.AddInteger(
1348 break;
1349 }
1350 default:
1351 Value.Profile(ID);
1352 }
1353}
llvm::MachO::Record Record
Definition MachO.h:31
This file contains the declaration of the ODRHash class, which calculates a hash based on AST nodes,...
A non-discriminated union of a base, field, or array index.
Definition APValue.h:208
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition APValue.h:122
CharUnits getMemberPointerPathAdjustment(const APValue &MP) const
Find the 'this' offset for the member path in a pointer-to-member APValue.
CanQualType getCanonicalTagType(const TagDecl *TD) const
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Definition CharUnits.h:185
Declaration of a class template.
A simple visitor class that helps create declaration visitors.
Definition DeclVisitor.h:75
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition DeclBase.h:1466
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition DeclBase.h:2126
bool isFileContext() const
Definition DeclBase.h:2197
DeclContext * getLexicalParent()
getLexicalParent - Returns the containing lexical DeclContext.
Definition DeclBase.h:2142
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Definition DeclBase.h:2403
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
ASTContext & getASTContext() const LLVM_READONLY
Definition DeclBase.cpp:550
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition DeclBase.h:601
DeclContext * getDeclContext()
Definition DeclBase.h:456
AccessSpecifier getAccess() const
Definition DeclBase.h:515
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition DeclBase.h:995
Kind getKind() const
Definition DeclBase.h:450
The name of a declaration.
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...
QualType getCXXNameType() const
If this name is one of the C++ names (of a constructor, destructor, or conversion function),...
Selector getObjCSelector() const
Get the Objective-C selector stored in this declaration name.
NameKind getNameKind() const
Determine what kind of name this is.
bool isEmpty() const
Evaluates true when this declaration name is empty.
Represents a dependent template name that cannot be resolved prior to template instantiation.
IdentifierOrOverloadedOperator getName() const
NestedNameSpecifier getQualifier() const
Return the nested name specifier that qualifies this name.
const Expr * getInitExpr() const
Definition Decl.h:3576
Represents an enum.
Definition Decl.h:4146
This represents one expression.
Definition Expr.h:113
bool isMutable() const
Determines whether this field is mutable (C++ only).
Definition Decl.h:3395
Expr * getInClassInitializer() const
Get the C++11 default member initializer for this member, or null if one has not been set.
Definition Decl.cpp:4789
bool isBitField() const
Determines whether this field is a bitfield.
Definition Decl.h:3398
Expr * getBitWidth() const
Returns the expression that represents the bit width, if this field is a bit field.
Definition Decl.h:3411
virtual NamedDecl * getFriendDecl() const
If this friend declaration doesn't name a type, return the inner declaration.
Definition DeclFriend.h:102
TypeSourceInfo * getFriendType() const
If this friend declaration names an (untemplated but possibly dependent) type, return the type; other...
Definition DeclFriend.h:96
bool isPackExpansion() const
Definition DeclFriend.h:113
TemplateName getFriendTemplateName() const
FriendTemplateEntityKind getFriendKind() const
ArrayRef< TemplateParameterList * > getTemplateParameterLists() const
Represents a function declaration or definition.
Definition Decl.h:2059
unsigned getODRHash()
Returns ODRHash of the function.
Definition Decl.cpp:4743
unsigned getNumParams() const
Definition TypeBase.h:5699
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx)
Definition Type.cpp:4118
ArrayRef< QualType > getParamTypes() const
Definition TypeBase.h:5706
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
void Profile(llvm::FoldingSetNodeID &ID) const
Definition TypeBase.h:4844
ExtInfo getExtInfo() const
Definition TypeBase.h:4973
bool isConst() const
Definition TypeBase.h:4979
bool isRestrict() const
Definition TypeBase.h:4981
QualType getReturnType() const
Definition TypeBase.h:4957
bool isVolatile() const
Definition TypeBase.h:4980
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
ImplicitParamKind getParameterKind() const
Returns the implicit parameter kind.
Definition Decl.h:1810
This represents a decl that may have a name.
Definition Decl.h:275
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition Decl.h:341
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
NamespaceAndPrefix getAsNamespaceAndPrefix() const
@ MicrosoftSuper
Microsoft's '__super' specifier, stored as a CXXRecordDecl* of the class it appeared in.
@ Global
The global specifier '::'. There is no stored value.
@ Namespace
A namespace-like entity, stored as a NamespaceBaseDecl*.
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
bool defaultArgumentWasInherited() const
Determines whether the default argument was inherited from a previous declaration of this template.
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
bool isParameterPack() const
Whether this parameter is a non-type template parameter pack.
void AddDecl(const Decl *D)
Definition ODRHash.cpp:850
void AddStmt(const Stmt *S)
Definition ODRHash.cpp:23
void AddStructuralValue(const APValue &)
Definition ODRHash.cpp:1292
void AddDeclarationNameInfo(DeclarationNameInfo NameInfo, bool TreatAsDecl=false)
Definition ODRHash.cpp:33
void AddCXXRecordDecl(const CXXRecordDecl *Record)
Definition ODRHash.cpp:612
void AddDeclarationName(DeclarationName Name, bool TreatAsDecl=false)
Definition ODRHash.h:101
void AddIdentifierInfo(const IdentifierInfo *II)
Definition ODRHash.cpp:28
void AddObjCProtocolDecl(const ObjCProtocolDecl *P)
Definition ODRHash.cpp:825
void AddObjCInterfaceDecl(const ObjCInterfaceDecl *Record)
Definition ODRHash.cpp:677
void AddType(const Type *T)
Definition ODRHash.cpp:1274
void AddEnumDecl(const EnumDecl *Enum)
Definition ODRHash.cpp:797
void AddDependentTemplateName(const DependentTemplateStorage &Name)
Definition ODRHash.cpp:134
void AddFunctionDecl(const FunctionDecl *Function, bool SkipBody=false)
Definition ODRHash.cpp:704
void AddBoolean(bool value)
Definition ODRHash.cpp:1288
void AddTemplateName(TemplateName Name)
Definition ODRHash.cpp:143
void AddRecordDecl(const RecordDecl *Record)
Definition ODRHash.cpp:659
void AddSubDecl(const Decl *D)
Definition ODRHash.cpp:606
void AddNestedNameSpecifier(NestedNameSpecifier NNS)
Definition ODRHash.cpp:114
void AddQualType(QualType T)
Definition ODRHash.cpp:1279
void AddTemplateParameterList(const TemplateParameterList *TPL)
Definition ODRHash.cpp:224
void AddTemplateArgument(TemplateArgument TA)
Definition ODRHash.cpp:182
unsigned CalculateHash()
Definition ODRHash.cpp:244
static bool isSubDeclToBeProcessed(const Decl *D, const DeclContext *Parent)
Definition ODRHash.cpp:579
Represents an ObjC class declaration.
Definition DeclObjC.h:1160
protocol_range protocols() const
Definition DeclObjC.h:1365
const ObjCProtocolList & getReferencedProtocols() const
Definition DeclObjC.h:1339
ObjCInterfaceDecl * getSuperClass() const
Definition DeclObjC.cpp:349
AccessControl getCanonicalAccessControl() const
Definition DeclObjC.h:2008
unsigned size() const
Definition DeclObjC.h:70
TypeSourceInfo * getTypeSourceInfo() const
Definition DeclObjC.h:808
ObjCPropertyAttribute::Kind getPropertyAttributes() const
Definition DeclObjC.h:821
PropertyControl getPropertyImplementation() const
Definition DeclObjC.h:918
Represents an Objective-C protocol declaration.
Definition DeclObjC.h:2090
const ObjCProtocolList & getReferencedProtocols() const
Definition DeclObjC.h:2159
protocol_range protocols() const
Definition DeclObjC.h:2167
A structure for storing a pack-index-template-name ([temp.names]).
A (possibly-)qualified type.
Definition TypeBase.h:938
bool hasLocalQualifiers() const
Determine whether this particular QualType instance has any qualifiers, without looking through any t...
Definition TypeBase.h:1065
Represents a template name as written in source code.
NestedNameSpecifier getQualifier() const
Return the nested name specifier that qualifies this name.
TemplateName getUnderlyingTemplate() const
Return the underlying template name.
bool hasTemplateKeyword() const
Whether the template name was prefixed by the "template" keyword.
uint64_t getAsOpaqueValue() const
Definition TypeBase.h:456
Represents a struct/union/class.
Definition Decl.h:4460
bool isMemberSpecialization() const
Determines whether this template was a specialization of a member template.
Smart pointer class that efficiently represents Objective-C method names.
const IdentifierInfo * getIdentifierInfoForSlot(unsigned argIndex) const
Retrieve the identifier at a given position in the selector.
bool isKeywordSelector() const
bool isUnarySelector() const
bool isNull() const
Determine whether this is the empty selector.
unsigned getNumArgs() const
Stmt - This represents one statement.
Definition Stmt.h:85
void ProcessODRHash(llvm::FoldingSetNodeID &ID, ODRHash &Hash) const
Calculate a unique representation for a statement that is stable across compiler invocations.
StringLiteral - This represents a string literal expression, e.g.
Definition Expr.h:1819
StringRef getBytes() const
Allow access to clients that need the byte representation, such as ASTWriterStmt::VisitStringLiteral(...
Definition Expr.h:1895
const TemplateArgument & getArgument() const
Represents a template argument.
QualType getStructuralValueType() const
Get the type of a StructuralValue.
Expr * getAsExpr() const
Retrieve the template argument as an expression.
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.
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Represents a C++ template name within the type system.
TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const
Retrieve the underlying template declaration that this template name refers to, if known.
bool isNull() const
Determine whether this template name is NULL.
DependentTemplateName * getAsDependentTemplateName() const
Retrieve the underlying dependent template name structure, if any.
QualifiedTemplateName * getAsQualifiedTemplateName() const
Retrieve the underlying qualified template name structure, if any.
NameKind getKind() const
@ UsingTemplate
A template name that refers to a template declaration found through a specific using shadow declarati...
@ OverloadedTemplate
A set of overloaded template declarations.
@ PackIndexingTemplate
A pack-index-template-name.
@ 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...
PackIndexingTemplateStorage * getAsPackIndexingTemplate() const
Retrieve the pack-index-template-name storage, if any.
Stores a list of template parameters for a TemplateDecl and its derived classes.
Expr * getRequiresClause()
The constraint-expression of the associated requires-clause.
ArrayRef< NamedDecl * > asArray()
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
bool isParameterPack() const
Whether this template template parameter is a template parameter pack.
bool defaultArgumentWasInherited() const
Determines whether the default argument was inherited from a previous declaration of this template.
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
const TypeConstraint * getTypeConstraint() const
Returns the type constraint associated with this template parameter (if any).
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
bool defaultArgumentWasInherited() const
Determines whether the default argument was inherited from a previous declaration of this template.
bool isParameterPack() const
Returns whether this is a parameter pack.
Expr * getImmediatelyDeclaredConstraint() const
Get the immediately-declared constraint expression introduced by this type-constraint,...
Definition ASTConcept.h:244
QualType getType() const
Return the type wrapped by this type source info.
Definition TypeBase.h:8483
An operation on a type.
Definition TypeVisitor.h:64
The base class of the type hierarchy.
Definition TypeBase.h:1879
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition Type.cpp:789
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
Definition TypeBase.h:9390
TypeClass getTypeClass() const
Definition TypeBase.h:2449
QualType getUnderlyingType() const
Definition Decl.h:3752
NamedDecl * getTargetDecl() const
Gets the underlying declaration which has been brought into the local scope.
Definition DeclCXX.h:3492
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition Decl.h:713
Kind getKind() const
Definition Value.h:137
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
Definition Decl.h:1594
bool hasInit() const
Definition Decl.cpp:2380
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
Definition Decl.h:1215
const Expr * getInit() const
Definition Decl.h:1392
#define CHAR_BIT
Definition limits.h:71
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
Definition Address.h:330
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
@ Result
The result type of a method or function.
Definition TypeBase.h:906
const FunctionProtoType * T
@ Template
We are parsing a template declaration.
Definition Parser.h:81
@ Type
The name was classified as a type.
Definition Sema.h:558
U cast(CodeGen::Address addr)
Definition Address.h:327
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
Definition TypeBase.h:6033
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
DeclarationName getName() const
getName - Returns the embedded declaration name.
TypeSourceInfo * getNamedTypeInfo() const
A std::pair-like structure for storing a qualified type split into its local qualifiers and its local...
Definition TypeBase.h:871
const Type * Ty
The locally-unqualified type.
Definition TypeBase.h:873
Qualifiers Quals
The local qualifiers.
Definition TypeBase.h:876
#define remainder(__x, __y)
Definition tgmath.h:1090