1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #include <precomp.h>
29 #include "pe_class.hxx"
30 
31 
32 // NOT FULLY DECLARED SERVICES
33 #include <cosv/tpl/tpltools.hxx>
34 #include <ary/cpp/c_gate.hxx>
35 #include <ary/cpp/c_class.hxx>
36 #include <ary/cpp/c_namesp.hxx>
37 #include <ary/cpp/cp_ce.hxx>
38 #include <all_toks.hxx>
39 #include "pe_base.hxx"
40 #include "pe_defs.hxx"
41 #include "pe_enum.hxx"
42 #include "pe_tydef.hxx"
43 #include "pe_vafu.hxx"
44 #include "pe_ignor.hxx"
45 
46 
47 namespace cpp {
48 
49 // using ary::Cid;
50 
51 PE_Class::PE_Class(Cpp_PE * i_pParent )
52 	:   Cpp_PE(i_pParent),
53 		pStati( new PeStatusArray<PE_Class> ),
54 		// pSpBase,
55 		// pSpTypedef,
56 		// pSpVarFunc,
57 		// pSpIgnore,
58 		// pSpuBase,
59 		// pSpuTypedef,
60 		// pSpuVarFunc,
61 		// pSpuUsing,
62         // pSpuIgnoreFailure,
63 		// sLocalName,
64 		eClassKey(ary::cpp::CK_class),
65 		pCurObject(0),
66         // aBases,
67 		eResult_KindOf(is_declaration)
68 {
69 	Setup_StatusFunctions();
70 
71 	pSpBase     = new SP_Base(*this);
72 	pSpTypedef  = new SP_Typedef(*this);
73 	pSpVarFunc  = new SP_VarFunc(*this);
74 	pSpIgnore   = new SP_Ignore(*this);
75 	pSpDefs     = new SP_Defines(*this);
76 
77 	pSpuBase	= new SPU_Base(*pSpBase, 0, &PE_Class::SpReturn_Base);
78 	pSpuTypedef	= new SPU_Typedef(*pSpTypedef, 0, 0);
79 	pSpuVarFunc = new SPU_VarFunc(*pSpVarFunc, 0, 0);
80 
81 	pSpuTemplate= new SPU_Ignore(*pSpIgnore, 0, 0);
82 	pSpuUsing   = new SPU_Ignore(*pSpIgnore, 0, 0);
83     pSpuIgnoreFailure
84                 = new SPU_Ignore(*pSpIgnore, 0, 0);
85 	pSpuDefs	= new SPU_Defines(*pSpDefs, 0, 0);
86 }
87 
88 
89 PE_Class::~PE_Class()
90 {
91 }
92 
93 void
94 PE_Class::Call_Handler( const cpp::Token &	i_rTok )
95 {
96 	pStati->Cur().Call_Handler(i_rTok.TypeId(), i_rTok.Text());
97 }
98 
99 Cpp_PE *
100 PE_Class::Handle_ChildFailure()
101 {
102     SetCurSPU(pSpuIgnoreFailure.Ptr());
103     return &pSpuIgnoreFailure->Child();
104 }
105 
106 void
107 PE_Class::Setup_StatusFunctions()
108 {
109 	typedef CallFunction<PE_Class>::F_Tok	F_Tok;
110 
111 	static F_Tok stateF_start[] =			{ &PE_Class::On_start_class,
112 											  &PE_Class::On_start_struct,
113 											  &PE_Class::On_start_union };
114 	static INT16 stateT_start[] =       	{ Tid_class,
115 											  Tid_struct,
116 											  Tid_union };
117 
118 	static F_Tok stateF_expectName[] = 		{ &PE_Class::On_expectName_Identifier,
119 											  &PE_Class::On_expectName_SwBracket_Left,
120 											  &PE_Class::On_expectName_Colon
121 											};
122 	static INT16 stateT_expectName[] = 		{ Tid_Identifier,
123 											  Tid_SwBracket_Left,
124 											  Tid_Colon
125 											};
126 
127 	static F_Tok stateF_gotName[] =			{ &PE_Class::On_gotName_SwBracket_Left,
128 											  &PE_Class::On_gotName_Semicolon,
129 											  &PE_Class::On_gotName_Colon };
130 	static INT16 stateT_gotName[] =       	{ Tid_SwBracket_Left,
131 											  Tid_Semicolon,
132 											  Tid_Colon };
133 
134 	static F_Tok stateF_bodyStd[] =			{ &PE_Class::On_bodyStd_VarFunc,
135 											  &PE_Class::On_bodyStd_VarFunc,
136 											  &PE_Class::On_bodyStd_ClassKey,
137 											  &PE_Class::On_bodyStd_ClassKey,
138 											  &PE_Class::On_bodyStd_ClassKey,
139 
140 											  &PE_Class::On_bodyStd_enum,
141 											  &PE_Class::On_bodyStd_typedef,
142 											  &PE_Class::On_bodyStd_public,
143 											  &PE_Class::On_bodyStd_protected,
144 											  &PE_Class::On_bodyStd_private,
145 
146 											  &PE_Class::On_bodyStd_template,
147 											  &PE_Class::On_bodyStd_VarFunc,
148 											  &PE_Class::On_bodyStd_friend,
149 											  &PE_Class::On_bodyStd_VarFunc,
150 											  &PE_Class::On_bodyStd_VarFunc,
151 
152 											  &PE_Class::On_bodyStd_VarFunc,
153 											  &PE_Class::On_bodyStd_VarFunc,
154 											  &PE_Class::On_bodyStd_VarFunc,
155 											  &PE_Class::On_bodyStd_VarFunc,
156 											  &PE_Class::On_bodyStd_VarFunc,
157 
158 											  &PE_Class::On_bodyStd_using,
159 											  &PE_Class::On_bodyStd_SwBracket_Right,
160 											  &PE_Class::On_bodyStd_VarFunc,
161                                               &PE_Class::On_bodyStd_DefineName,
162                                               &PE_Class::On_bodyStd_MacroName,
163 
164 											  &PE_Class::On_bodyStd_VarFunc,
165 											  &PE_Class::On_bodyStd_VarFunc,
166                                               &PE_Class::On_bodyStd_VarFunc, };
167 
168 	static INT16 stateT_bodyStd[] =       	{ Tid_Identifier,
169 											  Tid_operator,
170 											  Tid_class,
171 											  Tid_struct,
172 											  Tid_union,
173 
174 											  Tid_enum,
175 											  Tid_typedef,
176 											  Tid_public,
177 											  Tid_protected,
178 											  Tid_private,
179 
180 											  Tid_template,
181 											  Tid_virtual,
182 											  Tid_friend,
183 											  Tid_Tilde,
184 											  Tid_const,
185 
186 											  Tid_volatile,
187 											  Tid_static,
188 											  Tid_mutable,
189 					  						  Tid_inline,
190 											  Tid_explicit,
191 
192 											  Tid_using,
193 											  Tid_SwBracket_Right,
194 											  Tid_DoubleColon,
195                                               Tid_typename,
196                                               Tid_DefineName,
197 
198                                               Tid_MacroName,
199 											  Tid_BuiltInType,
200 											  Tid_TypeSpecializer };
201 
202 											  static F_Tok stateF_inProtection[] = 	{ &PE_Class::On_inProtection_Colon };
203 	static INT16 stateT_inProtection[] =   	{ Tid_Colon };
204 
205 	static F_Tok stateF_afterDecl[] = 	    { &PE_Class::On_afterDecl_Semicolon };
206 	static INT16 stateT_afterDecl[] =   	{ Tid_Semicolon };
207 
208 	SEMPARSE_CREATE_STATUS(PE_Class, start, Hdl_SyntaxError);
209 	SEMPARSE_CREATE_STATUS(PE_Class, expectName, Hdl_SyntaxError);
210 	SEMPARSE_CREATE_STATUS(PE_Class, gotName, On_gotName_Return2Type);
211 	SEMPARSE_CREATE_STATUS(PE_Class, bodyStd, Hdl_SyntaxError);
212 	SEMPARSE_CREATE_STATUS(PE_Class, inProtection, Hdl_SyntaxError);
213 	SEMPARSE_CREATE_STATUS(PE_Class, afterDecl, On_afterDecl_Return2Type);
214 
215 #if 0
216 	static F_Tok stateF_inFriend[] =	 	{ On_inFriend_class,
217 											  On_inFriend_struct,
218 											  On_inFriend_union };
219 											  // Default: On_inFriend_Function
220 	static INT16 stateT_inFriend[] =     	{ Tid_class,
221 											  Tid_struct,
222 											  Tid_union };
223 #endif // 0
224 }
225 
226 void
227 PE_Class::InitData()
228 {
229 	pStati->SetCur(start);
230 	sLocalName.clear();
231 	eClassKey = ary::cpp::CK_class;
232 	pCurObject = 0;
233     csv::erase_container(aBases);
234     eResult_KindOf = is_declaration;
235 }
236 
237 void
238 PE_Class::TransferData()
239 {
240 	pStati->SetCur(size_of_states);
241 }
242 
243 void
244 PE_Class::Hdl_SyntaxError( const char * i_sText)
245 {
246     if ( *i_sText == ';' )
247     {
248      	Cerr() << Env().CurFileName() << ", line "
249                   << Env().LineCount()
250                   << ": Sourcecode warning: ';' as a toplevel declaration is deprecated."
251                   << Endl();
252     	SetTokenResult(done,stay);
253         return;
254     }
255 
256 	StdHandlingOfSyntaxError(i_sText);
257 }
258 
259 void
260 PE_Class::Init_CurObject()
261 {
262     // KORR_FUTURE
263     //   This will have to be done before parsing base classes, because of
264     //   possible inline documentation for base classes.
265 	pCurObject = & Env().AryGate().Ces().Store_Class( Env().Context(), sLocalName, eClassKey );
266 
267   	for ( PE_Base::BaseList::const_iterator it = aBases.begin();
268 		  it !=  aBases.end();
269 		  ++it )
270 	{
271 		pCurObject->Add_BaseClass( *it );
272 	}  // end for
273 
274     Dyn< StringVector >
275             pTplParams( Env().Get_CurTemplateParameters() );
276     if ( pTplParams )
277     {
278       	for ( StringVector::const_iterator it = pTplParams->begin();
279 	    	  it !=  pTplParams->end();
280 		      ++it )
281     	{
282 	    	pCurObject->Add_TemplateParameterType( *it, ary::cpp::Type_id(0) );
283     	}  // end for
284     }
285 }
286 
287 void
288 PE_Class::SpReturn_Base()
289 {
290 	aBases = pSpuBase->Child().Result_BaseIds();
291 	pStati->SetCur(gotName);
292 }
293 
294 void
295 PE_Class::On_start_class( const char * )
296 {
297 	SetTokenResult(done, stay);
298 	pStati->SetCur(expectName);
299 	eClassKey = ary::cpp::CK_class;
300 }
301 
302 void
303 PE_Class::On_start_struct( const char * )
304 {
305 	SetTokenResult(done, stay);
306 	pStati->SetCur(expectName);
307 	eClassKey = ary::cpp::CK_struct;
308 }
309 
310 void
311 PE_Class::On_start_union( const char * )
312 {
313 	SetTokenResult(done, stay);
314 	pStati->SetCur(expectName);
315 	eClassKey = ary::cpp::CK_union;
316 }
317 
318 void
319 PE_Class::On_expectName_Identifier( const char * i_sText )
320 {
321 	SetTokenResult(done, stay);
322 	pStati->SetCur(gotName);
323     sLocalName = i_sText;
324 }
325 
326 void
327 PE_Class::On_expectName_SwBracket_Left( const char * )
328 {
329 	SetTokenResult(done, stay);
330 	pStati->SetCur(bodyStd);
331 
332     sLocalName = "";
333 	Init_CurObject();
334     sLocalName = pCurObject->LocalName();
335 
336     Env().OpenClass(*pCurObject);
337 }
338 
339 void
340 PE_Class::On_expectName_Colon( const char * )
341 {
342 	pStati->SetCur(gotName);
343     sLocalName = "";
344 
345 	pSpuBase->Push(done);
346 }
347 
348 void
349 PE_Class::On_gotName_SwBracket_Left( const char * )
350 {
351 	SetTokenResult(done, stay);
352 	pStati->SetCur(bodyStd);
353 
354 	Init_CurObject();
355     if ( sLocalName.empty() )
356         sLocalName = pCurObject->LocalName();
357 
358     Env().OpenClass(*pCurObject);
359 }
360 
361 void
362 PE_Class::On_gotName_Semicolon( const char * )
363 {
364 	SetTokenResult(not_done, pop_success);
365 
366 	eResult_KindOf = is_predeclaration;
367 }
368 
369 void
370 PE_Class::On_gotName_Colon( const char * )
371 {
372 	pSpuBase->Push(done);
373 }
374 
375 void
376 PE_Class::On_gotName_Return2Type( const char * )
377 {
378 	SetTokenResult(not_done, pop_success);
379 
380 	eResult_KindOf = is_qualified_typename;
381 }
382 
383 void
384 PE_Class::On_bodyStd_VarFunc( const char * )
385 {
386     pSpuVarFunc->Push(not_done);
387 }
388 
389 void
390 PE_Class::On_bodyStd_ClassKey( const char * )
391 {
392 	pSpuVarFunc->Push(not_done);		// This is correct,
393                                         //   classes are parsed via PE_Type.
394 }
395 
396 void
397 PE_Class::On_bodyStd_enum( const char * )
398 {
399 	pSpuVarFunc->Push(not_done);		// This is correct,
400                                         //   enums are parsed via PE_Type.
401 }
402 
403 void
404 PE_Class::On_bodyStd_typedef( const char * )
405 {
406     pSpuTypedef->Push(not_done);
407 }
408 
409 void
410 PE_Class::On_bodyStd_public( const char * )
411 {
412     SetTokenResult(done, stay);
413     pStati->SetCur(inProtection);
414 
415     Env().SetCurProtection(ary::cpp::PROTECT_public);
416 }
417 
418 void
419 PE_Class::On_bodyStd_protected( const char * )
420 {
421     SetTokenResult(done, stay);
422     pStati->SetCur(inProtection);
423 
424     Env().SetCurProtection(ary::cpp::PROTECT_protected);
425 }
426 
427 void
428 PE_Class::On_bodyStd_private( const char * )
429 {
430     SetTokenResult(done, stay);
431     pStati->SetCur(inProtection);
432 
433     Env().SetCurProtection(ary::cpp::PROTECT_private);
434 }
435 
436 void
437 PE_Class::On_bodyStd_template( const char * )
438 {
439     pSpuTemplate->Push(done);
440 }
441 
442 void
443 PE_Class::On_bodyStd_friend( const char * )
444 {
445     // KORR_FUTURE
446     pSpuUsing->Push(done);
447 }
448 
449 void
450 PE_Class::On_bodyStd_using( const char * )
451 {
452     pSpuUsing->Push(done);
453 }
454 
455 void
456 PE_Class::On_bodyStd_SwBracket_Right( const char * )
457 {
458     SetTokenResult(done, stay);
459     pStati->SetCur(afterDecl);
460 
461     Env().CloseClass();
462 }
463 
464 void
465 PE_Class::On_bodyStd_DefineName(const char * )
466 {
467 	pSpuDefs->Push(not_done);
468 }
469 
470 void
471 PE_Class::On_bodyStd_MacroName(const char * )
472 {
473 	pSpuDefs->Push(not_done);
474 }
475 
476 
477 void
478 PE_Class::On_inProtection_Colon( const char * )
479 {
480     SetTokenResult(done, stay);
481     pStati->SetCur(bodyStd);
482 }
483 
484 void
485 PE_Class::On_afterDecl_Semicolon( const char * )
486 {
487 	SetTokenResult(not_done, pop_success);
488 	eResult_KindOf = is_declaration;
489 }
490 
491 void
492 PE_Class::On_afterDecl_Return2Type( const char * )
493 {
494 	SetTokenResult(not_done, pop_success);
495 	eResult_KindOf = is_implicit_declaration;
496 }
497 
498 
499 }   // namespace cpp
500 
501 
502 
503 
504