Author: rtrieu Date: Wed Feb 22 18:23:01 2017 New Revision: 295911 URL: http://llvm.org/viewvc/llvm-project?rev=295911&view=rev Log: [ODRHash] Add IdentiferInfo and FieldDecl support.
IdentifierInfo is hashed based on the stored string. FieldDecl versus other Decl is now detected, as well as differently named fields. Differential Revision: https://reviews.llvm.org/D21675 Modified: cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td cfe/trunk/lib/AST/ODRHash.cpp cfe/trunk/lib/Serialization/ASTReader.cpp cfe/trunk/test/Modules/odr_hash.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td?rev=295911&r1=295910&r2=295911&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td Wed Feb 22 18:23:01 2017 @@ -121,10 +121,10 @@ def err_module_odr_violation_mismatch_de "%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}3">; + "protected access specifier|static assert|field}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}1">; + "protected access specifier|static assert|field}1">; def err_module_odr_violation_mismatch_decl_diff : Error< "%q0 has different definitions in different modules; first difference is " @@ -132,13 +132,15 @@ def err_module_odr_violation_mismatch_de "%select{" "static assert with condition|" "static assert with message|" - "static assert with %select{|no }4message}3">; + "static assert with %select{|no }4message|" + "field %4}3">; def note_module_odr_violation_mismatch_decl_diff : Note<"but in '%0' found " "%select{" "static assert with different condition|" "static assert with different message|" - "static assert with %select{|no }2message}1">; + "static assert with %select{|no }2message|" + "field %2}1">; def warn_module_uses_date_time : Warning< "%select{precompiled header|module}0 uses __DATE__ or __TIME__">, Modified: cfe/trunk/lib/AST/ODRHash.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ODRHash.cpp?rev=295911&r1=295910&r2=295911&view=diff ============================================================================== --- cfe/trunk/lib/AST/ODRHash.cpp (original) +++ cfe/trunk/lib/AST/ODRHash.cpp Wed Feb 22 18:23:01 2017 @@ -26,7 +26,12 @@ void ODRHash::AddStmt(const Stmt *S) { assert(S && "Expecting non-null pointer."); S->ProcessODRHash(ID, *this); } -void ODRHash::AddIdentifierInfo(const IdentifierInfo *II) {} + +void ODRHash::AddIdentifierInfo(const IdentifierInfo *II) { + assert(II && "Expecting non-null pointer."); + ID.AddString(II->getName()); +} + void ODRHash::AddNestedNameSpecifier(const NestedNameSpecifier *NNS) {} void ODRHash::AddTemplateName(TemplateName Name) {} void ODRHash::AddDeclarationName(DeclarationName Name) {} @@ -90,11 +95,23 @@ public: } } + void AddIdentifierInfo(const IdentifierInfo *II) { + Hash.AddBoolean(II); + if (II) { + Hash.AddIdentifierInfo(II); + } + } + void Visit(const Decl *D) { ID.AddInteger(D->getKind()); Inherited::Visit(D); } + void VisitNamedDecl(const NamedDecl *D) { + AddIdentifierInfo(D->getIdentifier()); + Inherited::VisitNamedDecl(D); + } + void VisitAccessSpecDecl(const AccessSpecDecl *D) { ID.AddInteger(D->getAccess()); Inherited::VisitAccessSpecDecl(D); @@ -106,6 +123,10 @@ public: Inherited::VisitStaticAssertDecl(D); } + + void VisitFieldDecl(const FieldDecl *D) { + Inherited::VisitFieldDecl(D); + } }; // Only allow a small portion of Decl's to be processed. Remove this once @@ -118,6 +139,7 @@ bool ODRHash::isWhitelistedDecl(const De default: return false; case Decl::AccessSpec: + case Decl::Field: case Decl::StaticAssert: return true; } Modified: cfe/trunk/lib/Serialization/ASTReader.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=295911&r1=295910&r2=295911&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTReader.cpp (original) +++ cfe/trunk/lib/Serialization/ASTReader.cpp Wed Feb 22 18:23:01 2017 @@ -8956,6 +8956,7 @@ void ASTReader::diagnoseOdrViolations() PrivateSpecifer, ProtectedSpecifer, StaticAssert, + Field, Other } FirstDiffType = Other, SecondDiffType = Other; @@ -8979,6 +8980,8 @@ void ASTReader::diagnoseOdrViolations() llvm_unreachable("Invalid access specifier"); case Decl::StaticAssert: return StaticAssert; + case Decl::Field: + return Field; } }; @@ -9058,6 +9061,7 @@ void ASTReader::diagnoseOdrViolations() StaticAssertCondition, StaticAssertMessage, StaticAssertOnlyMessage, + FieldName, }; // These lambdas have the common portions of the ODR diagnostics. This @@ -9144,6 +9148,24 @@ void ASTReader::diagnoseOdrViolations() Diagnosed = true; break; } + break; + } + case Field: { + FieldDecl *FirstField = cast<FieldDecl>(FirstDecl); + FieldDecl *SecondField = cast<FieldDecl>(SecondDecl); + IdentifierInfo *FirstII = FirstField->getIdentifier(); + IdentifierInfo *SecondII = SecondField->getIdentifier(); + if (FirstII->getName() != SecondII->getName()) { + ODRDiagError(FirstField->getLocation(), FirstField->getSourceRange(), + FieldName) + << FirstII; + ODRDiagNote(SecondField->getLocation(), SecondField->getSourceRange(), + FieldName) + << SecondII; + + Diagnosed = true; + break; + } break; } } Modified: cfe/trunk/test/Modules/odr_hash.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/odr_hash.cpp?rev=295911&r1=295910&r2=295911&view=diff ============================================================================== --- cfe/trunk/test/Modules/odr_hash.cpp (original) +++ cfe/trunk/test/Modules/odr_hash.cpp Wed Feb 22 18:23:01 2017 @@ -115,6 +115,41 @@ S4 s4; #endif } +namespace Field { +#if defined(FIRST) +struct S1 { + int x; + private: + int y; +}; +#elif defined(SECOND) +struct S1 { + int x; + int y; +}; +#else +S1 s1; +// expected-error@second.h:* {{'Field::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found field}} +// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}} +#endif + +#if defined(FIRST) +struct S2 { + int x; + int y; +}; +#elif defined(SECOND) +struct S2 { + int y; + int x; +}; +#else +S2 s2; +// expected-error@second.h:* {{'Field::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'y'}} +// expected-note@first.h:* {{but in 'FirstModule' found field 'x'}} +#endif +} // namespace Field + // 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 { @@ -151,6 +186,9 @@ struct S { static_assert(1 == 1, "Message"); static_assert(2 == 2); + + int x; + double y; }; #elif defined(SECOND) struct S { @@ -160,6 +198,9 @@ struct S { static_assert(1 == 1, "Message"); static_assert(2 == 2); + + int x; + double y; }; #else S s; @@ -174,6 +215,9 @@ struct T { static_assert(1 == 1, "Message"); static_assert(2 == 2); + int x; + double y; + private: }; #elif defined(SECOND) @@ -185,6 +229,9 @@ struct T { static_assert(1 == 1, "Message"); static_assert(2 == 2); + int x; + double y; + public: }; #else _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits