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