clang 20.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
21
22using namespace clang;
23
24void ODRHash::AddStmt(const Stmt *S) {
25 assert(S && "Expecting non-null pointer.");
26 S->ProcessODRHash(ID, *this);
27}
28
30 assert(II && "Expecting non-null pointer.");
31 ID.AddString(II->getName());
32}
33
34void ODRHash::AddDeclarationName(DeclarationName Name, bool TreatAsDecl) {
35 if (TreatAsDecl)
36 // Matches the NamedDecl check in AddDecl
37 AddBoolean(true);
38
39 AddDeclarationNameImpl(Name);
40
41 if (TreatAsDecl)
42 // Matches the ClassTemplateSpecializationDecl check in AddDecl
43 AddBoolean(false);
44}
45
46void ODRHash::AddDeclarationNameImpl(DeclarationName Name) {
47 // Index all DeclarationName and use index numbers to refer to them.
48 auto Result = DeclNameMap.insert(std::make_pair(Name, DeclNameMap.size()));
49 ID.AddInteger(Result.first->second);
50 if (!Result.second) {
51 // If found in map, the DeclarationName has previously been processed.
52 return;
53 }
54
55 // First time processing each DeclarationName, also process its details.
56 AddBoolean(Name.isEmpty());
57 if (Name.isEmpty())
58 return;
59
60 auto Kind = Name.getNameKind();
61 ID.AddInteger(Kind);
62 switch (Kind) {
64 AddIdentifierInfo(Name.getAsIdentifierInfo());
65 break;
69 Selector S = Name.getObjCSelector();
70 AddBoolean(S.isNull());
71 AddBoolean(S.isKeywordSelector());
72 AddBoolean(S.isUnarySelector());
73 unsigned NumArgs = S.getNumArgs();
74 ID.AddInteger(NumArgs);
75 // Compare all selector slots. For selectors with arguments it means all arg
76 // slots. And if there are no arguments, compare the first-and-only slot.
77 unsigned SlotsToCheck = NumArgs > 0 ? NumArgs : 1;
78 for (unsigned i = 0; i < SlotsToCheck; ++i) {
79 const IdentifierInfo *II = S.getIdentifierInfoForSlot(i);
80 AddBoolean(II);
81 if (II) {
83 }
84 }
85 break;
86 }
89 AddQualType(Name.getCXXNameType());
90 break;
92 ID.AddInteger(Name.getCXXOverloadedOperator());
93 break;
95 AddIdentifierInfo(Name.getCXXLiteralIdentifier());
96 break;
98 AddQualType(Name.getCXXNameType());
99 break;
101 break;
103 auto *Template = Name.getCXXDeductionGuideTemplate();
104 AddBoolean(Template);
105 if (Template) {
106 AddDecl(Template);
107 }
108 }
109 }
110}
111
113 assert(NNS && "Expecting non-null pointer.");
114 const auto *Prefix = NNS->getPrefix();
115 AddBoolean(Prefix);
116 if (Prefix) {
118 }
119 auto Kind = NNS->getKind();
120 ID.AddInteger(Kind);
121 switch (Kind) {
124 break;
126 AddDecl(NNS->getAsNamespace());
127 break;
130 break;
133 AddType(NNS->getAsType());
134 break;
137 break;
138 }
139}
140
142 auto Kind = Name.getKind();
143 ID.AddInteger(Kind);
144
145 switch (Kind) {
147 AddDecl(Name.getAsTemplateDecl());
148 break;
150 QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName();
151 if (NestedNameSpecifier *NNS = QTN->getQualifier())
155 break;
156 }
157 // TODO: Support these cases.
164 break;
165 }
166}
167
169 const auto Kind = TA.getKind();
170 ID.AddInteger(Kind);
171
172 switch (Kind) {
174 llvm_unreachable("Expected valid TemplateArgument");
177 break;
179 AddDecl(TA.getAsDecl());
180 break;
182 ID.AddPointer(nullptr);
183 break;
185 // There are integrals (e.g.: _BitInt(128)) that cannot be represented as
186 // any builtin integral type, so we use the hash of APSInt instead.
187 TA.getAsIntegral().Profile(ID);
188 break;
189 }
193 break;
197 break;
199 AddStmt(TA.getAsExpr());
200 break;
202 ID.AddInteger(TA.pack_size());
203 for (auto SubTA : TA.pack_elements()) {
204 AddTemplateArgument(SubTA);
205 }
206 break;
207 }
208}
209
211 assert(TPL && "Expecting non-null pointer.");
212
213 ID.AddInteger(TPL->size());
214 for (auto *ND : TPL->asArray()) {
215 AddSubDecl(ND);
216 }
217}
218
220 DeclNameMap.clear();
221 Bools.clear();
222 ID.clear();
223}
224
226 // Append the bools to the end of the data segment backwards. This allows
227 // for the bools data to be compressed 32 times smaller compared to using
228 // ID.AddBoolean
229 const unsigned unsigned_bits = sizeof(unsigned) * CHAR_BIT;
230 const unsigned size = Bools.size();
231 const unsigned remainder = size % unsigned_bits;
232 const unsigned loops = size / unsigned_bits;
233 auto I = Bools.rbegin();
234 unsigned value = 0;
235 for (unsigned i = 0; i < remainder; ++i) {
236 value <<= 1;
237 value |= *I;
238 ++I;
239 }
240 ID.AddInteger(value);
241
242 for (unsigned i = 0; i < loops; ++i) {
243 value = 0;
244 for (unsigned j = 0; j < unsigned_bits; ++j) {
245 value <<= 1;
246 value |= *I;
247 ++I;
248 }
249 ID.AddInteger(value);
250 }
251
252 assert(I == Bools.rend());
253 Bools.clear();
254 return ID.computeStableHash();
255}
256
257namespace {
258// Process a Decl pointer. Add* methods call back into ODRHash while Visit*
259// methods process the relevant parts of the Decl.
260class ODRDeclVisitor : public ConstDeclVisitor<ODRDeclVisitor> {
261 typedef ConstDeclVisitor<ODRDeclVisitor> Inherited;
262 llvm::FoldingSetNodeID &ID;
263 ODRHash &Hash;
264
265public:
266 ODRDeclVisitor(llvm::FoldingSetNodeID &ID, ODRHash &Hash)
267 : ID(ID), Hash(Hash) {}
268
269 void AddStmt(const Stmt *S) {
270 Hash.AddBoolean(S);
271 if (S) {
272 Hash.AddStmt(S);
273 }
274 }
275
276 void AddIdentifierInfo(const IdentifierInfo *II) {
277 Hash.AddBoolean(II);
278 if (II) {
279 Hash.AddIdentifierInfo(II);
280 }
281 }
282
283 void AddQualType(QualType T) {
284 Hash.AddQualType(T);
285 }
286
287 void AddDecl(const Decl *D) {
288 Hash.AddBoolean(D);
289 if (D) {
290 Hash.AddDecl(D);
291 }
292 }
293
294 void AddTemplateArgument(TemplateArgument TA) {
295 Hash.AddTemplateArgument(TA);
296 }
297
298 void Visit(const Decl *D) {
299 ID.AddInteger(D->getKind());
300 Inherited::Visit(D);
301 }
302
303 void VisitNamedDecl(const NamedDecl *D) {
304 Hash.AddDeclarationName(D->getDeclName());
305 Inherited::VisitNamedDecl(D);
306 }
307
308 void VisitValueDecl(const ValueDecl *D) {
309 if (auto *DD = dyn_cast<DeclaratorDecl>(D); DD && DD->getTypeSourceInfo())
310 AddQualType(DD->getTypeSourceInfo()->getType());
311
312 Inherited::VisitValueDecl(D);
313 }
314
315 void VisitVarDecl(const VarDecl *D) {
316 Hash.AddBoolean(D->isStaticLocal());
317 Hash.AddBoolean(D->isConstexpr());
318 const bool HasInit = D->hasInit();
319 Hash.AddBoolean(HasInit);
320 if (HasInit) {
321 AddStmt(D->getInit());
322 }
323 Inherited::VisitVarDecl(D);
324 }
325
326 void VisitParmVarDecl(const ParmVarDecl *D) {
327 // TODO: Handle default arguments.
328 Inherited::VisitParmVarDecl(D);
329 }
330
331 void VisitAccessSpecDecl(const AccessSpecDecl *D) {
332 ID.AddInteger(D->getAccess());
333 Inherited::VisitAccessSpecDecl(D);
334 }
335
336 void VisitStaticAssertDecl(const StaticAssertDecl *D) {
337 AddStmt(D->getAssertExpr());
338 AddStmt(D->getMessage());
339
340 Inherited::VisitStaticAssertDecl(D);
341 }
342
343 void VisitFieldDecl(const FieldDecl *D) {
344 const bool IsBitfield = D->isBitField();
345 Hash.AddBoolean(IsBitfield);
346
347 if (IsBitfield) {
348 AddStmt(D->getBitWidth());
349 }
350
351 Hash.AddBoolean(D->isMutable());
352 AddStmt(D->getInClassInitializer());
353
354 Inherited::VisitFieldDecl(D);
355 }
356
357 void VisitObjCIvarDecl(const ObjCIvarDecl *D) {
358 ID.AddInteger(D->getCanonicalAccessControl());
359 Inherited::VisitObjCIvarDecl(D);
360 }
361
362 void VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
363 ID.AddInteger(D->getPropertyAttributes());
364 ID.AddInteger(D->getPropertyImplementation());
365 AddQualType(D->getTypeSourceInfo()->getType());
366 AddDecl(D);
367
368 Inherited::VisitObjCPropertyDecl(D);
369 }
370
371 void VisitFunctionDecl(const FunctionDecl *D) {
372 // Handled by the ODRHash for FunctionDecl
373 ID.AddInteger(D->getODRHash());
374
375 Inherited::VisitFunctionDecl(D);
376 }
377
378 void VisitCXXMethodDecl(const CXXMethodDecl *D) {
379 // Handled by the ODRHash for FunctionDecl
380
381 Inherited::VisitCXXMethodDecl(D);
382 }
383
384 void VisitObjCMethodDecl(const ObjCMethodDecl *Method) {
385 ID.AddInteger(Method->getDeclKind());
386 Hash.AddBoolean(Method->isInstanceMethod()); // false if class method
387 Hash.AddBoolean(Method->isVariadic());
389 Hash.AddBoolean(Method->isDefined());
390 Hash.AddBoolean(Method->isDirectMethod());
392 Hash.AddBoolean(Method->hasSkippedBody());
393
394 ID.AddInteger(llvm::to_underlying(Method->getImplementationControl()));
395 ID.AddInteger(Method->getMethodFamily());
396 ImplicitParamDecl *Cmd = Method->getCmdDecl();
397 Hash.AddBoolean(Cmd);
398 if (Cmd)
399 ID.AddInteger(llvm::to_underlying(Cmd->getParameterKind()));
400
401 ImplicitParamDecl *Self = Method->getSelfDecl();
402 Hash.AddBoolean(Self);
403 if (Self)
404 ID.AddInteger(llvm::to_underlying(Self->getParameterKind()));
405
406 AddDecl(Method);
407
408 if (Method->getReturnTypeSourceInfo())
409 AddQualType(Method->getReturnTypeSourceInfo()->getType());
410
411 ID.AddInteger(Method->param_size());
412 for (auto Param : Method->parameters())
413 Hash.AddSubDecl(Param);
414
415 if (Method->hasBody()) {
416 const bool IsDefinition = Method->isThisDeclarationADefinition();
417 Hash.AddBoolean(IsDefinition);
418 if (IsDefinition) {
419 Stmt *Body = Method->getBody();
420 Hash.AddBoolean(Body);
421 if (Body)
422 AddStmt(Body);
423
424 // Filter out sub-Decls which will not be processed in order to get an
425 // accurate count of Decl's.
427 for (Decl *SubDecl : Method->decls())
428 if (ODRHash::isSubDeclToBeProcessed(SubDecl, Method))
429 Decls.push_back(SubDecl);
430
431 ID.AddInteger(Decls.size());
432 for (auto SubDecl : Decls)
433 Hash.AddSubDecl(SubDecl);
434 }
435 } else {
436 Hash.AddBoolean(false);
437 }
438
439 Inherited::VisitObjCMethodDecl(Method);
440 }
441
442 void VisitTypedefNameDecl(const TypedefNameDecl *D) {
443 AddQualType(D->getUnderlyingType());
444
445 Inherited::VisitTypedefNameDecl(D);
446 }
447
448 void VisitTypedefDecl(const TypedefDecl *D) {
449 Inherited::VisitTypedefDecl(D);
450 }
451
452 void VisitTypeAliasDecl(const TypeAliasDecl *D) {
453 Inherited::VisitTypeAliasDecl(D);
454 }
455
456 void VisitFriendDecl(const FriendDecl *D) {
457 TypeSourceInfo *TSI = D->getFriendType();
458 Hash.AddBoolean(TSI);
459 if (TSI) {
460 AddQualType(TSI->getType());
461 } else {
462 AddDecl(D->getFriendDecl());
463 }
464 }
465
466 void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
467 // Only care about default arguments as part of the definition.
468 const bool hasDefaultArgument =
469 D->hasDefaultArgument() && !D->defaultArgumentWasInherited();
470 Hash.AddBoolean(hasDefaultArgument);
471 if (hasDefaultArgument) {
472 AddTemplateArgument(D->getDefaultArgument().getArgument());
473 }
475
476 const TypeConstraint *TC = D->getTypeConstraint();
477 Hash.AddBoolean(TC != nullptr);
478 if (TC)
480
481 Inherited::VisitTemplateTypeParmDecl(D);
482 }
483
484 void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
485 // Only care about default arguments as part of the definition.
486 const bool hasDefaultArgument =
487 D->hasDefaultArgument() && !D->defaultArgumentWasInherited();
488 Hash.AddBoolean(hasDefaultArgument);
489 if (hasDefaultArgument) {
490 AddTemplateArgument(D->getDefaultArgument().getArgument());
491 }
493
494 Inherited::VisitNonTypeTemplateParmDecl(D);
495 }
496
497 void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D) {
498 // Only care about default arguments as part of the definition.
499 const bool hasDefaultArgument =
500 D->hasDefaultArgument() && !D->defaultArgumentWasInherited();
501 Hash.AddBoolean(hasDefaultArgument);
502 if (hasDefaultArgument) {
503 AddTemplateArgument(D->getDefaultArgument().getArgument());
504 }
506
507 Inherited::VisitTemplateTemplateParmDecl(D);
508 }
509
510 void VisitTemplateDecl(const TemplateDecl *D) {
511 Hash.AddTemplateParameterList(D->getTemplateParameters());
512
513 Inherited::VisitTemplateDecl(D);
514 }
515
516 void VisitRedeclarableTemplateDecl(const RedeclarableTemplateDecl *D) {
517 Hash.AddBoolean(D->isMemberSpecialization());
518 Inherited::VisitRedeclarableTemplateDecl(D);
519 }
520
521 void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
522 AddDecl(D->getTemplatedDecl());
523 ID.AddInteger(D->getTemplatedDecl()->getODRHash());
524 Inherited::VisitFunctionTemplateDecl(D);
525 }
526
527 void VisitEnumConstantDecl(const EnumConstantDecl *D) {
528 AddStmt(D->getInitExpr());
529 Inherited::VisitEnumConstantDecl(D);
530 }
531};
532} // namespace
533
534// Only allow a small portion of Decl's to be processed. Remove this once
535// all Decl's can be handled.
537 if (D->isImplicit()) return false;
538 if (D->getDeclContext() != Parent) return false;
539
540 switch (D->getKind()) {
541 default:
542 return false;
543 case Decl::AccessSpec:
544 case Decl::CXXConstructor:
545 case Decl::CXXDestructor:
546 case Decl::CXXMethod:
547 case Decl::EnumConstant: // Only found in EnumDecl's.
548 case Decl::Field:
549 case Decl::Friend:
550 case Decl::FunctionTemplate:
551 case Decl::StaticAssert:
552 case Decl::TypeAlias:
553 case Decl::Typedef:
554 case Decl::Var:
555 case Decl::ObjCMethod:
556 case Decl::ObjCIvar:
557 case Decl::ObjCProperty:
558 return true;
559 }
560}
561
563 assert(D && "Expecting non-null pointer.");
564
565 ODRDeclVisitor(ID, *this).Visit(D);
566}
567
569 assert(Record && Record->hasDefinition() &&
570 "Expected non-null record to be a definition.");
571
572 const DeclContext *DC = Record;
573 while (DC) {
574 if (isa<ClassTemplateSpecializationDecl>(DC)) {
575 return;
576 }
577 DC = DC->getParent();
578 }
579
581
582 // Filter out sub-Decls which will not be processed in order to get an
583 // accurate count of Decl's.
585 for (Decl *SubDecl : Record->decls()) {
586 if (isSubDeclToBeProcessed(SubDecl, Record)) {
587 Decls.push_back(SubDecl);
588 if (auto *Function = dyn_cast<FunctionDecl>(SubDecl)) {
589 // Compute/Preload ODRHash into FunctionDecl.
590 Function->getODRHash();
591 }
592 }
593 }
594
595 ID.AddInteger(Decls.size());
596 for (auto SubDecl : Decls) {
597 AddSubDecl(SubDecl);
598 }
599
600 const ClassTemplateDecl *TD = Record->getDescribedClassTemplate();
601 AddBoolean(TD);
602 if (TD) {
604 }
605
606 ID.AddInteger(Record->getNumBases());
607 auto Bases = Record->bases();
608 for (const auto &Base : Bases) {
609 AddQualType(Base.getTypeSourceInfo()->getType());
610 ID.AddInteger(Base.isVirtual());
611 ID.AddInteger(Base.getAccessSpecifierAsWritten());
612 }
613}
614
616 assert(!isa<CXXRecordDecl>(Record) &&
617 "For CXXRecordDecl should call AddCXXRecordDecl.");
619
620 // Filter out sub-Decls which will not be processed in order to get an
621 // accurate count of Decl's.
623 for (Decl *SubDecl : Record->decls()) {
624 if (isSubDeclToBeProcessed(SubDecl, Record))
625 Decls.push_back(SubDecl);
626 }
627
628 ID.AddInteger(Decls.size());
629 for (const Decl *SubDecl : Decls)
630 AddSubDecl(SubDecl);
631}
632
634 AddDecl(IF);
635
636 auto *SuperClass = IF->getSuperClass();
637 AddBoolean(SuperClass);
638 if (SuperClass)
639 ID.AddInteger(SuperClass->getODRHash());
640
641 // Hash referenced protocols.
642 ID.AddInteger(IF->getReferencedProtocols().size());
643 for (const ObjCProtocolDecl *RefP : IF->protocols()) {
644 // Hash the name only as a referenced protocol can be a forward declaration.
645 AddDeclarationName(RefP->getDeclName());
646 }
647
648 // Filter out sub-Decls which will not be processed in order to get an
649 // accurate count of Decl's.
651 for (Decl *SubDecl : IF->decls())
652 if (isSubDeclToBeProcessed(SubDecl, IF))
653 Decls.push_back(SubDecl);
654
655 ID.AddInteger(Decls.size());
656 for (auto *SubDecl : Decls)
657 AddSubDecl(SubDecl);
658}
659
661 bool SkipBody) {
662 assert(Function && "Expecting non-null pointer.");
663
664 // Skip functions that are specializations or in specialization context.
665 const DeclContext *DC = Function;
666 while (DC) {
667 if (isa<ClassTemplateSpecializationDecl>(DC)) return;
668 if (auto *F = dyn_cast<FunctionDecl>(DC)) {
669 if (F->isFunctionTemplateSpecialization()) {
670 if (!isa<CXXMethodDecl>(DC)) return;
671 if (DC->getLexicalParent()->isFileContext()) return;
672 // Skip class scope explicit function template specializations,
673 // as they have not yet been instantiated.
674 if (F->getDependentSpecializationInfo())
675 return;
676 // Inline method specializations are the only supported
677 // specialization for now.
678 }
679 }
680 DC = DC->getParent();
681 }
682
683 ID.AddInteger(Function->getDeclKind());
684
685 const auto *SpecializationArgs = Function->getTemplateSpecializationArgs();
686 AddBoolean(SpecializationArgs);
687 if (SpecializationArgs) {
688 ID.AddInteger(SpecializationArgs->size());
689 for (const TemplateArgument &TA : SpecializationArgs->asArray()) {
691 }
692 }
693
694 if (const auto *Method = dyn_cast<CXXMethodDecl>(Function)) {
695 AddBoolean(Method->isConst());
696 AddBoolean(Method->isVolatile());
697 }
698
699 ID.AddInteger(Function->getStorageClass());
700 AddBoolean(Function->isInlineSpecified());
701 AddBoolean(Function->isVirtualAsWritten());
702 AddBoolean(Function->isPureVirtual());
703 AddBoolean(Function->isDeletedAsWritten());
704 AddBoolean(Function->isExplicitlyDefaulted());
705
706 StringLiteral *DeletedMessage = Function->getDeletedMessage();
707 AddBoolean(DeletedMessage);
708
709 if (DeletedMessage)
710 ID.AddString(DeletedMessage->getBytes());
711
713
714 AddQualType(Function->getReturnType());
715
716 ID.AddInteger(Function->param_size());
717 for (auto *Param : Function->parameters())
718 AddSubDecl(Param);
719
720 if (SkipBody) {
721 AddBoolean(false);
722 return;
723 }
724
725 const bool HasBody = Function->isThisDeclarationADefinition() &&
726 !Function->isDefaulted() && !Function->isDeleted() &&
727 !Function->isLateTemplateParsed();
728 AddBoolean(HasBody);
729 if (!HasBody) {
730 return;
731 }
732
733 auto *Body = Function->getBody();
734 AddBoolean(Body);
735 if (Body)
736 AddStmt(Body);
737
738 // Filter out sub-Decls which will not be processed in order to get an
739 // accurate count of Decl's.
741 for (Decl *SubDecl : Function->decls()) {
742 if (isSubDeclToBeProcessed(SubDecl, Function)) {
743 Decls.push_back(SubDecl);
744 }
745 }
746
747 ID.AddInteger(Decls.size());
748 for (auto SubDecl : Decls) {
749 AddSubDecl(SubDecl);
750 }
751}
752
754 assert(Enum);
755 AddDeclarationName(Enum->getDeclName());
756
757 AddBoolean(Enum->isScoped());
758 if (Enum->isScoped())
759 AddBoolean(Enum->isScopedUsingClassTag());
760
761 if (Enum->getIntegerTypeSourceInfo())
762 AddQualType(Enum->getIntegerType().getCanonicalType());
763
764 // Filter out sub-Decls which will not be processed in order to get an
765 // accurate count of Decl's.
767 for (Decl *SubDecl : Enum->decls()) {
768 if (isSubDeclToBeProcessed(SubDecl, Enum)) {
769 assert(isa<EnumConstantDecl>(SubDecl) && "Unexpected Decl");
770 Decls.push_back(SubDecl);
771 }
772 }
773
774 ID.AddInteger(Decls.size());
775 for (auto SubDecl : Decls) {
776 AddSubDecl(SubDecl);
777 }
778
779}
780
782 AddDecl(P);
783
784 // Hash referenced protocols.
785 ID.AddInteger(P->getReferencedProtocols().size());
786 for (const ObjCProtocolDecl *RefP : P->protocols()) {
787 // Hash the name only as a referenced protocol can be a forward declaration.
788 AddDeclarationName(RefP->getDeclName());
789 }
790
791 // Filter out sub-Decls which will not be processed in order to get an
792 // accurate count of Decl's.
794 for (Decl *SubDecl : P->decls()) {
795 if (isSubDeclToBeProcessed(SubDecl, P)) {
796 Decls.push_back(SubDecl);
797 }
798 }
799
800 ID.AddInteger(Decls.size());
801 for (auto *SubDecl : Decls) {
802 AddSubDecl(SubDecl);
803 }
804}
805
806void ODRHash::AddDecl(const Decl *D) {
807 assert(D && "Expecting non-null pointer.");
808 D = D->getCanonicalDecl();
809
810 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
811 AddBoolean(ND);
812 if (!ND) {
813 ID.AddInteger(D->getKind());
814 return;
815 }
816
818
819 const auto *Specialization =
820 dyn_cast<ClassTemplateSpecializationDecl>(D);
822 if (Specialization) {
823 const TemplateArgumentList &List = Specialization->getTemplateArgs();
824 ID.AddInteger(List.size());
825 for (const TemplateArgument &TA : List.asArray())
827 }
828}
829
830namespace {
831// Process a Type pointer. Add* methods call back into ODRHash while Visit*
832// methods process the relevant parts of the Type.
833class ODRTypeVisitor : public TypeVisitor<ODRTypeVisitor> {
834 typedef TypeVisitor<ODRTypeVisitor> Inherited;
835 llvm::FoldingSetNodeID &ID;
836 ODRHash &Hash;
837
838public:
839 ODRTypeVisitor(llvm::FoldingSetNodeID &ID, ODRHash &Hash)
840 : ID(ID), Hash(Hash) {}
841
842 void AddStmt(Stmt *S) {
843 Hash.AddBoolean(S);
844 if (S) {
845 Hash.AddStmt(S);
846 }
847 }
848
849 void AddDecl(const Decl *D) {
850 Hash.AddBoolean(D);
851 if (D) {
852 Hash.AddDecl(D);
853 }
854 }
855
856 void AddQualType(QualType T) {
857 Hash.AddQualType(T);
858 }
859
860 void AddType(const Type *T) {
861 Hash.AddBoolean(T);
862 if (T) {
863 Hash.AddType(T);
864 }
865 }
866
867 void AddNestedNameSpecifier(const NestedNameSpecifier *NNS) {
868 Hash.AddBoolean(NNS);
869 if (NNS) {
870 Hash.AddNestedNameSpecifier(NNS);
871 }
872 }
873
874 void AddIdentifierInfo(const IdentifierInfo *II) {
875 Hash.AddBoolean(II);
876 if (II) {
877 Hash.AddIdentifierInfo(II);
878 }
879 }
880
881 void VisitQualifiers(Qualifiers Quals) {
882 ID.AddInteger(Quals.getAsOpaqueValue());
883 }
884
885 // Return the RecordType if the typedef only strips away a keyword.
886 // Otherwise, return the original type.
887 static const Type *RemoveTypedef(const Type *T) {
888 const auto *TypedefT = dyn_cast<TypedefType>(T);
889 if (!TypedefT) {
890 return T;
891 }
892
893 const TypedefNameDecl *D = TypedefT->getDecl();
894 QualType UnderlyingType = D->getUnderlyingType();
895
896 if (UnderlyingType.hasLocalQualifiers()) {
897 return T;
898 }
899
900 const auto *ElaboratedT = dyn_cast<ElaboratedType>(UnderlyingType);
901 if (!ElaboratedT) {
902 return T;
903 }
904
905 if (ElaboratedT->getQualifier() != nullptr) {
906 return T;
907 }
908
909 QualType NamedType = ElaboratedT->getNamedType();
910 if (NamedType.hasLocalQualifiers()) {
911 return T;
912 }
913
914 const auto *RecordT = dyn_cast<RecordType>(NamedType);
915 if (!RecordT) {
916 return T;
917 }
918
919 const IdentifierInfo *TypedefII = TypedefT->getDecl()->getIdentifier();
920 const IdentifierInfo *RecordII = RecordT->getDecl()->getIdentifier();
921 if (!TypedefII || !RecordII ||
922 TypedefII->getName() != RecordII->getName()) {
923 return T;
924 }
925
926 return RecordT;
927 }
928
929 void Visit(const Type *T) {
930 T = RemoveTypedef(T);
931 ID.AddInteger(T->getTypeClass());
932 Inherited::Visit(T);
933 }
934
935 void VisitType(const Type *T) {}
936
937 void VisitAdjustedType(const AdjustedType *T) {
938 AddQualType(T->getOriginalType());
939
940 VisitType(T);
941 }
942
943 void VisitDecayedType(const DecayedType *T) {
944 // getDecayedType and getPointeeType are derived from getAdjustedType
945 // and don't need to be separately processed.
946 VisitAdjustedType(T);
947 }
948
949 void VisitArrayType(const ArrayType *T) {
950 AddQualType(T->getElementType());
951 ID.AddInteger(llvm::to_underlying(T->getSizeModifier()));
952 VisitQualifiers(T->getIndexTypeQualifiers());
953 VisitType(T);
954 }
955 void VisitConstantArrayType(const ConstantArrayType *T) {
956 T->getSize().Profile(ID);
957 VisitArrayType(T);
958 }
959
960 void VisitArrayParameterType(const ArrayParameterType *T) {
961 VisitConstantArrayType(T);
962 }
963
964 void VisitDependentSizedArrayType(const DependentSizedArrayType *T) {
965 AddStmt(T->getSizeExpr());
966 VisitArrayType(T);
967 }
968
969 void VisitIncompleteArrayType(const IncompleteArrayType *T) {
970 VisitArrayType(T);
971 }
972
973 void VisitVariableArrayType(const VariableArrayType *T) {
974 AddStmt(T->getSizeExpr());
975 VisitArrayType(T);
976 }
977
978 void VisitAttributedType(const AttributedType *T) {
979 ID.AddInteger(T->getAttrKind());
980 AddQualType(T->getModifiedType());
981
982 VisitType(T);
983 }
984
985 void VisitBlockPointerType(const BlockPointerType *T) {
986 AddQualType(T->getPointeeType());
987 VisitType(T);
988 }
989
990 void VisitBuiltinType(const BuiltinType *T) {
991 ID.AddInteger(T->getKind());
992 VisitType(T);
993 }
994
995 void VisitComplexType(const ComplexType *T) {
996 AddQualType(T->getElementType());
997 VisitType(T);
998 }
999
1000 void VisitDecltypeType(const DecltypeType *T) {
1001 AddStmt(T->getUnderlyingExpr());
1002 VisitType(T);
1003 }
1004
1005 void VisitDependentDecltypeType(const DependentDecltypeType *T) {
1006 VisitDecltypeType(T);
1007 }
1008
1009 void VisitDeducedType(const DeducedType *T) {
1010 AddQualType(T->getDeducedType());
1011 VisitType(T);
1012 }
1013
1014 void VisitAutoType(const AutoType *T) {
1015 ID.AddInteger((unsigned)T->getKeyword());
1016 ID.AddInteger(T->isConstrained());
1017 if (T->isConstrained()) {
1018 AddDecl(T->getTypeConstraintConcept());
1019 ID.AddInteger(T->getTypeConstraintArguments().size());
1020 for (const auto &TA : T->getTypeConstraintArguments())
1021 Hash.AddTemplateArgument(TA);
1022 }
1023 VisitDeducedType(T);
1024 }
1025
1026 void VisitDeducedTemplateSpecializationType(
1028 Hash.AddTemplateName(T->getTemplateName());
1029 VisitDeducedType(T);
1030 }
1031
1032 void VisitDependentAddressSpaceType(const DependentAddressSpaceType *T) {
1033 AddQualType(T->getPointeeType());
1034 AddStmt(T->getAddrSpaceExpr());
1035 VisitType(T);
1036 }
1037
1038 void VisitDependentSizedExtVectorType(const DependentSizedExtVectorType *T) {
1039 AddQualType(T->getElementType());
1040 AddStmt(T->getSizeExpr());
1041 VisitType(T);
1042 }
1043
1044 void VisitFunctionType(const FunctionType *T) {
1045 AddQualType(T->getReturnType());
1046 T->getExtInfo().Profile(ID);
1047 Hash.AddBoolean(T->isConst());
1048 Hash.AddBoolean(T->isVolatile());
1049 Hash.AddBoolean(T->isRestrict());
1050 VisitType(T);
1051 }
1052
1053 void VisitFunctionNoProtoType(const FunctionNoProtoType *T) {
1054 VisitFunctionType(T);
1055 }
1056
1057 void VisitFunctionProtoType(const FunctionProtoType *T) {
1058 ID.AddInteger(T->getNumParams());
1059 for (auto ParamType : T->getParamTypes())
1060 AddQualType(ParamType);
1061
1062 VisitFunctionType(T);
1063 }
1064
1065 void VisitInjectedClassNameType(const InjectedClassNameType *T) {
1066 AddDecl(T->getDecl());
1067 VisitType(T);
1068 }
1069
1070 void VisitMemberPointerType(const MemberPointerType *T) {
1071 AddQualType(T->getPointeeType());
1072 AddType(T->getClass());
1073 VisitType(T);
1074 }
1075
1076 void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
1077 AddQualType(T->getPointeeType());
1078 VisitType(T);
1079 }
1080
1081 void VisitObjCObjectType(const ObjCObjectType *T) {
1082 AddDecl(T->getInterface());
1083
1084 auto TypeArgs = T->getTypeArgsAsWritten();
1085 ID.AddInteger(TypeArgs.size());
1086 for (auto Arg : TypeArgs) {
1087 AddQualType(Arg);
1088 }
1089
1090 auto Protocols = T->getProtocols();
1091 ID.AddInteger(Protocols.size());
1092 for (auto *Protocol : Protocols) {
1093 AddDecl(Protocol);
1094 }
1095
1096 Hash.AddBoolean(T->isKindOfType());
1097
1098 VisitType(T);
1099 }
1100
1101 void VisitObjCInterfaceType(const ObjCInterfaceType *T) {
1102 // This type is handled by the parent type ObjCObjectType.
1103 VisitObjCObjectType(T);
1104 }
1105
1106 void VisitObjCTypeParamType(const ObjCTypeParamType *T) {
1107 AddDecl(T->getDecl());
1108 auto Protocols = T->getProtocols();
1109 ID.AddInteger(Protocols.size());
1110 for (auto *Protocol : Protocols) {
1111 AddDecl(Protocol);
1112 }
1113
1114 VisitType(T);
1115 }
1116
1117 void VisitPackExpansionType(const PackExpansionType *T) {
1118 AddQualType(T->getPattern());
1119 VisitType(T);
1120 }
1121
1122 void VisitParenType(const ParenType *T) {
1123 AddQualType(T->getInnerType());
1124 VisitType(T);
1125 }
1126
1127 void VisitPipeType(const PipeType *T) {
1128 AddQualType(T->getElementType());
1129 Hash.AddBoolean(T->isReadOnly());
1130 VisitType(T);
1131 }
1132
1133 void VisitPointerType(const PointerType *T) {
1134 AddQualType(T->getPointeeType());
1135 VisitType(T);
1136 }
1137
1138 void VisitReferenceType(const ReferenceType *T) {
1139 AddQualType(T->getPointeeTypeAsWritten());
1140 VisitType(T);
1141 }
1142
1143 void VisitLValueReferenceType(const LValueReferenceType *T) {
1144 VisitReferenceType(T);
1145 }
1146
1147 void VisitRValueReferenceType(const RValueReferenceType *T) {
1148 VisitReferenceType(T);
1149 }
1150
1151 void
1152 VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T) {
1153 AddDecl(T->getAssociatedDecl());
1154 Hash.AddTemplateArgument(T->getArgumentPack());
1155 VisitType(T);
1156 }
1157
1158 void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
1159 AddDecl(T->getAssociatedDecl());
1160 AddQualType(T->getReplacementType());
1161 VisitType(T);
1162 }
1163
1164 void VisitTagType(const TagType *T) {
1165 AddDecl(T->getDecl());
1166 VisitType(T);
1167 }
1168
1169 void VisitRecordType(const RecordType *T) { VisitTagType(T); }
1170 void VisitEnumType(const EnumType *T) { VisitTagType(T); }
1171
1172 void VisitTemplateSpecializationType(const TemplateSpecializationType *T) {
1173 ID.AddInteger(T->template_arguments().size());
1174 for (const auto &TA : T->template_arguments()) {
1175 Hash.AddTemplateArgument(TA);
1176 }
1177 Hash.AddTemplateName(T->getTemplateName());
1178 VisitType(T);
1179 }
1180
1181 void VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
1182 ID.AddInteger(T->getDepth());
1183 ID.AddInteger(T->getIndex());
1184 Hash.AddBoolean(T->isParameterPack());
1185 AddDecl(T->getDecl());
1186 }
1187
1188 void VisitTypedefType(const TypedefType *T) {
1189 AddDecl(T->getDecl());
1190 VisitType(T);
1191 }
1192
1193 void VisitTypeOfExprType(const TypeOfExprType *T) {
1194 AddStmt(T->getUnderlyingExpr());
1195 Hash.AddBoolean(T->isSugared());
1196
1197 VisitType(T);
1198 }
1199 void VisitTypeOfType(const TypeOfType *T) {
1200 AddQualType(T->getUnmodifiedType());
1201 VisitType(T);
1202 }
1203
1204 void VisitTypeWithKeyword(const TypeWithKeyword *T) {
1205 ID.AddInteger(llvm::to_underlying(T->getKeyword()));
1206 VisitType(T);
1207 };
1208
1209 void VisitDependentNameType(const DependentNameType *T) {
1210 AddNestedNameSpecifier(T->getQualifier());
1211 AddIdentifierInfo(T->getIdentifier());
1212 VisitTypeWithKeyword(T);
1213 }
1214
1215 void VisitDependentTemplateSpecializationType(
1217 AddIdentifierInfo(T->getIdentifier());
1218 AddNestedNameSpecifier(T->getQualifier());
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 VisitElaboratedType(const ElaboratedType *T) {
1227 AddNestedNameSpecifier(T->getQualifier());
1228 AddQualType(T->getNamedType());
1229 VisitTypeWithKeyword(T);
1230 }
1231
1232 void VisitUnaryTransformType(const UnaryTransformType *T) {
1233 AddQualType(T->getUnderlyingType());
1234 AddQualType(T->getBaseType());
1235 VisitType(T);
1236 }
1237
1238 void VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
1239 AddDecl(T->getDecl());
1240 VisitType(T);
1241 }
1242
1243 void VisitVectorType(const VectorType *T) {
1244 AddQualType(T->getElementType());
1245 ID.AddInteger(T->getNumElements());
1246 ID.AddInteger(llvm::to_underlying(T->getVectorKind()));
1247 VisitType(T);
1248 }
1249
1250 void VisitExtVectorType(const ExtVectorType * T) {
1251 VisitVectorType(T);
1252 }
1253};
1254} // namespace
1255
1257 assert(T && "Expecting non-null pointer.");
1258 ODRTypeVisitor(ID, *this).Visit(T);
1259}
1260
1262 AddBoolean(T.isNull());
1263 if (T.isNull())
1264 return;
1265 SplitQualType split = T.split();
1266 ID.AddInteger(split.Quals.getAsOpaqueValue());
1267 AddType(split.Ty);
1268}
1269
1271 Bools.push_back(Value);
1272}
1273
1275 ID.AddInteger(Value.getKind());
1276
1277 // 'APValue::Profile' uses pointer values to make hash for LValue and
1278 // MemberPointer, but they differ from one compiler invocation to another.
1279 // So, handle them explicitly here.
1280
1281 switch (Value.getKind()) {
1282 case APValue::LValue: {
1283 const APValue::LValueBase &Base = Value.getLValueBase();
1284 if (!Base) {
1285 ID.AddInteger(Value.getLValueOffset().getQuantity());
1286 break;
1287 }
1288
1289 assert(Base.is<const ValueDecl *>());
1290 AddDecl(Base.get<const ValueDecl *>());
1291 ID.AddInteger(Value.getLValueOffset().getQuantity());
1292
1293 bool OnePastTheEnd = Value.isLValueOnePastTheEnd();
1294 if (Value.hasLValuePath()) {
1295 QualType TypeSoFar = Base.getType();
1296 for (APValue::LValuePathEntry E : Value.getLValuePath()) {
1297 if (const auto *AT = TypeSoFar->getAsArrayTypeUnsafe()) {
1298 if (const auto *CAT = dyn_cast<ConstantArrayType>(AT))
1299 OnePastTheEnd |= CAT->getSize() == E.getAsArrayIndex();
1300 TypeSoFar = AT->getElementType();
1301 } else {
1302 const Decl *D = E.getAsBaseOrMember().getPointer();
1303 if (const auto *FD = dyn_cast<FieldDecl>(D)) {
1304 if (FD->getParent()->isUnion())
1305 ID.AddInteger(FD->getFieldIndex());
1306 TypeSoFar = FD->getType();
1307 } else {
1308 TypeSoFar =
1309 D->getASTContext().getRecordType(cast<CXXRecordDecl>(D));
1310 }
1311 }
1312 }
1313 }
1314 unsigned Val = 0;
1315 if (Value.isNullPointer())
1316 Val |= 1 << 0;
1317 if (OnePastTheEnd)
1318 Val |= 1 << 1;
1319 if (Value.hasLValuePath())
1320 Val |= 1 << 2;
1321 ID.AddInteger(Val);
1322 break;
1323 }
1325 const ValueDecl *D = Value.getMemberPointerDecl();
1326 assert(D);
1327 AddDecl(D);
1328 ID.AddInteger(
1330 break;
1331 }
1332 default:
1333 Value.Profile(ID);
1334 }
1335}
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:208
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition: APValue.h:122
CharUnits getMemberPointerPathAdjustment(const APValue &MP) const
Find the 'this' offset for the member path in a pointer-to-member APValue.
QualType getRecordType(const RecordDecl *Decl) 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: Type.h:3320
Represents a constant array type that does not decay to a pointer when used as a function parameter.
Definition: Type.h:3710
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition: Type.h:3540
An attributed type is a type to which a type attribute has been applied.
Definition: Type.h:5991
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
Definition: Type.h:6368
Pointer to a block type.
Definition: Type.h:3371
This class is used for builtin types like 'int'.
Definition: Type.h:3000
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2060
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: Type.h:3108
A simple visitor class that helps create declaration visitors.
Definition: DeclVisitor.h:74
Represents the canonical version of C arrays with a specified constant size.
Definition: Type.h:3578
Represents a pointer type decayed from an array or function type.
Definition: Type.h:3354
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1425
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:2079
bool isFileContext() const
Definition: DeclBase.h:2150
DeclContext * getLexicalParent()
getLexicalParent - Returns the containing lexical DeclContext.
Definition: DeclBase.h:2095
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Definition: DeclBase.h:2339
Decl::Kind getDeclKind() const
Definition: DeclBase.h:2072
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:523
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition: DeclBase.h:599
bool isParameterPack() const
Whether this declaration is a parameter pack.
Definition: DeclBase.cpp:242
DeclContext * getDeclContext()
Definition: DeclBase.h:454
AccessSpecifier getAccess() const
Definition: DeclBase.h:513
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclBase.h:957
Kind getKind() const
Definition: DeclBase.h:448
The name of a declaration.
Represents the type decltype(expr) (C++11).
Definition: Type.h:5745
Represents a C++17 deduced template specialization type.
Definition: Type.h:6416
Common base class for placeholders for types that get replaced by placeholder type deduction: C++11 a...
Definition: Type.h:6334
Represents an extended address space qualifier where the input address space value is dependent.
Definition: Type.h:3881
Internal representation of canonical, dependent decltype(expr) types.
Definition: Type.h:5773
Represents a qualified type name for which the type name is dependent.
Definition: Type.h:6836
Represents an array type in C++ whose size is a value-dependent expression.
Definition: Type.h:3823
Represents an extended vector type where either the type or size is dependent.
Definition: Type.h:3921
Represents a template specialization type whose template cannot be resolved, e.g.
Definition: Type.h:6888
Represents a type that was referred to using an elaborated type keyword, e.g., struct S,...
Definition: Type.h:6755
An instance of this object exists for each enum constant that is defined.
Definition: Decl.h:3270
Represents an enum.
Definition: Decl.h:3840
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
Definition: Type.h:5962
ExtVectorType - Extended vector type.
Definition: Type.h:4083
Represents a member of a struct/union/class.
Definition: Decl.h:3030
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:1932
Represents a K&R-style 'int foo()' function, which has no information available about its arguments.
Definition: Type.h:4638
Represents a prototype with parameter type info, e.g.
Definition: Type.h:4973
unsigned getNumParams() const
Definition: Type.h:5226
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx)
Definition: Type.cpp:3815
ArrayRef< QualType > getParamTypes() const
Definition: Type.h:5233
bool isSugared() const
Definition: Type.h:5516
Declaration of a template function.
Definition: DeclTemplate.h:957
void Profile(llvm::FoldingSetNodeID &ID) const
Definition: Type.h:4508
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition: Type.h:4278
ExtInfo getExtInfo() const
Definition: Type.h:4612
bool isConst() const
Definition: Type.h:4618
bool isRestrict() const
Definition: Type.h:4620
QualType getReturnType() const
Definition: Type.h:4600
bool isVolatile() const
Definition: Type.h:4619
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: Type.h:3725
The injected class name of a C++ class template or class template partial specialization.
Definition: Type.h:6605
An lvalue reference type, per C++11 [dcl.ref].
Definition: Type.h:3446
A pointer to member type per C++ 8.3.3 - Pointers to members.
Definition: Type.h:3482
This represents a decl that may have a name.
Definition: Decl.h:249
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:315
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
SpecifierKind getKind() const
Determine what kind of nested name specifier is stored.
NamespaceAliasDecl * getAsNamespaceAlias() const
Retrieve the namespace alias stored in this nested name specifier.
IdentifierInfo * getAsIdentifier() const
Retrieve the identifier stored in this nested name specifier.
NestedNameSpecifier * getPrefix() const
Return the prefix of this nested name specifier.
@ NamespaceAlias
A namespace alias, stored as a NamespaceAliasDecl*.
@ TypeSpec
A type, stored as a Type*.
@ TypeSpecWithTemplate
A type that was preceded by the 'template' keyword, stored as a Type*.
@ Super
Microsoft's '__super' specifier, stored as a CXXRecordDecl* of the class it appeared in.
@ Identifier
An identifier, stored as an IdentifierInfo*.
@ Global
The global specifier '::'. There is no stored value.
@ Namespace
A namespace, stored as a NamespaceDecl*.
NamespaceDecl * getAsNamespace() const
Retrieve the namespace stored in this nested name specifier.
const Type * getAsType() const
Retrieve the type stored in this nested name specifier.
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
void AddDecl(const Decl *D)
Definition: ODRHash.cpp:806
void AddStmt(const Stmt *S)
Definition: ODRHash.cpp:24
void AddStructuralValue(const APValue &)
Definition: ODRHash.cpp:1274
void AddCXXRecordDecl(const CXXRecordDecl *Record)
Definition: ODRHash.cpp:568
void clear()
Definition: ODRHash.cpp:219
void AddIdentifierInfo(const IdentifierInfo *II)
Definition: ODRHash.cpp:29
void AddObjCProtocolDecl(const ObjCProtocolDecl *P)
Definition: ODRHash.cpp:781
void AddDeclarationName(DeclarationName Name, bool TreatAsDecl=false)
Definition: ODRHash.cpp:34
void AddObjCInterfaceDecl(const ObjCInterfaceDecl *Record)
Definition: ODRHash.cpp:633
void AddType(const Type *T)
Definition: ODRHash.cpp:1256
void AddEnumDecl(const EnumDecl *Enum)
Definition: ODRHash.cpp:753
void AddNestedNameSpecifier(const NestedNameSpecifier *NNS)
Definition: ODRHash.cpp:112
void AddFunctionDecl(const FunctionDecl *Function, bool SkipBody=false)
Definition: ODRHash.cpp:660
void AddBoolean(bool value)
Definition: ODRHash.cpp:1270
void AddTemplateName(TemplateName Name)
Definition: ODRHash.cpp:141
void AddRecordDecl(const RecordDecl *Record)
Definition: ODRHash.cpp:615
void AddSubDecl(const Decl *D)
Definition: ODRHash.cpp:562
void AddQualType(QualType T)
Definition: ODRHash.cpp:1261
void AddTemplateParameterList(const TemplateParameterList *TPL)
Definition: ODRHash.cpp:210
void AddTemplateArgument(TemplateArgument TA)
Definition: ODRHash.cpp:168
unsigned CalculateHash()
Definition: ODRHash.cpp:225
static bool isSubDeclToBeProcessed(const Decl *D, const DeclContext *Parent)
Definition: ODRHash.cpp:536
Represents an ObjC class declaration.
Definition: DeclObjC.h:1153
protocol_range protocols() const
Definition: DeclObjC.h:1358
const ObjCProtocolList & getReferencedProtocols() const
Definition: DeclObjC.h:1332
ObjCInterfaceDecl * getSuperClass() const
Definition: DeclObjC.cpp:352
Interfaces are the core concept in Objective-C for object oriented design.
Definition: Type.h:7336
ObjCIvarDecl - Represents an ObjC instance variable.
Definition: DeclObjC.h:1950
unsigned size() const
Definition: DeclObjC.h:70
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:140
ImplicitParamDecl * getSelfDecl() const
Definition: DeclObjC.h:418
bool hasBody() const override
Determine whether this method has a body.
Definition: DeclObjC.h:523
ArrayRef< ParmVarDecl * > parameters() const
Definition: DeclObjC.h:373
unsigned param_size() const
Definition: DeclObjC.h:347
bool isVariadic() const
Definition: DeclObjC.h:431
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
Definition: DeclObjC.cpp:909
TypeSourceInfo * getReturnTypeSourceInfo() const
Definition: DeclObjC.h:343
bool isSynthesizedAccessorStub() const
Definition: DeclObjC.h:444
bool isDirectMethod() const
True if the method is tagged as objc_direct.
Definition: DeclObjC.cpp:871
ImplicitParamDecl * getCmdDecl() const
Definition: DeclObjC.h:420
bool isInstanceMethod() const
Definition: DeclObjC.h:426
bool isThisDeclarationADefinition() const
Returns whether this specific method is a definition.
Definition: DeclObjC.h:534
bool isThisDeclarationADesignatedInitializer() const
Returns true if this specific method declaration is marked with the designated initializer attribute.
Definition: DeclObjC.cpp:876
bool isDefined() const
Definition: DeclObjC.h:452
ObjCMethodFamily getMethodFamily() const
Determines the family of this method.
Definition: DeclObjC.cpp:1053
ObjCImplementationControl getImplementationControl() const
Definition: DeclObjC.h:500
bool hasSkippedBody() const
True if the method was a definition but its body was skipped.
Definition: DeclObjC.h:477
Represents a pointer to an Objective C object.
Definition: Type.h:7392
Represents a class type in Objective C.
Definition: Type.h:7138
Represents one property declaration in an Objective-C interface.
Definition: DeclObjC.h:730
Represents an Objective-C protocol declaration.
Definition: DeclObjC.h:2082
Represents a type parameter type in Objective C.
Definition: Type.h:7064
Represents a pack expansion of types.
Definition: Type.h:6953
Sugar for parentheses used when specifying types.
Definition: Type.h:3135
Represents a parameter to a function.
Definition: Decl.h:1722
PipeType - OpenCL20.
Definition: Type.h:7592
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:3161
A (possibly-)qualified type.
Definition: Type.h:941
bool hasLocalQualifiers() const
Determine whether this particular QualType instance has any qualifiers, without looking through any t...
Definition: Type.h:1068
Represents a template name as written in source code.
Definition: TemplateName.h:434
TemplateName getUnderlyingTemplate() const
Return the underlying template name.
Definition: TemplateName.h:469
NestedNameSpecifier * getQualifier() const
Return the nested name specifier that qualifies this name.
Definition: TemplateName.h:462
bool hasTemplateKeyword() const
Whether the template name was prefixed by the "template" keyword.
Definition: TemplateName.h:466
The collection of all-type qualifiers we support.
Definition: Type.h:319
uint64_t getAsOpaqueValue() const
Definition: Type.h:442
An rvalue reference type, per C++11 [dcl.ref].
Definition: Type.h:3464
Represents a struct/union/class.
Definition: Decl.h:4141
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:5936
Declaration of a redeclarable template.
Definition: DeclTemplate.h:716
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:3402
Smart pointer class that efficiently represents Objective-C method names.
Represents a C++11 static_assert declaration.
Definition: DeclCXX.h:4058
Stmt - This represents one statement.
Definition: Stmt.h:84
StringLiteral - This represents a string literal expression, e.g.
Definition: Expr.h:1778
StringRef getBytes() const
Allow access to clients that need the byte representation, such as ASTWriterStmt::VisitStringLiteral(...
Definition: Expr.h:1863
Represents the result of substituting a set of types for a template type parameter pack.
Definition: Type.h:6276
Represents the result of substituting a type for a template type parameter.
Definition: Type.h:6206
A template argument list.
Definition: DeclTemplate.h:244
Represents a template argument.
Definition: TemplateBase.h:61
QualType getStructuralValueType() const
Get the type of a StructuralValue.
Definition: TemplateBase.h:399
Expr * getAsExpr() const
Retrieve the template argument as an expression.
Definition: TemplateBase.h:408
QualType getAsType() const
Retrieve the type for a type template argument.
Definition: TemplateBase.h:319
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
Definition: TemplateBase.h:363
unsigned pack_size() const
The number of template arguments in the given template argument pack.
Definition: TemplateBase.h:438
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
Definition: TemplateBase.h:326
ArrayRef< TemplateArgument > pack_elements() const
Iterator range referencing all of the elements of a template argument pack.
Definition: TemplateBase.h:432
@ 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:295
TemplateName getAsTemplateOrTemplatePattern() const
Retrieve the template argument as a template name; if the argument is a pack expansion,...
Definition: TemplateBase.h:350
const APValue & getAsStructuralValue() const
Get the value of a StructuralValue.
Definition: TemplateBase.h:396
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:394
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:413
Represents a C++ template name within the type system.
Definition: TemplateName.h:203
@ UsingTemplate
A template name that refers to a template declaration found through a specific using shadow declarati...
Definition: TemplateName.h:248
@ OverloadedTemplate
A set of overloaded template declarations.
Definition: TemplateName.h:223
@ Template
A single template declaration.
Definition: TemplateName.h:220
@ DependentTemplate
A dependent template name that has not been resolved to a template (or set of templates).
Definition: TemplateName.h:235
@ SubstTemplateTemplateParm
A template template parameter that has been substituted for some other template name.
Definition: TemplateName.h:239
@ SubstTemplateTemplateParmPack
A template template parameter pack that has been substituted for a template template argument pack,...
Definition: TemplateName.h:244
@ QualifiedTemplate
A qualified template name, where the qualification is kept to describe the source code as written.
Definition: TemplateName.h:231
@ AssumedTemplate
An unqualified-id that has been assumed to name a function template that will be found by ADL.
Definition: TemplateName.h:227
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:73
ArrayRef< NamedDecl * > asArray()
Definition: DeclTemplate.h:139
Represents a type template specialization; the template must be a class template, a type alias templa...
Definition: Type.h:6473
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:3528
Models the abbreviated syntax to constrain a template type parameter: template <convertible_to<string...
Definition: ASTConcept.h:228
Expr * getImmediatelyDeclaredConstraint() const
Get the immediately-declared constraint expression introduced by this type-constraint,...
Definition: ASTConcept.h:243
Represents a typeof (or typeof) expression (a C23 feature and GCC extension) or a typeof_unqual expre...
Definition: Type.h:5668
Represents typeof(type), a C23 feature and GCC extension, or `typeof_unqual(type),...
Definition: Type.h:5718
A container of type source information.
Definition: Type.h:7714
QualType getType() const
Return the type wrapped by this type source info.
Definition: Type.h:7725
An operation on a type.
Definition: TypeVisitor.h:64
A helper class for Type nodes having an ElaboratedTypeKeyword.
Definition: Type.h:6704
The base class of the type hierarchy.
Definition: Type.h:1829
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:705
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
Definition: Type.h:8569
TypeClass getTypeClass() const
Definition: Type.h:2316
Represents the declaration of a typedef-name via the 'typedef' type specifier.
Definition: Decl.h:3507
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3405
A unary type transform, which is a type constructed from another.
Definition: Type.h:5853
Represents the dependent type named by a dependently-scoped typename using declaration,...
Definition: Type.h:5538
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:667
Kind getKind() const
Definition: Value.h:136
Represents a variable declaration or definition.
Definition: Decl.h:879
Represents a C array with a specified size that is not an integer-constant-expression.
Definition: Type.h:3769
Represents a GCC generic vector type.
Definition: Type.h:3991
#define CHAR_BIT
Definition: limits.h:71
The JSON file list parser is used to communicate input to InstallAPI.
@ Specialization
We are substituting template parameters for template arguments in order to form a template specializa...
@ Result
The result type of a method or function.
const FunctionProtoType * T
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
A std::pair-like structure for storing a qualified type split into its local qualifiers and its local...
Definition: Type.h:874
const Type * Ty
The locally-unqualified type.
Definition: Type.h:876
Qualifiers Quals
The local qualifiers.
Definition: Type.h:879
#define remainder(__x, __y)
Definition: tgmath.h:1090