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;
+// [email protected]:* {{'RecordType::S1::x' from module 'FirstModule' is
not present in definition of 'RecordType::S1' in module 'SecondModule'}}
+// [email protected]:* {{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>;
+// [email protected]:* {{'DependentType::S1::x' from module 'FirstModule'
is not present in definition of 'S1<T>' in module 'SecondModule'}}
+// [email protected]:* {{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;
+// [email protected]:* {{'ElaboratedType::S1::x' from module
'FirstModule' is not present in definition of 'ElaboratedType::S1' in module
'SecondModule'}}
+// [email protected]:* {{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;
+// [email protected]:* {{'Enum::S1::x' from module 'FirstModule' is not
present in definition of 'Enum::S1' in module 'SecondModule'}}
+// [email protected]:* {{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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits