r317394 - Update ODR hashing tests

Richard Trieu via cfe-commits cfe-commits at lists.llvm.org
Fri Nov 3 18:20:50 PDT 2017


Author: rtrieu
Date: Fri Nov  3 18:20:50 2017
New Revision: 317394

URL: http://llvm.org/viewvc/llvm-project?rev=317394&view=rev
Log:
Update ODR hashing tests

Add a mix of postive and negative tests to check that wrong Decls won't be
flagged in the diagnostic.  Split the check everything test and moved the
pieces closer to where the related tests are.

Modified:
    cfe/trunk/test/Modules/odr_hash.cpp

Modified: cfe/trunk/test/Modules/odr_hash.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/odr_hash.cpp?rev=317394&r1=317393&r2=317394&view=diff
==============================================================================
--- cfe/trunk/test/Modules/odr_hash.cpp (original)
+++ cfe/trunk/test/Modules/odr_hash.cpp Fri Nov  3 18:20:50 2017
@@ -12,6 +12,10 @@
 // RUN: echo "#define SECOND" >> %t/Inputs/second.h
 // RUN: cat %s                >> %t/Inputs/second.h
 
+// Test that each header can compile
+// RUN: %clang_cc1 -fsyntax-only -x c++ -std=c++1z %t/Inputs/first.h
+// RUN: %clang_cc1 -fsyntax-only -x c++ -std=c++1z %t/Inputs/second.h
+
 // Build module map file
 // RUN: echo "module FirstModule {"     >> %t/Inputs/module.map
 // RUN: echo "    header \"first.h\""   >> %t/Inputs/module.map
@@ -28,6 +32,13 @@
 #include "second.h"
 #endif
 
+// Used for testing
+#if defined(FIRST)
+#define ACCESS public:
+#elif defined(SECOND)
+#define ACCESS private:
+#endif
+
 namespace AccessSpecifiers {
 #if defined(FIRST)
 struct S1 {
@@ -55,6 +66,32 @@ S2 s2;
 // expected-error at second.h:* {{'AccessSpecifiers::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found protected access specifier}}
 // expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
 #endif
+
+#define DECLS \
+public:       \
+private:      \
+protected:
+
+#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 at second.h:* {{'AccessSpecifiers::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+
+#undef DECLS
 } // namespace AccessSpecifiers
 
 namespace StaticAssert {
@@ -113,7 +150,31 @@ S4 s4;
 // expected-error at second.h:* {{'StaticAssert::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
 // expected-note at first.h:* {{but in 'FirstModule' found static assert}}
 #endif
-}
+
+#define DECLS                       \
+  static_assert(4 == 4, "Message"); \
+  static_assert(5 == 5);
+
+#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 at second.h:* {{'StaticAssert::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
+}  // namespace StaticAssert
 
 namespace Field {
 #if defined(FIRST)
@@ -302,6 +363,38 @@ S13 s13;
 // expected-error at first.h:* {{'Field::S13::x' from module 'FirstModule' is not present in definition of 'Field::S13' in module 'SecondModule'}}
 // expected-note at second.h:* {{declaration of 'x' does not match}}
 #endif
+
+#define DECLS         \
+  int a;              \
+  int b : 3;          \
+  unsigned c : 1 + 2; \
+  s d;                \
+  double e = 1.0;     \
+  long f[5];
+
+#if defined(FIRST) || defined(SECOND)
+typedef short s;
+#endif
+
+#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 at second.h:* {{'Field::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
 }  // namespace Field
 
 namespace Method {
@@ -531,6 +624,40 @@ S15 s15;
 // expected-error at first.h:* {{'Method::S15::A' from module 'FirstModule' is not present in definition of 'Method::S15' in module 'SecondModule'}}
 // expected-note at second.h:* {{declaration of 'A' does not match}}
 #endif
+
+#define DECLS            \
+  void A();              \
+  static void B();       \
+  virtual void C();      \
+  virtual void D() = 0;  \
+  inline void E();       \
+  void F() const;        \
+  void G() volatile;     \
+  void H(int x);         \
+  void I(int x = 5 + 5); \
+  void J(int);           \
+  void K(int x[2]);      \
+  int L();
+
+#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 at second.h:* {{'Method::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
 }  // namespace Method
 
 namespace Constructor {
@@ -565,6 +692,31 @@ S2* s2;
 // expected-error at second.h:* {{'Constructor::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found constructor that has 2 parameters}}
 // expected-note at first.h:* {{but in 'FirstModule' found constructor that has 1 parameter}}
 #endif
+
+#define DECLS(CLASS) \
+  CLASS(int);        \
+  CLASS(double);     \
+  CLASS(int, int);
+
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 {
+  DECLS(Valid1)
+};
+#else
+Valid1* v1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 {
+  DECLS(Invalid1)
+  ACCESS
+};
+#else
+Invalid1* i1;
+// expected-error at second.h:* {{'Constructor::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
 }  // namespace Constructor
 
 namespace Destructor {
@@ -600,32 +752,44 @@ S2 s2;
 // expected-note at first.h:* {{but in 'FirstModule' found destructor is virtual}}
 #endif
 
-}  // namespace Destructor
-
-// 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 {
-#if defined(FIRST)
-template <template <int> class T> class Wrapper {};
-
-template <int N> class S {
-  S(Wrapper<::SelfReference::S> &Ref) {}
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 {
+  ~Valid1();
 };
+#else
+Valid1 v1;
+#endif
 
-struct Xx {
-  struct Yy {
-  };
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 {
+  ~Invalid1();
+  ACCESS
 };
+#else
+Invalid1 i1;
+// expected-error at second.h:* {{'Destructor::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
 
-Xx::Xx::Xx::Yy yy;
+#if defined(FIRST) || defined(SECOND)
+struct Valid2 {
+  virtual ~Valid2();
+};
+#else
+Valid2 v2;
+#endif
 
-namespace NNS {
-template <typename> struct Foo;
-template <template <class> class T = NNS::Foo>
-struct NestedNamespaceSpecifier {};
-}
+#if defined(FIRST) || defined(SECOND)
+struct Invalid2 {
+  virtual ~Invalid2();
+  ACCESS
+};
+#else
+Invalid2 i2;
+// expected-error at second.h:* {{'Destructor::Invalid2' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
 #endif
-}  // namespace SelfReference
+}  // namespace Destructor
 
 namespace TypeDef {
 #if defined(FIRST)
@@ -722,6 +886,35 @@ S6 s6;
 // expected-error at second.h:* {{'TypeDef::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found typedef 'b' with underlying type 'float'}}
 // expected-note at first.h:* {{but in 'FirstModule' found typedef 'b' with different underlying type 'TypeDef::F' (aka 'float')}}
 #endif
+
+#define DECLS       \
+  typedef int A;    \
+  typedef double B; \
+  typedef I C;
+
+#if defined(FIRST) || defined(SECOND)
+typedef int I;
+#endif
+
+#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 at second.h:* {{'TypeDef::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
 }  // namespace TypeDef
 
 namespace Using {
@@ -819,6 +1012,35 @@ S6 s6;
 // expected-error at second.h:* {{'Using::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found type alias 'b' with underlying type 'float'}}
 // expected-note at first.h:* {{but in 'FirstModule' found type alias 'b' with different underlying type 'Using::F' (aka 'float')}}
 #endif
+
+#if defined(FIRST) || defined(SECOND)
+using I = int;
+#endif
+
+#define DECLS       \
+  using A = int;    \
+  using B = double; \
+  using C = I;
+
+#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 at second.h:* {{'Using::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
 }  // namespace Using
 
 namespace RecordType {
@@ -837,7 +1059,34 @@ 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
-}
+
+#define DECLS \
+  Foo F;
+
+#if defined(FIRST) || defined(SECOND)
+struct Foo {};
+#endif
+
+#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 at second.h:* {{'RecordType::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
+}  // namespace RecordType
 
 namespace DependentType {
 #if defined(FIRST)
@@ -856,7 +1105,34 @@ 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
-}
+
+#define DECLS \
+  typename T::typeA x;
+
+#if defined(FIRST) || defined(SECOND)
+template <class T>
+struct Valid1 {
+  DECLS
+};
+#else
+template <class T>
+using V1 = Valid1<T>;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+template <class T>
+struct Invalid1 {
+  DECLS
+  ACCESS
+};
+#else
+template <class T>
+using I1 = Invalid1<T>;
+// expected-error at second.h:* {{'DependentType::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
+}  // namespace DependentType
 
 namespace ElaboratedType {
 #if defined(FIRST)
@@ -874,7 +1150,34 @@ 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
-}
+
+#define DECLS \
+  NS::type x;
+
+#if defined(FIRST) || defined(SECOND)
+namespace NS { using type = float; }
+#endif
+
+#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 at second.h:* {{'ElaboratedType::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
+}  // namespace ElaboratedType
 
 namespace Enum {
 #if defined(FIRST)
@@ -892,6 +1195,33 @@ 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
+
+#define DECLS \
+  E e = E1;
+
+#if defined(FIRST) || defined(SECOND)
+enum E { E1, E2 };
+#endif
+
+#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 at second.h:* {{'Enum::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
 }
 
 namespace NestedNamespaceSpecifier {
@@ -1069,7 +1399,73 @@ S10 s10;
 // expected-note at first.h:* {{declaration of 'x' does not match}}
 #endif
 }
+
+#define DECLS       \
+  NS1::Type a;      \
+  NS1::NS2::Type b; \
+  NS1::S c;         \
+  NS3::Type d;
+
+#if defined(FIRST) || defined(SECOND)
+namespace NS1 {
+  using Type = int;
+  namespace NS2 {
+    using Type = double;
+  }
+  struct S {};
 }
+namespace NS3 = NS1;
+#endif
+
+#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 at second.h:* {{'NestedNamespaceSpecifier::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
+
+#define DECLS               \
+  typename T::type *x = {}; \
+  int y = x->T::foo();      \
+  int z = U::template X<int>::value;
+
+#if defined(FIRST) || defined(SECOND)
+template <class T, class U>
+struct Valid2 {
+  DECLS
+};
+#else
+template <class T, class U>
+using V2 = Valid2<T, U>;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+template <class T, class U>
+struct Invalid2 {
+  DECLS
+  ACCESS
+};
+#else
+template <class T, class U>
+using I2 = Invalid2<T, U>;
+// expected-error at second.h:* {{'NestedNamespaceSpecifier::Invalid2' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
+}  // namespace NestedNamespaceSpecifier
 
 namespace TemplateSpecializationType {
 #if defined(FIRST)
@@ -1103,7 +1499,40 @@ S2 s2;
 // expected-error at first.h:* {{'TemplateSpecializationType::S2::u' from module 'FirstModule' is not present in definition of 'TemplateSpecializationType::S2' in module 'SecondModule'}}
 // expected-note at second.h:* {{declaration of 'u' does not match}}
 #endif
-}
+
+#define DECLS                       \
+  OneTemplateArg<int> x;            \
+  OneTemplateArg<double> y;         \
+  OneTemplateArg<char *> z;         \
+  TwoTemplateArgs<int, int> a;      \
+  TwoTemplateArgs<double, float> b; \
+  TwoTemplateArgs<short *, char> c;
+
+#if defined(FIRST) || defined(SECOND)
+template <class T> struct OneTemplateArg {};
+template <class T, class U> struct TwoTemplateArgs {};
+#endif
+
+#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 at second.h:* {{'TemplateSpecializationType::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
+}  // namespace TemplateSpecializationType
 
 namespace TemplateArgument {
 #if defined(FIRST)
@@ -1205,7 +1634,43 @@ S6 s6;
 // expected-error at second.h:* {{'TemplateArgument::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'y'}}
 // expected-note at first.h:* {{but in 'FirstModule' found field 'x'}}
 #endif
-}
+
+#define DECLS                   \
+  OneClass<int> a;              \
+  OneInt<1> b;                  \
+  using c = OneClass<float>;    \
+  using d = OneInt<2>;          \
+  using e = OneInt<2 + 2>;      \
+  OneTemplateClass<OneClass> f; \
+  OneTemplateInt<OneInt> g;
+
+#if defined(FIRST) || defined(SECOND)
+template <class> struct OneClass{};
+template <int> struct OneInt{};
+template <template <class> class> struct OneTemplateClass{};
+template <template <int> class> struct OneTemplateInt{};
+#endif
+
+#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 at second.h:* {{'TemplateArgument::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
+}  // namespace TemplateArgument
 
 namespace TemplateTypeParmType {
 #if defined(FIRST)
@@ -1247,7 +1712,41 @@ using TemplateTypeParmType::S2;
 // expected-error at first.h:* {{'TemplateTypeParmType::S2::type' from module 'FirstModule' is not present in definition of 'S2<T, U>' in module 'SecondModule'}}
 // expected-note at second.h:* {{declaration of 'type' does not match}}
 #endif
-}
+
+#define DECLS            \
+  T t;                   \
+  U u;                   \
+  ParameterPack<T> a;    \
+  ParameterPack<T, U> b; \
+  ParameterPack<U> c;    \
+  ParameterPack<U, T> d;
+
+#if defined(FIRST) || defined(SECOND)
+template <class ...Ts> struct ParameterPack {};
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+template <class T, class U>
+struct Valid1 {
+  DECLS
+};
+#else
+using TemplateTypeParmType::Valid1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+template <class T, class U>
+struct Invalid1 {
+  DECLS
+  ACCESS
+};
+#else
+using TemplateTypeParmType::Invalid1;
+// expected-error at second.h:* {{'TemplateTypeParmType::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
+}  // namespace TemplateTypeParmType
 
 namespace VarDecl {
 #if defined(FIRST)
@@ -1381,46 +1880,36 @@ S9 s9;
 // expected-note at second.h:* {{declaration of 'x' does not match}}
 #endif
 
-#if defined(FIRST)
-template <typename T>
-struct S {
-  struct R {
-    void foo(T x = 0) {}
-  };
-};
-#elif defined(SECOND)
-template <typename T>
-struct S {
-  struct R {
-    void foo(T x = 1) {}
-  };
+#define DECLS             \
+  static int a;           \
+  static I b;             \
+  static const int c = 1; \
+  static constexpr int d = 5;
+
+#if defined(FIRST) || defined(SECOND)
+using I = int;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 {
+  DECLS
 };
 #else
-void run() {
-  S<int>::R().foo();
-}
-// expected-error at second.h:* {{'VarDecl::S::R' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'foo' with 1st parameter with a default argument}}
-// expected-note at first.h:* {{but in 'FirstModule' found method 'foo' with 1st parameter with a different default argument}}
+Valid1 v1;
 #endif
 
-#if defined(FIRST)
-template <typename alpha> struct Bravo {
-  void charlie(bool delta = false) {}
-};
-typedef Bravo<char> echo;
-echo foxtrot;
-#elif defined(SECOND)
-template <typename alpha> struct Bravo {
-  void charlie(bool delta = (false)) {}
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 {
+  DECLS
+  ACCESS
 };
-typedef Bravo<char> echo;
-echo foxtrot;
 #else
-Bravo<char> golf;
-// expected-error at second.h:* {{'VarDecl::Bravo' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'charlie' with 1st parameter with a default argument}}
-// expected-note at first.h:* {{but in 'FirstModule' found method 'charlie' with 1st parameter with a different default argument}}
+Invalid1 i1;
+// expected-error at second.h:* {{'VarDecl::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
 #endif
-}
+#undef DECLS
+}  // namespace VarDecl
 
 namespace Friend {
 #if defined(FIRST)
@@ -1499,7 +1988,41 @@ S5 s5;
 // expected-error at second.h:* {{'Friend::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found friend function 'T5b'}}
 // expected-note at first.h:* {{but in 'FirstModule' found friend function 'T5a'}}
 #endif
-}
+
+#define DECLS            \
+  friend class FriendA;  \
+  friend struct FriendB; \
+  friend FriendC;        \
+  friend const FriendD;  \
+  friend void Function();
+
+#if defined(FIRST) || defined(SECOND)
+class FriendA {};
+class FriendB {};
+class FriendC {};
+class FriendD {};
+#endif
+
+#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 at second.h:* {{'Friend::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
+}  // namespace Friend
 
 namespace TemplateParameters {
 #if defined(FIRST)
@@ -1575,6 +2098,38 @@ using TemplateParameters::S6;
 // expected-error at second.h:* {{'TemplateParameters::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found unnamed template parameter}}
 // expected-note at first.h:* {{but in 'FirstModule' found template parameter 'A'}}
 #endif
+
+#define DECLS
+
+#if defined(FIRST) || defined(SECOND)
+template <class> class DefaultArg;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+template <int, class, template <class> class,
+          int A, class B, template <int> class C,
+          int D = 1, class E = int, template <class F> class = DefaultArg>
+struct Valid1 {
+  DECLS
+};
+#else
+using TemplateParameters::Valid1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+template <int, class, template <class> class,
+          int A, class B, template <int> class C,
+          int D = 1, class E = int, template <class F> class = DefaultArg>
+struct Invalid1 {
+  DECLS
+  ACCESS
+};
+#else
+using TemplateParameters::Invalid1;
+// expected-error at second.h:* {{'TemplateParameters::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
 }  // namespace TemplateParameters
 
 namespace BaseClass {
@@ -1695,68 +2250,69 @@ S10 s10;
 // expected-error at second.h:* {{'BaseClass::S10' has different definitions in different modules; first difference is definition in module 'SecondModule' found 1st base class 'BaseClass::B10a' with protected access specifier}}
 // expected-note at first.h:* {{but in 'FirstModule' found 1st base class 'BaseClass::B10a' with no access specifier}}
 #endif
-}  // namespace BaseClass
 
-// 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.
-namespace AllDecls {
-#define CREATE_ALL_DECL_STRUCT(NAME, ACCESS)               \
-  typedef int INT;                                         \
-  struct NAME {                                            \
-  public:                                                  \
-  private:                                                 \
-  protected:                                               \
-    static_assert(1 == 1, "Message");                      \
-    static_assert(2 == 2);                                 \
-                                                           \
-    int x;                                                 \
-    double y;                                              \
-                                                           \
-    INT z;                                                 \
-                                                           \
-    unsigned a : 1;                                        \
-    unsigned b : 2 * 2 + 5 / 2;                            \
-                                                           \
-    mutable int c = sizeof(x + y);                         \
-                                                           \
-    void method() {}                                       \
-    static void static_method() {}                         \
-    virtual void virtual_method() {}                       \
-    virtual void pure_virtual_method() = 0;                \
-    inline void inline_method() {}                         \
-    void volatile_method() volatile {}                     \
-    void const_method() const {}                           \
-                                                           \
-    typedef int typedef_int;                               \
-    using using_int = int;                                 \
-                                                           \
-    void method_one_arg(int x) {}                          \
-    void method_one_arg_default_argument(int x = 5 + 5) {} \
-    void method_decayed_type(int x[5]) {}                  \
-                                                           \
-    int constant_arr[5];                                   \
-                                                           \
-    ACCESS:                                                \
-  };
+#define DECLS
 
-#if defined(FIRST)
-CREATE_ALL_DECL_STRUCT(S, public)
-#elif defined(SECOND)
-CREATE_ALL_DECL_STRUCT(S, public)
+#if defined(FIRST) || defined(SECOND)
+struct Base1 {};
+struct Base2 {};
+struct Base3 {};
+struct Base4 {};
+struct Base5 {};
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 :
+  Base1, virtual Base2, protected Base3, public Base4, private Base5 {
+
+  DECLS
+};
 #else
-S *s;
+Valid1 v1;
 #endif
 
-#if defined(FIRST)
-CREATE_ALL_DECL_STRUCT(T, private)
-#elif defined(SECOND)
-CREATE_ALL_DECL_STRUCT(T, public)
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 :
+  Base1, virtual Base2, protected Base3, public Base4, private Base5 {
+
+  DECLS
+  ACCESS
+};
 #else
-T *t;
-// expected-error at second.h:* {{'AllDecls::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
-// expected-note at first.h:* {{but in 'FirstModule' found private access specifier}}
+Invalid1 i1;
+// expected-error at second.h:* {{'BaseClass::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
 #endif
+#undef DECLS
+}  // namespace BaseClass
+
+
+// Collection of interesting cases below.
+
+// 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 {
+#if defined(FIRST)
+template <template <int> class T> class Wrapper {};
+
+template <int N> class S {
+  S(Wrapper<::SelfReference::S> &Ref) {}
+};
+
+struct Xx {
+  struct Yy {
+  };
+};
+
+Xx::Xx::Xx::Yy yy;
+
+namespace NNS {
+template <typename> struct Foo;
+template <template <class> class T = NNS::Foo>
+struct NestedNamespaceSpecifier {};
 }
+#endif
+}  // namespace SelfReference
 
 namespace FriendFunction {
 #if defined(FIRST)
@@ -1825,7 +2381,7 @@ T t;
 // expected-note at second.h:* {{but in 'SecondModule' found public access specifier}}
 #endif
 
-}  // namespace ImplicitDelc
+}  // namespace ImplicitDecl
 
 namespace TemplatedClass {
 #if defined(FIRST)
@@ -2051,7 +2607,7 @@ void run() {
   S<int>::R().foo();
 }
 #endif
-}
+}  // namespace LateParsedDefaultArgument
 
 namespace LateParsedDefaultArgument {
 #if defined(FIRST)
@@ -2065,7 +2621,7 @@ Bravo<char> golf;
 #elif defined(SECOND)
 #else
 #endif
-}
+}  // LateParsedDefaultArgument
 
 namespace DifferentParameterNameInTemplate {
 #if defined(FIRST) || defined(SECOND)
@@ -2111,7 +2667,7 @@ struct BetaHelper {
 #else
 Alpha::Alpha() {}
 #endif
-}
+}  // DifferentParameterNameInTemplate
 
 namespace ParameterTest {
 #if defined(FIRST)
@@ -2138,7 +2694,7 @@ G* S<G>::Foo(const G* asdf, int*) {}
 #else
 S<X> s;
 #endif
-}
+}  // ParameterTest
 
 namespace MultipleTypedefs {
 #if defined(FIRST)
@@ -2188,12 +2744,59 @@ struct S3 {
 #else
 S3 s3;
 #endif
+}  // MultipleTypedefs
+
+namespace DefaultArguments {
+#if defined(FIRST)
+template <typename T>
+struct S {
+  struct R {
+    void foo(T x = 0) {}
+  };
+};
+#elif defined(SECOND)
+template <typename T>
+struct S {
+  struct R {
+    void foo(T x = 1) {}
+  };
+};
+#else
+void run() {
+  S<int>::R().foo();
 }
+// expected-error at second.h:* {{'DefaultArguments::S::R' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'foo' with 1st parameter with a default argument}}
+// expected-note at first.h:* {{but in 'FirstModule' found method 'foo' with 1st parameter with a different default argument}}
+#endif
+
+#if defined(FIRST)
+template <typename alpha> struct Bravo {
+  void charlie(bool delta = false) {}
+};
+typedef Bravo<char> echo;
+echo foxtrot;
+#elif defined(SECOND)
+template <typename alpha> struct Bravo {
+  void charlie(bool delta = (false)) {}
+};
+typedef Bravo<char> echo;
+echo foxtrot;
+#else
+Bravo<char> golf;
+// expected-error at second.h:* {{'DefaultArguments::Bravo' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'charlie' with 1st parameter with a default argument}}
+// expected-note at first.h:* {{but in 'FirstModule' found method 'charlie' with 1st parameter with a different default argument}}
+#endif
+}  // namespace DefaultArguments
 
 // Keep macros contained to one file.
 #ifdef FIRST
 #undef FIRST
 #endif
+
 #ifdef SECOND
 #undef SECOND
 #endif
+
+#ifdef ACCESS
+#undef ACCESS
+#endif




More information about the cfe-commits mailing list