1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 #include <precomp.h>
23 #include "pe_type.hxx"
24 
25 
26 // NOT FULLY DEFINED SERVICES
27 #include <ary/cpp/inpcontx.hxx>
28 #include <ary/cpp/c_gate.hxx>
29 #include <ary/cpp/c_class.hxx>
30 #include <ary/cpp/c_namesp.hxx>
31 #include <ary/cpp/cp_type.hxx>
32 #include "pe_class.hxx"
33 #include "pe_enum.hxx"
34 #include <x_parse.hxx>
35 
36 
37 
38 class NullType : public ary::cpp::Type
39 {
40   private:
41     virtual void        do_Accept(
42                             csv::ProcessorIfc & io_processor ) const;
43     virtual ary::ClassId
44                         get_AryClass() const;
45 	virtual bool        inq_IsConst() const;
46 	virtual void        inq_Get_Text(
47 							StreamStr &         o_rPreName,
48 							StreamStr &         o_rName,
49 							StreamStr &         o_rPostName,
50 							const ary::cpp::Gate &
51 							                    i_rGate ) const;
52 };
53 
54 void
do_Accept(csv::ProcessorIfc &) const55 NullType::do_Accept(csv::ProcessorIfc & ) const
56 {
57     // Does nothing.
58 }
59 
60 ary::ClassId
get_AryClass() const61 NullType::get_AryClass() const
62 {
63     return 0;
64 }
65 
66 bool
inq_IsConst() const67 NullType::inq_IsConst() const
68 {
69     return true;
70 }
71 
72 void
inq_Get_Text(StreamStr &,StreamStr &,StreamStr &,const ary::cpp::Gate &) const73 NullType::inq_Get_Text(		StreamStr &         ,
74 							StreamStr &         ,
75 							StreamStr &         ,
76 							const ary::cpp::Gate &	) const
77 {
78     // Does nothing.
79 }
80 
81 
82 
83 
84 namespace cpp
85 {
86 
87 
88 inline bool
IsType() const89 PE_Type::IsType() const
90 	{ return eResult_KindOf == is_type; }
91 
92 
PE_Type(Cpp_PE * i_pParent)93 PE_Type::PE_Type( Cpp_PE * i_pParent )
94 	:   Cpp_PE(i_pParent),
95         pStati( new PeStatusArray<PE_Type> ),
96         pSpType(0),
97 		pSpuType_TemplateParameter(0),
98         // pSpClass,
99 	    // pSpuClass,
100 	    // pSpEnum,
101 	    // pSpuEnum,
102 	    pType(0),
103         pCurTemplate_ParameterList(0),
104 		// sOwningClassName,
105         // sParsedClass_Name,
106 		pResult_Type(0),
107 		eResult_KindOf(is_none),
108         bIsCastOperatorType(false)
109 {
110 	Setup_StatusFunctions();
111 
112 	pSpType         = new SP_Type(*this);
113 	pSpClass        = new SP_Class(*this);
114 	pSpEnum         = new SP_Enum(*this);
115 
116 	pSpuType_TemplateParameter
117 					= new SPU_Type(	 *pSpType, 0,
118 									 &PE_Type::SpReturn_Type_TemplateParameter );
119 	pSpuClass  		= new SPU_Class( *pSpClass, 0,
120 								&    PE_Type::SpReturn_Class );
121 	pSpuEnum  		= new SPU_Enum( *pSpEnum, 0,
122 								&    PE_Type::SpReturn_Enum );
123 }
124 
~PE_Type()125 PE_Type::~PE_Type()
126 {
127 }
128 
129 void
Init_AsCastOperatorType()130 PE_Type::Init_AsCastOperatorType()
131 {
132     bIsCastOperatorType = true;
133 }
134 
135 void
Call_Handler(const cpp::Token & i_rTok)136 PE_Type::Call_Handler( const cpp::Token & i_rTok )
137 {
138 	pStati->Cur().Call_Handler(i_rTok.TypeId(), i_rTok.Text());
139 }
140 
141 void
Setup_StatusFunctions()142 PE_Type::Setup_StatusFunctions()
143 {
144 	typedef CallFunction<PE_Type>::F_Tok	F_Tok;
145 	static F_Tok stateF_start[] =				{ &PE_Type::On_start_Identifier,
146 												  &PE_Type::On_start_class,
147 												  &PE_Type::On_start_class,
148 												  &PE_Type::On_start_class,
149 												  &PE_Type::On_start_enum,
150 												  &PE_Type::On_start_const,
151 												  &PE_Type::On_start_volatile,
152 												  &PE_Type::On_start_Bracket_Right,
153 												  &PE_Type::On_start_DoubleColon,
154 												  &PE_Type::On_start_typename,
155 												  &PE_Type::On_start_BuiltInType,
156 												  &PE_Type::On_start_TypeSpecializer };
157 	static INT16 stateT_start[] =       		{ Tid_Identifier,
158 												  Tid_class,
159 												  Tid_struct,
160 												  Tid_union,
161 												  Tid_enum,
162 												  Tid_const,
163 												  Tid_volatile,
164                                                   Tid_Bracket_Right,
165 												  Tid_DoubleColon,
166                                                   Tid_typename,
167 												  Tid_BuiltInType,
168 												  Tid_TypeSpecializer };
169 
170 	static F_Tok stateF_expect_namesegment[] =  { &PE_Type::On_expect_namesegment_Identifier,
171                                                   &PE_Type::On_expect_namesegment_Identifier };
172 	static INT16 stateT_expect_namesegment[] =  { Tid_Identifier,
173                                                   Tid_BuiltInType };
174 
175 	static F_Tok stateF_after_namesegment[] =	{ &PE_Type::On_after_namesegment_const,
176 												  &PE_Type::On_after_namesegment_volatile,
177                                                   &PE_Type::On_after_namesegment_Bracket_Left,
178 												  &PE_Type::On_after_namesegment_DoubleColon,
179 												  &PE_Type::On_after_namesegment_Less,
180 												  &PE_Type::On_after_namesegment_Asterix,
181 												  &PE_Type::On_after_namesegment_AmpersAnd };
182 	static INT16 stateT_after_namesegment[] =   { Tid_const,
183 												  Tid_volatile,
184 												  Tid_Bracket_Left,
185 												  Tid_DoubleColon,
186 												  Tid_Less,
187 												  Tid_Asterix,
188 												  Tid_AmpersAnd };
189 
190 	static F_Tok stateF_afterclass_expect_semicolon[] =
191 												{ &PE_Type::On_afterclass_expect_semicolon_Semicolon };
192 	static INT16 stateT_afterclass_expect_semicolon[] =
193 												{ Tid_Semicolon };
194 
195 	static F_Tok stateF_within_template[] =		{ &PE_Type::On_within_template_Comma,
196 												  &PE_Type::On_within_template_Greater,
197                                                   &PE_Type::On_within_template_Constant };
198 	static INT16 stateT_within_template[] =   	{ Tid_Comma,
199 												  Tid_Greater,
200                                                   Tid_Constant };
201 
202 	static F_Tok stateF_within_indirection[] =	{ &PE_Type::On_within_indirection_const,
203 												  &PE_Type::On_within_indirection_volatile,
204 												  &PE_Type::On_within_indirection_Asterix,
205 												  &PE_Type::On_within_indirection_AmpersAnd };
206 	static INT16 stateT_within_indirection[] =  { Tid_const,
207 												  Tid_volatile,
208 												  Tid_Asterix,
209 												  Tid_AmpersAnd };
210 
211 	SEMPARSE_CREATE_STATUS(PE_Type, start, Hdl_SyntaxError);
212 	SEMPARSE_CREATE_STATUS(PE_Type, expect_namesegment, On_EndOfType);
213 	SEMPARSE_CREATE_STATUS(PE_Type, after_namesegment, On_EndOfType);
214 	SEMPARSE_CREATE_STATUS(PE_Type, afterclass_expect_semicolon, Hdl_SyntaxError);
215 	SEMPARSE_CREATE_STATUS(PE_Type, within_template, On_within_template_TypeStart);
216 	SEMPARSE_CREATE_STATUS(PE_Type, within_indirection, On_EndOfType);
217 }
218 
219 void
InitData()220 PE_Type::InitData()
221 {
222 	pStati->SetCur(start);
223 
224     ary::cpp::Ce_id
225         scope_id = Env().Context().CurClass() != 0
226                     ?   Env().Context().CurClass()->CeId()
227                     :   Env().Context().CurNamespace().CeId();
228 
229     pType = new ary::cpp::UsedType(scope_id);
230     pCurTemplate_ParameterList = 0;
231     sOwningClassName
232             =   Env().Context().CurClass() != 0
233                     ?   Env().Context().CurClass()->LocalName().c_str()
234 					:   "";
235 	sParsedClass_Name.clear();
236 	pResult_Type = 0;
237 	eResult_KindOf = is_type;
238     bIsCastOperatorType = false;
239 }
240 
241 void
TransferData()242 PE_Type::TransferData()
243 {
244 	pStati->SetCur(size_of_states);
245 
246 	if ( IsType() )
247 		pResult_Type = & Env().AryGate().Types().CheckIn_UsedType(
248 		                                                Env().Context(),
249 		                                                *pType.Release() );
250 	else
251 		pResult_Type = new NullType;
252 }
253 
254 void
Hdl_SyntaxError(const char * i_sText)255 PE_Type::Hdl_SyntaxError( const char * i_sText )
256 {
257 	StdHandlingOfSyntaxError( i_sText );
258 }
259 
260 void
SpReturn_Type_TemplateParameter()261 PE_Type::SpReturn_Type_TemplateParameter()
262 {
263 	if ( pSpuType_TemplateParameter->Child().Result_KindOf() != is_type )
264 		throw X_Parser(X_Parser::x_UnspecifiedSyntaxError, "", String::Null_(), 0);
265 
266 	pCurTemplate_ParameterList->AddParam_Type(
267 			pSpuType_TemplateParameter->Child().Result_Type().TypeId() );
268 }
269 
270 void
SpReturn_Class()271 PE_Type::SpReturn_Class()
272 {
273 	switch ( pSpuClass->Child().Result_KindOf() )
274 	{
275 		case PE_Class::is_declaration:
276 					pStati->SetCur(afterclass_expect_semicolon);
277 					eResult_KindOf = is_explicit_class_declaration;
278 					break;
279 		case PE_Class::is_implicit_declaration:
280 					pStati->SetCur(after_namesegment);
281 					pType->Add_NameSegment(
282 							pSpuClass->Child().Result_LocalName() );
283 					break;
284 		case PE_Class::is_predeclaration:
285 					pStati->SetCur(afterclass_expect_semicolon);
286 					eResult_KindOf = is_class_predeclaration;
287 					break;
288 		case PE_Class::is_qualified_typename:
289 					pStati->SetCur(after_namesegment);
290 					pType->Add_NameSegment(
291 							pSpuClass->Child().Result_FirstNameSegment() );
292 					break;
293 		default:
294 					csv_assert(false);
295 	}
296 }
297 
298 void
SpReturn_Enum()299 PE_Type::SpReturn_Enum()
300 {
301 	switch ( pSpuEnum->Child().Result_KindOf() )
302 	{
303 		case PE_Enum::is_declaration:
304 					pStati->SetCur(afterclass_expect_semicolon);
305 					eResult_KindOf = is_explicit_enum_declaration;
306 					break;
307 		case PE_Enum::is_implicit_declaration:
308 					pStati->SetCur(after_namesegment);
309 					pType->Add_NameSegment(
310 							pSpuEnum->Child().Result_LocalName() );
311 					break;
312 		case PE_Enum::is_qualified_typename:
313 					pStati->SetCur(after_namesegment);
314 					pType->Add_NameSegment(
315 							pSpuEnum->Child().Result_FirstNameSegment() );
316 					break;
317 		default:
318 					csv_assert(false);
319 	}
320 }
321 
322 void
On_EndOfType(const char *)323 PE_Type::On_EndOfType(const char *)
324 {
325 	SetTokenResult(not_done, pop_success);
326 }
327 
328 void
On_start_Identifier(const char * i_sText)329 PE_Type::On_start_Identifier( const char * i_sText )
330 {
331 	SetTokenResult(done,stay);
332 	pStati->SetCur(after_namesegment);
333 
334 	pType->Add_NameSegment(i_sText);
335 }
336 
337 void
On_start_class(const char *)338 PE_Type::On_start_class(const char *)
339 {
340 	pSpuClass->Push(not_done);
341 }
342 
343 void
On_start_enum(const char *)344 PE_Type::On_start_enum(const char *)
345 {
346 	pSpuEnum->Push(done);
347 }
348 
349 void
On_start_const(const char *)350 PE_Type::On_start_const(const char *)
351 {
352 	SetTokenResult(done,stay);
353 	pType->Set_Const();
354 }
355 
356 void
On_start_volatile(const char *)357 PE_Type::On_start_volatile(const char *)
358 {
359 	SetTokenResult(done,stay);
360 	pType->Set_Volatile();
361 }
362 
363 void
On_start_Bracket_Right(const char *)364 PE_Type::On_start_Bracket_Right(const char *)
365 {
366 	SetTokenResult(not_done,pop_success);
367 
368     eResult_KindOf = is_none;
369 }
370 
371 void
On_start_DoubleColon(const char *)372 PE_Type::On_start_DoubleColon(const char *)
373 {
374 	SetTokenResult(done,stay);
375 	pType->Set_Absolute();
376 }
377 
378 void
On_start_BuiltInType(const char * i_sText)379 PE_Type::On_start_BuiltInType(const char * i_sText)
380 {
381 	SetTokenResult(done, stay);
382 	pStati->SetCur(after_namesegment);
383 	pType->Set_BuiltIn(i_sText);
384 }
385 
386 void
On_start_TypeSpecializer(const char * i_sText)387 PE_Type::On_start_TypeSpecializer(const char * i_sText)
388 {
389 	SetTokenResult(done,stay);
390 	if (*i_sText == 'u') {
391 		pType->Set_Unsigned();
392     }
393 	else if (*i_sText == 's') {
394 		pType->Set_Signed();
395     }
396 	else {
397     	csv_assert(false);
398     }
399 }
400 
401 void
On_start_typename(const char *)402 PE_Type::On_start_typename(const char *)
403 {
404 	SetTokenResult(done,stay);
405 }
406 
407 void
On_expect_namesegment_Identifier(const char * i_sText)408 PE_Type::On_expect_namesegment_Identifier(const char * i_sText)
409 {
410 	SetTokenResult(done,stay);
411 	pStati->SetCur(after_namesegment);
412 	pType->Add_NameSegment(i_sText);
413 }
414 
415 void
On_after_namesegment_const(const char *)416 PE_Type::On_after_namesegment_const(const char *)
417 {
418 	SetTokenResult(done,stay);
419 	pType->Set_Const();
420 }
421 
422 void
On_after_namesegment_volatile(const char *)423 PE_Type::On_after_namesegment_volatile(const char *)
424 {
425 	SetTokenResult(done,stay);
426 	pType->Set_Volatile();
427 }
428 
429 void
On_after_namesegment_Bracket_Left(const char * i_sText)430 PE_Type::On_after_namesegment_Bracket_Left(const char * i_sText)
431 {
432     if ( bIsCastOperatorType )
433     {
434     	SetTokenResult(not_done, pop_success);
435     }
436 	else if ( pType->LocalName() == sOwningClassName )
437 	{
438 		SetTokenResult(not_done,pop_success);
439 		eResult_KindOf = is_constructor;
440 
441 	}
442 	else //
443 	{
444         On_EndOfType(i_sText);
445 	}  // endif
446 }
447 
448 void
On_after_namesegment_DoubleColon(const char *)449 PE_Type::On_after_namesegment_DoubleColon(const char *)
450 {
451 	SetTokenResult(done,stay);
452 	pStati->SetCur(expect_namesegment);
453 }
454 
455 void
On_after_namesegment_Less(const char *)456 PE_Type::On_after_namesegment_Less(const char *)
457 {
458 	SetTokenResult(done,stay);
459 	pStati->SetCur(within_template);
460 
461 	pCurTemplate_ParameterList = & pType->Enter_Template();
462 }
463 
464 void
On_after_namesegment_Asterix(const char *)465 PE_Type::On_after_namesegment_Asterix(const char *)
466 {
467 	SetTokenResult(done,stay);
468 	pStati->SetCur(within_indirection);
469 	pType->Add_PtrLevel();
470 }
471 
472 void
On_after_namesegment_AmpersAnd(const char *)473 PE_Type::On_after_namesegment_AmpersAnd(const char *)
474 {
475 	SetTokenResult(done,pop_success);
476 	pType->Set_Reference();
477 }
478 
479 void
On_afterclass_expect_semicolon_Semicolon(const char *)480 PE_Type::On_afterclass_expect_semicolon_Semicolon(const char *)
481 {
482 	csv_assert( NOT IsType() );
483 	SetTokenResult(not_done,pop_success);
484 }
485 
486 void
On_within_template_Comma(const char *)487 PE_Type::On_within_template_Comma(const char *)
488 {
489 	SetTokenResult(done,stay);
490 }
491 
492 void
On_within_template_Greater(const char *)493 PE_Type::On_within_template_Greater(const char *)
494 {
495 	SetTokenResult(done,stay);
496 	pStati->SetCur(after_namesegment);
497 
498     pCurTemplate_ParameterList = 0;
499 }
500 
501 void
On_within_template_Constant(const char * i_sText)502 PE_Type::On_within_template_Constant(const char * i_sText)
503 {
504     // KORR_FUTURE
505     Cerr() << "Templates with constants as parameters are not yet supported by Autodoc" << Endl();
506     Hdl_SyntaxError(i_sText);
507 }
508 
509 void
On_within_template_TypeStart(const char *)510 PE_Type::On_within_template_TypeStart(const char *)
511 {
512     pSpuType_TemplateParameter->Push(not_done);
513 }
514 
515 void
On_within_indirection_const(const char *)516 PE_Type::On_within_indirection_const(const char *)
517 {
518 	SetTokenResult(done,stay);
519 	pType->Set_Const();
520 }
521 
522 void
On_within_indirection_volatile(const char *)523 PE_Type::On_within_indirection_volatile(const char *)
524 {
525 	SetTokenResult(done,stay);
526 	pType->Set_Volatile();
527 }
528 
529 void
On_within_indirection_Asterix(const char *)530 PE_Type::On_within_indirection_Asterix(const char *)
531 {
532 	SetTokenResult(done,stay);
533 	pType->Add_PtrLevel();
534 }
535 
536 void
On_within_indirection_AmpersAnd(const char *)537 PE_Type::On_within_indirection_AmpersAnd(const char *)
538 {
539 	SetTokenResult(done,pop_success);
540 	pType->Set_Reference();
541 }
542 
543 }   // namespace cpp
544 
545 
546 
547 
548 
549