r303231 - [ODRHash] Support more types in the ODR checker.
Richard Trieu via cfe-commits
cfe-commits at lists.llvm.org
Tue May 16 19:29:03 PDT 2017
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 at first.h:* {{'RecordType::S1::x' from module 'FirstModule' is not present in definition of 'RecordType::S1' in module 'SecondModule'}}
+// expected-note at 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 at first.h:* {{'DependentType::S1::x' from module 'FirstModule' is not present in definition of 'S1<T>' in module 'SecondModule'}}
+// expected-note at 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 at first.h:* {{'ElaboratedType::S1::x' from module 'FirstModule' is not present in definition of 'ElaboratedType::S1' in module 'SecondModule'}}
+// expected-note at 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 at first.h:* {{'Enum::S1::x' from module 'FirstModule' is not present in definition of 'Enum::S1' in module 'SecondModule'}}
+// expected-note at 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.
More information about the cfe-commits
mailing list