Clang: Add symbols collector

Change-Id: I64c25eef8eaa6cc6c3ff09d41866972b6c7248d0
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
Marco Bubke
2017-07-24 14:55:51 +02:00
parent 8640ef1927
commit f0e00a8c25
26 changed files with 957 additions and 162 deletions

View File

@@ -172,6 +172,7 @@ HEADERS += \
$$PWD/updatevisibletranslationunitsmessage.h \ $$PWD/updatevisibletranslationunitsmessage.h \
$$PWD/writemessageblock.h \ $$PWD/writemessageblock.h \
$$PWD/ipcclientprovider.h \ $$PWD/ipcclientprovider.h \
$$PWD/requestsourcerangesforquerymessage.h \
$$PWD/stringcachefwd.h $$PWD/stringcachefwd.h
contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols

View File

@@ -2,7 +2,14 @@ INCLUDEPATH += $$PWD
HEADERS += \ HEADERS += \
$$PWD/clangrefactoringbackend_global.h \ $$PWD/clangrefactoringbackend_global.h \
$$PWD/sourcerangefilter.h $$PWD/sourcerangefilter.h \
$$PWD/symbolscollector.h \
$$PWD/symbolentry.h \
$$PWD/collectsymbolsconsumer.h \
$$PWD/collectsymbolsaction.h \
$$PWD/collectmacrossourcefilecallbacks.h \
$$PWD/collectsymbolsastvisitor.h \
$$PWD/sourcelocationentry.h
!isEmpty(LIBTOOLING_LIBS) { !isEmpty(LIBTOOLING_LIBS) {
SOURCES += \ SOURCES += \
@@ -36,4 +43,9 @@ HEADERS += \
} }
SOURCES += \ SOURCES += \
$$PWD/sourcerangefilter.cpp $$PWD/sourcerangefilter.cpp \
$$PWD/symbolscollector.cpp \
$$PWD/collectsymbolsaction.cpp \
$$PWD/collectmacrossourcefilecallbacks.cpp \
$$PWD/symbolentry.cpp \
$$PWD/sourcelocationentry.cpp

View File

@@ -47,15 +47,15 @@ void ClangTool::addFile(std::string &&directory,
std::string &&content, std::string &&content,
std::vector<std::string> &&commandLine) std::vector<std::string> &&commandLine)
{ {
fileContents.emplace_back(toNativePath(std::move(directory)), m_fileContents.emplace_back(toNativePath(std::move(directory)),
std::move(fileName), std::move(fileName),
std::move(content), std::move(content),
std::move(commandLine)); std::move(commandLine));
const auto &fileContent = fileContents.back(); const auto &fileContent = m_fileContents.back();
compilationDatabase.addFile(fileContent.directory, fileContent.fileName, fileContent.commandLine); m_compilationDatabase.addFile(fileContent.directory, fileContent.fileName, fileContent.commandLine);
sourceFilePaths.push_back(fileContent.filePath); m_sourceFilePaths.push_back(fileContent.filePath);
} }
template <typename Container> template <typename Container>
@@ -86,7 +86,7 @@ void ClangTool::addFiles<Utils::PathStringVector>(const Utils::PathStringVector
void ClangTool::addUnsavedFiles(const V2::FileContainers &unsavedFiles) void ClangTool::addUnsavedFiles(const V2::FileContainers &unsavedFiles)
{ {
unsavedFileContents.reserve(unsavedFileContents.size() + unsavedFiles.size()); m_unsavedFileContents.reserve(m_unsavedFileContents.size() + unsavedFiles.size());
auto convertToUnsavedFileContent = [] (const V2::FileContainer &unsavedFile) { auto convertToUnsavedFileContent = [] (const V2::FileContainer &unsavedFile) {
return UnsavedFileContent{toNativePath(unsavedFile.filePath().path().clone()), return UnsavedFileContent{toNativePath(unsavedFile.filePath().path().clone()),
@@ -95,7 +95,7 @@ void ClangTool::addUnsavedFiles(const V2::FileContainers &unsavedFiles)
std::transform(unsavedFiles.begin(), std::transform(unsavedFiles.begin(),
unsavedFiles.end(), unsavedFiles.end(),
std::back_inserter(unsavedFileContents), std::back_inserter(m_unsavedFileContents),
convertToUnsavedFileContent); convertToUnsavedFileContent);
} }
@@ -109,14 +109,14 @@ llvm::StringRef toStringRef(const String &string)
clang::tooling::ClangTool ClangTool::createTool() const clang::tooling::ClangTool ClangTool::createTool() const
{ {
clang::tooling::ClangTool tool(compilationDatabase, sourceFilePaths); clang::tooling::ClangTool tool(m_compilationDatabase, m_sourceFilePaths);
for (const auto &fileContent : fileContents) { for (const auto &fileContent : m_fileContents) {
if (!fileContent.content.empty()) if (!fileContent.content.empty())
tool.mapVirtualFile(fileContent.filePath, fileContent.content); tool.mapVirtualFile(fileContent.filePath, fileContent.content);
} }
for (const auto &unsavedFileContent : unsavedFileContents) for (const auto &unsavedFileContent : m_unsavedFileContents)
tool.mapVirtualFile(toStringRef(unsavedFileContent.filePath), tool.mapVirtualFile(toStringRef(unsavedFileContent.filePath),
toStringRef(unsavedFileContent.content)); toStringRef(unsavedFileContent.content));

View File

@@ -104,10 +104,10 @@ public:
clang::tooling::ClangTool createTool() const; clang::tooling::ClangTool createTool() const;
private: private:
RefactoringCompilationDatabase compilationDatabase; RefactoringCompilationDatabase m_compilationDatabase;
std::vector<FileContent> fileContents; std::vector<FileContent> m_fileContents;
std::vector<std::string> sourceFilePaths; std::vector<std::string> m_sourceFilePaths;
std::vector<UnsavedFileContent> unsavedFileContents; std::vector<UnsavedFileContent> m_unsavedFileContents;
}; };
} // namespace ClangBackEnd } // namespace ClangBackEnd

View File

@@ -0,0 +1,35 @@
/****************************************************************************
**
** Copyright (C) 2017 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 "collectmacrossourcefilecallbacks.h"
namespace ClangBackEnd {
CollectMacrosSourceFileCallbacks::CollectMacrosSourceFileCallbacks()
{
}
} // namespace ClangBackEnd

View File

@@ -0,0 +1,38 @@
/****************************************************************************
**
** Copyright (C) 2017 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 <clang/Tooling/Tooling.h>
namespace ClangBackEnd {
class CollectMacrosSourceFileCallbacks : public clang::tooling::SourceFileCallbacks
{
public:
CollectMacrosSourceFileCallbacks();
};
} // namespace ClangBackEnd

View File

@@ -0,0 +1,39 @@
/****************************************************************************
**
** Copyright (C) 2017 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 "collectsymbolsaction.h"
#include "collectsymbolsconsumer.h"
namespace ClangBackEnd {
std::unique_ptr<clang::ASTConsumer> CollectSymbolsAction::newASTConsumer()
{
return std::make_unique<CollectSymbolsConsumer>(m_symbolEntries,
m_sourceLocationEntries,
m_filePathCache);
}
} // namespace ClangBackEnd

View File

@@ -0,0 +1,71 @@
/****************************************************************************
**
** Copyright (C) 2017 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 "clangrefactoringbackend_global.h"
#include "sourcelocationentry.h"
#include "symbolentry.h"
#include <utils/smallstring.h>
#include <stringcachefwd.h>
#include <clang/Frontend/FrontendAction.h>
namespace ClangBackEnd {
class CollectSymbolsAction
{
public:
CollectSymbolsAction(FilePathCache<> &filePathCache)
: m_filePathCache(filePathCache)
{}
std::unique_ptr<clang::ASTConsumer> newASTConsumer();
SymbolEntries takeSymbols()
{
return std::move(m_symbolEntries);
}
const SymbolEntries &symbols() const
{
return m_symbolEntries;
}
const SourceLocationEntries &sourceLocations() const
{
return m_sourceLocationEntries;
}
private:
SymbolEntries m_symbolEntries;
SourceLocationEntries m_sourceLocationEntries;
FilePathCache<> &m_filePathCache;
};
} // namespace ClangBackEnd

View File

@@ -0,0 +1,126 @@
/****************************************************************************
**
** Copyright (C) 2017 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 "symbolentry.h"
#include "sourcelocationentry.h"
#include <stringcache.h>
#include <clang/AST/AST.h>
#include <clang/AST/ASTContext.h>
#include <clang/AST/RecursiveASTVisitor.h>
#include <clang/Index/USRGeneration.h>
#include <llvm/ADT/SmallVector.h>
#include <vector>
namespace ClangBackEnd {
Utils::SmallStringView toStringView(clang::StringRef stringReference)
{
return Utils::SmallStringView(stringReference.data(), stringReference.size());
}
class CollectSymbolsASTVisitor : public clang::RecursiveASTVisitor<CollectSymbolsASTVisitor>
{
public:
CollectSymbolsASTVisitor(SymbolEntries &symbolEntries,
SourceLocationEntries &sourceLocationEntries,
FilePathCache<> &filePathCache,
const clang::SourceManager &sourceManager)
: m_symbolEntries(symbolEntries),
m_sourceLocationEntries(sourceLocationEntries),
m_filePathCache(filePathCache),
m_sourceManager(sourceManager)
{}
bool VisitNamedDecl(const clang::NamedDecl *declaration)
{
auto globalId = declaration->getCanonicalDecl()->getLocation().getRawEncoding();
auto sourceLocation = declaration->getLocation();
auto found = m_symbolEntries.find(globalId);
if (found == m_symbolEntries.end()) {
m_symbolEntries.emplace(std::piecewise_construct,
std::forward_as_tuple(globalId),
std::forward_as_tuple(generateUSR(declaration), declaration->getName()));
}
m_sourceLocationEntries.emplace_back(globalId,
filePathId(sourceLocation),
lineColum(sourceLocation),
SymbolType::Declaration);
return true;
}
bool VisitDeclRefExpr(const clang::DeclRefExpr *expression)
{
auto declaration = expression->getFoundDecl();
auto globalId = declaration->getCanonicalDecl()->getLocation().getRawEncoding();
auto sourceLocation = expression->getLocation();
m_sourceLocationEntries.emplace_back(globalId,
filePathId(sourceLocation),
lineColum(sourceLocation),
SymbolType::DeclarationReference);
return true;
}
uint filePathId(clang::SourceLocation sourceLocation)
{
auto filePath = m_sourceManager.getFilename(sourceLocation);
return m_filePathCache.stringId(toStringView(filePath));
}
LineColumn lineColum(clang::SourceLocation sourceLocation)
{
return {m_sourceManager.getSpellingLineNumber(sourceLocation),
m_sourceManager.getSpellingColumnNumber(sourceLocation)};
}
llvm::SmallVector<char, 128> generateUSR(const clang::Decl *declaration)
{
llvm::SmallVector<char, 128> usr;
clang::index::generateUSRForDecl(declaration, usr);
return usr;
}
private:
SymbolEntries &m_symbolEntries;
SourceLocationEntries &m_sourceLocationEntries;
FilePathCache<> &m_filePathCache;
const clang::SourceManager &m_sourceManager;
};
} // namespace ClangBackend

View File

@@ -0,0 +1,62 @@
/****************************************************************************
**
** Copyright (C) 2017 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 "collectsymbolsastvisitor.h"
#include <clang/AST/AST.h>
#include <clang/AST/ASTConsumer.h>
#include <clang/AST/ASTContext.h>
#include <stringcachefwd.h>
namespace ClangBackEnd {
class CollectSymbolsConsumer : public clang::ASTConsumer
{
public:
CollectSymbolsConsumer(SymbolEntries &symbolEntries,
SourceLocationEntries &sourceLocationEntries,
FilePathCache<> &filePathCache)
: m_symbolEntries(symbolEntries),
m_sourceLocationEntries(sourceLocationEntries),
m_filePathCache(filePathCache)
{}
void HandleTranslationUnit(clang::ASTContext &astContext) override {
CollectSymbolsASTVisitor visitor{m_symbolEntries,
m_sourceLocationEntries,
m_filePathCache,
astContext.getSourceManager()};
visitor.TraverseDecl(astContext.getTranslationUnitDecl());
}
private:
SymbolEntries &m_symbolEntries;
SourceLocationEntries &m_sourceLocationEntries;
FilePathCache<> &m_filePathCache;
};
}

View File

@@ -25,26 +25,12 @@
#pragma once #pragma once
#if defined(__GNUC__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wunused-parameter"
#elif defined(_MSC_VER)
# pragma warning(push)
# pragma warning( disable : 4100 )
#endif
#include <clang/AST/AST.h> #include <clang/AST/AST.h>
#include <clang/AST/ASTContext.h> #include <clang/AST/ASTContext.h>
#include <clang/AST/RecursiveASTVisitor.h> #include <clang/AST/RecursiveASTVisitor.h>
#include <clang/Index/USRGeneration.h> #include <clang/Index/USRGeneration.h>
#include <llvm/ADT/SmallVector.h> #include <llvm/ADT/SmallVector.h>
#if defined(__GNUC__)
# pragma GCC diagnostic pop
#elif defined(_MSC_VER)
# pragma warning(pop)
#endif
#include <vector> #include <vector>
namespace ClangBackEnd { namespace ClangBackEnd {
@@ -54,8 +40,8 @@ class FindNamedDeclarationASTVisitor : public clang::RecursiveASTVisitor<FindNam
public: public:
explicit FindNamedDeclarationASTVisitor(const clang::SourceManager &sourceManager, explicit FindNamedDeclarationASTVisitor(const clang::SourceManager &sourceManager,
const clang::SourceLocation cursorSourceLocation) const clang::SourceLocation cursorSourceLocation)
: sourceManager(sourceManager), : m_sourceManager(sourceManager),
cursorSourceLocation(cursorSourceLocation) m_cursorSourceLocation(cursorSourceLocation)
{ {
} }
@@ -96,7 +82,7 @@ public:
std::vector<const clang::NamedDecl*> takeNamedDecl() std::vector<const clang::NamedDecl*> takeNamedDecl()
{ {
return std::move(namedDeclarations); return std::move(m_namedDeclarations);
} }
private: private:
@@ -138,7 +124,7 @@ private:
bool isValid = isValidLocationWithCursorInside(startLocation, endLocation); bool isValid = isValidLocationWithCursorInside(startLocation, endLocation);
if (isValid) if (isValid)
namedDeclarations.push_back(declaration); m_namedDeclarations.push_back(declaration);
return !isValid; return !isValid;
} }
@@ -153,15 +139,15 @@ private:
bool isCursorLocationBetween(const clang::SourceLocation startLocation, bool isCursorLocationBetween(const clang::SourceLocation startLocation,
const clang::SourceLocation endLocation) const clang::SourceLocation endLocation)
{ {
return cursorSourceLocation == startLocation return m_cursorSourceLocation == startLocation
|| cursorSourceLocation == endLocation || m_cursorSourceLocation == endLocation
|| (sourceManager.isBeforeInTranslationUnit(startLocation, cursorSourceLocation) || (m_sourceManager.isBeforeInTranslationUnit(startLocation, m_cursorSourceLocation)
&& sourceManager.isBeforeInTranslationUnit(cursorSourceLocation, endLocation)); && m_sourceManager.isBeforeInTranslationUnit(m_cursorSourceLocation, endLocation));
} }
std::vector<const clang::NamedDecl*> namedDeclarations; std::vector<const clang::NamedDecl*> m_namedDeclarations;
const clang::SourceManager &sourceManager; const clang::SourceManager &m_sourceManager;
const clang::SourceLocation cursorSourceLocation; const clang::SourceLocation m_cursorSourceLocation;
}; };
inline inline

View File

@@ -27,24 +27,10 @@
#include "findcursorusr.h" #include "findcursorusr.h"
#if defined(__GNUC__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wunused-parameter"
#elif defined(_MSC_VER)
# pragma warning(push)
# pragma warning( disable : 4100 )
#endif
#include <clang/AST/AST.h> #include <clang/AST/AST.h>
#include <clang/AST/ASTConsumer.h> #include <clang/AST/ASTConsumer.h>
#include <clang/AST/ASTContext.h> #include <clang/AST/ASTContext.h>
#if defined(__GNUC__)
# pragma GCC diagnostic pop
#elif defined(_MSC_VER)
# pragma warning(pop)
#endif
#include <algorithm> #include <algorithm>
#include <vector> #include <vector>
@@ -87,18 +73,18 @@ public:
std::vector<USRName> &unifiedSymbolResolutions, std::vector<USRName> &unifiedSymbolResolutions,
uint line, uint line,
uint column) uint column)
: symbolName(symbolName), : m_symbolName(symbolName),
unifiedSymbolResolutions(unifiedSymbolResolutions), m_unifiedSymbolResolutions(unifiedSymbolResolutions),
line(line), m_line(line),
column(column) m_column(column)
{ {
} }
void HandleTranslationUnit(clang::ASTContext &astContext) override { void HandleTranslationUnit(clang::ASTContext &astContext) override {
const auto &sourceManager = astContext.getSourceManager(); const auto &sourceManager = astContext.getSourceManager();
const auto cursorSourceLocation = sourceManager.translateLineCol(sourceManager.getMainFileID(), const auto cursorSourceLocation = sourceManager.translateLineCol(sourceManager.getMainFileID(),
line, m_line,
column); m_column);
if (cursorSourceLocation.isValid()) if (cursorSourceLocation.isValid())
collectUnifiedSymbolResoltions(astContext, cursorSourceLocation); collectUnifiedSymbolResoltions(astContext, cursorSourceLocation);
@@ -114,32 +100,29 @@ public:
if (const auto *constructorDecl = clang::dyn_cast<clang::CXXConstructorDecl>(firstFoundDeclaration)) { if (const auto *constructorDecl = clang::dyn_cast<clang::CXXConstructorDecl>(firstFoundDeclaration)) {
const clang::CXXRecordDecl *foundDeclarationParent = constructorDecl->getParent(); const clang::CXXRecordDecl *foundDeclarationParent = constructorDecl->getParent();
unifiedSymbolResolutions = collectConstructorUnifiedSymbolResolutions(foundDeclarationParent); m_unifiedSymbolResolutions = collectConstructorUnifiedSymbolResolutions(foundDeclarationParent);
} else if (const auto *destructorDecl = clang::dyn_cast<clang::CXXDestructorDecl>(firstFoundDeclaration)) { } else if (const auto *destructorDecl = clang::dyn_cast<clang::CXXDestructorDecl>(firstFoundDeclaration)) {
const clang::CXXRecordDecl *foundDeclarationParent = destructorDecl->getParent(); const clang::CXXRecordDecl *foundDeclarationParent = destructorDecl->getParent();
unifiedSymbolResolutions = collectConstructorUnifiedSymbolResolutions(foundDeclarationParent); m_unifiedSymbolResolutions = collectConstructorUnifiedSymbolResolutions(foundDeclarationParent);
} else if (const auto *recordDeclaration = clang::dyn_cast<clang::CXXRecordDecl>(firstFoundDeclaration)) { } else if (const auto *recordDeclaration = clang::dyn_cast<clang::CXXRecordDecl>(firstFoundDeclaration)) {
unifiedSymbolResolutions = collectConstructorUnifiedSymbolResolutions(recordDeclaration); m_unifiedSymbolResolutions = collectConstructorUnifiedSymbolResolutions(recordDeclaration);
} }
addUnifiedSymbolResolutionsForDeclaration(foundDeclarations, unifiedSymbolResolutions); addUnifiedSymbolResolutionsForDeclaration(foundDeclarations, m_unifiedSymbolResolutions);
symbolName = firstFoundDeclaration->getNameAsString(); m_symbolName = firstFoundDeclaration->getNameAsString();
} }
} }
private: private:
Utils::SmallString &symbolName; Utils::SmallString &m_symbolName;
std::vector<USRName> &unifiedSymbolResolutions; std::vector<USRName> &m_unifiedSymbolResolutions;
uint line; uint m_line;
uint column; uint m_column;
}; };
std::unique_ptr<clang::ASTConsumer> std::unique_ptr<clang::ASTConsumer>
USRFindingAction::newASTConsumer() { USRFindingAction::newASTConsumer() {
std::unique_ptr<FindDeclarationsConsumer> Consumer( return std::make_unique<FindDeclarationsConsumer>(m_symbolName, m_unifiedSymbolResolutions, m_line, m_column);
new FindDeclarationsConsumer(symbolName, unifiedSymbolResolutions_, line, column));
return std::move(Consumer);
} }
} // namespace ClangBackEnd } // namespace ClangBackEnd

View File

@@ -29,21 +29,7 @@
#include <utils/smallstring.h> #include <utils/smallstring.h>
#if defined(__GNUC__) #include <clang/Frontend/FrontendAction.h>
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wunused-parameter"
#elif defined(_MSC_VER)
# pragma warning(push)
# pragma warning( disable : 4100 )
#endif
#include "clang/Frontend/FrontendAction.h"
#if defined(__GNUC__)
# pragma GCC diagnostic pop
#elif defined(_MSC_VER)
# pragma warning(pop)
#endif
namespace clang { namespace clang {
class ASTConsumer; class ASTConsumer;
@@ -57,8 +43,8 @@ class USRFindingAction
{ {
public: public:
USRFindingAction(uint line, uint column) USRFindingAction(uint line, uint column)
: line(line), : m_line(line),
column(column) m_column(column)
{ {
} }
@@ -66,19 +52,19 @@ public:
std::string takeSymbolName() std::string takeSymbolName()
{ {
return std::string(symbolName); return std::string(m_symbolName);
} }
std::vector<USRName> takeUnifiedSymbolResolutions() std::vector<USRName> takeUnifiedSymbolResolutions()
{ {
return std::move(unifiedSymbolResolutions_); return std::move(m_unifiedSymbolResolutions);
} }
private: private:
Utils::SmallString symbolName; Utils::SmallString m_symbolName;
std::vector<USRName> unifiedSymbolResolutions_; std::vector<USRName> m_unifiedSymbolResolutions;
uint line; uint m_line;
uint column; uint m_column;
}; };
} // namespace ClangBackEnd } // namespace ClangBackEnd

View File

@@ -27,22 +27,8 @@
#include <sourcelocationscontainer.h> #include <sourcelocationscontainer.h>
#if defined(__GNUC__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wunused-parameter"
#elif defined(_MSC_VER)
# pragma warning(push)
# pragma warning( disable : 4100 )
#endif
#include <clang/Tooling/Tooling.h> #include <clang/Tooling/Tooling.h>
#if defined(__GNUC__)
# pragma GCC diagnostic pop
#elif defined(_MSC_VER)
# pragma warning(pop)
#endif
namespace llvm { namespace llvm {
class StringRef; class StringRef;
} }

View File

@@ -0,0 +1,42 @@
/****************************************************************************
**
** Copyright (C) 2017 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 "sourcelocationentry.h"
#include <utils/smallstringio.h>
namespace ClangBackEnd {
std::ostream &operator<<(std::ostream &out, const SourceLocationEntry &entry)
{
out << "("
<< entry.fileId << ", "
<< entry.line << ", "
<< entry.column << ")";
return out;
}
} // namespace ClangBackEnd

View File

@@ -0,0 +1,79 @@
/****************************************************************************
**
** Copyright (C) 2017 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 <limits>
#include <vector>
#include <iosfwd>
using uint = unsigned int;
namespace ClangBackEnd {
enum class SymbolType
{
Declaration,
DeclarationReference
};
class LineColumn
{
public:
LineColumn(uint line, uint column)
: line(line),
column(column)
{}
uint line = 0;
uint column = 0;
};
class SourceLocationEntry
{
public:
SourceLocationEntry(uint symbolId,
uint fileId,
LineColumn lineColumn,
SymbolType symbolType)
: symbolId(symbolId),
fileId(fileId),
line(lineColumn.line),
column(lineColumn.column),
symbolType(symbolType)
{}
uint symbolId = 0;
uint fileId = std::numeric_limits<uint>::max();
uint line = 0;
uint column = 0;
SymbolType symbolType;
};
using SourceLocationEntries = std::vector<SourceLocationEntry>;
std::ostream &operator<<(std::ostream &out, const SourceLocationEntry &entry);
} // namespace ClangBackEnd

View File

@@ -0,0 +1,41 @@
/****************************************************************************
**
** Copyright (C) 2017 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 "symbolentry.h"
#include <utils/smallstringio.h>
namespace ClangBackEnd {
std::ostream &operator<<(std::ostream &out, const SymbolEntry &entry)
{
out << "("
<< entry.symbolName << ", "
<< entry.usr <<")";
return out;
}
} // namespace ClangBackEnd

View File

@@ -0,0 +1,56 @@
/****************************************************************************
**
** Copyright (C) 2017 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 <utils/smallstring.h>
#include <llvm/ADT/SmallVector.h>
#include <llvm/ADT/StringRef.h>
#include <limits>
#include <unordered_map>
#include <iosfwd>
namespace ClangBackEnd {
class SymbolEntry
{
public:
SymbolEntry(const llvm::SmallVector<char, 128> &usr,
llvm::StringRef name)
: usr(usr.data(), usr.size()),
symbolName(name.data(), name.size())
{}
Utils::PathString usr;
Utils::SmallString symbolName;
};
using SymbolEntries = std::unordered_map<uint, SymbolEntry>;
std::ostream &operator<<(std::ostream &out, const SymbolEntry &entry);
} // namespace ClangBackEnd

View File

@@ -32,22 +32,6 @@
#include <sourcelocationscontainer.h> #include <sourcelocationscontainer.h>
#if defined(__GNUC__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wunused-parameter"
#elif defined(_MSC_VER)
# pragma warning(push)
# pragma warning( disable : 4100 )
#endif
#include "clang/Tooling/Refactoring.h"
#if defined(__GNUC__)
# pragma GCC diagnostic pop
#elif defined(_MSC_VER)
# pragma warning(pop)
#endif
namespace ClangBackEnd { namespace ClangBackEnd {
class SymbolFinder : public ClangTool class SymbolFinder : public ClangTool

View File

@@ -39,7 +39,7 @@ class FindingSymbolsASTConsumer : public clang::ASTConsumer
{ {
public: public:
FindingSymbolsASTConsumer(std::vector<USRName> &unifiedSymbolResolutions) FindingSymbolsASTConsumer(std::vector<USRName> &unifiedSymbolResolutions)
: unifiedSymbolResolutions(unifiedSymbolResolutions) : m_unifiedSymbolResolutions(unifiedSymbolResolutions)
{ {
} }
@@ -48,7 +48,7 @@ public:
std::vector<clang::SourceLocation> sourceLocations; std::vector<clang::SourceLocation> sourceLocations;
auto &&sourceLocationsOfUsr = takeLocationsOfUSRs(unifiedSymbolResolutions, context.getTranslationUnitDecl()); auto &&sourceLocationsOfUsr = takeLocationsOfUSRs(m_unifiedSymbolResolutions, context.getTranslationUnitDecl());
sourceLocations.insert(sourceLocations.end(), sourceLocations.insert(sourceLocations.end(),
sourceLocationsOfUsr.begin(), sourceLocationsOfUsr.begin(),
sourceLocationsOfUsr.end()); sourceLocationsOfUsr.end());
@@ -65,24 +65,24 @@ public:
void updateSourceLocations(const std::vector<clang::SourceLocation> &sourceLocations, void updateSourceLocations(const std::vector<clang::SourceLocation> &sourceLocations,
const clang::SourceManager &sourceManager) const clang::SourceManager &sourceManager)
{ {
appendSourceLocationsToSourceLocationsContainer(*sourceLocationsContainer, sourceLocations, sourceManager); appendSourceLocationsToSourceLocationsContainer(*m_sourceLocationsContainer, sourceLocations, sourceManager);
} }
void setSourceLocations(ClangBackEnd::SourceLocationsContainer *sourceLocations) void setSourceLocations(ClangBackEnd::SourceLocationsContainer *sourceLocations)
{ {
sourceLocationsContainer = sourceLocations; m_sourceLocationsContainer = sourceLocations;
} }
private: private:
ClangBackEnd::SourceLocationsContainer *sourceLocationsContainer = nullptr; ClangBackEnd::SourceLocationsContainer *m_sourceLocationsContainer = nullptr;
std::vector<USRName> &unifiedSymbolResolutions; std::vector<USRName> &m_unifiedSymbolResolutions;
}; };
std::unique_ptr<clang::ASTConsumer> SymbolLocationFinderAction::newASTConsumer() std::unique_ptr<clang::ASTConsumer> SymbolLocationFinderAction::newASTConsumer()
{ {
auto consumer = std::unique_ptr<FindingSymbolsASTConsumer>(new FindingSymbolsASTConsumer(unifiedSymbolResolutions_)); auto consumer = std::unique_ptr<FindingSymbolsASTConsumer>(new FindingSymbolsASTConsumer(m_unifiedSymbolResolutions_));
consumer->setSourceLocations(&sourceLocations); consumer->setSourceLocations(&m_sourceLocations);
return std::move(consumer); return std::move(consumer);
} }

View File

@@ -29,22 +29,8 @@
#include <sourcelocationscontainer.h> #include <sourcelocationscontainer.h>
#if defined(__GNUC__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wunused-parameter"
#elif defined(_MSC_VER)
# pragma warning(push)
# pragma warning( disable : 4100 )
#endif
#include <clang/Tooling/Refactoring.h> #include <clang/Tooling/Refactoring.h>
#if defined(__GNUC__)
# pragma GCC diagnostic pop
#elif defined(_MSC_VER)
# pragma warning(pop)
#endif
namespace clang { namespace clang {
class ASTConsumer; class ASTConsumer;
} }
@@ -59,22 +45,22 @@ public:
SourceLocationsContainer takeSourceLocations() SourceLocationsContainer takeSourceLocations()
{ {
return std::move(sourceLocations); return std::move(m_sourceLocations);
} }
void setUnifiedSymbolResolutions(std::vector<USRName> &&unifiedSymbolResolutions) void setUnifiedSymbolResolutions(std::vector<USRName> &&unifiedSymbolResolutions)
{ {
unifiedSymbolResolutions_ = std::move(unifiedSymbolResolutions); m_unifiedSymbolResolutions_ = std::move(unifiedSymbolResolutions);
} }
const std::vector<USRName> &unifiedSymbolResolutions() const const std::vector<USRName> &unifiedSymbolResolutions() const
{ {
return unifiedSymbolResolutions_; return m_unifiedSymbolResolutions_;
} }
private: private:
ClangBackEnd::SourceLocationsContainer sourceLocations; ClangBackEnd::SourceLocationsContainer m_sourceLocations;
std::vector<USRName> unifiedSymbolResolutions_; std::vector<USRName> m_unifiedSymbolResolutions_;
}; };
} // namespace ClangBackEnd } // namespace ClangBackEnd

View File

@@ -0,0 +1,53 @@
/****************************************************************************
**
** Copyright (C) 2017 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 "symbolscollector.h"
namespace ClangBackEnd {
SymbolsCollector::SymbolsCollector(FilePathCache<> &filePathCache)
: m_collectSymbolsAction(filePathCache)
{
}
void SymbolsCollector::collectSymbols()
{
auto tool = createTool();
tool.run(clang::tooling::newFrontendActionFactory(&m_collectSymbolsAction,
&m_collectMacrosSourceFileCallbacks).get());
}
const SymbolEntries &SymbolsCollector::symbols() const
{
return m_collectSymbolsAction.symbols();
}
const SourceLocationEntries &SymbolsCollector::sourceLocations() const
{
return m_collectSymbolsAction.sourceLocations();
}
} // namespace ClangBackEnd

View File

@@ -0,0 +1,51 @@
/****************************************************************************
**
** Copyright (C) 2017 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 "clangtool.h"
#include "collectmacrossourcefilecallbacks.h"
#include "collectsymbolsaction.h"
#include "symbolentry.h"
#include "stringcache.h"
namespace ClangBackEnd {
class SymbolsCollector: public ClangTool
{
public:
SymbolsCollector(FilePathCache<> &filePathCache);
void collectSymbols();
const SymbolEntries &symbols() const;
const SourceLocationEntries &sourceLocations() const;
private:
CollectSymbolsAction m_collectSymbolsAction;
CollectMacrosSourceFileCallbacks m_collectMacrosSourceFileCallbacks;
};
} // namespace ClangBackEnd

View File

@@ -0,0 +1,15 @@
void function();
void function();
void function(int x);
void function()
{
int x;
x = 4;
int y = 4;
y = x + 3;
}
void f()
{
function();
}

View File

@@ -0,0 +1,162 @@
/****************************************************************************
**
** Copyright (C) 2017 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 "googletest.h"
#include <symbolscollector.h>
#include "filesystem-utilities.h"
using testing::PrintToString;
using testing::AllOf;
using testing::Contains;
using testing::Not;
using testing::Field;
using testing::Key;
using testing::Pair;
using testing::Value;
using testing::_;
using ClangBackEnd::SourceLocationEntry;
using ClangBackEnd::SymbolEntry;
using ClangBackEnd::SymbolType;
namespace {
class SymbolsCollector : public testing::Test
{
protected:
uint stringId(Utils::SmallStringView string)
{
return filePathCache.stringId(string);
}
uint symbolIdForSymbolName(const Utils::SmallString &symbolName);
protected:
ClangBackEnd::FilePathCache<> filePathCache;
ClangBackEnd::SymbolsCollector collector{filePathCache};
};
TEST_F(SymbolsCollector, CollectSymbolName)
{
collector.addFile(TESTDATA_DIR, "symbolscollector_simple.cpp", "", {"cc", TESTDATA_DIR"/symbolscollector_simple.cpp"});
collector.collectSymbols();
ASSERT_THAT(collector.symbols(),
Contains(
Pair(_, Field(&SymbolEntry::symbolName, "x"))));
}
TEST_F(SymbolsCollector, SymbolMatchesLocation)
{
collector.addFile(TESTDATA_DIR, "symbolscollector_simple.cpp", "", {"cc", TESTDATA_DIR"/symbolscollector_simple.cpp"});
collector.collectSymbols();
ASSERT_THAT(collector.sourceLocations(),
Contains(
AllOf(Field(&SourceLocationEntry::symbolId, symbolIdForSymbolName("function")),
Field(&SourceLocationEntry::line, 1),
Field(&SourceLocationEntry::column, 6))));
}
TEST_F(SymbolsCollector, OtherSymboldMatchesLocation)
{
collector.addFile(TESTDATA_DIR, "symbolscollector_simple.cpp", "", {"cc", TESTDATA_DIR"/symbolscollector_simple.cpp"});
collector.collectSymbols();
ASSERT_THAT(collector.sourceLocations(),
Contains(
AllOf(Field(&SourceLocationEntry::symbolId, symbolIdForSymbolName("function")),
Field(&SourceLocationEntry::line, 2),
Field(&SourceLocationEntry::column, 6))));
}
TEST_F(SymbolsCollector, CollectFilePath)
{
collector.addFile(TESTDATA_DIR, "symbolscollector_simple.cpp", "", {"cc", TESTDATA_DIR"/symbolscollector_simple.cpp"});
collector.collectSymbols();
ASSERT_THAT(collector.sourceLocations(),
Contains(
AllOf(Field(&SourceLocationEntry::fileId,
stringId(TESTDATA_DIR"/symbolscollector_simple.cpp")),
Field(&SourceLocationEntry::symbolType, SymbolType::Declaration))));
}
TEST_F(SymbolsCollector, CollectLineColumn)
{
collector.addFile(TESTDATA_DIR, "symbolscollector_simple.cpp", "", {"cc", TESTDATA_DIR"/symbolscollector_simple.cpp"});
collector.collectSymbols();
ASSERT_THAT(collector.sourceLocations(),
Contains(
AllOf(Field(&SourceLocationEntry::line, 1),
Field(&SourceLocationEntry::column, 6),
Field(&SourceLocationEntry::symbolType, SymbolType::Declaration))));
}
TEST_F(SymbolsCollector, CollectReference)
{
collector.addFile(TESTDATA_DIR, "symbolscollector_simple.cpp", "", {"cc", TESTDATA_DIR"/symbolscollector_simple.cpp"});
collector.collectSymbols();
ASSERT_THAT(collector.sourceLocations(),
Contains(
AllOf(Field(&SourceLocationEntry::line, 14),
Field(&SourceLocationEntry::column, 5),
Field(&SourceLocationEntry::symbolType, SymbolType::DeclarationReference))));
}
TEST_F(SymbolsCollector, ReferencedSymboldMatchesLocation)
{
collector.addFile(TESTDATA_DIR, "symbolscollector_simple.cpp", "", {"cc", TESTDATA_DIR"/symbolscollector_simple.cpp"});
collector.collectSymbols();
ASSERT_THAT(collector.sourceLocations(),
Contains(
AllOf(Field(&SourceLocationEntry::symbolId, symbolIdForSymbolName("function")),
Field(&SourceLocationEntry::line, 14),
Field(&SourceLocationEntry::column, 5))));
}
uint SymbolsCollector::symbolIdForSymbolName(const Utils::SmallString &symbolName)
{
for (const auto &entry : collector.symbols()) {
if (entry.second.symbolName == symbolName)
return entry.first;
}
return 0;
}
}

View File

@@ -68,7 +68,7 @@ SOURCES += \
spydummy.cpp \ spydummy.cpp \
stringcache-test.cpp \ stringcache-test.cpp \
unittests-main.cpp \ unittests-main.cpp \
utf8-test.cpp \ utf8-test.cpp
!isEmpty(LIBCLANG_LIBS) { !isEmpty(LIBCLANG_LIBS) {
SOURCES += \ SOURCES += \
@@ -144,6 +144,7 @@ SOURCES += \
refactoringengine-test.cpp \ refactoringengine-test.cpp \
refactoringserver-test.cpp \ refactoringserver-test.cpp \
sourcerangeextractor-test.cpp \ sourcerangeextractor-test.cpp \
symbolscollector-test.cpp \
symbolfinder-test.cpp \ symbolfinder-test.cpp \
testclangtool.cpp \ testclangtool.cpp \
} }