// { dg-do compile { target c++11 } } // Reduced from Mozilla SpiderMonkey, licensed under MPL-2.0. template class Vector { public: Vector() {} unsigned length() const { return 0; } }; class TokenStreamShared { }; template class TokenStreamSpecific; class TokenStreamAnyChars : public TokenStreamShared { public: TokenStreamAnyChars() {} }; template class SourceUnits { public: SourceUnits() {} bool atEnd() const { return true; } unsigned offset() const { return 0; } bool matchCodeUnit(CharT c) { return true; } }; class TokenStreamCharsShared { using CharBuffer = Vector; protected: CharBuffer charBuffer; protected: explicit TokenStreamCharsShared() {} }; template class TokenStreamCharsBase : public TokenStreamCharsShared { public: TokenStreamCharsBase() : TokenStreamCharsShared(), sourceUnits() {} using SourceUnits = ::SourceUnits; bool matchCodeUnit(int expect) { return true; } protected: SourceUnits sourceUnits; }; template class GeneralTokenStreamChars : public TokenStreamCharsBase { using CharsBase = TokenStreamCharsBase; protected: using CharsBase::CharsBase; TokenStreamAnyChars& anyCharsAccess(); const TokenStreamAnyChars& anyCharsAccess() const; }; template class TokenStreamChars; template class TokenStreamChars : public GeneralTokenStreamChars { private: using CharsBase = TokenStreamCharsBase; using GeneralCharsBase = GeneralTokenStreamChars; using Self = TokenStreamChars; protected: using GeneralCharsBase::anyCharsAccess; using CharsBase::sourceUnits; using typename GeneralCharsBase::SourceUnits; protected: using GeneralCharsBase::GeneralCharsBase; bool getFullAsciiCodePoint(int lead, int* codePoint) { if (lead == '\r') { bool isAtEnd = sourceUnits.atEnd(); if (!isAtEnd) sourceUnits.matchCodeUnit('\n'); } else if (lead != '\n') { *codePoint = lead; return true; } *codePoint = '\n'; return true; } }; template class TokenStreamSpecific : public TokenStreamChars, public TokenStreamShared { public: using CharsBase = TokenStreamCharsBase; using GeneralCharsBase = GeneralTokenStreamChars; using SpecializedCharsBase = TokenStreamChars; public: using GeneralCharsBase::anyCharsAccess; private: using typename CharsBase::SourceUnits; private: using TokenStreamCharsShared::charBuffer; using CharsBase::sourceUnits; public: TokenStreamSpecific() : SpecializedCharsBase() {} public: bool advance(unsigned position) { bool t = charBuffer.length() + 1 > 0; auto offs = sourceUnits.offset(); return t && offs > 0; } }; class TokenStreamAnyCharsAccess { }; class TokenStream final : public TokenStreamAnyChars, public TokenStreamSpecific { using CharT = char16_t; public: TokenStream() : TokenStreamAnyChars(), TokenStreamSpecific() {} }; class SyntaxParseHandler {}; class ParserBase { public: TokenStreamAnyChars anyChars; }; template class GeneralParser; template class PerHandlerParser : public ParserBase { }; template class ParserAnyCharsAccess { }; template class Parser; template class GeneralParser : public PerHandlerParser { public: TokenStreamSpecific> tokenStream; public: GeneralParser(); }; template class TokenStreamCharsBase; template class TokenStreamChars; template class TokenStreamChars>>; template class TokenStreamSpecific>>;