File indexing completed on 2024-05-19 04:39:14

0001 /*
0002     SPDX-FileCopyrightText: 2008 David Nolden <david.nolden.kdevelop@art-master.de>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-only
0005 */
0006 
0007 #include "functiondefinition.h"
0008 #include "duchainregister.h"
0009 #include "definitions.h"
0010 
0011 namespace KDevelop {
0012 REGISTER_DUCHAIN_ITEM(FunctionDefinition);
0013 
0014 FunctionDefinition::FunctionDefinition(FunctionDefinitionData& data) : FunctionDeclaration(data)
0015 {
0016 }
0017 
0018 FunctionDefinition::FunctionDefinition(const RangeInRevision& range, DUContext* context)
0019     : FunctionDeclaration(*new FunctionDefinitionData, range)
0020 {
0021     d_func_dynamic()->setClassId(this);
0022     setDeclarationIsDefinition(true);
0023     if (context)
0024         setContext(context);
0025 }
0026 
0027 FunctionDefinition::FunctionDefinition(const FunctionDefinition& rhs) : FunctionDeclaration(*new FunctionDefinitionData(
0028             *rhs.d_func()))
0029 {
0030 }
0031 
0032 FunctionDefinition::~FunctionDefinition()
0033 {
0034     if (!topContext()->isOnDisk())
0035         DUChain::definitions()->removeDefinition(d_func()->m_declaration, this);
0036 }
0037 
0038 Declaration* FunctionDefinition::declaration(const TopDUContext* topContext) const
0039 {
0040     ENSURE_CAN_READ
0041 
0042     const KDevVarLengthArray<Declaration*> declarations = d_func()->m_declaration.declarations(
0043         topContext ? topContext : this->topContext());
0044 
0045     for (Declaration* decl : declarations) {
0046         if (!dynamic_cast<FunctionDefinition*>(decl))
0047             return decl;
0048     }
0049 
0050     return nullptr;
0051 }
0052 
0053 bool FunctionDefinition::hasDeclaration() const
0054 {
0055     return d_func()->m_declaration.isValid();
0056 }
0057 
0058 void FunctionDefinition::setDeclaration(Declaration* declaration)
0059 {
0060     ENSURE_CAN_WRITE
0061 
0062     if (declaration) {
0063         DUChain::definitions()->addDefinition(declaration->id(), this);
0064         d_func_dynamic()->m_declaration = declaration->id();
0065     } else {
0066         if (d_func()->m_declaration.isValid()) {
0067             DUChain::definitions()->removeDefinition(d_func()->m_declaration, this);
0068             d_func_dynamic()->m_declaration = DeclarationId();
0069         }
0070     }
0071 }
0072 
0073 Declaration* FunctionDefinition::definition(const Declaration* decl)
0074 {
0075     ENSURE_CHAIN_READ_LOCKED
0076     if (!decl) {
0077         return nullptr;
0078     }
0079 
0080     if (decl->isFunctionDeclaration() && decl->isDefinition()) {
0081         return const_cast<Declaration*>(decl);
0082     }
0083 
0084     const KDevVarLengthArray<IndexedDeclaration> allDefinitions = DUChain::definitions()->definitions(decl->id());
0085     for (const IndexedDeclaration decl : allDefinitions) {
0086         if (decl.data()) ///@todo Find better ways of deciding which definition to use
0087             return decl.data();
0088     }
0089 
0090     return nullptr;
0091 }
0092 
0093 Declaration* FunctionDefinition::clonePrivate() const
0094 {
0095     return new FunctionDefinition(*new FunctionDefinitionData(*d_func()));
0096 }
0097 }