diff options
Diffstat (limited to 'clang/lib/Serialization/ASTReader.cpp')
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 72d4c75b063..932803885fa 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -9062,6 +9062,7 @@ void ASTReader::diagnoseOdrViolations() { StaticAssertMessage, StaticAssertOnlyMessage, FieldName, + FieldTypeName, }; // These lambdas have the common portions of the ODR diagnostics. This @@ -9086,6 +9087,12 @@ void ASTReader::diagnoseOdrViolations() { return Hash.CalculateHash(); }; + auto ComputeDeclNameODRHash = [&Hash](const DeclarationName Name) { + Hash.clear(); + Hash.AddDeclarationName(Name); + return Hash.CalculateHash(); + }; + switch (FirstDiffType) { case Other: case EndOfClass: @@ -9166,6 +9173,46 @@ void ASTReader::diagnoseOdrViolations() { Diagnosed = true; break; } + + assert( + Context.hasSameType(FirstField->getType(), SecondField->getType())); + + QualType FirstType = FirstField->getType(); + QualType SecondType = SecondField->getType(); + const TypedefType *FirstTypedef = dyn_cast<TypedefType>(FirstType); + const TypedefType *SecondTypedef = dyn_cast<TypedefType>(SecondType); + + if ((FirstTypedef && !SecondTypedef) || + (!FirstTypedef && SecondTypedef)) { + ODRDiagError(FirstField->getLocation(), FirstField->getSourceRange(), + FieldTypeName) + << FirstII << FirstType; + ODRDiagNote(SecondField->getLocation(), SecondField->getSourceRange(), + FieldTypeName) + << SecondII << SecondType; + + Diagnosed = true; + break; + } + + if (FirstTypedef && SecondTypedef) { + unsigned FirstHash = ComputeDeclNameODRHash( + FirstTypedef->getDecl()->getDeclName()); + unsigned SecondHash = ComputeDeclNameODRHash( + SecondTypedef->getDecl()->getDeclName()); + if (FirstHash != SecondHash) { + ODRDiagError(FirstField->getLocation(), + FirstField->getSourceRange(), FieldTypeName) + << FirstII << FirstType; + ODRDiagNote(SecondField->getLocation(), + SecondField->getSourceRange(), FieldTypeName) + << SecondII << SecondType; + + Diagnosed = true; + break; + } + } + break; } } |