From 7f8ee8422801534de8e432037bf0b6b12183636f Mon Sep 17 00:00:00 2001 From: Richard Trieu Date: Tue, 28 Feb 2017 21:24:38 +0000 Subject: [PATCH] [ODRHash] Add basic support for CXXRecordDecl git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@296521 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Basic/DiagnosticSerializationKinds.td | 10 +++-- lib/AST/ODRHash.cpp | 9 ++++ lib/Serialization/ASTReader.cpp | 23 +++++++++++ test/Modules/odr_hash.cpp | 41 +++++++++++++++++++ 4 files changed, 79 insertions(+), 4 deletions(-) diff --git a/include/clang/Basic/DiagnosticSerializationKinds.td b/include/clang/Basic/DiagnosticSerializationKinds.td index 78efc69f57..4d6ffa1b2a 100644 --- a/include/clang/Basic/DiagnosticSerializationKinds.td +++ b/include/clang/Basic/DiagnosticSerializationKinds.td @@ -121,10 +121,10 @@ def err_module_odr_violation_mismatch_decl : Error< "%q0 has different definitions in different modules; first difference is " "%select{definition in module '%2'|defined here}1 found " "%select{end of class|public access specifier|private access specifier|" - "protected access specifier|static assert|field}3">; + "protected access specifier|static assert|field|method}3">; def note_module_odr_violation_mismatch_decl : Note<"but in '%0' found " "%select{end of class|public access specifier|private access specifier|" - "protected access specifier|static assert|field}1">; + "protected access specifier|static assert|field|method}1">; def err_module_odr_violation_mismatch_decl_diff : Error< "%q0 has different definitions in different modules; first difference is " @@ -139,7 +139,8 @@ def err_module_odr_violation_mismatch_decl_diff : Error< "bitfield %4 with one width expression|" "%select{non-|}5mutable field %4|" "field %4 with %select{no|an}5 initalizer|" - "field %4 with an initializer}3">; + "field %4 with an initializer|" + "method %4}3">; def note_module_odr_violation_mismatch_decl_diff : Note<"but in '%0' found " "%select{" @@ -152,7 +153,8 @@ def note_module_odr_violation_mismatch_decl_diff : Note<"but in '%0' found " "bitfield %2 with different width expression|" "%select{non-|}3mutable field %2|" "field %2 with %select{no|an}3 initializer|" - "field %2 with a different initializer}1">; + "field %2 with a different initializer|" + "method %2}1">; def warn_module_uses_date_time : Warning< "%select{precompiled header|module}0 uses __DATE__ or __TIME__">, diff --git a/lib/AST/ODRHash.cpp b/lib/AST/ODRHash.cpp index d8c2e20ede..78a3eeca03 100644 --- a/lib/AST/ODRHash.cpp +++ b/lib/AST/ODRHash.cpp @@ -194,6 +194,14 @@ public: Inherited::VisitFieldDecl(D); } + + void VisitFunctionDecl(const FunctionDecl *D) { + Inherited::VisitFunctionDecl(D); + } + + void VisitCXXMethodDecl(const CXXMethodDecl *D) { + Inherited::VisitCXXMethodDecl(D); + } }; // Only allow a small portion of Decl's to be processed. Remove this once @@ -206,6 +214,7 @@ bool ODRHash::isWhitelistedDecl(const Decl *D, const CXXRecordDecl *Parent) { default: return false; case Decl::AccessSpec: + case Decl::CXXMethod: case Decl::Field: case Decl::StaticAssert: return true; diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 982f59272e..e9cb51dec6 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -8957,6 +8957,7 @@ void ASTReader::diagnoseOdrViolations() { ProtectedSpecifer, StaticAssert, Field, + CXXMethod, Other } FirstDiffType = Other, SecondDiffType = Other; @@ -8982,6 +8983,8 @@ void ASTReader::diagnoseOdrViolations() { return StaticAssert; case Decl::Field: return Field; + case Decl::CXXMethod: + return CXXMethod; } }; @@ -9068,6 +9071,7 @@ void ASTReader::diagnoseOdrViolations() { FieldSingleMutable, FieldSingleInitializer, FieldDifferentInitializers, + MethodName, }; // These lambdas have the common portions of the ODR diagnostics. This @@ -9288,6 +9292,25 @@ void ASTReader::diagnoseOdrViolations() { break; } + case CXXMethod: { + const CXXMethodDecl *FirstMethod = cast(FirstDecl); + const CXXMethodDecl *SecondMethod = cast(SecondDecl); + IdentifierInfo *FirstII = FirstMethod->getIdentifier(); + IdentifierInfo *SecondII = SecondMethod->getIdentifier(); + if (FirstII->getName() != SecondII->getName()) { + ODRDiagError(FirstMethod->getLocation(), + FirstMethod->getSourceRange(), MethodName) + << FirstII; + ODRDiagNote(SecondMethod->getLocation(), + SecondMethod->getSourceRange(), MethodName) + << SecondII; + + Diagnosed = true; + break; + } + + break; + } } if (Diagnosed == true) diff --git a/test/Modules/odr_hash.cpp b/test/Modules/odr_hash.cpp index e485f633f8..c1ea3b034f 100644 --- a/test/Modules/odr_hash.cpp +++ b/test/Modules/odr_hash.cpp @@ -277,6 +277,39 @@ S11 s11; } // namespace Field +namespace Method { +#if defined(FIRST) +struct S1 { + void A() {} +}; +#elif defined(SECOND) +struct S1 { + private: + void A() {} +}; +#else +S1 s1; +// expected-error@second.h:* {{'Method::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found method}} +#endif + +#if defined(FIRST) +struct S2 { + void A() {} + void B() {} +}; +#elif defined(SECOND) +struct S2 { + void B() {} + void A() {} +}; +#else +S2 s2; +// expected-error@second.h:* {{'Method::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'B'}} +// expected-note@first.h:* {{but in 'FirstModule' found method 'A'}} +#endif +} // namespace Method + // Naive parsing of AST can lead to cycles in processing. Ensure // self-references don't trigger an endless cycles of AST node processing. namespace SelfReference { @@ -324,6 +357,8 @@ struct S { unsigned b : 2*2 + 5/2; mutable int c = sizeof(x + y); + + void method() {} }; #elif defined(SECOND) typedef int INT; @@ -344,6 +379,8 @@ struct S { unsigned b : 2 * 2 + 5 / 2; mutable int c = sizeof(x + y); + + void method() {} }; #else S s; @@ -369,6 +406,8 @@ struct T { mutable int c = sizeof(x + y); + void method() {} + private: }; #elif defined(SECOND) @@ -391,6 +430,8 @@ struct T { mutable int c = sizeof(x + y); + void method() {} + public: }; #else -- 2.40.0