summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorRichard Trieu <rtrieu@google.com>2017-04-11 21:31:00 +0000
committerRichard Trieu <rtrieu@google.com>2017-04-11 21:31:00 +0000
commitfd1acbb9bb372b98e3dcb2be726098a1f7def7e9 (patch)
tree454491711bbbcd296617bbdcd711c2c0b790ebaa /clang/lib
parentf720c036f4b1ac9178410b3d47c3543b9b529a65 (diff)
downloadbcm5719-llvm-fd1acbb9bb372b98e3dcb2be726098a1f7def7e9.tar.gz
bcm5719-llvm-fd1acbb9bb372b98e3dcb2be726098a1f7def7e9.zip
[ODRHash] Improve handling of hash values
Calculating the hash in Sema::ActOnTagFinishDefinition could happen before all sub-Decls were parsed or processed, which would produce the wrong hash value. Change to calculating the hash on the first use and storing the value instead. Also, avoid using the macros that were only for Boolean fields and use an explicit checker during the DefintionData merge. No functional change, but was this blocking other ODRHash patches. llvm-svn: 299989
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/DeclCXX.cpp22
-rw-r--r--clang/lib/Sema/SemaDecl.cpp4
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp6
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp5
4 files changed, 25 insertions, 12 deletions
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index a1aed332a13..2e5cec9c108 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -73,8 +73,9 @@ CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D)
ImplicitCopyAssignmentHasConstParam(true),
HasDeclaredCopyConstructorWithConstParam(false),
HasDeclaredCopyAssignmentWithConstParam(false), IsLambda(false),
- IsParsingBaseSpecifiers(false), ODRHash(0), NumBases(0), NumVBases(0),
- Bases(), VBases(), Definition(D), FirstFriend() {}
+ IsParsingBaseSpecifiers(false), HasODRHash(false), ODRHash(0),
+ NumBases(0), NumVBases(0), Bases(), VBases(), Definition(D),
+ FirstFriend() {}
CXXBaseSpecifier *CXXRecordDecl::DefinitionData::getBasesSlowCase() const {
return Bases.get(Definition->getASTContext().getExternalSource());
@@ -381,16 +382,23 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
data().IsParsingBaseSpecifiers = false;
}
-void CXXRecordDecl::computeODRHash() {
- if (!DefinitionData)
- return;
+unsigned CXXRecordDecl::getODRHash() const {
+ assert(hasDefinition() && "ODRHash only for records with definitions");
- ODRHash Hash;
- Hash.AddCXXRecordDecl(this);
+ // Previously calculated hash is stored in DefinitionData.
+ if (DefinitionData->HasODRHash)
+ return DefinitionData->ODRHash;
+ // Only calculate hash on first call of getODRHash per record.
+ ODRHash Hash;
+ Hash.AddCXXRecordDecl(getDefinition());
+ DefinitionData->HasODRHash = true;
DefinitionData->ODRHash = Hash.CalculateHash();
+
+ return DefinitionData->ODRHash;
}
+
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/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 02cbca8b2bb..c6a0b0101d3 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -13797,10 +13797,8 @@ void Sema::ActOnTagFinishDefinition(Scope *S, Decl *TagD,
RD->completeDefinition();
}
- if (auto *RD = dyn_cast<CXXRecordDecl>(Tag)) {
+ if (isa<CXXRecordDecl>(Tag)) {
FieldCollector->FinishClass();
- if (Context.getLangOpts().Modules)
- RD->computeODRHash();
}
// Exit this scope of this tag's definition.
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index db7d55ec0b8..2fb882c1bec 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -1536,6 +1536,7 @@ void ASTDeclReader::ReadCXXDefinitionData(
Data.HasDeclaredCopyConstructorWithConstParam = Record.readInt();
Data.HasDeclaredCopyAssignmentWithConstParam = Record.readInt();
Data.ODRHash = Record.readInt();
+ Data.HasODRHash = true;
if (Record.readInt()) {
Reader.BodySource[D] = Loc.F->Kind == ModuleKind::MK_MainFile
@@ -1673,7 +1674,6 @@ void ASTDeclReader::MergeDefinitionData(
OR_FIELD(HasDeclaredCopyConstructorWithConstParam)
OR_FIELD(HasDeclaredCopyAssignmentWithConstParam)
MATCH_FIELD(IsLambda)
- MATCH_FIELD(ODRHash)
#undef OR_FIELD
#undef MATCH_FIELD
@@ -1697,6 +1697,10 @@ void ASTDeclReader::MergeDefinitionData(
// when they occur within the body of a function template specialization).
}
+ if (D->getODRHash() != MergeDD.ODRHash) {
+ DetectedOdrViolation = true;
+ }
+
if (DetectedOdrViolation)
Reader.PendingOdrMergeFailures[DD.Definition].push_back(MergeDD.Definition);
}
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index ec59250e192..6f0d0eed5b9 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -5769,7 +5769,10 @@ 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);
+
+ // getODRHash will compute the ODRHash if it has not been previously computed.
+ Record->push_back(D->getODRHash());
+
bool ModularCodegen = Writer->Context->getLangOpts().ModularCodegen &&
Writer->WritingModule && !D->isDependentType();
Record->push_back(ModularCodegen);
OpenPOWER on IntegriCloud