From: Richard Trieu Date: Sat, 18 Feb 2017 02:09:28 +0000 (+0000) Subject: Part of adding an improved ODR checker. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=182eb8f62d1fdb0c9620af8e5a3d40b60baff409;p=clang Part of adding an improved ODR checker. Reserve a spot for ODR hash in CXXRecordDecl and in its modules storage. Default the hash value to 0 for all classes. Differential Revision: https://reviews.llvm.org/D21675 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@295533 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 7267afdc7f..d321d19068 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -458,6 +458,9 @@ class CXXRecordDecl : public RecordDecl { /// \brief Whether we are currently parsing base specifiers. unsigned IsParsingBaseSpecifiers : 1; + /// \brief A hash of parts of the class to help in ODR checking. + unsigned ODRHash; + /// \brief The number of base class specifiers in Bases. unsigned NumBases; @@ -703,6 +706,9 @@ public: return data().IsParsingBaseSpecifiers; } + void computeODRHash(); + unsigned getODRHash() const { return data().ODRHash; } + /// \brief Sets the base classes of this struct or class. void setBases(CXXBaseSpecifier const * const *Bases, unsigned NumBases); diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index fdfd6c0705..19ffe1a720 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -71,8 +71,8 @@ CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D) ImplicitCopyAssignmentHasConstParam(true), HasDeclaredCopyConstructorWithConstParam(false), HasDeclaredCopyAssignmentWithConstParam(false), IsLambda(false), - IsParsingBaseSpecifiers(false), NumBases(0), NumVBases(0), Bases(), - VBases(), Definition(D), FirstFriend() {} + IsParsingBaseSpecifiers(false), ODRHash(0), NumBases(0), NumVBases(0), + Bases(), VBases(), Definition(D), FirstFriend() {} CXXBaseSpecifier *CXXRecordDecl::DefinitionData::getBasesSlowCase() const { return Bases.get(Definition->getASTContext().getExternalSource()); @@ -371,6 +371,8 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases, data().IsParsingBaseSpecifiers = false; } +void CXXRecordDecl::computeODRHash() {} + void CXXRecordDecl::addedClassSubobject(CXXRecordDecl *Subobj) { // C++11 [class.copy]p11: // A defaulted copy/move constructor for a class X is defined as diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 77d7498302..e96860a294 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -13771,8 +13771,11 @@ void Sema::ActOnTagFinishDefinition(Scope *S, Decl *TagD, RD->completeDefinition(); } - if (isa(Tag)) + if (auto *RD = dyn_cast(Tag)) { FieldCollector->FinishClass(); + if (Context.getLangOpts().Modules) + RD->computeODRHash(); + } // Exit this scope of this tag's definition. PopDeclContext(); diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index add3b3e828..0f43e9fcf6 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -1528,6 +1528,7 @@ void ASTDeclReader::ReadCXXDefinitionData( Data.ImplicitCopyAssignmentHasConstParam = Record.readInt(); Data.HasDeclaredCopyConstructorWithConstParam = Record.readInt(); Data.HasDeclaredCopyAssignmentWithConstParam = Record.readInt(); + Data.ODRHash = Record.readInt(); Data.NumBases = Record.readInt(); if (Data.NumBases) @@ -1658,6 +1659,7 @@ void ASTDeclReader::MergeDefinitionData( OR_FIELD(HasDeclaredCopyConstructorWithConstParam) OR_FIELD(HasDeclaredCopyAssignmentWithConstParam) MATCH_FIELD(IsLambda) + MATCH_FIELD(ODRHash) #undef OR_FIELD #undef MATCH_FIELD diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 5dee86c141..5fe693ba8e 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -5707,6 +5707,7 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) { Record->push_back(Data.ImplicitCopyAssignmentHasConstParam); Record->push_back(Data.HasDeclaredCopyConstructorWithConstParam); Record->push_back(Data.HasDeclaredCopyAssignmentWithConstParam); + Record->push_back(Data.ODRHash); // IsLambda bit is already saved. Record->push_back(Data.NumBases);