Minor header fixes to reduce parsing issues with Clang (#1700)
* Work around Clang's incomplete C++20 support for omitting typename * vapours: fix Clang error about missing return in constexpr function * stratosphere: fix call to non-constexpr strlen in constexpr function strlen being constexpr is a non-compliant GCC extension; Clang explicitly rejects it: https://reviews.llvm.org/D23692 * stratosphere: add a bunch of missing override specifiers * stratosphere: work around Clang consteval bug Minimal example: https://godbolt.org/z/MoM64v93M The issue seems to be that Clang does not consider f(x) to be a constant expression if x comes from a template argument that isn't a non-type auto template argument (???) We can work around this by relaxing GetMessageHeaderForCheck (by using constexpr instead of consteval). This produces no functional changes because the result of GetMessageHeaderForCheck() is assigned to a constexpr variable, so the result is guaranteed to be computed at compile-time. * stratosphere: fix missing require clauses in definitions GCC not requiring the require clauses to be repeated for member definitions is actually a compiler bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96830 Clang rejects declarations with missing require clauses. * Fix ALWAYS_INLINE_LAMBDA and parameter list relative order While GCC doesn't seem to care about the position of the always_inline attribute relative to the parameter list, Clang is very picky and requires the attribute to appear after the parameter list (and before a trailing return type) * stratosphere: fix static constexpr member variable with incomplete type GCC accepts this for some reason (because of the lambda?) but Clang correctly rejects this.
This commit is contained in:
@@ -62,20 +62,16 @@ namespace ams::settings {
|
||||
|
||||
char name[MaxLength];
|
||||
|
||||
static constexpr LanguageCode Encode(const char *name, size_t name_size) {
|
||||
static constexpr LanguageCode Encode(util::string_view name) {
|
||||
LanguageCode out{};
|
||||
for (size_t i = 0; i < MaxLength && i < name_size; i++) {
|
||||
for (size_t i = 0; i < MaxLength && i < name.size(); i++) {
|
||||
out.name[i] = name[i];
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
static constexpr LanguageCode Encode(const char *name) {
|
||||
return Encode(name, std::strlen(name));
|
||||
}
|
||||
|
||||
template<Language Lang>
|
||||
static constexpr inline LanguageCode EncodeLanguage = [] {
|
||||
static constexpr inline LanguageCode EncodeLanguage() {
|
||||
if constexpr (false) { /* ... */ }
|
||||
#define AMS_MATCH_LANGUAGE(lang, enc) else if constexpr (Lang == Language_##lang) { return LanguageCode::Encode(enc); }
|
||||
AMS_MATCH_LANGUAGE(Japanese, "ja")
|
||||
@@ -98,28 +94,28 @@ namespace ams::settings {
|
||||
AMS_MATCH_LANGUAGE(TraditionalChinese, "zh-Hant")
|
||||
#undef AMS_MATCH_LANGUAGE
|
||||
else { static_assert(Lang != Language_Japanese); }
|
||||
}();
|
||||
}
|
||||
|
||||
static constexpr inline LanguageCode Encode(const Language language) {
|
||||
constexpr LanguageCode EncodedLanguages[Language_Count] = {
|
||||
EncodeLanguage<Language_Japanese>,
|
||||
EncodeLanguage<Language_AmericanEnglish>,
|
||||
EncodeLanguage<Language_French>,
|
||||
EncodeLanguage<Language_German>,
|
||||
EncodeLanguage<Language_Italian>,
|
||||
EncodeLanguage<Language_Spanish>,
|
||||
EncodeLanguage<Language_Chinese>,
|
||||
EncodeLanguage<Language_Korean>,
|
||||
EncodeLanguage<Language_Dutch>,
|
||||
EncodeLanguage<Language_Portuguese>,
|
||||
EncodeLanguage<Language_Russian>,
|
||||
EncodeLanguage<Language_Taiwanese>,
|
||||
EncodeLanguage<Language_BritishEnglish>,
|
||||
EncodeLanguage<Language_CanadianFrench>,
|
||||
EncodeLanguage<Language_LatinAmericanSpanish>,
|
||||
EncodeLanguage<Language_Japanese>(),
|
||||
EncodeLanguage<Language_AmericanEnglish>(),
|
||||
EncodeLanguage<Language_French>(),
|
||||
EncodeLanguage<Language_German>(),
|
||||
EncodeLanguage<Language_Italian>(),
|
||||
EncodeLanguage<Language_Spanish>(),
|
||||
EncodeLanguage<Language_Chinese>(),
|
||||
EncodeLanguage<Language_Korean>(),
|
||||
EncodeLanguage<Language_Dutch>(),
|
||||
EncodeLanguage<Language_Portuguese>(),
|
||||
EncodeLanguage<Language_Russian>(),
|
||||
EncodeLanguage<Language_Taiwanese>(),
|
||||
EncodeLanguage<Language_BritishEnglish>(),
|
||||
EncodeLanguage<Language_CanadianFrench>(),
|
||||
EncodeLanguage<Language_LatinAmericanSpanish>(),
|
||||
/* 4.0.0+ */
|
||||
EncodeLanguage<Language_SimplifiedChinese>,
|
||||
EncodeLanguage<Language_TraditionalChinese>,
|
||||
EncodeLanguage<Language_SimplifiedChinese>(),
|
||||
EncodeLanguage<Language_TraditionalChinese>(),
|
||||
};
|
||||
return EncodedLanguages[language];
|
||||
}
|
||||
|
||||
@@ -54,11 +54,11 @@ namespace ams::sf::cmif {
|
||||
|
||||
void DisposeImpl();
|
||||
|
||||
virtual void AddReference() {
|
||||
virtual void AddReference() override {
|
||||
ServiceObjectImplBase2::AddReferenceImpl();
|
||||
}
|
||||
|
||||
virtual void Release() {
|
||||
virtual void Release() override {
|
||||
if (ServiceObjectImplBase2::ReleaseImpl()) {
|
||||
this->DisposeImpl();
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace ams::sf {
|
||||
return lmem::FreeToExpHeap(m_handle, buffer);
|
||||
}
|
||||
|
||||
virtual bool IsEqualImpl(const MemoryResource &resource) const {
|
||||
virtual bool IsEqualImpl(const MemoryResource &resource) const override {
|
||||
return this == std::addressof(resource);
|
||||
}
|
||||
};
|
||||
@@ -76,9 +76,9 @@ namespace ams::sf {
|
||||
return lmem::FreeToUnitHeap(m_handle, buffer);
|
||||
}
|
||||
|
||||
virtual bool IsEqualImpl(const MemoryResource &resource) const {
|
||||
virtual bool IsEqualImpl(const MemoryResource &resource) const override {
|
||||
return this == std::addressof(resource);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,9 +37,9 @@ namespace ams::sf {
|
||||
return m_standard_allocator->Free(buffer);
|
||||
}
|
||||
|
||||
virtual bool IsEqualImpl(const MemoryResource &resource) const {
|
||||
virtual bool IsEqualImpl(const MemoryResource &resource) const override {
|
||||
return this == std::addressof(resource);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace ams::sf {
|
||||
public:
|
||||
class Object;
|
||||
using Allocator = StatelessDummyAllocator;
|
||||
using StatelessAllocator = typename Policy::StatelessAllocator<Object>;
|
||||
using StatelessAllocator = typename Policy::template StatelessAllocator<Object>;
|
||||
|
||||
class Object final : private ::ams::sf::impl::ServiceObjectImplBase2, public Base {
|
||||
NON_COPYABLE(Object);
|
||||
|
||||
@@ -40,8 +40,8 @@ namespace ams::sm {
|
||||
return out;
|
||||
}
|
||||
|
||||
static constexpr ServiceName Encode(const char *name) {
|
||||
return Encode(name, std::strlen(name));
|
||||
static constexpr ServiceName Encode(util::string_view name) {
|
||||
return Encode(name.data(), name.size());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace ams::time {
|
||||
AMS_ASSERT(rhs.IsValid());
|
||||
}
|
||||
|
||||
constexpr auto ToUint64 = [] ALWAYS_INLINE_LAMBDA (const time::CalendarTime &time) {
|
||||
constexpr auto ToUint64 = [](const time::CalendarTime &time) ALWAYS_INLINE_LAMBDA {
|
||||
return (static_cast<u64>(time.year) << 40) |
|
||||
(static_cast<u64>(time.month) << 32) |
|
||||
(static_cast<u64>(time.day) << 24) |
|
||||
|
||||
@@ -472,7 +472,7 @@ namespace ams::tipc::impl {
|
||||
using OutRawHolderType = OutRawHolder<CommandMeta::OutDataSize, CommandMeta::OutDataAlign, CommandMeta::OutMessageRawDataIndex>;
|
||||
using OutHandleHolderType = OutHandleHolder<CommandMeta::NumOutMoveHandles, CommandMeta::NumOutCopyHandles, CommandMeta::OutMessageHandleIndex>;
|
||||
private:
|
||||
static consteval u64 GetMessageHeaderForCheck(const svc::ipc::MessageBuffer::MessageHeader &header) {
|
||||
static constexpr u64 GetMessageHeaderForCheck(const svc::ipc::MessageBuffer::MessageHeader &header) {
|
||||
using Value = util::BitPack32::Field<0, BITSIZEOF(util::BitPack32)>;
|
||||
|
||||
const util::BitPack32 *data = header.GetData();
|
||||
@@ -482,7 +482,7 @@ namespace ams::tipc::impl {
|
||||
return static_cast<u64>(lower) | (static_cast<u64>(upper) << BITSIZEOF(u32));
|
||||
}
|
||||
|
||||
static consteval u32 GetSpecialHeaderForCheck(const svc::ipc::MessageBuffer::SpecialHeader &header) {
|
||||
static constexpr u32 GetSpecialHeaderForCheck(const svc::ipc::MessageBuffer::SpecialHeader &header) {
|
||||
using Value = util::BitPack32::Field<0, BITSIZEOF(util::BitPack32)>;
|
||||
|
||||
return header.GetHeader()->Get<Value>();
|
||||
|
||||
@@ -167,12 +167,12 @@ namespace ams::tipc {
|
||||
return AMS_OFFSETOF(DeferralManagerBase, m_objects_base);
|
||||
}
|
||||
|
||||
template<size_t N>
|
||||
template<size_t N> requires (N > 0)
|
||||
consteval size_t DeferralManager<N>::GetObjectPointersOffset() {
|
||||
return AMS_OFFSETOF(DeferralManager<N>, m_objects);
|
||||
}
|
||||
|
||||
template<size_t N>
|
||||
template<size_t N> requires (N > 0)
|
||||
inline DeferralManager<N>::DeferralManager() : DeferralManagerBase() {
|
||||
static_assert(GetObjectPointersOffset() == GetObjectPointersOffsetBase());
|
||||
static_assert(sizeof(DeferralManager<N>) == sizeof(DeferralManagerBase) + N * sizeof(DeferrableBase *));
|
||||
|
||||
@@ -686,7 +686,7 @@ namespace ams::tipc {
|
||||
}
|
||||
|
||||
/* Try to reply/receive. */
|
||||
const Result result = [&] ALWAYS_INLINE_LAMBDA () -> Result {
|
||||
const Result result = [&]() ALWAYS_INLINE_LAMBDA -> Result {
|
||||
os::MultiWaitHolderType *signaled_holder = nullptr;
|
||||
ON_SCOPE_EXIT { AMS_ABORT_UNLESS(signaled_holder == nullptr); };
|
||||
return m_object_manager->ReplyAndReceive(std::addressof(signaled_holder), out_object, reply_target, std::addressof(m_multi_wait));
|
||||
@@ -747,7 +747,7 @@ namespace ams::tipc {
|
||||
using PortManager = PortManagerImpl;
|
||||
private:
|
||||
PortManager m_port_manager;
|
||||
PortInfo::Allocator m_port_allocator;
|
||||
typename PortInfo::Allocator m_port_allocator;
|
||||
public:
|
||||
constexpr ServerManagerImpl() : m_port_manager(), m_port_allocator() { /* ... */ }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user