forked from qt-creator/qt-creator
Clang: On the road to update and preprocessor support
This patch has grown in a quite big change set and it is really hard to divide it in different parts. V2::ProjectPartContainer is now using FileIds instead of file paths. This cleans code up because it is a big step in the direction that internally only file ids are used. But it is depending on the file cache, so the file cache has to be provided as an argument. There is now an interface for transactions too which are ease the testing of them and enables the support of preprocessor. It adds macros as symbols and is saving used macros. The used macro support is enabling update improvements because only if a changed macro is used it needs to be recompiled. This is still in flux and can be changed in later patches. Change-Id: I492a2c9af1201d40fdd9f46a0045f7878bbbaa3d Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
This commit is contained in:
@@ -12,7 +12,10 @@ HEADERS += \
|
||||
$$PWD/storagesqlitestatementfactory.h \
|
||||
$$PWD/symbolindexing.h \
|
||||
$$PWD/symbolindexinginterface.h \
|
||||
$$PWD/collectmacrospreprocessorcallbacks.h
|
||||
$$PWD/collectmacrospreprocessorcallbacks.h \
|
||||
$$PWD/projectpartentry.h \
|
||||
$$PWD/useddefines.h \
|
||||
$$PWD/symbolsvisitorbase.h
|
||||
|
||||
!isEmpty(LIBTOOLING_LIBS) {
|
||||
SOURCES += \
|
||||
@@ -58,4 +61,5 @@ HEADERS += \
|
||||
SOURCES += \
|
||||
$$PWD/sourcerangefilter.cpp \
|
||||
$$PWD/symbolindexer.cpp \
|
||||
$$PWD/symbolentry.cpp
|
||||
$$PWD/symbolentry.cpp \
|
||||
$$PWD/symbolstorageinterface.cpp
|
||||
|
||||
@@ -58,6 +58,19 @@ void ClangTool::addFile(std::string &&directory,
|
||||
m_sourceFilePaths.push_back(fileContent.filePath);
|
||||
}
|
||||
|
||||
void ClangTool::addFiles(const FilePaths &filePaths, const Utils::SmallStringVector &arguments)
|
||||
{
|
||||
for (const FilePath &filePath : filePaths) {
|
||||
std::vector<std::string> commandLine(arguments.begin(), arguments.end());
|
||||
commandLine.push_back(std::string(filePath.name()));
|
||||
|
||||
addFile(filePath.directory(),
|
||||
filePath.name(),
|
||||
{},
|
||||
std::move(commandLine));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
void ClangTool::addFiles(const Container &filePaths,
|
||||
const Utils::SmallStringVector &arguments)
|
||||
|
||||
@@ -84,6 +84,9 @@ public:
|
||||
template <typename Container>
|
||||
void addFiles(const Container &filePaths,
|
||||
const Utils::SmallStringVector &arguments);
|
||||
void addFiles(const FilePaths &filePaths,
|
||||
const Utils::SmallStringVector &arguments);
|
||||
|
||||
|
||||
void addUnsavedFiles(const V2::FileContainers &unsavedFiles);
|
||||
|
||||
|
||||
@@ -25,7 +25,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "symbolsvisitorbase.h"
|
||||
#include "sourcelocationsutils.h"
|
||||
#include "sourcelocationentry.h"
|
||||
#include "symbolentry.h"
|
||||
#include "useddefines.h"
|
||||
|
||||
#include <filepath.h>
|
||||
#include <filepathid.h>
|
||||
@@ -36,14 +40,21 @@
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
class CollectMacrosPreprocessorCallbacks final : public clang::PPCallbacks
|
||||
class CollectMacrosPreprocessorCallbacks final : public clang::PPCallbacks,
|
||||
public SymbolsVisitorBase
|
||||
{
|
||||
public:
|
||||
CollectMacrosPreprocessorCallbacks(FilePathIds &sourceFiles,
|
||||
FilePathCachingInterface &filePathCache)
|
||||
: m_sourceFiles(sourceFiles),
|
||||
m_filePathCache(filePathCache)
|
||||
|
||||
CollectMacrosPreprocessorCallbacks(SymbolEntries &symbolEntries,
|
||||
SourceLocationEntries &sourceLocationEntries,
|
||||
FilePathIds &sourceFiles,
|
||||
UsedDefines &usedDefines,
|
||||
FilePathCachingInterface &filePathCache,
|
||||
const clang::SourceManager &sourceManager)
|
||||
: SymbolsVisitorBase(filePathCache, sourceManager),
|
||||
m_symbolEntries(symbolEntries),
|
||||
m_sourceLocationEntries(sourceLocationEntries),
|
||||
m_sourceFiles(sourceFiles),
|
||||
m_usedDefines(usedDefines)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -70,6 +81,125 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
void Ifndef(clang::SourceLocation,
|
||||
const clang::Token ¯oNameToken,
|
||||
const clang::MacroDefinition ¯oDefinition) override
|
||||
{
|
||||
addUsedDefine(macroNameToken, macroDefinition);
|
||||
addMacroAsSymbol(macroNameToken,
|
||||
firstMacroInfo(macroDefinition.getLocalDirective()),
|
||||
SymbolType::MacroUsage);
|
||||
}
|
||||
|
||||
void Ifdef(clang::SourceLocation,
|
||||
const clang::Token ¯oNameToken,
|
||||
const clang::MacroDefinition ¯oDefinition) override
|
||||
{
|
||||
addUsedDefine( macroNameToken, macroDefinition);
|
||||
addMacroAsSymbol(macroNameToken,
|
||||
firstMacroInfo(macroDefinition.getLocalDirective()),
|
||||
SymbolType::MacroUsage);
|
||||
}
|
||||
|
||||
void Defined(const clang::Token ¯oNameToken,
|
||||
const clang::MacroDefinition ¯oDefinition,
|
||||
clang::SourceRange) override
|
||||
{
|
||||
addUsedDefine(macroNameToken, macroDefinition);
|
||||
addMacroAsSymbol(macroNameToken,
|
||||
firstMacroInfo(macroDefinition.getLocalDirective()),
|
||||
SymbolType::MacroUsage);
|
||||
}
|
||||
|
||||
void MacroDefined(const clang::Token ¯oNameToken,
|
||||
const clang::MacroDirective *macroDirective) override
|
||||
{
|
||||
addMacroAsSymbol(macroNameToken,
|
||||
firstMacroInfo(macroDirective),
|
||||
SymbolType::MacroDefinition);
|
||||
}
|
||||
|
||||
void MacroUndefined(const clang::Token ¯oNameToken,
|
||||
const clang::MacroDefinition ¯oDefinition,
|
||||
const clang::MacroDirective *) override
|
||||
{
|
||||
addMacroAsSymbol(macroNameToken,
|
||||
firstMacroInfo(macroDefinition.getLocalDirective()),
|
||||
SymbolType::MacroUndefinition);
|
||||
}
|
||||
|
||||
void MacroExpands(const clang::Token ¯oNameToken,
|
||||
const clang::MacroDefinition ¯oDefinition,
|
||||
clang::SourceRange,
|
||||
const clang::MacroArgs *) override
|
||||
{
|
||||
addUsedDefine(macroNameToken, macroDefinition);
|
||||
addMacroAsSymbol(macroNameToken,
|
||||
firstMacroInfo(macroDefinition.getLocalDirective()),
|
||||
SymbolType::MacroUsage);
|
||||
}
|
||||
|
||||
void addUsedDefine(const clang::Token ¯oNameToken,
|
||||
const clang::MacroDefinition ¯oDefinition)
|
||||
{
|
||||
clang::MacroInfo *macroInfo = macroDefinition.getMacroInfo();
|
||||
if (macroInfo) {
|
||||
UsedDefine usedDefine{macroNameToken.getIdentifierInfo()->getName(),
|
||||
filePathId(macroNameToken.getLocation())};
|
||||
auto found = std::lower_bound(m_usedDefines.begin(),
|
||||
m_usedDefines.end(), usedDefine);
|
||||
|
||||
if (found == m_usedDefines.end() || *found != usedDefine)
|
||||
m_usedDefines.insert(found, std::move(usedDefine));
|
||||
}
|
||||
}
|
||||
|
||||
static const clang::MacroInfo *firstMacroInfo(const clang::MacroDirective *macroDirective)
|
||||
{
|
||||
if (macroDirective) {
|
||||
const clang::MacroDirective *previousDirective = macroDirective;
|
||||
do {
|
||||
macroDirective = previousDirective;
|
||||
previousDirective = macroDirective->getPrevious();
|
||||
} while (previousDirective);
|
||||
|
||||
return macroDirective->getMacroInfo();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void addMacroAsSymbol(const clang::Token ¯oNameToken,
|
||||
const clang::MacroInfo *macroInfo,
|
||||
SymbolType symbolType)
|
||||
{
|
||||
clang::SourceLocation sourceLocation = macroNameToken.getLocation();
|
||||
if (macroInfo && sourceLocation.isFileID()) {
|
||||
FilePathId fileId = filePathId(sourceLocation);
|
||||
auto macroName = macroNameToken.getIdentifierInfo()->getName();
|
||||
if (fileId.isValid()) {
|
||||
auto macroName = macroNameToken.getIdentifierInfo()->getName();
|
||||
SymbolIndex globalId = toSymbolIndex(macroInfo);
|
||||
|
||||
auto found = m_symbolEntries.find(globalId);
|
||||
if (found == m_symbolEntries.end()) {
|
||||
Utils::optional<Utils::PathString> usr = generateUSR(macroName, sourceLocation);
|
||||
if (usr) {
|
||||
m_symbolEntries.emplace(std::piecewise_construct,
|
||||
std::forward_as_tuple(globalId),
|
||||
std::forward_as_tuple(std::move(usr.value()), macroName));
|
||||
}
|
||||
}
|
||||
|
||||
m_sourceLocationEntries.emplace_back(globalId,
|
||||
fileId,
|
||||
lineColum(sourceLocation),
|
||||
symbolType);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void addSourceFile(const clang::FileEntry *file)
|
||||
{
|
||||
auto filePathId = m_filePathCache.filePathId(
|
||||
@@ -82,8 +212,10 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
SymbolEntries &m_symbolEntries;
|
||||
SourceLocationEntries &m_sourceLocationEntries;
|
||||
FilePathIds &m_sourceFiles;
|
||||
FilePathCachingInterface &m_filePathCache;
|
||||
UsedDefines &m_usedDefines;
|
||||
bool m_skipInclude = false;
|
||||
};
|
||||
|
||||
|
||||
@@ -33,8 +33,12 @@ namespace ClangBackEnd {
|
||||
|
||||
bool CollectMacrosSourceFileCallbacks::handleBeginSource(clang::CompilerInstance &compilerInstance)
|
||||
{
|
||||
auto callbacks = std::make_unique<CollectMacrosPreprocessorCallbacks>(m_sourceFiles,
|
||||
m_filePathCache);
|
||||
auto callbacks = std::make_unique<CollectMacrosPreprocessorCallbacks>(m_symbolEntries,
|
||||
m_sourceLocationEntries,
|
||||
m_sourceFiles,
|
||||
m_usedDefines,
|
||||
m_filePathCache,
|
||||
compilerInstance.getSourceManager());
|
||||
|
||||
compilerInstance.getPreprocessorPtr()->addPPCallbacks(std::move(callbacks));
|
||||
|
||||
|
||||
@@ -25,6 +25,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sourcelocationentry.h"
|
||||
#include "symbolentry.h"
|
||||
#include "useddefines.h"
|
||||
|
||||
#include <filepathcachinginterface.h>
|
||||
|
||||
#include <clang/Tooling/Tooling.h>
|
||||
@@ -34,8 +38,12 @@ namespace ClangBackEnd {
|
||||
class CollectMacrosSourceFileCallbacks : public clang::tooling::SourceFileCallbacks
|
||||
{
|
||||
public:
|
||||
CollectMacrosSourceFileCallbacks(FilePathCachingInterface &filePathCache)
|
||||
: m_filePathCache(filePathCache)
|
||||
CollectMacrosSourceFileCallbacks(SymbolEntries &symbolEntries,
|
||||
SourceLocationEntries &sourceLocationEntries,
|
||||
FilePathCachingInterface &filePathCache)
|
||||
: m_symbolEntries(symbolEntries),
|
||||
m_sourceLocationEntries(sourceLocationEntries),
|
||||
m_filePathCache(filePathCache)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -46,14 +54,9 @@ public:
|
||||
return m_sourceFiles;
|
||||
}
|
||||
|
||||
void addSourceFiles(const Utils::PathStringVector &filePaths)
|
||||
void addSourceFiles(const FilePathIds &filePathIds)
|
||||
{
|
||||
std::transform(filePaths.begin(),
|
||||
filePaths.end(),
|
||||
std::back_inserter(m_sourceFiles),
|
||||
[&] (const Utils::PathString &filePath) {
|
||||
return m_filePathCache.filePathId(FilePathView{filePath});
|
||||
});
|
||||
m_sourceFiles = filePathIds;
|
||||
}
|
||||
|
||||
void clearSourceFiles()
|
||||
@@ -61,8 +64,16 @@ public:
|
||||
m_sourceFiles.clear();
|
||||
}
|
||||
|
||||
const UsedDefines &usedDefines() const
|
||||
{
|
||||
return m_usedDefines;
|
||||
}
|
||||
|
||||
private:
|
||||
FilePathIds m_sourceFiles;
|
||||
UsedDefines m_usedDefines;
|
||||
SymbolEntries &m_symbolEntries;
|
||||
SourceLocationEntries &m_sourceLocationEntries;
|
||||
FilePathCachingInterface &m_filePathCache;
|
||||
};
|
||||
|
||||
|
||||
@@ -42,8 +42,12 @@ namespace ClangBackEnd {
|
||||
class CollectSymbolsAction
|
||||
{
|
||||
public:
|
||||
CollectSymbolsAction(FilePathCachingInterface &filePathCache)
|
||||
: m_filePathCache(filePathCache)
|
||||
CollectSymbolsAction(SymbolEntries &symbolEntries,
|
||||
SourceLocationEntries &sourceLocationEntries,
|
||||
FilePathCachingInterface &filePathCache)
|
||||
: m_symbolEntries(symbolEntries),
|
||||
m_sourceLocationEntries(sourceLocationEntries),
|
||||
m_filePathCache(filePathCache)
|
||||
{}
|
||||
|
||||
std::unique_ptr<clang::ASTConsumer> newASTConsumer();
|
||||
@@ -63,15 +67,9 @@ public:
|
||||
return m_sourceLocationEntries;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
m_symbolEntries.clear();
|
||||
m_sourceLocationEntries.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
SymbolEntries m_symbolEntries;
|
||||
SourceLocationEntries m_sourceLocationEntries;
|
||||
SymbolEntries &m_symbolEntries;
|
||||
SourceLocationEntries &m_sourceLocationEntries;
|
||||
FilePathCachingInterface &m_filePathCache;
|
||||
|
||||
};
|
||||
|
||||
@@ -25,32 +25,30 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "symbolentry.h"
|
||||
#include "sourcelocationentry.h"
|
||||
|
||||
#include <filepathcachinginterface.h>
|
||||
#include "sourcelocationsutils.h"
|
||||
#include "symbolentry.h"
|
||||
#include "symbolsvisitorbase.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 {
|
||||
|
||||
class CollectSymbolsASTVisitor : public clang::RecursiveASTVisitor<CollectSymbolsASTVisitor>
|
||||
class CollectSymbolsASTVisitor : public clang::RecursiveASTVisitor<CollectSymbolsASTVisitor>,
|
||||
public SymbolsVisitorBase
|
||||
{
|
||||
public:
|
||||
CollectSymbolsASTVisitor(SymbolEntries &symbolEntries,
|
||||
SourceLocationEntries &sourceLocationEntries,
|
||||
FilePathCachingInterface &filePathCache,
|
||||
const clang::SourceManager &sourceManager)
|
||||
: m_symbolEntries(symbolEntries),
|
||||
m_sourceLocationEntries(sourceLocationEntries),
|
||||
m_filePathCache(filePathCache),
|
||||
m_sourceManager(sourceManager)
|
||||
: SymbolsVisitorBase(filePathCache, sourceManager),
|
||||
m_symbolEntries(symbolEntries),
|
||||
m_sourceLocationEntries(sourceLocationEntries)
|
||||
{}
|
||||
|
||||
bool shouldVisitTemplateInstantiations() const
|
||||
@@ -68,9 +66,12 @@ public:
|
||||
|
||||
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), symbolName(declaration)));
|
||||
Utils::optional<Utils::PathString> usr = generateUSR(declaration);
|
||||
if (usr) {
|
||||
m_symbolEntries.emplace(std::piecewise_construct,
|
||||
std::forward_as_tuple(globalId),
|
||||
std::forward_as_tuple(std::move(usr.value()), symbolName(declaration)));
|
||||
}
|
||||
}
|
||||
|
||||
m_sourceLocationEntries.emplace_back(globalId,
|
||||
@@ -95,57 +96,15 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
FilePathId filePathId(clang::SourceLocation sourceLocation)
|
||||
{
|
||||
uint clangFileId = m_sourceManager.getFileID(sourceLocation).getHashValue();
|
||||
|
||||
auto found = m_filePathIndices.find(clangFileId);
|
||||
|
||||
if (found != m_filePathIndices.end())
|
||||
return found->second;
|
||||
|
||||
auto filePath = m_sourceManager.getFilename(sourceLocation);
|
||||
|
||||
FilePathId filePathId = m_filePathCache.filePathId(FilePath::fromNativeFilePath(filePath));
|
||||
|
||||
m_filePathIndices.emplace(clangFileId, filePathId);
|
||||
|
||||
return filePathId;
|
||||
}
|
||||
|
||||
LineColumn lineColum(clang::SourceLocation sourceLocation)
|
||||
{
|
||||
return {m_sourceManager.getSpellingLineNumber(sourceLocation),
|
||||
m_sourceManager.getSpellingColumnNumber(sourceLocation)};
|
||||
}
|
||||
|
||||
Utils::PathString generateUSR(const clang::Decl *declaration)
|
||||
{
|
||||
llvm::SmallVector<char, 128> usr;
|
||||
|
||||
clang::index::generateUSRForDecl(declaration, usr);
|
||||
|
||||
return {usr.data(), usr.size()};
|
||||
}
|
||||
|
||||
Utils::SmallString symbolName(const clang::NamedDecl *declaration)
|
||||
{
|
||||
const llvm::StringRef symbolName{declaration->getName()};
|
||||
|
||||
return {symbolName.data(), symbolName.size()};
|
||||
}
|
||||
|
||||
static SymbolIndex toSymbolIndex(const void *pointer)
|
||||
{
|
||||
return SymbolIndex(reinterpret_cast<std::uintptr_t>(pointer));
|
||||
return declaration->getName();
|
||||
}
|
||||
|
||||
private:
|
||||
SymbolEntries &m_symbolEntries;
|
||||
std::unordered_map<uint, FilePathId> m_filePathIndices;
|
||||
SourceLocationEntries &m_sourceLocationEntries;
|
||||
FilePathCachingInterface &m_filePathCache;
|
||||
const clang::SourceManager &m_sourceManager;
|
||||
};
|
||||
|
||||
|
||||
|
||||
58
src/tools/clangrefactoringbackend/source/projectpartentry.h
Normal file
58
src/tools/clangrefactoringbackend/source/projectpartentry.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 <filepathid.h>
|
||||
|
||||
#include <utils/smallstringvector.h>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
class ProjectPartEntry
|
||||
{
|
||||
public:
|
||||
ProjectPartEntry(Utils::SmallStringView projectPathName,
|
||||
const FilePathIds &filePathIds,
|
||||
Utils::SmallStringVector &&compilerArguments)
|
||||
: projectPathName(projectPathName), filePathIds(filePathIds), compilerArguments(compilerArguments)
|
||||
{}
|
||||
|
||||
friend bool operator==(const ProjectPartEntry &first, const ProjectPartEntry &second)
|
||||
{
|
||||
return first.projectPathName == second.projectPathName
|
||||
&& first.filePathIds == second.filePathIds
|
||||
&& first.compilerArguments == second.compilerArguments;
|
||||
}
|
||||
|
||||
public:
|
||||
Utils::PathString projectPathName;
|
||||
FilePathIds filePathIds;
|
||||
Utils::SmallStringVector compilerArguments;
|
||||
};
|
||||
|
||||
using ProjectPartEntries = std::vector<ProjectPartEntry>;
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
@@ -27,6 +27,8 @@
|
||||
|
||||
#include <filepathid.h>
|
||||
|
||||
#include <utils/linecolumn.h>
|
||||
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
@@ -37,19 +39,10 @@ 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;
|
||||
DeclarationReference,
|
||||
MacroDefinition,
|
||||
MacroUsage,
|
||||
MacroUndefinition
|
||||
};
|
||||
|
||||
using SymbolIndex = long long;
|
||||
@@ -59,27 +52,24 @@ class SourceLocationEntry
|
||||
public:
|
||||
SourceLocationEntry(SymbolIndex symbolId,
|
||||
FilePathId filePathId,
|
||||
LineColumn lineColumn,
|
||||
Utils::LineColumn lineColumn,
|
||||
SymbolType symbolType)
|
||||
: symbolId(symbolId),
|
||||
filePathId(filePathId),
|
||||
line(lineColumn.line),
|
||||
column(lineColumn.column),
|
||||
lineColumn(lineColumn),
|
||||
symbolType(symbolType)
|
||||
{}
|
||||
|
||||
SymbolIndex symbolId = 0;
|
||||
FilePathId filePathId;
|
||||
uint line = 0;
|
||||
uint column = 0;
|
||||
Utils::LineColumn lineColumn;
|
||||
SymbolType symbolType;
|
||||
|
||||
friend bool operator==(const SourceLocationEntry &first, const SourceLocationEntry &second)
|
||||
{
|
||||
return first.symbolId == second.symbolId
|
||||
&& first.filePathId == second.filePathId
|
||||
&& first.line == second.line
|
||||
&& first.column == second.column
|
||||
&& first.lineColumn == second.lineColumn
|
||||
&& first.symbolType == second.symbolType;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -57,7 +57,7 @@ public:
|
||||
table.addIndex({usrColumn, symbolNameColumn});
|
||||
table.addIndex({symbolIdColumn});
|
||||
|
||||
Sqlite::ImmediateTransaction<DatabaseType> transaction(database);
|
||||
Sqlite::ImmediateTransaction transaction(database);
|
||||
table.initialize(database);
|
||||
transaction.commit();
|
||||
|
||||
@@ -76,7 +76,7 @@ public:
|
||||
const Sqlite::Column &sourceIdColumn = table.addColumn("sourceId", Sqlite::ColumnType::Integer);
|
||||
table.addIndex({sourceIdColumn});
|
||||
|
||||
Sqlite::ImmediateTransaction<DatabaseType> transaction(database);
|
||||
Sqlite::ImmediateTransaction transaction(database);
|
||||
table.initialize(database);
|
||||
transaction.commit();
|
||||
|
||||
@@ -128,6 +128,30 @@ public:
|
||||
"DELETE FROM newLocations",
|
||||
database
|
||||
};
|
||||
WriteStatement insertProjectPart{
|
||||
"INSERT OR IGNORE INTO projectParts(projectPartName, compilerArguments) VALUES (?,?)",
|
||||
database
|
||||
};
|
||||
WriteStatement updateProjectPart{
|
||||
"UPDATE projectParts SET compilerArguments = ? WHERE projectPartName = ?",
|
||||
database
|
||||
};
|
||||
ReadStatement getProjectPartId{
|
||||
"SELECT projectPartId FROM projectParts WHERE projectPartName = ?",
|
||||
database
|
||||
};
|
||||
WriteStatement deleteAllProjectPartsSourcesWithProjectPartId{
|
||||
"DELETE FROM projectPartsSources WHERE projectPartId = ?",
|
||||
database
|
||||
};
|
||||
WriteStatement insertProjectPartSources{
|
||||
"INSERT INTO projectPartsSources(projectPartId, sourceId) VALUES (?,?)",
|
||||
database
|
||||
};
|
||||
ReadStatement getCompileArgumentsForFileId{
|
||||
"SELECT compilerArguments FROM projectParts WHERE projectPartId = (SELECT projectPartId FROM projectPartsSources WHERE sourceId = ?)",
|
||||
database
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
||||
@@ -29,28 +29,47 @@ namespace ClangBackEnd {
|
||||
|
||||
SymbolIndexer::SymbolIndexer(SymbolsCollectorInterface &symbolsCollector,
|
||||
SymbolStorageInterface &symbolStorage,
|
||||
ClangPathWatcherInterface &pathWatcher)
|
||||
ClangPathWatcherInterface &pathWatcher,
|
||||
FilePathCachingInterface &filePathCache,
|
||||
Sqlite::TransactionInterface &transactionInterface)
|
||||
: m_symbolsCollector(symbolsCollector),
|
||||
m_symbolStorage(symbolStorage),
|
||||
m_pathWatcher(pathWatcher)
|
||||
m_pathWatcher(pathWatcher),
|
||||
m_filePathCache(filePathCache),
|
||||
m_transactionInterface(transactionInterface)
|
||||
{
|
||||
pathWatcher.setNotifier(this);
|
||||
}
|
||||
|
||||
void SymbolIndexer::updateProjectParts(V2::ProjectPartContainers &&projectParts,
|
||||
V2::FileContainers &&generatedFiles)
|
||||
void SymbolIndexer::updateProjectParts(V2::ProjectPartContainers &&projectParts, V2::FileContainers &&generatedFiles)
|
||||
{
|
||||
for (V2::ProjectPartContainer &projectPart : projectParts)
|
||||
updateProjectPart(std::move(projectPart), generatedFiles);
|
||||
}
|
||||
|
||||
void SymbolIndexer::updateProjectPart(V2::ProjectPartContainer &&projectPart,
|
||||
const V2::FileContainers &generatedFiles)
|
||||
{
|
||||
m_symbolsCollector.clear();
|
||||
|
||||
for (const V2::ProjectPartContainer &projectPart : projectParts)
|
||||
m_symbolsCollector.addFiles(projectPart.sourcePaths(), projectPart.arguments());
|
||||
m_symbolsCollector.addFiles(projectPart.sourcePathIds(), projectPart.arguments());
|
||||
|
||||
m_symbolsCollector.addUnsavedFiles(generatedFiles);
|
||||
|
||||
m_symbolsCollector.collectSymbols();
|
||||
|
||||
Sqlite::ImmediateTransaction transaction{m_transactionInterface};
|
||||
|
||||
m_symbolStorage.addSymbolsAndSourceLocations(m_symbolsCollector.symbols(),
|
||||
m_symbolsCollector.sourceLocations());
|
||||
|
||||
m_symbolStorage.insertOrUpdateProjectPart(projectPart.projectPartId(),
|
||||
projectPart.arguments());
|
||||
m_symbolStorage.updateProjectPartSources(projectPart.projectPartId(),
|
||||
m_symbolsCollector.sourceFiles());
|
||||
|
||||
transaction.commit();
|
||||
|
||||
}
|
||||
|
||||
void SymbolIndexer::pathsWithIdsChanged(const Utils::SmallStringVector &)
|
||||
|
||||
@@ -39,10 +39,14 @@ class SymbolIndexer : public ClangPathWatcherNotifier
|
||||
public:
|
||||
SymbolIndexer(SymbolsCollectorInterface &symbolsCollector,
|
||||
SymbolStorageInterface &symbolStorage,
|
||||
ClangPathWatcherInterface &pathWatcher);
|
||||
ClangPathWatcherInterface &pathWatcher,
|
||||
FilePathCachingInterface &filePathCache,
|
||||
Sqlite::TransactionInterface &transactionInterface);
|
||||
|
||||
void updateProjectParts(V2::ProjectPartContainers &&projectParts,
|
||||
V2::FileContainers &&generatedFiles);
|
||||
void updateProjectPart(V2::ProjectPartContainer &&projectPart,
|
||||
const V2::FileContainers &generatedFiles);
|
||||
|
||||
void pathsWithIdsChanged(const Utils::SmallStringVector &ids) override;
|
||||
void pathsChanged(const FilePathIds &filePathIds) override;
|
||||
@@ -51,6 +55,8 @@ private:
|
||||
SymbolsCollectorInterface &m_symbolsCollector;
|
||||
SymbolStorageInterface &m_symbolStorage;
|
||||
ClangPathWatcherInterface &m_pathWatcher;
|
||||
FilePathCachingInterface &m_filePathCache;
|
||||
Sqlite::TransactionInterface &m_transactionInterface;
|
||||
};
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
||||
@@ -75,7 +75,7 @@ private:
|
||||
StatementFactory m_statementFactory;
|
||||
Storage m_symbolStorage{m_statementFactory, m_filePathCache};
|
||||
ClangPathWatcher<QFileSystemWatcher, QTimer> m_sourceWatcher{m_filePathCache};
|
||||
SymbolIndexer m_indexer{m_collector, m_symbolStorage, m_sourceWatcher};
|
||||
SymbolIndexer m_indexer{m_collector, m_symbolStorage, m_sourceWatcher, m_filePathCache, m_statementFactory.database};
|
||||
};
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
||||
@@ -28,15 +28,17 @@
|
||||
namespace ClangBackEnd {
|
||||
|
||||
SymbolsCollector::SymbolsCollector(FilePathCachingInterface &filePathCache)
|
||||
: m_collectSymbolsAction(filePathCache),
|
||||
m_collectMacrosSourceFileCallbacks(filePathCache)
|
||||
: m_collectSymbolsAction(m_symbolEntries, m_sourceLocationEntries, filePathCache),
|
||||
m_collectMacrosSourceFileCallbacks(m_symbolEntries, m_sourceLocationEntries, filePathCache),
|
||||
m_filePathCache(filePathCache)
|
||||
{
|
||||
}
|
||||
|
||||
void SymbolsCollector::addFiles(const Utils::PathStringVector &filePaths, const Utils::SmallStringVector &arguments)
|
||||
void SymbolsCollector::addFiles(const FilePathIds &filePathIds,
|
||||
const Utils::SmallStringVector &arguments)
|
||||
{
|
||||
m_clangTool.addFiles(filePaths, arguments);
|
||||
m_collectMacrosSourceFileCallbacks.addSourceFiles(filePaths);
|
||||
m_clangTool.addFiles(m_filePathCache.filePaths(filePathIds), arguments);
|
||||
m_collectMacrosSourceFileCallbacks.addSourceFiles(filePathIds);
|
||||
}
|
||||
|
||||
void SymbolsCollector::addUnsavedFiles(const V2::FileContainers &unsavedFiles)
|
||||
@@ -47,8 +49,8 @@ void SymbolsCollector::addUnsavedFiles(const V2::FileContainers &unsavedFiles)
|
||||
void SymbolsCollector::clear()
|
||||
{
|
||||
m_collectMacrosSourceFileCallbacks.clearSourceFiles();
|
||||
m_collectSymbolsAction.clear();
|
||||
|
||||
m_symbolEntries.clear();
|
||||
m_sourceLocationEntries.clear();
|
||||
m_clangTool = ClangTool();
|
||||
}
|
||||
|
||||
@@ -75,4 +77,9 @@ const FilePathIds &SymbolsCollector::sourceFiles() const
|
||||
return m_collectMacrosSourceFileCallbacks.sourceFiles();
|
||||
}
|
||||
|
||||
const UsedDefines &SymbolsCollector::usedDefines() const
|
||||
{
|
||||
return m_collectMacrosSourceFileCallbacks.usedDefines();
|
||||
}
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#include "collectmacrossourcefilecallbacks.h"
|
||||
#include "collectsymbolsaction.h"
|
||||
#include "symbolscollectorinterface.h"
|
||||
#include "symbolentry.h"
|
||||
|
||||
#include <filepathcachingfwd.h>
|
||||
|
||||
@@ -40,7 +39,7 @@ class SymbolsCollector : public SymbolsCollectorInterface
|
||||
public:
|
||||
SymbolsCollector(FilePathCachingInterface &filePathCache);
|
||||
|
||||
void addFiles(const Utils::PathStringVector &filePaths,
|
||||
void addFiles(const FilePathIds &filePathIds,
|
||||
const Utils::SmallStringVector &arguments) override;
|
||||
|
||||
void addUnsavedFiles(const V2::FileContainers &unsavedFiles) override;
|
||||
@@ -52,11 +51,15 @@ public:
|
||||
const SymbolEntries &symbols() const override;
|
||||
const SourceLocationEntries &sourceLocations() const override;
|
||||
const FilePathIds &sourceFiles() const override;
|
||||
const UsedDefines &usedDefines() const override;
|
||||
|
||||
private:
|
||||
ClangTool m_clangTool;
|
||||
SymbolEntries m_symbolEntries;
|
||||
SourceLocationEntries m_sourceLocationEntries;
|
||||
CollectSymbolsAction m_collectSymbolsAction;
|
||||
CollectMacrosSourceFileCallbacks m_collectMacrosSourceFileCallbacks;
|
||||
FilePathCachingInterface &m_filePathCache;
|
||||
};
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#include "symbolentry.h"
|
||||
#include "sourcelocationentry.h"
|
||||
#include "useddefines.h"
|
||||
|
||||
#include <filecontainerv2.h>
|
||||
|
||||
@@ -40,7 +41,7 @@ namespace ClangBackEnd {
|
||||
class SymbolsCollectorInterface
|
||||
{
|
||||
public:
|
||||
virtual void addFiles(const Utils::PathStringVector &filePaths,
|
||||
virtual void addFiles(const FilePathIds &filePathIds,
|
||||
const Utils::SmallStringVector &arguments) = 0;
|
||||
|
||||
virtual void addUnsavedFiles(const V2::FileContainers &unsavedFiles) = 0;
|
||||
@@ -52,6 +53,7 @@ public:
|
||||
virtual const SymbolEntries &symbols() const = 0;
|
||||
virtual const SourceLocationEntries &sourceLocations() const = 0;
|
||||
virtual const FilePathIds &sourceFiles() const = 0;
|
||||
virtual const UsedDefines &usedDefines() const = 0;
|
||||
};
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
||||
@@ -31,12 +31,14 @@
|
||||
#include <sqlitetransaction.h>
|
||||
#include <filepathcachingfwd.h>
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
template <typename StatementFactory>
|
||||
class SymbolStorage : public SymbolStorageInterface
|
||||
class SymbolStorage final : public SymbolStorageInterface
|
||||
{
|
||||
using Transaction = Sqlite::ImmediateTransaction<typename StatementFactory::DatabaseType>;
|
||||
using ReadStatement = typename StatementFactory::ReadStatementType;
|
||||
using WriteStatement = typename StatementFactory::WriteStatementType;
|
||||
using Database = typename StatementFactory::DatabaseType;
|
||||
@@ -52,8 +54,6 @@ public:
|
||||
void addSymbolsAndSourceLocations(const SymbolEntries &symbolEntries,
|
||||
const SourceLocationEntries &sourceLocations) override
|
||||
{
|
||||
Transaction transaction{m_statementFactory.database};
|
||||
|
||||
fillTemporarySymbolsTable(symbolEntries);
|
||||
fillTemporaryLocationsTable(sourceLocations);
|
||||
addNewSymbolsToSymbols();
|
||||
@@ -63,8 +63,50 @@ public:
|
||||
insertNewLocationsInLocations();
|
||||
deleteNewSymbolsTable();
|
||||
deleteNewLocationsTable();
|
||||
}
|
||||
|
||||
transaction.commit();
|
||||
void insertOrUpdateProjectPart(Utils::SmallStringView projectPartName,
|
||||
const Utils::SmallStringVector &commandLineArguments) override
|
||||
{
|
||||
m_statementFactory.database.setLastInsertedRowId(-1);
|
||||
|
||||
Utils::SmallString compilerArguementsAsJson = toJson(commandLineArguments);
|
||||
|
||||
WriteStatement &insertStatement = m_statementFactory.insertProjectPart;
|
||||
insertStatement.write(projectPartName, compilerArguementsAsJson);
|
||||
|
||||
if (m_statementFactory.database.lastInsertedRowId() == -1) {
|
||||
WriteStatement &updateStatement = m_statementFactory.updateProjectPart;
|
||||
updateStatement.write(compilerArguementsAsJson, projectPartName);
|
||||
}
|
||||
}
|
||||
|
||||
void updateProjectPartSources(Utils::SmallStringView projectPartName,
|
||||
const FilePathIds &sourceFilePathIds) override
|
||||
{
|
||||
ReadStatement &getProjectPartIdStatement = m_statementFactory.getProjectPartId;
|
||||
int projectPartId = getProjectPartIdStatement.template value<int>(projectPartName).value();
|
||||
|
||||
WriteStatement &deleteStatement = m_statementFactory.deleteAllProjectPartsSourcesWithProjectPartId;
|
||||
deleteStatement.write(projectPartId);
|
||||
|
||||
WriteStatement &insertStatement = m_statementFactory.insertProjectPartSources;
|
||||
for (const FilePathId &sourceFilePathId : sourceFilePathIds)
|
||||
insertStatement.write(projectPartId, sourceFilePathId.filePathId);
|
||||
}
|
||||
|
||||
static Utils::SmallString toJson(const Utils::SmallStringVector &strings)
|
||||
{
|
||||
QJsonDocument document;
|
||||
QJsonArray array;
|
||||
|
||||
std::transform(strings.begin(), strings.end(), std::back_inserter(array), [] (const auto &string) {
|
||||
return QJsonValue(string.data());
|
||||
});
|
||||
|
||||
document.setArray(array);
|
||||
|
||||
return document.toJson(QJsonDocument::Compact);
|
||||
}
|
||||
|
||||
void fillTemporarySymbolsTable(const SymbolEntries &symbolEntries)
|
||||
@@ -84,8 +126,8 @@ public:
|
||||
|
||||
for (const auto &locationsEntry : sourceLocations) {
|
||||
statement.write(locationsEntry.symbolId,
|
||||
locationsEntry.line,
|
||||
locationsEntry.column,
|
||||
locationsEntry.lineColumn.line,
|
||||
locationsEntry.lineColumn.column,
|
||||
locationsEntry.filePathId.filePathId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2018 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 "symbolstorageinterface.h"
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
SymbolStorageInterface::~SymbolStorageInterface()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
@@ -25,16 +25,28 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "projectpartentry.h"
|
||||
#include "sourcelocationentry.h"
|
||||
#include "symbolentry.h"
|
||||
|
||||
#include <sqlitetransaction.h>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
class SymbolStorageInterface
|
||||
{
|
||||
public:
|
||||
SymbolStorageInterface() = default;
|
||||
virtual ~SymbolStorageInterface();
|
||||
SymbolStorageInterface(const SymbolStorageInterface &) = delete;
|
||||
SymbolStorageInterface &operator=(const SymbolStorageInterface &) = delete;
|
||||
|
||||
virtual void addSymbolsAndSourceLocations(const SymbolEntries &symbolEntries,
|
||||
const SourceLocationEntries &sourceLocations) = 0;
|
||||
virtual void insertOrUpdateProjectPart(Utils::SmallStringView projectPartName,
|
||||
const Utils::SmallStringVector &commandLineArguments) = 0;
|
||||
virtual void updateProjectPartSources(Utils::SmallStringView projectPartName,
|
||||
const FilePathIds &sourceFilePathIds) = 0;
|
||||
};
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
||||
121
src/tools/clangrefactoringbackend/source/symbolsvisitorbase.h
Normal file
121
src/tools/clangrefactoringbackend/source/symbolsvisitorbase.h
Normal file
@@ -0,0 +1,121 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2018 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 "sourcelocationsutils.h"
|
||||
|
||||
#include <filepathcachinginterface.h>
|
||||
|
||||
#include <utils/linecolumn.h>
|
||||
#include <utils/optional.h>
|
||||
|
||||
#include <clang/Basic/SourceLocation.h>
|
||||
#include <clang/Basic/SourceManager.h>
|
||||
#include <clang/Index/USRGeneration.h>
|
||||
#include <llvm/ADT/SmallVector.h>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
class SymbolsVisitorBase
|
||||
{
|
||||
public:
|
||||
SymbolsVisitorBase(FilePathCachingInterface &filePathCache,
|
||||
const clang::SourceManager &sourceManager)
|
||||
: m_filePathCache(filePathCache),
|
||||
m_sourceManager(sourceManager)
|
||||
{}
|
||||
|
||||
FilePathId filePathId(clang::SourceLocation sourceLocation)
|
||||
{
|
||||
uint clangFileId = m_sourceManager.getFileID(sourceLocation).getHashValue();
|
||||
|
||||
auto found = m_filePathIndices.find(clangFileId);
|
||||
|
||||
if (found != m_filePathIndices.end())
|
||||
return found->second;
|
||||
|
||||
auto filePath = m_sourceManager.getFilename(sourceLocation);
|
||||
|
||||
if (filePath.size() > 0) {
|
||||
FilePathId filePathId = m_filePathCache.filePathId(FilePath::fromNativeFilePath(absolutePath(filePath)));
|
||||
|
||||
m_filePathIndices.emplace(clangFileId, filePathId);
|
||||
|
||||
return filePathId;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
Utils::LineColumn lineColum(clang::SourceLocation sourceLocation)
|
||||
{
|
||||
return {int(m_sourceManager.getSpellingLineNumber(sourceLocation)),
|
||||
int(m_sourceManager.getSpellingColumnNumber(sourceLocation))};
|
||||
}
|
||||
|
||||
static Utils::optional<Utils::PathString> generateUSR(const clang::Decl *declaration)
|
||||
{
|
||||
llvm::SmallVector<char, 128> usr;
|
||||
|
||||
Utils::optional<Utils::PathString> usrOptional;
|
||||
|
||||
bool wasNotWorking = clang::index::generateUSRForDecl(declaration, usr);
|
||||
|
||||
if (!wasNotWorking)
|
||||
usrOptional.emplace(usr.data(), usr.size());
|
||||
|
||||
return usrOptional;
|
||||
}
|
||||
|
||||
Utils::optional<Utils::PathString> generateUSR(clang::StringRef macroName,
|
||||
clang::SourceLocation sourceLocation)
|
||||
{
|
||||
llvm::SmallVector<char, 128> usr;
|
||||
|
||||
Utils::optional<Utils::PathString> usrOptional;
|
||||
|
||||
bool wasNotWorking = clang::index::generateUSRForMacro(macroName,
|
||||
sourceLocation,
|
||||
m_sourceManager,
|
||||
usr);
|
||||
|
||||
if (!wasNotWorking)
|
||||
usrOptional.emplace(usr.data(), usr.size());
|
||||
|
||||
return usrOptional;
|
||||
}
|
||||
|
||||
static SymbolIndex toSymbolIndex(const void *pointer)
|
||||
{
|
||||
return SymbolIndex(reinterpret_cast<std::uintptr_t>(pointer));
|
||||
}
|
||||
|
||||
protected:
|
||||
std::unordered_map<uint, FilePathId> m_filePathIndices;
|
||||
FilePathCachingInterface &m_filePathCache;
|
||||
const clang::SourceManager &m_sourceManager;
|
||||
};
|
||||
|
||||
} // namespace ClangBackend
|
||||
66
src/tools/clangrefactoringbackend/source/useddefines.h
Normal file
66
src/tools/clangrefactoringbackend/source/useddefines.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 <filepathid.h>
|
||||
|
||||
#include <utils/smallstring.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
class UsedDefine
|
||||
{
|
||||
public:
|
||||
UsedDefine(Utils::SmallStringView defineName, FilePathId filePathId)
|
||||
: defineName(defineName),
|
||||
filePathId(filePathId)
|
||||
{}
|
||||
|
||||
friend bool operator<(const UsedDefine &first, const UsedDefine &second)
|
||||
{
|
||||
return std::tie(first.filePathId, first.defineName)
|
||||
< std::tie(second.filePathId, second.defineName);
|
||||
}
|
||||
|
||||
friend bool operator==(const UsedDefine &first, const UsedDefine &second)
|
||||
{
|
||||
return first.filePathId == second.filePathId && first.defineName == second.defineName;
|
||||
}
|
||||
|
||||
friend bool operator!=(const UsedDefine &first, const UsedDefine &second)
|
||||
{
|
||||
return !(first == second);
|
||||
}
|
||||
public:
|
||||
Utils::SmallString defineName;
|
||||
FilePathId filePathId;
|
||||
};
|
||||
|
||||
using UsedDefines = std::vector<UsedDefine>;
|
||||
|
||||
} // ClangBackEnd
|
||||
Reference in New Issue
Block a user