Author: rtrieu Date: Tue May 16 21:29:02 2017 New Revision: 303231 URL: http://llvm.org/viewvc/llvm-project?rev=303231&view=rev Log: [ODRHash] Support more types in the ODR checker.
Added support for TagType, TypeWithKeyword, and all children types. Modified: cfe/trunk/lib/AST/ODRHash.cpp cfe/trunk/test/Modules/odr_hash.cpp Modified: cfe/trunk/lib/AST/ODRHash.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ODRHash.cpp?rev=303231&r1=303230&r2=303231&view=diff ============================================================================== --- cfe/trunk/lib/AST/ODRHash.cpp (original) +++ cfe/trunk/lib/AST/ODRHash.cpp Tue May 16 21:29:02 2017 @@ -335,6 +335,20 @@ public: Hash.AddQualType(T); } + void AddNestedNameSpecifier(const NestedNameSpecifier *NNS) { + Hash.AddBoolean(NNS); + if (NNS) { + Hash.AddNestedNameSpecifier(NNS); + } + } + + void AddIdentifierInfo(const IdentifierInfo *II) { + Hash.AddBoolean(II); + if (II) { + Hash.AddIdentifierInfo(II); + } + } + void VisitQualifiers(Qualifiers Quals) { ID.AddInteger(Quals.getAsOpaqueValue()); } @@ -414,6 +428,42 @@ public: AddQualType(T->getDecl()->getUnderlyingType().getCanonicalType()); VisitType(T); } + + void VisitTagType(const TagType *T) { + AddDecl(T->getDecl()); + VisitType(T); + } + + void VisitRecordType(const RecordType *T) { VisitTagType(T); } + void VisitEnumType(const EnumType *T) { VisitTagType(T); } + + void VisitTypeWithKeyword(const TypeWithKeyword *T) { + ID.AddInteger(T->getKeyword()); + VisitType(T); + }; + + void VisitDependentNameType(const DependentNameType *T) { + AddNestedNameSpecifier(T->getQualifier()); + AddIdentifierInfo(T->getIdentifier()); + VisitTypeWithKeyword(T); + } + + void VisitDependentTemplateSpecializationType( + const DependentTemplateSpecializationType *T) { + AddIdentifierInfo(T->getIdentifier()); + AddNestedNameSpecifier(T->getQualifier()); + ID.AddInteger(T->getNumArgs()); + for (const auto &TA : T->template_arguments()) { + Hash.AddTemplateArgument(TA); + } + VisitTypeWithKeyword(T); + } + + void VisitElaboratedType(const ElaboratedType *T) { + AddNestedNameSpecifier(T->getQualifier()); + AddQualType(T->getNamedType()); + VisitTypeWithKeyword(T); + } }; void ODRHash::AddType(const Type *T) { Modified: cfe/trunk/test/Modules/odr_hash.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/odr_hash.cpp?rev=303231&r1=303230&r2=303231&view=diff ============================================================================== --- cfe/trunk/test/Modules/odr_hash.cpp (original) +++ cfe/trunk/test/Modules/odr_hash.cpp Tue May 16 21:29:02 2017 @@ -634,6 +634,78 @@ S3 s3; #endif } // namespace Using +namespace RecordType { +#if defined(FIRST) +struct B1 {}; +struct S1 { + B1 x; +}; +#elif defined(SECOND) +struct A1 {}; +struct S1 { + A1 x; +}; +#else +S1 s1; +// expected-error@first.h:* {{'RecordType::S1::x' from module 'FirstModule' is not present in definition of 'RecordType::S1' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'x' does not match}} +#endif +} + +namespace DependentType { +#if defined(FIRST) +template <class T> +class S1 { + typename T::typeA x; +}; +#elif defined(SECOND) +template <class T> +class S1 { + typename T::typeB x; +}; +#else +template<class T> +using U1 = S1<T>; +// expected-error@first.h:* {{'DependentType::S1::x' from module 'FirstModule' is not present in definition of 'S1<T>' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'x' does not match}} +#endif +} + +namespace ElaboratedType { +#if defined(FIRST) +namespace N1 { using type = double; } +struct S1 { + N1::type x; +}; +#elif defined(SECOND) +namespace N1 { using type = int; } +struct S1 { + N1::type x; +}; +#else +S1 s1; +// expected-error@first.h:* {{'ElaboratedType::S1::x' from module 'FirstModule' is not present in definition of 'ElaboratedType::S1' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'x' does not match}} +#endif +} + +namespace Enum { +#if defined(FIRST) +enum A1 {}; +struct S1 { + A1 x; +}; +#elif defined(SECOND) +enum A2 {}; +struct S1 { + A2 x; +}; +#else +S1 s1; +// expected-error@first.h:* {{'Enum::S1::x' from module 'FirstModule' is not present in definition of 'Enum::S1' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'x' does not match}} +#endif +} // Interesting cases that should not cause errors. struct S should not error // while struct T should error at the access specifier mismatch at the end. _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits