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