| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| #include <precomp.h> |
| #include "pe_vafu.hxx" |
| |
| |
| // NOT FULLY DEFINED SERVICES |
| #include <cosv/tpl/tpltools.hxx> |
| #include <ary/cpp/c_gate.hxx> |
| #include <ary/cpp/c_class.hxx> |
| #include <ary/cpp/c_vari.hxx> |
| #include <ary/cpp/c_vfflag.hxx> |
| #include <ary/cpp/cp_ce.hxx> |
| #include <ary/cpp/inpcontx.hxx> |
| #include "pe_type.hxx" |
| #include "pe_vari.hxx" |
| #include "pe_funct.hxx" |
| #include "pe_ignor.hxx" |
| #include <x_parse.hxx> |
| |
| |
| |
| |
| namespace cpp { |
| |
| |
| |
| //*********************** PE_VarFunc ***********************// |
| |
| |
| PE_VarFunc::PE_VarFunc( Cpp_PE * i_pParent ) |
| : Cpp_PE(i_pParent), |
| pStati( new PeStatusArray<PE_VarFunc> ), |
| // pSpType, |
| // pSpuType, |
| // pSpVariable, |
| // pSpuVariable, |
| // pSpFunction, |
| // pSpuFunctionStd, |
| // pSpuFunctionCtor, |
| // pSpuFunctionDtor, |
| // pSpuFunctionCastOperator, |
| // pSpuFunctionNormalOperator |
| // pSpIgnore, |
| // pSpuIgnore, |
| nCounter_TemplateBrackets(0), |
| bInDestructor(false), |
| // aResultIds, |
| nResultFrontType(0), |
| eResultType(result_unknown), |
| bVirtual(false), |
| bStatic(false), |
| bExtern(false), |
| bExternC(false), |
| bMutable(false), |
| bInline(false), |
| bRegister(false), |
| bExplicit(false) |
| { |
| Setup_StatusFunctions(); |
| |
| pSpType = new SP_Type(*this); |
| pSpuType = new SPU_Type(*pSpType, 0, &PE_VarFunc::SpReturn_Type); |
| pSpVariable = new SP_Variable(*this); |
| pSpuVariable = new SPU_Variable(*pSpVariable, 0, &PE_VarFunc::SpReturn_Variable); |
| pSpFunction = new SP_Function(*this); |
| pSpuFunctionStd = new SPU_Function(*pSpFunction, &PE_VarFunc::SpInit_FunctionStd, &PE_VarFunc::SpReturn_FunctionStd); |
| pSpuFunctionCtor = new SPU_Function(*pSpFunction, &PE_VarFunc::SpInit_FunctionCtor, &PE_VarFunc::SpReturn_FunctionStd); |
| pSpuFunctionDtor = new SPU_Function(*pSpFunction, &PE_VarFunc::SpInit_FunctionDtor, &PE_VarFunc::SpReturn_FunctionStd); |
| pSpuFunctionCastOperator |
| = new SPU_Function(*pSpFunction, &PE_VarFunc::SpInit_FunctionCastOperator, &PE_VarFunc::SpReturn_FunctionStd); |
| pSpuFunctionNormalOperator |
| = new SPU_Function(*pSpFunction, &PE_VarFunc::SpInit_FunctionNormalOperator, &PE_VarFunc::SpReturn_FunctionStd); |
| pSpIgnore = new SP_Ignore(*this); |
| pSpuIgnore = new SPU_Ignore(*pSpIgnore, 0, &PE_VarFunc::SpReturn_Ignore); |
| } |
| |
| PE_VarFunc::~PE_VarFunc() |
| { |
| } |
| |
| void |
| PE_VarFunc::Call_Handler( const cpp::Token & i_rTok ) |
| { |
| pStati->Cur().Call_Handler(i_rTok.TypeId(), i_rTok.Text()); |
| } |
| |
| void |
| PE_VarFunc::Setup_StatusFunctions() |
| { |
| typedef CallFunction<PE_VarFunc>::F_Tok F_Tok; |
| |
| static F_Tok stateF_start[] = { &PE_VarFunc::On_start_Identifier, |
| &PE_VarFunc::On_start_operator, |
| &PE_VarFunc::On_start_TypeKey, |
| &PE_VarFunc::On_start_TypeKey, |
| &PE_VarFunc::On_start_TypeKey, |
| &PE_VarFunc::On_start_TypeKey, |
| &PE_VarFunc::On_start_virtual, |
| &PE_VarFunc::On_start_Tilde, |
| &PE_VarFunc::On_start_const, |
| &PE_VarFunc::On_start_volatile, |
| &PE_VarFunc::On_start_extern, |
| &PE_VarFunc::On_start_static, |
| &PE_VarFunc::On_start_mutable, |
| &PE_VarFunc::On_start_register, |
| &PE_VarFunc::On_start_inline, |
| &PE_VarFunc::On_start_explicit, |
| &PE_VarFunc::On_start_Bracket_Right, |
| &PE_VarFunc::On_start_Identifier, |
| &PE_VarFunc::On_start_typename, |
| &PE_VarFunc::On_start_Identifier, |
| &PE_VarFunc::On_start_Identifier }; |
| static INT16 stateT_start[] = { Tid_Identifier, |
| Tid_operator, |
| Tid_class, |
| Tid_struct, |
| Tid_union, |
| Tid_enum, |
| Tid_virtual, |
| Tid_Tilde, |
| Tid_const, |
| Tid_volatile, |
| Tid_extern, |
| Tid_static, |
| Tid_mutable, |
| Tid_register, |
| Tid_inline, |
| Tid_explicit, |
| Tid_Bracket_Right, |
| Tid_DoubleColon, |
| Tid_typename, |
| Tid_BuiltInType, |
| Tid_TypeSpecializer }; |
| |
| static F_Tok stateF_expectCtor[] = { &PE_VarFunc::On_expectCtor_Bracket_Left }; |
| static INT16 stateT_expectCtor[] = { Tid_Bracket_Left }; |
| |
| static F_Tok stateF_afterClassDecl[] = { &PE_VarFunc::On_afterClassDecl_Semicolon }; |
| static INT16 stateT_afterClassDecl[] = { Tid_Semicolon }; |
| |
| static F_Tok stateF_expectName[] = { &PE_VarFunc::On_expectName_Identifier, |
| &PE_VarFunc::On_expectName_operator, |
| &PE_VarFunc::On_expectName_Bracket_Left }; |
| static INT16 stateT_expectName[] = { Tid_Identifier, |
| Tid_operator, |
| Tid_Bracket_Left }; |
| |
| static F_Tok stateF_afterName[] = { &PE_VarFunc::On_afterName_ArrayBracket_Left, |
| &PE_VarFunc::On_afterName_Bracket_Left, |
| &PE_VarFunc::On_afterName_DoubleColon, |
| &PE_VarFunc::On_afterName_Semicolon, |
| &PE_VarFunc::On_afterName_Comma, |
| &PE_VarFunc::On_afterName_Assign, |
| &PE_VarFunc::On_afterName_Less }; |
| static INT16 stateT_afterName[] = { Tid_ArrayBracket_Left, |
| Tid_Bracket_Left, |
| Tid_DoubleColon, |
| Tid_Semicolon, |
| Tid_Comma, |
| Tid_Assign, |
| Tid_Less }; |
| |
| static F_Tok stateF_afterName_inErraneousTemplate[] = |
| { &PE_VarFunc::On_afterName_inErraneousTemplate_Less, |
| &PE_VarFunc::On_afterName_inErraneousTemplate_Greater }; |
| static INT16 stateT_afterName_inErraneousTemplate[] = |
| { Tid_Less, |
| Tid_Greater }; |
| |
| static F_Tok stateF_finished[] = { &PE_VarFunc::On_finished_Semicolon, |
| &PE_VarFunc::On_finished_Comma }; |
| static INT16 stateT_finished[] = { Tid_Semicolon, |
| Tid_Comma }; |
| |
| static F_Tok stateF_finishedIncludingFunctionImplementation[] = |
| { &PE_VarFunc::On_finishedIncludingFunctionImplementation_Default |
| }; |
| static INT16 stateT_finishedIncludingFunctionImplementation[] = |
| { Tid_BuiltInType // Just to have one entry, but it is default handled, too. |
| }; |
| |
| SEMPARSE_CREATE_STATUS(PE_VarFunc, start, Hdl_UnknownToken); |
| SEMPARSE_CREATE_STATUS(PE_VarFunc, expectCtor, Hdl_UnknownToken); |
| SEMPARSE_CREATE_STATUS(PE_VarFunc, afterClassDecl, Hdl_UnknownToken); |
| SEMPARSE_CREATE_STATUS(PE_VarFunc, expectName, Hdl_UnknownToken); |
| SEMPARSE_CREATE_STATUS(PE_VarFunc, afterName, Hdl_UnknownToken); |
| SEMPARSE_CREATE_STATUS(PE_VarFunc, afterName_inErraneousTemplate, On_afterName_inErraneousTemplate_Default); |
| SEMPARSE_CREATE_STATUS(PE_VarFunc, finished, On_finished_Default); |
| SEMPARSE_CREATE_STATUS(PE_VarFunc, finishedIncludingFunctionImplementation, On_finishedIncludingFunctionImplementation_Default); |
| } |
| |
| void |
| PE_VarFunc::InitData() |
| { |
| pStati->SetCur(start); |
| csv::erase_container(aResultIds); |
| |
| nCounter_TemplateBrackets = 0; |
| bInDestructor = false; |
| |
| nResultFrontType = 0; |
| eResultType = result_unknown; |
| sName.clear(); |
| bVirtual = ary::cpp::VIRTUAL_none; |
| bStatic = false; |
| bExtern = false; |
| bExternC = false; |
| bMutable = false; |
| bInline = false; |
| bRegister = false; |
| bExplicit = false; |
| } |
| |
| void |
| PE_VarFunc::TransferData() |
| { |
| pStati->SetCur(size_of_states); |
| } |
| |
| void |
| PE_VarFunc::Hdl_UnknownToken( const char *) |
| { |
| pSpuIgnore->Push(not_done); |
| } |
| |
| void |
| PE_VarFunc::SpInit_FunctionStd() |
| { |
| if ( nResultFrontType.IsValid() AND sName.length() > 0 ) |
| { |
| pSpuFunctionStd->Child().Init_Std( |
| sName, |
| nResultFrontType, |
| bVirtual, |
| CreateFunctionFlags() ); |
| } |
| else |
| { |
| throw X_Parser( X_Parser::x_UnexpectedToken, |
| "", |
| Env().CurFileName(), |
| Env().LineCount() ); |
| } |
| } |
| |
| void |
| PE_VarFunc::SpInit_FunctionCtor() |
| { |
| ary::cpp::Class * pOwnerClass = Env().Context().CurClass(); |
| csv_assert( pOwnerClass != 0 ); |
| pSpuFunctionStd->Child().Init_Ctor( pOwnerClass->LocalName(), |
| CreateFunctionFlags() ); |
| } |
| |
| void |
| PE_VarFunc::SpInit_FunctionDtor() |
| { |
| pSpuFunctionStd->Child().Init_Dtor( sName, |
| bVirtual, |
| CreateFunctionFlags() ); |
| } |
| |
| void |
| PE_VarFunc::SpInit_FunctionCastOperator() |
| { |
| pSpuFunctionStd->Child().Init_CastOperator( bVirtual, |
| CreateFunctionFlags() ); |
| } |
| |
| void |
| PE_VarFunc::SpInit_FunctionNormalOperator() |
| { |
| pSpuFunctionStd->Child().Init_NormalOperator( nResultFrontType, |
| bVirtual, |
| CreateFunctionFlags() ); |
| } |
| |
| void |
| PE_VarFunc::SpReturn_Type() |
| { |
| switch ( pSpuType->Child().Result_KindOf() ) |
| { |
| case PE_Type::is_type: |
| pStati->SetCur(expectName); |
| nResultFrontType |
| = pSpuType->Child().Result_Type().Id(); |
| break; |
| case PE_Type::is_constructor: |
| pStati->SetCur(expectCtor); |
| eResultType = result_function; |
| break; |
| case PE_Type::is_explicit_class_declaration: |
| case PE_Type::is_explicit_enum_declaration: |
| pStati->SetCur(afterClassDecl); |
| eResultType = result_ignore; |
| break; |
| case PE_Type::is_class_predeclaration: |
| pStati->SetCur(afterClassDecl); |
| eResultType = result_ignore; |
| break; |
| default: |
| ; |
| } |
| } |
| |
| void |
| PE_VarFunc::SpReturn_Variable() |
| { |
| typedef ary::cpp::VariableFlags VarFlags; |
| |
| if ( NOT bExtern ) |
| { |
| VarFlags aFlags( UINT16( |
| ( bStatic AND Env().Context().CurClass() == 0 ? VarFlags::f_static_local : 0 ) |
| | ( bStatic AND Env().Context().CurClass() != 0 ? VarFlags::f_static_member : 0 ) |
| | ( bMutable ? VarFlags::f_mutable : 0 ) ) |
| ); |
| |
| // ary::S_InitData aData( 0, Env().CurCeSpace().Id(), i_sName, 0 ); |
| ary::cpp::Variable & rCurParsedVariable |
| = Env().AryGate().Ces().Store_Variable( Env().Context(), |
| sName, |
| nResultFrontType, |
| aFlags, |
| pSpuVariable->Child().Result_SizeExpression(), |
| pSpuVariable->Child().Result_InitExpression() ); |
| Env().Event_Store_Variable(rCurParsedVariable); |
| aResultIds.push_back( rCurParsedVariable.CeId() ); |
| eResultType = result_variable; |
| } |
| else if (bExtern) |
| { |
| eResultType = result_ignore; |
| } |
| |
| pStati->SetCur(finished); |
| } |
| |
| void |
| PE_VarFunc::SpReturn_FunctionStd() |
| { |
| if ( (NOT bExtern) OR bExternC ) |
| { |
| aResultIds.push_back(pSpuFunctionStd->Child().Result_Id()); |
| eResultType = result_function; |
| } |
| else |
| { |
| eResultType = result_ignore; |
| } |
| |
| if ( NOT pSpuFunctionStd->Child().Result_WithImplementation() ) |
| pStati->SetCur(finished); |
| else |
| pStati->SetCur(finishedIncludingFunctionImplementation); |
| } |
| |
| void |
| PE_VarFunc::SpReturn_Ignore() |
| { |
| pStati->SetCur(finished); |
| } |
| |
| void |
| PE_VarFunc::On_start_Identifier(const char *) |
| { |
| pSpuType->Push(not_done); |
| } |
| |
| void |
| PE_VarFunc::On_start_operator(const char *) |
| { |
| pSpuFunctionCastOperator->Push(done); |
| } |
| |
| void |
| PE_VarFunc::On_start_TypeKey(const char *) |
| { |
| pSpuType->Push(not_done); |
| } |
| |
| void |
| PE_VarFunc::On_start_virtual(const char *) |
| { |
| SetTokenResult(done, stay); |
| bVirtual = true; |
| } |
| |
| void |
| PE_VarFunc::On_start_Tilde(const char *) |
| { |
| SetTokenResult(done, stay); |
| pStati->SetCur(expectName); |
| |
| bInDestructor = true; |
| } |
| |
| void |
| PE_VarFunc::On_start_const(const char *) |
| { |
| pSpuType->Push(not_done); |
| } |
| |
| void |
| PE_VarFunc::On_start_volatile(const char *) |
| { |
| pSpuType->Push(not_done); |
| } |
| |
| void |
| PE_VarFunc::On_start_extern(const char *) |
| { |
| SetTokenResult(done, stay); |
| bExtern = true; |
| } |
| |
| void |
| PE_VarFunc::On_start_static(const char *) |
| { |
| SetTokenResult(done, stay); |
| bStatic = true; |
| } |
| |
| void |
| PE_VarFunc::On_start_mutable(const char *) |
| { |
| SetTokenResult(done, stay); |
| bMutable = true; |
| } |
| |
| void |
| PE_VarFunc::On_start_register(const char *) |
| { |
| SetTokenResult(done, stay); |
| bRegister = true; |
| } |
| |
| void |
| PE_VarFunc::On_start_inline(const char *) |
| { |
| SetTokenResult(done, stay); |
| |
| bInline = true; |
| } |
| |
| void |
| PE_VarFunc::On_start_explicit(const char *) |
| { |
| SetTokenResult(done, stay); |
| bExplicit = true; |
| } |
| |
| void |
| PE_VarFunc::On_start_Bracket_Right(const char *) |
| { |
| SetTokenResult(not_done, pop_success); |
| } |
| |
| void |
| PE_VarFunc::On_start_typename(const char *) |
| { |
| pSpuType->Push(not_done); |
| } |
| |
| void |
| PE_VarFunc::On_expectCtor_Bracket_Left(const char *) |
| { |
| pSpuFunctionCtor->Push(not_done); |
| } |
| |
| void |
| PE_VarFunc::On_afterClassDecl_Semicolon(const char *) |
| { |
| SetTokenResult(done, pop_success); |
| } |
| |
| void |
| PE_VarFunc::On_expectName_Identifier(const char * i_sText) |
| { |
| SetTokenResult(done, stay); |
| pStati->SetCur(afterName); |
| sName = i_sText; |
| } |
| |
| void |
| PE_VarFunc::On_expectName_operator(const char *) |
| { |
| pSpuFunctionNormalOperator->Push(done); |
| } |
| |
| void |
| PE_VarFunc::On_expectName_Bracket_Left(const char *) |
| { |
| // Function pointer declaration |
| pSpuIgnore->Push(not_done); |
| // TODO |
| } |
| |
| |
| void |
| PE_VarFunc::On_afterName_ArrayBracket_Left(const char *) |
| { |
| pSpuVariable->Push(not_done); |
| } |
| |
| void |
| PE_VarFunc::On_afterName_Bracket_Left(const char *) |
| { |
| if ( NOT bInDestructor) |
| pSpuFunctionStd->Push(not_done); |
| else |
| pSpuFunctionDtor->Push(not_done); |
| } |
| |
| void |
| PE_VarFunc::On_afterName_DoubleColon(const char *) |
| { |
| pSpuIgnore->Push(done); // This seems to be only an implementation. |
| |
| // This may have been a template. |
| // In that case, the declaration needs to be closed. |
| Env().Close_OpenTemplate(); |
| } |
| |
| void |
| PE_VarFunc::On_afterName_Semicolon(const char *) |
| { |
| pSpuVariable->Push(not_done); |
| } |
| |
| void |
| PE_VarFunc::On_afterName_Comma(const char *) |
| { |
| pSpuVariable->Push(not_done); |
| } |
| |
| void |
| PE_VarFunc::On_afterName_Assign(const char * ) |
| { |
| pSpuVariable->Push(not_done); |
| } |
| |
| void |
| PE_VarFunc::On_afterName_Less(const char * ) |
| { |
| SetTokenResult(done, stay); |
| pStati->SetCur(afterName_inErraneousTemplate); |
| |
| nCounter_TemplateBrackets = 1; |
| } |
| |
| void |
| PE_VarFunc::On_afterName_inErraneousTemplate_Less(const char * ) |
| { |
| SetTokenResult(done, stay); |
| |
| nCounter_TemplateBrackets++; |
| } |
| |
| void |
| PE_VarFunc::On_afterName_inErraneousTemplate_Greater(const char * ) |
| { |
| SetTokenResult(done, stay); |
| |
| nCounter_TemplateBrackets--; |
| if ( nCounter_TemplateBrackets == 0 ) |
| pStati->SetCur(afterName); |
| } |
| |
| void |
| PE_VarFunc::On_afterName_inErraneousTemplate_Default(const char * ) |
| { |
| SetTokenResult(done, stay); |
| } |
| |
| void |
| PE_VarFunc::On_finished_Semicolon(const char * ) // Should be Semicolon !!! |
| { |
| SetTokenResult(done, pop_success); |
| } |
| |
| void |
| PE_VarFunc::On_finished_Comma(const char * ) |
| { |
| SetTokenResult(done, stay); |
| pStati->SetCur(expectName); |
| } |
| |
| void |
| PE_VarFunc::On_finished_Default(const char * ) |
| { |
| SetTokenResult(not_done, pop_success); |
| } |
| |
| void |
| PE_VarFunc::On_finishedIncludingFunctionImplementation_Default(const char * ) |
| { |
| SetTokenResult(not_done, pop_success); |
| } |
| |
| ary::cpp::FunctionFlags |
| PE_VarFunc::CreateFunctionFlags() |
| { |
| typedef ary::cpp::FunctionFlags FuncFlags; |
| |
| return FuncFlags( UINT16( |
| ( bStatic AND Env().Context().CurClass() == 0 ? FuncFlags::f_static_local : 0 ) |
| | ( bStatic AND Env().Context().CurClass() != 0 ? FuncFlags::f_static_member : 0 ) |
| | ( bExtern ? FuncFlags::f_extern : 0 ) |
| | ( Env().IsExternC() ? FuncFlags::f_externC : 0 ) |
| | ( bMutable ? FuncFlags::f_mutable : 0 ) |
| | ( bInline ? FuncFlags::f_inline : 0 ) |
| | ( bRegister ? FuncFlags::f_register : 0 ) |
| | ( bExplicit ? FuncFlags::f_explicit : 0 ) ) |
| ); |
| |
| } |
| |
| |
| } // namespace cpp |
| |
| |
| |