From 2e20b0d1289ae3d3ebf08125fcf0891fcbe86a57 Mon Sep 17 00:00:00 2001 From: Nika Layzell Date: Thu, 5 Oct 2017 17:06:43 -0400 Subject: [PATCH] Bug 1377351 - Part 5: Add a workaround for gcc 4.9 compiler bug, r=froydnj MozReview-Commit-ID: CHywpZ4fvXf --- xpcom/string/nsTLiteralString.h | 9 +++++++++ xpcom/string/nsTString.h | 31 +++++++++++++++++++++++++++++++ xpcom/string/nsTStringRepr.h | 2 ++ xpcom/string/nsTSubstring.cpp | 8 ++++++++ xpcom/string/nsTSubstring.h | 14 ++++++++++++++ 5 files changed, 64 insertions(+) diff --git a/xpcom/string/nsTLiteralString.h b/xpcom/string/nsTLiteralString.h index d18e6c137a84..d32618f86201 100644 --- a/xpcom/string/nsTLiteralString.h +++ b/xpcom/string/nsTLiteralString.h @@ -26,7 +26,16 @@ class nsTLiteralString : public mozilla::detail::nsTStringRepr public: typedef nsTLiteralString self_type; + +#ifdef __clang__ + // bindgen w/ clang 3.9 at least chokes on a typedef, but using is okay. + using typename mozilla::detail::nsTStringRepr::base_string_type; +#else + // On the other hand msvc chokes on the using statement. It seems others + // don't care either way so we lump them in here. typedef typename mozilla::detail::nsTStringRepr::base_string_type base_string_type; +#endif + typedef typename base_string_type::char_type char_type; typedef typename base_string_type::size_type size_type; typedef typename base_string_type::DataFlags DataFlags; diff --git a/xpcom/string/nsTString.h b/xpcom/string/nsTString.h index d30054081702..a41f9cf50c8d 100644 --- a/xpcom/string/nsTString.h +++ b/xpcom/string/nsTString.h @@ -38,6 +38,8 @@ public: typedef typename nsTSubstring::substring_type substring_type; #endif + typedef typename substring_type::literalstring_type literalstring_type; + typedef typename substring_type::fallible_t fallible_t; typedef typename substring_type::char_type char_type; @@ -124,6 +126,14 @@ public: this->Assign(mozilla::Move(aReadable)); } + // NOTE(nika): gcc 4.9 workaround. Remove when support is dropped. + explicit + nsTString(const literalstring_type& aReadable) + : substring_type(ClassFlags::NULL_TERMINATED) + { + this->Assign(aReadable); + } + // |operator=| does not inherit, so we must define our own self_type& operator=(char_type aChar) @@ -164,6 +174,12 @@ public: this->Assign(mozilla::Move(aStr)); return *this; } + // NOTE(nika): gcc 4.9 workaround. Remove when support is dropped. + self_type& operator=(const literalstring_type& aStr) + { + this->Assign(aStr); + return *this; + } self_type& operator=(const substring_tuple_type& aTuple) { this->Assign(aTuple); @@ -574,6 +590,7 @@ public: typedef typename base_string_type::substring_type substring_type; typedef typename base_string_type::size_type size_type; typedef typename base_string_type::substring_tuple_type substring_tuple_type; + typedef typename base_string_type::literalstring_type literalstring_type; // These are only for internal use within the string classes: typedef typename base_string_type::DataFlags DataFlags; @@ -646,6 +663,14 @@ public: this->Assign(mozilla::Move(aStr)); } + // NOTE(nika): gcc 4.9 workaround. Remove when support is dropped. + explicit + nsTAutoStringN(const literalstring_type& aStr) + : self_type() + { + this->Assign(aStr); + } + MOZ_IMPLICIT nsTAutoStringN(const substring_tuple_type& aTuple) : self_type() { @@ -691,6 +716,12 @@ public: this->Assign(mozilla::Move(aStr)); return *this; } + // NOTE(nika): gcc 4.9 workaround. Remove when support is dropped. + self_type& operator=(const literalstring_type& aStr) + { + this->Assign(aStr); + return *this; + } self_type& operator=(const substring_tuple_type& aTuple) { this->Assign(aTuple); diff --git a/xpcom/string/nsTStringRepr.h b/xpcom/string/nsTStringRepr.h index 6b6088b66bd1..26b6c1a050e6 100644 --- a/xpcom/string/nsTStringRepr.h +++ b/xpcom/string/nsTStringRepr.h @@ -13,6 +13,7 @@ #include "nsCharTraits.h" template class nsTSubstringTuple; +template class nsTLiteralString; // The base for string comparators template class nsTStringComparator @@ -74,6 +75,7 @@ public: typedef nsTSubstring substring_type; typedef nsTSubstringTuple substring_tuple_type; + typedef nsTLiteralString literalstring_type; typedef nsReadingIterator const_iterator; typedef nsWritingIterator iterator; diff --git a/xpcom/string/nsTSubstring.cpp b/xpcom/string/nsTSubstring.cpp index d78f02cc4d75..2257437c15ce 100644 --- a/xpcom/string/nsTSubstring.cpp +++ b/xpcom/string/nsTSubstring.cpp @@ -530,6 +530,14 @@ nsTSubstring::Assign(self_type&& aStr, const fallible_t& aFallible) return true; } +// NOTE(nika): gcc 4.9 workaround. Remove when support is dropped. +template +void +nsTSubstring::Assign(const literalstring_type& aStr) +{ + Assign(aStr.AsString()); +} + template void nsTSubstring::Assign(const substring_tuple_type& aTuple) diff --git a/xpcom/string/nsTSubstring.h b/xpcom/string/nsTSubstring.h index b8b36152853f..29c42c85e5f8 100644 --- a/xpcom/string/nsTSubstring.h +++ b/xpcom/string/nsTSubstring.h @@ -46,6 +46,7 @@ public: typedef typename mozilla::detail::nsTStringRepr base_string_type; typedef typename base_string_type::substring_type substring_type; + typedef typename base_string_type::literalstring_type literalstring_type; typedef typename base_string_type::fallible_t fallible_t; @@ -174,6 +175,13 @@ public: void NS_FASTCALL Assign(self_type&&); MOZ_MUST_USE bool NS_FASTCALL Assign(self_type&&, const fallible_t&); + // XXX(nika): GCC 4.9 doesn't correctly resolve calls to Assign a + // nsLiteralCString into a nsTSubstring, due to a frontend bug. This explcit + // Assign overload (and the corresponding constructor and operator= overloads) + // are used to avoid this bug. Once we stop supporting GCC 4.9 we can remove + // them. + void NS_FASTCALL Assign(const literalstring_type&); + void NS_FASTCALL Assign(const substring_tuple_type&); MOZ_MUST_USE bool NS_FASTCALL Assign(const substring_tuple_type&, const fallible_t&); @@ -263,6 +271,12 @@ public: Assign(mozilla::Move(aStr)); return *this; } + // NOTE(nika): gcc 4.9 workaround. Remove when support is dropped. + self_type& operator=(const literalstring_type& aStr) + { + Assign(aStr); + return *this; + } self_type& operator=(const substring_tuple_type& aTuple) { Assign(aTuple);