xref: /freebsd-src/contrib/llvm-project/clang/lib/AST/ODRHash.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===-- ODRHash.cpp - Hashing to diagnose ODR failures ----------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric ///
90b57cec5SDimitry Andric /// \file
100b57cec5SDimitry Andric /// This file implements the ODRHash class, which calculates a hash based
110b57cec5SDimitry Andric /// on AST nodes, which is stable across different runs.
120b57cec5SDimitry Andric ///
130b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
140b57cec5SDimitry Andric 
150b57cec5SDimitry Andric #include "clang/AST/ODRHash.h"
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric #include "clang/AST/DeclVisitor.h"
180b57cec5SDimitry Andric #include "clang/AST/NestedNameSpecifier.h"
190b57cec5SDimitry Andric #include "clang/AST/StmtVisitor.h"
200b57cec5SDimitry Andric #include "clang/AST/TypeVisitor.h"
210b57cec5SDimitry Andric 
220b57cec5SDimitry Andric using namespace clang;
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric void ODRHash::AddStmt(const Stmt *S) {
250b57cec5SDimitry Andric   assert(S && "Expecting non-null pointer.");
260b57cec5SDimitry Andric   S->ProcessODRHash(ID, *this);
270b57cec5SDimitry Andric }
280b57cec5SDimitry Andric 
290b57cec5SDimitry Andric void ODRHash::AddIdentifierInfo(const IdentifierInfo *II) {
300b57cec5SDimitry Andric   assert(II && "Expecting non-null pointer.");
310b57cec5SDimitry Andric   ID.AddString(II->getName());
320b57cec5SDimitry Andric }
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric void ODRHash::AddDeclarationName(DeclarationName Name, bool TreatAsDecl) {
350b57cec5SDimitry Andric   if (TreatAsDecl)
360b57cec5SDimitry Andric     // Matches the NamedDecl check in AddDecl
370b57cec5SDimitry Andric     AddBoolean(true);
380b57cec5SDimitry Andric 
390b57cec5SDimitry Andric   AddDeclarationNameImpl(Name);
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric   if (TreatAsDecl)
420b57cec5SDimitry Andric     // Matches the ClassTemplateSpecializationDecl check in AddDecl
430b57cec5SDimitry Andric     AddBoolean(false);
440b57cec5SDimitry Andric }
450b57cec5SDimitry Andric 
460b57cec5SDimitry Andric void ODRHash::AddDeclarationNameImpl(DeclarationName Name) {
470b57cec5SDimitry Andric   // Index all DeclarationName and use index numbers to refer to them.
480b57cec5SDimitry Andric   auto Result = DeclNameMap.insert(std::make_pair(Name, DeclNameMap.size()));
490b57cec5SDimitry Andric   ID.AddInteger(Result.first->second);
500b57cec5SDimitry Andric   if (!Result.second) {
510b57cec5SDimitry Andric     // If found in map, the DeclarationName has previously been processed.
520b57cec5SDimitry Andric     return;
530b57cec5SDimitry Andric   }
540b57cec5SDimitry Andric 
550b57cec5SDimitry Andric   // First time processing each DeclarationName, also process its details.
560b57cec5SDimitry Andric   AddBoolean(Name.isEmpty());
570b57cec5SDimitry Andric   if (Name.isEmpty())
580b57cec5SDimitry Andric     return;
590b57cec5SDimitry Andric 
600b57cec5SDimitry Andric   auto Kind = Name.getNameKind();
610b57cec5SDimitry Andric   ID.AddInteger(Kind);
620b57cec5SDimitry Andric   switch (Kind) {
630b57cec5SDimitry Andric   case DeclarationName::Identifier:
640b57cec5SDimitry Andric     AddIdentifierInfo(Name.getAsIdentifierInfo());
650b57cec5SDimitry Andric     break;
660b57cec5SDimitry Andric   case DeclarationName::ObjCZeroArgSelector:
670b57cec5SDimitry Andric   case DeclarationName::ObjCOneArgSelector:
680b57cec5SDimitry Andric   case DeclarationName::ObjCMultiArgSelector: {
690b57cec5SDimitry Andric     Selector S = Name.getObjCSelector();
700b57cec5SDimitry Andric     AddBoolean(S.isNull());
710b57cec5SDimitry Andric     AddBoolean(S.isKeywordSelector());
720b57cec5SDimitry Andric     AddBoolean(S.isUnarySelector());
730b57cec5SDimitry Andric     unsigned NumArgs = S.getNumArgs();
740b57cec5SDimitry Andric     ID.AddInteger(NumArgs);
75bdd1243dSDimitry Andric     // Compare all selector slots. For selectors with arguments it means all arg
76bdd1243dSDimitry Andric     // slots. And if there are no arguments, compare the first-and-only slot.
77bdd1243dSDimitry Andric     unsigned SlotsToCheck = NumArgs > 0 ? NumArgs : 1;
78bdd1243dSDimitry Andric     for (unsigned i = 0; i < SlotsToCheck; ++i) {
790b57cec5SDimitry Andric       const IdentifierInfo *II = S.getIdentifierInfoForSlot(i);
800b57cec5SDimitry Andric       AddBoolean(II);
810b57cec5SDimitry Andric       if (II) {
820b57cec5SDimitry Andric         AddIdentifierInfo(II);
830b57cec5SDimitry Andric       }
840b57cec5SDimitry Andric     }
850b57cec5SDimitry Andric     break;
860b57cec5SDimitry Andric   }
870b57cec5SDimitry Andric   case DeclarationName::CXXConstructorName:
880b57cec5SDimitry Andric   case DeclarationName::CXXDestructorName:
890b57cec5SDimitry Andric     AddQualType(Name.getCXXNameType());
900b57cec5SDimitry Andric     break;
910b57cec5SDimitry Andric   case DeclarationName::CXXOperatorName:
920b57cec5SDimitry Andric     ID.AddInteger(Name.getCXXOverloadedOperator());
930b57cec5SDimitry Andric     break;
940b57cec5SDimitry Andric   case DeclarationName::CXXLiteralOperatorName:
950b57cec5SDimitry Andric     AddIdentifierInfo(Name.getCXXLiteralIdentifier());
960b57cec5SDimitry Andric     break;
970b57cec5SDimitry Andric   case DeclarationName::CXXConversionFunctionName:
980b57cec5SDimitry Andric     AddQualType(Name.getCXXNameType());
990b57cec5SDimitry Andric     break;
1000b57cec5SDimitry Andric   case DeclarationName::CXXUsingDirective:
1010b57cec5SDimitry Andric     break;
1020b57cec5SDimitry Andric   case DeclarationName::CXXDeductionGuideName: {
1030b57cec5SDimitry Andric     auto *Template = Name.getCXXDeductionGuideTemplate();
1040b57cec5SDimitry Andric     AddBoolean(Template);
1050b57cec5SDimitry Andric     if (Template) {
1060b57cec5SDimitry Andric       AddDecl(Template);
1070b57cec5SDimitry Andric     }
1080b57cec5SDimitry Andric   }
1090b57cec5SDimitry Andric   }
1100b57cec5SDimitry Andric }
1110b57cec5SDimitry Andric 
1120b57cec5SDimitry Andric void ODRHash::AddNestedNameSpecifier(const NestedNameSpecifier *NNS) {
1130b57cec5SDimitry Andric   assert(NNS && "Expecting non-null pointer.");
1140b57cec5SDimitry Andric   const auto *Prefix = NNS->getPrefix();
1150b57cec5SDimitry Andric   AddBoolean(Prefix);
1160b57cec5SDimitry Andric   if (Prefix) {
1170b57cec5SDimitry Andric     AddNestedNameSpecifier(Prefix);
1180b57cec5SDimitry Andric   }
1190b57cec5SDimitry Andric   auto Kind = NNS->getKind();
1200b57cec5SDimitry Andric   ID.AddInteger(Kind);
1210b57cec5SDimitry Andric   switch (Kind) {
1220b57cec5SDimitry Andric   case NestedNameSpecifier::Identifier:
1230b57cec5SDimitry Andric     AddIdentifierInfo(NNS->getAsIdentifier());
1240b57cec5SDimitry Andric     break;
1250b57cec5SDimitry Andric   case NestedNameSpecifier::Namespace:
1260b57cec5SDimitry Andric     AddDecl(NNS->getAsNamespace());
1270b57cec5SDimitry Andric     break;
1280b57cec5SDimitry Andric   case NestedNameSpecifier::NamespaceAlias:
1290b57cec5SDimitry Andric     AddDecl(NNS->getAsNamespaceAlias());
1300b57cec5SDimitry Andric     break;
1310b57cec5SDimitry Andric   case NestedNameSpecifier::TypeSpec:
1320b57cec5SDimitry Andric   case NestedNameSpecifier::TypeSpecWithTemplate:
1330b57cec5SDimitry Andric     AddType(NNS->getAsType());
1340b57cec5SDimitry Andric     break;
1350b57cec5SDimitry Andric   case NestedNameSpecifier::Global:
1360b57cec5SDimitry Andric   case NestedNameSpecifier::Super:
1370b57cec5SDimitry Andric     break;
1380b57cec5SDimitry Andric   }
1390b57cec5SDimitry Andric }
1400b57cec5SDimitry Andric 
1410b57cec5SDimitry Andric void ODRHash::AddTemplateName(TemplateName Name) {
1420b57cec5SDimitry Andric   auto Kind = Name.getKind();
1430b57cec5SDimitry Andric   ID.AddInteger(Kind);
1440b57cec5SDimitry Andric 
1450b57cec5SDimitry Andric   switch (Kind) {
1460b57cec5SDimitry Andric   case TemplateName::Template:
1470b57cec5SDimitry Andric     AddDecl(Name.getAsTemplateDecl());
1480b57cec5SDimitry Andric     break;
149*0fca6ea1SDimitry Andric   case TemplateName::QualifiedTemplate: {
150*0fca6ea1SDimitry Andric     QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName();
151*0fca6ea1SDimitry Andric     if (NestedNameSpecifier *NNS = QTN->getQualifier())
152*0fca6ea1SDimitry Andric       AddNestedNameSpecifier(NNS);
153*0fca6ea1SDimitry Andric     AddBoolean(QTN->hasTemplateKeyword());
154*0fca6ea1SDimitry Andric     AddTemplateName(QTN->getUnderlyingTemplate());
155*0fca6ea1SDimitry Andric     break;
156*0fca6ea1SDimitry Andric   }
1570b57cec5SDimitry Andric   // TODO: Support these cases.
1580b57cec5SDimitry Andric   case TemplateName::OverloadedTemplate:
1590b57cec5SDimitry Andric   case TemplateName::AssumedTemplate:
1600b57cec5SDimitry Andric   case TemplateName::DependentTemplate:
1610b57cec5SDimitry Andric   case TemplateName::SubstTemplateTemplateParm:
1620b57cec5SDimitry Andric   case TemplateName::SubstTemplateTemplateParmPack:
16381ad6265SDimitry Andric   case TemplateName::UsingTemplate:
1640b57cec5SDimitry Andric     break;
1650b57cec5SDimitry Andric   }
1660b57cec5SDimitry Andric }
1670b57cec5SDimitry Andric 
1680b57cec5SDimitry Andric void ODRHash::AddTemplateArgument(TemplateArgument TA) {
1690b57cec5SDimitry Andric   const auto Kind = TA.getKind();
1700b57cec5SDimitry Andric   ID.AddInteger(Kind);
1710b57cec5SDimitry Andric 
1720b57cec5SDimitry Andric   switch (Kind) {
1730b57cec5SDimitry Andric     case TemplateArgument::Null:
1740b57cec5SDimitry Andric       llvm_unreachable("Expected valid TemplateArgument");
1750b57cec5SDimitry Andric     case TemplateArgument::Type:
1760b57cec5SDimitry Andric       AddQualType(TA.getAsType());
1770b57cec5SDimitry Andric       break;
1780b57cec5SDimitry Andric     case TemplateArgument::Declaration:
1790b57cec5SDimitry Andric       AddDecl(TA.getAsDecl());
1800b57cec5SDimitry Andric       break;
1810b57cec5SDimitry Andric     case TemplateArgument::NullPtr:
182bdd1243dSDimitry Andric       ID.AddPointer(nullptr);
1830b57cec5SDimitry Andric       break;
184bdd1243dSDimitry Andric     case TemplateArgument::Integral: {
185bdd1243dSDimitry Andric       // There are integrals (e.g.: _BitInt(128)) that cannot be represented as
186bdd1243dSDimitry Andric       // any builtin integral type, so we use the hash of APSInt instead.
187bdd1243dSDimitry Andric       TA.getAsIntegral().Profile(ID);
188bdd1243dSDimitry Andric       break;
189bdd1243dSDimitry Andric     }
1907a6dacacSDimitry Andric     case TemplateArgument::StructuralValue:
1917a6dacacSDimitry Andric       AddQualType(TA.getStructuralValueType());
1927a6dacacSDimitry Andric       AddStructuralValue(TA.getAsStructuralValue());
1937a6dacacSDimitry Andric       break;
1940b57cec5SDimitry Andric     case TemplateArgument::Template:
1950b57cec5SDimitry Andric     case TemplateArgument::TemplateExpansion:
1960b57cec5SDimitry Andric       AddTemplateName(TA.getAsTemplateOrTemplatePattern());
1970b57cec5SDimitry Andric       break;
1980b57cec5SDimitry Andric     case TemplateArgument::Expression:
1990b57cec5SDimitry Andric       AddStmt(TA.getAsExpr());
2000b57cec5SDimitry Andric       break;
2010b57cec5SDimitry Andric     case TemplateArgument::Pack:
2020b57cec5SDimitry Andric       ID.AddInteger(TA.pack_size());
2030b57cec5SDimitry Andric       for (auto SubTA : TA.pack_elements()) {
2040b57cec5SDimitry Andric         AddTemplateArgument(SubTA);
2050b57cec5SDimitry Andric       }
2060b57cec5SDimitry Andric       break;
2070b57cec5SDimitry Andric   }
2080b57cec5SDimitry Andric }
2090b57cec5SDimitry Andric 
2100b57cec5SDimitry Andric void ODRHash::AddTemplateParameterList(const TemplateParameterList *TPL) {
2110b57cec5SDimitry Andric   assert(TPL && "Expecting non-null pointer.");
2120b57cec5SDimitry Andric 
2130b57cec5SDimitry Andric   ID.AddInteger(TPL->size());
2140b57cec5SDimitry Andric   for (auto *ND : TPL->asArray()) {
2150b57cec5SDimitry Andric     AddSubDecl(ND);
2160b57cec5SDimitry Andric   }
2170b57cec5SDimitry Andric }
2180b57cec5SDimitry Andric 
2190b57cec5SDimitry Andric void ODRHash::clear() {
2200b57cec5SDimitry Andric   DeclNameMap.clear();
2210b57cec5SDimitry Andric   Bools.clear();
2220b57cec5SDimitry Andric   ID.clear();
2230b57cec5SDimitry Andric }
2240b57cec5SDimitry Andric 
2250b57cec5SDimitry Andric unsigned ODRHash::CalculateHash() {
2260b57cec5SDimitry Andric   // Append the bools to the end of the data segment backwards.  This allows
2270b57cec5SDimitry Andric   // for the bools data to be compressed 32 times smaller compared to using
2280b57cec5SDimitry Andric   // ID.AddBoolean
2290b57cec5SDimitry Andric   const unsigned unsigned_bits = sizeof(unsigned) * CHAR_BIT;
2300b57cec5SDimitry Andric   const unsigned size = Bools.size();
2310b57cec5SDimitry Andric   const unsigned remainder = size % unsigned_bits;
2320b57cec5SDimitry Andric   const unsigned loops = size / unsigned_bits;
2330b57cec5SDimitry Andric   auto I = Bools.rbegin();
2340b57cec5SDimitry Andric   unsigned value = 0;
2350b57cec5SDimitry Andric   for (unsigned i = 0; i < remainder; ++i) {
2360b57cec5SDimitry Andric     value <<= 1;
2370b57cec5SDimitry Andric     value |= *I;
2380b57cec5SDimitry Andric     ++I;
2390b57cec5SDimitry Andric   }
2400b57cec5SDimitry Andric   ID.AddInteger(value);
2410b57cec5SDimitry Andric 
2420b57cec5SDimitry Andric   for (unsigned i = 0; i < loops; ++i) {
2430b57cec5SDimitry Andric     value = 0;
2440b57cec5SDimitry Andric     for (unsigned j = 0; j < unsigned_bits; ++j) {
2450b57cec5SDimitry Andric       value <<= 1;
2460b57cec5SDimitry Andric       value |= *I;
2470b57cec5SDimitry Andric       ++I;
2480b57cec5SDimitry Andric     }
2490b57cec5SDimitry Andric     ID.AddInteger(value);
2500b57cec5SDimitry Andric   }
2510b57cec5SDimitry Andric 
2520b57cec5SDimitry Andric   assert(I == Bools.rend());
2530b57cec5SDimitry Andric   Bools.clear();
254*0fca6ea1SDimitry Andric   return ID.computeStableHash();
2550b57cec5SDimitry Andric }
2560b57cec5SDimitry Andric 
2570b57cec5SDimitry Andric namespace {
2580b57cec5SDimitry Andric // Process a Decl pointer.  Add* methods call back into ODRHash while Visit*
2590b57cec5SDimitry Andric // methods process the relevant parts of the Decl.
2600b57cec5SDimitry Andric class ODRDeclVisitor : public ConstDeclVisitor<ODRDeclVisitor> {
2610b57cec5SDimitry Andric   typedef ConstDeclVisitor<ODRDeclVisitor> Inherited;
2620b57cec5SDimitry Andric   llvm::FoldingSetNodeID &ID;
2630b57cec5SDimitry Andric   ODRHash &Hash;
2640b57cec5SDimitry Andric 
2650b57cec5SDimitry Andric public:
2660b57cec5SDimitry Andric   ODRDeclVisitor(llvm::FoldingSetNodeID &ID, ODRHash &Hash)
2670b57cec5SDimitry Andric       : ID(ID), Hash(Hash) {}
2680b57cec5SDimitry Andric 
2690b57cec5SDimitry Andric   void AddStmt(const Stmt *S) {
2700b57cec5SDimitry Andric     Hash.AddBoolean(S);
2710b57cec5SDimitry Andric     if (S) {
2720b57cec5SDimitry Andric       Hash.AddStmt(S);
2730b57cec5SDimitry Andric     }
2740b57cec5SDimitry Andric   }
2750b57cec5SDimitry Andric 
2760b57cec5SDimitry Andric   void AddIdentifierInfo(const IdentifierInfo *II) {
2770b57cec5SDimitry Andric     Hash.AddBoolean(II);
2780b57cec5SDimitry Andric     if (II) {
2790b57cec5SDimitry Andric       Hash.AddIdentifierInfo(II);
2800b57cec5SDimitry Andric     }
2810b57cec5SDimitry Andric   }
2820b57cec5SDimitry Andric 
2830b57cec5SDimitry Andric   void AddQualType(QualType T) {
2840b57cec5SDimitry Andric     Hash.AddQualType(T);
2850b57cec5SDimitry Andric   }
2860b57cec5SDimitry Andric 
2870b57cec5SDimitry Andric   void AddDecl(const Decl *D) {
2880b57cec5SDimitry Andric     Hash.AddBoolean(D);
2890b57cec5SDimitry Andric     if (D) {
2900b57cec5SDimitry Andric       Hash.AddDecl(D);
2910b57cec5SDimitry Andric     }
2920b57cec5SDimitry Andric   }
2930b57cec5SDimitry Andric 
2940b57cec5SDimitry Andric   void AddTemplateArgument(TemplateArgument TA) {
2950b57cec5SDimitry Andric     Hash.AddTemplateArgument(TA);
2960b57cec5SDimitry Andric   }
2970b57cec5SDimitry Andric 
2980b57cec5SDimitry Andric   void Visit(const Decl *D) {
2990b57cec5SDimitry Andric     ID.AddInteger(D->getKind());
3000b57cec5SDimitry Andric     Inherited::Visit(D);
3010b57cec5SDimitry Andric   }
3020b57cec5SDimitry Andric 
3030b57cec5SDimitry Andric   void VisitNamedDecl(const NamedDecl *D) {
3040b57cec5SDimitry Andric     Hash.AddDeclarationName(D->getDeclName());
3050b57cec5SDimitry Andric     Inherited::VisitNamedDecl(D);
3060b57cec5SDimitry Andric   }
3070b57cec5SDimitry Andric 
3080b57cec5SDimitry Andric   void VisitValueDecl(const ValueDecl *D) {
3095f757f3fSDimitry Andric     if (auto *DD = dyn_cast<DeclaratorDecl>(D); DD && DD->getTypeSourceInfo())
3105f757f3fSDimitry Andric       AddQualType(DD->getTypeSourceInfo()->getType());
3115f757f3fSDimitry Andric 
3120b57cec5SDimitry Andric     Inherited::VisitValueDecl(D);
3130b57cec5SDimitry Andric   }
3140b57cec5SDimitry Andric 
3150b57cec5SDimitry Andric   void VisitVarDecl(const VarDecl *D) {
3160b57cec5SDimitry Andric     Hash.AddBoolean(D->isStaticLocal());
3170b57cec5SDimitry Andric     Hash.AddBoolean(D->isConstexpr());
3180b57cec5SDimitry Andric     const bool HasInit = D->hasInit();
3190b57cec5SDimitry Andric     Hash.AddBoolean(HasInit);
3200b57cec5SDimitry Andric     if (HasInit) {
3210b57cec5SDimitry Andric       AddStmt(D->getInit());
3220b57cec5SDimitry Andric     }
3230b57cec5SDimitry Andric     Inherited::VisitVarDecl(D);
3240b57cec5SDimitry Andric   }
3250b57cec5SDimitry Andric 
3260b57cec5SDimitry Andric   void VisitParmVarDecl(const ParmVarDecl *D) {
3270b57cec5SDimitry Andric     // TODO: Handle default arguments.
3280b57cec5SDimitry Andric     Inherited::VisitParmVarDecl(D);
3290b57cec5SDimitry Andric   }
3300b57cec5SDimitry Andric 
3310b57cec5SDimitry Andric   void VisitAccessSpecDecl(const AccessSpecDecl *D) {
3320b57cec5SDimitry Andric     ID.AddInteger(D->getAccess());
3330b57cec5SDimitry Andric     Inherited::VisitAccessSpecDecl(D);
3340b57cec5SDimitry Andric   }
3350b57cec5SDimitry Andric 
3360b57cec5SDimitry Andric   void VisitStaticAssertDecl(const StaticAssertDecl *D) {
3370b57cec5SDimitry Andric     AddStmt(D->getAssertExpr());
3380b57cec5SDimitry Andric     AddStmt(D->getMessage());
3390b57cec5SDimitry Andric 
3400b57cec5SDimitry Andric     Inherited::VisitStaticAssertDecl(D);
3410b57cec5SDimitry Andric   }
3420b57cec5SDimitry Andric 
3430b57cec5SDimitry Andric   void VisitFieldDecl(const FieldDecl *D) {
3440b57cec5SDimitry Andric     const bool IsBitfield = D->isBitField();
3450b57cec5SDimitry Andric     Hash.AddBoolean(IsBitfield);
3460b57cec5SDimitry Andric 
3470b57cec5SDimitry Andric     if (IsBitfield) {
3480b57cec5SDimitry Andric       AddStmt(D->getBitWidth());
3490b57cec5SDimitry Andric     }
3500b57cec5SDimitry Andric 
3510b57cec5SDimitry Andric     Hash.AddBoolean(D->isMutable());
3520b57cec5SDimitry Andric     AddStmt(D->getInClassInitializer());
3530b57cec5SDimitry Andric 
3540b57cec5SDimitry Andric     Inherited::VisitFieldDecl(D);
3550b57cec5SDimitry Andric   }
3560b57cec5SDimitry Andric 
357bdd1243dSDimitry Andric   void VisitObjCIvarDecl(const ObjCIvarDecl *D) {
358bdd1243dSDimitry Andric     ID.AddInteger(D->getCanonicalAccessControl());
359bdd1243dSDimitry Andric     Inherited::VisitObjCIvarDecl(D);
360bdd1243dSDimitry Andric   }
361bdd1243dSDimitry Andric 
362bdd1243dSDimitry Andric   void VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
363bdd1243dSDimitry Andric     ID.AddInteger(D->getPropertyAttributes());
364bdd1243dSDimitry Andric     ID.AddInteger(D->getPropertyImplementation());
3655f757f3fSDimitry Andric     AddQualType(D->getTypeSourceInfo()->getType());
366bdd1243dSDimitry Andric     AddDecl(D);
367bdd1243dSDimitry Andric 
368bdd1243dSDimitry Andric     Inherited::VisitObjCPropertyDecl(D);
369bdd1243dSDimitry Andric   }
370bdd1243dSDimitry Andric 
3710b57cec5SDimitry Andric   void VisitFunctionDecl(const FunctionDecl *D) {
3720b57cec5SDimitry Andric     // Handled by the ODRHash for FunctionDecl
3730b57cec5SDimitry Andric     ID.AddInteger(D->getODRHash());
3740b57cec5SDimitry Andric 
3750b57cec5SDimitry Andric     Inherited::VisitFunctionDecl(D);
3760b57cec5SDimitry Andric   }
3770b57cec5SDimitry Andric 
3780b57cec5SDimitry Andric   void VisitCXXMethodDecl(const CXXMethodDecl *D) {
3790b57cec5SDimitry Andric     // Handled by the ODRHash for FunctionDecl
3800b57cec5SDimitry Andric 
3810b57cec5SDimitry Andric     Inherited::VisitCXXMethodDecl(D);
3820b57cec5SDimitry Andric   }
3830b57cec5SDimitry Andric 
384bdd1243dSDimitry Andric   void VisitObjCMethodDecl(const ObjCMethodDecl *Method) {
385bdd1243dSDimitry Andric     ID.AddInteger(Method->getDeclKind());
386bdd1243dSDimitry Andric     Hash.AddBoolean(Method->isInstanceMethod()); // false if class method
387bdd1243dSDimitry Andric     Hash.AddBoolean(Method->isVariadic());
388bdd1243dSDimitry Andric     Hash.AddBoolean(Method->isSynthesizedAccessorStub());
389bdd1243dSDimitry Andric     Hash.AddBoolean(Method->isDefined());
390bdd1243dSDimitry Andric     Hash.AddBoolean(Method->isDirectMethod());
391bdd1243dSDimitry Andric     Hash.AddBoolean(Method->isThisDeclarationADesignatedInitializer());
392bdd1243dSDimitry Andric     Hash.AddBoolean(Method->hasSkippedBody());
393bdd1243dSDimitry Andric 
3945f757f3fSDimitry Andric     ID.AddInteger(llvm::to_underlying(Method->getImplementationControl()));
395bdd1243dSDimitry Andric     ID.AddInteger(Method->getMethodFamily());
396bdd1243dSDimitry Andric     ImplicitParamDecl *Cmd = Method->getCmdDecl();
397bdd1243dSDimitry Andric     Hash.AddBoolean(Cmd);
398bdd1243dSDimitry Andric     if (Cmd)
3995f757f3fSDimitry Andric       ID.AddInteger(llvm::to_underlying(Cmd->getParameterKind()));
400bdd1243dSDimitry Andric 
401bdd1243dSDimitry Andric     ImplicitParamDecl *Self = Method->getSelfDecl();
402bdd1243dSDimitry Andric     Hash.AddBoolean(Self);
403bdd1243dSDimitry Andric     if (Self)
4045f757f3fSDimitry Andric       ID.AddInteger(llvm::to_underlying(Self->getParameterKind()));
405bdd1243dSDimitry Andric 
406bdd1243dSDimitry Andric     AddDecl(Method);
407bdd1243dSDimitry Andric 
4085f757f3fSDimitry Andric     if (Method->getReturnTypeSourceInfo())
4095f757f3fSDimitry Andric       AddQualType(Method->getReturnTypeSourceInfo()->getType());
4105f757f3fSDimitry Andric 
411bdd1243dSDimitry Andric     ID.AddInteger(Method->param_size());
412bdd1243dSDimitry Andric     for (auto Param : Method->parameters())
413bdd1243dSDimitry Andric       Hash.AddSubDecl(Param);
414bdd1243dSDimitry Andric 
415bdd1243dSDimitry Andric     if (Method->hasBody()) {
416bdd1243dSDimitry Andric       const bool IsDefinition = Method->isThisDeclarationADefinition();
417bdd1243dSDimitry Andric       Hash.AddBoolean(IsDefinition);
418bdd1243dSDimitry Andric       if (IsDefinition) {
419bdd1243dSDimitry Andric         Stmt *Body = Method->getBody();
420bdd1243dSDimitry Andric         Hash.AddBoolean(Body);
421bdd1243dSDimitry Andric         if (Body)
422bdd1243dSDimitry Andric           AddStmt(Body);
423bdd1243dSDimitry Andric 
424bdd1243dSDimitry Andric         // Filter out sub-Decls which will not be processed in order to get an
425bdd1243dSDimitry Andric         // accurate count of Decl's.
426bdd1243dSDimitry Andric         llvm::SmallVector<const Decl *, 16> Decls;
427bdd1243dSDimitry Andric         for (Decl *SubDecl : Method->decls())
428bdd1243dSDimitry Andric           if (ODRHash::isSubDeclToBeProcessed(SubDecl, Method))
429bdd1243dSDimitry Andric             Decls.push_back(SubDecl);
430bdd1243dSDimitry Andric 
431bdd1243dSDimitry Andric         ID.AddInteger(Decls.size());
432bdd1243dSDimitry Andric         for (auto SubDecl : Decls)
433bdd1243dSDimitry Andric           Hash.AddSubDecl(SubDecl);
434bdd1243dSDimitry Andric       }
435bdd1243dSDimitry Andric     } else {
436bdd1243dSDimitry Andric       Hash.AddBoolean(false);
437bdd1243dSDimitry Andric     }
438bdd1243dSDimitry Andric 
439bdd1243dSDimitry Andric     Inherited::VisitObjCMethodDecl(Method);
440bdd1243dSDimitry Andric   }
441bdd1243dSDimitry Andric 
4420b57cec5SDimitry Andric   void VisitTypedefNameDecl(const TypedefNameDecl *D) {
4430b57cec5SDimitry Andric     AddQualType(D->getUnderlyingType());
4440b57cec5SDimitry Andric 
4450b57cec5SDimitry Andric     Inherited::VisitTypedefNameDecl(D);
4460b57cec5SDimitry Andric   }
4470b57cec5SDimitry Andric 
4480b57cec5SDimitry Andric   void VisitTypedefDecl(const TypedefDecl *D) {
4490b57cec5SDimitry Andric     Inherited::VisitTypedefDecl(D);
4500b57cec5SDimitry Andric   }
4510b57cec5SDimitry Andric 
4520b57cec5SDimitry Andric   void VisitTypeAliasDecl(const TypeAliasDecl *D) {
4530b57cec5SDimitry Andric     Inherited::VisitTypeAliasDecl(D);
4540b57cec5SDimitry Andric   }
4550b57cec5SDimitry Andric 
4560b57cec5SDimitry Andric   void VisitFriendDecl(const FriendDecl *D) {
4570b57cec5SDimitry Andric     TypeSourceInfo *TSI = D->getFriendType();
4580b57cec5SDimitry Andric     Hash.AddBoolean(TSI);
4590b57cec5SDimitry Andric     if (TSI) {
4600b57cec5SDimitry Andric       AddQualType(TSI->getType());
4610b57cec5SDimitry Andric     } else {
4620b57cec5SDimitry Andric       AddDecl(D->getFriendDecl());
4630b57cec5SDimitry Andric     }
4640b57cec5SDimitry Andric   }
4650b57cec5SDimitry Andric 
4660b57cec5SDimitry Andric   void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
4670b57cec5SDimitry Andric     // Only care about default arguments as part of the definition.
4680b57cec5SDimitry Andric     const bool hasDefaultArgument =
4690b57cec5SDimitry Andric         D->hasDefaultArgument() && !D->defaultArgumentWasInherited();
4700b57cec5SDimitry Andric     Hash.AddBoolean(hasDefaultArgument);
4710b57cec5SDimitry Andric     if (hasDefaultArgument) {
472*0fca6ea1SDimitry Andric       AddTemplateArgument(D->getDefaultArgument().getArgument());
4730b57cec5SDimitry Andric     }
4740b57cec5SDimitry Andric     Hash.AddBoolean(D->isParameterPack());
4750b57cec5SDimitry Andric 
476480093f4SDimitry Andric     const TypeConstraint *TC = D->getTypeConstraint();
477480093f4SDimitry Andric     Hash.AddBoolean(TC != nullptr);
478480093f4SDimitry Andric     if (TC)
479480093f4SDimitry Andric       AddStmt(TC->getImmediatelyDeclaredConstraint());
480480093f4SDimitry Andric 
4810b57cec5SDimitry Andric     Inherited::VisitTemplateTypeParmDecl(D);
4820b57cec5SDimitry Andric   }
4830b57cec5SDimitry Andric 
4840b57cec5SDimitry Andric   void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
4850b57cec5SDimitry Andric     // Only care about default arguments as part of the definition.
4860b57cec5SDimitry Andric     const bool hasDefaultArgument =
4870b57cec5SDimitry Andric         D->hasDefaultArgument() && !D->defaultArgumentWasInherited();
4880b57cec5SDimitry Andric     Hash.AddBoolean(hasDefaultArgument);
4890b57cec5SDimitry Andric     if (hasDefaultArgument) {
490*0fca6ea1SDimitry Andric       AddTemplateArgument(D->getDefaultArgument().getArgument());
4910b57cec5SDimitry Andric     }
4920b57cec5SDimitry Andric     Hash.AddBoolean(D->isParameterPack());
4930b57cec5SDimitry Andric 
4940b57cec5SDimitry Andric     Inherited::VisitNonTypeTemplateParmDecl(D);
4950b57cec5SDimitry Andric   }
4960b57cec5SDimitry Andric 
4970b57cec5SDimitry Andric   void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D) {
4980b57cec5SDimitry Andric     // Only care about default arguments as part of the definition.
4990b57cec5SDimitry Andric     const bool hasDefaultArgument =
5000b57cec5SDimitry Andric         D->hasDefaultArgument() && !D->defaultArgumentWasInherited();
5010b57cec5SDimitry Andric     Hash.AddBoolean(hasDefaultArgument);
5020b57cec5SDimitry Andric     if (hasDefaultArgument) {
5030b57cec5SDimitry Andric       AddTemplateArgument(D->getDefaultArgument().getArgument());
5040b57cec5SDimitry Andric     }
5050b57cec5SDimitry Andric     Hash.AddBoolean(D->isParameterPack());
5060b57cec5SDimitry Andric 
5070b57cec5SDimitry Andric     Inherited::VisitTemplateTemplateParmDecl(D);
5080b57cec5SDimitry Andric   }
5090b57cec5SDimitry Andric 
5100b57cec5SDimitry Andric   void VisitTemplateDecl(const TemplateDecl *D) {
5110b57cec5SDimitry Andric     Hash.AddTemplateParameterList(D->getTemplateParameters());
5120b57cec5SDimitry Andric 
5130b57cec5SDimitry Andric     Inherited::VisitTemplateDecl(D);
5140b57cec5SDimitry Andric   }
5150b57cec5SDimitry Andric 
5160b57cec5SDimitry Andric   void VisitRedeclarableTemplateDecl(const RedeclarableTemplateDecl *D) {
5170b57cec5SDimitry Andric     Hash.AddBoolean(D->isMemberSpecialization());
5180b57cec5SDimitry Andric     Inherited::VisitRedeclarableTemplateDecl(D);
5190b57cec5SDimitry Andric   }
5200b57cec5SDimitry Andric 
5210b57cec5SDimitry Andric   void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
5220b57cec5SDimitry Andric     AddDecl(D->getTemplatedDecl());
5230b57cec5SDimitry Andric     ID.AddInteger(D->getTemplatedDecl()->getODRHash());
5240b57cec5SDimitry Andric     Inherited::VisitFunctionTemplateDecl(D);
5250b57cec5SDimitry Andric   }
5260b57cec5SDimitry Andric 
5270b57cec5SDimitry Andric   void VisitEnumConstantDecl(const EnumConstantDecl *D) {
5280b57cec5SDimitry Andric     AddStmt(D->getInitExpr());
5290b57cec5SDimitry Andric     Inherited::VisitEnumConstantDecl(D);
5300b57cec5SDimitry Andric   }
5310b57cec5SDimitry Andric };
5320b57cec5SDimitry Andric } // namespace
5330b57cec5SDimitry Andric 
5340b57cec5SDimitry Andric // Only allow a small portion of Decl's to be processed.  Remove this once
5350b57cec5SDimitry Andric // all Decl's can be handled.
536bdd1243dSDimitry Andric bool ODRHash::isSubDeclToBeProcessed(const Decl *D, const DeclContext *Parent) {
5370b57cec5SDimitry Andric   if (D->isImplicit()) return false;
5380b57cec5SDimitry Andric   if (D->getDeclContext() != Parent) return false;
5390b57cec5SDimitry Andric 
5400b57cec5SDimitry Andric   switch (D->getKind()) {
5410b57cec5SDimitry Andric     default:
5420b57cec5SDimitry Andric       return false;
5430b57cec5SDimitry Andric     case Decl::AccessSpec:
5440b57cec5SDimitry Andric     case Decl::CXXConstructor:
5450b57cec5SDimitry Andric     case Decl::CXXDestructor:
5460b57cec5SDimitry Andric     case Decl::CXXMethod:
5470b57cec5SDimitry Andric     case Decl::EnumConstant: // Only found in EnumDecl's.
5480b57cec5SDimitry Andric     case Decl::Field:
5490b57cec5SDimitry Andric     case Decl::Friend:
5500b57cec5SDimitry Andric     case Decl::FunctionTemplate:
5510b57cec5SDimitry Andric     case Decl::StaticAssert:
5520b57cec5SDimitry Andric     case Decl::TypeAlias:
5530b57cec5SDimitry Andric     case Decl::Typedef:
5540b57cec5SDimitry Andric     case Decl::Var:
555bdd1243dSDimitry Andric     case Decl::ObjCMethod:
556bdd1243dSDimitry Andric     case Decl::ObjCIvar:
557bdd1243dSDimitry Andric     case Decl::ObjCProperty:
5580b57cec5SDimitry Andric       return true;
5590b57cec5SDimitry Andric   }
5600b57cec5SDimitry Andric }
5610b57cec5SDimitry Andric 
5620b57cec5SDimitry Andric void ODRHash::AddSubDecl(const Decl *D) {
5630b57cec5SDimitry Andric   assert(D && "Expecting non-null pointer.");
5640b57cec5SDimitry Andric 
5650b57cec5SDimitry Andric   ODRDeclVisitor(ID, *this).Visit(D);
5660b57cec5SDimitry Andric }
5670b57cec5SDimitry Andric 
5680b57cec5SDimitry Andric void ODRHash::AddCXXRecordDecl(const CXXRecordDecl *Record) {
5690b57cec5SDimitry Andric   assert(Record && Record->hasDefinition() &&
5700b57cec5SDimitry Andric          "Expected non-null record to be a definition.");
5710b57cec5SDimitry Andric 
5720b57cec5SDimitry Andric   const DeclContext *DC = Record;
5730b57cec5SDimitry Andric   while (DC) {
5740b57cec5SDimitry Andric     if (isa<ClassTemplateSpecializationDecl>(DC)) {
5750b57cec5SDimitry Andric       return;
5760b57cec5SDimitry Andric     }
5770b57cec5SDimitry Andric     DC = DC->getParent();
5780b57cec5SDimitry Andric   }
5790b57cec5SDimitry Andric 
5800b57cec5SDimitry Andric   AddDecl(Record);
5810b57cec5SDimitry Andric 
5820b57cec5SDimitry Andric   // Filter out sub-Decls which will not be processed in order to get an
5830b57cec5SDimitry Andric   // accurate count of Decl's.
5840b57cec5SDimitry Andric   llvm::SmallVector<const Decl *, 16> Decls;
5850b57cec5SDimitry Andric   for (Decl *SubDecl : Record->decls()) {
586bdd1243dSDimitry Andric     if (isSubDeclToBeProcessed(SubDecl, Record)) {
5870b57cec5SDimitry Andric       Decls.push_back(SubDecl);
5880b57cec5SDimitry Andric       if (auto *Function = dyn_cast<FunctionDecl>(SubDecl)) {
5890b57cec5SDimitry Andric         // Compute/Preload ODRHash into FunctionDecl.
5900b57cec5SDimitry Andric         Function->getODRHash();
5910b57cec5SDimitry Andric       }
5920b57cec5SDimitry Andric     }
5930b57cec5SDimitry Andric   }
5940b57cec5SDimitry Andric 
5950b57cec5SDimitry Andric   ID.AddInteger(Decls.size());
5960b57cec5SDimitry Andric   for (auto SubDecl : Decls) {
5970b57cec5SDimitry Andric     AddSubDecl(SubDecl);
5980b57cec5SDimitry Andric   }
5990b57cec5SDimitry Andric 
6000b57cec5SDimitry Andric   const ClassTemplateDecl *TD = Record->getDescribedClassTemplate();
6010b57cec5SDimitry Andric   AddBoolean(TD);
6020b57cec5SDimitry Andric   if (TD) {
6030b57cec5SDimitry Andric     AddTemplateParameterList(TD->getTemplateParameters());
6040b57cec5SDimitry Andric   }
6050b57cec5SDimitry Andric 
6060b57cec5SDimitry Andric   ID.AddInteger(Record->getNumBases());
6070b57cec5SDimitry Andric   auto Bases = Record->bases();
60806c3fb27SDimitry Andric   for (const auto &Base : Bases) {
6095f757f3fSDimitry Andric     AddQualType(Base.getTypeSourceInfo()->getType());
6100b57cec5SDimitry Andric     ID.AddInteger(Base.isVirtual());
6110b57cec5SDimitry Andric     ID.AddInteger(Base.getAccessSpecifierAsWritten());
6120b57cec5SDimitry Andric   }
6130b57cec5SDimitry Andric }
6140b57cec5SDimitry Andric 
615bdd1243dSDimitry Andric void ODRHash::AddRecordDecl(const RecordDecl *Record) {
616bdd1243dSDimitry Andric   assert(!isa<CXXRecordDecl>(Record) &&
617bdd1243dSDimitry Andric          "For CXXRecordDecl should call AddCXXRecordDecl.");
618bdd1243dSDimitry Andric   AddDecl(Record);
619bdd1243dSDimitry Andric 
620bdd1243dSDimitry Andric   // Filter out sub-Decls which will not be processed in order to get an
621bdd1243dSDimitry Andric   // accurate count of Decl's.
622bdd1243dSDimitry Andric   llvm::SmallVector<const Decl *, 16> Decls;
623bdd1243dSDimitry Andric   for (Decl *SubDecl : Record->decls()) {
624bdd1243dSDimitry Andric     if (isSubDeclToBeProcessed(SubDecl, Record))
625bdd1243dSDimitry Andric       Decls.push_back(SubDecl);
626bdd1243dSDimitry Andric   }
627bdd1243dSDimitry Andric 
628bdd1243dSDimitry Andric   ID.AddInteger(Decls.size());
629bdd1243dSDimitry Andric   for (const Decl *SubDecl : Decls)
630bdd1243dSDimitry Andric     AddSubDecl(SubDecl);
631bdd1243dSDimitry Andric }
632bdd1243dSDimitry Andric 
633bdd1243dSDimitry Andric void ODRHash::AddObjCInterfaceDecl(const ObjCInterfaceDecl *IF) {
634bdd1243dSDimitry Andric   AddDecl(IF);
635bdd1243dSDimitry Andric 
636bdd1243dSDimitry Andric   auto *SuperClass = IF->getSuperClass();
637bdd1243dSDimitry Andric   AddBoolean(SuperClass);
638bdd1243dSDimitry Andric   if (SuperClass)
639bdd1243dSDimitry Andric     ID.AddInteger(SuperClass->getODRHash());
640bdd1243dSDimitry Andric 
641bdd1243dSDimitry Andric   // Hash referenced protocols.
642bdd1243dSDimitry Andric   ID.AddInteger(IF->getReferencedProtocols().size());
643bdd1243dSDimitry Andric   for (const ObjCProtocolDecl *RefP : IF->protocols()) {
644bdd1243dSDimitry Andric     // Hash the name only as a referenced protocol can be a forward declaration.
645bdd1243dSDimitry Andric     AddDeclarationName(RefP->getDeclName());
646bdd1243dSDimitry Andric   }
647bdd1243dSDimitry Andric 
648bdd1243dSDimitry Andric   // Filter out sub-Decls which will not be processed in order to get an
649bdd1243dSDimitry Andric   // accurate count of Decl's.
650bdd1243dSDimitry Andric   llvm::SmallVector<const Decl *, 16> Decls;
651bdd1243dSDimitry Andric   for (Decl *SubDecl : IF->decls())
652bdd1243dSDimitry Andric     if (isSubDeclToBeProcessed(SubDecl, IF))
653bdd1243dSDimitry Andric       Decls.push_back(SubDecl);
654bdd1243dSDimitry Andric 
655bdd1243dSDimitry Andric   ID.AddInteger(Decls.size());
656bdd1243dSDimitry Andric   for (auto *SubDecl : Decls)
657bdd1243dSDimitry Andric     AddSubDecl(SubDecl);
658bdd1243dSDimitry Andric }
659bdd1243dSDimitry Andric 
6600b57cec5SDimitry Andric void ODRHash::AddFunctionDecl(const FunctionDecl *Function,
6610b57cec5SDimitry Andric                               bool SkipBody) {
6620b57cec5SDimitry Andric   assert(Function && "Expecting non-null pointer.");
6630b57cec5SDimitry Andric 
6640b57cec5SDimitry Andric   // Skip functions that are specializations or in specialization context.
6650b57cec5SDimitry Andric   const DeclContext *DC = Function;
6660b57cec5SDimitry Andric   while (DC) {
6670b57cec5SDimitry Andric     if (isa<ClassTemplateSpecializationDecl>(DC)) return;
6680b57cec5SDimitry Andric     if (auto *F = dyn_cast<FunctionDecl>(DC)) {
6690b57cec5SDimitry Andric       if (F->isFunctionTemplateSpecialization()) {
6700b57cec5SDimitry Andric         if (!isa<CXXMethodDecl>(DC)) return;
6710b57cec5SDimitry Andric         if (DC->getLexicalParent()->isFileContext()) return;
6725f757f3fSDimitry Andric         // Skip class scope explicit function template specializations,
6735f757f3fSDimitry Andric         // as they have not yet been instantiated.
6745f757f3fSDimitry Andric         if (F->getDependentSpecializationInfo())
6755f757f3fSDimitry Andric           return;
6760b57cec5SDimitry Andric         // Inline method specializations are the only supported
6770b57cec5SDimitry Andric         // specialization for now.
6780b57cec5SDimitry Andric       }
6790b57cec5SDimitry Andric     }
6800b57cec5SDimitry Andric     DC = DC->getParent();
6810b57cec5SDimitry Andric   }
6820b57cec5SDimitry Andric 
6830b57cec5SDimitry Andric   ID.AddInteger(Function->getDeclKind());
6840b57cec5SDimitry Andric 
6850b57cec5SDimitry Andric   const auto *SpecializationArgs = Function->getTemplateSpecializationArgs();
6860b57cec5SDimitry Andric   AddBoolean(SpecializationArgs);
6870b57cec5SDimitry Andric   if (SpecializationArgs) {
6880b57cec5SDimitry Andric     ID.AddInteger(SpecializationArgs->size());
6890b57cec5SDimitry Andric     for (const TemplateArgument &TA : SpecializationArgs->asArray()) {
6900b57cec5SDimitry Andric       AddTemplateArgument(TA);
6910b57cec5SDimitry Andric     }
6920b57cec5SDimitry Andric   }
6930b57cec5SDimitry Andric 
6940b57cec5SDimitry Andric   if (const auto *Method = dyn_cast<CXXMethodDecl>(Function)) {
6950b57cec5SDimitry Andric     AddBoolean(Method->isConst());
6960b57cec5SDimitry Andric     AddBoolean(Method->isVolatile());
6970b57cec5SDimitry Andric   }
6980b57cec5SDimitry Andric 
6990b57cec5SDimitry Andric   ID.AddInteger(Function->getStorageClass());
7000b57cec5SDimitry Andric   AddBoolean(Function->isInlineSpecified());
7010b57cec5SDimitry Andric   AddBoolean(Function->isVirtualAsWritten());
7027a6dacacSDimitry Andric   AddBoolean(Function->isPureVirtual());
7030b57cec5SDimitry Andric   AddBoolean(Function->isDeletedAsWritten());
7040b57cec5SDimitry Andric   AddBoolean(Function->isExplicitlyDefaulted());
7050b57cec5SDimitry Andric 
706*0fca6ea1SDimitry Andric   StringLiteral *DeletedMessage = Function->getDeletedMessage();
707*0fca6ea1SDimitry Andric   AddBoolean(DeletedMessage);
708*0fca6ea1SDimitry Andric 
709*0fca6ea1SDimitry Andric   if (DeletedMessage)
710*0fca6ea1SDimitry Andric     ID.AddString(DeletedMessage->getBytes());
711*0fca6ea1SDimitry Andric 
7120b57cec5SDimitry Andric   AddDecl(Function);
7130b57cec5SDimitry Andric 
7140b57cec5SDimitry Andric   AddQualType(Function->getReturnType());
7150b57cec5SDimitry Andric 
7160b57cec5SDimitry Andric   ID.AddInteger(Function->param_size());
717bdd1243dSDimitry Andric   for (auto *Param : Function->parameters())
7180b57cec5SDimitry Andric     AddSubDecl(Param);
7190b57cec5SDimitry Andric 
7200b57cec5SDimitry Andric   if (SkipBody) {
7210b57cec5SDimitry Andric     AddBoolean(false);
7220b57cec5SDimitry Andric     return;
7230b57cec5SDimitry Andric   }
7240b57cec5SDimitry Andric 
7250b57cec5SDimitry Andric   const bool HasBody = Function->isThisDeclarationADefinition() &&
7260b57cec5SDimitry Andric                        !Function->isDefaulted() && !Function->isDeleted() &&
7270b57cec5SDimitry Andric                        !Function->isLateTemplateParsed();
7280b57cec5SDimitry Andric   AddBoolean(HasBody);
7290b57cec5SDimitry Andric   if (!HasBody) {
7300b57cec5SDimitry Andric     return;
7310b57cec5SDimitry Andric   }
7320b57cec5SDimitry Andric 
7330b57cec5SDimitry Andric   auto *Body = Function->getBody();
7340b57cec5SDimitry Andric   AddBoolean(Body);
7350b57cec5SDimitry Andric   if (Body)
7360b57cec5SDimitry Andric     AddStmt(Body);
7370b57cec5SDimitry Andric 
7380b57cec5SDimitry Andric   // Filter out sub-Decls which will not be processed in order to get an
7390b57cec5SDimitry Andric   // accurate count of Decl's.
7400b57cec5SDimitry Andric   llvm::SmallVector<const Decl *, 16> Decls;
7410b57cec5SDimitry Andric   for (Decl *SubDecl : Function->decls()) {
742bdd1243dSDimitry Andric     if (isSubDeclToBeProcessed(SubDecl, Function)) {
7430b57cec5SDimitry Andric       Decls.push_back(SubDecl);
7440b57cec5SDimitry Andric     }
7450b57cec5SDimitry Andric   }
7460b57cec5SDimitry Andric 
7470b57cec5SDimitry Andric   ID.AddInteger(Decls.size());
7480b57cec5SDimitry Andric   for (auto SubDecl : Decls) {
7490b57cec5SDimitry Andric     AddSubDecl(SubDecl);
7500b57cec5SDimitry Andric   }
7510b57cec5SDimitry Andric }
7520b57cec5SDimitry Andric 
7530b57cec5SDimitry Andric void ODRHash::AddEnumDecl(const EnumDecl *Enum) {
7540b57cec5SDimitry Andric   assert(Enum);
7550b57cec5SDimitry Andric   AddDeclarationName(Enum->getDeclName());
7560b57cec5SDimitry Andric 
7570b57cec5SDimitry Andric   AddBoolean(Enum->isScoped());
7580b57cec5SDimitry Andric   if (Enum->isScoped())
7590b57cec5SDimitry Andric     AddBoolean(Enum->isScopedUsingClassTag());
7600b57cec5SDimitry Andric 
761b3edf446SDimitry Andric   if (Enum->getIntegerTypeSourceInfo())
7627a6dacacSDimitry Andric     AddQualType(Enum->getIntegerType().getCanonicalType());
7630b57cec5SDimitry Andric 
7640b57cec5SDimitry Andric   // Filter out sub-Decls which will not be processed in order to get an
7650b57cec5SDimitry Andric   // accurate count of Decl's.
7660b57cec5SDimitry Andric   llvm::SmallVector<const Decl *, 16> Decls;
7670b57cec5SDimitry Andric   for (Decl *SubDecl : Enum->decls()) {
768bdd1243dSDimitry Andric     if (isSubDeclToBeProcessed(SubDecl, Enum)) {
7690b57cec5SDimitry Andric       assert(isa<EnumConstantDecl>(SubDecl) && "Unexpected Decl");
7700b57cec5SDimitry Andric       Decls.push_back(SubDecl);
7710b57cec5SDimitry Andric     }
7720b57cec5SDimitry Andric   }
7730b57cec5SDimitry Andric 
7740b57cec5SDimitry Andric   ID.AddInteger(Decls.size());
7750b57cec5SDimitry Andric   for (auto SubDecl : Decls) {
7760b57cec5SDimitry Andric     AddSubDecl(SubDecl);
7770b57cec5SDimitry Andric   }
7780b57cec5SDimitry Andric 
7790b57cec5SDimitry Andric }
7800b57cec5SDimitry Andric 
781bdd1243dSDimitry Andric void ODRHash::AddObjCProtocolDecl(const ObjCProtocolDecl *P) {
782bdd1243dSDimitry Andric   AddDecl(P);
783bdd1243dSDimitry Andric 
784bdd1243dSDimitry Andric   // Hash referenced protocols.
785bdd1243dSDimitry Andric   ID.AddInteger(P->getReferencedProtocols().size());
786bdd1243dSDimitry Andric   for (const ObjCProtocolDecl *RefP : P->protocols()) {
787bdd1243dSDimitry Andric     // Hash the name only as a referenced protocol can be a forward declaration.
788bdd1243dSDimitry Andric     AddDeclarationName(RefP->getDeclName());
789bdd1243dSDimitry Andric   }
790bdd1243dSDimitry Andric 
791bdd1243dSDimitry Andric   // Filter out sub-Decls which will not be processed in order to get an
792bdd1243dSDimitry Andric   // accurate count of Decl's.
793bdd1243dSDimitry Andric   llvm::SmallVector<const Decl *, 16> Decls;
794bdd1243dSDimitry Andric   for (Decl *SubDecl : P->decls()) {
795bdd1243dSDimitry Andric     if (isSubDeclToBeProcessed(SubDecl, P)) {
796bdd1243dSDimitry Andric       Decls.push_back(SubDecl);
797bdd1243dSDimitry Andric     }
798bdd1243dSDimitry Andric   }
799bdd1243dSDimitry Andric 
800bdd1243dSDimitry Andric   ID.AddInteger(Decls.size());
801bdd1243dSDimitry Andric   for (auto *SubDecl : Decls) {
802bdd1243dSDimitry Andric     AddSubDecl(SubDecl);
803bdd1243dSDimitry Andric   }
804bdd1243dSDimitry Andric }
805bdd1243dSDimitry Andric 
8060b57cec5SDimitry Andric void ODRHash::AddDecl(const Decl *D) {
8070b57cec5SDimitry Andric   assert(D && "Expecting non-null pointer.");
8080b57cec5SDimitry Andric   D = D->getCanonicalDecl();
8090b57cec5SDimitry Andric 
8100b57cec5SDimitry Andric   const NamedDecl *ND = dyn_cast<NamedDecl>(D);
8110b57cec5SDimitry Andric   AddBoolean(ND);
8120b57cec5SDimitry Andric   if (!ND) {
8130b57cec5SDimitry Andric     ID.AddInteger(D->getKind());
8140b57cec5SDimitry Andric     return;
8150b57cec5SDimitry Andric   }
8160b57cec5SDimitry Andric 
8170b57cec5SDimitry Andric   AddDeclarationName(ND->getDeclName());
8180b57cec5SDimitry Andric 
8190b57cec5SDimitry Andric   const auto *Specialization =
8200b57cec5SDimitry Andric             dyn_cast<ClassTemplateSpecializationDecl>(D);
8210b57cec5SDimitry Andric   AddBoolean(Specialization);
8220b57cec5SDimitry Andric   if (Specialization) {
8230b57cec5SDimitry Andric     const TemplateArgumentList &List = Specialization->getTemplateArgs();
8240b57cec5SDimitry Andric     ID.AddInteger(List.size());
8250b57cec5SDimitry Andric     for (const TemplateArgument &TA : List.asArray())
8260b57cec5SDimitry Andric       AddTemplateArgument(TA);
8270b57cec5SDimitry Andric   }
8280b57cec5SDimitry Andric }
8290b57cec5SDimitry Andric 
8300b57cec5SDimitry Andric namespace {
8310b57cec5SDimitry Andric // Process a Type pointer.  Add* methods call back into ODRHash while Visit*
8320b57cec5SDimitry Andric // methods process the relevant parts of the Type.
8330b57cec5SDimitry Andric class ODRTypeVisitor : public TypeVisitor<ODRTypeVisitor> {
8340b57cec5SDimitry Andric   typedef TypeVisitor<ODRTypeVisitor> Inherited;
8350b57cec5SDimitry Andric   llvm::FoldingSetNodeID &ID;
8360b57cec5SDimitry Andric   ODRHash &Hash;
8370b57cec5SDimitry Andric 
8380b57cec5SDimitry Andric public:
8390b57cec5SDimitry Andric   ODRTypeVisitor(llvm::FoldingSetNodeID &ID, ODRHash &Hash)
8400b57cec5SDimitry Andric       : ID(ID), Hash(Hash) {}
8410b57cec5SDimitry Andric 
8420b57cec5SDimitry Andric   void AddStmt(Stmt *S) {
8430b57cec5SDimitry Andric     Hash.AddBoolean(S);
8440b57cec5SDimitry Andric     if (S) {
8450b57cec5SDimitry Andric       Hash.AddStmt(S);
8460b57cec5SDimitry Andric     }
8470b57cec5SDimitry Andric   }
8480b57cec5SDimitry Andric 
849bdd1243dSDimitry Andric   void AddDecl(const Decl *D) {
8500b57cec5SDimitry Andric     Hash.AddBoolean(D);
8510b57cec5SDimitry Andric     if (D) {
8520b57cec5SDimitry Andric       Hash.AddDecl(D);
8530b57cec5SDimitry Andric     }
8540b57cec5SDimitry Andric   }
8550b57cec5SDimitry Andric 
8560b57cec5SDimitry Andric   void AddQualType(QualType T) {
8570b57cec5SDimitry Andric     Hash.AddQualType(T);
8580b57cec5SDimitry Andric   }
8590b57cec5SDimitry Andric 
8600b57cec5SDimitry Andric   void AddType(const Type *T) {
8610b57cec5SDimitry Andric     Hash.AddBoolean(T);
8620b57cec5SDimitry Andric     if (T) {
8630b57cec5SDimitry Andric       Hash.AddType(T);
8640b57cec5SDimitry Andric     }
8650b57cec5SDimitry Andric   }
8660b57cec5SDimitry Andric 
8670b57cec5SDimitry Andric   void AddNestedNameSpecifier(const NestedNameSpecifier *NNS) {
8680b57cec5SDimitry Andric     Hash.AddBoolean(NNS);
8690b57cec5SDimitry Andric     if (NNS) {
8700b57cec5SDimitry Andric       Hash.AddNestedNameSpecifier(NNS);
8710b57cec5SDimitry Andric     }
8720b57cec5SDimitry Andric   }
8730b57cec5SDimitry Andric 
8740b57cec5SDimitry Andric   void AddIdentifierInfo(const IdentifierInfo *II) {
8750b57cec5SDimitry Andric     Hash.AddBoolean(II);
8760b57cec5SDimitry Andric     if (II) {
8770b57cec5SDimitry Andric       Hash.AddIdentifierInfo(II);
8780b57cec5SDimitry Andric     }
8790b57cec5SDimitry Andric   }
8800b57cec5SDimitry Andric 
8810b57cec5SDimitry Andric   void VisitQualifiers(Qualifiers Quals) {
8820b57cec5SDimitry Andric     ID.AddInteger(Quals.getAsOpaqueValue());
8830b57cec5SDimitry Andric   }
8840b57cec5SDimitry Andric 
8850b57cec5SDimitry Andric   // Return the RecordType if the typedef only strips away a keyword.
8860b57cec5SDimitry Andric   // Otherwise, return the original type.
8870b57cec5SDimitry Andric   static const Type *RemoveTypedef(const Type *T) {
8880b57cec5SDimitry Andric     const auto *TypedefT = dyn_cast<TypedefType>(T);
8890b57cec5SDimitry Andric     if (!TypedefT) {
8900b57cec5SDimitry Andric       return T;
8910b57cec5SDimitry Andric     }
8920b57cec5SDimitry Andric 
8930b57cec5SDimitry Andric     const TypedefNameDecl *D = TypedefT->getDecl();
8940b57cec5SDimitry Andric     QualType UnderlyingType = D->getUnderlyingType();
8950b57cec5SDimitry Andric 
8960b57cec5SDimitry Andric     if (UnderlyingType.hasLocalQualifiers()) {
8970b57cec5SDimitry Andric       return T;
8980b57cec5SDimitry Andric     }
8990b57cec5SDimitry Andric 
9000b57cec5SDimitry Andric     const auto *ElaboratedT = dyn_cast<ElaboratedType>(UnderlyingType);
9010b57cec5SDimitry Andric     if (!ElaboratedT) {
9020b57cec5SDimitry Andric       return T;
9030b57cec5SDimitry Andric     }
9040b57cec5SDimitry Andric 
9050b57cec5SDimitry Andric     if (ElaboratedT->getQualifier() != nullptr) {
9060b57cec5SDimitry Andric       return T;
9070b57cec5SDimitry Andric     }
9080b57cec5SDimitry Andric 
9090b57cec5SDimitry Andric     QualType NamedType = ElaboratedT->getNamedType();
9100b57cec5SDimitry Andric     if (NamedType.hasLocalQualifiers()) {
9110b57cec5SDimitry Andric       return T;
9120b57cec5SDimitry Andric     }
9130b57cec5SDimitry Andric 
9140b57cec5SDimitry Andric     const auto *RecordT = dyn_cast<RecordType>(NamedType);
9150b57cec5SDimitry Andric     if (!RecordT) {
9160b57cec5SDimitry Andric       return T;
9170b57cec5SDimitry Andric     }
9180b57cec5SDimitry Andric 
9190b57cec5SDimitry Andric     const IdentifierInfo *TypedefII = TypedefT->getDecl()->getIdentifier();
9200b57cec5SDimitry Andric     const IdentifierInfo *RecordII = RecordT->getDecl()->getIdentifier();
9210b57cec5SDimitry Andric     if (!TypedefII || !RecordII ||
9220b57cec5SDimitry Andric         TypedefII->getName() != RecordII->getName()) {
9230b57cec5SDimitry Andric       return T;
9240b57cec5SDimitry Andric     }
9250b57cec5SDimitry Andric 
9260b57cec5SDimitry Andric     return RecordT;
9270b57cec5SDimitry Andric   }
9280b57cec5SDimitry Andric 
9290b57cec5SDimitry Andric   void Visit(const Type *T) {
9300b57cec5SDimitry Andric     T = RemoveTypedef(T);
9310b57cec5SDimitry Andric     ID.AddInteger(T->getTypeClass());
9320b57cec5SDimitry Andric     Inherited::Visit(T);
9330b57cec5SDimitry Andric   }
9340b57cec5SDimitry Andric 
9350b57cec5SDimitry Andric   void VisitType(const Type *T) {}
9360b57cec5SDimitry Andric 
9370b57cec5SDimitry Andric   void VisitAdjustedType(const AdjustedType *T) {
9385f757f3fSDimitry Andric     AddQualType(T->getOriginalType());
9390b57cec5SDimitry Andric 
9400b57cec5SDimitry Andric     VisitType(T);
9410b57cec5SDimitry Andric   }
9420b57cec5SDimitry Andric 
9430b57cec5SDimitry Andric   void VisitDecayedType(const DecayedType *T) {
9440b57cec5SDimitry Andric     // getDecayedType and getPointeeType are derived from getAdjustedType
9450b57cec5SDimitry Andric     // and don't need to be separately processed.
9460b57cec5SDimitry Andric     VisitAdjustedType(T);
9470b57cec5SDimitry Andric   }
9480b57cec5SDimitry Andric 
9490b57cec5SDimitry Andric   void VisitArrayType(const ArrayType *T) {
9500b57cec5SDimitry Andric     AddQualType(T->getElementType());
9515f757f3fSDimitry Andric     ID.AddInteger(llvm::to_underlying(T->getSizeModifier()));
9520b57cec5SDimitry Andric     VisitQualifiers(T->getIndexTypeQualifiers());
9530b57cec5SDimitry Andric     VisitType(T);
9540b57cec5SDimitry Andric   }
9550b57cec5SDimitry Andric   void VisitConstantArrayType(const ConstantArrayType *T) {
9560b57cec5SDimitry Andric     T->getSize().Profile(ID);
9570b57cec5SDimitry Andric     VisitArrayType(T);
9580b57cec5SDimitry Andric   }
9590b57cec5SDimitry Andric 
960*0fca6ea1SDimitry Andric   void VisitArrayParameterType(const ArrayParameterType *T) {
961*0fca6ea1SDimitry Andric     VisitConstantArrayType(T);
962*0fca6ea1SDimitry Andric   }
963*0fca6ea1SDimitry Andric 
9640b57cec5SDimitry Andric   void VisitDependentSizedArrayType(const DependentSizedArrayType *T) {
9650b57cec5SDimitry Andric     AddStmt(T->getSizeExpr());
9660b57cec5SDimitry Andric     VisitArrayType(T);
9670b57cec5SDimitry Andric   }
9680b57cec5SDimitry Andric 
9690b57cec5SDimitry Andric   void VisitIncompleteArrayType(const IncompleteArrayType *T) {
9700b57cec5SDimitry Andric     VisitArrayType(T);
9710b57cec5SDimitry Andric   }
9720b57cec5SDimitry Andric 
9730b57cec5SDimitry Andric   void VisitVariableArrayType(const VariableArrayType *T) {
9740b57cec5SDimitry Andric     AddStmt(T->getSizeExpr());
9750b57cec5SDimitry Andric     VisitArrayType(T);
9760b57cec5SDimitry Andric   }
9770b57cec5SDimitry Andric 
9780b57cec5SDimitry Andric   void VisitAttributedType(const AttributedType *T) {
9790b57cec5SDimitry Andric     ID.AddInteger(T->getAttrKind());
9800b57cec5SDimitry Andric     AddQualType(T->getModifiedType());
9810b57cec5SDimitry Andric 
9820b57cec5SDimitry Andric     VisitType(T);
9830b57cec5SDimitry Andric   }
9840b57cec5SDimitry Andric 
9850b57cec5SDimitry Andric   void VisitBlockPointerType(const BlockPointerType *T) {
9860b57cec5SDimitry Andric     AddQualType(T->getPointeeType());
9870b57cec5SDimitry Andric     VisitType(T);
9880b57cec5SDimitry Andric   }
9890b57cec5SDimitry Andric 
9900b57cec5SDimitry Andric   void VisitBuiltinType(const BuiltinType *T) {
9910b57cec5SDimitry Andric     ID.AddInteger(T->getKind());
9920b57cec5SDimitry Andric     VisitType(T);
9930b57cec5SDimitry Andric   }
9940b57cec5SDimitry Andric 
9950b57cec5SDimitry Andric   void VisitComplexType(const ComplexType *T) {
9960b57cec5SDimitry Andric     AddQualType(T->getElementType());
9970b57cec5SDimitry Andric     VisitType(T);
9980b57cec5SDimitry Andric   }
9990b57cec5SDimitry Andric 
10000b57cec5SDimitry Andric   void VisitDecltypeType(const DecltypeType *T) {
10010b57cec5SDimitry Andric     AddStmt(T->getUnderlyingExpr());
10020b57cec5SDimitry Andric     VisitType(T);
10030b57cec5SDimitry Andric   }
10040b57cec5SDimitry Andric 
10050b57cec5SDimitry Andric   void VisitDependentDecltypeType(const DependentDecltypeType *T) {
10060b57cec5SDimitry Andric     VisitDecltypeType(T);
10070b57cec5SDimitry Andric   }
10080b57cec5SDimitry Andric 
10090b57cec5SDimitry Andric   void VisitDeducedType(const DeducedType *T) {
10100b57cec5SDimitry Andric     AddQualType(T->getDeducedType());
10110b57cec5SDimitry Andric     VisitType(T);
10120b57cec5SDimitry Andric   }
10130b57cec5SDimitry Andric 
10140b57cec5SDimitry Andric   void VisitAutoType(const AutoType *T) {
10150b57cec5SDimitry Andric     ID.AddInteger((unsigned)T->getKeyword());
101655e4f9d5SDimitry Andric     ID.AddInteger(T->isConstrained());
101755e4f9d5SDimitry Andric     if (T->isConstrained()) {
101855e4f9d5SDimitry Andric       AddDecl(T->getTypeConstraintConcept());
1019bdd1243dSDimitry Andric       ID.AddInteger(T->getTypeConstraintArguments().size());
102055e4f9d5SDimitry Andric       for (const auto &TA : T->getTypeConstraintArguments())
102155e4f9d5SDimitry Andric         Hash.AddTemplateArgument(TA);
102255e4f9d5SDimitry Andric     }
10230b57cec5SDimitry Andric     VisitDeducedType(T);
10240b57cec5SDimitry Andric   }
10250b57cec5SDimitry Andric 
10260b57cec5SDimitry Andric   void VisitDeducedTemplateSpecializationType(
10270b57cec5SDimitry Andric       const DeducedTemplateSpecializationType *T) {
10280b57cec5SDimitry Andric     Hash.AddTemplateName(T->getTemplateName());
10290b57cec5SDimitry Andric     VisitDeducedType(T);
10300b57cec5SDimitry Andric   }
10310b57cec5SDimitry Andric 
10320b57cec5SDimitry Andric   void VisitDependentAddressSpaceType(const DependentAddressSpaceType *T) {
10330b57cec5SDimitry Andric     AddQualType(T->getPointeeType());
10340b57cec5SDimitry Andric     AddStmt(T->getAddrSpaceExpr());
10350b57cec5SDimitry Andric     VisitType(T);
10360b57cec5SDimitry Andric   }
10370b57cec5SDimitry Andric 
10380b57cec5SDimitry Andric   void VisitDependentSizedExtVectorType(const DependentSizedExtVectorType *T) {
10390b57cec5SDimitry Andric     AddQualType(T->getElementType());
10400b57cec5SDimitry Andric     AddStmt(T->getSizeExpr());
10410b57cec5SDimitry Andric     VisitType(T);
10420b57cec5SDimitry Andric   }
10430b57cec5SDimitry Andric 
10440b57cec5SDimitry Andric   void VisitFunctionType(const FunctionType *T) {
10450b57cec5SDimitry Andric     AddQualType(T->getReturnType());
10460b57cec5SDimitry Andric     T->getExtInfo().Profile(ID);
10470b57cec5SDimitry Andric     Hash.AddBoolean(T->isConst());
10480b57cec5SDimitry Andric     Hash.AddBoolean(T->isVolatile());
10490b57cec5SDimitry Andric     Hash.AddBoolean(T->isRestrict());
10500b57cec5SDimitry Andric     VisitType(T);
10510b57cec5SDimitry Andric   }
10520b57cec5SDimitry Andric 
10530b57cec5SDimitry Andric   void VisitFunctionNoProtoType(const FunctionNoProtoType *T) {
10540b57cec5SDimitry Andric     VisitFunctionType(T);
10550b57cec5SDimitry Andric   }
10560b57cec5SDimitry Andric 
10570b57cec5SDimitry Andric   void VisitFunctionProtoType(const FunctionProtoType *T) {
10580b57cec5SDimitry Andric     ID.AddInteger(T->getNumParams());
10590b57cec5SDimitry Andric     for (auto ParamType : T->getParamTypes())
10600b57cec5SDimitry Andric       AddQualType(ParamType);
10610b57cec5SDimitry Andric 
10620b57cec5SDimitry Andric     VisitFunctionType(T);
10630b57cec5SDimitry Andric   }
10640b57cec5SDimitry Andric 
10650b57cec5SDimitry Andric   void VisitInjectedClassNameType(const InjectedClassNameType *T) {
10660b57cec5SDimitry Andric     AddDecl(T->getDecl());
10670b57cec5SDimitry Andric     VisitType(T);
10680b57cec5SDimitry Andric   }
10690b57cec5SDimitry Andric 
10700b57cec5SDimitry Andric   void VisitMemberPointerType(const MemberPointerType *T) {
10710b57cec5SDimitry Andric     AddQualType(T->getPointeeType());
10720b57cec5SDimitry Andric     AddType(T->getClass());
10730b57cec5SDimitry Andric     VisitType(T);
10740b57cec5SDimitry Andric   }
10750b57cec5SDimitry Andric 
10760b57cec5SDimitry Andric   void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
10770b57cec5SDimitry Andric     AddQualType(T->getPointeeType());
10780b57cec5SDimitry Andric     VisitType(T);
10790b57cec5SDimitry Andric   }
10800b57cec5SDimitry Andric 
10810b57cec5SDimitry Andric   void VisitObjCObjectType(const ObjCObjectType *T) {
10820b57cec5SDimitry Andric     AddDecl(T->getInterface());
10830b57cec5SDimitry Andric 
10840b57cec5SDimitry Andric     auto TypeArgs = T->getTypeArgsAsWritten();
10850b57cec5SDimitry Andric     ID.AddInteger(TypeArgs.size());
10860b57cec5SDimitry Andric     for (auto Arg : TypeArgs) {
10870b57cec5SDimitry Andric       AddQualType(Arg);
10880b57cec5SDimitry Andric     }
10890b57cec5SDimitry Andric 
10900b57cec5SDimitry Andric     auto Protocols = T->getProtocols();
10910b57cec5SDimitry Andric     ID.AddInteger(Protocols.size());
1092bdd1243dSDimitry Andric     for (auto *Protocol : Protocols) {
10930b57cec5SDimitry Andric       AddDecl(Protocol);
10940b57cec5SDimitry Andric     }
10950b57cec5SDimitry Andric 
10960b57cec5SDimitry Andric     Hash.AddBoolean(T->isKindOfType());
10970b57cec5SDimitry Andric 
10980b57cec5SDimitry Andric     VisitType(T);
10990b57cec5SDimitry Andric   }
11000b57cec5SDimitry Andric 
11010b57cec5SDimitry Andric   void VisitObjCInterfaceType(const ObjCInterfaceType *T) {
11020b57cec5SDimitry Andric     // This type is handled by the parent type ObjCObjectType.
11030b57cec5SDimitry Andric     VisitObjCObjectType(T);
11040b57cec5SDimitry Andric   }
11050b57cec5SDimitry Andric 
11060b57cec5SDimitry Andric   void VisitObjCTypeParamType(const ObjCTypeParamType *T) {
11070b57cec5SDimitry Andric     AddDecl(T->getDecl());
11080b57cec5SDimitry Andric     auto Protocols = T->getProtocols();
11090b57cec5SDimitry Andric     ID.AddInteger(Protocols.size());
1110bdd1243dSDimitry Andric     for (auto *Protocol : Protocols) {
11110b57cec5SDimitry Andric       AddDecl(Protocol);
11120b57cec5SDimitry Andric     }
11130b57cec5SDimitry Andric 
11140b57cec5SDimitry Andric     VisitType(T);
11150b57cec5SDimitry Andric   }
11160b57cec5SDimitry Andric 
11170b57cec5SDimitry Andric   void VisitPackExpansionType(const PackExpansionType *T) {
11180b57cec5SDimitry Andric     AddQualType(T->getPattern());
11190b57cec5SDimitry Andric     VisitType(T);
11200b57cec5SDimitry Andric   }
11210b57cec5SDimitry Andric 
11220b57cec5SDimitry Andric   void VisitParenType(const ParenType *T) {
11230b57cec5SDimitry Andric     AddQualType(T->getInnerType());
11240b57cec5SDimitry Andric     VisitType(T);
11250b57cec5SDimitry Andric   }
11260b57cec5SDimitry Andric 
11270b57cec5SDimitry Andric   void VisitPipeType(const PipeType *T) {
11280b57cec5SDimitry Andric     AddQualType(T->getElementType());
11290b57cec5SDimitry Andric     Hash.AddBoolean(T->isReadOnly());
11300b57cec5SDimitry Andric     VisitType(T);
11310b57cec5SDimitry Andric   }
11320b57cec5SDimitry Andric 
11330b57cec5SDimitry Andric   void VisitPointerType(const PointerType *T) {
11340b57cec5SDimitry Andric     AddQualType(T->getPointeeType());
11350b57cec5SDimitry Andric     VisitType(T);
11360b57cec5SDimitry Andric   }
11370b57cec5SDimitry Andric 
11380b57cec5SDimitry Andric   void VisitReferenceType(const ReferenceType *T) {
11390b57cec5SDimitry Andric     AddQualType(T->getPointeeTypeAsWritten());
11400b57cec5SDimitry Andric     VisitType(T);
11410b57cec5SDimitry Andric   }
11420b57cec5SDimitry Andric 
11430b57cec5SDimitry Andric   void VisitLValueReferenceType(const LValueReferenceType *T) {
11440b57cec5SDimitry Andric     VisitReferenceType(T);
11450b57cec5SDimitry Andric   }
11460b57cec5SDimitry Andric 
11470b57cec5SDimitry Andric   void VisitRValueReferenceType(const RValueReferenceType *T) {
11480b57cec5SDimitry Andric     VisitReferenceType(T);
11490b57cec5SDimitry Andric   }
11500b57cec5SDimitry Andric 
11510b57cec5SDimitry Andric   void
11520b57cec5SDimitry Andric   VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T) {
1153bdd1243dSDimitry Andric     AddDecl(T->getAssociatedDecl());
11540b57cec5SDimitry Andric     Hash.AddTemplateArgument(T->getArgumentPack());
11550b57cec5SDimitry Andric     VisitType(T);
11560b57cec5SDimitry Andric   }
11570b57cec5SDimitry Andric 
11580b57cec5SDimitry Andric   void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
1159bdd1243dSDimitry Andric     AddDecl(T->getAssociatedDecl());
11600b57cec5SDimitry Andric     AddQualType(T->getReplacementType());
11610b57cec5SDimitry Andric     VisitType(T);
11620b57cec5SDimitry Andric   }
11630b57cec5SDimitry Andric 
11640b57cec5SDimitry Andric   void VisitTagType(const TagType *T) {
11650b57cec5SDimitry Andric     AddDecl(T->getDecl());
11660b57cec5SDimitry Andric     VisitType(T);
11670b57cec5SDimitry Andric   }
11680b57cec5SDimitry Andric 
11690b57cec5SDimitry Andric   void VisitRecordType(const RecordType *T) { VisitTagType(T); }
11700b57cec5SDimitry Andric   void VisitEnumType(const EnumType *T) { VisitTagType(T); }
11710b57cec5SDimitry Andric 
11720b57cec5SDimitry Andric   void VisitTemplateSpecializationType(const TemplateSpecializationType *T) {
1173bdd1243dSDimitry Andric     ID.AddInteger(T->template_arguments().size());
11740b57cec5SDimitry Andric     for (const auto &TA : T->template_arguments()) {
11750b57cec5SDimitry Andric       Hash.AddTemplateArgument(TA);
11760b57cec5SDimitry Andric     }
11770b57cec5SDimitry Andric     Hash.AddTemplateName(T->getTemplateName());
11780b57cec5SDimitry Andric     VisitType(T);
11790b57cec5SDimitry Andric   }
11800b57cec5SDimitry Andric 
11810b57cec5SDimitry Andric   void VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
11820b57cec5SDimitry Andric     ID.AddInteger(T->getDepth());
11830b57cec5SDimitry Andric     ID.AddInteger(T->getIndex());
11840b57cec5SDimitry Andric     Hash.AddBoolean(T->isParameterPack());
11850b57cec5SDimitry Andric     AddDecl(T->getDecl());
11860b57cec5SDimitry Andric   }
11870b57cec5SDimitry Andric 
11880b57cec5SDimitry Andric   void VisitTypedefType(const TypedefType *T) {
11890b57cec5SDimitry Andric     AddDecl(T->getDecl());
11900b57cec5SDimitry Andric     VisitType(T);
11910b57cec5SDimitry Andric   }
11920b57cec5SDimitry Andric 
11930b57cec5SDimitry Andric   void VisitTypeOfExprType(const TypeOfExprType *T) {
11940b57cec5SDimitry Andric     AddStmt(T->getUnderlyingExpr());
11950b57cec5SDimitry Andric     Hash.AddBoolean(T->isSugared());
11960b57cec5SDimitry Andric 
11970b57cec5SDimitry Andric     VisitType(T);
11980b57cec5SDimitry Andric   }
11990b57cec5SDimitry Andric   void VisitTypeOfType(const TypeOfType *T) {
1200bdd1243dSDimitry Andric     AddQualType(T->getUnmodifiedType());
12010b57cec5SDimitry Andric     VisitType(T);
12020b57cec5SDimitry Andric   }
12030b57cec5SDimitry Andric 
12040b57cec5SDimitry Andric   void VisitTypeWithKeyword(const TypeWithKeyword *T) {
12055f757f3fSDimitry Andric     ID.AddInteger(llvm::to_underlying(T->getKeyword()));
12060b57cec5SDimitry Andric     VisitType(T);
12070b57cec5SDimitry Andric   };
12080b57cec5SDimitry Andric 
12090b57cec5SDimitry Andric   void VisitDependentNameType(const DependentNameType *T) {
12100b57cec5SDimitry Andric     AddNestedNameSpecifier(T->getQualifier());
12110b57cec5SDimitry Andric     AddIdentifierInfo(T->getIdentifier());
12120b57cec5SDimitry Andric     VisitTypeWithKeyword(T);
12130b57cec5SDimitry Andric   }
12140b57cec5SDimitry Andric 
12150b57cec5SDimitry Andric   void VisitDependentTemplateSpecializationType(
12160b57cec5SDimitry Andric       const DependentTemplateSpecializationType *T) {
12170b57cec5SDimitry Andric     AddIdentifierInfo(T->getIdentifier());
12180b57cec5SDimitry Andric     AddNestedNameSpecifier(T->getQualifier());
1219bdd1243dSDimitry Andric     ID.AddInteger(T->template_arguments().size());
12200b57cec5SDimitry Andric     for (const auto &TA : T->template_arguments()) {
12210b57cec5SDimitry Andric       Hash.AddTemplateArgument(TA);
12220b57cec5SDimitry Andric     }
12230b57cec5SDimitry Andric     VisitTypeWithKeyword(T);
12240b57cec5SDimitry Andric   }
12250b57cec5SDimitry Andric 
12260b57cec5SDimitry Andric   void VisitElaboratedType(const ElaboratedType *T) {
12270b57cec5SDimitry Andric     AddNestedNameSpecifier(T->getQualifier());
12280b57cec5SDimitry Andric     AddQualType(T->getNamedType());
12290b57cec5SDimitry Andric     VisitTypeWithKeyword(T);
12300b57cec5SDimitry Andric   }
12310b57cec5SDimitry Andric 
12320b57cec5SDimitry Andric   void VisitUnaryTransformType(const UnaryTransformType *T) {
12330b57cec5SDimitry Andric     AddQualType(T->getUnderlyingType());
12340b57cec5SDimitry Andric     AddQualType(T->getBaseType());
12350b57cec5SDimitry Andric     VisitType(T);
12360b57cec5SDimitry Andric   }
12370b57cec5SDimitry Andric 
12380b57cec5SDimitry Andric   void VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
12390b57cec5SDimitry Andric     AddDecl(T->getDecl());
12400b57cec5SDimitry Andric     VisitType(T);
12410b57cec5SDimitry Andric   }
12420b57cec5SDimitry Andric 
12430b57cec5SDimitry Andric   void VisitVectorType(const VectorType *T) {
12440b57cec5SDimitry Andric     AddQualType(T->getElementType());
12450b57cec5SDimitry Andric     ID.AddInteger(T->getNumElements());
12465f757f3fSDimitry Andric     ID.AddInteger(llvm::to_underlying(T->getVectorKind()));
12470b57cec5SDimitry Andric     VisitType(T);
12480b57cec5SDimitry Andric   }
12490b57cec5SDimitry Andric 
12500b57cec5SDimitry Andric   void VisitExtVectorType(const ExtVectorType * T) {
12510b57cec5SDimitry Andric     VisitVectorType(T);
12520b57cec5SDimitry Andric   }
12530b57cec5SDimitry Andric };
12540b57cec5SDimitry Andric } // namespace
12550b57cec5SDimitry Andric 
12560b57cec5SDimitry Andric void ODRHash::AddType(const Type *T) {
12570b57cec5SDimitry Andric   assert(T && "Expecting non-null pointer.");
12580b57cec5SDimitry Andric   ODRTypeVisitor(ID, *this).Visit(T);
12590b57cec5SDimitry Andric }
12600b57cec5SDimitry Andric 
12610b57cec5SDimitry Andric void ODRHash::AddQualType(QualType T) {
12620b57cec5SDimitry Andric   AddBoolean(T.isNull());
12630b57cec5SDimitry Andric   if (T.isNull())
12640b57cec5SDimitry Andric     return;
12650b57cec5SDimitry Andric   SplitQualType split = T.split();
12660b57cec5SDimitry Andric   ID.AddInteger(split.Quals.getAsOpaqueValue());
12670b57cec5SDimitry Andric   AddType(split.Ty);
12680b57cec5SDimitry Andric }
12690b57cec5SDimitry Andric 
12700b57cec5SDimitry Andric void ODRHash::AddBoolean(bool Value) {
12710b57cec5SDimitry Andric   Bools.push_back(Value);
12720b57cec5SDimitry Andric }
12737a6dacacSDimitry Andric 
12747a6dacacSDimitry Andric void ODRHash::AddStructuralValue(const APValue &Value) {
12757a6dacacSDimitry Andric   ID.AddInteger(Value.getKind());
12767a6dacacSDimitry Andric 
12777a6dacacSDimitry Andric   // 'APValue::Profile' uses pointer values to make hash for LValue and
12787a6dacacSDimitry Andric   // MemberPointer, but they differ from one compiler invocation to another.
12797a6dacacSDimitry Andric   // So, handle them explicitly here.
12807a6dacacSDimitry Andric 
12817a6dacacSDimitry Andric   switch (Value.getKind()) {
12827a6dacacSDimitry Andric   case APValue::LValue: {
12837a6dacacSDimitry Andric     const APValue::LValueBase &Base = Value.getLValueBase();
12847a6dacacSDimitry Andric     if (!Base) {
12857a6dacacSDimitry Andric       ID.AddInteger(Value.getLValueOffset().getQuantity());
12867a6dacacSDimitry Andric       break;
12877a6dacacSDimitry Andric     }
12887a6dacacSDimitry Andric 
12897a6dacacSDimitry Andric     assert(Base.is<const ValueDecl *>());
12907a6dacacSDimitry Andric     AddDecl(Base.get<const ValueDecl *>());
12917a6dacacSDimitry Andric     ID.AddInteger(Value.getLValueOffset().getQuantity());
12927a6dacacSDimitry Andric 
12937a6dacacSDimitry Andric     bool OnePastTheEnd = Value.isLValueOnePastTheEnd();
12947a6dacacSDimitry Andric     if (Value.hasLValuePath()) {
12957a6dacacSDimitry Andric       QualType TypeSoFar = Base.getType();
12967a6dacacSDimitry Andric       for (APValue::LValuePathEntry E : Value.getLValuePath()) {
12977a6dacacSDimitry Andric         if (const auto *AT = TypeSoFar->getAsArrayTypeUnsafe()) {
12987a6dacacSDimitry Andric           if (const auto *CAT = dyn_cast<ConstantArrayType>(AT))
12997a6dacacSDimitry Andric             OnePastTheEnd |= CAT->getSize() == E.getAsArrayIndex();
13007a6dacacSDimitry Andric           TypeSoFar = AT->getElementType();
13017a6dacacSDimitry Andric         } else {
13027a6dacacSDimitry Andric           const Decl *D = E.getAsBaseOrMember().getPointer();
13037a6dacacSDimitry Andric           if (const auto *FD = dyn_cast<FieldDecl>(D)) {
13047a6dacacSDimitry Andric             if (FD->getParent()->isUnion())
13057a6dacacSDimitry Andric               ID.AddInteger(FD->getFieldIndex());
13067a6dacacSDimitry Andric             TypeSoFar = FD->getType();
13077a6dacacSDimitry Andric           } else {
13087a6dacacSDimitry Andric             TypeSoFar =
13097a6dacacSDimitry Andric                 D->getASTContext().getRecordType(cast<CXXRecordDecl>(D));
13107a6dacacSDimitry Andric           }
13117a6dacacSDimitry Andric         }
13127a6dacacSDimitry Andric       }
13137a6dacacSDimitry Andric     }
13147a6dacacSDimitry Andric     unsigned Val = 0;
13157a6dacacSDimitry Andric     if (Value.isNullPointer())
13167a6dacacSDimitry Andric       Val |= 1 << 0;
13177a6dacacSDimitry Andric     if (OnePastTheEnd)
13187a6dacacSDimitry Andric       Val |= 1 << 1;
13197a6dacacSDimitry Andric     if (Value.hasLValuePath())
13207a6dacacSDimitry Andric       Val |= 1 << 2;
13217a6dacacSDimitry Andric     ID.AddInteger(Val);
13227a6dacacSDimitry Andric     break;
13237a6dacacSDimitry Andric   }
13247a6dacacSDimitry Andric   case APValue::MemberPointer: {
13257a6dacacSDimitry Andric     const ValueDecl *D = Value.getMemberPointerDecl();
13267a6dacacSDimitry Andric     assert(D);
13277a6dacacSDimitry Andric     AddDecl(D);
13287a6dacacSDimitry Andric     ID.AddInteger(
13297a6dacacSDimitry Andric         D->getASTContext().getMemberPointerPathAdjustment(Value).getQuantity());
13307a6dacacSDimitry Andric     break;
13317a6dacacSDimitry Andric   }
13327a6dacacSDimitry Andric   default:
13337a6dacacSDimitry Andric     Value.Profile(ID);
13347a6dacacSDimitry Andric   }
13357a6dacacSDimitry Andric }
1336