1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
/*
* Copyright 2014 Kevin Funk <kfunk@kde.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "duchainutils.h"
#include "util/clangdebug.h"
#include <language/duchain/declaration.h>
#include <language/duchain/duchainutils.h>
#include <language/duchain/ducontext.h>
#include <language/duchain/functiondefinition.h>
#include <language/duchain/types/typeregister.h>
#include "macrodefinition.h"
#include "clangducontext.h"
#include "clangparsingenvironmentfile.h"
#include "types/classspecializationtype.h"
using namespace KDevelop;
namespace ClangIntegration {
KTextEditor::Range DUChainUtils::functionSignatureRange(const Declaration* decl)
{
if (!decl->isFunctionDeclaration()) {
qCWarning(KDEV_CLANG) << "Invalid declaration:" << decl;
return {};
}
auto functionContext = decl->internalContext();
Q_ASSERT(functionContext);
auto childContexts = functionContext->childContexts();
if (childContexts.isEmpty()) {
return functionContext->rangeInCurrentRevision();
}
const auto start = functionContext->rangeInCurrentRevision().start();
const auto end = childContexts[0]->rangeInCurrentRevision().start();
return {start, end};
}
void DUChainUtils::registerDUChainItems()
{
duchainRegisterType<ClangTopDUContext>();
duchainRegisterType<ClangParsingEnvironmentFile>();
duchainRegisterType<ClangNormalDUContext>();
duchainRegisterType<MacroDefinition>();
TypeSystem::self().registerTypeClass<ClassSpecializationType, ClassSpecializationTypeData>();
}
void DUChainUtils::unregisterDUChainItems()
{
TypeSystem::self().unregisterTypeClass<ClassSpecializationType, ClassSpecializationTypeData>();
/// FIXME: this is currently not supported by the DUChain code...
/// When the items are unregistered on plugin destruction, we'll get hit by
/// assertions later on when the DUChain is finalized. There, when the data is getting cleaned up,
/// we try to load all kinds of items again which would fail to find our items if we unregister.
/// So let's not do it...
/*
duchainUnregisterType<ClangTopDUContext>();
duchainUnregisterType<ClangParsingEnvironmentFile>();
duchainUnregisterType<ClangNormalDUContext>();
duchainUnregisterType<MacroDefinition>();
*/
}
ParseSessionData::Ptr DUChainUtils::findParseSessionData(const IndexedString &file, const IndexedString &tufile)
{
DUChainReadLocker lock;
auto context = KDevelop::DUChainUtils::standardContextForUrl(file.toUrl());
if (!context || !context->ast()) {
// no cached data found for the current file, but maybe
// we are lucky and can grab it from the TU context
// this happens e.g. when originally a .cpp file is open and then one
// of its included files is opened in the editor.
context = KDevelop::DUChainUtils::standardContextForUrl(tufile.toUrl());
}
if (context) {
return ParseSessionData::Ptr(dynamic_cast<ParseSessionData*>(context->ast().data()));
}
return {};
}
}
|