1 // { dg-do compile { target c++11 } }
2 
3 // Reduced from Mozilla SpiderMonkey, licensed under MPL-2.0.
4 
5 template<typename T, unsigned N>
6 class Vector
7 {
8   public:
Vector()9     Vector() {}
length()10     unsigned length() const { return 0; }
11 };
12 
13 class TokenStreamShared
14 {
15 };
16 
17 template<typename CharT, class AnyCharsAccess>
18 class TokenStreamSpecific;
19 
20 class TokenStreamAnyChars
21   : public TokenStreamShared
22 {
23   public:
TokenStreamAnyChars()24     TokenStreamAnyChars() {}
25 };
26 
27 template<typename CharT>
28 class SourceUnits
29 {
30   public:
SourceUnits()31     SourceUnits() {}
32 
atEnd()33     bool atEnd() const { return true; }
offset()34     unsigned offset() const { return 0; }
matchCodeUnit(CharT c)35     bool matchCodeUnit(CharT c) { return true; }
36 };
37 
38 class TokenStreamCharsShared
39 {
40     using CharBuffer = Vector<char16_t, 32>;
41 
42   protected:
43     CharBuffer charBuffer;
44 
45   protected:
TokenStreamCharsShared()46     explicit TokenStreamCharsShared() {}
47 };
48 
49 template<typename CharT>
50 class TokenStreamCharsBase
51   : public TokenStreamCharsShared
52 {
53   public:
TokenStreamCharsBase()54     TokenStreamCharsBase()
55       : TokenStreamCharsShared(), sourceUnits()
56     {}
57 
58     using SourceUnits = ::SourceUnits<CharT>;
59 
matchCodeUnit(int expect)60     bool matchCodeUnit(int expect) { return true; }
61 
62   protected:
63     SourceUnits sourceUnits;
64 };
65 
66 template<typename CharT, class AnyCharsAccess>
67 class GeneralTokenStreamChars
68   : public TokenStreamCharsBase<CharT>
69 {
70     using CharsBase = TokenStreamCharsBase<CharT>;
71 
72   protected:
73     using CharsBase::CharsBase;
74 
75     TokenStreamAnyChars& anyCharsAccess();
76     const TokenStreamAnyChars& anyCharsAccess() const;
77 };
78 
79 template<typename CharT, class AnyCharsAccess> class TokenStreamChars;
80 
81 template<class AnyCharsAccess>
82 class TokenStreamChars<char16_t, AnyCharsAccess>
83   : public GeneralTokenStreamChars<char16_t, AnyCharsAccess>
84 {
85   private:
86     using CharsBase = TokenStreamCharsBase<char16_t>;
87     using GeneralCharsBase = GeneralTokenStreamChars<char16_t, AnyCharsAccess>;
88     using Self = TokenStreamChars<char16_t, AnyCharsAccess>;
89 
90   protected:
91     using GeneralCharsBase::anyCharsAccess;
92     using CharsBase::sourceUnits;
93 
94     using typename GeneralCharsBase::SourceUnits;
95 
96   protected:
97     using GeneralCharsBase::GeneralCharsBase;
98 
getFullAsciiCodePoint(int lead,int * codePoint)99     bool getFullAsciiCodePoint(int lead, int* codePoint) {
100         if (lead == '\r') {
101             bool isAtEnd = sourceUnits.atEnd();
102             if (!isAtEnd)
103                 sourceUnits.matchCodeUnit('\n');
104         } else if (lead != '\n') {
105             *codePoint = lead;
106             return true;
107         }
108 
109         *codePoint = '\n';
110         return true;
111     }
112 };
113 
114 template<typename CharT, class AnyCharsAccess>
115 class TokenStreamSpecific
116   : public TokenStreamChars<CharT, AnyCharsAccess>,
117     public TokenStreamShared
118 {
119   public:
120     using CharsBase = TokenStreamCharsBase<CharT>;
121     using GeneralCharsBase = GeneralTokenStreamChars<CharT, AnyCharsAccess>;
122     using SpecializedCharsBase = TokenStreamChars<CharT, AnyCharsAccess>;
123 
124   public:
125     using GeneralCharsBase::anyCharsAccess;
126 
127   private:
128     using typename CharsBase::SourceUnits;
129 
130   private:
131     using TokenStreamCharsShared::charBuffer;
132     using CharsBase::sourceUnits;
133 
134   public:
TokenStreamSpecific()135     TokenStreamSpecific()
136       : SpecializedCharsBase()
137     {}
138 
139   public:
advance(unsigned position)140     bool advance(unsigned position) {
141         bool t = charBuffer.length() + 1 > 0;
142         auto offs = sourceUnits.offset();
143         return t && offs > 0;
144     }
145 };
146 
147 class TokenStreamAnyCharsAccess
148 {
149 };
150 
151 class TokenStream final
152   : public TokenStreamAnyChars,
153     public TokenStreamSpecific<char16_t, TokenStreamAnyCharsAccess>
154 {
155     using CharT = char16_t;
156 
157   public:
TokenStream()158     TokenStream()
159     : TokenStreamAnyChars(),
160       TokenStreamSpecific<CharT, TokenStreamAnyCharsAccess>()
161     {}
162 };
163 
164 class SyntaxParseHandler {};
165 
166 class ParserBase
167 {
168   public:
169     TokenStreamAnyChars anyChars;
170 };
171 
172 template<class ParseHandler, typename CharT> class GeneralParser;
173 
174 template <class ParseHandler>
175 class PerHandlerParser : public ParserBase
176 {
177 };
178 
179 template<class Parser>
180 class ParserAnyCharsAccess
181 {
182 };
183 
184 template <class ParseHandler, typename CharT>
185 class Parser;
186 
187 template <class ParseHandler, typename CharT>
188 class GeneralParser
189   : public PerHandlerParser<ParseHandler>
190 {
191   public:
192     TokenStreamSpecific<CharT, ParserAnyCharsAccess<GeneralParser>> tokenStream;
193 
194   public:
195     GeneralParser();
196 };
197 
198 
199 template class TokenStreamCharsBase<char16_t>;
200 
201 template class TokenStreamChars<char16_t, TokenStreamAnyCharsAccess>;
202 
203 template class
204 TokenStreamChars<char16_t, ParserAnyCharsAccess<GeneralParser<SyntaxParseHandler, char16_t>>>;
205 
206 template class
207 TokenStreamSpecific<char16_t, ParserAnyCharsAccess<GeneralParser<SyntaxParseHandler, char16_t>>>;
208