mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
This patch is follow-up work from #78942 and imports non-public members, which were previously not being imported. Those members can be accessed in a Swift file blessed by the SWIFT_PRIVATE_FILEID annotation. As a consequence of this patch, we are also now importing inherited members that are inaccessible from the derived classes, because they were declared private, or because they were inherited via nested private inheritance. We import them anyway but mark them unavailable, for better diagnostics and to (somewhat) simplify the import logic for inheritance. Because non-public base class members are now imported too, this patch inflames an existing issue where a 'using' declaration on an inherited member with a synthesized name (e.g., operators) produces duplicate members, leading to miscompilation (resulting in a runtime crash). This was not previously noticed because a 'using' declaration on a public inherited member is not usually necessary, but is a common way to expose otherwise non-public members. This patch puts in a workaround to prevent this from affecting the behavior of MSVC's std::optional implementation, which uses this pattern of 'using' a private inherited member. That will be fixed in a follow-up patch. Follow-up work is also needed to correctly diagnose ambiguous overloads in cases of multiple inheritance, and to account for virtual inheritance. rdar://137764620
83 lines
1.8 KiB
C++
83 lines
1.8 KiB
C++
#ifndef _USING_BASE_MEMBERS_H
|
|
#define _USING_BASE_MEMBERS_H
|
|
|
|
struct PublicBase {
|
|
private:
|
|
int value = 123;
|
|
|
|
public:
|
|
int publicGetter() const { return value; }
|
|
void publicSetter(int v) { value = v; }
|
|
void notExposed() const {}
|
|
};
|
|
|
|
struct PublicBasePrivateInheritance : private PublicBase {
|
|
using PublicBase::publicGetter;
|
|
using PublicBase::publicSetter;
|
|
};
|
|
|
|
struct PublicBaseProtectedInheritance : protected PublicBase {
|
|
using PublicBase::publicGetter;
|
|
using PublicBase::publicSetter;
|
|
};
|
|
|
|
struct PublicBaseUsingPrivateTypedef : private PublicBase {
|
|
private:
|
|
typedef PublicBase MyBase;
|
|
public:
|
|
using MyBase::publicGetter;
|
|
using MyBase::publicSetter;
|
|
};
|
|
|
|
struct PublicBaseUsingPrivateUsingType : private PublicBase {
|
|
private:
|
|
using MyBase = PublicBase;
|
|
public:
|
|
using MyBase::publicGetter;
|
|
using MyBase::publicSetter;
|
|
};
|
|
|
|
struct IntBox {
|
|
int value;
|
|
IntBox(int value) : value(value) {}
|
|
IntBox(unsigned value) : value(value) {}
|
|
};
|
|
|
|
struct UsingBaseConstructorWithParam : IntBox {
|
|
using IntBox::IntBox;
|
|
};
|
|
|
|
struct Empty {};
|
|
|
|
struct UsingBaseConstructorEmpty : private Empty {
|
|
using Empty::Empty;
|
|
|
|
int value = 456;
|
|
};
|
|
|
|
struct ProtectedBase {
|
|
protected:
|
|
int protectedGetter() const { return 456; }
|
|
};
|
|
|
|
struct ProtectedMemberPrivateInheritance : private ProtectedBase {
|
|
using ProtectedBase::protectedGetter;
|
|
};
|
|
|
|
struct OperatorBase {
|
|
operator bool() const { return true; }
|
|
int operator*() const { return 456; }
|
|
OperatorBase operator!() const { return *this; }
|
|
// int operator[](const int x) const { return x; } // FIXME: see below
|
|
};
|
|
|
|
struct OperatorBasePrivateInheritance : private OperatorBase {
|
|
public:
|
|
using OperatorBase::operator bool;
|
|
using OperatorBase::operator*;
|
|
using OperatorBase::operator!;
|
|
// using OperatorBase::operator[]; // FIXME: using operator[] is broken
|
|
};
|
|
|
|
#endif // !_USING_BASE_MEMBERS_H
|