diff options
author | Richard Trieu <rtrieu@google.com> | 2017-03-04 00:08:58 +0000 |
---|---|---|
committer | Richard Trieu <rtrieu@google.com> | 2017-03-04 00:08:58 +0000 |
commit | 583e2c175a241dc39dfc28acda8a38514286950e (patch) | |
tree | f87bdaf5f526f144e8db1b25aca6f9ad0676bff1 /clang/lib/Serialization/ASTReader.cpp | |
parent | 71c1958fca2852cd418f89250547861b7c9bb016 (diff) | |
download | bcm5719-llvm-583e2c175a241dc39dfc28acda8a38514286950e.tar.gz bcm5719-llvm-583e2c175a241dc39dfc28acda8a38514286950e.zip |
[ODRHash] Add support for detecting different method properties.
Now print diagnostics for static, virtual, inline, volatile, and const
differences in methods. Also use DeclarationName instead of IdentifierInfo
for additional robustness in diagnostic printing.
llvm-svn: 296932
Diffstat (limited to 'clang/lib/Serialization/ASTReader.cpp')
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 103 |
1 files changed, 98 insertions, 5 deletions
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index fc23e4f7754..c6564d666b2 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -9067,6 +9067,12 @@ void ASTReader::diagnoseOdrViolations() { FieldSingleInitializer, FieldDifferentInitializers, MethodName, + MethodDeleted, + MethodVirtual, + MethodStatic, + MethodVolatile, + MethodConst, + MethodInline, }; // These lambdas have the common portions of the ODR diagnostics. This @@ -9290,16 +9296,103 @@ void ASTReader::diagnoseOdrViolations() { case CXXMethod: { const CXXMethodDecl *FirstMethod = cast<CXXMethodDecl>(FirstDecl); const CXXMethodDecl *SecondMethod = cast<CXXMethodDecl>(SecondDecl); - IdentifierInfo *FirstII = FirstMethod->getIdentifier(); - IdentifierInfo *SecondII = SecondMethod->getIdentifier(); - if (FirstII->getName() != SecondII->getName()) { + auto FirstName = FirstMethod->getDeclName(); + auto SecondName = SecondMethod->getDeclName(); + if (FirstName != SecondName) { ODRDiagError(FirstMethod->getLocation(), FirstMethod->getSourceRange(), MethodName) - << FirstII; + << FirstName; ODRDiagNote(SecondMethod->getLocation(), SecondMethod->getSourceRange(), MethodName) - << SecondII; + << SecondName; + + Diagnosed = true; + break; + } + + const bool FirstDeleted = FirstMethod->isDeleted(); + const bool SecondDeleted = SecondMethod->isDeleted(); + if (FirstDeleted != SecondDeleted) { + ODRDiagError(FirstMethod->getLocation(), + FirstMethod->getSourceRange(), MethodDeleted) + << FirstName << FirstDeleted; + + ODRDiagNote(SecondMethod->getLocation(), + SecondMethod->getSourceRange(), MethodDeleted) + << SecondName << SecondDeleted; + Diagnosed = true; + break; + } + + const bool FirstVirtual = FirstMethod->isVirtualAsWritten(); + const bool SecondVirtual = SecondMethod->isVirtualAsWritten(); + const bool FirstPure = FirstMethod->isPure(); + const bool SecondPure = SecondMethod->isPure(); + if ((FirstVirtual || SecondVirtual) && + (FirstVirtual != SecondVirtual || FirstPure != SecondPure)) { + ODRDiagError(FirstMethod->getLocation(), + FirstMethod->getSourceRange(), MethodVirtual) + << FirstName << FirstPure << FirstVirtual; + ODRDiagNote(SecondMethod->getLocation(), + SecondMethod->getSourceRange(), MethodVirtual) + << SecondName << SecondPure << SecondVirtual; + Diagnosed = true; + break; + } + // CXXMethodDecl::isStatic uses the canonical Decl. With Decl merging, + // FirstDecl is the canonical Decl of SecondDecl, so the storage + // class needs to be checked instead. + const auto FirstStorage = FirstMethod->getStorageClass(); + const auto SecondStorage = SecondMethod->getStorageClass(); + const bool FirstStatic = FirstStorage == SC_Static; + const bool SecondStatic = SecondStorage == SC_Static; + if (FirstStatic != SecondStatic) { + ODRDiagError(FirstMethod->getLocation(), + FirstMethod->getSourceRange(), MethodStatic) + << FirstName << FirstStatic; + ODRDiagNote(SecondMethod->getLocation(), + SecondMethod->getSourceRange(), MethodStatic) + << SecondName << SecondStatic; + Diagnosed = true; + break; + } + + const bool FirstVolatile = FirstMethod->isVolatile(); + const bool SecondVolatile = SecondMethod->isVolatile(); + if (FirstVolatile != SecondVolatile) { + ODRDiagError(FirstMethod->getLocation(), + FirstMethod->getSourceRange(), MethodVolatile) + << FirstName << FirstVolatile; + ODRDiagNote(SecondMethod->getLocation(), + SecondMethod->getSourceRange(), MethodVolatile) + << SecondName << SecondVolatile; + Diagnosed = true; + break; + } + + const bool FirstConst = FirstMethod->isConst(); + const bool SecondConst = SecondMethod->isConst(); + if (FirstConst != SecondConst) { + ODRDiagError(FirstMethod->getLocation(), + FirstMethod->getSourceRange(), MethodConst) + << FirstName << FirstConst; + ODRDiagNote(SecondMethod->getLocation(), + SecondMethod->getSourceRange(), MethodConst) + << SecondName << SecondConst; + Diagnosed = true; + break; + } + + const bool FirstInline = FirstMethod->isInlineSpecified(); + const bool SecondInline = SecondMethod->isInlineSpecified(); + if (FirstInline != SecondInline) { + ODRDiagError(FirstMethod->getLocation(), + FirstMethod->getSourceRange(), MethodInline) + << FirstName << FirstInline; + ODRDiagNote(SecondMethod->getLocation(), + SecondMethod->getSourceRange(), MethodInline) + << SecondName << SecondInline; Diagnosed = true; break; } |