1 //===-- ODRHash.cpp - Hashing to diagnose ODR failures ----------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// This file implements the ODRHash class, which calculates a hash based
12 /// on AST nodes, which is stable across different runs.
13 ///
14 //===----------------------------------------------------------------------===//
15 
16 #include "clang/AST/ODRHash.h"
17 
18 #include "clang/AST/DeclVisitor.h"
19 #include "clang/AST/NestedNameSpecifier.h"
20 #include "clang/AST/StmtVisitor.h"
21 #include "clang/AST/TypeVisitor.h"
22 
23 using namespace clang;
24 
25 void ODRHash::AddStmt(const Stmt *S) {
26   assert(S && "Expecting non-null pointer.");
27   S->ProcessODRHash(ID, *this);
28 }
29 
30 void ODRHash::AddIdentifierInfo(const IdentifierInfo *II) {
31   assert(II && "Expecting non-null pointer.");
32   ID.AddString(II->getName());
33 }
34 
35 void ODRHash::AddDeclarationName(DeclarationName Name) {
36   // Index all DeclarationName and use index numbers to refer to them.
37   auto Result = DeclNameMap.insert(std::make_pair(Name, DeclNameMap.size()));
38   ID.AddInteger(Result.first->second);
39   if (!Result.second) {
40     // If found in map, the the DeclarationName has previously been processed.
41     return;
42   }
43 
44   // First time processing each DeclarationName, also process its details.
45   AddBoolean(Name.isEmpty());
46   if (Name.isEmpty())
47     return;
48 
49   auto Kind = Name.getNameKind();
50   ID.AddInteger(Kind);
51   switch (Kind) {
52   case DeclarationName::Identifier:
53     AddIdentifierInfo(Name.getAsIdentifierInfo());
54     break;
55   case DeclarationName::ObjCZeroArgSelector:
56   case DeclarationName::ObjCOneArgSelector:
57   case DeclarationName::ObjCMultiArgSelector: {
58     Selector S = Name.getObjCSelector();
59     AddBoolean(S.isNull());
60     AddBoolean(S.isKeywordSelector());
61     AddBoolean(S.isUnarySelector());
62     unsigned NumArgs = S.getNumArgs();
63     for (unsigned i = 0; i < NumArgs; ++i) {
64       AddIdentifierInfo(S.getIdentifierInfoForSlot(i));
65     }
66     break;
67   }
68   case DeclarationName::CXXConstructorName:
69   case DeclarationName::CXXDestructorName:
70     AddQualType(Name.getCXXNameType());
71     break;
72   case DeclarationName::CXXOperatorName:
73     ID.AddInteger(Name.getCXXOverloadedOperator());
74     break;
75   case DeclarationName::CXXLiteralOperatorName:
76     AddIdentifierInfo(Name.getCXXLiteralIdentifier());
77     break;
78   case DeclarationName::CXXConversionFunctionName:
79     AddQualType(Name.getCXXNameType());
80     break;
81   case DeclarationName::CXXUsingDirective:
82     break;
83   case DeclarationName::CXXDeductionGuideName: {
84     auto *Template = Name.getCXXDeductionGuideTemplate();
85     AddBoolean(Template);
86     if (Template) {
87       AddDecl(Template);
88     }
89   }
90   }
91 }
92 
93 void ODRHash::AddNestedNameSpecifier(const NestedNameSpecifier *NNS) {
94   assert(NNS && "Expecting non-null pointer.");
95   const auto *Prefix = NNS->getPrefix();
96   AddBoolean(Prefix);
97   if (Prefix) {
98     AddNestedNameSpecifier(Prefix);
99   }
100   auto Kind = NNS->getKind();
101   ID.AddInteger(Kind);
102   switch (Kind) {
103   case NestedNameSpecifier::Identifier:
104     AddIdentifierInfo(NNS->getAsIdentifier());
105     break;
106   case NestedNameSpecifier::Namespace:
107     AddDecl(NNS->getAsNamespace());
108     break;
109   case NestedNameSpecifier::NamespaceAlias:
110     AddDecl(NNS->getAsNamespaceAlias());
111     break;
112   case NestedNameSpecifier::TypeSpec:
113   case NestedNameSpecifier::TypeSpecWithTemplate:
114     AddType(NNS->getAsType());
115     break;
116   case NestedNameSpecifier::Global:
117   case NestedNameSpecifier::Super:
118     break;
119   }
120 }
121 
122 void ODRHash::AddTemplateName(TemplateName Name) {
123   auto Kind = Name.getKind();
124   ID.AddInteger(Kind);
125 
126   switch (Kind) {
127   case TemplateName::Template:
128     AddDecl(Name.getAsTemplateDecl());
129     break;
130   // TODO: Support these cases.
131   case TemplateName::OverloadedTemplate:
132   case TemplateName::QualifiedTemplate:
133   case TemplateName::DependentTemplate:
134   case TemplateName::SubstTemplateTemplateParm:
135   case TemplateName::SubstTemplateTemplateParmPack:
136     break;
137   }
138 }
139 
140 void ODRHash::AddTemplateArgument(TemplateArgument TA) {
141   const auto Kind = TA.getKind();
142   ID.AddInteger(Kind);
143 
144   switch (Kind) {
145     case TemplateArgument::Null:
146       llvm_unreachable("Expected valid TemplateArgument");
147     case TemplateArgument::Type:
148       AddQualType(TA.getAsType());
149       break;
150     case TemplateArgument::Declaration:
151       AddDecl(TA.getAsDecl());
152       break;
153     case TemplateArgument::NullPtr:
154     case TemplateArgument::Integral:
155       break;
156     case TemplateArgument::Template:
157     case TemplateArgument::TemplateExpansion:
158       AddTemplateName(TA.getAsTemplateOrTemplatePattern());
159       break;
160     case TemplateArgument::Expression:
161       AddStmt(TA.getAsExpr());
162       break;
163     case TemplateArgument::Pack:
164       ID.AddInteger(TA.pack_size());
165       for (auto SubTA : TA.pack_elements()) {
166         AddTemplateArgument(SubTA);
167       }
168       break;
169   }
170 }
171 
172 void ODRHash::AddTemplateParameterList(const TemplateParameterList *TPL) {
173   assert(TPL && "Expecting non-null pointer.");
174 
175   ID.AddInteger(TPL->size());
176   for (auto *ND : TPL->asArray()) {
177     AddSubDecl(ND);
178   }
179 }
180 
181 void ODRHash::clear() {
182   DeclNameMap.clear();
183   Bools.clear();
184   ID.clear();
185 }
186 
187 unsigned ODRHash::CalculateHash() {
188   // Append the bools to the end of the data segment backwards.  This allows
189   // for the bools data to be compressed 32 times smaller compared to using
190   // ID.AddBoolean
191   const unsigned unsigned_bits = sizeof(unsigned) * CHAR_BIT;
192   const unsigned size = Bools.size();
193   const unsigned remainder = size % unsigned_bits;
194   const unsigned loops = size / unsigned_bits;
195   auto I = Bools.rbegin();
196   unsigned value = 0;
197   for (unsigned i = 0; i < remainder; ++i) {
198     value <<= 1;
199     value |= *I;
200     ++I;
201   }
202   ID.AddInteger(value);
203 
204   for (unsigned i = 0; i < loops; ++i) {
205     value = 0;
206     for (unsigned j = 0; j < unsigned_bits; ++j) {
207       value <<= 1;
208       value |= *I;
209       ++I;
210     }
211     ID.AddInteger(value);
212   }
213 
214   assert(I == Bools.rend());
215   Bools.clear();
216   return ID.ComputeHash();
217 }
218 
219 namespace {
220 // Process a Decl pointer.  Add* methods call back into ODRHash while Visit*
221 // methods process the relevant parts of the Decl.
222 class ODRDeclVisitor : public ConstDeclVisitor<ODRDeclVisitor> {
223   typedef ConstDeclVisitor<ODRDeclVisitor> Inherited;
224   llvm::FoldingSetNodeID &ID;
225   ODRHash &Hash;
226 
227 public:
228   ODRDeclVisitor(llvm::FoldingSetNodeID &ID, ODRHash &Hash)
229       : ID(ID), Hash(Hash) {}
230 
231   void AddStmt(const Stmt *S) {
232     Hash.AddBoolean(S);
233     if (S) {
234       Hash.AddStmt(S);
235     }
236   }
237 
238   void AddIdentifierInfo(const IdentifierInfo *II) {
239     Hash.AddBoolean(II);
240     if (II) {
241       Hash.AddIdentifierInfo(II);
242     }
243   }
244 
245   void AddQualType(QualType T) {
246     Hash.AddQualType(T);
247   }
248 
249   void AddDecl(const Decl *D) {
250     Hash.AddBoolean(D);
251     if (D) {
252       Hash.AddDecl(D);
253     }
254   }
255 
256   void AddTemplateArgument(TemplateArgument TA) {
257     Hash.AddTemplateArgument(TA);
258   }
259 
260   void Visit(const Decl *D) {
261     ID.AddInteger(D->getKind());
262     Inherited::Visit(D);
263   }
264 
265   void VisitNamedDecl(const NamedDecl *D) {
266     Hash.AddDeclarationName(D->getDeclName());
267     Inherited::VisitNamedDecl(D);
268   }
269 
270   void VisitValueDecl(const ValueDecl *D) {
271     if (!isa<FunctionDecl>(D)) {
272       AddQualType(D->getType());
273     }
274     Inherited::VisitValueDecl(D);
275   }
276 
277   void VisitVarDecl(const VarDecl *D) {
278     Hash.AddBoolean(D->isStaticLocal());
279     Hash.AddBoolean(D->isConstexpr());
280     const bool HasInit = D->hasInit();
281     Hash.AddBoolean(HasInit);
282     if (HasInit) {
283       AddStmt(D->getInit());
284     }
285     Inherited::VisitVarDecl(D);
286   }
287 
288   void VisitParmVarDecl(const ParmVarDecl *D) {
289     // TODO: Handle default arguments.
290     Inherited::VisitParmVarDecl(D);
291   }
292 
293   void VisitAccessSpecDecl(const AccessSpecDecl *D) {
294     ID.AddInteger(D->getAccess());
295     Inherited::VisitAccessSpecDecl(D);
296   }
297 
298   void VisitStaticAssertDecl(const StaticAssertDecl *D) {
299     AddStmt(D->getAssertExpr());
300     AddStmt(D->getMessage());
301 
302     Inherited::VisitStaticAssertDecl(D);
303   }
304 
305   void VisitFieldDecl(const FieldDecl *D) {
306     const bool IsBitfield = D->isBitField();
307     Hash.AddBoolean(IsBitfield);
308 
309     if (IsBitfield) {
310       AddStmt(D->getBitWidth());
311     }
312 
313     Hash.AddBoolean(D->isMutable());
314     AddStmt(D->getInClassInitializer());
315 
316     Inherited::VisitFieldDecl(D);
317   }
318 
319   void VisitFunctionDecl(const FunctionDecl *D) {
320     ID.AddInteger(D->getStorageClass());
321     Hash.AddBoolean(D->isInlineSpecified());
322     Hash.AddBoolean(D->isVirtualAsWritten());
323     Hash.AddBoolean(D->isPure());
324     Hash.AddBoolean(D->isDeletedAsWritten());
325 
326     ID.AddInteger(D->param_size());
327 
328     for (auto *Param : D->parameters()) {
329       Hash.AddSubDecl(Param);
330     }
331 
332     AddQualType(D->getReturnType());
333 
334     const auto* SpecializationArgs = D->getTemplateSpecializationArgs();
335     Hash.AddBoolean(SpecializationArgs);
336     if (SpecializationArgs) {
337       ID.AddInteger(SpecializationArgs->size());
338       for (const TemplateArgument &TA : SpecializationArgs->asArray()) {
339         Hash.AddTemplateArgument(TA);
340       }
341     }
342 
343     Inherited::VisitFunctionDecl(D);
344   }
345 
346   void VisitCXXMethodDecl(const CXXMethodDecl *D) {
347     Hash.AddBoolean(D->isConst());
348     Hash.AddBoolean(D->isVolatile());
349 
350     Inherited::VisitCXXMethodDecl(D);
351   }
352 
353   void VisitTypedefNameDecl(const TypedefNameDecl *D) {
354     AddQualType(D->getUnderlyingType());
355 
356     Inherited::VisitTypedefNameDecl(D);
357   }
358 
359   void VisitTypedefDecl(const TypedefDecl *D) {
360     Inherited::VisitTypedefDecl(D);
361   }
362 
363   void VisitTypeAliasDecl(const TypeAliasDecl *D) {
364     Inherited::VisitTypeAliasDecl(D);
365   }
366 
367   void VisitFriendDecl(const FriendDecl *D) {
368     TypeSourceInfo *TSI = D->getFriendType();
369     Hash.AddBoolean(TSI);
370     if (TSI) {
371       AddQualType(TSI->getType());
372     } else {
373       AddDecl(D->getFriendDecl());
374     }
375   }
376 
377   void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
378     // Only care about default arguments as part of the definition.
379     const bool hasDefaultArgument =
380         D->hasDefaultArgument() && !D->defaultArgumentWasInherited();
381     Hash.AddBoolean(hasDefaultArgument);
382     if (hasDefaultArgument) {
383       AddTemplateArgument(D->getDefaultArgument());
384     }
385     Hash.AddBoolean(D->isParameterPack());
386 
387     Inherited::VisitTemplateTypeParmDecl(D);
388   }
389 
390   void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
391     // Only care about default arguments as part of the definition.
392     const bool hasDefaultArgument =
393         D->hasDefaultArgument() && !D->defaultArgumentWasInherited();
394     Hash.AddBoolean(hasDefaultArgument);
395     if (hasDefaultArgument) {
396       AddStmt(D->getDefaultArgument());
397     }
398     Hash.AddBoolean(D->isParameterPack());
399 
400     Inherited::VisitNonTypeTemplateParmDecl(D);
401   }
402 
403   void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D) {
404     // Only care about default arguments as part of the definition.
405     const bool hasDefaultArgument =
406         D->hasDefaultArgument() && !D->defaultArgumentWasInherited();
407     Hash.AddBoolean(hasDefaultArgument);
408     if (hasDefaultArgument) {
409       AddTemplateArgument(D->getDefaultArgument().getArgument());
410     }
411     Hash.AddBoolean(D->isParameterPack());
412 
413     Inherited::VisitTemplateTemplateParmDecl(D);
414   }
415 
416   void VisitTemplateDecl(const TemplateDecl *D) {
417     Hash.AddTemplateParameterList(D->getTemplateParameters());
418 
419     Inherited::VisitTemplateDecl(D);
420   }
421 
422   void VisitRedeclarableTemplateDecl(const RedeclarableTemplateDecl *D) {
423     Hash.AddBoolean(D->isMemberSpecialization());
424     Inherited::VisitRedeclarableTemplateDecl(D);
425   }
426 
427   void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
428     Visit(D->getTemplatedDecl());
429     AddDecl(D->getTemplatedDecl());
430     Inherited::VisitFunctionTemplateDecl(D);
431   }
432 };
433 } // namespace
434 
435 // Only allow a small portion of Decl's to be processed.  Remove this once
436 // all Decl's can be handled.
437 bool ODRHash::isWhitelistedDecl(const Decl *D, const CXXRecordDecl *Parent) {
438   if (D->isImplicit()) return false;
439   if (D->getDeclContext() != Parent) return false;
440 
441   switch (D->getKind()) {
442     default:
443       return false;
444     case Decl::AccessSpec:
445     case Decl::CXXConstructor:
446     case Decl::CXXDestructor:
447     case Decl::CXXMethod:
448     case Decl::Field:
449     case Decl::Friend:
450     case Decl::FunctionTemplate:
451     case Decl::StaticAssert:
452     case Decl::TypeAlias:
453     case Decl::Typedef:
454     case Decl::Var:
455       return true;
456   }
457 }
458 
459 void ODRHash::AddSubDecl(const Decl *D) {
460   assert(D && "Expecting non-null pointer.");
461 
462   ODRDeclVisitor(ID, *this).Visit(D);
463 }
464 
465 void ODRHash::AddCXXRecordDecl(const CXXRecordDecl *Record) {
466   assert(Record && Record->hasDefinition() &&
467          "Expected non-null record to be a definition.");
468 
469   const DeclContext *DC = Record;
470   while (DC) {
471     if (isa<ClassTemplateSpecializationDecl>(DC)) {
472       return;
473     }
474     DC = DC->getParent();
475   }
476 
477   AddDecl(Record);
478 
479   // Filter out sub-Decls which will not be processed in order to get an
480   // accurate count of Decl's.
481   llvm::SmallVector<const Decl *, 16> Decls;
482   for (const Decl *SubDecl : Record->decls()) {
483     if (isWhitelistedDecl(SubDecl, Record)) {
484       Decls.push_back(SubDecl);
485     }
486   }
487 
488   ID.AddInteger(Decls.size());
489   for (auto SubDecl : Decls) {
490     AddSubDecl(SubDecl);
491   }
492 
493   const ClassTemplateDecl *TD = Record->getDescribedClassTemplate();
494   AddBoolean(TD);
495   if (TD) {
496     AddTemplateParameterList(TD->getTemplateParameters());
497   }
498 
499   ID.AddInteger(Record->getNumBases());
500   auto Bases = Record->bases();
501   for (auto Base : Bases) {
502     AddQualType(Base.getType());
503     ID.AddInteger(Base.isVirtual());
504     ID.AddInteger(Base.getAccessSpecifierAsWritten());
505   }
506 }
507 
508 void ODRHash::AddFunctionDecl(const FunctionDecl *Function) {
509   assert(Function && "Expecting non-null pointer.");
510 
511   // Skip hashing these kinds of function.
512   if (Function->isImplicit()) return;
513   if (Function->isDefaulted()) return;
514   if (Function->isDeleted()) return;
515   if (!Function->hasBody()) return;
516   if (!Function->getBody()) return;
517 
518   // Skip functions that are specializations or in specialization context.
519   const DeclContext *DC = Function;
520   while (DC) {
521     if (isa<ClassTemplateSpecializationDecl>(DC)) return;
522     if (auto *F = dyn_cast<FunctionDecl>(DC))
523       if (F->isFunctionTemplateSpecialization()) return;
524     DC = DC->getParent();
525   }
526 
527   AddDecl(Function);
528 
529   AddQualType(Function->getReturnType());
530 
531   ID.AddInteger(Function->param_size());
532   for (auto Param : Function->parameters())
533     AddSubDecl(Param);
534 
535   AddStmt(Function->getBody());
536 }
537 
538 void ODRHash::AddDecl(const Decl *D) {
539   assert(D && "Expecting non-null pointer.");
540   D = D->getCanonicalDecl();
541 
542   if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
543     AddDeclarationName(ND->getDeclName());
544     return;
545   }
546 
547   ID.AddInteger(D->getKind());
548   // TODO: Handle non-NamedDecl here.
549 }
550 
551 namespace {
552 // Process a Type pointer.  Add* methods call back into ODRHash while Visit*
553 // methods process the relevant parts of the Type.
554 class ODRTypeVisitor : public TypeVisitor<ODRTypeVisitor> {
555   typedef TypeVisitor<ODRTypeVisitor> Inherited;
556   llvm::FoldingSetNodeID &ID;
557   ODRHash &Hash;
558 
559 public:
560   ODRTypeVisitor(llvm::FoldingSetNodeID &ID, ODRHash &Hash)
561       : ID(ID), Hash(Hash) {}
562 
563   void AddStmt(Stmt *S) {
564     Hash.AddBoolean(S);
565     if (S) {
566       Hash.AddStmt(S);
567     }
568   }
569 
570   void AddDecl(Decl *D) {
571     Hash.AddBoolean(D);
572     if (D) {
573       Hash.AddDecl(D);
574     }
575   }
576 
577   void AddQualType(QualType T) {
578     Hash.AddQualType(T);
579   }
580 
581   void AddType(const Type *T) {
582     Hash.AddBoolean(T);
583     if (T) {
584       Hash.AddType(T);
585     }
586   }
587 
588   void AddNestedNameSpecifier(const NestedNameSpecifier *NNS) {
589     Hash.AddBoolean(NNS);
590     if (NNS) {
591       Hash.AddNestedNameSpecifier(NNS);
592     }
593   }
594 
595   void AddIdentifierInfo(const IdentifierInfo *II) {
596     Hash.AddBoolean(II);
597     if (II) {
598       Hash.AddIdentifierInfo(II);
599     }
600   }
601 
602   void VisitQualifiers(Qualifiers Quals) {
603     ID.AddInteger(Quals.getAsOpaqueValue());
604   }
605 
606   void Visit(const Type *T) {
607     ID.AddInteger(T->getTypeClass());
608     Inherited::Visit(T);
609   }
610 
611   void VisitType(const Type *T) {}
612 
613   void VisitAdjustedType(const AdjustedType *T) {
614     AddQualType(T->getOriginalType());
615     AddQualType(T->getAdjustedType());
616     VisitType(T);
617   }
618 
619   void VisitDecayedType(const DecayedType *T) {
620     AddQualType(T->getDecayedType());
621     AddQualType(T->getPointeeType());
622     VisitAdjustedType(T);
623   }
624 
625   void VisitArrayType(const ArrayType *T) {
626     AddQualType(T->getElementType());
627     ID.AddInteger(T->getSizeModifier());
628     VisitQualifiers(T->getIndexTypeQualifiers());
629     VisitType(T);
630   }
631   void VisitConstantArrayType(const ConstantArrayType *T) {
632     T->getSize().Profile(ID);
633     VisitArrayType(T);
634   }
635 
636   void VisitDependentSizedArrayType(const DependentSizedArrayType *T) {
637     AddStmt(T->getSizeExpr());
638     VisitArrayType(T);
639   }
640 
641   void VisitIncompleteArrayType(const IncompleteArrayType *T) {
642     VisitArrayType(T);
643   }
644 
645   void VisitVariableArrayType(const VariableArrayType *T) {
646     AddStmt(T->getSizeExpr());
647     VisitArrayType(T);
648   }
649 
650   void VisitBuiltinType(const BuiltinType *T) {
651     ID.AddInteger(T->getKind());
652     VisitType(T);
653   }
654 
655   void VisitFunctionType(const FunctionType *T) {
656     AddQualType(T->getReturnType());
657     T->getExtInfo().Profile(ID);
658     Hash.AddBoolean(T->isConst());
659     Hash.AddBoolean(T->isVolatile());
660     Hash.AddBoolean(T->isRestrict());
661     VisitType(T);
662   }
663 
664   void VisitFunctionNoProtoType(const FunctionNoProtoType *T) {
665     VisitFunctionType(T);
666   }
667 
668   void VisitFunctionProtoType(const FunctionProtoType *T) {
669     ID.AddInteger(T->getNumParams());
670     for (auto ParamType : T->getParamTypes())
671       AddQualType(ParamType);
672 
673     VisitFunctionType(T);
674   }
675 
676   void VisitPointerType(const PointerType *T) {
677     AddQualType(T->getPointeeType());
678     VisitType(T);
679   }
680 
681   void VisitReferenceType(const ReferenceType *T) {
682     AddQualType(T->getPointeeTypeAsWritten());
683     VisitType(T);
684   }
685 
686   void VisitLValueReferenceType(const LValueReferenceType *T) {
687     VisitReferenceType(T);
688   }
689 
690   void VisitRValueReferenceType(const RValueReferenceType *T) {
691     VisitReferenceType(T);
692   }
693 
694   void VisitTypedefType(const TypedefType *T) {
695     AddDecl(T->getDecl());
696     QualType UnderlyingType = T->getDecl()->getUnderlyingType();
697     VisitQualifiers(UnderlyingType.getQualifiers());
698     while (true) {
699       if (const TypedefType *Underlying =
700               dyn_cast<TypedefType>(UnderlyingType.getTypePtr())) {
701         UnderlyingType = Underlying->getDecl()->getUnderlyingType();
702         continue;
703       }
704       if (const ElaboratedType *Underlying =
705               dyn_cast<ElaboratedType>(UnderlyingType.getTypePtr())) {
706         UnderlyingType = Underlying->getNamedType();
707         continue;
708       }
709 
710       break;
711     }
712     AddType(UnderlyingType.getTypePtr());
713     VisitType(T);
714   }
715 
716   void VisitTagType(const TagType *T) {
717     AddDecl(T->getDecl());
718     VisitType(T);
719   }
720 
721   void VisitRecordType(const RecordType *T) { VisitTagType(T); }
722   void VisitEnumType(const EnumType *T) { VisitTagType(T); }
723 
724   void VisitTypeWithKeyword(const TypeWithKeyword *T) {
725     ID.AddInteger(T->getKeyword());
726     VisitType(T);
727   };
728 
729   void VisitDependentNameType(const DependentNameType *T) {
730     AddNestedNameSpecifier(T->getQualifier());
731     AddIdentifierInfo(T->getIdentifier());
732     VisitTypeWithKeyword(T);
733   }
734 
735   void VisitDependentTemplateSpecializationType(
736       const DependentTemplateSpecializationType *T) {
737     AddIdentifierInfo(T->getIdentifier());
738     AddNestedNameSpecifier(T->getQualifier());
739     ID.AddInteger(T->getNumArgs());
740     for (const auto &TA : T->template_arguments()) {
741       Hash.AddTemplateArgument(TA);
742     }
743     VisitTypeWithKeyword(T);
744   }
745 
746   void VisitElaboratedType(const ElaboratedType *T) {
747     AddNestedNameSpecifier(T->getQualifier());
748     AddQualType(T->getNamedType());
749     VisitTypeWithKeyword(T);
750   }
751 
752   void VisitTemplateSpecializationType(const TemplateSpecializationType *T) {
753     ID.AddInteger(T->getNumArgs());
754     for (const auto &TA : T->template_arguments()) {
755       Hash.AddTemplateArgument(TA);
756     }
757     Hash.AddTemplateName(T->getTemplateName());
758     VisitType(T);
759   }
760 
761   void VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
762     ID.AddInteger(T->getDepth());
763     ID.AddInteger(T->getIndex());
764     Hash.AddBoolean(T->isParameterPack());
765     AddDecl(T->getDecl());
766   }
767 };
768 } // namespace
769 
770 void ODRHash::AddType(const Type *T) {
771   assert(T && "Expecting non-null pointer.");
772   ODRTypeVisitor(ID, *this).Visit(T);
773 }
774 
775 void ODRHash::AddQualType(QualType T) {
776   AddBoolean(T.isNull());
777   if (T.isNull())
778     return;
779   SplitQualType split = T.split();
780   ID.AddInteger(split.Quals.getAsOpaqueValue());
781   AddType(split.Ty);
782 }
783 
784 void ODRHash::AddBoolean(bool Value) {
785   Bools.push_back(Value);
786 }
787