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) {
65 AddIdentifierInfo(Name.getAsIdentifierInfo());
66 break;
70 Selector S = Name.getObjCSelector();
71 AddBoolean(S.isNull());
72 AddBoolean(S.isKeywordSelector());
73 AddBoolean(S.isUnarySelector());
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) {
80 const IdentifierInfo *II = S.getIdentifierInfoForSlot(i);
81 AddBoolean(II);
82 if (II) {
84 }
85 }
86 break;
87 }
91 if (auto *TSI = NameInfo.getNamedTypeInfo())
92 AddQualType(TSI->getType());
93 else
94 AddQualType(Name.getCXXNameType());
95 break;
97 ID.AddInteger(Name.getCXXOverloadedOperator());
98 break;
100 AddIdentifierInfo(Name.getCXXLiteralIdentifier());
101 break;
103 break;
105 auto *Template = Name.getCXXDeductionGuideTemplate();
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
135 AddNestedNameSpecifier(Name.getQualifier());
136 if (IdentifierOrOverloadedOperator IO = Name.getName();
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) {
149 AddDecl(Name.getAsTemplateDecl());
150 break;
152 QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName();
156 break;
157 }
159 AddDependentTemplateName(*Name.getAsDependentTemplateName());
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
313 Hash.AddDeclarationName(D->getDeclName());
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.
436 for (Decl *SubDecl : Method->decls())
437 if (ODRHash::isSubDeclToBeProcessed(SubDecl, Method))
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 =
479 D->hasDefaultArgument() && !D->defaultArgumentWasInherited();
480 Hash.AddBoolean(hasDefaultArgument);
481 if (hasDefaultArgument) {
482 AddTemplateArgument(D->getDefaultArgument().getArgument());
483 }
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 =
497 D->hasDefaultArgument() && !D->defaultArgumentWasInherited();
498 Hash.AddBoolean(hasDefaultArgument);
499 if (hasDefaultArgument) {
500 AddTemplateArgument(D->getDefaultArgument().getArgument());
501 }
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 =
510 D->hasDefaultArgument() && !D->defaultArgumentWasInherited();
511 Hash.AddBoolean(hasDefaultArgument);
512 if (hasDefaultArgument) {
513 AddTemplateArgument(D->getDefaultArgument().getArgument());
514 }
516
517 Inherited::VisitTemplateTemplateParmDecl(D);
518 }
519
520 void VisitTemplateDecl(const TemplateDecl *D) {
521 Hash.AddTemplateParameterList(D->getTemplateParameters());
522
523 Inherited::VisitTemplateDecl(D);
524 }
525
526 void VisitRedeclarableTemplateDecl(const RedeclarableTemplateDecl *D) {
527 Hash.AddBoolean(D->isMemberSpecialization());
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.
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
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) {
584 if (isa<ClassTemplateSpecializationDecl>(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) {
677 if (isa<ClassTemplateSpecializationDecl>(DC)) return;
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(
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 VisitDependentTemplateSpecializationType(
1218 Hash.AddDependentTemplateName(T->getDependentTemplateName());
1219 ID.AddInteger(T->template_arguments().size());
1220 for (const auto &TA : T->template_arguments()) {
1221 Hash.AddTemplateArgument(TA);
1222 }
1223 VisitTypeWithKeyword(T);
1224 }
1225
1226 void VisitUnaryTransformType(const UnaryTransformType *T) {
1227 AddQualType(T->getUnderlyingType());
1228 AddQualType(T->getBaseType());
1229 VisitType(T);
1230 }
1231
1232 void VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
1233 AddDecl(T->getDecl());
1234 VisitType(T);
1235 }
1236
1237 void VisitVectorType(const VectorType *T) {
1238 AddQualType(T->getElementType());
1239 ID.AddInteger(T->getNumElements());
1240 ID.AddInteger(llvm::to_underlying(T->getVectorKind()));
1241 VisitType(T);
1242 }
1243
1244 void VisitExtVectorType(const ExtVectorType * T) {
1245 VisitVectorType(T);
1246 }
1247};
1248} // namespace
1249
1251 assert(T && "Expecting non-null pointer.");
1252 ODRTypeVisitor(ID, *this).Visit(T);
1253}
1254
1256 AddBoolean(T.isNull());
1257 if (T.isNull())
1258 return;
1259 SplitQualType split = T.split();
1260 ID.AddInteger(split.Quals.getAsOpaqueValue());
1261 AddType(split.Ty);
1262}
1263
1265 Bools.push_back(Value);
1266}
1267
1269 ID.AddInteger(Value.getKind());
1270
1271 // 'APValue::Profile' uses pointer values to make hash for LValue and
1272 // MemberPointer, but they differ from one compiler invocation to another.
1273 // So, handle them explicitly here.
1274
1275 switch (Value.getKind()) {
1276 case APValue::LValue: {
1277 const APValue::LValueBase &Base = Value.getLValueBase();
1278 if (!Base) {
1279 ID.AddInteger(Value.getLValueOffset().getQuantity());
1280 break;
1281 }
1282
1283 assert(Base.is<const ValueDecl *>());
1284 AddDecl(Base.get<const ValueDecl *>());
1285 ID.AddInteger(Value.getLValueOffset().getQuantity());
1286
1287 bool OnePastTheEnd = Value.isLValueOnePastTheEnd();
1288 if (Value.hasLValuePath()) {
1289 QualType TypeSoFar = Base.getType();
1290 for (APValue::LValuePathEntry E : Value.getLValuePath()) {
1291 if (const auto *AT = TypeSoFar->getAsArrayTypeUnsafe()) {
1292 if (const auto *CAT = dyn_cast<ConstantArrayType>(AT))
1293 OnePastTheEnd |= CAT->getSize() == E.getAsArrayIndex();
1294 TypeSoFar = AT->getElementType();
1295 } else {
1296 const Decl *D = E.getAsBaseOrMember().getPointer();
1297 if (const auto *FD = dyn_cast<FieldDecl>(D)) {
1298 if (FD->getParent()->isUnion())
1299 ID.AddInteger(FD->getFieldIndex());
1300 TypeSoFar = FD->getType();
1301 } else {
1302 TypeSoFar =
1303 D->getASTContext().getCanonicalTagType(cast<CXXRecordDecl>(D));
1304 }
1305 }
1306 }
1307 }
1308 unsigned Val = 0;
1309 if (Value.isNullPointer())
1310 Val |= 1 << 0;
1311 if (OnePastTheEnd)
1312 Val |= 1 << 1;
1313 if (Value.hasLValuePath())
1314 Val |= 1 << 2;
1315 ID.AddInteger(Val);
1316 break;
1317 }
1319 const ValueDecl *D = Value.getMemberPointerDecl();
1320 assert(D);
1321 AddDecl(D);
1322 ID.AddInteger(
1324 break;
1325 }
1326 default:
1327 Value.Profile(ID);
1328 }
1329}
NodeId Parent
Definition: ASTDiff.cpp:191
StringRef P
static char ID
Definition: Arena.cpp:183
const Decl * D
Expr * E
CompileCommand Cmd
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 an access specifier followed by colon ':'.
Definition: DeclCXX.h:86
Represents a type which was implicitly adjusted by the semantic engine for arbitrary reasons.
Definition: TypeBase.h:3507
Represents a constant array type that does not decay to a pointer when used as a function parameter.
Definition: TypeBase.h:3908
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition: TypeBase.h:3738
An attributed type is a type to which a type attribute has been applied.
Definition: TypeBase.h:6585
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
Definition: TypeBase.h:7180
Pointer to a block type.
Definition: TypeBase.h:3558
This class is used for builtin types like 'int'.
Definition: TypeBase.h:3182
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2129
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.
Complex values, per C99 6.2.5p11.
Definition: TypeBase.h:3293
A simple visitor class that helps create declaration visitors.
Definition: DeclVisitor.h:75
Represents the canonical version of C arrays with a specified constant size.
Definition: TypeBase.h:3776
Represents a pointer type decayed from an array or function type.
Definition: TypeBase.h:3541
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
bool isParameterPack() const
Whether this declaration is a parameter pack.
Definition: DeclBase.cpp:244
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.
Represents the type decltype(expr) (C++11).
Definition: TypeBase.h:6270
Represents a C++17 deduced template specialization type.
Definition: TypeBase.h:7228
Common base class for placeholders for types that get replaced by placeholder type deduction: C++11 a...
Definition: TypeBase.h:7146
Represents an extended address space qualifier where the input address space value is dependent.
Definition: TypeBase.h:4077
Internal representation of canonical, dependent decltype(expr) types.
Definition: TypeBase.h:6298
Represents a qualified type name for which the type name is dependent.
Definition: TypeBase.h:7414
Represents an array type in C++ whose size is a value-dependent expression.
Definition: TypeBase.h:4027
Represents an extended vector type where either the type or size is dependent.
Definition: TypeBase.h:4117
Represents a template specialization type whose template cannot be resolved, e.g.
Definition: TypeBase.h:7465
Represents a dependent template name that cannot be resolved prior to template instantiation.
Definition: TemplateName.h:590
An instance of this object exists for each enum constant that is defined.
Definition: Decl.h:3416
Represents an enum.
Definition: Decl.h:4000
ExtVectorType - Extended vector type.
Definition: TypeBase.h:4283
Represents a member of a struct/union/class.
Definition: Decl.h:3153
FriendDecl - Represents the declaration of a friend entity, which can be a function,...
Definition: DeclFriend.h:54
Represents a function declaration or definition.
Definition: Decl.h:1999
Represents a K&R-style 'int foo()' function, which has no information available about its arguments.
Definition: TypeBase.h:4860
Represents a prototype with parameter type info, e.g.
Definition: TypeBase.h:5282
unsigned getNumParams() const
Definition: TypeBase.h:5560
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx)
Definition: Type.cpp:3991
ArrayRef< QualType > getParamTypes() const
Definition: TypeBase.h:5567
bool isSugared() const
Definition: TypeBase.h:5862
Declaration of a template function.
Definition: DeclTemplate.h:952
void Profile(llvm::FoldingSetNodeID &ID) const
Definition: TypeBase.h:4705
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition: TypeBase.h:4478
ExtInfo getExtInfo() const
Definition: TypeBase.h:4834
bool isConst() const
Definition: TypeBase.h:4840
bool isRestrict() const
Definition: TypeBase.h:4842
QualType getReturnType() const
Definition: TypeBase.h:4818
bool isVolatile() const
Definition: TypeBase.h:4841
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
Represents a C array with an unspecified size.
Definition: TypeBase.h:3925
The injected class name of a C++ class template or class template partial specialization.
Definition: TypeBase.h:6553
An lvalue reference type, per C++11 [dcl.ref].
Definition: TypeBase.h:3633
A pointer to member type per C++ 8.3.3 - Pointers to members.
Definition: TypeBase.h:3669
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.
@ Type
A type, stored as a Type*.
@ Namespace
A namespace-like entity, stored as a NamespaceBaseDecl*.
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
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:1268
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 clear()
Definition: ODRHash.cpp:225
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:1250
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:1264
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:1255
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
Interfaces are the core concept in Objective-C for object oriented design.
Definition: TypeBase.h:7905
ObjCIvarDecl - Represents an ObjC instance variable.
Definition: DeclObjC.h:1952
unsigned size() const
Definition: DeclObjC.h:70
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:140
Represents a pointer to an Objective C object.
Definition: TypeBase.h:7961
Represents a class type in Objective C.
Definition: TypeBase.h:7707
Represents one property declaration in an Objective-C interface.
Definition: DeclObjC.h:731
Represents an Objective-C protocol declaration.
Definition: DeclObjC.h:2084
Represents a type parameter type in Objective C.
Definition: TypeBase.h:7633
Represents a pack expansion of types.
Definition: TypeBase.h:7524
Sugar for parentheses used when specifying types.
Definition: TypeBase.h:3320
Represents a parameter to a function.
Definition: Decl.h:1789
PipeType - OpenCL20.
Definition: TypeBase.h:8161
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: TypeBase.h:3346
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.
Definition: TemplateName.h:504
NestedNameSpecifier getQualifier() const
Return the nested name specifier that qualifies this name.
Definition: TemplateName.h:532
TemplateName getUnderlyingTemplate() const
Return the underlying template name.
Definition: TemplateName.h:539
bool hasTemplateKeyword() const
Whether the template name was prefixed by the "template" keyword.
Definition: TemplateName.h:536
The collection of all-type qualifiers we support.
Definition: TypeBase.h:331
uint64_t getAsOpaqueValue() const
Definition: TypeBase.h:455
An rvalue reference type, per C++11 [dcl.ref].
Definition: TypeBase.h:3651
Represents a struct/union/class.
Definition: Decl.h:4305
Declaration of a redeclarable template.
Definition: DeclTemplate.h:715
Base for LValueReferenceType and RValueReferenceType.
Definition: TypeBase.h:3589
Smart pointer class that efficiently represents Objective-C method names.
Represents a C++11 static_assert declaration.
Definition: DeclCXX.h:4130
Stmt - This represents one statement.
Definition: Stmt.h:85
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
Represents the result of substituting a set of types for a template type parameter pack.
Definition: TypeBase.h:7091
Represents the result of substituting a type for a template type parameter.
Definition: TypeBase.h:6972
Represents a template argument.
Definition: TemplateBase.h:61
QualType getStructuralValueType() const
Get the type of a StructuralValue.
Definition: TemplateBase.h:402
Expr * getAsExpr() const
Retrieve the template argument as an expression.
Definition: TemplateBase.h:411
QualType getAsType() const
Retrieve the type for a type template argument.
Definition: TemplateBase.h:322
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
Definition: TemplateBase.h:366
unsigned pack_size() const
The number of template arguments in the given template argument pack.
Definition: TemplateBase.h:446
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
Definition: TemplateBase.h:329
ArrayRef< TemplateArgument > pack_elements() const
Iterator range referencing all of the elements of a template argument pack.
Definition: TemplateBase.h:440
@ Declaration
The template argument is a declaration that was provided for a pointer, reference,...
Definition: TemplateBase.h:74
@ Template
The template argument is a template name that was provided for a template template parameter.
Definition: TemplateBase.h:93
@ StructuralValue
The template argument is a non-type template argument that can't be represented by the special-case D...
Definition: TemplateBase.h:89
@ Pack
The template argument is actually a parameter pack.
Definition: TemplateBase.h:107
@ TemplateExpansion
The template argument is a pack expansion of a template name that was provided for a template templat...
Definition: TemplateBase.h:97
@ NullPtr
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
Definition: TemplateBase.h:78
@ Type
The template argument is a type.
Definition: TemplateBase.h:70
@ Null
Represents an empty template argument, e.g., one that has not been deduced.
Definition: TemplateBase.h:67
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
Definition: TemplateBase.h:82
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
Definition: TemplateBase.h:103
ArgKind getKind() const
Return the kind of stored template argument.
Definition: TemplateBase.h:296
TemplateName getAsTemplateOrTemplatePattern() const
Retrieve the template argument as a template name; if the argument is a pack expansion,...
Definition: TemplateBase.h:353
const APValue & getAsStructuralValue() const
Get the value of a StructuralValue.
Definition: TemplateBase.h:399
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:396
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:415
Represents a C++ template name within the type system.
Definition: TemplateName.h:222
@ UsingTemplate
A template name that refers to a template declaration found through a specific using shadow declarati...
Definition: TemplateName.h:267
@ OverloadedTemplate
A set of overloaded template declarations.
Definition: TemplateName.h:242
@ Template
A single template declaration.
Definition: TemplateName.h:239
@ DependentTemplate
A dependent template name that has not been resolved to a template (or set of templates).
Definition: TemplateName.h:254
@ SubstTemplateTemplateParm
A template template parameter that has been substituted for some other template name.
Definition: TemplateName.h:258
@ SubstTemplateTemplateParmPack
A template template parameter pack that has been substituted for a template template argument pack,...
Definition: TemplateName.h:263
@ DeducedTemplate
A template name that refers to another TemplateName with deduced default arguments.
Definition: TemplateName.h:271
@ QualifiedTemplate
A qualified template name, where the qualification is kept to describe the source code as written.
Definition: TemplateName.h:250
@ AssumedTemplate
An unqualified-id that has been assumed to name a function template that will be found by ADL.
Definition: TemplateName.h:246
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:74
ArrayRef< NamedDecl * > asArray()
Definition: DeclTemplate.h:143
Represents a type template specialization; the template must be a class template, a type alias templa...
Definition: TypeBase.h:7290
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
Declaration of a template type parameter.
Represents the declaration of a typedef-name via a C++11 alias-declaration.
Definition: Decl.h:3681
Models the abbreviated syntax to constrain a template type parameter: template <convertible_to<string...
Definition: ASTConcept.h:223
Expr * getImmediatelyDeclaredConstraint() const
Get the immediately-declared constraint expression introduced by this type-constraint,...
Definition: ASTConcept.h:240
Represents a typeof (or typeof) expression (a C23 feature and GCC extension) or a typeof_unqual expre...
Definition: TypeBase.h:6193
Represents typeof(type), a C23 feature and GCC extension, or `typeof_unqual(type),...
Definition: TypeBase.h:6243
A container of type source information.
Definition: TypeBase.h:8314
QualType getType() const
Return the type wrapped by this type source info.
Definition: TypeBase.h:8325
An operation on a type.
Definition: TypeVisitor.h:64
A helper class for Type nodes having an ElaboratedTypeKeyword.
Definition: TypeBase.h:5969
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:9212
TypeClass getTypeClass() const
Definition: TypeBase.h:2403
Represents the declaration of a typedef-name via the 'typedef' type specifier.
Definition: Decl.h:3660
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3555
A unary type transform, which is a type constructed from another.
Definition: TypeBase.h:6375
Represents the dependent type named by a dependently-scoped typename using declaration,...
Definition: TypeBase.h:5998
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
Represents a variable declaration or definition.
Definition: Decl.h:925
Represents a C array with a specified size that is not an integer-constant-expression.
Definition: TypeBase.h:3982
Represents a GCC generic vector type.
Definition: TypeBase.h:4191
#define CHAR_BIT
Definition: limits.h:71
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.
@ Template
We are parsing a template declaration.
const FunctionProtoType * T
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
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