1 /*
2     SPDX-FileCopyrightText: 2014 Kevin Funk <kfunk@kde.org>
3 
4     SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
5 */
6 
7 #include "duchainutils.h"
8 
9 #include "util/clangdebug.h"
10 
11 #include <language/duchain/declaration.h>
12 #include <language/duchain/duchainutils.h>
13 #include <language/duchain/ducontext.h>
14 #include <language/duchain/functiondefinition.h>
15 #include <language/duchain/types/typeregister.h>
16 
17 #include "macrodefinition.h"
18 #include "clangducontext.h"
19 #include "clangparsingenvironmentfile.h"
20 #include "types/classspecializationtype.h"
21 
22 using namespace KDevelop;
23 
24 namespace ClangIntegration {
25 
functionSignatureRange(const Declaration * decl)26 KTextEditor::Range DUChainUtils::functionSignatureRange(const Declaration* decl)
27 {
28     if (!decl->isFunctionDeclaration()) {
29         qCWarning(KDEV_CLANG) << "Invalid declaration:" << decl;
30         return {};
31     }
32 
33     auto functionContext = decl->internalContext();
34     Q_ASSERT(functionContext);
35     auto childContexts = functionContext->childContexts();
36     if (childContexts.isEmpty()) {
37         return functionContext->rangeInCurrentRevision();
38     }
39 
40     const auto start = functionContext->rangeInCurrentRevision().start();
41     const auto end = childContexts[0]->rangeInCurrentRevision().start();
42     return {start, end};
43 }
44 
registerDUChainItems()45 void DUChainUtils::registerDUChainItems()
46 {
47     duchainRegisterType<ClangTopDUContext>();
48     duchainRegisterType<ClangParsingEnvironmentFile>();
49     duchainRegisterType<ClangNormalDUContext>();
50     duchainRegisterType<MacroDefinition>();
51 
52     TypeSystem::self().registerTypeClass<ClassSpecializationType, ClassSpecializationTypeData>();
53 }
54 
unregisterDUChainItems()55 void DUChainUtils::unregisterDUChainItems()
56 {
57     TypeSystem::self().unregisterTypeClass<ClassSpecializationType, ClassSpecializationTypeData>();
58 
59     /// FIXME: this is currently not supported by the DUChain code...
60     /// When the items are unregistered on plugin destruction, we'll get hit by
61     /// assertions later on when the DUChain is finalized. There, when the data is getting cleaned up,
62     /// we try to load all kinds of items again which would fail to find our items if we unregister.
63     /// So let's not do it...
64 /*
65     duchainUnregisterType<ClangTopDUContext>();
66     duchainUnregisterType<ClangParsingEnvironmentFile>();
67     duchainUnregisterType<ClangNormalDUContext>();
68     duchainUnregisterType<MacroDefinition>();
69 
70 */
71 }
72 
findParseSessionData(const IndexedString & file,const IndexedString & tufile)73 ParseSessionData::Ptr DUChainUtils::findParseSessionData(const IndexedString &file, const IndexedString &tufile)
74 {
75     DUChainReadLocker lock;
76     auto context = KDevelop::DUChainUtils::standardContextForUrl(file.toUrl());
77     if (!context || !context->ast()) {
78         // no cached data found for the current file, but maybe
79         // we are lucky and can grab it from the TU context
80         // this happens e.g. when originally a .cpp file is open and then one
81         // of its included files is opened in the editor.
82         context = KDevelop::DUChainUtils::standardContextForUrl(tufile.toUrl());
83     }
84 
85     if (context) {
86         return ParseSessionData::Ptr(dynamic_cast<ParseSessionData*>(context->ast().data()));
87     }
88     return {};
89 }
90 
91 }
92