forked from OSchip/llvm-project
954 lines
22 KiB
C++
954 lines
22 KiB
C++
// Clear and create directories
|
|
// RUN: rm -rf %t
|
|
// RUN: mkdir %t
|
|
// RUN: mkdir %t/cache
|
|
// RUN: mkdir %t/Inputs
|
|
|
|
// Build first header file
|
|
// RUN: echo "#define FIRST" >> %t/Inputs/first.h
|
|
// RUN: cat %s >> %t/Inputs/first.h
|
|
|
|
// Build second header file
|
|
// RUN: echo "#define SECOND" >> %t/Inputs/second.h
|
|
// RUN: cat %s >> %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
|
|
// RUN: echo "}" >> %t/Inputs/module.map
|
|
// RUN: echo "module SecondModule {" >> %t/Inputs/module.map
|
|
// RUN: echo " header \"second.h\"" >> %t/Inputs/module.map
|
|
// RUN: echo "}" >> %t/Inputs/module.map
|
|
|
|
// Run test
|
|
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -x c++ -I%t/Inputs -verify %s -std=c++1z
|
|
|
|
#if !defined(FIRST) && !defined(SECOND)
|
|
#include "first.h"
|
|
#include "second.h"
|
|
#endif
|
|
|
|
namespace AccessSpecifiers {
|
|
#if defined(FIRST)
|
|
struct S1 {
|
|
};
|
|
#elif defined(SECOND)
|
|
struct S1 {
|
|
private:
|
|
};
|
|
#else
|
|
S1 s1;
|
|
// expected-error@second.h:* {{'AccessSpecifiers::S1' 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 end of class}}
|
|
#endif
|
|
|
|
#if defined(FIRST)
|
|
struct S2 {
|
|
public:
|
|
};
|
|
#elif defined(SECOND)
|
|
struct S2 {
|
|
protected:
|
|
};
|
|
#else
|
|
S2 s2;
|
|
// expected-error@second.h:* {{'AccessSpecifiers::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found protected access specifier}}
|
|
// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
|
|
#endif
|
|
} // namespace AccessSpecifiers
|
|
|
|
namespace StaticAssert {
|
|
#if defined(FIRST)
|
|
struct S1 {
|
|
static_assert(1 == 1, "First");
|
|
};
|
|
#elif defined(SECOND)
|
|
struct S1 {
|
|
static_assert(1 == 1, "Second");
|
|
};
|
|
#else
|
|
S1 s1;
|
|
// expected-error@second.h:* {{'StaticAssert::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found static assert with message}}
|
|
// expected-note@first.h:* {{but in 'FirstModule' found static assert with different message}}
|
|
#endif
|
|
|
|
#if defined(FIRST)
|
|
struct S2 {
|
|
static_assert(2 == 2, "Message");
|
|
};
|
|
#elif defined(SECOND)
|
|
struct S2 {
|
|
static_assert(2 == 2);
|
|
};
|
|
#else
|
|
S2 s2;
|
|
// expected-error@second.h:* {{'StaticAssert::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found static assert with no message}}
|
|
// expected-note@first.h:* {{but in 'FirstModule' found static assert with message}}
|
|
#endif
|
|
|
|
#if defined(FIRST)
|
|
struct S3 {
|
|
static_assert(3 == 3, "Message");
|
|
};
|
|
#elif defined(SECOND)
|
|
struct S3 {
|
|
static_assert(3 != 4, "Message");
|
|
};
|
|
#else
|
|
S3 s3;
|
|
// expected-error@second.h:* {{'StaticAssert::S3' has different definitions in different modules; first difference is definition in module 'SecondModule' found static assert with condition}}
|
|
// expected-note@first.h:* {{but in 'FirstModule' found static assert with different condition}}
|
|
#endif
|
|
|
|
#if defined(FIRST)
|
|
struct S4 {
|
|
static_assert(4 == 4, "Message");
|
|
};
|
|
#elif defined(SECOND)
|
|
struct S4 {
|
|
public:
|
|
};
|
|
#else
|
|
S4 s4;
|
|
// expected-error@second.h:* {{'StaticAssert::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
|
|
// expected-note@first.h:* {{but in 'FirstModule' found static assert}}
|
|
#endif
|
|
}
|
|
|
|
namespace Field {
|
|
#if defined(FIRST)
|
|
struct S1 {
|
|
int x;
|
|
private:
|
|
int y;
|
|
};
|
|
#elif defined(SECOND)
|
|
struct S1 {
|
|
int x;
|
|
int y;
|
|
};
|
|
#else
|
|
S1 s1;
|
|
// expected-error@second.h:* {{'Field::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found field}}
|
|
// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
|
|
#endif
|
|
|
|
#if defined(FIRST)
|
|
struct S2 {
|
|
int x;
|
|
int y;
|
|
};
|
|
#elif defined(SECOND)
|
|
struct S2 {
|
|
int y;
|
|
int x;
|
|
};
|
|
#else
|
|
S2 s2;
|
|
// expected-error@second.h:* {{'Field::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'y'}}
|
|
// expected-note@first.h:* {{but in 'FirstModule' found field 'x'}}
|
|
#endif
|
|
|
|
#if defined(FIRST)
|
|
struct S3 {
|
|
double x;
|
|
};
|
|
#elif defined(SECOND)
|
|
struct S3 {
|
|
int x;
|
|
};
|
|
#else
|
|
S3 s3;
|
|
// expected-error@first.h:* {{'Field::S3::x' from module 'FirstModule' is not present in definition of 'Field::S3' in module 'SecondModule'}}
|
|
// expected-note@second.h:* {{declaration of 'x' does not match}}
|
|
#endif
|
|
|
|
#if defined(FIRST)
|
|
typedef int A;
|
|
struct S4 {
|
|
A x;
|
|
};
|
|
|
|
struct S5 {
|
|
A x;
|
|
};
|
|
#elif defined(SECOND)
|
|
typedef int B;
|
|
struct S4 {
|
|
B x;
|
|
};
|
|
|
|
struct S5 {
|
|
int x;
|
|
};
|
|
#else
|
|
S4 s4;
|
|
// expected-error@second.h:* {{'Field::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with type 'Field::B' (aka 'int')}}
|
|
// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'Field::A' (aka 'int')}}
|
|
|
|
S5 s5;
|
|
// expected-error@second.h:* {{'Field::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with type 'int'}}
|
|
// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'Field::A' (aka 'int')}}
|
|
#endif
|
|
|
|
#if defined(FIRST)
|
|
struct S6 {
|
|
unsigned x;
|
|
};
|
|
#elif defined(SECOND)
|
|
struct S6 {
|
|
unsigned x : 1;
|
|
};
|
|
#else
|
|
S6 s6;
|
|
// expected-error@second.h:* {{'Field::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found bitfield 'x'}}
|
|
// expected-note@first.h:* {{but in 'FirstModule' found non-bitfield 'x'}}
|
|
#endif
|
|
|
|
#if defined(FIRST)
|
|
struct S7 {
|
|
unsigned x : 2;
|
|
};
|
|
#elif defined(SECOND)
|
|
struct S7 {
|
|
unsigned x : 1;
|
|
};
|
|
#else
|
|
S7 s7;
|
|
// expected-error@second.h:* {{'Field::S7' has different definitions in different modules; first difference is definition in module 'SecondModule' found bitfield 'x' with one width expression}}
|
|
// expected-note@first.h:* {{but in 'FirstModule' found bitfield 'x' with different width expression}}
|
|
#endif
|
|
|
|
#if defined(FIRST)
|
|
struct S8 {
|
|
unsigned x : 2;
|
|
};
|
|
#elif defined(SECOND)
|
|
struct S8 {
|
|
unsigned x : 1 + 1;
|
|
};
|
|
#else
|
|
S8 s8;
|
|
// expected-error@second.h:* {{'Field::S8' has different definitions in different modules; first difference is definition in module 'SecondModule' found bitfield 'x' with one width expression}}
|
|
// expected-note@first.h:* {{but in 'FirstModule' found bitfield 'x' with different width expression}}
|
|
#endif
|
|
|
|
#if defined(FIRST)
|
|
struct S9 {
|
|
mutable int x;
|
|
};
|
|
#elif defined(SECOND)
|
|
struct S9 {
|
|
int x;
|
|
};
|
|
#else
|
|
S9 s9;
|
|
// expected-error@second.h:* {{'Field::S9' has different definitions in different modules; first difference is definition in module 'SecondModule' found non-mutable field 'x'}}
|
|
// expected-note@first.h:* {{but in 'FirstModule' found mutable field 'x'}}
|
|
#endif
|
|
|
|
#if defined(FIRST)
|
|
struct S10 {
|
|
unsigned x = 5;
|
|
};
|
|
#elif defined(SECOND)
|
|
struct S10 {
|
|
unsigned x;
|
|
};
|
|
#else
|
|
S10 s10;
|
|
// expected-error@second.h:* {{'Field::S10' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with no initalizer}}
|
|
// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with an initializer}}
|
|
#endif
|
|
|
|
#if defined(FIRST)
|
|
struct S11 {
|
|
unsigned x = 5;
|
|
};
|
|
#elif defined(SECOND)
|
|
struct S11 {
|
|
unsigned x = 7;
|
|
};
|
|
#else
|
|
S11 s11;
|
|
// expected-error@second.h:* {{'Field::S11' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with an initializer}}
|
|
// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with a different initializer}}
|
|
#endif
|
|
|
|
} // namespace Field
|
|
|
|
namespace Method {
|
|
#if defined(FIRST)
|
|
struct S1 {
|
|
void A() {}
|
|
};
|
|
#elif defined(SECOND)
|
|
struct S1 {
|
|
private:
|
|
void A() {}
|
|
};
|
|
#else
|
|
S1 s1;
|
|
// expected-error@second.h:* {{'Method::S1' 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 method}}
|
|
#endif
|
|
|
|
#if defined(FIRST)
|
|
struct S2 {
|
|
void A() {}
|
|
void B() {}
|
|
};
|
|
#elif defined(SECOND)
|
|
struct S2 {
|
|
void B() {}
|
|
void A() {}
|
|
};
|
|
#else
|
|
S2 s2;
|
|
// expected-error@second.h:* {{'Method::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'B'}}
|
|
// expected-note@first.h:* {{but in 'FirstModule' found method 'A'}}
|
|
#endif
|
|
|
|
#if defined(FIRST)
|
|
struct S3 {
|
|
static void A() {}
|
|
void A(int) {}
|
|
};
|
|
#elif defined(SECOND)
|
|
struct S3 {
|
|
void A(int) {}
|
|
static void A() {}
|
|
};
|
|
#else
|
|
S3 s3;
|
|
// expected-error@second.h:* {{'Method::S3' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' is not static}}
|
|
// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is static}}
|
|
#endif
|
|
|
|
#if defined(FIRST)
|
|
struct S4 {
|
|
virtual void A() {}
|
|
void B() {}
|
|
};
|
|
#elif defined(SECOND)
|
|
struct S4 {
|
|
void A() {}
|
|
virtual void B() {}
|
|
};
|
|
#else
|
|
S4 s4;
|
|
// expected-error@second.h:* {{'Method::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' is not virtual}}
|
|
// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is virtual}}
|
|
#endif
|
|
|
|
#if defined(FIRST)
|
|
struct S5 {
|
|
virtual void A() = 0;
|
|
virtual void B() {};
|
|
};
|
|
#elif defined(SECOND)
|
|
struct S5 {
|
|
virtual void A() {}
|
|
virtual void B() = 0;
|
|
};
|
|
#else
|
|
S5 *s5;
|
|
// expected-error@second.h:* {{'Method::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' is virtual}}
|
|
// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is pure virtual}}
|
|
#endif
|
|
|
|
#if defined(FIRST)
|
|
struct S6 {
|
|
inline void A() {}
|
|
};
|
|
#elif defined(SECOND)
|
|
struct S6 {
|
|
void A() {}
|
|
};
|
|
#else
|
|
S6 s6;
|
|
// expected-error@second.h:* {{'Method::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' is not inline}}
|
|
// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is inline}}
|
|
#endif
|
|
|
|
#if defined(FIRST)
|
|
struct S7 {
|
|
void A() volatile {}
|
|
void A() {}
|
|
};
|
|
#elif defined(SECOND)
|
|
struct S7 {
|
|
void A() {}
|
|
void A() volatile {}
|
|
};
|
|
#else
|
|
S7 s7;
|
|
// expected-error@second.h:* {{'Method::S7' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' is not volatile}}
|
|
// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is volatile}}
|
|
#endif
|
|
|
|
#if defined(FIRST)
|
|
struct S8 {
|
|
void A() const {}
|
|
void A() {}
|
|
};
|
|
#elif defined(SECOND)
|
|
struct S8 {
|
|
void A() {}
|
|
void A() const {}
|
|
};
|
|
#else
|
|
S8 s8;
|
|
// expected-error@second.h:* {{'Method::S8' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' is not const}}
|
|
// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is const}}
|
|
#endif
|
|
|
|
} // namespace Method
|
|
|
|
// 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 TypeDef {
|
|
#if defined(FIRST)
|
|
struct S1 {
|
|
typedef int a;
|
|
};
|
|
#elif defined(SECOND)
|
|
struct S1 {
|
|
typedef double a;
|
|
};
|
|
#else
|
|
S1 s1;
|
|
// expected-error@first.h:* {{'TypeDef::S1::a' from module 'FirstModule' is not present in definition of 'TypeDef::S1' in module 'SecondModule'}}
|
|
// expected-note@second.h:* {{declaration of 'a' does not match}}
|
|
#endif
|
|
|
|
#if defined(FIRST)
|
|
struct S2 {
|
|
typedef int a;
|
|
};
|
|
#elif defined(SECOND)
|
|
struct S2 {
|
|
typedef int b;
|
|
};
|
|
#else
|
|
S2 s2;
|
|
// expected-error@first.h:* {{'TypeDef::S2::a' from module 'FirstModule' is not present in definition of 'TypeDef::S2' in module 'SecondModule'}}
|
|
// expected-note@second.h:* {{definition has no member 'a'}}
|
|
#endif
|
|
|
|
#if defined(FIRST)
|
|
typedef int T;
|
|
struct S3 {
|
|
typedef T a;
|
|
};
|
|
#elif defined(SECOND)
|
|
typedef double T;
|
|
struct S3 {
|
|
typedef T a;
|
|
};
|
|
#else
|
|
S3 s3;
|
|
// expected-error@first.h:* {{'TypeDef::S3::a' from module 'FirstModule' is not present in definition of 'TypeDef::S3' in module 'SecondModule'}}
|
|
// expected-note@second.h:* {{declaration of 'a' does not match}}
|
|
#endif
|
|
} // namespace TypeDef
|
|
|
|
namespace Using {
|
|
#if defined(FIRST)
|
|
struct S1 {
|
|
using a = int;
|
|
};
|
|
#elif defined(SECOND)
|
|
struct S1 {
|
|
using a = double;
|
|
};
|
|
#else
|
|
S1 s1;
|
|
// expected-error@first.h:* {{'Using::S1::a' from module 'FirstModule' is not present in definition of 'Using::S1' in module 'SecondModule'}}
|
|
// expected-note@second.h:* {{declaration of 'a' does not match}}
|
|
#endif
|
|
|
|
#if defined(FIRST)
|
|
struct S2 {
|
|
using a = int;
|
|
};
|
|
#elif defined(SECOND)
|
|
struct S2 {
|
|
using b = int;
|
|
};
|
|
#else
|
|
S2 s2;
|
|
// expected-error@first.h:* {{'Using::S2::a' from module 'FirstModule' is not present in definition of 'Using::S2' in module 'SecondModule'}}
|
|
// expected-note@second.h:* {{definition has no member 'a'}}
|
|
#endif
|
|
|
|
#if defined(FIRST)
|
|
typedef int T;
|
|
struct S3 {
|
|
using a = T;
|
|
};
|
|
#elif defined(SECOND)
|
|
typedef double T;
|
|
struct S3 {
|
|
using a = T;
|
|
};
|
|
#else
|
|
S3 s3;
|
|
// expected-error@first.h:* {{'Using::S3::a' from module 'FirstModule' is not present in definition of 'Using::S3' in module 'SecondModule'}}
|
|
// expected-note@second.h:* {{declaration of 'a' does not match}}
|
|
#endif
|
|
} // namespace Using
|
|
|
|
|
|
// 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 {
|
|
#if defined(FIRST)
|
|
typedef int INT;
|
|
struct S {
|
|
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;
|
|
};
|
|
#elif defined(SECOND)
|
|
typedef int INT;
|
|
struct S {
|
|
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;
|
|
};
|
|
#else
|
|
S *s;
|
|
#endif
|
|
|
|
#if defined(FIRST)
|
|
typedef int INT;
|
|
struct T {
|
|
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;
|
|
|
|
private:
|
|
};
|
|
#elif defined(SECOND)
|
|
typedef int INT;
|
|
struct T {
|
|
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;
|
|
|
|
public:
|
|
};
|
|
#else
|
|
T *t;
|
|
// expected-error@second.h:* {{'AllDecls::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
|
|
// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
|
|
#endif
|
|
}
|
|
|
|
namespace FriendFunction {
|
|
#if defined(FIRST)
|
|
void F(int = 0);
|
|
struct S { friend void F(int); };
|
|
#elif defined(SECOND)
|
|
void F(int);
|
|
struct S { friend void F(int); };
|
|
#else
|
|
S s;
|
|
#endif
|
|
|
|
#if defined(FIRST)
|
|
void G(int = 0);
|
|
struct T {
|
|
friend void G(int);
|
|
|
|
private:
|
|
};
|
|
#elif defined(SECOND)
|
|
void G(int);
|
|
struct T {
|
|
friend void G(int);
|
|
|
|
public:
|
|
};
|
|
#else
|
|
T t;
|
|
// expected-error@second.h:* {{'FriendFunction::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
|
|
// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
|
|
#endif
|
|
} // namespace FriendFunction
|
|
|
|
namespace ImplicitDecl {
|
|
#if defined(FIRST)
|
|
struct S { };
|
|
void S_Constructors() {
|
|
// Trigger creation of implicit contructors
|
|
S foo;
|
|
S bar = foo;
|
|
S baz(bar);
|
|
}
|
|
#elif defined(SECOND)
|
|
struct S { };
|
|
#else
|
|
S s;
|
|
#endif
|
|
|
|
#if defined(FIRST)
|
|
struct T {
|
|
private:
|
|
};
|
|
void T_Constructors() {
|
|
// Trigger creation of implicit contructors
|
|
T foo;
|
|
T bar = foo;
|
|
T baz(bar);
|
|
}
|
|
#elif defined(SECOND)
|
|
struct T {
|
|
public:
|
|
};
|
|
#else
|
|
T t;
|
|
// expected-error@first.h:* {{'ImplicitDecl::T' has different definitions in different modules; first difference is definition in module 'FirstModule' found private access specifier}}
|
|
// expected-note@second.h:* {{but in 'SecondModule' found public access specifier}}
|
|
#endif
|
|
|
|
} // namespace ImplicitDelc
|
|
|
|
namespace TemplatedClass {
|
|
#if defined(FIRST)
|
|
template <class>
|
|
struct S {};
|
|
#elif defined(SECOND)
|
|
template <class>
|
|
struct S {};
|
|
#else
|
|
S<int> s;
|
|
#endif
|
|
|
|
#if defined(FIRST)
|
|
template <class>
|
|
struct T {
|
|
private:
|
|
};
|
|
#elif defined(SECOND)
|
|
template <class>
|
|
struct T {
|
|
public:
|
|
};
|
|
#else
|
|
T<int> t;
|
|
// expected-error@second.h:* {{'TemplatedClass::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
|
|
// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
|
|
#endif
|
|
} // namespace TemplatedClass
|
|
|
|
namespace TemplateClassWithField {
|
|
#if defined(FIRST)
|
|
template <class A>
|
|
struct S {
|
|
A a;
|
|
};
|
|
#elif defined(SECOND)
|
|
template <class A>
|
|
struct S {
|
|
A a;
|
|
};
|
|
#else
|
|
S<int> s;
|
|
#endif
|
|
|
|
#if defined(FIRST)
|
|
template <class A>
|
|
struct T {
|
|
A a;
|
|
|
|
private:
|
|
};
|
|
#elif defined(SECOND)
|
|
template <class A>
|
|
struct T {
|
|
A a;
|
|
|
|
public:
|
|
};
|
|
#else
|
|
T<int> t;
|
|
// expected-error@second.h:* {{'TemplateClassWithField::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
|
|
// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
|
|
#endif
|
|
} // namespace TemplateClassWithField
|
|
|
|
namespace TemplateClassWithTemplateField {
|
|
#if defined(FIRST)
|
|
template <class A>
|
|
class WrapperS;
|
|
template <class A>
|
|
struct S {
|
|
WrapperS<A> a;
|
|
};
|
|
#elif defined(SECOND)
|
|
template <class A>
|
|
class WrapperS;
|
|
template <class A>
|
|
struct S {
|
|
WrapperS<A> a;
|
|
};
|
|
#else
|
|
template <class A>
|
|
class WrapperS{};
|
|
S<int> s;
|
|
#endif
|
|
|
|
#if defined(FIRST)
|
|
template <class A>
|
|
class WrapperT;
|
|
template <class A>
|
|
struct T {
|
|
WrapperT<A> a;
|
|
|
|
public:
|
|
};
|
|
#elif defined(SECOND)
|
|
template <class A>
|
|
class WrapperT;
|
|
template <class A>
|
|
struct T {
|
|
WrapperT<A> a;
|
|
|
|
private:
|
|
};
|
|
#else
|
|
template <class A>
|
|
class WrapperT{};
|
|
T<int> t;
|
|
// expected-error@second.h:* {{'TemplateClassWithTemplateField::T' 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
|
|
} // namespace TemplateClassWithTemplateField
|
|
|
|
namespace EnumWithForwardDeclaration {
|
|
#if defined(FIRST)
|
|
enum E : int;
|
|
struct S {
|
|
void get(E) {}
|
|
};
|
|
#elif defined(SECOND)
|
|
enum E : int { A, B };
|
|
struct S {
|
|
void get(E) {}
|
|
};
|
|
#else
|
|
S s;
|
|
#endif
|
|
|
|
#if defined(FIRST)
|
|
struct T {
|
|
void get(E) {}
|
|
public:
|
|
};
|
|
#elif defined(SECOND)
|
|
struct T {
|
|
void get(E) {}
|
|
private:
|
|
};
|
|
#else
|
|
T t;
|
|
// expected-error@second.h:* {{'EnumWithForwardDeclaration::T' 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
|
|
} // namespace EnumWithForwardDeclaration
|
|
|
|
namespace StructWithForwardDeclaration {
|
|
#if defined(FIRST)
|
|
struct P {};
|
|
struct S {
|
|
struct P *ptr;
|
|
};
|
|
#elif defined(SECOND)
|
|
struct S {
|
|
struct P *ptr;
|
|
};
|
|
#else
|
|
S s;
|
|
#endif
|
|
|
|
#if defined(FIRST)
|
|
struct Q {};
|
|
struct T {
|
|
struct Q *ptr;
|
|
public:
|
|
};
|
|
#elif defined(SECOND)
|
|
struct T {
|
|
struct Q *ptr;
|
|
private:
|
|
};
|
|
#else
|
|
T t;
|
|
// expected-error@second.h:* {{'StructWithForwardDeclaration::T' 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
|
|
} // namespace StructWithForwardDeclaration
|
|
|
|
namespace StructWithForwardDeclarationNoDefinition {
|
|
#if defined(FIRST)
|
|
struct P;
|
|
struct S {
|
|
struct P *ptr;
|
|
};
|
|
#elif defined(SECOND)
|
|
struct S {
|
|
struct P *ptr;
|
|
};
|
|
#else
|
|
S s;
|
|
#endif
|
|
|
|
#if defined(FIRST)
|
|
struct Q;
|
|
struct T {
|
|
struct Q *ptr;
|
|
|
|
public:
|
|
};
|
|
#elif defined(SECOND)
|
|
struct T {
|
|
struct Q *ptr;
|
|
|
|
private:
|
|
};
|
|
#else
|
|
T t;
|
|
// expected-error@second.h:* {{'StructWithForwardDeclarationNoDefinition::T' 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
|
|
} // namespace StructWithForwardDeclarationNoDefinition
|
|
|
|
// Keep macros contained to one file.
|
|
#ifdef FIRST
|
|
#undef FIRST
|
|
#endif
|
|
#ifdef SECOND
|
|
#undef SECOND
|
|
#endif
|