Commit 9c7ff519 authored by Tim Jenssen's avatar Tim Jenssen

Clang: Add clang query

Clang query is mechanism to use AST matcher to search for code. Think
about regular expression but in the context of AST. So you get a semantic
search tool for C++.

Change-Id: I72e882c5b53a0c52f352a3664847c4c3e4f6fc2e
Reviewed-by: Tim Jenssen's avatarTim Jenssen <tim.jenssen@qt.io>
parent 96187594
......@@ -57,7 +57,16 @@ SOURCES += $$PWD/clangcodemodelserverinterface.cpp \
$$PWD/sourcelocationcontainerv2.cpp \
$$PWD/sourcelocationsforrenamingmessage.cpp \
$$PWD/requestsourcelocationforrenamingmessage.cpp \
$$PWD/filepath.cpp
$$PWD/filepath.cpp \
$$PWD/sourcerangescontainer.cpp \
$$PWD/sourcerangecontainerv2.cpp \
$$PWD/dynamicastmatcherdiagnosticcontainer.cpp \
$$PWD/dynamicastmatcherdiagnosticcontextcontainer.cpp \
$$PWD/dynamicastmatcherdiagnosticmessagecontainer.cpp \
$$PWD/requestsourcerangesanddiagnosticsforquerymessage.cpp \
$$PWD/sourcerangesanddiagnosticsforquerymessage.cpp \
$$PWD/sourcerangewithtextcontainer.cpp \
$$PWD/filecontainerv2.cpp
HEADERS += \
$$PWD/clangcodemodelserverinterface.h \
......@@ -110,6 +119,17 @@ HEADERS += \
$$PWD/sourcelocationcontainerv2.h \
$$PWD/sourcelocationsforrenamingmessage.h \
$$PWD/requestsourcelocationforrenamingmessage.h \
$$PWD/filepath.h
$$PWD/filepath.h \
$$PWD/sourcerangescontainer.h \
$$PWD/sourcefilepathcontainerbase.h \
$$PWD/sourcerangecontainerv2.h \
$$PWD/dynamicmatcherdiagnostics.h \
$$PWD/dynamicastmatcherdiagnosticcontainer.h \
$$PWD/dynamicastmatcherdiagnosticcontextcontainer.h \
$$PWD/dynamicastmatcherdiagnosticmessagecontainer.h \
$$PWD/requestsourcerangesanddiagnosticsforquerymessage.h \
$$PWD/sourcerangesanddiagnosticsforquerymessage.h \
$$PWD/sourcerangewithtextcontainer.h \
$$PWD/filecontainerv2.h
contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols
......@@ -29,6 +29,10 @@
#include <QtCore/qglobal.h>
#ifdef UNIT_TESTS
#include <gtest/gtest.h>
#endif
#if defined(CLANGBACKENDIPC_BUILD_LIB)
# define CMBIPC_EXPORT Q_DECL_EXPORT
#elif defined(CLANGBACKENDIPC_BUILD_STATIC_LIB)
......@@ -41,6 +45,12 @@
# define CLANGBACKENDPROCESSPATH ""
#endif
namespace Utils {
template<uint Size>
class BasicSmallString;
using SmallString = BasicSmallString<31>;
}
namespace ClangBackEnd {
enum class DiagnosticSeverity : quint32 // one to one mapping of the clang enum numbers
......@@ -109,7 +119,10 @@ enum class MessageType : quint8 {
ProjectPartsDoNotExistMessage,
SourceLocationsForRenamingMessage,
RequestSourceLocationsForRenamingMessage
RequestSourceLocationsForRenamingMessage,
RequestSourceRangesAndDiagnosticsForQueryMessage,
SourceRangesAndDiagnosticsForQueryMessage
};
template<MessageType messageEnumeration>
......
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "dynamicastmatcherdiagnosticcontainer.h"
namespace ClangBackEnd {
QDebug operator<<(QDebug debug, const DynamicASTMatcherDiagnosticContainer &container)
{
debug.nospace() << "DynamicASTMatcherDiagnosticContextContainer("
<< container.messages() << ", "
<< container.contexts()
<< ")";
return debug;
}
void PrintTo(const DynamicASTMatcherDiagnosticContainer &container, ::std::ostream* os)
{
*os << "{[";
for (const auto &message : container.messages()) {
PrintTo(message, os);
*os << ", ";
}
*os << "], [";
for (const auto &context : container.contexts()) {
PrintTo(context, os);
*os << ", ";
}
*os << "]}";
}
} // namespace ClangBackEnd
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "dynamicastmatcherdiagnosticmessagecontainer.h"
#include "dynamicastmatcherdiagnosticcontextcontainer.h"
namespace ClangBackEnd {
class DynamicASTMatcherDiagnosticContainer
{
public:
DynamicASTMatcherDiagnosticContainer() = default;
DynamicASTMatcherDiagnosticContainer(std::vector<DynamicASTMatcherDiagnosticMessageContainer> &&messages,
std::vector<DynamicASTMatcherDiagnosticContextContainer> &&contexts)
: messages_(std::move(messages)),
contexts_(std::move(contexts))
{
}
const std::vector<DynamicASTMatcherDiagnosticMessageContainer> &messages() const
{
return messages_;
}
const std::vector<DynamicASTMatcherDiagnosticContextContainer> &contexts() const
{
return contexts_;
}
void insertMessage(V2::SourceRangeContainer &&sourceRange,
ClangQueryDiagnosticErrorType errorType,
Utils::SmallStringVector &&arguments) {
messages_.emplace_back(std::move(sourceRange), errorType, std::move(arguments));
}
void insertContext(V2::SourceRangeContainer &&sourceRange,
ClangQueryDiagnosticContextType contextType,
Utils::SmallStringVector &&arguments) {
contexts_.emplace_back(std::move(sourceRange), contextType, std::move(arguments));
}
friend QDataStream &operator<<(QDataStream &out, const DynamicASTMatcherDiagnosticContainer &container)
{
out << container.messages_;
out << container.contexts_;
return out;
}
friend QDataStream &operator>>(QDataStream &in, DynamicASTMatcherDiagnosticContainer &container)
{
in >> container.messages_;
in >> container.contexts_;
return in;
}
friend bool operator==(const DynamicASTMatcherDiagnosticContainer &first,
const DynamicASTMatcherDiagnosticContainer &second)
{
return first.messages_ == second.messages_
&& first.contexts_ == second.contexts_;
}
DynamicASTMatcherDiagnosticContainer clone() const
{
return DynamicASTMatcherDiagnosticContainer(Utils::clone(messages_),
Utils::clone(contexts_));
}
private:
std::vector<DynamicASTMatcherDiagnosticMessageContainer> messages_;
std::vector<DynamicASTMatcherDiagnosticContextContainer> contexts_;
};
CMBIPC_EXPORT QDebug operator<<(QDebug debug, const DynamicASTMatcherDiagnosticContainer &container);
void PrintTo(const DynamicASTMatcherDiagnosticContainer &container, ::std::ostream* os);
} // namespace ClangBackEnd
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "dynamicastmatcherdiagnosticcontextcontainer.h"
namespace ClangBackEnd {
QDebug operator<<(QDebug debug, const DynamicASTMatcherDiagnosticContextContainer &container)
{
debug.nospace() << "DynamicASTMatcherDiagnosticContextContainer("
<< container.sourceRange() << ", "
<< container.contextTypeText() << ", "
<< container.arguments()
<< ")";
return debug;
}
void PrintTo(const DynamicASTMatcherDiagnosticContextContainer &container, ::std::ostream* os)
{
*os << "{"
<< container.contextTypeText() << ": ";
PrintTo(container.sourceRange(), os);
*os << ", [";
for (const auto &argument : container.arguments()) {
PrintTo(argument, os);
*os << ", ";
}
*os << "]}";
}
#define RETURN_CASE(name) \
case ClangQueryDiagnosticContextType::name: return #name;
Utils::SmallString DynamicASTMatcherDiagnosticContextContainer::contextTypeText() const
{
switch (contextType_) {
RETURN_CASE(MatcherArg)
RETURN_CASE(MatcherConstruct)
}
Q_UNREACHABLE();
}
} // namespace ClangBackEnd
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "dynamicmatcherdiagnostics.h"
#include "sourcerangecontainerv2.h"
#include <utils/smallstringio.h>
namespace ClangBackEnd {
class DynamicASTMatcherDiagnosticContextContainer
{
public:
DynamicASTMatcherDiagnosticContextContainer() = default;
DynamicASTMatcherDiagnosticContextContainer(V2::SourceRangeContainer &&sourceRange,
ClangQueryDiagnosticContextType contextType,
Utils::SmallStringVector &&arguments)
: sourceRange_(sourceRange),
contextType_(contextType),
arguments_(std::move(arguments))
{
}
const V2::SourceRangeContainer &sourceRange() const
{
return sourceRange_;
}
ClangQueryDiagnosticContextType contextType() const
{
return contextType_;
}
Utils::SmallString contextTypeText() const;
const Utils::SmallStringVector &arguments() const
{
return arguments_;
}
friend QDataStream &operator<<(QDataStream &out, const DynamicASTMatcherDiagnosticContextContainer &container)
{
out << container.sourceRange_;
out << quint32(container.contextType_);
out << container.arguments_;
return out;
}
friend QDataStream &operator>>(QDataStream &in, DynamicASTMatcherDiagnosticContextContainer &container)
{
quint32 contextType;
in >> container.sourceRange_;
in >> contextType;
in >> container.arguments_;
container.contextType_ = static_cast<ClangQueryDiagnosticContextType>(contextType);
return in;
}
friend bool operator==(const DynamicASTMatcherDiagnosticContextContainer &first,
const DynamicASTMatcherDiagnosticContextContainer &second)
{
return first.contextType_ == second.contextType_
&& first.sourceRange_ == second.sourceRange_
&& first.arguments_ == second.arguments_;
}
DynamicASTMatcherDiagnosticContextContainer clone() const
{
return DynamicASTMatcherDiagnosticContextContainer(sourceRange_.clone(),
contextType_,
arguments_.clone());
}
private:
V2::SourceRangeContainer sourceRange_;
ClangQueryDiagnosticContextType contextType_;
Utils::SmallStringVector arguments_;
};
CMBIPC_EXPORT QDebug operator<<(QDebug debug, const DynamicASTMatcherDiagnosticContextContainer &container);
void PrintTo(const DynamicASTMatcherDiagnosticContextContainer &container, ::std::ostream* os);
} // namespace ClangBackEnd
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "dynamicastmatcherdiagnosticmessagecontainer.h"
#define RETURN_CASE(name) \
case ClangQueryDiagnosticErrorType::name: return #name;
namespace ClangBackEnd {
QDebug operator<<(QDebug debug, const DynamicASTMatcherDiagnosticMessageContainer &container)
{
debug.nospace() << "DynamicASTMatcherDiagnosticMessageContainer("
<< container.sourceRange() << ", "
<< container.errorTypeText() << ", "
<< container.arguments()
<< ")";
return debug;
}
void PrintTo(const DynamicASTMatcherDiagnosticMessageContainer &container, ::std::ostream* os)
{
*os << "{"
<< container.errorTypeText() << ": ";
PrintTo(container.sourceRange(), os);
*os << ", [";
for (const auto &argument : container.arguments()) {
PrintTo(argument, os);
*os << ", ";
}
*os << "]}";
}
Utils::SmallString DynamicASTMatcherDiagnosticMessageContainer::errorTypeText() const
{
switch (errorType_) {
RETURN_CASE(None)
RETURN_CASE(RegistryMatcherNotFound)
RETURN_CASE(RegistryWrongArgCount)
RETURN_CASE(RegistryWrongArgType)
RETURN_CASE(RegistryNotBindable)
RETURN_CASE(RegistryAmbiguousOverload)
RETURN_CASE(RegistryValueNotFound)
RETURN_CASE(ParserStringError)
RETURN_CASE(ParserNoOpenParen)
RETURN_CASE(ParserNoCloseParen)
RETURN_CASE(ParserNoComma)
RETURN_CASE(ParserNoCode)
RETURN_CASE(ParserNotAMatcher)
RETURN_CASE(ParserInvalidToken)
RETURN_CASE(ParserMalformedBindExpr)
RETURN_CASE(ParserTrailingCode)
RETURN_CASE(ParserUnsignedError)
RETURN_CASE(ParserOverloadedType)
}
Q_UNREACHABLE();
}
} // namespace ClangBackEnd
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "dynamicmatcherdiagnostics.h"
#include "sourcerangecontainerv2.h"
#include <utils/smallstringio.h>
namespace ClangBackEnd {
class DynamicASTMatcherDiagnosticMessageContainer
{
public:
DynamicASTMatcherDiagnosticMessageContainer() = default;
DynamicASTMatcherDiagnosticMessageContainer(V2::SourceRangeContainer &&sourceRange,
ClangQueryDiagnosticErrorType errorType,
Utils::SmallStringVector &&arguments)
: sourceRange_(sourceRange),
errorType_(errorType),
arguments_(std::move(arguments))
{
}
const V2::SourceRangeContainer &sourceRange() const
{
return sourceRange_;
}
ClangQueryDiagnosticErrorType errorType() const
{
return errorType_;
}
Utils::SmallString errorTypeText() const;
const Utils::SmallStringVector &arguments() const
{
return arguments_;
}
friend QDataStream &operator<<(QDataStream &out, const DynamicASTMatcherDiagnosticMessageContainer &container)
{
out << container.sourceRange_;
out << quint32(container.errorType_);
out << container.arguments_;
return out;
}
friend QDataStream &operator>>(QDataStream &in, DynamicASTMatcherDiagnosticMessageContainer &container)
{
quint32 errorType;
in >> container.sourceRange_;
in >> errorType;
in >> container.arguments_;
container.errorType_ = static_cast<ClangQueryDiagnosticErrorType>(errorType);
return in;
}
friend bool operator==(const DynamicASTMatcherDiagnosticMessageContainer &first,
const DynamicASTMatcherDiagnosticMessageContainer &second)
{
return first.errorType_ == second.errorType_
&& first.sourceRange_ == second.sourceRange_
&& first.arguments_ == second.arguments_;
}
DynamicASTMatcherDiagnosticMessageContainer clone() const
{
return DynamicASTMatcherDiagnosticMessageContainer(sourceRange_.clone(),
errorType_,
arguments_.clone());
}
private:
V2::SourceRangeContainer sourceRange_;
ClangQueryDiagnosticErrorType errorType_;
Utils::SmallStringVector arguments_;
};