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 const bool IsDefinition = Method->isThisDeclarationADefinition();
438 Hash.AddBoolean(IsDefinition);
439 if (IsDefinition) {
440 AddStmt(Method->getBody());
441
442 // Filter out sub-Decls which will not be processed in order to get an
443 // accurate count of Decl's.
444 llvm::SmallVector<const Decl *, 16> Decls;
445 for (Decl *SubDecl : Method->decls())
447 Decls.push_back(SubDecl);
448
449 ID.AddInteger(Decls.size());
450 for (auto SubDecl : Decls)
451 Hash.AddSubDecl(SubDecl);
452 }
453
454 Inherited::VisitObjCMethodDecl(Method);
455 }
456
457 void VisitTypedefNameDecl(const TypedefNameDecl *D) {
458 AddQualType(D->getUnderlyingType());
459
460 Inherited::VisitTypedefNameDecl(D);
461 }
462
463 void VisitTypedefDecl(const TypedefDecl *D) {
464 Inherited::VisitTypedefDecl(D);
465 }
466
467 void VisitTypeAliasDecl(const TypeAliasDecl *D) {
468 Inherited::VisitTypeAliasDecl(D);
469 }
470
471 void VisitFriendDecl(const FriendDecl *D) {
472 TypeSourceInfo *TSI = D->getFriendType();
473 Hash.AddBoolean(TSI);
474 if (TSI) {
475 AddQualType(TSI->getType());
476 } else {
477 AddDecl(D->getFriendDecl());
478 }
479 Hash.AddBoolean(D->isPackExpansion());
480 }
481
482 void VisitFriendTemplateDecl(const FriendTemplateDecl *D) {
483 for (const TemplateParameterList *TPL : D->getTemplateParameterLists())
484 Hash.AddTemplateParameterList(TPL);
485
486 bool IsTemplateFriend =
487 D->getFriendKind() ==
488 FriendTemplateDecl::FriendTemplateEntityKind::Template;
489 Hash.AddBoolean(!IsTemplateFriend);
490 if (!IsTemplateFriend) {
491 VisitFriendDecl(D);
492 if (D->getFriendKind() ==
493 FriendTemplateDecl::FriendTemplateEntityKind::Type &&
496 } else {
498 Hash.AddBoolean(D->isPackExpansion());
499 }
500 }
501
502 void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
503 // Only care about default arguments as part of the definition.
504 const bool hasDefaultArgument =
506 Hash.AddBoolean(hasDefaultArgument);
507 if (hasDefaultArgument) {
508 AddTemplateArgument(D->getDefaultArgument().getArgument());
509 }
510 Hash.AddBoolean(D->isParameterPack());
511
512 const TypeConstraint *TC = D->getTypeConstraint();
513 Hash.AddBoolean(TC != nullptr);
514 if (TC)
516
517 Inherited::VisitTemplateTypeParmDecl(D);
518 }
519
520 void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
521 // Only care about default arguments as part of the definition.
522 const bool hasDefaultArgument =
524 Hash.AddBoolean(hasDefaultArgument);
525 if (hasDefaultArgument) {
526 AddTemplateArgument(D->getDefaultArgument().getArgument());
527 }
528 Hash.AddBoolean(D->isParameterPack());
529
530 Inherited::VisitNonTypeTemplateParmDecl(D);
531 }
532
533 void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D) {
534 // Only care about default arguments as part of the definition.
535 const bool hasDefaultArgument =
537 Hash.AddBoolean(hasDefaultArgument);
538 if (hasDefaultArgument) {
539 AddTemplateArgument(D->getDefaultArgument().getArgument());
540 }
541 Hash.AddBoolean(D->isParameterPack());
542
543 Inherited::VisitTemplateTemplateParmDecl(D);
544 }
545
546 void VisitTemplateDecl(const TemplateDecl *D) {
548
549 Inherited::VisitTemplateDecl(D);
550 }
551
552 void VisitRedeclarableTemplateDecl(const RedeclarableTemplateDecl *D) {
554 Inherited::VisitRedeclarableTemplateDecl(D);
555 }
556
557 void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
558 AddDecl(D->getTemplatedDecl());
559 ID.AddInteger(D->getTemplatedDecl()->getODRHash());
560 Inherited::VisitFunctionTemplateDecl(D);
561 }
562
563 void VisitEnumConstantDecl(const EnumConstantDecl *D) {
564 AddStmt(D->getInitExpr());
565 Inherited::VisitEnumConstantDecl(D);
566 }
567};
568} // namespace
569
570// Only allow a small portion of Decl's to be processed. Remove this once
571// all Decl's can be handled.
572bool ODRHash::isSubDeclToBeProcessed(const Decl *D, const DeclContext *Parent) {
573 if (D->isImplicit()) return false;
574 if (D->getDeclContext() != Parent) return false;
575
576 switch (D->getKind()) {
577 default:
578 return false;
579 case Decl::AccessSpec:
580 case Decl::CXXConstructor:
581 case Decl::CXXDestructor:
582 case Decl::CXXMethod:
583 case Decl::EnumConstant: // Only found in EnumDecl's.
584 case Decl::Field:
585 case Decl::Friend:
586 case Decl::FriendTemplate:
587 case Decl::FunctionTemplate:
588 case Decl::StaticAssert:
589 case Decl::TypeAlias:
590 case Decl::Typedef:
591 case Decl::Var:
592 case Decl::ObjCMethod:
593 case Decl::ObjCIvar:
594 case Decl::ObjCProperty:
595 return true;
596 }
597}
598
599void ODRHash::AddSubDecl(const Decl *D) {
600 assert(D && "Expecting non-null pointer.");
601
602 ODRDeclVisitor(ID, *this).Visit(D);
603}
604
606 assert(Record && Record->hasDefinition() &&
607 "Expected non-null record to be a definition.");
608
609 const DeclContext *DC = Record;
610 while (DC) {
612 return;
613 }
614 DC = DC->getParent();
615 }
616
618
619 // Filter out sub-Decls which will not be processed in order to get an
620 // accurate count of Decl's.
622 for (Decl *SubDecl : Record->decls()) {
623 if (isSubDeclToBeProcessed(SubDecl, Record)) {
624 Decls.push_back(SubDecl);
625 if (auto *Function = dyn_cast<FunctionDecl>(SubDecl)) {
626 // Compute/Preload ODRHash into FunctionDecl.
627 Function->getODRHash();
628 }
629 }
630 }
631
632 ID.AddInteger(Decls.size());
633 for (auto SubDecl : Decls) {
634 AddSubDecl(SubDecl);
635 }
636
637 const ClassTemplateDecl *TD = Record->getDescribedClassTemplate();
638 AddBoolean(TD);
639 if (TD) {
641 }
642
643 ID.AddInteger(Record->getNumBases());
644 auto Bases = Record->bases();
645 for (const auto &Base : Bases) {
646 AddQualType(Base.getTypeSourceInfo()->getType());
647 ID.AddInteger(Base.isVirtual());
648 ID.AddInteger(Base.getAccessSpecifierAsWritten());
649 }
650}
651
653 assert(!isa<CXXRecordDecl>(Record) &&
654 "For CXXRecordDecl should call AddCXXRecordDecl.");
656
657 // Filter out sub-Decls which will not be processed in order to get an
658 // accurate count of Decl's.
660 for (Decl *SubDecl : Record->decls()) {
661 if (isSubDeclToBeProcessed(SubDecl, Record))
662 Decls.push_back(SubDecl);
663 }
664
665 ID.AddInteger(Decls.size());
666 for (const Decl *SubDecl : Decls)
667 AddSubDecl(SubDecl);
668}
669
671 AddDecl(IF);
672
673 auto *SuperClass = IF->getSuperClass();
674 AddBoolean(SuperClass);
675 if (SuperClass)
676 ID.AddInteger(SuperClass->getODRHash());
677
678 // Hash referenced protocols.
679 ID.AddInteger(IF->getReferencedProtocols().size());
680 for (const ObjCProtocolDecl *RefP : IF->protocols()) {
681 // Hash the name only as a referenced protocol can be a forward declaration.
682 AddDeclarationName(RefP->getDeclName());
683 }
684
685 // Filter out sub-Decls which will not be processed in order to get an
686 // accurate count of Decl's.
688 for (Decl *SubDecl : IF->decls())
689 if (isSubDeclToBeProcessed(SubDecl, IF))
690 Decls.push_back(SubDecl);
691
692 ID.AddInteger(Decls.size());
693 for (auto *SubDecl : Decls)
694 AddSubDecl(SubDecl);
695}
696
698 bool SkipBody) {
699 assert(Function && "Expecting non-null pointer.");
700
701 // Skip functions that are specializations or in specialization context.
702 const DeclContext *DC = Function;
703 while (DC) {
705 if (auto *F = dyn_cast<FunctionDecl>(DC)) {
706 if (F->isFunctionTemplateSpecialization()) {
707 if (!isa<CXXMethodDecl>(DC)) return;
708 if (DC->getLexicalParent()->isFileContext()) return;
709 // Skip class scope explicit function template specializations,
710 // as they have not yet been instantiated.
711 if (F->getDependentSpecializationInfo())
712 return;
713 // Inline method specializations are the only supported
714 // specialization for now.
715 }
716 }
717 DC = DC->getParent();
718 }
719
720 ID.AddInteger(Function->getDeclKind());
721
722 const auto *SpecializationArgs = Function->getTemplateSpecializationArgs();
723 AddBoolean(SpecializationArgs);
724 if (SpecializationArgs) {
725 ID.AddInteger(SpecializationArgs->size());
726 for (const TemplateArgument &TA : SpecializationArgs->asArray()) {
728 }
729 }
730
731 if (const auto *Method = dyn_cast<CXXMethodDecl>(Function)) {
732 AddBoolean(Method->isConst());
733 AddBoolean(Method->isVolatile());
734 }
735
736 ID.AddInteger(Function->getStorageClass());
737 AddBoolean(Function->isInlineSpecified());
738 AddBoolean(Function->isVirtualAsWritten());
739 AddBoolean(Function->isPureVirtual());
740 AddBoolean(Function->isDeletedAsWritten());
741 AddBoolean(Function->isExplicitlyDefaulted());
742
743 StringLiteral *DeletedMessage = Function->getDeletedMessage();
744 AddBoolean(DeletedMessage);
745
746 if (DeletedMessage)
747 ID.AddString(DeletedMessage->getBytes());
748
750
751 AddQualType(Function->getReturnType());
752
753 ID.AddInteger(Function->param_size());
754 for (auto *Param : Function->parameters())
755 AddSubDecl(Param);
756
757 if (SkipBody) {
758 AddBoolean(false);
759 return;
760 }
761
762 const bool HasBody = Function->isThisDeclarationADefinition() &&
763 !Function->isDefaulted() && !Function->isDeleted() &&
764 !Function->isLateTemplateParsed();
765 AddBoolean(HasBody);
766 if (!HasBody) {
767 return;
768 }
769
770 auto *Body = Function->getBody();
771 AddBoolean(Body);
772 if (Body)
773 AddStmt(Body);
774
775 // Filter out sub-Decls which will not be processed in order to get an
776 // accurate count of Decl's.
778 for (Decl *SubDecl : Function->decls()) {
779 if (isSubDeclToBeProcessed(SubDecl, Function)) {
780 Decls.push_back(SubDecl);
781 }
782 }
783
784 ID.AddInteger(Decls.size());
785 for (auto SubDecl : Decls) {
786 AddSubDecl(SubDecl);
787 }
788}
789
791 assert(Enum);
792 AddDeclarationName(Enum->getDeclName());
793
794 AddBoolean(Enum->isScoped());
795 if (Enum->isScoped())
796 AddBoolean(Enum->isScopedUsingClassTag());
797
798 if (Enum->getIntegerTypeSourceInfo())
799 AddQualType(Enum->getIntegerType().getCanonicalType());
800
801 // Filter out sub-Decls which will not be processed in order to get an
802 // accurate count of Decl's.
804 for (Decl *SubDecl : Enum->decls()) {
805 if (isSubDeclToBeProcessed(SubDecl, Enum)) {
806 assert(isa<EnumConstantDecl>(SubDecl) && "Unexpected Decl");
807 Decls.push_back(SubDecl);
808 }
809 }
810
811 ID.AddInteger(Decls.size());
812 for (auto SubDecl : Decls) {
813 AddSubDecl(SubDecl);
814 }
815
816}
817
819 AddDecl(P);
820
821 // Hash referenced protocols.
822 ID.AddInteger(P->getReferencedProtocols().size());
823 for (const ObjCProtocolDecl *RefP : P->protocols()) {
824 // Hash the name only as a referenced protocol can be a forward declaration.
825 AddDeclarationName(RefP->getDeclName());
826 }
827
828 // Filter out sub-Decls which will not be processed in order to get an
829 // accurate count of Decl's.
831 for (Decl *SubDecl : P->decls()) {
832 if (isSubDeclToBeProcessed(SubDecl, P)) {
833 Decls.push_back(SubDecl);
834 }
835 }
836
837 ID.AddInteger(Decls.size());
838 for (auto *SubDecl : Decls) {
839 AddSubDecl(SubDecl);
840 }
841}
842
843void ODRHash::AddDecl(const Decl *D) {
844 assert(D && "Expecting non-null pointer.");
845 D = D->getCanonicalDecl();
846
847 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
848 AddBoolean(ND);
849 if (!ND) {
850 ID.AddInteger(D->getKind());
851 return;
852 }
853
854 if (auto *FD = dyn_cast<FunctionDecl>(D))
855 AddDeclarationNameInfo(FD->getNameInfo());
856 else
858
859 // If this was a specialization we should take into account its template
860 // arguments. This helps to reduce collisions coming when visiting template
861 // specialization types (eg. when processing type template arguments).
863 if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D))
864 Args = CTSD->getTemplateArgs().asArray();
865 else if (auto *VTSD = dyn_cast<VarTemplateSpecializationDecl>(D))
866 Args = VTSD->getTemplateArgs().asArray();
867 else if (auto *FD = dyn_cast<FunctionDecl>(D))
868 if (FD->getTemplateSpecializationArgs())
869 Args = FD->getTemplateSpecializationArgs()->asArray();
870
871 for (auto &TA : Args)
873}
874
875namespace {
876// Process a Type pointer. Add* methods call back into ODRHash while Visit*
877// methods process the relevant parts of the Type.
878class ODRTypeVisitor : public TypeVisitor<ODRTypeVisitor> {
879 typedef TypeVisitor<ODRTypeVisitor> Inherited;
880 llvm::FoldingSetNodeID &ID;
881 ODRHash &Hash;
882
883public:
884 ODRTypeVisitor(llvm::FoldingSetNodeID &ID, ODRHash &Hash)
885 : ID(ID), Hash(Hash) {}
886
887 void AddStmt(Stmt *S) {
888 Hash.AddBoolean(S);
889 if (S) {
890 Hash.AddStmt(S);
891 }
892 }
893
894 void AddDecl(const Decl *D) {
895 Hash.AddBoolean(D);
896 if (D) {
897 Hash.AddDecl(D);
898 }
899 }
900
901 void AddQualType(QualType T) {
902 Hash.AddQualType(T);
903 }
904
905 void AddType(const Type *T) {
906 Hash.AddBoolean(T);
907 if (T) {
908 Hash.AddType(T);
909 }
910 }
911
912 void AddNestedNameSpecifier(NestedNameSpecifier NNS) {
913 Hash.AddNestedNameSpecifier(NNS);
914 }
915
916 void AddIdentifierInfo(const IdentifierInfo *II) {
917 Hash.AddBoolean(II);
918 if (II) {
919 Hash.AddIdentifierInfo(II);
920 }
921 }
922
923 void VisitQualifiers(Qualifiers Quals) {
924 ID.AddInteger(Quals.getAsOpaqueValue());
925 }
926
927 // Handle typedefs which only strip away a keyword.
928 bool handleTypedef(const Type *T) {
929 const auto *TypedefT = dyn_cast<TypedefType>(T);
930 if (!TypedefT)
931 return false;
932
933 QualType UnderlyingType = TypedefT->desugar();
934
935 if (UnderlyingType.hasLocalQualifiers())
936 return false;
937
938 const auto *TagT = dyn_cast<TagType>(UnderlyingType);
939 if (!TagT || TagT->getQualifier())
940 return false;
941
942 if (TypedefT->getDecl()->getIdentifier() !=
943 TagT->getDecl()->getIdentifier())
944 return false;
945
946 ID.AddInteger(TagT->getTypeClass());
947 VisitTagType(TagT, /*ElaboratedOverride=*/TypedefT);
948 return true;
949 }
950
951 void Visit(const Type *T) {
952 if (const auto *UsingT = dyn_cast<UsingType>(T)) {
953 // A using-declaration changes lookup, not the referenced entity. Preserve
954 // the keyword and qualifier at the use, not at the using-declaration.
955 const auto *Target = cast<TypeDecl>(UsingT->getDecl()->getTargetDecl());
956 T = Target->getASTContext()
957 .getTypeDeclType(UsingT->getKeyword(), UsingT->getQualifier(),
958 Target)
959 .getTypePtr();
960 }
961 if (handleTypedef(T))
962 return;
963 ID.AddInteger(T->getTypeClass());
964 Inherited::Visit(T);
965 }
966
967 void VisitType(const Type *T) {}
968
969 void VisitAdjustedType(const AdjustedType *T) {
970 AddQualType(T->getOriginalType());
971
972 VisitType(T);
973 }
974
975 void VisitDecayedType(const DecayedType *T) {
976 // getDecayedType and getPointeeType are derived from getAdjustedType
977 // and don't need to be separately processed.
978 VisitAdjustedType(T);
979 }
980
981 void VisitArrayType(const ArrayType *T) {
982 AddQualType(T->getElementType());
983 ID.AddInteger(llvm::to_underlying(T->getSizeModifier()));
984 VisitQualifiers(T->getIndexTypeQualifiers());
985 VisitType(T);
986 }
987 void VisitConstantArrayType(const ConstantArrayType *T) {
988 T->getSize().Profile(ID);
989 VisitArrayType(T);
990 }
991
992 void VisitArrayParameterType(const ArrayParameterType *T) {
993 VisitConstantArrayType(T);
994 }
995
996 void VisitDependentSizedArrayType(const DependentSizedArrayType *T) {
997 AddStmt(T->getSizeExpr());
998 VisitArrayType(T);
999 }
1000
1001 void VisitIncompleteArrayType(const IncompleteArrayType *T) {
1002 VisitArrayType(T);
1003 }
1004
1005 void VisitVariableArrayType(const VariableArrayType *T) {
1006 AddStmt(T->getSizeExpr());
1007 VisitArrayType(T);
1008 }
1009
1010 void VisitAttributedType(const AttributedType *T) {
1011 ID.AddInteger(T->getAttrKind());
1012 AddQualType(T->getModifiedType());
1013
1014 VisitType(T);
1015 }
1016
1017 void VisitBlockPointerType(const BlockPointerType *T) {
1018 AddQualType(T->getPointeeType());
1019 VisitType(T);
1020 }
1021
1022 void VisitBuiltinType(const BuiltinType *T) {
1023 ID.AddInteger(T->getKind());
1024 VisitType(T);
1025 }
1026
1027 void VisitComplexType(const ComplexType *T) {
1028 AddQualType(T->getElementType());
1029 VisitType(T);
1030 }
1031
1032 void VisitDecltypeType(const DecltypeType *T) {
1033 Hash.AddStmt(T->getUnderlyingExpr());
1034 VisitType(T);
1035 }
1036
1037 void VisitDependentDecltypeType(const DependentDecltypeType *T) {
1038 VisitDecltypeType(T);
1039 }
1040
1041 void VisitDeducedType(const DeducedType *T) {
1042 AddQualType(T->getDeducedType());
1043 VisitType(T);
1044 }
1045
1046 void VisitAutoType(const AutoType *T) {
1047 ID.AddInteger((unsigned)T->getKeyword());
1048 ID.AddInteger(T->isConstrained());
1049 if (T->isConstrained()) {
1050 Hash.AddTemplateName(T->getTypeConstraintConcept());
1051 ID.AddInteger(T->getTypeConstraintArguments().size());
1052 for (const auto &TA : T->getTypeConstraintArguments())
1053 Hash.AddTemplateArgument(TA);
1054 }
1055 VisitDeducedType(T);
1056 }
1057
1058 void VisitDeducedTemplateSpecializationType(
1059 const DeducedTemplateSpecializationType *T) {
1060 Hash.AddTemplateName(T->getTemplateName());
1061 VisitDeducedType(T);
1062 }
1063
1064 void VisitDependentAddressSpaceType(const DependentAddressSpaceType *T) {
1065 AddQualType(T->getPointeeType());
1066 AddStmt(T->getAddrSpaceExpr());
1067 VisitType(T);
1068 }
1069
1070 void VisitDependentSizedExtVectorType(const DependentSizedExtVectorType *T) {
1071 AddQualType(T->getElementType());
1072 AddStmt(T->getSizeExpr());
1073 VisitType(T);
1074 }
1075
1076 void VisitFunctionType(const FunctionType *T) {
1077 AddQualType(T->getReturnType());
1078 T->getExtInfo().Profile(ID);
1079 Hash.AddBoolean(T->isConst());
1080 Hash.AddBoolean(T->isVolatile());
1081 Hash.AddBoolean(T->isRestrict());
1082 VisitType(T);
1083 }
1084
1085 void VisitFunctionNoProtoType(const FunctionNoProtoType *T) {
1086 VisitFunctionType(T);
1087 }
1088
1089 void VisitFunctionProtoType(const FunctionProtoType *T) {
1090 ID.AddInteger(T->getNumParams());
1091 for (auto ParamType : T->getParamTypes())
1092 AddQualType(ParamType);
1093
1094 VisitFunctionType(T);
1095 }
1096
1097 void VisitInjectedClassNameType(const InjectedClassNameType *T) {
1098 AddDecl(T->getDecl()->getDefinitionOrSelf());
1099 VisitType(T);
1100 }
1101
1102 void VisitMemberPointerType(const MemberPointerType *T) {
1103 AddQualType(T->getPointeeType());
1104 AddNestedNameSpecifier(T->getQualifier());
1105 VisitType(T);
1106 }
1107
1108 void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
1109 AddQualType(T->getPointeeType());
1110 VisitType(T);
1111 }
1112
1113 void VisitObjCObjectType(const ObjCObjectType *T) {
1114 AddDecl(T->getInterface());
1115
1116 auto TypeArgs = T->getTypeArgsAsWritten();
1117 ID.AddInteger(TypeArgs.size());
1118 for (auto Arg : TypeArgs) {
1119 AddQualType(Arg);
1120 }
1121
1122 auto Protocols = T->getProtocols();
1123 ID.AddInteger(Protocols.size());
1124 for (auto *Protocol : Protocols) {
1125 AddDecl(Protocol);
1126 }
1127
1128 Hash.AddBoolean(T->isKindOfType());
1129
1130 VisitType(T);
1131 }
1132
1133 void VisitObjCInterfaceType(const ObjCInterfaceType *T) {
1134 // This type is handled by the parent type ObjCObjectType.
1135 VisitObjCObjectType(T);
1136 }
1137
1138 void VisitObjCTypeParamType(const ObjCTypeParamType *T) {
1139 AddDecl(T->getDecl());
1140 auto Protocols = T->getProtocols();
1141 ID.AddInteger(Protocols.size());
1142 for (auto *Protocol : Protocols) {
1143 AddDecl(Protocol);
1144 }
1145
1146 VisitType(T);
1147 }
1148
1149 void VisitPackExpansionType(const PackExpansionType *T) {
1150 AddQualType(T->getPattern());
1151 VisitType(T);
1152 }
1153
1154 void VisitParenType(const ParenType *T) {
1155 AddQualType(T->getInnerType());
1156 VisitType(T);
1157 }
1158
1159 void VisitPipeType(const PipeType *T) {
1160 AddQualType(T->getElementType());
1161 Hash.AddBoolean(T->isReadOnly());
1162 VisitType(T);
1163 }
1164
1165 void VisitPointerType(const PointerType *T) {
1166 AddQualType(T->getPointeeType());
1167 VisitType(T);
1168 }
1169
1170 void VisitReferenceType(const ReferenceType *T) {
1171 AddQualType(T->getPointeeTypeAsWritten());
1172 VisitType(T);
1173 }
1174
1175 void VisitLValueReferenceType(const LValueReferenceType *T) {
1176 VisitReferenceType(T);
1177 }
1178
1179 void VisitRValueReferenceType(const RValueReferenceType *T) {
1180 VisitReferenceType(T);
1181 }
1182
1183 void
1184 VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T) {
1185 AddDecl(T->getAssociatedDecl());
1186 Hash.AddTemplateArgument(T->getArgumentPack());
1187 VisitType(T);
1188 }
1189
1190 void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
1191 AddDecl(T->getAssociatedDecl());
1192 AddQualType(T->getReplacementType());
1193 VisitType(T);
1194 }
1195
1196 void VisitTagType(const TagType *T,
1197 const TypedefType *ElaboratedOverride = nullptr) {
1198 ID.AddInteger(llvm::to_underlying(
1199 ElaboratedOverride ? ElaboratedTypeKeyword::None : T->getKeyword()));
1200 AddNestedNameSpecifier(ElaboratedOverride
1201 ? ElaboratedOverride->getQualifier()
1202 : T->getQualifier());
1203 AddDecl(T->getDecl()->getDefinitionOrSelf());
1204 VisitType(T);
1205 }
1206
1207 void VisitTemplateSpecializationType(const TemplateSpecializationType *T) {
1208 ID.AddInteger(T->template_arguments().size());
1209 for (const auto &TA : T->template_arguments()) {
1210 Hash.AddTemplateArgument(TA);
1211 }
1212 Hash.AddTemplateName(T->getTemplateName());
1213 VisitType(T);
1214 }
1215
1216 void VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
1217 ID.AddInteger(T->getDepth());
1218 ID.AddInteger(T->getIndex());
1219 Hash.AddBoolean(T->isParameterPack());
1220 AddDecl(T->getDecl());
1221 }
1222
1223 void VisitTypedefType(const TypedefType *T) {
1224 ID.AddInteger(llvm::to_underlying(T->getKeyword()));
1225 AddNestedNameSpecifier(T->getQualifier());
1226 AddDecl(T->getDecl());
1227 VisitType(T);
1228 }
1229
1230 void VisitTypeOfExprType(const TypeOfExprType *T) {
1231 AddStmt(T->getUnderlyingExpr());
1232 Hash.AddBoolean(T->isSugared());
1233
1234 VisitType(T);
1235 }
1236 void VisitTypeOfType(const TypeOfType *T) {
1237 AddQualType(T->getUnmodifiedType());
1238 VisitType(T);
1239 }
1240
1241 void VisitTypeWithKeyword(const TypeWithKeyword *T) {
1242 ID.AddInteger(llvm::to_underlying(T->getKeyword()));
1243 VisitType(T);
1244 };
1245
1246 void VisitDependentNameType(const DependentNameType *T) {
1247 AddNestedNameSpecifier(T->getQualifier());
1248 AddIdentifierInfo(T->getIdentifier());
1249 VisitTypeWithKeyword(T);
1250 }
1251
1252 void VisitUnaryTransformType(const UnaryTransformType *T) {
1253 AddQualType(T->getUnderlyingType());
1254 AddQualType(T->getBaseType());
1255 VisitType(T);
1256 }
1257
1258 void VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
1259 AddDecl(T->getDecl());
1260 VisitType(T);
1261 }
1262
1263 void VisitVectorType(const VectorType *T) {
1264 AddQualType(T->getElementType());
1265 ID.AddInteger(T->getNumElements());
1266 ID.AddInteger(llvm::to_underlying(T->getVectorKind()));
1267 VisitType(T);
1268 }
1269
1270 void VisitExtVectorType(const ExtVectorType * T) {
1271 VisitVectorType(T);
1272 }
1273};
1274} // namespace
1275
1277 assert(T && "Expecting non-null pointer.");
1278 ODRTypeVisitor(ID, *this).Visit(T);
1279}
1280
1282 AddBoolean(T.isNull());
1283 if (T.isNull())
1284 return;
1285 SplitQualType split = T.split();
1286 ID.AddInteger(split.Quals.getAsOpaqueValue());
1287 AddType(split.Ty);
1288}
1289
1291 Bools.push_back(Value);
1292}
1293
1295 ID.AddInteger(Value.getKind());
1296
1297 // 'APValue::Profile' uses pointer values to make hash for LValue and
1298 // MemberPointer, but they differ from one compiler invocation to another.
1299 // So, handle them explicitly here.
1300
1301 switch (Value.getKind()) {
1302 case APValue::LValue: {
1303 const APValue::LValueBase &Base = Value.getLValueBase();
1304 if (!Base) {
1305 ID.AddInteger(Value.getLValueOffset().getQuantity());
1306 break;
1307 }
1308
1309 assert(Base.is<const ValueDecl *>());
1310 AddDecl(Base.get<const ValueDecl *>());
1311 ID.AddInteger(Value.getLValueOffset().getQuantity());
1312
1313 bool OnePastTheEnd = Value.isLValueOnePastTheEnd();
1314 if (Value.hasLValuePath()) {
1315 QualType TypeSoFar = Base.getType();
1316 for (APValue::LValuePathEntry E : Value.getLValuePath()) {
1317 if (const auto *AT = TypeSoFar->getAsArrayTypeUnsafe()) {
1318 if (const auto *CAT = dyn_cast<ConstantArrayType>(AT))
1319 OnePastTheEnd |= CAT->getSize() == E.getAsArrayIndex();
1320 TypeSoFar = AT->getElementType();
1321 } else {
1322 const Decl *D = E.getAsBaseOrMember().getPointer();
1323 if (const auto *FD = dyn_cast<FieldDecl>(D)) {
1324 if (FD->getParent()->isUnion())
1325 ID.AddInteger(FD->getFieldIndex());
1326 TypeSoFar = FD->getType();
1327 } else {
1328 TypeSoFar =
1330 }
1331 }
1332 }
1333 }
1334 unsigned Val = 0;
1335 if (Value.isNullPointer())
1336 Val |= 1 << 0;
1337 if (OnePastTheEnd)
1338 Val |= 1 << 1;
1339 if (Value.hasLValuePath())
1340 Val |= 1 << 2;
1341 ID.AddInteger(Val);
1342 break;
1343 }
1345 const ValueDecl *D = Value.getMemberPointerDecl();
1346 assert(D);
1347 AddDecl(D);
1348 ID.AddInteger(
1350 break;
1351 }
1352 default:
1353 Value.Profile(ID);
1354 }
1355}
llvm::MachO::Target Target
Definition MachO.h:51
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:209
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition APValue.h:123
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:2217
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:2423
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:4790
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:4744
unsigned getNumParams() const
Definition TypeBase.h:5676
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx)
Definition Type.cpp:4222
ArrayRef< QualType > getParamTypes() const
Definition TypeBase.h:5683
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
void Profile(llvm::FoldingSetNodeID &ID) const
Definition TypeBase.h:4821
ExtInfo getExtInfo() const
Definition TypeBase.h:4950
bool isConst() const
Definition TypeBase.h:4956
bool isRestrict() const
Definition TypeBase.h:4958
QualType getReturnType() const
Definition TypeBase.h:4934
bool isVolatile() const
Definition TypeBase.h:4957
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:843
void AddStmt(const Stmt *S)
Definition ODRHash.cpp:23
void AddStructuralValue(const APValue &)
Definition ODRHash.cpp:1294
void AddDeclarationNameInfo(DeclarationNameInfo NameInfo, bool TreatAsDecl=false)
Definition ODRHash.cpp:33
void AddCXXRecordDecl(const CXXRecordDecl *Record)
Definition ODRHash.cpp:605
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:818
void AddObjCInterfaceDecl(const ObjCInterfaceDecl *Record)
Definition ODRHash.cpp:670
void AddType(const Type *T)
Definition ODRHash.cpp:1276
void AddEnumDecl(const EnumDecl *Enum)
Definition ODRHash.cpp:790
void AddDependentTemplateName(const DependentTemplateStorage &Name)
Definition ODRHash.cpp:134
void AddFunctionDecl(const FunctionDecl *Function, bool SkipBody=false)
Definition ODRHash.cpp:697
void AddBoolean(bool value)
Definition ODRHash.cpp:1290
void AddTemplateName(TemplateName Name)
Definition ODRHash.cpp:143
void AddRecordDecl(const RecordDecl *Record)
Definition ODRHash.cpp:652
void AddSubDecl(const Decl *D)
Definition ODRHash.cpp:599
void AddNestedNameSpecifier(NestedNameSpecifier NNS)
Definition ODRHash.cpp:114
void AddQualType(QualType T)
Definition ODRHash.cpp:1281
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:572
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:8410
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:881
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
Definition TypeBase.h:9317
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:3493
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:2378
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:6010
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