| /************************************************************** |
| * |
| * 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 <ary/cpp/usedtype.hxx> |
| |
| |
| // NOT FULLY DEFINED SERVICES |
| #include <cosv/tpl/tpltools.hxx> |
| #include <ary/symtreenode.hxx> |
| #include <ary/cpp/c_ce.hxx> |
| #include <ary/cpp/c_class.hxx> |
| #include <ary/cpp/c_namesp.hxx> |
| #include <ary/cpp/c_slntry.hxx> |
| #include <ary/cpp/c_tydef.hxx> |
| #include <ary/cpp/c_traits.hxx> |
| #include <ary/cpp/c_types4cpp.hxx> |
| #include <ary/cpp/c_gate.hxx> |
| #include <ary/cpp/cp_ce.hxx> |
| #include <ary/cpp/cp_type.hxx> |
| #include <ary/doc/d_oldcppdocu.hxx> |
| #include <ary/getncast.hxx> |
| #include "tplparam.hxx" |
| |
| |
| |
| namespace |
| { |
| |
| using namespace ::ary::cpp; |
| typedef std::vector< ary::cpp::E_ConVol > PtrLevelVector; |
| |
| |
| inline bool |
| result2bool( intt i_nResult ) |
| { return i_nResult < 0; } |
| |
| |
| intt compare_PtrLevelVector( |
| const PtrLevelVector & |
| i_r1, |
| const PtrLevelVector & |
| i_r2 ); |
| inline intt |
| compare_ConVol( E_ConVol i_e1, |
| E_ConVol i_e2 ) |
| { return intt(i_e1) - intt(i_e2); } |
| |
| inline intt |
| compare_bool( bool i_b1, |
| bool i_b2 ) |
| { return i_b1 == i_b2 |
| ? 0 |
| : i_b1 |
| ? -1 |
| : +1; } |
| inline intt |
| compare_Specialisation( E_TypeSpecialisation i_e1, |
| E_TypeSpecialisation i_e2 ) |
| { return intt(i_e1) - intt(i_e2); } |
| |
| inline bool |
| is_const( E_ConVol i_eCV ) |
| { return ( intt(i_eCV) & intt(CONVOL_const) ) != 0; } |
| |
| inline bool |
| is_volatile( E_ConVol i_eCV ) |
| { return ( intt(i_eCV) & intt(CONVOL_volatile) ) != 0; } |
| |
| |
| intt |
| compare_PtrLevelVector( const PtrLevelVector & i_r1, |
| const PtrLevelVector & i_r2 ) |
| { |
| intt nResult = i_r1.size() - i_r2.size(); |
| if ( nResult != 0 ) |
| return nResult; |
| |
| PtrLevelVector::const_iterator it1 = i_r1.begin(); |
| PtrLevelVector::const_iterator it1End = i_r1.end(); |
| PtrLevelVector::const_iterator it2 = i_r2.begin(); |
| |
| for ( ; it1 != it1End; ++it1, ++it2 ) |
| { |
| nResult = compare_ConVol(*it1, *it2); |
| if ( nResult != 0 ) |
| return nResult; |
| } |
| |
| return 0; |
| } |
| |
| |
| } // anonymous namespace |
| |
| |
| |
| |
| namespace ary |
| { |
| namespace cpp |
| { |
| |
| typedef symtree::Node<CeNode_Traits> CeNode; |
| typedef ut::NameChain::const_iterator nc_iter; |
| |
| Ce_id CheckForRelatedCe_inNode( |
| const CeNode & i_node, |
| const StringVector& i_qualification, |
| const String & i_name ); |
| |
| |
| UsedType::UsedType(Ce_id i_scope ) |
| : aPath(), |
| aPtrLevels(), |
| eConVol_Type(CONVOL_none), |
| bIsReference(false), |
| bIsAbsolute(false), |
| bRefers2BuiltInType(false), |
| eTypeSpecialisation(TYSP_none), |
| nRelatedCe(0), |
| nScope(i_scope) |
| { |
| } |
| |
| UsedType::~UsedType() |
| { |
| } |
| |
| |
| bool |
| UsedType::operator<( const UsedType & i_rType ) const |
| { |
| intt nResult = compare_bool( bIsAbsolute, i_rType.bIsAbsolute ); |
| if ( nResult != 0 ) |
| return result2bool(nResult); |
| |
| nResult = static_cast<intt>(nScope.Value()) |
| - |
| static_cast<intt>(i_rType.nScope.Value()); |
| if ( nResult != 0 ) |
| return result2bool(nResult); |
| |
| nResult = aPath.Compare( i_rType.aPath ); |
| if ( nResult != 0 ) |
| return result2bool(nResult); |
| |
| nResult = compare_ConVol( eConVol_Type, i_rType.eConVol_Type ); |
| if ( nResult != 0 ) |
| return result2bool(nResult); |
| |
| nResult = compare_PtrLevelVector( aPtrLevels, i_rType.aPtrLevels ); |
| if ( nResult != 0 ) |
| return result2bool(nResult); |
| |
| nResult = compare_bool( bIsReference, i_rType.bIsReference ); |
| if ( nResult != 0 ) |
| return result2bool(nResult); |
| |
| nResult = compare_Specialisation( eTypeSpecialisation, i_rType.eTypeSpecialisation ); |
| if ( nResult != 0 ) |
| return result2bool(nResult); |
| |
| return false; |
| } |
| |
| void |
| UsedType::Set_Absolute() |
| { |
| bIsAbsolute = true; |
| } |
| |
| void |
| UsedType::Add_NameSegment( const char * i_sSeg ) |
| { |
| aPath.Add_Segment(i_sSeg); |
| } |
| |
| ut::List_TplParameter & |
| UsedType::Enter_Template() |
| { |
| return aPath.Templatize_LastSegment(); |
| } |
| |
| void |
| UsedType::Set_Unsigned() |
| { |
| eTypeSpecialisation = TYSP_unsigned; |
| } |
| |
| void |
| UsedType::Set_Signed() |
| { |
| eTypeSpecialisation = TYSP_signed; |
| } |
| |
| void |
| UsedType::Set_BuiltIn( const char * i_sType ) |
| { |
| aPath.Add_Segment(i_sType); |
| bRefers2BuiltInType = true; |
| } |
| |
| void |
| UsedType::Set_Const() |
| { |
| if (PtrLevel() == 0) |
| eConVol_Type = E_ConVol(eConVol_Type | CONVOL_const); |
| else |
| aPtrLevels.back() = E_ConVol(aPtrLevels.back() | CONVOL_const); |
| } |
| |
| void |
| UsedType::Set_Volatile() |
| { |
| if (PtrLevel() == 0) |
| eConVol_Type = E_ConVol(eConVol_Type | CONVOL_volatile); |
| else |
| aPtrLevels.back() = E_ConVol(aPtrLevels.back() | CONVOL_volatile); |
| } |
| |
| void |
| UsedType::Add_PtrLevel() |
| { |
| aPtrLevels.push_back(CONVOL_none); |
| } |
| |
| void |
| UsedType::Set_Reference() |
| { |
| bIsReference = true; |
| } |
| |
| inline bool |
| IsInternal(const ary::cpp::CodeEntity & i_ce) |
| { |
| const ary::doc::OldCppDocu * |
| docu = dynamic_cast< const ary::doc::OldCppDocu* >(i_ce.Docu().Data()); |
| if (docu != 0) |
| return docu->IsInternal(); |
| return false; |
| } |
| |
| |
| void |
| UsedType::Connect2Ce( const CePilot & i_ces) |
| { |
| StringVector |
| qualification; |
| String |
| name; |
| Get_NameParts(qualification, name); |
| |
| for ( const CeNode * scope_node = CeNode_Traits::NodeOf_( |
| i_ces.Find_Ce(nScope)); |
| scope_node != 0; |
| scope_node = scope_node->Parent() ) |
| { |
| nRelatedCe = CheckForRelatedCe_inNode(*scope_node, qualification, name); |
| if ( nRelatedCe.IsValid() ) |
| { |
| if ( IsInternal(i_ces.Find_Ce(nRelatedCe)) ) |
| nRelatedCe = Ce_id(0); |
| return; |
| } |
| } // end for |
| } |
| |
| void |
| UsedType::Connect2CeOnlyKnownViaBaseClass(const Gate & i_gate) |
| { |
| csv_assert(nScope.IsValid()); |
| CesResultList |
| instances = i_gate.Ces().Search_TypeName( LocalName() ); |
| |
| // If there are no matches, or only one match that was already |
| // accepted, all work is done. |
| if ( (nRelatedCe.IsValid() AND instances.size() == 1) |
| OR instances.size() == 0 ) |
| return; |
| |
| StringVector |
| qualification; |
| String |
| name; |
| Get_NameParts(qualification, name); |
| |
| const CodeEntity & |
| scopece = i_gate.Ces().Find_Ce(nScope); |
| |
| // Else search for declaration in own class and then in base classes. |
| // These would be of higher priority than those in parent namespaces. |
| Ce_id |
| foundce = RecursiveSearchCe_InBaseClassesOf( |
| scopece, qualification, name, i_gate); |
| if (foundce.IsValid()) |
| nRelatedCe = foundce; |
| |
| if ( nRelatedCe.IsValid() AND IsInternal(i_gate.Ces().Find_Ce(nRelatedCe)) ) |
| { |
| nRelatedCe = Ce_id(0); |
| } |
| } |
| |
| bool |
| UsedType::IsBuiltInType() const |
| { |
| return bRefers2BuiltInType |
| AND aPtrLevels.size() == 0 |
| AND NOT bIsReference |
| AND eConVol_Type == ary::cpp::CONVOL_none; |
| } |
| |
| const String & |
| UsedType::LocalName() const |
| { |
| return aPath.LastSegment(); |
| } |
| |
| E_TypeSpecialisation |
| UsedType::TypeSpecialisation() const |
| { |
| return eTypeSpecialisation; |
| } |
| |
| void |
| UsedType::do_Accept(csv::ProcessorIfc & io_processor) const |
| { |
| csv::CheckedCall(io_processor,*this); |
| } |
| |
| ary::ClassId |
| UsedType::get_AryClass() const |
| { |
| return class_id; |
| } |
| |
| Rid |
| UsedType::inq_RelatedCe() const |
| { |
| return nRelatedCe.Value(); |
| } |
| |
| bool |
| UsedType::inq_IsConst() const |
| { |
| if ( is_const(eConVol_Type) ) |
| return true; |
| for ( PtrLevelVector::const_iterator it = aPtrLevels.begin(); |
| it != aPtrLevels.end(); |
| ++it ) |
| { |
| if ( is_const(*it) ) |
| return true; |
| } |
| |
| return false; |
| } |
| |
| void |
| UsedType::inq_Get_Text( StreamStr & o_rPreName, |
| StreamStr & o_rName, |
| StreamStr & o_rPostName, |
| const Gate & i_rGate ) const |
| { |
| if ( is_const(eConVol_Type) ) |
| o_rPreName << "const "; |
| if ( is_volatile(eConVol_Type) ) |
| o_rPreName << "volatile "; |
| if ( bIsAbsolute ) |
| o_rPreName << "::"; |
| |
| aPath.Get_Text( o_rPreName, o_rName, o_rPostName, i_rGate ); |
| |
| for ( PtrLevelVector::const_iterator it = aPtrLevels.begin(); |
| it != aPtrLevels.end(); |
| ++it ) |
| { |
| o_rPostName << " *"; |
| if ( is_const(*it) ) |
| o_rPostName << " const"; |
| if ( is_volatile(*it) ) |
| o_rPostName << " volatile"; |
| } |
| if ( bIsReference ) |
| o_rPostName << " &"; |
| } |
| |
| Ce_id |
| UsedType::RecursiveSearchCe_InBaseClassesOf( const CodeEntity & i_mayBeClass, |
| const StringVector & i_myQualification, |
| const String & i_myName, |
| const Gate & i_gate ) const |
| { |
| // Find in this class? |
| const CeNode * |
| basenode = CeNode_Traits::NodeOf_(i_mayBeClass); |
| if (basenode == 0) |
| return Ce_id(0); |
| Ce_id |
| found = CheckForRelatedCe_inNode(*basenode, i_myQualification, i_myName); |
| if (found.IsValid()) |
| return found; |
| |
| |
| const Class * |
| cl = ary_cast<Class>(&i_mayBeClass); |
| if (cl == 0) |
| return Ce_id(0); |
| |
| for ( List_Bases::const_iterator it = cl->BaseClasses().begin(); |
| it != cl->BaseClasses().end(); |
| ++it ) |
| { |
| csv_assert((*it).nId.IsValid()); |
| Ce_id |
| base = i_gate.Types().Find_Type((*it).nId).RelatedCe(); |
| while (base.IsValid() AND is_type<Typedef>(i_gate.Ces().Find_Ce(base)) ) |
| { |
| base = i_gate.Types().Find_Type( |
| ary_cast<Typedef>(i_gate.Ces().Find_Ce(base)) |
| .DescribingType() ) |
| .RelatedCe(); |
| } |
| |
| if (base.IsValid()) |
| { |
| const CodeEntity & |
| basece = i_gate.Ces().Find_Ce(base); |
| found = RecursiveSearchCe_InBaseClassesOf( |
| basece, i_myQualification, i_myName, i_gate); |
| if (found.IsValid()) |
| return found; |
| } |
| } // end for |
| |
| return Ce_id(0); |
| } |
| |
| |
| void |
| UsedType::Get_NameParts( StringVector & o_qualification, |
| String & o_name ) |
| { |
| nc_iter nit = aPath.begin(); |
| nc_iter nit_end = aPath.end(); |
| csv_assert(nit != nit_end); // Each UsedType has to have a local name. |
| |
| --nit_end; |
| o_name = (*nit_end).Name(); |
| for ( ; |
| nit != nit_end; |
| ++nit ) |
| { |
| o_qualification.push_back( (*nit).Name() ); |
| } |
| } |
| |
| Ce_id |
| CheckForRelatedCe_inNode( const CeNode & i_node, |
| const StringVector & i_qualification, |
| const String & i_name ) |
| { |
| if (i_qualification.size() > 0) |
| { |
| Ce_id |
| ret(0); |
| i_node.SearchBelow( ret, |
| i_qualification.begin(), |
| i_qualification.end(), |
| i_name ); |
| return ret; |
| } |
| else |
| { |
| return i_node.Search(i_name); |
| } |
| } |
| |
| |
| namespace ut |
| { |
| |
| List_TplParameter::List_TplParameter() |
| : aTplParameters() |
| { |
| } |
| |
| List_TplParameter::~List_TplParameter() |
| { |
| csv::erase_container_of_heap_ptrs(aTplParameters); |
| } |
| |
| void |
| List_TplParameter::AddParam_Type( Type_id i_nType ) |
| { |
| aTplParameters.push_back( new TplParameter_Type(i_nType) ); |
| } |
| |
| void |
| List_TplParameter::Get_Text( StreamStr & o_rOut, |
| const ary::cpp::Gate & i_rGate ) const |
| { |
| Vector_TplArgument::const_iterator it = aTplParameters.begin(); |
| Vector_TplArgument::const_iterator itEnd = aTplParameters.end(); |
| |
| if ( it == itEnd ) |
| { |
| o_rOut << "<>"; |
| return; |
| } |
| |
| o_rOut << "< "; |
| |
| (*it)->Get_Text( o_rOut, i_rGate ); |
| |
| for ( ++it; it != itEnd; ++it ) |
| { |
| o_rOut << ", "; |
| (*it)->Get_Text( o_rOut, i_rGate ); |
| } |
| |
| o_rOut << " >"; |
| } |
| |
| intt |
| List_TplParameter::Compare( const List_TplParameter & i_rOther ) const |
| { |
| intt nResult = intt(aTplParameters.size()) - intt(i_rOther.aTplParameters.size()); |
| |
| if (nResult != 0) |
| return nResult; |
| |
| Vector_TplArgument::const_iterator it1 = aTplParameters.begin(); |
| Vector_TplArgument::const_iterator it1End = aTplParameters.end(); |
| Vector_TplArgument::const_iterator it2 = i_rOther.aTplParameters.begin(); |
| |
| for ( ; it1 != it1End; ++it1, ++it2 ) |
| { |
| nResult = (*it1)->Compare( *(*it2) ); |
| if (nResult != 0) |
| return nResult; |
| } |
| |
| return 0; |
| } |
| |
| |
| } // namespace ut |
| } // namespace cpp |
| } // namespace ary |