brintos

brintos / llvm-project-archived public Read only

0
0
Text · 36.6 KiB · 46a4e25 Raw
1320 lines · cpp
1//===-- ODRHash.cpp - Hashing to diagnose ODR failures ----------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// This file implements the ODRHash class, which calculates a hash based11/// on AST nodes, which is stable across different runs.12///13//===----------------------------------------------------------------------===//14 15#include "clang/AST/ODRHash.h"16 17#include "clang/AST/DeclVisitor.h"18#include "clang/AST/NestedNameSpecifier.h"19#include "clang/AST/TypeVisitor.h"20 21using namespace clang;22 23void ODRHash::AddStmt(const Stmt *S) {24  assert(S && "Expecting non-null pointer.");25  S->ProcessODRHash(ID, *this);26}27 28void ODRHash::AddIdentifierInfo(const IdentifierInfo *II) {29  assert(II && "Expecting non-null pointer.");30  ID.AddString(II->getName());31}32 33void ODRHash::AddDeclarationNameInfo(DeclarationNameInfo NameInfo,34                                     bool TreatAsDecl) {35  if (TreatAsDecl)36    // Matches the NamedDecl check in AddDecl37    AddBoolean(true);38 39  AddDeclarationNameInfoImpl(NameInfo);40 41  if (TreatAsDecl)42    // Matches the ClassTemplateSpecializationDecl check in AddDecl43    AddBoolean(false);44}45 46void ODRHash::AddDeclarationNameInfoImpl(DeclarationNameInfo NameInfo) {47  DeclarationName Name = NameInfo.getName();48  // Index all DeclarationName and use index numbers to refer to them.49  auto Result = DeclNameMap.insert(std::make_pair(Name, DeclNameMap.size()));50  ID.AddInteger(Result.first->second);51  if (!Result.second) {52    // If found in map, the DeclarationName has previously been processed.53    return;54  }55 56  // First time processing each DeclarationName, also process its details.57  AddBoolean(Name.isEmpty());58  if (Name.isEmpty())59    return;60 61  auto Kind = Name.getNameKind();62  ID.AddInteger(Kind);63  switch (Kind) {64  case DeclarationName::Identifier:65    AddIdentifierInfo(Name.getAsIdentifierInfo());66    break;67  case DeclarationName::ObjCZeroArgSelector:68  case DeclarationName::ObjCOneArgSelector:69  case DeclarationName::ObjCMultiArgSelector: {70    Selector S = Name.getObjCSelector();71    AddBoolean(S.isNull());72    AddBoolean(S.isKeywordSelector());73    AddBoolean(S.isUnarySelector());74    unsigned NumArgs = S.getNumArgs();75    ID.AddInteger(NumArgs);76    // Compare all selector slots. For selectors with arguments it means all arg77    // slots. And if there are no arguments, compare the first-and-only slot.78    unsigned SlotsToCheck = NumArgs > 0 ? NumArgs : 1;79    for (unsigned i = 0; i < SlotsToCheck; ++i) {80      const IdentifierInfo *II = S.getIdentifierInfoForSlot(i);81      AddBoolean(II);82      if (II) {83        AddIdentifierInfo(II);84      }85    }86    break;87  }88  case DeclarationName::CXXConstructorName:89  case DeclarationName::CXXDestructorName:90  case DeclarationName::CXXConversionFunctionName:91    if (auto *TSI = NameInfo.getNamedTypeInfo())92      AddQualType(TSI->getType());93    else94      AddQualType(Name.getCXXNameType());95    break;96  case DeclarationName::CXXOperatorName:97    ID.AddInteger(Name.getCXXOverloadedOperator());98    break;99  case DeclarationName::CXXLiteralOperatorName:100    AddIdentifierInfo(Name.getCXXLiteralIdentifier());101    break;102  case DeclarationName::CXXUsingDirective:103    break;104  case DeclarationName::CXXDeductionGuideName: {105    auto *Template = Name.getCXXDeductionGuideTemplate();106    AddBoolean(Template);107    if (Template) {108      AddDecl(Template);109    }110  }111  }112}113 114void ODRHash::AddNestedNameSpecifier(NestedNameSpecifier NNS) {115  auto Kind = NNS.getKind();116  ID.AddInteger(llvm::to_underlying(Kind));117  switch (Kind) {118  case NestedNameSpecifier::Kind::Namespace: {119    auto [Namespace, Prefix] = NNS.getAsNamespaceAndPrefix();120    AddDecl(Namespace);121    AddNestedNameSpecifier(Prefix);122    break;123  }124  case NestedNameSpecifier::Kind::Type:125    AddType(NNS.getAsType());126    break;127  case NestedNameSpecifier::Kind::Null:128  case NestedNameSpecifier::Kind::Global:129  case NestedNameSpecifier::Kind::MicrosoftSuper:130    break;131  }132}133 134void ODRHash::AddDependentTemplateName(const DependentTemplateStorage &Name) {135  AddNestedNameSpecifier(Name.getQualifier());136  if (IdentifierOrOverloadedOperator IO = Name.getName();137      const IdentifierInfo *II = IO.getIdentifier())138    AddIdentifierInfo(II);139  else140    ID.AddInteger(IO.getOperator());141}142 143void ODRHash::AddTemplateName(TemplateName Name) {144  auto Kind = Name.getKind();145  ID.AddInteger(Kind);146 147  switch (Kind) {148  case TemplateName::Template:149    AddDecl(Name.getAsTemplateDecl());150    break;151  case TemplateName::QualifiedTemplate: {152    QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName();153    AddNestedNameSpecifier(QTN->getQualifier());154    AddBoolean(QTN->hasTemplateKeyword());155    AddTemplateName(QTN->getUnderlyingTemplate());156    break;157  }158  case TemplateName::DependentTemplate: {159    AddDependentTemplateName(*Name.getAsDependentTemplateName());160    break;161  }162  // TODO: Support these cases.163  case TemplateName::OverloadedTemplate:164  case TemplateName::AssumedTemplate:165  case TemplateName::SubstTemplateTemplateParm:166  case TemplateName::SubstTemplateTemplateParmPack:167  case TemplateName::UsingTemplate:168    break;169  case TemplateName::DeducedTemplate:170    llvm_unreachable("Unexpected DeducedTemplate");171  }172}173 174void ODRHash::AddTemplateArgument(TemplateArgument TA) {175  const auto Kind = TA.getKind();176  ID.AddInteger(Kind);177 178  switch (Kind) {179    case TemplateArgument::Null:180      llvm_unreachable("Expected valid TemplateArgument");181    case TemplateArgument::Type:182      AddQualType(TA.getAsType());183      break;184    case TemplateArgument::Declaration:185      AddDecl(TA.getAsDecl());186      break;187    case TemplateArgument::NullPtr:188      ID.AddPointer(nullptr);189      break;190    case TemplateArgument::Integral: {191      // There are integrals (e.g.: _BitInt(128)) that cannot be represented as192      // any builtin integral type, so we use the hash of APSInt instead.193      TA.getAsIntegral().Profile(ID);194      break;195    }196    case TemplateArgument::StructuralValue:197      AddQualType(TA.getStructuralValueType());198      AddStructuralValue(TA.getAsStructuralValue());199      break;200    case TemplateArgument::Template:201    case TemplateArgument::TemplateExpansion:202      AddTemplateName(TA.getAsTemplateOrTemplatePattern());203      break;204    case TemplateArgument::Expression:205      AddStmt(TA.getAsExpr());206      break;207    case TemplateArgument::Pack:208      ID.AddInteger(TA.pack_size());209      for (auto SubTA : TA.pack_elements()) {210        AddTemplateArgument(SubTA);211      }212      break;213  }214}215 216void ODRHash::AddTemplateParameterList(const TemplateParameterList *TPL) {217  assert(TPL && "Expecting non-null pointer.");218 219  ID.AddInteger(TPL->size());220  for (auto *ND : TPL->asArray()) {221    AddSubDecl(ND);222  }223}224 225void ODRHash::clear() {226  DeclNameMap.clear();227  Bools.clear();228  ID.clear();229}230 231unsigned ODRHash::CalculateHash() {232  // Append the bools to the end of the data segment backwards.  This allows233  // for the bools data to be compressed 32 times smaller compared to using234  // ID.AddBoolean235  const unsigned unsigned_bits = sizeof(unsigned) * CHAR_BIT;236  const unsigned size = Bools.size();237  const unsigned remainder = size % unsigned_bits;238  const unsigned loops = size / unsigned_bits;239  auto I = Bools.rbegin();240  unsigned value = 0;241  for (unsigned i = 0; i < remainder; ++i) {242    value <<= 1;243    value |= *I;244    ++I;245  }246  ID.AddInteger(value);247 248  for (unsigned i = 0; i < loops; ++i) {249    value = 0;250    for (unsigned j = 0; j < unsigned_bits; ++j) {251      value <<= 1;252      value |= *I;253      ++I;254    }255    ID.AddInteger(value);256  }257 258  assert(I == Bools.rend());259  Bools.clear();260  return ID.computeStableHash();261}262 263namespace {264// Process a Decl pointer.  Add* methods call back into ODRHash while Visit*265// methods process the relevant parts of the Decl.266class ODRDeclVisitor : public ConstDeclVisitor<ODRDeclVisitor> {267  typedef ConstDeclVisitor<ODRDeclVisitor> Inherited;268  llvm::FoldingSetNodeID &ID;269  ODRHash &Hash;270 271public:272  ODRDeclVisitor(llvm::FoldingSetNodeID &ID, ODRHash &Hash)273      : ID(ID), Hash(Hash) {}274 275  void AddStmt(const Stmt *S) {276    Hash.AddBoolean(S);277    if (S) {278      Hash.AddStmt(S);279    }280  }281 282  void AddIdentifierInfo(const IdentifierInfo *II) {283    Hash.AddBoolean(II);284    if (II) {285      Hash.AddIdentifierInfo(II);286    }287  }288 289  void AddQualType(QualType T) {290    Hash.AddQualType(T);291  }292 293  void AddDecl(const Decl *D) {294    Hash.AddBoolean(D);295    if (D) {296      Hash.AddDecl(D);297    }298  }299 300  void AddTemplateArgument(TemplateArgument TA) {301    Hash.AddTemplateArgument(TA);302  }303 304  void Visit(const Decl *D) {305    ID.AddInteger(D->getKind());306    Inherited::Visit(D);307  }308 309  void VisitNamedDecl(const NamedDecl *D) {310    if (const auto *FD = dyn_cast<FunctionDecl>(D))311      Hash.AddDeclarationNameInfo(FD->getNameInfo());312    else313      Hash.AddDeclarationName(D->getDeclName());314    Inherited::VisitNamedDecl(D);315  }316 317  void VisitValueDecl(const ValueDecl *D) {318    if (auto *DD = dyn_cast<DeclaratorDecl>(D); DD && DD->getTypeSourceInfo())319      AddQualType(DD->getTypeSourceInfo()->getType());320 321    Inherited::VisitValueDecl(D);322  }323 324  void VisitVarDecl(const VarDecl *D) {325    Hash.AddBoolean(D->isStaticLocal());326    Hash.AddBoolean(D->isConstexpr());327    const bool HasInit = D->hasInit();328    Hash.AddBoolean(HasInit);329    if (HasInit) {330      AddStmt(D->getInit());331    }332    Inherited::VisitVarDecl(D);333  }334 335  void VisitParmVarDecl(const ParmVarDecl *D) {336    // TODO: Handle default arguments.337    Inherited::VisitParmVarDecl(D);338  }339 340  void VisitAccessSpecDecl(const AccessSpecDecl *D) {341    ID.AddInteger(D->getAccess());342    Inherited::VisitAccessSpecDecl(D);343  }344 345  void VisitStaticAssertDecl(const StaticAssertDecl *D) {346    AddStmt(D->getAssertExpr());347    AddStmt(D->getMessage());348 349    Inherited::VisitStaticAssertDecl(D);350  }351 352  void VisitFieldDecl(const FieldDecl *D) {353    const bool IsBitfield = D->isBitField();354    Hash.AddBoolean(IsBitfield);355 356    if (IsBitfield) {357      AddStmt(D->getBitWidth());358    }359 360    Hash.AddBoolean(D->isMutable());361    AddStmt(D->getInClassInitializer());362 363    Inherited::VisitFieldDecl(D);364  }365 366  void VisitObjCIvarDecl(const ObjCIvarDecl *D) {367    ID.AddInteger(D->getCanonicalAccessControl());368    Inherited::VisitObjCIvarDecl(D);369  }370 371  void VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {372    ID.AddInteger(D->getPropertyAttributes());373    ID.AddInteger(D->getPropertyImplementation());374    AddQualType(D->getTypeSourceInfo()->getType());375    AddDecl(D);376 377    Inherited::VisitObjCPropertyDecl(D);378  }379 380  void VisitFunctionDecl(const FunctionDecl *D) {381    // Handled by the ODRHash for FunctionDecl382    ID.AddInteger(D->getODRHash());383 384    Inherited::VisitFunctionDecl(D);385  }386 387  void VisitCXXMethodDecl(const CXXMethodDecl *D) {388    // Handled by the ODRHash for FunctionDecl389 390    Inherited::VisitCXXMethodDecl(D);391  }392 393  void VisitObjCMethodDecl(const ObjCMethodDecl *Method) {394    ID.AddInteger(Method->getDeclKind());395    Hash.AddBoolean(Method->isInstanceMethod()); // false if class method396    Hash.AddBoolean(Method->isVariadic());397    Hash.AddBoolean(Method->isSynthesizedAccessorStub());398    Hash.AddBoolean(Method->isDefined());399    Hash.AddBoolean(Method->isDirectMethod());400    Hash.AddBoolean(Method->isThisDeclarationADesignatedInitializer());401    Hash.AddBoolean(Method->hasSkippedBody());402 403    ID.AddInteger(llvm::to_underlying(Method->getImplementationControl()));404    ID.AddInteger(Method->getMethodFamily());405    ImplicitParamDecl *Cmd = Method->getCmdDecl();406    Hash.AddBoolean(Cmd);407    if (Cmd)408      ID.AddInteger(llvm::to_underlying(Cmd->getParameterKind()));409 410    ImplicitParamDecl *Self = Method->getSelfDecl();411    Hash.AddBoolean(Self);412    if (Self)413      ID.AddInteger(llvm::to_underlying(Self->getParameterKind()));414 415    AddDecl(Method);416 417    if (Method->getReturnTypeSourceInfo())418      AddQualType(Method->getReturnTypeSourceInfo()->getType());419 420    ID.AddInteger(Method->param_size());421    for (auto Param : Method->parameters())422      Hash.AddSubDecl(Param);423 424    if (Method->hasBody()) {425      const bool IsDefinition = Method->isThisDeclarationADefinition();426      Hash.AddBoolean(IsDefinition);427      if (IsDefinition) {428        Stmt *Body = Method->getBody();429        Hash.AddBoolean(Body);430        if (Body)431          AddStmt(Body);432 433        // Filter out sub-Decls which will not be processed in order to get an434        // accurate count of Decl's.435        llvm::SmallVector<const Decl *, 16> Decls;436        for (Decl *SubDecl : Method->decls())437          if (ODRHash::isSubDeclToBeProcessed(SubDecl, Method))438            Decls.push_back(SubDecl);439 440        ID.AddInteger(Decls.size());441        for (auto SubDecl : Decls)442          Hash.AddSubDecl(SubDecl);443      }444    } else {445      Hash.AddBoolean(false);446    }447 448    Inherited::VisitObjCMethodDecl(Method);449  }450 451  void VisitTypedefNameDecl(const TypedefNameDecl *D) {452    AddQualType(D->getUnderlyingType());453 454    Inherited::VisitTypedefNameDecl(D);455  }456 457  void VisitTypedefDecl(const TypedefDecl *D) {458    Inherited::VisitTypedefDecl(D);459  }460 461  void VisitTypeAliasDecl(const TypeAliasDecl *D) {462    Inherited::VisitTypeAliasDecl(D);463  }464 465  void VisitFriendDecl(const FriendDecl *D) {466    TypeSourceInfo *TSI = D->getFriendType();467    Hash.AddBoolean(TSI);468    if (TSI) {469      AddQualType(TSI->getType());470    } else {471      AddDecl(D->getFriendDecl());472    }473    Hash.AddBoolean(D->isPackExpansion());474  }475 476  void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {477    // Only care about default arguments as part of the definition.478    const bool hasDefaultArgument =479        D->hasDefaultArgument() && !D->defaultArgumentWasInherited();480    Hash.AddBoolean(hasDefaultArgument);481    if (hasDefaultArgument) {482      AddTemplateArgument(D->getDefaultArgument().getArgument());483    }484    Hash.AddBoolean(D->isParameterPack());485 486    const TypeConstraint *TC = D->getTypeConstraint();487    Hash.AddBoolean(TC != nullptr);488    if (TC)489      AddStmt(TC->getImmediatelyDeclaredConstraint());490 491    Inherited::VisitTemplateTypeParmDecl(D);492  }493 494  void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {495    // Only care about default arguments as part of the definition.496    const bool hasDefaultArgument =497        D->hasDefaultArgument() && !D->defaultArgumentWasInherited();498    Hash.AddBoolean(hasDefaultArgument);499    if (hasDefaultArgument) {500      AddTemplateArgument(D->getDefaultArgument().getArgument());501    }502    Hash.AddBoolean(D->isParameterPack());503 504    Inherited::VisitNonTypeTemplateParmDecl(D);505  }506 507  void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D) {508    // Only care about default arguments as part of the definition.509    const bool hasDefaultArgument =510        D->hasDefaultArgument() && !D->defaultArgumentWasInherited();511    Hash.AddBoolean(hasDefaultArgument);512    if (hasDefaultArgument) {513      AddTemplateArgument(D->getDefaultArgument().getArgument());514    }515    Hash.AddBoolean(D->isParameterPack());516 517    Inherited::VisitTemplateTemplateParmDecl(D);518  }519 520  void VisitTemplateDecl(const TemplateDecl *D) {521    Hash.AddTemplateParameterList(D->getTemplateParameters());522 523    Inherited::VisitTemplateDecl(D);524  }525 526  void VisitRedeclarableTemplateDecl(const RedeclarableTemplateDecl *D) {527    Hash.AddBoolean(D->isMemberSpecialization());528    Inherited::VisitRedeclarableTemplateDecl(D);529  }530 531  void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {532    AddDecl(D->getTemplatedDecl());533    ID.AddInteger(D->getTemplatedDecl()->getODRHash());534    Inherited::VisitFunctionTemplateDecl(D);535  }536 537  void VisitEnumConstantDecl(const EnumConstantDecl *D) {538    AddStmt(D->getInitExpr());539    Inherited::VisitEnumConstantDecl(D);540  }541};542} // namespace543 544// Only allow a small portion of Decl's to be processed.  Remove this once545// all Decl's can be handled.546bool ODRHash::isSubDeclToBeProcessed(const Decl *D, const DeclContext *Parent) {547  if (D->isImplicit()) return false;548  if (D->getDeclContext() != Parent) return false;549 550  switch (D->getKind()) {551    default:552      return false;553    case Decl::AccessSpec:554    case Decl::CXXConstructor:555    case Decl::CXXDestructor:556    case Decl::CXXMethod:557    case Decl::EnumConstant: // Only found in EnumDecl's.558    case Decl::Field:559    case Decl::Friend:560    case Decl::FunctionTemplate:561    case Decl::StaticAssert:562    case Decl::TypeAlias:563    case Decl::Typedef:564    case Decl::Var:565    case Decl::ObjCMethod:566    case Decl::ObjCIvar:567    case Decl::ObjCProperty:568      return true;569  }570}571 572void ODRHash::AddSubDecl(const Decl *D) {573  assert(D && "Expecting non-null pointer.");574 575  ODRDeclVisitor(ID, *this).Visit(D);576}577 578void ODRHash::AddCXXRecordDecl(const CXXRecordDecl *Record) {579  assert(Record && Record->hasDefinition() &&580         "Expected non-null record to be a definition.");581 582  const DeclContext *DC = Record;583  while (DC) {584    if (isa<ClassTemplateSpecializationDecl>(DC)) {585      return;586    }587    DC = DC->getParent();588  }589 590  AddDecl(Record);591 592  // Filter out sub-Decls which will not be processed in order to get an593  // accurate count of Decl's.594  llvm::SmallVector<const Decl *, 16> Decls;595  for (Decl *SubDecl : Record->decls()) {596    if (isSubDeclToBeProcessed(SubDecl, Record)) {597      Decls.push_back(SubDecl);598      if (auto *Function = dyn_cast<FunctionDecl>(SubDecl)) {599        // Compute/Preload ODRHash into FunctionDecl.600        Function->getODRHash();601      }602    }603  }604 605  ID.AddInteger(Decls.size());606  for (auto SubDecl : Decls) {607    AddSubDecl(SubDecl);608  }609 610  const ClassTemplateDecl *TD = Record->getDescribedClassTemplate();611  AddBoolean(TD);612  if (TD) {613    AddTemplateParameterList(TD->getTemplateParameters());614  }615 616  ID.AddInteger(Record->getNumBases());617  auto Bases = Record->bases();618  for (const auto &Base : Bases) {619    AddQualType(Base.getTypeSourceInfo()->getType());620    ID.AddInteger(Base.isVirtual());621    ID.AddInteger(Base.getAccessSpecifierAsWritten());622  }623}624 625void ODRHash::AddRecordDecl(const RecordDecl *Record) {626  assert(!isa<CXXRecordDecl>(Record) &&627         "For CXXRecordDecl should call AddCXXRecordDecl.");628  AddDecl(Record);629 630  // Filter out sub-Decls which will not be processed in order to get an631  // accurate count of Decl's.632  llvm::SmallVector<const Decl *, 16> Decls;633  for (Decl *SubDecl : Record->decls()) {634    if (isSubDeclToBeProcessed(SubDecl, Record))635      Decls.push_back(SubDecl);636  }637 638  ID.AddInteger(Decls.size());639  for (const Decl *SubDecl : Decls)640    AddSubDecl(SubDecl);641}642 643void ODRHash::AddObjCInterfaceDecl(const ObjCInterfaceDecl *IF) {644  AddDecl(IF);645 646  auto *SuperClass = IF->getSuperClass();647  AddBoolean(SuperClass);648  if (SuperClass)649    ID.AddInteger(SuperClass->getODRHash());650 651  // Hash referenced protocols.652  ID.AddInteger(IF->getReferencedProtocols().size());653  for (const ObjCProtocolDecl *RefP : IF->protocols()) {654    // Hash the name only as a referenced protocol can be a forward declaration.655    AddDeclarationName(RefP->getDeclName());656  }657 658  // Filter out sub-Decls which will not be processed in order to get an659  // accurate count of Decl's.660  llvm::SmallVector<const Decl *, 16> Decls;661  for (Decl *SubDecl : IF->decls())662    if (isSubDeclToBeProcessed(SubDecl, IF))663      Decls.push_back(SubDecl);664 665  ID.AddInteger(Decls.size());666  for (auto *SubDecl : Decls)667    AddSubDecl(SubDecl);668}669 670void ODRHash::AddFunctionDecl(const FunctionDecl *Function,671                              bool SkipBody) {672  assert(Function && "Expecting non-null pointer.");673 674  // Skip functions that are specializations or in specialization context.675  const DeclContext *DC = Function;676  while (DC) {677    if (isa<ClassTemplateSpecializationDecl>(DC)) return;678    if (auto *F = dyn_cast<FunctionDecl>(DC)) {679      if (F->isFunctionTemplateSpecialization()) {680        if (!isa<CXXMethodDecl>(DC)) return;681        if (DC->getLexicalParent()->isFileContext()) return;682        // Skip class scope explicit function template specializations,683        // as they have not yet been instantiated.684        if (F->getDependentSpecializationInfo())685          return;686        // Inline method specializations are the only supported687        // specialization for now.688      }689    }690    DC = DC->getParent();691  }692 693  ID.AddInteger(Function->getDeclKind());694 695  const auto *SpecializationArgs = Function->getTemplateSpecializationArgs();696  AddBoolean(SpecializationArgs);697  if (SpecializationArgs) {698    ID.AddInteger(SpecializationArgs->size());699    for (const TemplateArgument &TA : SpecializationArgs->asArray()) {700      AddTemplateArgument(TA);701    }702  }703 704  if (const auto *Method = dyn_cast<CXXMethodDecl>(Function)) {705    AddBoolean(Method->isConst());706    AddBoolean(Method->isVolatile());707  }708 709  ID.AddInteger(Function->getStorageClass());710  AddBoolean(Function->isInlineSpecified());711  AddBoolean(Function->isVirtualAsWritten());712  AddBoolean(Function->isPureVirtual());713  AddBoolean(Function->isDeletedAsWritten());714  AddBoolean(Function->isExplicitlyDefaulted());715 716  StringLiteral *DeletedMessage = Function->getDeletedMessage();717  AddBoolean(DeletedMessage);718 719  if (DeletedMessage)720    ID.AddString(DeletedMessage->getBytes());721 722  AddDecl(Function);723 724  AddQualType(Function->getReturnType());725 726  ID.AddInteger(Function->param_size());727  for (auto *Param : Function->parameters())728    AddSubDecl(Param);729 730  if (SkipBody) {731    AddBoolean(false);732    return;733  }734 735  const bool HasBody = Function->isThisDeclarationADefinition() &&736                       !Function->isDefaulted() && !Function->isDeleted() &&737                       !Function->isLateTemplateParsed();738  AddBoolean(HasBody);739  if (!HasBody) {740    return;741  }742 743  auto *Body = Function->getBody();744  AddBoolean(Body);745  if (Body)746    AddStmt(Body);747 748  // Filter out sub-Decls which will not be processed in order to get an749  // accurate count of Decl's.750  llvm::SmallVector<const Decl *, 16> Decls;751  for (Decl *SubDecl : Function->decls()) {752    if (isSubDeclToBeProcessed(SubDecl, Function)) {753      Decls.push_back(SubDecl);754    }755  }756 757  ID.AddInteger(Decls.size());758  for (auto SubDecl : Decls) {759    AddSubDecl(SubDecl);760  }761}762 763void ODRHash::AddEnumDecl(const EnumDecl *Enum) {764  assert(Enum);765  AddDeclarationName(Enum->getDeclName());766 767  AddBoolean(Enum->isScoped());768  if (Enum->isScoped())769    AddBoolean(Enum->isScopedUsingClassTag());770 771  if (Enum->getIntegerTypeSourceInfo())772    AddQualType(Enum->getIntegerType().getCanonicalType());773 774  // Filter out sub-Decls which will not be processed in order to get an775  // accurate count of Decl's.776  llvm::SmallVector<const Decl *, 16> Decls;777  for (Decl *SubDecl : Enum->decls()) {778    if (isSubDeclToBeProcessed(SubDecl, Enum)) {779      assert(isa<EnumConstantDecl>(SubDecl) && "Unexpected Decl");780      Decls.push_back(SubDecl);781    }782  }783 784  ID.AddInteger(Decls.size());785  for (auto SubDecl : Decls) {786    AddSubDecl(SubDecl);787  }788 789}790 791void ODRHash::AddObjCProtocolDecl(const ObjCProtocolDecl *P) {792  AddDecl(P);793 794  // Hash referenced protocols.795  ID.AddInteger(P->getReferencedProtocols().size());796  for (const ObjCProtocolDecl *RefP : P->protocols()) {797    // Hash the name only as a referenced protocol can be a forward declaration.798    AddDeclarationName(RefP->getDeclName());799  }800 801  // Filter out sub-Decls which will not be processed in order to get an802  // accurate count of Decl's.803  llvm::SmallVector<const Decl *, 16> Decls;804  for (Decl *SubDecl : P->decls()) {805    if (isSubDeclToBeProcessed(SubDecl, P)) {806      Decls.push_back(SubDecl);807    }808  }809 810  ID.AddInteger(Decls.size());811  for (auto *SubDecl : Decls) {812    AddSubDecl(SubDecl);813  }814}815 816void ODRHash::AddDecl(const Decl *D) {817  assert(D && "Expecting non-null pointer.");818  D = D->getCanonicalDecl();819 820  const NamedDecl *ND = dyn_cast<NamedDecl>(D);821  AddBoolean(ND);822  if (!ND) {823    ID.AddInteger(D->getKind());824    return;825  }826 827  if (auto *FD = dyn_cast<FunctionDecl>(D))828    AddDeclarationNameInfo(FD->getNameInfo());829  else830    AddDeclarationName(ND->getDeclName());831 832  // If this was a specialization we should take into account its template833  // arguments. This helps to reduce collisions coming when visiting template834  // specialization types (eg. when processing type template arguments).835  ArrayRef<TemplateArgument> Args;836  if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D))837    Args = CTSD->getTemplateArgs().asArray();838  else if (auto *VTSD = dyn_cast<VarTemplateSpecializationDecl>(D))839    Args = VTSD->getTemplateArgs().asArray();840  else if (auto *FD = dyn_cast<FunctionDecl>(D))841    if (FD->getTemplateSpecializationArgs())842      Args = FD->getTemplateSpecializationArgs()->asArray();843 844  for (auto &TA : Args)845    AddTemplateArgument(TA);846}847 848namespace {849// Process a Type pointer.  Add* methods call back into ODRHash while Visit*850// methods process the relevant parts of the Type.851class ODRTypeVisitor : public TypeVisitor<ODRTypeVisitor> {852  typedef TypeVisitor<ODRTypeVisitor> Inherited;853  llvm::FoldingSetNodeID &ID;854  ODRHash &Hash;855 856public:857  ODRTypeVisitor(llvm::FoldingSetNodeID &ID, ODRHash &Hash)858      : ID(ID), Hash(Hash) {}859 860  void AddStmt(Stmt *S) {861    Hash.AddBoolean(S);862    if (S) {863      Hash.AddStmt(S);864    }865  }866 867  void AddDecl(const Decl *D) {868    Hash.AddBoolean(D);869    if (D) {870      Hash.AddDecl(D);871    }872  }873 874  void AddQualType(QualType T) {875    Hash.AddQualType(T);876  }877 878  void AddType(const Type *T) {879    Hash.AddBoolean(T);880    if (T) {881      Hash.AddType(T);882    }883  }884 885  void AddNestedNameSpecifier(NestedNameSpecifier NNS) {886    Hash.AddNestedNameSpecifier(NNS);887  }888 889  void AddIdentifierInfo(const IdentifierInfo *II) {890    Hash.AddBoolean(II);891    if (II) {892      Hash.AddIdentifierInfo(II);893    }894  }895 896  void VisitQualifiers(Qualifiers Quals) {897    ID.AddInteger(Quals.getAsOpaqueValue());898  }899 900  // Handle typedefs which only strip away a keyword.901  bool handleTypedef(const Type *T) {902    const auto *TypedefT = dyn_cast<TypedefType>(T);903    if (!TypedefT)904      return false;905 906    QualType UnderlyingType = TypedefT->desugar();907 908    if (UnderlyingType.hasLocalQualifiers())909      return false;910 911    const auto *TagT = dyn_cast<TagType>(UnderlyingType);912    if (!TagT || TagT->getQualifier())913      return false;914 915    if (TypedefT->getDecl()->getIdentifier() !=916        TagT->getDecl()->getIdentifier())917      return false;918 919    ID.AddInteger(TagT->getTypeClass());920    VisitTagType(TagT, /*ElaboratedOverride=*/TypedefT);921    return true;922  }923 924  void Visit(const Type *T) {925    if (handleTypedef(T))926      return;927    ID.AddInteger(T->getTypeClass());928    Inherited::Visit(T);929  }930 931  void VisitType(const Type *T) {}932 933  void VisitAdjustedType(const AdjustedType *T) {934    AddQualType(T->getOriginalType());935 936    VisitType(T);937  }938 939  void VisitDecayedType(const DecayedType *T) {940    // getDecayedType and getPointeeType are derived from getAdjustedType941    // and don't need to be separately processed.942    VisitAdjustedType(T);943  }944 945  void VisitArrayType(const ArrayType *T) {946    AddQualType(T->getElementType());947    ID.AddInteger(llvm::to_underlying(T->getSizeModifier()));948    VisitQualifiers(T->getIndexTypeQualifiers());949    VisitType(T);950  }951  void VisitConstantArrayType(const ConstantArrayType *T) {952    T->getSize().Profile(ID);953    VisitArrayType(T);954  }955 956  void VisitArrayParameterType(const ArrayParameterType *T) {957    VisitConstantArrayType(T);958  }959 960  void VisitDependentSizedArrayType(const DependentSizedArrayType *T) {961    AddStmt(T->getSizeExpr());962    VisitArrayType(T);963  }964 965  void VisitIncompleteArrayType(const IncompleteArrayType *T) {966    VisitArrayType(T);967  }968 969  void VisitVariableArrayType(const VariableArrayType *T) {970    AddStmt(T->getSizeExpr());971    VisitArrayType(T);972  }973 974  void VisitAttributedType(const AttributedType *T) {975    ID.AddInteger(T->getAttrKind());976    AddQualType(T->getModifiedType());977 978    VisitType(T);979  }980 981  void VisitBlockPointerType(const BlockPointerType *T) {982    AddQualType(T->getPointeeType());983    VisitType(T);984  }985 986  void VisitBuiltinType(const BuiltinType *T) {987    ID.AddInteger(T->getKind());988    VisitType(T);989  }990 991  void VisitComplexType(const ComplexType *T) {992    AddQualType(T->getElementType());993    VisitType(T);994  }995 996  void VisitDecltypeType(const DecltypeType *T) {997    Hash.AddStmt(T->getUnderlyingExpr());998    VisitType(T);999  }1000 1001  void VisitDependentDecltypeType(const DependentDecltypeType *T) {1002    VisitDecltypeType(T);1003  }1004 1005  void VisitDeducedType(const DeducedType *T) {1006    AddQualType(T->getDeducedType());1007    VisitType(T);1008  }1009 1010  void VisitAutoType(const AutoType *T) {1011    ID.AddInteger((unsigned)T->getKeyword());1012    ID.AddInteger(T->isConstrained());1013    if (T->isConstrained()) {1014      AddDecl(T->getTypeConstraintConcept());1015      ID.AddInteger(T->getTypeConstraintArguments().size());1016      for (const auto &TA : T->getTypeConstraintArguments())1017        Hash.AddTemplateArgument(TA);1018    }1019    VisitDeducedType(T);1020  }1021 1022  void VisitDeducedTemplateSpecializationType(1023      const DeducedTemplateSpecializationType *T) {1024    Hash.AddTemplateName(T->getTemplateName());1025    VisitDeducedType(T);1026  }1027 1028  void VisitDependentAddressSpaceType(const DependentAddressSpaceType *T) {1029    AddQualType(T->getPointeeType());1030    AddStmt(T->getAddrSpaceExpr());1031    VisitType(T);1032  }1033 1034  void VisitDependentSizedExtVectorType(const DependentSizedExtVectorType *T) {1035    AddQualType(T->getElementType());1036    AddStmt(T->getSizeExpr());1037    VisitType(T);1038  }1039 1040  void VisitFunctionType(const FunctionType *T) {1041    AddQualType(T->getReturnType());1042    T->getExtInfo().Profile(ID);1043    Hash.AddBoolean(T->isConst());1044    Hash.AddBoolean(T->isVolatile());1045    Hash.AddBoolean(T->isRestrict());1046    VisitType(T);1047  }1048 1049  void VisitFunctionNoProtoType(const FunctionNoProtoType *T) {1050    VisitFunctionType(T);1051  }1052 1053  void VisitFunctionProtoType(const FunctionProtoType *T) {1054    ID.AddInteger(T->getNumParams());1055    for (auto ParamType : T->getParamTypes())1056      AddQualType(ParamType);1057 1058    VisitFunctionType(T);1059  }1060 1061  void VisitInjectedClassNameType(const InjectedClassNameType *T) {1062    AddDecl(T->getDecl()->getDefinitionOrSelf());1063    VisitType(T);1064  }1065 1066  void VisitMemberPointerType(const MemberPointerType *T) {1067    AddQualType(T->getPointeeType());1068    AddNestedNameSpecifier(T->getQualifier());1069    VisitType(T);1070  }1071 1072  void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {1073    AddQualType(T->getPointeeType());1074    VisitType(T);1075  }1076 1077  void VisitObjCObjectType(const ObjCObjectType *T) {1078    AddDecl(T->getInterface());1079 1080    auto TypeArgs = T->getTypeArgsAsWritten();1081    ID.AddInteger(TypeArgs.size());1082    for (auto Arg : TypeArgs) {1083      AddQualType(Arg);1084    }1085 1086    auto Protocols = T->getProtocols();1087    ID.AddInteger(Protocols.size());1088    for (auto *Protocol : Protocols) {1089      AddDecl(Protocol);1090    }1091 1092    Hash.AddBoolean(T->isKindOfType());1093 1094    VisitType(T);1095  }1096 1097  void VisitObjCInterfaceType(const ObjCInterfaceType *T) {1098    // This type is handled by the parent type ObjCObjectType.1099    VisitObjCObjectType(T);1100  }1101 1102  void VisitObjCTypeParamType(const ObjCTypeParamType *T) {1103    AddDecl(T->getDecl());1104    auto Protocols = T->getProtocols();1105    ID.AddInteger(Protocols.size());1106    for (auto *Protocol : Protocols) {1107      AddDecl(Protocol);1108    }1109 1110    VisitType(T);1111  }1112 1113  void VisitPackExpansionType(const PackExpansionType *T) {1114    AddQualType(T->getPattern());1115    VisitType(T);1116  }1117 1118  void VisitParenType(const ParenType *T) {1119    AddQualType(T->getInnerType());1120    VisitType(T);1121  }1122 1123  void VisitPipeType(const PipeType *T) {1124    AddQualType(T->getElementType());1125    Hash.AddBoolean(T->isReadOnly());1126    VisitType(T);1127  }1128 1129  void VisitPointerType(const PointerType *T) {1130    AddQualType(T->getPointeeType());1131    VisitType(T);1132  }1133 1134  void VisitReferenceType(const ReferenceType *T) {1135    AddQualType(T->getPointeeTypeAsWritten());1136    VisitType(T);1137  }1138 1139  void VisitLValueReferenceType(const LValueReferenceType *T) {1140    VisitReferenceType(T);1141  }1142 1143  void VisitRValueReferenceType(const RValueReferenceType *T) {1144    VisitReferenceType(T);1145  }1146 1147  void1148  VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T) {1149    AddDecl(T->getAssociatedDecl());1150    Hash.AddTemplateArgument(T->getArgumentPack());1151    VisitType(T);1152  }1153 1154  void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {1155    AddDecl(T->getAssociatedDecl());1156    AddQualType(T->getReplacementType());1157    VisitType(T);1158  }1159 1160  void VisitTagType(const TagType *T,1161                    const TypedefType *ElaboratedOverride = nullptr) {1162    ID.AddInteger(llvm::to_underlying(1163        ElaboratedOverride ? ElaboratedTypeKeyword::None : T->getKeyword()));1164    AddNestedNameSpecifier(ElaboratedOverride1165                               ? ElaboratedOverride->getQualifier()1166                               : T->getQualifier());1167    AddDecl(T->getDecl()->getDefinitionOrSelf());1168    VisitType(T);1169  }1170 1171  void VisitTemplateSpecializationType(const TemplateSpecializationType *T) {1172    ID.AddInteger(T->template_arguments().size());1173    for (const auto &TA : T->template_arguments()) {1174      Hash.AddTemplateArgument(TA);1175    }1176    Hash.AddTemplateName(T->getTemplateName());1177    VisitType(T);1178  }1179 1180  void VisitTemplateTypeParmType(const TemplateTypeParmType *T) {1181    ID.AddInteger(T->getDepth());1182    ID.AddInteger(T->getIndex());1183    Hash.AddBoolean(T->isParameterPack());1184    AddDecl(T->getDecl());1185  }1186 1187  void VisitTypedefType(const TypedefType *T) {1188    ID.AddInteger(llvm::to_underlying(T->getKeyword()));1189    AddNestedNameSpecifier(T->getQualifier());1190    AddDecl(T->getDecl());1191    VisitType(T);1192  }1193 1194  void VisitTypeOfExprType(const TypeOfExprType *T) {1195    AddStmt(T->getUnderlyingExpr());1196    Hash.AddBoolean(T->isSugared());1197 1198    VisitType(T);1199  }1200  void VisitTypeOfType(const TypeOfType *T) {1201    AddQualType(T->getUnmodifiedType());1202    VisitType(T);1203  }1204 1205  void VisitTypeWithKeyword(const TypeWithKeyword *T) {1206    ID.AddInteger(llvm::to_underlying(T->getKeyword()));1207    VisitType(T);1208  };1209 1210  void VisitDependentNameType(const DependentNameType *T) {1211    AddNestedNameSpecifier(T->getQualifier());1212    AddIdentifierInfo(T->getIdentifier());1213    VisitTypeWithKeyword(T);1214  }1215 1216  void VisitUnaryTransformType(const UnaryTransformType *T) {1217    AddQualType(T->getUnderlyingType());1218    AddQualType(T->getBaseType());1219    VisitType(T);1220  }1221 1222  void VisitUnresolvedUsingType(const UnresolvedUsingType *T) {1223    AddDecl(T->getDecl());1224    VisitType(T);1225  }1226 1227  void VisitVectorType(const VectorType *T) {1228    AddQualType(T->getElementType());1229    ID.AddInteger(T->getNumElements());1230    ID.AddInteger(llvm::to_underlying(T->getVectorKind()));1231    VisitType(T);1232  }1233 1234  void VisitExtVectorType(const ExtVectorType * T) {1235    VisitVectorType(T);1236  }1237};1238} // namespace1239 1240void ODRHash::AddType(const Type *T) {1241  assert(T && "Expecting non-null pointer.");1242  ODRTypeVisitor(ID, *this).Visit(T);1243}1244 1245void ODRHash::AddQualType(QualType T) {1246  AddBoolean(T.isNull());1247  if (T.isNull())1248    return;1249  SplitQualType split = T.split();1250  ID.AddInteger(split.Quals.getAsOpaqueValue());1251  AddType(split.Ty);1252}1253 1254void ODRHash::AddBoolean(bool Value) {1255  Bools.push_back(Value);1256}1257 1258void ODRHash::AddStructuralValue(const APValue &Value) {1259  ID.AddInteger(Value.getKind());1260 1261  // 'APValue::Profile' uses pointer values to make hash for LValue and1262  // MemberPointer, but they differ from one compiler invocation to another.1263  // So, handle them explicitly here.1264 1265  switch (Value.getKind()) {1266  case APValue::LValue: {1267    const APValue::LValueBase &Base = Value.getLValueBase();1268    if (!Base) {1269      ID.AddInteger(Value.getLValueOffset().getQuantity());1270      break;1271    }1272 1273    assert(Base.is<const ValueDecl *>());1274    AddDecl(Base.get<const ValueDecl *>());1275    ID.AddInteger(Value.getLValueOffset().getQuantity());1276 1277    bool OnePastTheEnd = Value.isLValueOnePastTheEnd();1278    if (Value.hasLValuePath()) {1279      QualType TypeSoFar = Base.getType();1280      for (APValue::LValuePathEntry E : Value.getLValuePath()) {1281        if (const auto *AT = TypeSoFar->getAsArrayTypeUnsafe()) {1282          if (const auto *CAT = dyn_cast<ConstantArrayType>(AT))1283            OnePastTheEnd |= CAT->getSize() == E.getAsArrayIndex();1284          TypeSoFar = AT->getElementType();1285        } else {1286          const Decl *D = E.getAsBaseOrMember().getPointer();1287          if (const auto *FD = dyn_cast<FieldDecl>(D)) {1288            if (FD->getParent()->isUnion())1289              ID.AddInteger(FD->getFieldIndex());1290            TypeSoFar = FD->getType();1291          } else {1292            TypeSoFar =1293                D->getASTContext().getCanonicalTagType(cast<CXXRecordDecl>(D));1294          }1295        }1296      }1297    }1298    unsigned Val = 0;1299    if (Value.isNullPointer())1300      Val |= 1 << 0;1301    if (OnePastTheEnd)1302      Val |= 1 << 1;1303    if (Value.hasLValuePath())1304      Val |= 1 << 2;1305    ID.AddInteger(Val);1306    break;1307  }1308  case APValue::MemberPointer: {1309    const ValueDecl *D = Value.getMemberPointerDecl();1310    assert(D);1311    AddDecl(D);1312    ID.AddInteger(1313        D->getASTContext().getMemberPointerPathAdjustment(Value).getQuantity());1314    break;1315  }1316  default:1317    Value.Profile(ID);1318  }1319}1320