xref: /netbsd-src/external/apache2/llvm/dist/clang/lib/AST/ODRHash.cpp (revision e038c9c4676b0f19b1b7dd08a940c6ed64a6d5ae)
17330f729Sjoerg //===-- ODRHash.cpp - Hashing to diagnose ODR failures ----------*- C++ -*-===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg ///
97330f729Sjoerg /// \file
107330f729Sjoerg /// This file implements the ODRHash class, which calculates a hash based
117330f729Sjoerg /// on AST nodes, which is stable across different runs.
127330f729Sjoerg ///
137330f729Sjoerg //===----------------------------------------------------------------------===//
147330f729Sjoerg 
157330f729Sjoerg #include "clang/AST/ODRHash.h"
167330f729Sjoerg 
177330f729Sjoerg #include "clang/AST/DeclVisitor.h"
187330f729Sjoerg #include "clang/AST/NestedNameSpecifier.h"
197330f729Sjoerg #include "clang/AST/StmtVisitor.h"
207330f729Sjoerg #include "clang/AST/TypeVisitor.h"
217330f729Sjoerg 
227330f729Sjoerg using namespace clang;
237330f729Sjoerg 
AddStmt(const Stmt * S)247330f729Sjoerg void ODRHash::AddStmt(const Stmt *S) {
257330f729Sjoerg   assert(S && "Expecting non-null pointer.");
267330f729Sjoerg   S->ProcessODRHash(ID, *this);
277330f729Sjoerg }
287330f729Sjoerg 
AddIdentifierInfo(const IdentifierInfo * II)297330f729Sjoerg void ODRHash::AddIdentifierInfo(const IdentifierInfo *II) {
307330f729Sjoerg   assert(II && "Expecting non-null pointer.");
317330f729Sjoerg   ID.AddString(II->getName());
327330f729Sjoerg }
337330f729Sjoerg 
AddDeclarationName(DeclarationName Name,bool TreatAsDecl)347330f729Sjoerg void ODRHash::AddDeclarationName(DeclarationName Name, bool TreatAsDecl) {
357330f729Sjoerg   if (TreatAsDecl)
367330f729Sjoerg     // Matches the NamedDecl check in AddDecl
377330f729Sjoerg     AddBoolean(true);
387330f729Sjoerg 
397330f729Sjoerg   AddDeclarationNameImpl(Name);
407330f729Sjoerg 
417330f729Sjoerg   if (TreatAsDecl)
427330f729Sjoerg     // Matches the ClassTemplateSpecializationDecl check in AddDecl
437330f729Sjoerg     AddBoolean(false);
447330f729Sjoerg }
457330f729Sjoerg 
AddDeclarationNameImpl(DeclarationName Name)467330f729Sjoerg void ODRHash::AddDeclarationNameImpl(DeclarationName Name) {
477330f729Sjoerg   // Index all DeclarationName and use index numbers to refer to them.
487330f729Sjoerg   auto Result = DeclNameMap.insert(std::make_pair(Name, DeclNameMap.size()));
497330f729Sjoerg   ID.AddInteger(Result.first->second);
507330f729Sjoerg   if (!Result.second) {
517330f729Sjoerg     // If found in map, the DeclarationName has previously been processed.
527330f729Sjoerg     return;
537330f729Sjoerg   }
547330f729Sjoerg 
557330f729Sjoerg   // First time processing each DeclarationName, also process its details.
567330f729Sjoerg   AddBoolean(Name.isEmpty());
577330f729Sjoerg   if (Name.isEmpty())
587330f729Sjoerg     return;
597330f729Sjoerg 
607330f729Sjoerg   auto Kind = Name.getNameKind();
617330f729Sjoerg   ID.AddInteger(Kind);
627330f729Sjoerg   switch (Kind) {
637330f729Sjoerg   case DeclarationName::Identifier:
647330f729Sjoerg     AddIdentifierInfo(Name.getAsIdentifierInfo());
657330f729Sjoerg     break;
667330f729Sjoerg   case DeclarationName::ObjCZeroArgSelector:
677330f729Sjoerg   case DeclarationName::ObjCOneArgSelector:
687330f729Sjoerg   case DeclarationName::ObjCMultiArgSelector: {
697330f729Sjoerg     Selector S = Name.getObjCSelector();
707330f729Sjoerg     AddBoolean(S.isNull());
717330f729Sjoerg     AddBoolean(S.isKeywordSelector());
727330f729Sjoerg     AddBoolean(S.isUnarySelector());
737330f729Sjoerg     unsigned NumArgs = S.getNumArgs();
747330f729Sjoerg     ID.AddInteger(NumArgs);
757330f729Sjoerg     for (unsigned i = 0; i < NumArgs; ++i) {
767330f729Sjoerg       const IdentifierInfo *II = S.getIdentifierInfoForSlot(i);
777330f729Sjoerg       AddBoolean(II);
787330f729Sjoerg       if (II) {
797330f729Sjoerg         AddIdentifierInfo(II);
807330f729Sjoerg       }
817330f729Sjoerg     }
827330f729Sjoerg     break;
837330f729Sjoerg   }
847330f729Sjoerg   case DeclarationName::CXXConstructorName:
857330f729Sjoerg   case DeclarationName::CXXDestructorName:
867330f729Sjoerg     AddQualType(Name.getCXXNameType());
877330f729Sjoerg     break;
887330f729Sjoerg   case DeclarationName::CXXOperatorName:
897330f729Sjoerg     ID.AddInteger(Name.getCXXOverloadedOperator());
907330f729Sjoerg     break;
917330f729Sjoerg   case DeclarationName::CXXLiteralOperatorName:
927330f729Sjoerg     AddIdentifierInfo(Name.getCXXLiteralIdentifier());
937330f729Sjoerg     break;
947330f729Sjoerg   case DeclarationName::CXXConversionFunctionName:
957330f729Sjoerg     AddQualType(Name.getCXXNameType());
967330f729Sjoerg     break;
977330f729Sjoerg   case DeclarationName::CXXUsingDirective:
987330f729Sjoerg     break;
997330f729Sjoerg   case DeclarationName::CXXDeductionGuideName: {
1007330f729Sjoerg     auto *Template = Name.getCXXDeductionGuideTemplate();
1017330f729Sjoerg     AddBoolean(Template);
1027330f729Sjoerg     if (Template) {
1037330f729Sjoerg       AddDecl(Template);
1047330f729Sjoerg     }
1057330f729Sjoerg   }
1067330f729Sjoerg   }
1077330f729Sjoerg }
1087330f729Sjoerg 
AddNestedNameSpecifier(const NestedNameSpecifier * NNS)1097330f729Sjoerg void ODRHash::AddNestedNameSpecifier(const NestedNameSpecifier *NNS) {
1107330f729Sjoerg   assert(NNS && "Expecting non-null pointer.");
1117330f729Sjoerg   const auto *Prefix = NNS->getPrefix();
1127330f729Sjoerg   AddBoolean(Prefix);
1137330f729Sjoerg   if (Prefix) {
1147330f729Sjoerg     AddNestedNameSpecifier(Prefix);
1157330f729Sjoerg   }
1167330f729Sjoerg   auto Kind = NNS->getKind();
1177330f729Sjoerg   ID.AddInteger(Kind);
1187330f729Sjoerg   switch (Kind) {
1197330f729Sjoerg   case NestedNameSpecifier::Identifier:
1207330f729Sjoerg     AddIdentifierInfo(NNS->getAsIdentifier());
1217330f729Sjoerg     break;
1227330f729Sjoerg   case NestedNameSpecifier::Namespace:
1237330f729Sjoerg     AddDecl(NNS->getAsNamespace());
1247330f729Sjoerg     break;
1257330f729Sjoerg   case NestedNameSpecifier::NamespaceAlias:
1267330f729Sjoerg     AddDecl(NNS->getAsNamespaceAlias());
1277330f729Sjoerg     break;
1287330f729Sjoerg   case NestedNameSpecifier::TypeSpec:
1297330f729Sjoerg   case NestedNameSpecifier::TypeSpecWithTemplate:
1307330f729Sjoerg     AddType(NNS->getAsType());
1317330f729Sjoerg     break;
1327330f729Sjoerg   case NestedNameSpecifier::Global:
1337330f729Sjoerg   case NestedNameSpecifier::Super:
1347330f729Sjoerg     break;
1357330f729Sjoerg   }
1367330f729Sjoerg }
1377330f729Sjoerg 
AddTemplateName(TemplateName Name)1387330f729Sjoerg void ODRHash::AddTemplateName(TemplateName Name) {
1397330f729Sjoerg   auto Kind = Name.getKind();
1407330f729Sjoerg   ID.AddInteger(Kind);
1417330f729Sjoerg 
1427330f729Sjoerg   switch (Kind) {
1437330f729Sjoerg   case TemplateName::Template:
1447330f729Sjoerg     AddDecl(Name.getAsTemplateDecl());
1457330f729Sjoerg     break;
1467330f729Sjoerg   // TODO: Support these cases.
1477330f729Sjoerg   case TemplateName::OverloadedTemplate:
1487330f729Sjoerg   case TemplateName::AssumedTemplate:
1497330f729Sjoerg   case TemplateName::QualifiedTemplate:
1507330f729Sjoerg   case TemplateName::DependentTemplate:
1517330f729Sjoerg   case TemplateName::SubstTemplateTemplateParm:
1527330f729Sjoerg   case TemplateName::SubstTemplateTemplateParmPack:
1537330f729Sjoerg     break;
1547330f729Sjoerg   }
1557330f729Sjoerg }
1567330f729Sjoerg 
AddTemplateArgument(TemplateArgument TA)1577330f729Sjoerg void ODRHash::AddTemplateArgument(TemplateArgument TA) {
1587330f729Sjoerg   const auto Kind = TA.getKind();
1597330f729Sjoerg   ID.AddInteger(Kind);
1607330f729Sjoerg 
1617330f729Sjoerg   switch (Kind) {
1627330f729Sjoerg     case TemplateArgument::Null:
1637330f729Sjoerg       llvm_unreachable("Expected valid TemplateArgument");
1647330f729Sjoerg     case TemplateArgument::Type:
1657330f729Sjoerg       AddQualType(TA.getAsType());
1667330f729Sjoerg       break;
1677330f729Sjoerg     case TemplateArgument::Declaration:
1687330f729Sjoerg       AddDecl(TA.getAsDecl());
1697330f729Sjoerg       break;
1707330f729Sjoerg     case TemplateArgument::NullPtr:
1717330f729Sjoerg     case TemplateArgument::Integral:
1727330f729Sjoerg       break;
1737330f729Sjoerg     case TemplateArgument::Template:
1747330f729Sjoerg     case TemplateArgument::TemplateExpansion:
1757330f729Sjoerg       AddTemplateName(TA.getAsTemplateOrTemplatePattern());
1767330f729Sjoerg       break;
1777330f729Sjoerg     case TemplateArgument::Expression:
1787330f729Sjoerg       AddStmt(TA.getAsExpr());
1797330f729Sjoerg       break;
1807330f729Sjoerg     case TemplateArgument::Pack:
1817330f729Sjoerg       ID.AddInteger(TA.pack_size());
1827330f729Sjoerg       for (auto SubTA : TA.pack_elements()) {
1837330f729Sjoerg         AddTemplateArgument(SubTA);
1847330f729Sjoerg       }
1857330f729Sjoerg       break;
1867330f729Sjoerg   }
1877330f729Sjoerg }
1887330f729Sjoerg 
AddTemplateParameterList(const TemplateParameterList * TPL)1897330f729Sjoerg void ODRHash::AddTemplateParameterList(const TemplateParameterList *TPL) {
1907330f729Sjoerg   assert(TPL && "Expecting non-null pointer.");
1917330f729Sjoerg 
1927330f729Sjoerg   ID.AddInteger(TPL->size());
1937330f729Sjoerg   for (auto *ND : TPL->asArray()) {
1947330f729Sjoerg     AddSubDecl(ND);
1957330f729Sjoerg   }
1967330f729Sjoerg }
1977330f729Sjoerg 
clear()1987330f729Sjoerg void ODRHash::clear() {
1997330f729Sjoerg   DeclNameMap.clear();
2007330f729Sjoerg   Bools.clear();
2017330f729Sjoerg   ID.clear();
2027330f729Sjoerg }
2037330f729Sjoerg 
CalculateHash()2047330f729Sjoerg unsigned ODRHash::CalculateHash() {
2057330f729Sjoerg   // Append the bools to the end of the data segment backwards.  This allows
2067330f729Sjoerg   // for the bools data to be compressed 32 times smaller compared to using
2077330f729Sjoerg   // ID.AddBoolean
2087330f729Sjoerg   const unsigned unsigned_bits = sizeof(unsigned) * CHAR_BIT;
2097330f729Sjoerg   const unsigned size = Bools.size();
2107330f729Sjoerg   const unsigned remainder = size % unsigned_bits;
2117330f729Sjoerg   const unsigned loops = size / unsigned_bits;
2127330f729Sjoerg   auto I = Bools.rbegin();
2137330f729Sjoerg   unsigned value = 0;
2147330f729Sjoerg   for (unsigned i = 0; i < remainder; ++i) {
2157330f729Sjoerg     value <<= 1;
2167330f729Sjoerg     value |= *I;
2177330f729Sjoerg     ++I;
2187330f729Sjoerg   }
2197330f729Sjoerg   ID.AddInteger(value);
2207330f729Sjoerg 
2217330f729Sjoerg   for (unsigned i = 0; i < loops; ++i) {
2227330f729Sjoerg     value = 0;
2237330f729Sjoerg     for (unsigned j = 0; j < unsigned_bits; ++j) {
2247330f729Sjoerg       value <<= 1;
2257330f729Sjoerg       value |= *I;
2267330f729Sjoerg       ++I;
2277330f729Sjoerg     }
2287330f729Sjoerg     ID.AddInteger(value);
2297330f729Sjoerg   }
2307330f729Sjoerg 
2317330f729Sjoerg   assert(I == Bools.rend());
2327330f729Sjoerg   Bools.clear();
2337330f729Sjoerg   return ID.ComputeHash();
2347330f729Sjoerg }
2357330f729Sjoerg 
2367330f729Sjoerg namespace {
2377330f729Sjoerg // Process a Decl pointer.  Add* methods call back into ODRHash while Visit*
2387330f729Sjoerg // methods process the relevant parts of the Decl.
2397330f729Sjoerg class ODRDeclVisitor : public ConstDeclVisitor<ODRDeclVisitor> {
2407330f729Sjoerg   typedef ConstDeclVisitor<ODRDeclVisitor> Inherited;
2417330f729Sjoerg   llvm::FoldingSetNodeID &ID;
2427330f729Sjoerg   ODRHash &Hash;
2437330f729Sjoerg 
2447330f729Sjoerg public:
ODRDeclVisitor(llvm::FoldingSetNodeID & ID,ODRHash & Hash)2457330f729Sjoerg   ODRDeclVisitor(llvm::FoldingSetNodeID &ID, ODRHash &Hash)
2467330f729Sjoerg       : ID(ID), Hash(Hash) {}
2477330f729Sjoerg 
AddStmt(const Stmt * S)2487330f729Sjoerg   void AddStmt(const Stmt *S) {
2497330f729Sjoerg     Hash.AddBoolean(S);
2507330f729Sjoerg     if (S) {
2517330f729Sjoerg       Hash.AddStmt(S);
2527330f729Sjoerg     }
2537330f729Sjoerg   }
2547330f729Sjoerg 
AddIdentifierInfo(const IdentifierInfo * II)2557330f729Sjoerg   void AddIdentifierInfo(const IdentifierInfo *II) {
2567330f729Sjoerg     Hash.AddBoolean(II);
2577330f729Sjoerg     if (II) {
2587330f729Sjoerg       Hash.AddIdentifierInfo(II);
2597330f729Sjoerg     }
2607330f729Sjoerg   }
2617330f729Sjoerg 
AddQualType(QualType T)2627330f729Sjoerg   void AddQualType(QualType T) {
2637330f729Sjoerg     Hash.AddQualType(T);
2647330f729Sjoerg   }
2657330f729Sjoerg 
AddDecl(const Decl * D)2667330f729Sjoerg   void AddDecl(const Decl *D) {
2677330f729Sjoerg     Hash.AddBoolean(D);
2687330f729Sjoerg     if (D) {
2697330f729Sjoerg       Hash.AddDecl(D);
2707330f729Sjoerg     }
2717330f729Sjoerg   }
2727330f729Sjoerg 
AddTemplateArgument(TemplateArgument TA)2737330f729Sjoerg   void AddTemplateArgument(TemplateArgument TA) {
2747330f729Sjoerg     Hash.AddTemplateArgument(TA);
2757330f729Sjoerg   }
2767330f729Sjoerg 
Visit(const Decl * D)2777330f729Sjoerg   void Visit(const Decl *D) {
2787330f729Sjoerg     ID.AddInteger(D->getKind());
2797330f729Sjoerg     Inherited::Visit(D);
2807330f729Sjoerg   }
2817330f729Sjoerg 
VisitNamedDecl(const NamedDecl * D)2827330f729Sjoerg   void VisitNamedDecl(const NamedDecl *D) {
2837330f729Sjoerg     Hash.AddDeclarationName(D->getDeclName());
2847330f729Sjoerg     Inherited::VisitNamedDecl(D);
2857330f729Sjoerg   }
2867330f729Sjoerg 
VisitValueDecl(const ValueDecl * D)2877330f729Sjoerg   void VisitValueDecl(const ValueDecl *D) {
2887330f729Sjoerg     if (!isa<FunctionDecl>(D)) {
2897330f729Sjoerg       AddQualType(D->getType());
2907330f729Sjoerg     }
2917330f729Sjoerg     Inherited::VisitValueDecl(D);
2927330f729Sjoerg   }
2937330f729Sjoerg 
VisitVarDecl(const VarDecl * D)2947330f729Sjoerg   void VisitVarDecl(const VarDecl *D) {
2957330f729Sjoerg     Hash.AddBoolean(D->isStaticLocal());
2967330f729Sjoerg     Hash.AddBoolean(D->isConstexpr());
2977330f729Sjoerg     const bool HasInit = D->hasInit();
2987330f729Sjoerg     Hash.AddBoolean(HasInit);
2997330f729Sjoerg     if (HasInit) {
3007330f729Sjoerg       AddStmt(D->getInit());
3017330f729Sjoerg     }
3027330f729Sjoerg     Inherited::VisitVarDecl(D);
3037330f729Sjoerg   }
3047330f729Sjoerg 
VisitParmVarDecl(const ParmVarDecl * D)3057330f729Sjoerg   void VisitParmVarDecl(const ParmVarDecl *D) {
3067330f729Sjoerg     // TODO: Handle default arguments.
3077330f729Sjoerg     Inherited::VisitParmVarDecl(D);
3087330f729Sjoerg   }
3097330f729Sjoerg 
VisitAccessSpecDecl(const AccessSpecDecl * D)3107330f729Sjoerg   void VisitAccessSpecDecl(const AccessSpecDecl *D) {
3117330f729Sjoerg     ID.AddInteger(D->getAccess());
3127330f729Sjoerg     Inherited::VisitAccessSpecDecl(D);
3137330f729Sjoerg   }
3147330f729Sjoerg 
VisitStaticAssertDecl(const StaticAssertDecl * D)3157330f729Sjoerg   void VisitStaticAssertDecl(const StaticAssertDecl *D) {
3167330f729Sjoerg     AddStmt(D->getAssertExpr());
3177330f729Sjoerg     AddStmt(D->getMessage());
3187330f729Sjoerg 
3197330f729Sjoerg     Inherited::VisitStaticAssertDecl(D);
3207330f729Sjoerg   }
3217330f729Sjoerg 
VisitFieldDecl(const FieldDecl * D)3227330f729Sjoerg   void VisitFieldDecl(const FieldDecl *D) {
3237330f729Sjoerg     const bool IsBitfield = D->isBitField();
3247330f729Sjoerg     Hash.AddBoolean(IsBitfield);
3257330f729Sjoerg 
3267330f729Sjoerg     if (IsBitfield) {
3277330f729Sjoerg       AddStmt(D->getBitWidth());
3287330f729Sjoerg     }
3297330f729Sjoerg 
3307330f729Sjoerg     Hash.AddBoolean(D->isMutable());
3317330f729Sjoerg     AddStmt(D->getInClassInitializer());
3327330f729Sjoerg 
3337330f729Sjoerg     Inherited::VisitFieldDecl(D);
3347330f729Sjoerg   }
3357330f729Sjoerg 
VisitFunctionDecl(const FunctionDecl * D)3367330f729Sjoerg   void VisitFunctionDecl(const FunctionDecl *D) {
3377330f729Sjoerg     // Handled by the ODRHash for FunctionDecl
3387330f729Sjoerg     ID.AddInteger(D->getODRHash());
3397330f729Sjoerg 
3407330f729Sjoerg     Inherited::VisitFunctionDecl(D);
3417330f729Sjoerg   }
3427330f729Sjoerg 
VisitCXXMethodDecl(const CXXMethodDecl * D)3437330f729Sjoerg   void VisitCXXMethodDecl(const CXXMethodDecl *D) {
3447330f729Sjoerg     // Handled by the ODRHash for FunctionDecl
3457330f729Sjoerg 
3467330f729Sjoerg     Inherited::VisitCXXMethodDecl(D);
3477330f729Sjoerg   }
3487330f729Sjoerg 
VisitTypedefNameDecl(const TypedefNameDecl * D)3497330f729Sjoerg   void VisitTypedefNameDecl(const TypedefNameDecl *D) {
3507330f729Sjoerg     AddQualType(D->getUnderlyingType());
3517330f729Sjoerg 
3527330f729Sjoerg     Inherited::VisitTypedefNameDecl(D);
3537330f729Sjoerg   }
3547330f729Sjoerg 
VisitTypedefDecl(const TypedefDecl * D)3557330f729Sjoerg   void VisitTypedefDecl(const TypedefDecl *D) {
3567330f729Sjoerg     Inherited::VisitTypedefDecl(D);
3577330f729Sjoerg   }
3587330f729Sjoerg 
VisitTypeAliasDecl(const TypeAliasDecl * D)3597330f729Sjoerg   void VisitTypeAliasDecl(const TypeAliasDecl *D) {
3607330f729Sjoerg     Inherited::VisitTypeAliasDecl(D);
3617330f729Sjoerg   }
3627330f729Sjoerg 
VisitFriendDecl(const FriendDecl * D)3637330f729Sjoerg   void VisitFriendDecl(const FriendDecl *D) {
3647330f729Sjoerg     TypeSourceInfo *TSI = D->getFriendType();
3657330f729Sjoerg     Hash.AddBoolean(TSI);
3667330f729Sjoerg     if (TSI) {
3677330f729Sjoerg       AddQualType(TSI->getType());
3687330f729Sjoerg     } else {
3697330f729Sjoerg       AddDecl(D->getFriendDecl());
3707330f729Sjoerg     }
3717330f729Sjoerg   }
3727330f729Sjoerg 
VisitTemplateTypeParmDecl(const TemplateTypeParmDecl * D)3737330f729Sjoerg   void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
3747330f729Sjoerg     // Only care about default arguments as part of the definition.
3757330f729Sjoerg     const bool hasDefaultArgument =
3767330f729Sjoerg         D->hasDefaultArgument() && !D->defaultArgumentWasInherited();
3777330f729Sjoerg     Hash.AddBoolean(hasDefaultArgument);
3787330f729Sjoerg     if (hasDefaultArgument) {
3797330f729Sjoerg       AddTemplateArgument(D->getDefaultArgument());
3807330f729Sjoerg     }
3817330f729Sjoerg     Hash.AddBoolean(D->isParameterPack());
3827330f729Sjoerg 
383*e038c9c4Sjoerg     const TypeConstraint *TC = D->getTypeConstraint();
384*e038c9c4Sjoerg     Hash.AddBoolean(TC != nullptr);
385*e038c9c4Sjoerg     if (TC)
386*e038c9c4Sjoerg       AddStmt(TC->getImmediatelyDeclaredConstraint());
387*e038c9c4Sjoerg 
3887330f729Sjoerg     Inherited::VisitTemplateTypeParmDecl(D);
3897330f729Sjoerg   }
3907330f729Sjoerg 
VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl * D)3917330f729Sjoerg   void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
3927330f729Sjoerg     // Only care about default arguments as part of the definition.
3937330f729Sjoerg     const bool hasDefaultArgument =
3947330f729Sjoerg         D->hasDefaultArgument() && !D->defaultArgumentWasInherited();
3957330f729Sjoerg     Hash.AddBoolean(hasDefaultArgument);
3967330f729Sjoerg     if (hasDefaultArgument) {
3977330f729Sjoerg       AddStmt(D->getDefaultArgument());
3987330f729Sjoerg     }
3997330f729Sjoerg     Hash.AddBoolean(D->isParameterPack());
4007330f729Sjoerg 
4017330f729Sjoerg     Inherited::VisitNonTypeTemplateParmDecl(D);
4027330f729Sjoerg   }
4037330f729Sjoerg 
VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl * D)4047330f729Sjoerg   void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D) {
4057330f729Sjoerg     // Only care about default arguments as part of the definition.
4067330f729Sjoerg     const bool hasDefaultArgument =
4077330f729Sjoerg         D->hasDefaultArgument() && !D->defaultArgumentWasInherited();
4087330f729Sjoerg     Hash.AddBoolean(hasDefaultArgument);
4097330f729Sjoerg     if (hasDefaultArgument) {
4107330f729Sjoerg       AddTemplateArgument(D->getDefaultArgument().getArgument());
4117330f729Sjoerg     }
4127330f729Sjoerg     Hash.AddBoolean(D->isParameterPack());
4137330f729Sjoerg 
4147330f729Sjoerg     Inherited::VisitTemplateTemplateParmDecl(D);
4157330f729Sjoerg   }
4167330f729Sjoerg 
VisitTemplateDecl(const TemplateDecl * D)4177330f729Sjoerg   void VisitTemplateDecl(const TemplateDecl *D) {
4187330f729Sjoerg     Hash.AddTemplateParameterList(D->getTemplateParameters());
4197330f729Sjoerg 
4207330f729Sjoerg     Inherited::VisitTemplateDecl(D);
4217330f729Sjoerg   }
4227330f729Sjoerg 
VisitRedeclarableTemplateDecl(const RedeclarableTemplateDecl * D)4237330f729Sjoerg   void VisitRedeclarableTemplateDecl(const RedeclarableTemplateDecl *D) {
4247330f729Sjoerg     Hash.AddBoolean(D->isMemberSpecialization());
4257330f729Sjoerg     Inherited::VisitRedeclarableTemplateDecl(D);
4267330f729Sjoerg   }
4277330f729Sjoerg 
VisitFunctionTemplateDecl(const FunctionTemplateDecl * D)4287330f729Sjoerg   void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
4297330f729Sjoerg     AddDecl(D->getTemplatedDecl());
4307330f729Sjoerg     ID.AddInteger(D->getTemplatedDecl()->getODRHash());
4317330f729Sjoerg     Inherited::VisitFunctionTemplateDecl(D);
4327330f729Sjoerg   }
4337330f729Sjoerg 
VisitEnumConstantDecl(const EnumConstantDecl * D)4347330f729Sjoerg   void VisitEnumConstantDecl(const EnumConstantDecl *D) {
4357330f729Sjoerg     AddStmt(D->getInitExpr());
4367330f729Sjoerg     Inherited::VisitEnumConstantDecl(D);
4377330f729Sjoerg   }
4387330f729Sjoerg };
4397330f729Sjoerg } // namespace
4407330f729Sjoerg 
4417330f729Sjoerg // Only allow a small portion of Decl's to be processed.  Remove this once
4427330f729Sjoerg // all Decl's can be handled.
isDeclToBeProcessed(const Decl * D,const DeclContext * Parent)443*e038c9c4Sjoerg bool ODRHash::isDeclToBeProcessed(const Decl *D, const DeclContext *Parent) {
4447330f729Sjoerg   if (D->isImplicit()) return false;
4457330f729Sjoerg   if (D->getDeclContext() != Parent) return false;
4467330f729Sjoerg 
4477330f729Sjoerg   switch (D->getKind()) {
4487330f729Sjoerg     default:
4497330f729Sjoerg       return false;
4507330f729Sjoerg     case Decl::AccessSpec:
4517330f729Sjoerg     case Decl::CXXConstructor:
4527330f729Sjoerg     case Decl::CXXDestructor:
4537330f729Sjoerg     case Decl::CXXMethod:
4547330f729Sjoerg     case Decl::EnumConstant: // Only found in EnumDecl's.
4557330f729Sjoerg     case Decl::Field:
4567330f729Sjoerg     case Decl::Friend:
4577330f729Sjoerg     case Decl::FunctionTemplate:
4587330f729Sjoerg     case Decl::StaticAssert:
4597330f729Sjoerg     case Decl::TypeAlias:
4607330f729Sjoerg     case Decl::Typedef:
4617330f729Sjoerg     case Decl::Var:
4627330f729Sjoerg       return true;
4637330f729Sjoerg   }
4647330f729Sjoerg }
4657330f729Sjoerg 
AddSubDecl(const Decl * D)4667330f729Sjoerg void ODRHash::AddSubDecl(const Decl *D) {
4677330f729Sjoerg   assert(D && "Expecting non-null pointer.");
4687330f729Sjoerg 
4697330f729Sjoerg   ODRDeclVisitor(ID, *this).Visit(D);
4707330f729Sjoerg }
4717330f729Sjoerg 
AddCXXRecordDecl(const CXXRecordDecl * Record)4727330f729Sjoerg void ODRHash::AddCXXRecordDecl(const CXXRecordDecl *Record) {
4737330f729Sjoerg   assert(Record && Record->hasDefinition() &&
4747330f729Sjoerg          "Expected non-null record to be a definition.");
4757330f729Sjoerg 
4767330f729Sjoerg   const DeclContext *DC = Record;
4777330f729Sjoerg   while (DC) {
4787330f729Sjoerg     if (isa<ClassTemplateSpecializationDecl>(DC)) {
4797330f729Sjoerg       return;
4807330f729Sjoerg     }
4817330f729Sjoerg     DC = DC->getParent();
4827330f729Sjoerg   }
4837330f729Sjoerg 
4847330f729Sjoerg   AddDecl(Record);
4857330f729Sjoerg 
4867330f729Sjoerg   // Filter out sub-Decls which will not be processed in order to get an
4877330f729Sjoerg   // accurate count of Decl's.
4887330f729Sjoerg   llvm::SmallVector<const Decl *, 16> Decls;
4897330f729Sjoerg   for (Decl *SubDecl : Record->decls()) {
490*e038c9c4Sjoerg     if (isDeclToBeProcessed(SubDecl, Record)) {
4917330f729Sjoerg       Decls.push_back(SubDecl);
4927330f729Sjoerg       if (auto *Function = dyn_cast<FunctionDecl>(SubDecl)) {
4937330f729Sjoerg         // Compute/Preload ODRHash into FunctionDecl.
4947330f729Sjoerg         Function->getODRHash();
4957330f729Sjoerg       }
4967330f729Sjoerg     }
4977330f729Sjoerg   }
4987330f729Sjoerg 
4997330f729Sjoerg   ID.AddInteger(Decls.size());
5007330f729Sjoerg   for (auto SubDecl : Decls) {
5017330f729Sjoerg     AddSubDecl(SubDecl);
5027330f729Sjoerg   }
5037330f729Sjoerg 
5047330f729Sjoerg   const ClassTemplateDecl *TD = Record->getDescribedClassTemplate();
5057330f729Sjoerg   AddBoolean(TD);
5067330f729Sjoerg   if (TD) {
5077330f729Sjoerg     AddTemplateParameterList(TD->getTemplateParameters());
5087330f729Sjoerg   }
5097330f729Sjoerg 
5107330f729Sjoerg   ID.AddInteger(Record->getNumBases());
5117330f729Sjoerg   auto Bases = Record->bases();
5127330f729Sjoerg   for (auto Base : Bases) {
5137330f729Sjoerg     AddQualType(Base.getType());
5147330f729Sjoerg     ID.AddInteger(Base.isVirtual());
5157330f729Sjoerg     ID.AddInteger(Base.getAccessSpecifierAsWritten());
5167330f729Sjoerg   }
5177330f729Sjoerg }
5187330f729Sjoerg 
AddFunctionDecl(const FunctionDecl * Function,bool SkipBody)5197330f729Sjoerg void ODRHash::AddFunctionDecl(const FunctionDecl *Function,
5207330f729Sjoerg                               bool SkipBody) {
5217330f729Sjoerg   assert(Function && "Expecting non-null pointer.");
5227330f729Sjoerg 
5237330f729Sjoerg   // Skip functions that are specializations or in specialization context.
5247330f729Sjoerg   const DeclContext *DC = Function;
5257330f729Sjoerg   while (DC) {
5267330f729Sjoerg     if (isa<ClassTemplateSpecializationDecl>(DC)) return;
5277330f729Sjoerg     if (auto *F = dyn_cast<FunctionDecl>(DC)) {
5287330f729Sjoerg       if (F->isFunctionTemplateSpecialization()) {
5297330f729Sjoerg         if (!isa<CXXMethodDecl>(DC)) return;
5307330f729Sjoerg         if (DC->getLexicalParent()->isFileContext()) return;
5317330f729Sjoerg         // Inline method specializations are the only supported
5327330f729Sjoerg         // specialization for now.
5337330f729Sjoerg       }
5347330f729Sjoerg     }
5357330f729Sjoerg     DC = DC->getParent();
5367330f729Sjoerg   }
5377330f729Sjoerg 
5387330f729Sjoerg   ID.AddInteger(Function->getDeclKind());
5397330f729Sjoerg 
5407330f729Sjoerg   const auto *SpecializationArgs = Function->getTemplateSpecializationArgs();
5417330f729Sjoerg   AddBoolean(SpecializationArgs);
5427330f729Sjoerg   if (SpecializationArgs) {
5437330f729Sjoerg     ID.AddInteger(SpecializationArgs->size());
5447330f729Sjoerg     for (const TemplateArgument &TA : SpecializationArgs->asArray()) {
5457330f729Sjoerg       AddTemplateArgument(TA);
5467330f729Sjoerg     }
5477330f729Sjoerg   }
5487330f729Sjoerg 
5497330f729Sjoerg   if (const auto *Method = dyn_cast<CXXMethodDecl>(Function)) {
5507330f729Sjoerg     AddBoolean(Method->isConst());
5517330f729Sjoerg     AddBoolean(Method->isVolatile());
5527330f729Sjoerg   }
5537330f729Sjoerg 
5547330f729Sjoerg   ID.AddInteger(Function->getStorageClass());
5557330f729Sjoerg   AddBoolean(Function->isInlineSpecified());
5567330f729Sjoerg   AddBoolean(Function->isVirtualAsWritten());
5577330f729Sjoerg   AddBoolean(Function->isPure());
5587330f729Sjoerg   AddBoolean(Function->isDeletedAsWritten());
5597330f729Sjoerg   AddBoolean(Function->isExplicitlyDefaulted());
5607330f729Sjoerg 
5617330f729Sjoerg   AddDecl(Function);
5627330f729Sjoerg 
5637330f729Sjoerg   AddQualType(Function->getReturnType());
5647330f729Sjoerg 
5657330f729Sjoerg   ID.AddInteger(Function->param_size());
5667330f729Sjoerg   for (auto Param : Function->parameters())
5677330f729Sjoerg     AddSubDecl(Param);
5687330f729Sjoerg 
5697330f729Sjoerg   if (SkipBody) {
5707330f729Sjoerg     AddBoolean(false);
5717330f729Sjoerg     return;
5727330f729Sjoerg   }
5737330f729Sjoerg 
5747330f729Sjoerg   const bool HasBody = Function->isThisDeclarationADefinition() &&
5757330f729Sjoerg                        !Function->isDefaulted() && !Function->isDeleted() &&
5767330f729Sjoerg                        !Function->isLateTemplateParsed();
5777330f729Sjoerg   AddBoolean(HasBody);
5787330f729Sjoerg   if (!HasBody) {
5797330f729Sjoerg     return;
5807330f729Sjoerg   }
5817330f729Sjoerg 
5827330f729Sjoerg   auto *Body = Function->getBody();
5837330f729Sjoerg   AddBoolean(Body);
5847330f729Sjoerg   if (Body)
5857330f729Sjoerg     AddStmt(Body);
5867330f729Sjoerg 
5877330f729Sjoerg   // Filter out sub-Decls which will not be processed in order to get an
5887330f729Sjoerg   // accurate count of Decl's.
5897330f729Sjoerg   llvm::SmallVector<const Decl *, 16> Decls;
5907330f729Sjoerg   for (Decl *SubDecl : Function->decls()) {
591*e038c9c4Sjoerg     if (isDeclToBeProcessed(SubDecl, Function)) {
5927330f729Sjoerg       Decls.push_back(SubDecl);
5937330f729Sjoerg     }
5947330f729Sjoerg   }
5957330f729Sjoerg 
5967330f729Sjoerg   ID.AddInteger(Decls.size());
5977330f729Sjoerg   for (auto SubDecl : Decls) {
5987330f729Sjoerg     AddSubDecl(SubDecl);
5997330f729Sjoerg   }
6007330f729Sjoerg }
6017330f729Sjoerg 
AddEnumDecl(const EnumDecl * Enum)6027330f729Sjoerg void ODRHash::AddEnumDecl(const EnumDecl *Enum) {
6037330f729Sjoerg   assert(Enum);
6047330f729Sjoerg   AddDeclarationName(Enum->getDeclName());
6057330f729Sjoerg 
6067330f729Sjoerg   AddBoolean(Enum->isScoped());
6077330f729Sjoerg   if (Enum->isScoped())
6087330f729Sjoerg     AddBoolean(Enum->isScopedUsingClassTag());
6097330f729Sjoerg 
6107330f729Sjoerg   if (Enum->getIntegerTypeSourceInfo())
6117330f729Sjoerg     AddQualType(Enum->getIntegerType());
6127330f729Sjoerg 
6137330f729Sjoerg   // Filter out sub-Decls which will not be processed in order to get an
6147330f729Sjoerg   // accurate count of Decl's.
6157330f729Sjoerg   llvm::SmallVector<const Decl *, 16> Decls;
6167330f729Sjoerg   for (Decl *SubDecl : Enum->decls()) {
617*e038c9c4Sjoerg     if (isDeclToBeProcessed(SubDecl, Enum)) {
6187330f729Sjoerg       assert(isa<EnumConstantDecl>(SubDecl) && "Unexpected Decl");
6197330f729Sjoerg       Decls.push_back(SubDecl);
6207330f729Sjoerg     }
6217330f729Sjoerg   }
6227330f729Sjoerg 
6237330f729Sjoerg   ID.AddInteger(Decls.size());
6247330f729Sjoerg   for (auto SubDecl : Decls) {
6257330f729Sjoerg     AddSubDecl(SubDecl);
6267330f729Sjoerg   }
6277330f729Sjoerg 
6287330f729Sjoerg }
6297330f729Sjoerg 
AddDecl(const Decl * D)6307330f729Sjoerg void ODRHash::AddDecl(const Decl *D) {
6317330f729Sjoerg   assert(D && "Expecting non-null pointer.");
6327330f729Sjoerg   D = D->getCanonicalDecl();
6337330f729Sjoerg 
6347330f729Sjoerg   const NamedDecl *ND = dyn_cast<NamedDecl>(D);
6357330f729Sjoerg   AddBoolean(ND);
6367330f729Sjoerg   if (!ND) {
6377330f729Sjoerg     ID.AddInteger(D->getKind());
6387330f729Sjoerg     return;
6397330f729Sjoerg   }
6407330f729Sjoerg 
6417330f729Sjoerg   AddDeclarationName(ND->getDeclName());
6427330f729Sjoerg 
6437330f729Sjoerg   const auto *Specialization =
6447330f729Sjoerg             dyn_cast<ClassTemplateSpecializationDecl>(D);
6457330f729Sjoerg   AddBoolean(Specialization);
6467330f729Sjoerg   if (Specialization) {
6477330f729Sjoerg     const TemplateArgumentList &List = Specialization->getTemplateArgs();
6487330f729Sjoerg     ID.AddInteger(List.size());
6497330f729Sjoerg     for (const TemplateArgument &TA : List.asArray())
6507330f729Sjoerg       AddTemplateArgument(TA);
6517330f729Sjoerg   }
6527330f729Sjoerg }
6537330f729Sjoerg 
6547330f729Sjoerg namespace {
6557330f729Sjoerg // Process a Type pointer.  Add* methods call back into ODRHash while Visit*
6567330f729Sjoerg // methods process the relevant parts of the Type.
6577330f729Sjoerg class ODRTypeVisitor : public TypeVisitor<ODRTypeVisitor> {
6587330f729Sjoerg   typedef TypeVisitor<ODRTypeVisitor> Inherited;
6597330f729Sjoerg   llvm::FoldingSetNodeID &ID;
6607330f729Sjoerg   ODRHash &Hash;
6617330f729Sjoerg 
6627330f729Sjoerg public:
ODRTypeVisitor(llvm::FoldingSetNodeID & ID,ODRHash & Hash)6637330f729Sjoerg   ODRTypeVisitor(llvm::FoldingSetNodeID &ID, ODRHash &Hash)
6647330f729Sjoerg       : ID(ID), Hash(Hash) {}
6657330f729Sjoerg 
AddStmt(Stmt * S)6667330f729Sjoerg   void AddStmt(Stmt *S) {
6677330f729Sjoerg     Hash.AddBoolean(S);
6687330f729Sjoerg     if (S) {
6697330f729Sjoerg       Hash.AddStmt(S);
6707330f729Sjoerg     }
6717330f729Sjoerg   }
6727330f729Sjoerg 
AddDecl(Decl * D)6737330f729Sjoerg   void AddDecl(Decl *D) {
6747330f729Sjoerg     Hash.AddBoolean(D);
6757330f729Sjoerg     if (D) {
6767330f729Sjoerg       Hash.AddDecl(D);
6777330f729Sjoerg     }
6787330f729Sjoerg   }
6797330f729Sjoerg 
AddQualType(QualType T)6807330f729Sjoerg   void AddQualType(QualType T) {
6817330f729Sjoerg     Hash.AddQualType(T);
6827330f729Sjoerg   }
6837330f729Sjoerg 
AddType(const Type * T)6847330f729Sjoerg   void AddType(const Type *T) {
6857330f729Sjoerg     Hash.AddBoolean(T);
6867330f729Sjoerg     if (T) {
6877330f729Sjoerg       Hash.AddType(T);
6887330f729Sjoerg     }
6897330f729Sjoerg   }
6907330f729Sjoerg 
AddNestedNameSpecifier(const NestedNameSpecifier * NNS)6917330f729Sjoerg   void AddNestedNameSpecifier(const NestedNameSpecifier *NNS) {
6927330f729Sjoerg     Hash.AddBoolean(NNS);
6937330f729Sjoerg     if (NNS) {
6947330f729Sjoerg       Hash.AddNestedNameSpecifier(NNS);
6957330f729Sjoerg     }
6967330f729Sjoerg   }
6977330f729Sjoerg 
AddIdentifierInfo(const IdentifierInfo * II)6987330f729Sjoerg   void AddIdentifierInfo(const IdentifierInfo *II) {
6997330f729Sjoerg     Hash.AddBoolean(II);
7007330f729Sjoerg     if (II) {
7017330f729Sjoerg       Hash.AddIdentifierInfo(II);
7027330f729Sjoerg     }
7037330f729Sjoerg   }
7047330f729Sjoerg 
VisitQualifiers(Qualifiers Quals)7057330f729Sjoerg   void VisitQualifiers(Qualifiers Quals) {
7067330f729Sjoerg     ID.AddInteger(Quals.getAsOpaqueValue());
7077330f729Sjoerg   }
7087330f729Sjoerg 
7097330f729Sjoerg   // Return the RecordType if the typedef only strips away a keyword.
7107330f729Sjoerg   // Otherwise, return the original type.
RemoveTypedef(const Type * T)7117330f729Sjoerg   static const Type *RemoveTypedef(const Type *T) {
7127330f729Sjoerg     const auto *TypedefT = dyn_cast<TypedefType>(T);
7137330f729Sjoerg     if (!TypedefT) {
7147330f729Sjoerg       return T;
7157330f729Sjoerg     }
7167330f729Sjoerg 
7177330f729Sjoerg     const TypedefNameDecl *D = TypedefT->getDecl();
7187330f729Sjoerg     QualType UnderlyingType = D->getUnderlyingType();
7197330f729Sjoerg 
7207330f729Sjoerg     if (UnderlyingType.hasLocalQualifiers()) {
7217330f729Sjoerg       return T;
7227330f729Sjoerg     }
7237330f729Sjoerg 
7247330f729Sjoerg     const auto *ElaboratedT = dyn_cast<ElaboratedType>(UnderlyingType);
7257330f729Sjoerg     if (!ElaboratedT) {
7267330f729Sjoerg       return T;
7277330f729Sjoerg     }
7287330f729Sjoerg 
7297330f729Sjoerg     if (ElaboratedT->getQualifier() != nullptr) {
7307330f729Sjoerg       return T;
7317330f729Sjoerg     }
7327330f729Sjoerg 
7337330f729Sjoerg     QualType NamedType = ElaboratedT->getNamedType();
7347330f729Sjoerg     if (NamedType.hasLocalQualifiers()) {
7357330f729Sjoerg       return T;
7367330f729Sjoerg     }
7377330f729Sjoerg 
7387330f729Sjoerg     const auto *RecordT = dyn_cast<RecordType>(NamedType);
7397330f729Sjoerg     if (!RecordT) {
7407330f729Sjoerg       return T;
7417330f729Sjoerg     }
7427330f729Sjoerg 
7437330f729Sjoerg     const IdentifierInfo *TypedefII = TypedefT->getDecl()->getIdentifier();
7447330f729Sjoerg     const IdentifierInfo *RecordII = RecordT->getDecl()->getIdentifier();
7457330f729Sjoerg     if (!TypedefII || !RecordII ||
7467330f729Sjoerg         TypedefII->getName() != RecordII->getName()) {
7477330f729Sjoerg       return T;
7487330f729Sjoerg     }
7497330f729Sjoerg 
7507330f729Sjoerg     return RecordT;
7517330f729Sjoerg   }
7527330f729Sjoerg 
Visit(const Type * T)7537330f729Sjoerg   void Visit(const Type *T) {
7547330f729Sjoerg     T = RemoveTypedef(T);
7557330f729Sjoerg     ID.AddInteger(T->getTypeClass());
7567330f729Sjoerg     Inherited::Visit(T);
7577330f729Sjoerg   }
7587330f729Sjoerg 
VisitType(const Type * T)7597330f729Sjoerg   void VisitType(const Type *T) {}
7607330f729Sjoerg 
VisitAdjustedType(const AdjustedType * T)7617330f729Sjoerg   void VisitAdjustedType(const AdjustedType *T) {
7627330f729Sjoerg     QualType Original = T->getOriginalType();
7637330f729Sjoerg     QualType Adjusted = T->getAdjustedType();
7647330f729Sjoerg 
7657330f729Sjoerg     // The original type and pointee type can be the same, as in the case of
7667330f729Sjoerg     // function pointers decaying to themselves.  Set a bool and only process
7677330f729Sjoerg     // the type once, to prevent doubling the work.
7687330f729Sjoerg     SplitQualType split = Adjusted.split();
7697330f729Sjoerg     if (auto Pointer = dyn_cast<PointerType>(split.Ty)) {
7707330f729Sjoerg       if (Pointer->getPointeeType() == Original) {
7717330f729Sjoerg         Hash.AddBoolean(true);
7727330f729Sjoerg         ID.AddInteger(split.Quals.getAsOpaqueValue());
7737330f729Sjoerg         AddQualType(Original);
7747330f729Sjoerg         VisitType(T);
7757330f729Sjoerg         return;
7767330f729Sjoerg       }
7777330f729Sjoerg     }
7787330f729Sjoerg 
7797330f729Sjoerg     // The original type and pointee type are different, such as in the case
7807330f729Sjoerg     // of a array decaying to an element pointer.  Set a bool to false and
7817330f729Sjoerg     // process both types.
7827330f729Sjoerg     Hash.AddBoolean(false);
7837330f729Sjoerg     AddQualType(Original);
7847330f729Sjoerg     AddQualType(Adjusted);
7857330f729Sjoerg 
7867330f729Sjoerg     VisitType(T);
7877330f729Sjoerg   }
7887330f729Sjoerg 
VisitDecayedType(const DecayedType * T)7897330f729Sjoerg   void VisitDecayedType(const DecayedType *T) {
7907330f729Sjoerg     // getDecayedType and getPointeeType are derived from getAdjustedType
7917330f729Sjoerg     // and don't need to be separately processed.
7927330f729Sjoerg     VisitAdjustedType(T);
7937330f729Sjoerg   }
7947330f729Sjoerg 
VisitArrayType(const ArrayType * T)7957330f729Sjoerg   void VisitArrayType(const ArrayType *T) {
7967330f729Sjoerg     AddQualType(T->getElementType());
7977330f729Sjoerg     ID.AddInteger(T->getSizeModifier());
7987330f729Sjoerg     VisitQualifiers(T->getIndexTypeQualifiers());
7997330f729Sjoerg     VisitType(T);
8007330f729Sjoerg   }
VisitConstantArrayType(const ConstantArrayType * T)8017330f729Sjoerg   void VisitConstantArrayType(const ConstantArrayType *T) {
8027330f729Sjoerg     T->getSize().Profile(ID);
8037330f729Sjoerg     VisitArrayType(T);
8047330f729Sjoerg   }
8057330f729Sjoerg 
VisitDependentSizedArrayType(const DependentSizedArrayType * T)8067330f729Sjoerg   void VisitDependentSizedArrayType(const DependentSizedArrayType *T) {
8077330f729Sjoerg     AddStmt(T->getSizeExpr());
8087330f729Sjoerg     VisitArrayType(T);
8097330f729Sjoerg   }
8107330f729Sjoerg 
VisitIncompleteArrayType(const IncompleteArrayType * T)8117330f729Sjoerg   void VisitIncompleteArrayType(const IncompleteArrayType *T) {
8127330f729Sjoerg     VisitArrayType(T);
8137330f729Sjoerg   }
8147330f729Sjoerg 
VisitVariableArrayType(const VariableArrayType * T)8157330f729Sjoerg   void VisitVariableArrayType(const VariableArrayType *T) {
8167330f729Sjoerg     AddStmt(T->getSizeExpr());
8177330f729Sjoerg     VisitArrayType(T);
8187330f729Sjoerg   }
8197330f729Sjoerg 
VisitAttributedType(const AttributedType * T)8207330f729Sjoerg   void VisitAttributedType(const AttributedType *T) {
8217330f729Sjoerg     ID.AddInteger(T->getAttrKind());
8227330f729Sjoerg     AddQualType(T->getModifiedType());
8237330f729Sjoerg     AddQualType(T->getEquivalentType());
8247330f729Sjoerg 
8257330f729Sjoerg     VisitType(T);
8267330f729Sjoerg   }
8277330f729Sjoerg 
VisitBlockPointerType(const BlockPointerType * T)8287330f729Sjoerg   void VisitBlockPointerType(const BlockPointerType *T) {
8297330f729Sjoerg     AddQualType(T->getPointeeType());
8307330f729Sjoerg     VisitType(T);
8317330f729Sjoerg   }
8327330f729Sjoerg 
VisitBuiltinType(const BuiltinType * T)8337330f729Sjoerg   void VisitBuiltinType(const BuiltinType *T) {
8347330f729Sjoerg     ID.AddInteger(T->getKind());
8357330f729Sjoerg     VisitType(T);
8367330f729Sjoerg   }
8377330f729Sjoerg 
VisitComplexType(const ComplexType * T)8387330f729Sjoerg   void VisitComplexType(const ComplexType *T) {
8397330f729Sjoerg     AddQualType(T->getElementType());
8407330f729Sjoerg     VisitType(T);
8417330f729Sjoerg   }
8427330f729Sjoerg 
VisitDecltypeType(const DecltypeType * T)8437330f729Sjoerg   void VisitDecltypeType(const DecltypeType *T) {
8447330f729Sjoerg     AddStmt(T->getUnderlyingExpr());
8457330f729Sjoerg     AddQualType(T->getUnderlyingType());
8467330f729Sjoerg     VisitType(T);
8477330f729Sjoerg   }
8487330f729Sjoerg 
VisitDependentDecltypeType(const DependentDecltypeType * T)8497330f729Sjoerg   void VisitDependentDecltypeType(const DependentDecltypeType *T) {
8507330f729Sjoerg     VisitDecltypeType(T);
8517330f729Sjoerg   }
8527330f729Sjoerg 
VisitDeducedType(const DeducedType * T)8537330f729Sjoerg   void VisitDeducedType(const DeducedType *T) {
8547330f729Sjoerg     AddQualType(T->getDeducedType());
8557330f729Sjoerg     VisitType(T);
8567330f729Sjoerg   }
8577330f729Sjoerg 
VisitAutoType(const AutoType * T)8587330f729Sjoerg   void VisitAutoType(const AutoType *T) {
8597330f729Sjoerg     ID.AddInteger((unsigned)T->getKeyword());
860*e038c9c4Sjoerg     ID.AddInteger(T->isConstrained());
861*e038c9c4Sjoerg     if (T->isConstrained()) {
862*e038c9c4Sjoerg       AddDecl(T->getTypeConstraintConcept());
863*e038c9c4Sjoerg       ID.AddInteger(T->getNumArgs());
864*e038c9c4Sjoerg       for (const auto &TA : T->getTypeConstraintArguments())
865*e038c9c4Sjoerg         Hash.AddTemplateArgument(TA);
866*e038c9c4Sjoerg     }
8677330f729Sjoerg     VisitDeducedType(T);
8687330f729Sjoerg   }
8697330f729Sjoerg 
VisitDeducedTemplateSpecializationType(const DeducedTemplateSpecializationType * T)8707330f729Sjoerg   void VisitDeducedTemplateSpecializationType(
8717330f729Sjoerg       const DeducedTemplateSpecializationType *T) {
8727330f729Sjoerg     Hash.AddTemplateName(T->getTemplateName());
8737330f729Sjoerg     VisitDeducedType(T);
8747330f729Sjoerg   }
8757330f729Sjoerg 
VisitDependentAddressSpaceType(const DependentAddressSpaceType * T)8767330f729Sjoerg   void VisitDependentAddressSpaceType(const DependentAddressSpaceType *T) {
8777330f729Sjoerg     AddQualType(T->getPointeeType());
8787330f729Sjoerg     AddStmt(T->getAddrSpaceExpr());
8797330f729Sjoerg     VisitType(T);
8807330f729Sjoerg   }
8817330f729Sjoerg 
VisitDependentSizedExtVectorType(const DependentSizedExtVectorType * T)8827330f729Sjoerg   void VisitDependentSizedExtVectorType(const DependentSizedExtVectorType *T) {
8837330f729Sjoerg     AddQualType(T->getElementType());
8847330f729Sjoerg     AddStmt(T->getSizeExpr());
8857330f729Sjoerg     VisitType(T);
8867330f729Sjoerg   }
8877330f729Sjoerg 
VisitFunctionType(const FunctionType * T)8887330f729Sjoerg   void VisitFunctionType(const FunctionType *T) {
8897330f729Sjoerg     AddQualType(T->getReturnType());
8907330f729Sjoerg     T->getExtInfo().Profile(ID);
8917330f729Sjoerg     Hash.AddBoolean(T->isConst());
8927330f729Sjoerg     Hash.AddBoolean(T->isVolatile());
8937330f729Sjoerg     Hash.AddBoolean(T->isRestrict());
8947330f729Sjoerg     VisitType(T);
8957330f729Sjoerg   }
8967330f729Sjoerg 
VisitFunctionNoProtoType(const FunctionNoProtoType * T)8977330f729Sjoerg   void VisitFunctionNoProtoType(const FunctionNoProtoType *T) {
8987330f729Sjoerg     VisitFunctionType(T);
8997330f729Sjoerg   }
9007330f729Sjoerg 
VisitFunctionProtoType(const FunctionProtoType * T)9017330f729Sjoerg   void VisitFunctionProtoType(const FunctionProtoType *T) {
9027330f729Sjoerg     ID.AddInteger(T->getNumParams());
9037330f729Sjoerg     for (auto ParamType : T->getParamTypes())
9047330f729Sjoerg       AddQualType(ParamType);
9057330f729Sjoerg 
9067330f729Sjoerg     VisitFunctionType(T);
9077330f729Sjoerg   }
9087330f729Sjoerg 
VisitInjectedClassNameType(const InjectedClassNameType * T)9097330f729Sjoerg   void VisitInjectedClassNameType(const InjectedClassNameType *T) {
9107330f729Sjoerg     AddDecl(T->getDecl());
9117330f729Sjoerg     VisitType(T);
9127330f729Sjoerg   }
9137330f729Sjoerg 
VisitMemberPointerType(const MemberPointerType * T)9147330f729Sjoerg   void VisitMemberPointerType(const MemberPointerType *T) {
9157330f729Sjoerg     AddQualType(T->getPointeeType());
9167330f729Sjoerg     AddType(T->getClass());
9177330f729Sjoerg     VisitType(T);
9187330f729Sjoerg   }
9197330f729Sjoerg 
VisitObjCObjectPointerType(const ObjCObjectPointerType * T)9207330f729Sjoerg   void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
9217330f729Sjoerg     AddQualType(T->getPointeeType());
9227330f729Sjoerg     VisitType(T);
9237330f729Sjoerg   }
9247330f729Sjoerg 
VisitObjCObjectType(const ObjCObjectType * T)9257330f729Sjoerg   void VisitObjCObjectType(const ObjCObjectType *T) {
9267330f729Sjoerg     AddDecl(T->getInterface());
9277330f729Sjoerg 
9287330f729Sjoerg     auto TypeArgs = T->getTypeArgsAsWritten();
9297330f729Sjoerg     ID.AddInteger(TypeArgs.size());
9307330f729Sjoerg     for (auto Arg : TypeArgs) {
9317330f729Sjoerg       AddQualType(Arg);
9327330f729Sjoerg     }
9337330f729Sjoerg 
9347330f729Sjoerg     auto Protocols = T->getProtocols();
9357330f729Sjoerg     ID.AddInteger(Protocols.size());
9367330f729Sjoerg     for (auto Protocol : Protocols) {
9377330f729Sjoerg       AddDecl(Protocol);
9387330f729Sjoerg     }
9397330f729Sjoerg 
9407330f729Sjoerg     Hash.AddBoolean(T->isKindOfType());
9417330f729Sjoerg 
9427330f729Sjoerg     VisitType(T);
9437330f729Sjoerg   }
9447330f729Sjoerg 
VisitObjCInterfaceType(const ObjCInterfaceType * T)9457330f729Sjoerg   void VisitObjCInterfaceType(const ObjCInterfaceType *T) {
9467330f729Sjoerg     // This type is handled by the parent type ObjCObjectType.
9477330f729Sjoerg     VisitObjCObjectType(T);
9487330f729Sjoerg   }
9497330f729Sjoerg 
VisitObjCTypeParamType(const ObjCTypeParamType * T)9507330f729Sjoerg   void VisitObjCTypeParamType(const ObjCTypeParamType *T) {
9517330f729Sjoerg     AddDecl(T->getDecl());
9527330f729Sjoerg     auto Protocols = T->getProtocols();
9537330f729Sjoerg     ID.AddInteger(Protocols.size());
9547330f729Sjoerg     for (auto Protocol : Protocols) {
9557330f729Sjoerg       AddDecl(Protocol);
9567330f729Sjoerg     }
9577330f729Sjoerg 
9587330f729Sjoerg     VisitType(T);
9597330f729Sjoerg   }
9607330f729Sjoerg 
VisitPackExpansionType(const PackExpansionType * T)9617330f729Sjoerg   void VisitPackExpansionType(const PackExpansionType *T) {
9627330f729Sjoerg     AddQualType(T->getPattern());
9637330f729Sjoerg     VisitType(T);
9647330f729Sjoerg   }
9657330f729Sjoerg 
VisitParenType(const ParenType * T)9667330f729Sjoerg   void VisitParenType(const ParenType *T) {
9677330f729Sjoerg     AddQualType(T->getInnerType());
9687330f729Sjoerg     VisitType(T);
9697330f729Sjoerg   }
9707330f729Sjoerg 
VisitPipeType(const PipeType * T)9717330f729Sjoerg   void VisitPipeType(const PipeType *T) {
9727330f729Sjoerg     AddQualType(T->getElementType());
9737330f729Sjoerg     Hash.AddBoolean(T->isReadOnly());
9747330f729Sjoerg     VisitType(T);
9757330f729Sjoerg   }
9767330f729Sjoerg 
VisitPointerType(const PointerType * T)9777330f729Sjoerg   void VisitPointerType(const PointerType *T) {
9787330f729Sjoerg     AddQualType(T->getPointeeType());
9797330f729Sjoerg     VisitType(T);
9807330f729Sjoerg   }
9817330f729Sjoerg 
VisitReferenceType(const ReferenceType * T)9827330f729Sjoerg   void VisitReferenceType(const ReferenceType *T) {
9837330f729Sjoerg     AddQualType(T->getPointeeTypeAsWritten());
9847330f729Sjoerg     VisitType(T);
9857330f729Sjoerg   }
9867330f729Sjoerg 
VisitLValueReferenceType(const LValueReferenceType * T)9877330f729Sjoerg   void VisitLValueReferenceType(const LValueReferenceType *T) {
9887330f729Sjoerg     VisitReferenceType(T);
9897330f729Sjoerg   }
9907330f729Sjoerg 
VisitRValueReferenceType(const RValueReferenceType * T)9917330f729Sjoerg   void VisitRValueReferenceType(const RValueReferenceType *T) {
9927330f729Sjoerg     VisitReferenceType(T);
9937330f729Sjoerg   }
9947330f729Sjoerg 
9957330f729Sjoerg   void
VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType * T)9967330f729Sjoerg   VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T) {
9977330f729Sjoerg     AddType(T->getReplacedParameter());
9987330f729Sjoerg     Hash.AddTemplateArgument(T->getArgumentPack());
9997330f729Sjoerg     VisitType(T);
10007330f729Sjoerg   }
10017330f729Sjoerg 
VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType * T)10027330f729Sjoerg   void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
10037330f729Sjoerg     AddType(T->getReplacedParameter());
10047330f729Sjoerg     AddQualType(T->getReplacementType());
10057330f729Sjoerg     VisitType(T);
10067330f729Sjoerg   }
10077330f729Sjoerg 
VisitTagType(const TagType * T)10087330f729Sjoerg   void VisitTagType(const TagType *T) {
10097330f729Sjoerg     AddDecl(T->getDecl());
10107330f729Sjoerg     VisitType(T);
10117330f729Sjoerg   }
10127330f729Sjoerg 
VisitRecordType(const RecordType * T)10137330f729Sjoerg   void VisitRecordType(const RecordType *T) { VisitTagType(T); }
VisitEnumType(const EnumType * T)10147330f729Sjoerg   void VisitEnumType(const EnumType *T) { VisitTagType(T); }
10157330f729Sjoerg 
VisitTemplateSpecializationType(const TemplateSpecializationType * T)10167330f729Sjoerg   void VisitTemplateSpecializationType(const TemplateSpecializationType *T) {
10177330f729Sjoerg     ID.AddInteger(T->getNumArgs());
10187330f729Sjoerg     for (const auto &TA : T->template_arguments()) {
10197330f729Sjoerg       Hash.AddTemplateArgument(TA);
10207330f729Sjoerg     }
10217330f729Sjoerg     Hash.AddTemplateName(T->getTemplateName());
10227330f729Sjoerg     VisitType(T);
10237330f729Sjoerg   }
10247330f729Sjoerg 
VisitTemplateTypeParmType(const TemplateTypeParmType * T)10257330f729Sjoerg   void VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
10267330f729Sjoerg     ID.AddInteger(T->getDepth());
10277330f729Sjoerg     ID.AddInteger(T->getIndex());
10287330f729Sjoerg     Hash.AddBoolean(T->isParameterPack());
10297330f729Sjoerg     AddDecl(T->getDecl());
10307330f729Sjoerg   }
10317330f729Sjoerg 
VisitTypedefType(const TypedefType * T)10327330f729Sjoerg   void VisitTypedefType(const TypedefType *T) {
10337330f729Sjoerg     AddDecl(T->getDecl());
10347330f729Sjoerg     QualType UnderlyingType = T->getDecl()->getUnderlyingType();
10357330f729Sjoerg     VisitQualifiers(UnderlyingType.getQualifiers());
10367330f729Sjoerg     while (true) {
10377330f729Sjoerg       if (const TypedefType *Underlying =
10387330f729Sjoerg               dyn_cast<TypedefType>(UnderlyingType.getTypePtr())) {
10397330f729Sjoerg         UnderlyingType = Underlying->getDecl()->getUnderlyingType();
10407330f729Sjoerg         continue;
10417330f729Sjoerg       }
10427330f729Sjoerg       if (const ElaboratedType *Underlying =
10437330f729Sjoerg               dyn_cast<ElaboratedType>(UnderlyingType.getTypePtr())) {
10447330f729Sjoerg         UnderlyingType = Underlying->getNamedType();
10457330f729Sjoerg         continue;
10467330f729Sjoerg       }
10477330f729Sjoerg 
10487330f729Sjoerg       break;
10497330f729Sjoerg     }
10507330f729Sjoerg     AddType(UnderlyingType.getTypePtr());
10517330f729Sjoerg     VisitType(T);
10527330f729Sjoerg   }
10537330f729Sjoerg 
VisitTypeOfExprType(const TypeOfExprType * T)10547330f729Sjoerg   void VisitTypeOfExprType(const TypeOfExprType *T) {
10557330f729Sjoerg     AddStmt(T->getUnderlyingExpr());
10567330f729Sjoerg     Hash.AddBoolean(T->isSugared());
10577330f729Sjoerg     if (T->isSugared())
10587330f729Sjoerg       AddQualType(T->desugar());
10597330f729Sjoerg 
10607330f729Sjoerg     VisitType(T);
10617330f729Sjoerg   }
VisitTypeOfType(const TypeOfType * T)10627330f729Sjoerg   void VisitTypeOfType(const TypeOfType *T) {
10637330f729Sjoerg     AddQualType(T->getUnderlyingType());
10647330f729Sjoerg     VisitType(T);
10657330f729Sjoerg   }
10667330f729Sjoerg 
VisitTypeWithKeyword(const TypeWithKeyword * T)10677330f729Sjoerg   void VisitTypeWithKeyword(const TypeWithKeyword *T) {
10687330f729Sjoerg     ID.AddInteger(T->getKeyword());
10697330f729Sjoerg     VisitType(T);
10707330f729Sjoerg   };
10717330f729Sjoerg 
VisitDependentNameType(const DependentNameType * T)10727330f729Sjoerg   void VisitDependentNameType(const DependentNameType *T) {
10737330f729Sjoerg     AddNestedNameSpecifier(T->getQualifier());
10747330f729Sjoerg     AddIdentifierInfo(T->getIdentifier());
10757330f729Sjoerg     VisitTypeWithKeyword(T);
10767330f729Sjoerg   }
10777330f729Sjoerg 
VisitDependentTemplateSpecializationType(const DependentTemplateSpecializationType * T)10787330f729Sjoerg   void VisitDependentTemplateSpecializationType(
10797330f729Sjoerg       const DependentTemplateSpecializationType *T) {
10807330f729Sjoerg     AddIdentifierInfo(T->getIdentifier());
10817330f729Sjoerg     AddNestedNameSpecifier(T->getQualifier());
10827330f729Sjoerg     ID.AddInteger(T->getNumArgs());
10837330f729Sjoerg     for (const auto &TA : T->template_arguments()) {
10847330f729Sjoerg       Hash.AddTemplateArgument(TA);
10857330f729Sjoerg     }
10867330f729Sjoerg     VisitTypeWithKeyword(T);
10877330f729Sjoerg   }
10887330f729Sjoerg 
VisitElaboratedType(const ElaboratedType * T)10897330f729Sjoerg   void VisitElaboratedType(const ElaboratedType *T) {
10907330f729Sjoerg     AddNestedNameSpecifier(T->getQualifier());
10917330f729Sjoerg     AddQualType(T->getNamedType());
10927330f729Sjoerg     VisitTypeWithKeyword(T);
10937330f729Sjoerg   }
10947330f729Sjoerg 
VisitUnaryTransformType(const UnaryTransformType * T)10957330f729Sjoerg   void VisitUnaryTransformType(const UnaryTransformType *T) {
10967330f729Sjoerg     AddQualType(T->getUnderlyingType());
10977330f729Sjoerg     AddQualType(T->getBaseType());
10987330f729Sjoerg     VisitType(T);
10997330f729Sjoerg   }
11007330f729Sjoerg 
VisitUnresolvedUsingType(const UnresolvedUsingType * T)11017330f729Sjoerg   void VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
11027330f729Sjoerg     AddDecl(T->getDecl());
11037330f729Sjoerg     VisitType(T);
11047330f729Sjoerg   }
11057330f729Sjoerg 
VisitVectorType(const VectorType * T)11067330f729Sjoerg   void VisitVectorType(const VectorType *T) {
11077330f729Sjoerg     AddQualType(T->getElementType());
11087330f729Sjoerg     ID.AddInteger(T->getNumElements());
11097330f729Sjoerg     ID.AddInteger(T->getVectorKind());
11107330f729Sjoerg     VisitType(T);
11117330f729Sjoerg   }
11127330f729Sjoerg 
VisitExtVectorType(const ExtVectorType * T)11137330f729Sjoerg   void VisitExtVectorType(const ExtVectorType * T) {
11147330f729Sjoerg     VisitVectorType(T);
11157330f729Sjoerg   }
11167330f729Sjoerg };
11177330f729Sjoerg } // namespace
11187330f729Sjoerg 
AddType(const Type * T)11197330f729Sjoerg void ODRHash::AddType(const Type *T) {
11207330f729Sjoerg   assert(T && "Expecting non-null pointer.");
11217330f729Sjoerg   ODRTypeVisitor(ID, *this).Visit(T);
11227330f729Sjoerg }
11237330f729Sjoerg 
AddQualType(QualType T)11247330f729Sjoerg void ODRHash::AddQualType(QualType T) {
11257330f729Sjoerg   AddBoolean(T.isNull());
11267330f729Sjoerg   if (T.isNull())
11277330f729Sjoerg     return;
11287330f729Sjoerg   SplitQualType split = T.split();
11297330f729Sjoerg   ID.AddInteger(split.Quals.getAsOpaqueValue());
11307330f729Sjoerg   AddType(split.Ty);
11317330f729Sjoerg }
11327330f729Sjoerg 
AddBoolean(bool Value)11337330f729Sjoerg void ODRHash::AddBoolean(bool Value) {
11347330f729Sjoerg   Bools.push_back(Value);
11357330f729Sjoerg }
1136