[ODRHash] Support pointer and reference types.
authorRichard Trieu <rtrieu@google.com>
Fri, 13 Apr 2018 22:34:43 +0000 (22:34 +0000)
committerRichard Trieu <rtrieu@google.com>
Fri, 13 Apr 2018 22:34:43 +0000 (22:34 +0000)
Recommit r328404 which was reverted in rL328404.  r329869 fixed the issue that
caused the revert.

llvm-svn: 330074

clang/lib/AST/ODRHash.cpp
clang/test/Modules/odr_hash.cpp

index 0ee30fb..364fd04 100644 (file)
@@ -642,6 +642,24 @@ public:
     VisitFunctionType(T);
   }
 
+  void VisitPointerType(const PointerType *T) {
+    AddQualType(T->getPointeeType());
+    VisitType(T);
+  }
+
+  void VisitReferenceType(const ReferenceType *T) {
+    AddQualType(T->getPointeeTypeAsWritten());
+    VisitType(T);
+  }
+
+  void VisitLValueReferenceType(const LValueReferenceType *T) {
+    VisitReferenceType(T);
+  }
+
+  void VisitRValueReferenceType(const RValueReferenceType *T) {
+    VisitReferenceType(T);
+  }
+
   void VisitTypedefType(const TypedefType *T) {
     AddDecl(T->getDecl());
     QualType UnderlyingType = T->getDecl()->getUnderlyingType();
index b22ccdd..8667a3a 100644 (file)
@@ -2286,6 +2286,127 @@ Invalid1 i1;
 #undef DECLS
 }  // namespace BaseClass
 
+namespace PointersAndReferences {
+#if defined(FIRST) || defined(SECOND)
+template<typename> struct Wrapper{};
+#endif
+
+#if defined(FIRST)
+struct S1 {
+  Wrapper<int*> x;
+};
+#elif defined(SECOND)
+struct S1 {
+  Wrapper<float*> x;
+};
+#else
+S1 s1;
+// expected-error@first.h:* {{PointersAndReferences::S1::x' from module 'FirstModule' is not present in definition of 'PointersAndReferences::S1' in module 'SecondModule'}}
+// expected-note@second.h:* {{declaration of 'x' does not match}}
+#endif
+
+#if defined(FIRST)
+struct S2 {
+  Wrapper<int &&> x;
+};
+#elif defined(SECOND)
+struct S2 {
+  Wrapper<float &&> x;
+};
+#else
+S2 s2;
+// expected-error@first.h:* {{PointersAndReferences::S2::x' from module 'FirstModule' is not present in definition of 'PointersAndReferences::S2' in module 'SecondModule'}}
+// expected-note@second.h:* {{declaration of 'x' does not match}}
+#endif
+
+#if defined(FIRST)
+struct S3 {
+  Wrapper<int *> x;
+};
+#elif defined(SECOND)
+struct S3 {
+  Wrapper<float *> x;
+};
+#else
+S3 s3;
+// expected-error@first.h:* {{PointersAndReferences::S3::x' from module 'FirstModule' is not present in definition of 'PointersAndReferences::S3' in module 'SecondModule'}}
+// expected-note@second.h:* {{declaration of 'x' does not match}}
+#endif
+
+#if defined(FIRST)
+struct S4 {
+  Wrapper<int &> x;
+};
+#elif defined(SECOND)
+struct S4 {
+  Wrapper<float &> x;
+};
+#else
+S4 s4;
+// expected-error@first.h:* {{PointersAndReferences::S4::x' from module 'FirstModule' is not present in definition of 'PointersAndReferences::S4' in module 'SecondModule'}}
+// expected-note@second.h:* {{declaration of 'x' does not match}}
+#endif
+
+#if defined(FIRST)
+struct S5 {
+  Wrapper<S5 *> x;
+};
+#elif defined(SECOND)
+struct S5 {
+  Wrapper<const S5 *> x;
+};
+#else
+S5 s5;
+// expected-error@second.h:* {{'PointersAndReferences::S5::x' from module 'SecondModule' is not present in definition of 'PointersAndReferences::S5' in module 'FirstModule'}}
+// expected-note@first.h:* {{declaration of 'x' does not match}}
+#endif
+
+#if defined(FIRST)
+struct S6 {
+  Wrapper<int &> x;
+};
+#elif defined(SECOND)
+struct S6 {
+  Wrapper<const int &> x;
+};
+#else
+S6 s6;
+// expected-error@first.h:* {{PointersAndReferences::S6::x' from module 'FirstModule' is not present in definition of 'PointersAndReferences::S6' in module 'SecondModule'}}
+// expected-note@second.h:* {{declaration of 'x' does not match}}
+#endif
+
+#define DECLS                \
+  Wrapper<int *> x1;         \
+  Wrapper<float *> x2;       \
+  Wrapper<const float *> x3; \
+  Wrapper<int &> x4;         \
+  Wrapper<int &&> x5;        \
+  Wrapper<const int &> x6;   \
+  Wrapper<S1 *> x7;          \
+  Wrapper<S1 &> x8;          \
+  Wrapper<S1 &&> x9;
+
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 {
+  DECLS
+};
+#else
+Valid1 v1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 {
+  DECLS
+  ACCESS
+};
+#else
+Invalid1 i1;
+// expected-error@second.h:* {{'PointersAndReferences::Invalid1' 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 public access specifier}}
+#endif
+#undef DECLS
+}  // namespace PointersAndReferences
+
 
 // Collection of interesting cases below.