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