1 /* 2 SPDX-FileCopyrightText: 2008 David Nolden <david.nolden.kdevelop@art-master.de> 3 4 SPDX-License-Identifier: LGPL-2.0-only 5 */ 6 7 #include "functiondefinition.h" 8 #include "duchainregister.h" 9 #include "definitions.h" 10 11 namespace KDevelop { 12 REGISTER_DUCHAIN_ITEM(FunctionDefinition); 13 FunctionDefinition(FunctionDefinitionData & data)14FunctionDefinition::FunctionDefinition(FunctionDefinitionData& data) : FunctionDeclaration(data) 15 { 16 } 17 FunctionDefinition(const RangeInRevision & range,DUContext * context)18FunctionDefinition::FunctionDefinition(const RangeInRevision& range, DUContext* context) 19 : FunctionDeclaration(*new FunctionDefinitionData, range) 20 { 21 d_func_dynamic()->setClassId(this); 22 setDeclarationIsDefinition(true); 23 if (context) 24 setContext(context); 25 } 26 FunctionDefinition(const FunctionDefinition & rhs)27FunctionDefinition::FunctionDefinition(const FunctionDefinition& rhs) : FunctionDeclaration(*new FunctionDefinitionData( 28 *rhs.d_func())) 29 { 30 } 31 ~FunctionDefinition()32FunctionDefinition::~FunctionDefinition() 33 { 34 if (!topContext()->isOnDisk()) 35 DUChain::definitions()->removeDefinition(d_func()->m_declaration, this); 36 } 37 declaration(const TopDUContext * topContext) const38Declaration* FunctionDefinition::declaration(const TopDUContext* topContext) const 39 { 40 ENSURE_CAN_READ 41 42 const KDevVarLengthArray<Declaration*> declarations = d_func()->m_declaration.declarations( 43 topContext ? topContext : this->topContext()); 44 45 for (Declaration* decl : declarations) { 46 if (!dynamic_cast<FunctionDefinition*>(decl)) 47 return decl; 48 } 49 50 return nullptr; 51 } 52 hasDeclaration() const53bool FunctionDefinition::hasDeclaration() const 54 { 55 return d_func()->m_declaration.isValid(); 56 } 57 setDeclaration(Declaration * declaration)58void FunctionDefinition::setDeclaration(Declaration* declaration) 59 { 60 ENSURE_CAN_WRITE 61 62 if (declaration) { 63 DUChain::definitions()->addDefinition(declaration->id(), this); 64 d_func_dynamic()->m_declaration = declaration->id(); 65 } else { 66 if (d_func()->m_declaration.isValid()) { 67 DUChain::definitions()->removeDefinition(d_func()->m_declaration, this); 68 d_func_dynamic()->m_declaration = DeclarationId(); 69 } 70 } 71 } 72 definition(const Declaration * decl)73Declaration* FunctionDefinition::definition(const Declaration* decl) 74 { 75 ENSURE_CHAIN_READ_LOCKED 76 if (!decl) { 77 return nullptr; 78 } 79 80 if (decl->isFunctionDeclaration() && decl->isDefinition()) { 81 return const_cast<Declaration*>(decl); 82 } 83 84 const KDevVarLengthArray<IndexedDeclaration> allDefinitions = DUChain::definitions()->definitions(decl->id()); 85 for (const IndexedDeclaration decl : allDefinitions) { 86 if (decl.data()) ///@todo Find better ways of deciding which definition to use 87 return decl.data(); 88 } 89 90 return nullptr; 91 } 92 clonePrivate() const93Declaration* FunctionDefinition::clonePrivate() const 94 { 95 return new FunctionDefinition(*new FunctionDefinitionData(*d_func())); 96 } 97 } 98