File indexing completed on 2024-05-12 04:39:12

0001 /*
0002     SPDX-FileCopyrightText: 2014 Kevin Funk <kfunk@kde.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005 */
0006 
0007 #include "duchainutils.h"
0008 
0009 #include "util/clangdebug.h"
0010 
0011 #include <language/duchain/declaration.h>
0012 #include <language/duchain/duchainutils.h>
0013 #include <language/duchain/ducontext.h>
0014 #include <language/duchain/functiondefinition.h>
0015 #include <language/duchain/types/typeregister.h>
0016 
0017 #include "macrodefinition.h"
0018 #include "clangducontext.h"
0019 #include "clangparsingenvironmentfile.h"
0020 #include "types/classspecializationtype.h"
0021 
0022 using namespace KDevelop;
0023 
0024 namespace ClangIntegration {
0025 
0026 KTextEditor::Range DUChainUtils::functionSignatureRange(const Declaration* decl)
0027 {
0028     if (!decl->isFunctionDeclaration()) {
0029         qCWarning(KDEV_CLANG) << "Invalid declaration:" << decl;
0030         return {};
0031     }
0032 
0033     auto functionContext = decl->internalContext();
0034     Q_ASSERT(functionContext);
0035     auto childContexts = functionContext->childContexts();
0036     if (childContexts.isEmpty()) {
0037         return functionContext->rangeInCurrentRevision();
0038     }
0039 
0040     const auto start = functionContext->rangeInCurrentRevision().start();
0041     const auto end = childContexts[0]->rangeInCurrentRevision().start();
0042     return {start, end};
0043 }
0044 
0045 void DUChainUtils::registerDUChainItems()
0046 {
0047     duchainRegisterType<ClangTopDUContext>();
0048     duchainRegisterType<ClangParsingEnvironmentFile>();
0049     duchainRegisterType<ClangNormalDUContext>();
0050     duchainRegisterType<MacroDefinition>();
0051 
0052     TypeSystem::self().registerTypeClass<ClassSpecializationType, ClassSpecializationTypeData>();
0053 }
0054 
0055 void DUChainUtils::unregisterDUChainItems()
0056 {
0057     TypeSystem::self().unregisterTypeClass<ClassSpecializationType, ClassSpecializationTypeData>();
0058 
0059     /// FIXME: this is currently not supported by the DUChain code...
0060     /// When the items are unregistered on plugin destruction, we'll get hit by
0061     /// assertions later on when the DUChain is finalized. There, when the data is getting cleaned up,
0062     /// we try to load all kinds of items again which would fail to find our items if we unregister.
0063     /// So let's not do it...
0064 /*
0065     duchainUnregisterType<ClangTopDUContext>();
0066     duchainUnregisterType<ClangParsingEnvironmentFile>();
0067     duchainUnregisterType<ClangNormalDUContext>();
0068     duchainUnregisterType<MacroDefinition>();
0069 
0070 */
0071 }
0072 
0073 ParseSessionData::Ptr DUChainUtils::findParseSessionData(const IndexedString &file, const IndexedString &tufile)
0074 {
0075     DUChainReadLocker lock;
0076     auto context = KDevelop::DUChainUtils::standardContextForUrl(file.toUrl());
0077     if (!context || !context->ast()) {
0078         // no cached data found for the current file, but maybe
0079         // we are lucky and can grab it from the TU context
0080         // this happens e.g. when originally a .cpp file is open and then one
0081         // of its included files is opened in the editor.
0082         context = KDevelop::DUChainUtils::standardContextForUrl(tufile.toUrl());
0083     }
0084 
0085     if (context) {
0086         return ParseSessionData::Ptr(dynamic_cast<ParseSessionData*>(context->ast().data()));
0087     }
0088     return {};
0089 }
0090 
0091 }