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