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 Hash.AddBoolean(D->isPackExpansion());
465 }
466
467 void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
468 // Only care about default arguments as part of the definition.
469 const bool hasDefaultArgument =
470 D->hasDefaultArgument() && !D->defaultArgumentWasInherited();
471 Hash.AddBoolean(hasDefaultArgument);
472 if (hasDefaultArgument) {
473 AddTemplateArgument(D->getDefaultArgument().getArgument());
474 }
476
477 const TypeConstraint *TC = D->getTypeConstraint();
478 Hash.AddBoolean(TC != nullptr);
479 if (TC)
481
482 Inherited::VisitTemplateTypeParmDecl(D);
483 }
484
485 void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
486 // Only care about default arguments as part of the definition.
487 const bool hasDefaultArgument =
488 D->hasDefaultArgument() && !D->defaultArgumentWasInherited();
489 Hash.AddBoolean(hasDefaultArgument);
490 if (hasDefaultArgument) {
491 AddTemplateArgument(D->getDefaultArgument().getArgument());
492 }
494
495 Inherited::VisitNonTypeTemplateParmDecl(D);
496 }
497
498 void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D) {
499 // Only care about default arguments as part of the definition.
500 const bool hasDefaultArgument =
501 D->hasDefaultArgument() && !D->defaultArgumentWasInherited();
502 Hash.AddBoolean(hasDefaultArgument);
503 if (hasDefaultArgument) {
504 AddTemplateArgument(D->getDefaultArgument().getArgument());
505 }
507
508 Inherited::VisitTemplateTemplateParmDecl(D);
509 }
510
511 void VisitTemplateDecl(const TemplateDecl *D) {
512 Hash.AddTemplateParameterList(D->getTemplateParameters());
513
514 Inherited::VisitTemplateDecl(D);
515 }
516
517 void VisitRedeclarableTemplateDecl(const RedeclarableTemplateDecl *D) {
518 Hash.AddBoolean(D->isMemberSpecialization());
519 Inherited::VisitRedeclarableTemplateDecl(D);
520 }
521
522 void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
523 AddDecl(D->getTemplatedDecl());
524 ID.AddInteger(D->getTemplatedDecl()->getODRHash());
525 Inherited::VisitFunctionTemplateDecl(D);
526 }
527
528 void VisitEnumConstantDecl(const EnumConstantDecl *D) {
529 AddStmt(D->getInitExpr());
530 Inherited::VisitEnumConstantDecl(D);
531 }
532};
533} // namespace
534
535// Only allow a small portion of Decl's to be processed. Remove this once
536// all Decl's can be handled.
538 if (D->isImplicit()) return false;
539 if (D->getDeclContext() != Parent) return false;
540
541 switch (D->getKind()) {
542 default:
543 return false;
544 case Decl::AccessSpec:
545 case Decl::CXXConstructor:
546 case Decl::CXXDestructor:
547 case Decl::CXXMethod:
548 case Decl::EnumConstant: // Only found in EnumDecl's.
549 case Decl::Field:
550 case Decl::Friend:
551 case Decl::FunctionTemplate:
552 case Decl::StaticAssert:
553 case Decl::TypeAlias:
554 case Decl::Typedef:
555 case Decl::Var:
556 case Decl::ObjCMethod:
557 case Decl::ObjCIvar:
558 case Decl::ObjCProperty:
559 return true;
560 }
561}
562
564 assert(D && "Expecting non-null pointer.");
565
566 ODRDeclVisitor(ID, *this).Visit(D);
567}
568
570 assert(Record && Record->hasDefinition() &&
571 "Expected non-null record to be a definition.");
572
573 const DeclContext *DC = Record;
574 while (DC) {
575 if (isa<ClassTemplateSpecializationDecl>(DC)) {
576 return;
577 }
578 DC = DC->getParent();
579 }
580
582
583 // Filter out sub-Decls which will not be processed in order to get an
584 // accurate count of Decl's.
586 for (Decl *SubDecl : Record->decls()) {
587 if (isSubDeclToBeProcessed(SubDecl, Record)) {
588 Decls.push_back(SubDecl);
589 if (auto *Function = dyn_cast<FunctionDecl>(SubDecl)) {
590 // Compute/Preload ODRHash into FunctionDecl.
591 Function->getODRHash();
592 }
593 }
594 }
595
596 ID.AddInteger(Decls.size());
597 for (auto SubDecl : Decls) {
598 AddSubDecl(SubDecl);
599 }
600
601 const ClassTemplateDecl *TD = Record->getDescribedClassTemplate();
602 AddBoolean(TD);
603 if (TD) {
605 }
606
607 ID.AddInteger(Record->getNumBases());
608 auto Bases = Record->bases();
609 for (const auto &Base : Bases) {
610 AddQualType(Base.getTypeSourceInfo()->getType());
611 ID.AddInteger(Base.isVirtual());
612 ID.AddInteger(Base.getAccessSpecifierAsWritten());
613 }
614}
615
617 assert(!isa<CXXRecordDecl>(Record) &&
618 "For CXXRecordDecl should call AddCXXRecordDecl.");
620
621 // Filter out sub-Decls which will not be processed in order to get an
622 // accurate count of Decl's.
624 for (Decl *SubDecl : Record->decls()) {
625 if (isSubDeclToBeProcessed(SubDecl, Record))
626 Decls.push_back(SubDecl);
627 }
628
629 ID.AddInteger(Decls.size());
630 for (const Decl *SubDecl : Decls)
631 AddSubDecl(SubDecl);
632}
633
635 AddDecl(IF);
636
637 auto *SuperClass = IF->getSuperClass();
638 AddBoolean(SuperClass);
639 if (SuperClass)
640 ID.AddInteger(SuperClass->getODRHash());
641
642 // Hash referenced protocols.
643 ID.AddInteger(IF->getReferencedProtocols().size());
644 for (const ObjCProtocolDecl *RefP : IF->protocols()) {
645 // Hash the name only as a referenced protocol can be a forward declaration.
646 AddDeclarationName(RefP->getDeclName());
647 }
648
649 // Filter out sub-Decls which will not be processed in order to get an
650 // accurate count of Decl's.
652 for (Decl *SubDecl : IF->decls())
653 if (isSubDeclToBeProcessed(SubDecl, IF))
654 Decls.push_back(SubDecl);
655
656 ID.AddInteger(Decls.size());
657 for (auto *SubDecl : Decls)
658 AddSubDecl(SubDecl);
659}
660
662 bool SkipBody) {
663 assert(Function && "Expecting non-null pointer.");
664
665 // Skip functions that are specializations or in specialization context.
666 const DeclContext *DC = Function;
667 while (DC) {
668 if (isa<ClassTemplateSpecializationDecl>(DC)) return;
669 if (auto *F = dyn_cast<FunctionDecl>(DC)) {
670 if (F->isFunctionTemplateSpecialization()) {
671 if (!isa<CXXMethodDecl>(DC)) return;
672 if (DC->getLexicalParent()->isFileContext()) return;
673 // Skip class scope explicit function template specializations,
674 // as they have not yet been instantiated.
675 if (F->getDependentSpecializationInfo())
676 return;
677 // Inline method specializations are the only supported
678 // specialization for now.
679 }
680 }
681 DC = DC->getParent();
682 }
683
684 ID.AddInteger(Function->getDeclKind());
685
686 const auto *SpecializationArgs = Function->getTemplateSpecializationArgs();
687 AddBoolean(SpecializationArgs);
688 if (SpecializationArgs) {
689 ID.AddInteger(SpecializationArgs->size());
690 for (const TemplateArgument &TA : SpecializationArgs->asArray()) {
692 }
693 }
694
695 if (const auto *Method = dyn_cast<CXXMethodDecl>(Function)) {
696 AddBoolean(Method->isConst());
697 AddBoolean(Method->isVolatile());
698 }
699
700 ID.AddInteger(Function->getStorageClass());
701 AddBoolean(Function->isInlineSpecified());
702 AddBoolean(Function->isVirtualAsWritten());
703 AddBoolean(Function->isPureVirtual());
704 AddBoolean(Function->isDeletedAsWritten());
705 AddBoolean(Function->isExplicitlyDefaulted());
706
707 StringLiteral *DeletedMessage = Function->getDeletedMessage();
708 AddBoolean(DeletedMessage);
709
710 if (DeletedMessage)
711 ID.AddString(DeletedMessage->getBytes());
712
714
715 AddQualType(Function->getReturnType());
716
717 ID.AddInteger(Function->param_size());
718 for (auto *Param : Function->parameters())
719 AddSubDecl(Param);
720
721 if (SkipBody) {
722 AddBoolean(false);
723 return;
724 }
725
726 const bool HasBody = Function->isThisDeclarationADefinition() &&
727 !Function->isDefaulted() && !Function->isDeleted() &&
728 !Function->isLateTemplateParsed();
729 AddBoolean(HasBody);
730 if (!HasBody) {
731 return;
732 }
733
734 auto *Body = Function->getBody();
735 AddBoolean(Body);
736 if (Body)
737 AddStmt(Body);
738
739 // Filter out sub-Decls which will not be processed in order to get an
740 // accurate count of Decl's.
742 for (Decl *SubDecl : Function->decls()) {
743 if (isSubDeclToBeProcessed(SubDecl, Function)) {
744 Decls.push_back(SubDecl);
745 }
746 }
747
748 ID.AddInteger(Decls.size());
749 for (auto SubDecl : Decls) {
750 AddSubDecl(SubDecl);
751 }
752}
753
755 assert(Enum);
756 AddDeclarationName(Enum->getDeclName());
757
758 AddBoolean(Enum->isScoped());
759 if (Enum->isScoped())
760 AddBoolean(Enum->isScopedUsingClassTag());
761
762 if (Enum->getIntegerTypeSourceInfo())
763 AddQualType(Enum->getIntegerType().getCanonicalType());
764
765 // Filter out sub-Decls which will not be processed in order to get an
766 // accurate count of Decl's.
768 for (Decl *SubDecl : Enum->decls()) {
769 if (isSubDeclToBeProcessed(SubDecl, Enum)) {
770 assert(isa<EnumConstantDecl>(SubDecl) && "Unexpected Decl");
771 Decls.push_back(SubDecl);
772 }
773 }
774
775 ID.AddInteger(Decls.size());
776 for (auto SubDecl : Decls) {
777 AddSubDecl(SubDecl);
778 }
779
780}
781
783 AddDecl(P);
784
785 // Hash referenced protocols.
786 ID.AddInteger(P->getReferencedProtocols().size());
787 for (const ObjCProtocolDecl *RefP : P->protocols()) {
788 // Hash the name only as a referenced protocol can be a forward declaration.
789 AddDeclarationName(RefP->getDeclName());
790 }
791
792 // Filter out sub-Decls which will not be processed in order to get an
793 // accurate count of Decl's.
795 for (Decl *SubDecl : P->decls()) {
796 if (isSubDeclToBeProcessed(SubDecl, P)) {
797 Decls.push_back(SubDecl);
798 }
799 }
800
801 ID.AddInteger(Decls.size());
802 for (auto *SubDecl : Decls) {
803 AddSubDecl(SubDecl);
804 }
805}
806
807void ODRHash::AddDecl(const Decl *D) {
808 assert(D && "Expecting non-null pointer.");
809 D = D->getCanonicalDecl();
810
811 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
812 AddBoolean(ND);
813 if (!ND) {
814 ID.AddInteger(D->getKind());
815 return;
816 }
817
819
820 const auto *Specialization =
821 dyn_cast<ClassTemplateSpecializationDecl>(D);
823 if (Specialization) {
824 const TemplateArgumentList &List = Specialization->getTemplateArgs();
825 ID.AddInteger(List.size());
826 for (const TemplateArgument &TA : List.asArray())
828 }
829}
830
831namespace {
832// Process a Type pointer. Add* methods call back into ODRHash while Visit*
833// methods process the relevant parts of the Type.
834class ODRTypeVisitor : public TypeVisitor<ODRTypeVisitor> {
835 typedef TypeVisitor<ODRTypeVisitor> Inherited;
836 llvm::FoldingSetNodeID &ID;
837 ODRHash &Hash;
838
839public:
840 ODRTypeVisitor(llvm::FoldingSetNodeID &ID, ODRHash &Hash)
841 : ID(ID), Hash(Hash) {}
842
843 void AddStmt(Stmt *S) {
844 Hash.AddBoolean(S);
845 if (S) {
846 Hash.AddStmt(S);
847 }
848 }
849
850 void AddDecl(const Decl *D) {
851 Hash.AddBoolean(D);
852 if (D) {
853 Hash.AddDecl(D);
854 }
855 }
856
857 void AddQualType(QualType T) {
858 Hash.AddQualType(T);
859 }
860
861 void AddType(const Type *T) {
862 Hash.AddBoolean(T);
863 if (T) {
864 Hash.AddType(T);
865 }
866 }
867
868 void AddNestedNameSpecifier(const NestedNameSpecifier *NNS) {
869 Hash.AddBoolean(NNS);
870 if (NNS) {
871 Hash.AddNestedNameSpecifier(NNS);
872 }
873 }
874
875 void AddIdentifierInfo(const IdentifierInfo *II) {
876 Hash.AddBoolean(II);
877 if (II) {
878 Hash.AddIdentifierInfo(II);
879 }
880 }
881
882 void VisitQualifiers(Qualifiers Quals) {
883 ID.AddInteger(Quals.getAsOpaqueValue());
884 }
885
886 // Return the RecordType if the typedef only strips away a keyword.
887 // Otherwise, return the original type.
888 static const Type *RemoveTypedef(const Type *T) {
889 const auto *TypedefT = dyn_cast<TypedefType>(T);
890 if (!TypedefT) {
891 return T;
892 }
893
894 const TypedefNameDecl *D = TypedefT->getDecl();
895 QualType UnderlyingType = D->getUnderlyingType();
896
897 if (UnderlyingType.hasLocalQualifiers()) {
898 return T;
899 }
900
901 const auto *ElaboratedT = dyn_cast<ElaboratedType>(UnderlyingType);
902 if (!ElaboratedT) {
903 return T;
904 }
905
906 if (ElaboratedT->getQualifier() != nullptr) {
907 return T;
908 }
909
910 QualType NamedType = ElaboratedT->getNamedType();
911 if (NamedType.hasLocalQualifiers()) {
912 return T;
913 }
914
915 const auto *RecordT = dyn_cast<RecordType>(NamedType);
916 if (!RecordT) {
917 return T;
918 }
919
920 const IdentifierInfo *TypedefII = TypedefT->getDecl()->getIdentifier();
921 const IdentifierInfo *RecordII = RecordT->getDecl()->getIdentifier();
922 if (!TypedefII || !RecordII ||
923 TypedefII->getName() != RecordII->getName()) {
924 return T;
925 }
926
927 return RecordT;
928 }
929
930 void Visit(const Type *T) {
931 T = RemoveTypedef(T);
932 ID.AddInteger(T->getTypeClass());
933 Inherited::Visit(T);
934 }
935
936 void VisitType(const Type *T) {}
937
938 void VisitAdjustedType(const AdjustedType *T) {
939 AddQualType(T->getOriginalType());
940
941 VisitType(T);
942 }
943
944 void VisitDecayedType(const DecayedType *T) {
945 // getDecayedType and getPointeeType are derived from getAdjustedType
946 // and don't need to be separately processed.
947 VisitAdjustedType(T);
948 }
949
950 void VisitArrayType(const ArrayType *T) {
951 AddQualType(T->getElementType());
952 ID.AddInteger(llvm::to_underlying(T->getSizeModifier()));
953 VisitQualifiers(T->getIndexTypeQualifiers());
954 VisitType(T);
955 }
956 void VisitConstantArrayType(const ConstantArrayType *T) {
957 T->getSize().Profile(ID);
958 VisitArrayType(T);
959 }
960
961 void VisitArrayParameterType(const ArrayParameterType *T) {
962 VisitConstantArrayType(T);
963 }
964
965 void VisitDependentSizedArrayType(const DependentSizedArrayType *T) {
966 AddStmt(T->getSizeExpr());
967 VisitArrayType(T);
968 }
969
970 void VisitIncompleteArrayType(const IncompleteArrayType *T) {
971 VisitArrayType(T);
972 }
973
974 void VisitVariableArrayType(const VariableArrayType *T) {
975 AddStmt(T->getSizeExpr());
976 VisitArrayType(T);
977 }
978
979 void VisitAttributedType(const AttributedType *T) {
980 ID.AddInteger(T->getAttrKind());
981 AddQualType(T->getModifiedType());
982
983 VisitType(T);
984 }
985
986 void VisitBlockPointerType(const BlockPointerType *T) {
987 AddQualType(T->getPointeeType());
988 VisitType(T);
989 }
990
991 void VisitBuiltinType(const BuiltinType *T) {
992 ID.AddInteger(T->getKind());
993 VisitType(T);
994 }
995
996 void VisitComplexType(const ComplexType *T) {
997 AddQualType(T->getElementType());
998 VisitType(T);
999 }
1000
1001 void VisitDecltypeType(const DecltypeType *T) {
1002 AddStmt(T->getUnderlyingExpr());
1003 VisitType(T);
1004 }
1005
1006 void VisitDependentDecltypeType(const DependentDecltypeType *T) {
1007 VisitDecltypeType(T);
1008 }
1009
1010 void VisitDeducedType(const DeducedType *T) {
1011 AddQualType(T->getDeducedType());
1012 VisitType(T);
1013 }
1014
1015 void VisitAutoType(const AutoType *T) {
1016 ID.AddInteger((unsigned)T->getKeyword());
1017 ID.AddInteger(T->isConstrained());
1018 if (T->isConstrained()) {
1019 AddDecl(T->getTypeConstraintConcept());
1020 ID.AddInteger(T->getTypeConstraintArguments().size());
1021 for (const auto &TA : T->getTypeConstraintArguments())
1022 Hash.AddTemplateArgument(TA);
1023 }
1024 VisitDeducedType(T);
1025 }
1026
1027 void VisitDeducedTemplateSpecializationType(
1029 Hash.AddTemplateName(T->getTemplateName());
1030 VisitDeducedType(T);
1031 }
1032
1033 void VisitDependentAddressSpaceType(const DependentAddressSpaceType *T) {
1034 AddQualType(T->getPointeeType());
1035 AddStmt(T->getAddrSpaceExpr());
1036 VisitType(T);
1037 }
1038
1039 void VisitDependentSizedExtVectorType(const DependentSizedExtVectorType *T) {
1040 AddQualType(T->getElementType());
1041 AddStmt(T->getSizeExpr());
1042 VisitType(T);
1043 }
1044
1045 void VisitFunctionType(const FunctionType *T) {
1046 AddQualType(T->getReturnType());
1047 T->getExtInfo().Profile(ID);
1048 Hash.AddBoolean(T->isConst());
1049 Hash.AddBoolean(T->isVolatile());
1050 Hash.AddBoolean(T->isRestrict());
1051 VisitType(T);
1052 }
1053
1054 void VisitFunctionNoProtoType(const FunctionNoProtoType *T) {
1055 VisitFunctionType(T);
1056 }
1057
1058 void VisitFunctionProtoType(const FunctionProtoType *T) {
1059 ID.AddInteger(T->getNumParams());
1060 for (auto ParamType : T->getParamTypes())
1061 AddQualType(ParamType);
1062
1063 VisitFunctionType(T);
1064 }
1065
1066 void VisitInjectedClassNameType(const InjectedClassNameType *T) {
1067 AddDecl(T->getDecl());
1068 VisitType(T);
1069 }
1070
1071 void VisitMemberPointerType(const MemberPointerType *T) {
1072 AddQualType(T->getPointeeType());
1073 AddType(T->getClass());
1074 VisitType(T);
1075 }
1076
1077 void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
1078 AddQualType(T->getPointeeType());
1079 VisitType(T);
1080 }
1081
1082 void VisitObjCObjectType(const ObjCObjectType *T) {
1083 AddDecl(T->getInterface());
1084
1085 auto TypeArgs = T->getTypeArgsAsWritten();
1086 ID.AddInteger(TypeArgs.size());
1087 for (auto Arg : TypeArgs) {
1088 AddQualType(Arg);
1089 }
1090
1091 auto Protocols = T->getProtocols();
1092 ID.AddInteger(Protocols.size());
1093 for (auto *Protocol : Protocols) {
1094 AddDecl(Protocol);
1095 }
1096
1097 Hash.AddBoolean(T->isKindOfType());
1098
1099 VisitType(T);
1100 }
1101
1102 void VisitObjCInterfaceType(const ObjCInterfaceType *T) {
1103 // This type is handled by the parent type ObjCObjectType.
1104 VisitObjCObjectType(T);
1105 }
1106
1107 void VisitObjCTypeParamType(const ObjCTypeParamType *T) {
1108 AddDecl(T->getDecl());
1109 auto Protocols = T->getProtocols();
1110 ID.AddInteger(Protocols.size());
1111 for (auto *Protocol : Protocols) {
1112 AddDecl(Protocol);
1113 }
1114
1115 VisitType(T);
1116 }
1117
1118 void VisitPackExpansionType(const PackExpansionType *T) {
1119 AddQualType(T->getPattern());
1120 VisitType(T);
1121 }
1122
1123 void VisitParenType(const ParenType *T) {
1124 AddQualType(T->getInnerType());
1125 VisitType(T);
1126 }
1127
1128 void VisitPipeType(const PipeType *T) {
1129 AddQualType(T->getElementType());
1130 Hash.AddBoolean(T->isReadOnly());
1131 VisitType(T);
1132 }
1133
1134 void VisitPointerType(const PointerType *T) {
1135 AddQualType(T->getPointeeType());
1136 VisitType(T);
1137 }
1138
1139 void VisitReferenceType(const ReferenceType *T) {
1140 AddQualType(T->getPointeeTypeAsWritten());
1141 VisitType(T);
1142 }
1143
1144 void VisitLValueReferenceType(const LValueReferenceType *T) {
1145 VisitReferenceType(T);
1146 }
1147
1148 void VisitRValueReferenceType(const RValueReferenceType *T) {
1149 VisitReferenceType(T);
1150 }
1151
1152 void
1153 VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T) {
1154 AddDecl(T->getAssociatedDecl());
1155 Hash.AddTemplateArgument(T->getArgumentPack());
1156 VisitType(T);
1157 }
1158
1159 void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
1160 AddDecl(T->getAssociatedDecl());
1161 AddQualType(T->getReplacementType());
1162 VisitType(T);
1163 }
1164
1165 void VisitTagType(const TagType *T) {
1166 AddDecl(T->getDecl());
1167 VisitType(T);
1168 }
1169
1170 void VisitRecordType(const RecordType *T) { VisitTagType(T); }
1171 void VisitEnumType(const EnumType *T) { VisitTagType(T); }
1172
1173 void VisitTemplateSpecializationType(const TemplateSpecializationType *T) {
1174 ID.AddInteger(T->template_arguments().size());
1175 for (const auto &TA : T->template_arguments()) {
1176 Hash.AddTemplateArgument(TA);
1177 }
1178 Hash.AddTemplateName(T->getTemplateName());
1179 VisitType(T);
1180 }
1181
1182 void VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
1183 ID.AddInteger(T->getDepth());
1184 ID.AddInteger(T->getIndex());
1185 Hash.AddBoolean(T->isParameterPack());
1186 AddDecl(T->getDecl());
1187 }
1188
1189 void VisitTypedefType(const TypedefType *T) {
1190 AddDecl(T->getDecl());
1191 VisitType(T);
1192 }
1193
1194 void VisitTypeOfExprType(const TypeOfExprType *T) {
1195 AddStmt(T->getUnderlyingExpr());
1196 Hash.AddBoolean(T->isSugared());
1197
1198 VisitType(T);
1199 }
1200 void VisitTypeOfType(const TypeOfType *T) {
1201 AddQualType(T->getUnmodifiedType());
1202 VisitType(T);
1203 }
1204
1205 void VisitTypeWithKeyword(const TypeWithKeyword *T) {
1206 ID.AddInteger(llvm::to_underlying(T->getKeyword()));
1207 VisitType(T);
1208 };
1209
1210 void VisitDependentNameType(const DependentNameType *T) {
1211 AddNestedNameSpecifier(T->getQualifier());
1212 AddIdentifierInfo(T->getIdentifier());
1213 VisitTypeWithKeyword(T);
1214 }
1215
1216 void VisitDependentTemplateSpecializationType(
1218 AddIdentifierInfo(T->getIdentifier());
1219 AddNestedNameSpecifier(T->getQualifier());
1220 ID.AddInteger(T->template_arguments().size());
1221 for (const auto &TA : T->template_arguments()) {
1222 Hash.AddTemplateArgument(TA);
1223 }
1224 VisitTypeWithKeyword(T);
1225 }
1226
1227 void VisitElaboratedType(const ElaboratedType *T) {
1228 AddNestedNameSpecifier(T->getQualifier());
1229 AddQualType(T->getNamedType());
1230 VisitTypeWithKeyword(T);
1231 }
1232
1233 void VisitUnaryTransformType(const UnaryTransformType *T) {
1234 AddQualType(T->getUnderlyingType());
1235 AddQualType(T->getBaseType());
1236 VisitType(T);
1237 }
1238
1239 void VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
1240 AddDecl(T->getDecl());
1241 VisitType(T);
1242 }
1243
1244 void VisitVectorType(const VectorType *T) {
1245 AddQualType(T->getElementType());
1246 ID.AddInteger(T->getNumElements());
1247 ID.AddInteger(llvm::to_underlying(T->getVectorKind()));
1248 VisitType(T);
1249 }
1250
1251 void VisitExtVectorType(const ExtVectorType * T) {
1252 VisitVectorType(T);
1253 }
1254};
1255} // namespace
1256
1258 assert(T && "Expecting non-null pointer.");
1259 ODRTypeVisitor(ID, *this).Visit(T);
1260}
1261
1263 AddBoolean(T.isNull());
1264 if (T.isNull())
1265 return;
1266 SplitQualType split = T.split();
1267 ID.AddInteger(split.Quals.getAsOpaqueValue());
1268 AddType(split.Ty);
1269}
1270
1272 Bools.push_back(Value);
1273}
1274
1276 ID.AddInteger(Value.getKind());
1277
1278 // 'APValue::Profile' uses pointer values to make hash for LValue and
1279 // MemberPointer, but they differ from one compiler invocation to another.
1280 // So, handle them explicitly here.
1281
1282 switch (Value.getKind()) {
1283 case APValue::LValue: {
1284 const APValue::LValueBase &Base = Value.getLValueBase();
1285 if (!Base) {
1286 ID.AddInteger(Value.getLValueOffset().getQuantity());
1287 break;
1288 }
1289
1290 assert(Base.is<const ValueDecl *>());
1291 AddDecl(Base.get<const ValueDecl *>());
1292 ID.AddInteger(Value.getLValueOffset().getQuantity());
1293
1294 bool OnePastTheEnd = Value.isLValueOnePastTheEnd();
1295 if (Value.hasLValuePath()) {
1296 QualType TypeSoFar = Base.getType();
1297 for (APValue::LValuePathEntry E : Value.getLValuePath()) {
1298 if (const auto *AT = TypeSoFar->getAsArrayTypeUnsafe()) {
1299 if (const auto *CAT = dyn_cast<ConstantArrayType>(AT))
1300 OnePastTheEnd |= CAT->getSize() == E.getAsArrayIndex();
1301 TypeSoFar = AT->getElementType();
1302 } else {
1303 const Decl *D = E.getAsBaseOrMember().getPointer();
1304 if (const auto *FD = dyn_cast<FieldDecl>(D)) {
1305 if (FD->getParent()->isUnion())
1306 ID.AddInteger(FD->getFieldIndex());
1307 TypeSoFar = FD->getType();
1308 } else {
1309 TypeSoFar =
1310 D->getASTContext().getRecordType(cast<CXXRecordDecl>(D));
1311 }
1312 }
1313 }
1314 }
1315 unsigned Val = 0;
1316 if (Value.isNullPointer())
1317 Val |= 1 << 0;
1318 if (OnePastTheEnd)
1319 Val |= 1 << 1;
1320 if (Value.hasLValuePath())
1321 Val |= 1 << 2;
1322 ID.AddInteger(Val);
1323 break;
1324 }
1326 const ValueDecl *D = Value.getMemberPointerDecl();
1327 assert(D);
1328 AddDecl(D);
1329 ID.AddInteger(
1331 break;
1332 }
1333 default:
1334 Value.Profile(ID);
1335 }
1336}
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:3346
Represents a constant array type that does not decay to a pointer when used as a function parameter.
Definition: Type.h:3736
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition: Type.h:3566
An attributed type is a type to which a type attribute has been applied.
Definition: Type.h:6020
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
Definition: Type.h:6375
Pointer to a block type.
Definition: Type.h:3397
This class is used for builtin types like 'int'.
Definition: Type.h:3023
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2064
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:3134
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:3604
Represents a pointer type decayed from an array or function type.
Definition: Type.h:3380
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1436
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:2090
bool isFileContext() const
Definition: DeclBase.h:2161
DeclContext * getLexicalParent()
getLexicalParent - Returns the containing lexical DeclContext.
Definition: DeclBase.h:2106
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Definition: DeclBase.h:2350
Decl::Kind getDeclKind() const
Definition: DeclBase.h:2083
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:600
bool isParameterPack() const
Whether this declaration is a parameter pack.
Definition: DeclBase.cpp:242
DeclContext * getDeclContext()
Definition: DeclBase.h:455
AccessSpecifier getAccess() const
Definition: DeclBase.h:514
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclBase.h:968
Kind getKind() const
Definition: DeclBase.h:449
The name of a declaration.
Represents the type decltype(expr) (C++11).
Definition: Type.h:5774
Represents a C++17 deduced template specialization type.
Definition: Type.h:6423
Common base class for placeholders for types that get replaced by placeholder type deduction: C++11 a...
Definition: Type.h:6341
Represents an extended address space qualifier where the input address space value is dependent.
Definition: Type.h:3907
Internal representation of canonical, dependent decltype(expr) types.
Definition: Type.h:5802
Represents a qualified type name for which the type name is dependent.
Definition: Type.h:6843
Represents an array type in C++ whose size is a value-dependent expression.
Definition: Type.h:3849
Represents an extended vector type where either the type or size is dependent.
Definition: Type.h:3947
Represents a template specialization type whose template cannot be resolved, e.g.
Definition: Type.h:6895
Represents a type that was referred to using an elaborated type keyword, e.g., struct S,...
Definition: Type.h:6762
An instance of this object exists for each enum constant that is defined.
Definition: Decl.h:3274
Represents an enum.
Definition: Decl.h:3844
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
Definition: Type.h:5991
ExtVectorType - Extended vector type.
Definition: Type.h:4113
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:4668
Represents a prototype with parameter type info, e.g.
Definition: Type.h:5002
unsigned getNumParams() const
Definition: Type.h:5255
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx)
Definition: Type.cpp:3822
ArrayRef< QualType > getParamTypes() const
Definition: Type.h:5262
bool isSugared() const
Definition: Type.h:5545
Declaration of a template function.
Definition: DeclTemplate.h:957
void Profile(llvm::FoldingSetNodeID &ID) const
Definition: Type.h:4538
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition: Type.h:4308
ExtInfo getExtInfo() const
Definition: Type.h:4642
bool isConst() const
Definition: Type.h:4648
bool isRestrict() const
Definition: Type.h:4650
QualType getReturnType() const
Definition: Type.h:4630
bool isVolatile() const
Definition: Type.h:4649
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:3751
The injected class name of a C++ class template or class template partial specialization.
Definition: Type.h:6612
An lvalue reference type, per C++11 [dcl.ref].
Definition: Type.h:3472
A pointer to member type per C++ 8.3.3 - Pointers to members.
Definition: Type.h:3508
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:807
void AddStmt(const Stmt *S)
Definition: ODRHash.cpp:24
void AddStructuralValue(const APValue &)
Definition: ODRHash.cpp:1275
void AddCXXRecordDecl(const CXXRecordDecl *Record)
Definition: ODRHash.cpp:569
void clear()
Definition: ODRHash.cpp:219
void AddIdentifierInfo(const IdentifierInfo *II)
Definition: ODRHash.cpp:29
void AddObjCProtocolDecl(const ObjCProtocolDecl *P)
Definition: ODRHash.cpp:782
void AddDeclarationName(DeclarationName Name, bool TreatAsDecl=false)
Definition: ODRHash.cpp:34
void AddObjCInterfaceDecl(const ObjCInterfaceDecl *Record)
Definition: ODRHash.cpp:634
void AddType(const Type *T)
Definition: ODRHash.cpp:1257
void AddEnumDecl(const EnumDecl *Enum)
Definition: ODRHash.cpp:754
void AddNestedNameSpecifier(const NestedNameSpecifier *NNS)
Definition: ODRHash.cpp:112
void AddFunctionDecl(const FunctionDecl *Function, bool SkipBody=false)
Definition: ODRHash.cpp:661
void AddBoolean(bool value)
Definition: ODRHash.cpp:1271
void AddTemplateName(TemplateName Name)
Definition: ODRHash.cpp:141
void AddRecordDecl(const RecordDecl *Record)
Definition: ODRHash.cpp:616
void AddSubDecl(const Decl *D)
Definition: ODRHash.cpp:563
void AddQualType(QualType T)
Definition: ODRHash.cpp:1262
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:537
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:7343
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: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:7399
Represents a class type in Objective C.
Definition: Type.h:7145
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:7071
Represents a pack expansion of types.
Definition: Type.h:6960
Sugar for parentheses used when specifying types.
Definition: Type.h:3161
Represents a parameter to a function.
Definition: Decl.h:1722
PipeType - OpenCL20.
Definition: Type.h:7599
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:3187
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:3490
Represents a struct/union/class.
Definition: Decl.h:4145
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:5965
Declaration of a redeclarable template.
Definition: DeclTemplate.h:716
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:3428
Smart pointer class that efficiently represents Objective-C method names.
Represents a C++11 static_assert declaration.
Definition: DeclCXX.h:4062
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:6283
Represents the result of substituting a type for a template type parameter.
Definition: Type.h:6213
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:6480
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:3532
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:5697
Represents typeof(type), a C23 feature and GCC extension, or `typeof_unqual(type),...
Definition: Type.h:5747
A container of type source information.
Definition: Type.h:7721
QualType getType() const
Return the type wrapped by this type source info.
Definition: Type.h:7732
An operation on a type.
Definition: TypeVisitor.h:64
A helper class for Type nodes having an ElaboratedTypeKeyword.
Definition: Type.h:6711
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:8593
TypeClass getTypeClass() const
Definition: Type.h:2334
Represents the declaration of a typedef-name via the 'typedef' type specifier.
Definition: Decl.h:3511
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3409
A unary type transform, which is a type constructed from another.
Definition: Type.h:5882
Represents the dependent type named by a dependently-scoped typename using declaration,...
Definition: Type.h:5567
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:3795
Represents a GCC generic vector type.
Definition: Type.h:4021
#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