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