diff options
Diffstat (limited to 'src/tools/clangrefactoringbackend')
18 files changed, 371 insertions, 189 deletions
diff --git a/src/tools/clangrefactoringbackend/source/CMakeLists.txt b/src/tools/clangrefactoringbackend/source/CMakeLists.txt index 213ce6ffd7..d43472fd60 100644 --- a/src/tools/clangrefactoringbackend/source/CMakeLists.txt +++ b/src/tools/clangrefactoringbackend/source/CMakeLists.txt @@ -6,7 +6,7 @@ add_qtc_library(clangrefactoringbackend_lib STATIC clangHandleCXX clangIndex clangLex clangSerialization clangTooling clangQuery ClangSupport - DEFINES CLANGSUPPORT_BUILD_LIB + PUBLIC_DEFINES CLANGSUPPORT_BUILD_LIB PUBLIC_INCLUDES ${CLANG_INCLUDE_DIRS} "../../clangpchmanagerbackend/source" @@ -20,6 +20,7 @@ add_qtc_library(clangrefactoringbackend_lib STATIC collectsymbolsaction.cpp collectsymbolsaction.h filestatus.h filestatuscache.cpp filestatuscache.h + filestatuspreprocessorcallbacks.cpp filestatuspreprocessorcallbacks.h findcursorusr.h findlocationsofusrs.h findusrforcursoraction.cpp findusrforcursoraction.h diff --git a/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri b/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri index fcac51f226..e7e83da788 100644 --- a/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri +++ b/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri @@ -2,6 +2,7 @@ INCLUDEPATH += $$PWD HEADERS += \ $$PWD/clangrefactoringbackend_global.h \ + $$PWD/filestatuspreprocessorcallbacks.h \ $$PWD/sourcerangefilter.h \ $$PWD/symbolindexer.h \ $$PWD/symbolentry.h \ @@ -64,6 +65,7 @@ HEADERS += \ } SOURCES += \ + $$PWD/filestatuspreprocessorcallbacks.cpp \ $$PWD/sourcerangefilter.cpp \ $$PWD/symbolindexer.cpp \ $$PWD/filestatuscache.cpp diff --git a/src/tools/clangrefactoringbackend/source/collectmacrospreprocessorcallbacks.h b/src/tools/clangrefactoringbackend/source/collectmacrospreprocessorcallbacks.h index 1d16b0f5e1..b0d59607e2 100644 --- a/src/tools/clangrefactoringbackend/source/collectmacrospreprocessorcallbacks.h +++ b/src/tools/clangrefactoringbackend/source/collectmacrospreprocessorcallbacks.h @@ -56,18 +56,16 @@ public: SourceDependencies &sourceDependencies, FilePathCachingInterface &filePathCache, const clang::SourceManager &sourceManager, - std::shared_ptr<clang::Preprocessor> &&preprocessor, - SourcesManager &sourcesManager) + std::shared_ptr<clang::Preprocessor> &&preprocessor) : CollectUsedMacrosAndSourcesPreprocessorCallbacksBase(usedMacros, filePathCache, sourceManager, - sourcesManager, std::move(preprocessor), sourceDependencies, sourceFiles, - fileStatuses), - m_symbolEntries(symbolEntries), - m_sourceLocationEntries(sourceLocationEntries) + fileStatuses) + , m_symbolEntries(symbolEntries) + , m_sourceLocationEntries(sourceLocationEntries) { } @@ -88,17 +86,15 @@ public: } void InclusionDirective(clang::SourceLocation hashLocation, - const clang::Token &/*includeToken*/, + const clang::Token & /*includeToken*/, llvm::StringRef /*fileName*/, bool /*isAngled*/, clang::CharSourceRange /*fileNameRange*/, const clang::FileEntry *file, llvm::StringRef /*searchPath*/, llvm::StringRef /*relativePath*/, - const clang::Module * /*imported*/ -#if LLVM_VERSION_MAJOR >= 7 - , clang::SrcMgr::CharacteristicKind /*fileType*/ -#endif + const clang::Module * /*imported*/, + clang::SrcMgr::CharacteristicKind /*fileType*/ ) override { if (!m_skipInclude && file) @@ -174,7 +170,6 @@ public: { filterOutHeaderGuards(); mergeUsedMacros(); - m_sourcesManager.updateModifiedTimeStamps(); } static const clang::MacroInfo *firstMacroInfo(const clang::MacroDirective *macroDirective) diff --git a/src/tools/clangrefactoringbackend/source/collectmacrossourcefilecallbacks.cpp b/src/tools/clangrefactoringbackend/source/collectmacrossourcefilecallbacks.cpp index d96fb05026..d360b727c4 100644 --- a/src/tools/clangrefactoringbackend/source/collectmacrossourcefilecallbacks.cpp +++ b/src/tools/clangrefactoringbackend/source/collectmacrossourcefilecallbacks.cpp @@ -34,16 +34,15 @@ namespace ClangBackEnd { bool CollectMacrosSourceFileCallbacks::handleBeginSource(clang::CompilerInstance &compilerInstance) { auto callbacks = std::make_unique<CollectMacrosPreprocessorCallbacks>( - m_symbolEntries, - m_sourceLocationEntries, - m_sourceFiles, - m_usedMacros, - m_fileStatuses, - m_sourceDependencies, - m_filePathCache, - compilerInstance.getSourceManager(), - compilerInstance.getPreprocessorPtr(), - m_sourcesManager); + m_symbolEntries, + m_sourceLocationEntries, + m_sourceFiles, + m_usedMacros, + m_fileStatuses, + m_sourceDependencies, + m_filePathCache, + compilerInstance.getSourceManager(), + compilerInstance.getPreprocessorPtr()); compilerInstance.getPreprocessorPtr()->addPPCallbacks(std::move(callbacks)); diff --git a/src/tools/clangrefactoringbackend/source/collectmacrossourcefilecallbacks.h b/src/tools/clangrefactoringbackend/source/collectmacrossourcefilecallbacks.h index 2392238106..16ba5a4f53 100644 --- a/src/tools/clangrefactoringbackend/source/collectmacrossourcefilecallbacks.h +++ b/src/tools/clangrefactoringbackend/source/collectmacrossourcefilecallbacks.h @@ -44,12 +44,10 @@ class CollectMacrosSourceFileCallbacks : public clang::tooling::SourceFileCallba public: CollectMacrosSourceFileCallbacks(SymbolEntries &symbolEntries, SourceLocationEntries &sourceLocationEntries, - FilePathCachingInterface &filePathCache, - SourcesManager &sourcesManager) - : m_symbolEntries(symbolEntries), - m_sourceLocationEntries(sourceLocationEntries), - m_filePathCache(filePathCache), - m_sourcesManager(sourcesManager) + FilePathCachingInterface &filePathCache) + : m_symbolEntries(symbolEntries) + , m_sourceLocationEntries(sourceLocationEntries) + , m_filePathCache(filePathCache) { } @@ -96,7 +94,6 @@ private: SymbolEntries &m_symbolEntries; SourceLocationEntries &m_sourceLocationEntries; FilePathCachingInterface &m_filePathCache; - SourcesManager &m_sourcesManager; }; } // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/collectsymbolsaction.cpp b/src/tools/clangrefactoringbackend/source/collectsymbolsaction.cpp index 91c0dd28d8..301f50beae 100644 --- a/src/tools/clangrefactoringbackend/source/collectsymbolsaction.cpp +++ b/src/tools/clangrefactoringbackend/source/collectsymbolsaction.cpp @@ -33,8 +33,7 @@ std::unique_ptr<clang::ASTConsumer> CollectSymbolsAction::newASTConsumer( clang::CompilerInstance &compilerInstance, llvm::StringRef inFile) { - m_indexDataConsumer->setSourceManager(&compilerInstance.getSourceManager()); - return m_action.CreateASTConsumer(compilerInstance, inFile); + return clang::WrapperFrontendAction::CreateASTConsumer(compilerInstance, inFile); } } // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/collectsymbolsaction.h b/src/tools/clangrefactoringbackend/source/collectsymbolsaction.h index 2074a25a6e..a38f1c4f87 100644 --- a/src/tools/clangrefactoringbackend/source/collectsymbolsaction.h +++ b/src/tools/clangrefactoringbackend/source/collectsymbolsaction.h @@ -26,8 +26,8 @@ #pragma once #include "clangrefactoringbackend_global.h" -#include "sourcelocationentry.h" #include "indexdataconsumer.h" +#include "sourcelocationentry.h" #include "symbolentry.h" #include <utils/smallstring.h> @@ -37,53 +37,68 @@ #include <clang/Frontend/CompilerInstance.h> #include <clang/Frontend/FrontendAction.h> #include <clang/Index/IndexingAction.h> +#include <clang/Lex/PreprocessorOptions.h> #include <mutex> namespace ClangBackEnd { -class CollectSymbolsAction +class CollectSymbolsAction : public clang::WrapperFrontendAction { public: CollectSymbolsAction(std::shared_ptr<IndexDataConsumer> indexDataConsumer) - : m_action(indexDataConsumer, createIndexingOptions()), - m_indexDataConsumer(indexDataConsumer.get()) + : clang::WrapperFrontendAction( + clang::index::createIndexingAction(indexDataConsumer, createIndexingOptions(), nullptr)) + , m_indexDataConsumer(indexDataConsumer) {} std::unique_ptr<clang::ASTConsumer> newASTConsumer(clang::CompilerInstance &compilerInstance, llvm::StringRef inFile); -private: - class WrappedIndexAction final : public clang::WrapperFrontendAction - { - public: - WrappedIndexAction(std::shared_ptr<clang::index::IndexDataConsumer> indexDataConsumer, - clang::index::IndexingOptions indexingOptions) - : clang::WrapperFrontendAction( - clang::index::createIndexingAction(indexDataConsumer, indexingOptions, nullptr)) - {} - - std::unique_ptr<clang::ASTConsumer> - CreateASTConsumer(clang::CompilerInstance &compilerInstance, - llvm::StringRef inFile) override - { - return WrapperFrontendAction::CreateASTConsumer(compilerInstance, inFile); - } - }; - - static - clang::index::IndexingOptions createIndexingOptions() + + static clang::index::IndexingOptions createIndexingOptions() { clang::index::IndexingOptions options; options.SystemSymbolFilter = clang::index::IndexingOptions::SystemSymbolFilterKind::None; options.IndexFunctionLocals = true; + options.IndexMacrosInPreprocessor = true; return options; } + bool BeginInvocation(clang::CompilerInstance &compilerInstance) override + { + m_indexDataConsumer->setSourceManager(&compilerInstance.getSourceManager()); + compilerInstance.getPreprocessorOpts().AllowPCHWithCompilerErrors = true; + compilerInstance.getDiagnosticOpts().ErrorLimit = 1; + + return clang::WrapperFrontendAction::BeginInvocation(compilerInstance); + } + + bool BeginSourceFileAction(clang::CompilerInstance &compilerInstance) override + { + compilerInstance.getPreprocessor().SetSuppressIncludeNotFoundError(true); + + return clang::WrapperFrontendAction::BeginSourceFileAction(compilerInstance); + } + + void EndSourceFileAction() override { clang::WrapperFrontendAction::EndSourceFileAction(); } + + bool PrepareToExecuteAction(clang::CompilerInstance &instance) override + { + return clang::WrapperFrontendAction::PrepareToExecuteAction(instance); + } + + void ExecuteAction() override { clang::WrapperFrontendAction::ExecuteAction(); } + + std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(clang::CompilerInstance &compilerInstance, + llvm::StringRef inFile) override + { + return WrapperFrontendAction::CreateASTConsumer(compilerInstance, inFile); + } + private: - WrappedIndexAction m_action; - IndexDataConsumer *m_indexDataConsumer; + std::shared_ptr<IndexDataConsumer> m_indexDataConsumer; }; } // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/filestatuspreprocessorcallbacks.cpp b/src/tools/clangrefactoringbackend/source/filestatuspreprocessorcallbacks.cpp new file mode 100644 index 0000000000..28efe39f9b --- /dev/null +++ b/src/tools/clangrefactoringbackend/source/filestatuspreprocessorcallbacks.cpp @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2019 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 "filestatuspreprocessorcallbacks.h" + +namespace ClangBackEnd { + +void FileStatusPreprocessorCallbacks::FileChanged(clang::SourceLocation sourceLocation, + clang::PPCallbacks::FileChangeReason reason, + clang::SrcMgr::CharacteristicKind, + clang::FileID) +{ + if (reason == clang::PPCallbacks::EnterFile) { + const clang::FileEntry *fileEntry = m_sourceManager->getFileEntryForID( + m_sourceManager->getFileID(sourceLocation)); + if (fileEntry) + addFileStatus(fileEntry); + } +} + +void FileStatusPreprocessorCallbacks::addFileStatus(const clang::FileEntry *fileEntry) +{ + auto id = filePathId(fileEntry); + + auto found = std::lower_bound(m_fileStatuses.begin(), + m_fileStatuses.end(), + id, + [](const auto &first, const auto &second) { + return first.filePathId < second; + }); + + if (found == m_fileStatuses.end() || found->filePathId != id) { + m_fileStatuses.emplace(found, id, fileEntry->getSize(), fileEntry->getModificationTime()); + } +} + +} // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/filestatuspreprocessorcallbacks.h b/src/tools/clangrefactoringbackend/source/filestatuspreprocessorcallbacks.h new file mode 100644 index 0000000000..ad7bc4f4d6 --- /dev/null +++ b/src/tools/clangrefactoringbackend/source/filestatuspreprocessorcallbacks.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2019 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 "filestatus.h" +#include "symbolsvisitorbase.h" + +#include <filepathid.h> + +#include <clang/Lex/PPCallbacks.h> + +namespace ClangBackEnd { + +class FileStatusPreprocessorCallbacks final : public clang::PPCallbacks, public SymbolsVisitorBase +{ +public: + FileStatusPreprocessorCallbacks(FileStatuses &fileStatuses, + const FilePathCachingInterface &filePathCache, + const clang::SourceManager *sourceManager, + FilePathIds &filePathIndices) + : SymbolsVisitorBase(filePathCache, sourceManager, filePathIndices) + , m_fileStatuses(fileStatuses) + {} + + void FileChanged(clang::SourceLocation sourceLocation, + clang::PPCallbacks::FileChangeReason reason, + clang::SrcMgr::CharacteristicKind, + clang::FileID) override; + + void addFileStatus(const clang::FileEntry *fileEntry); + +private: + FileStatuses &m_fileStatuses; +}; + +} // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/indexdataconsumer.cpp b/src/tools/clangrefactoringbackend/source/indexdataconsumer.cpp index 86e5fb597c..1fa6043461 100644 --- a/src/tools/clangrefactoringbackend/source/indexdataconsumer.cpp +++ b/src/tools/clangrefactoringbackend/source/indexdataconsumer.cpp @@ -24,14 +24,18 @@ ****************************************************************************/ #include "indexdataconsumer.h" +#include "collectsymbolsaction.h" +#include "filestatuspreprocessorcallbacks.h" +#include <clang/AST/DeclVisitor.h> #include <clang/Basic/SourceLocation.h> #include <clang/Index/IndexSymbol.h> -#include <clang/AST/Decl.h> -#include <clang/AST/DeclVisitor.h> +#include <clang/Index/IndexingAction.h> #include <llvm/ADT/ArrayRef.h> +#include <iostream> + namespace ClangBackEnd { namespace { @@ -113,23 +117,33 @@ bool isReference(clang::index::SymbolRoleSet symbolRoles) return symbolRoles & (uint(SymbolRole::Reference) | uint(SymbolRole::Call)); } -} +} // namespace bool IndexDataConsumer::skipSymbol(clang::FileID fileId, clang::index::SymbolRoleSet symbolRoles) { - bool alreadyParsed = isAlreadyParsed(fileId); - bool isParsedDeclaration = alreadyParsed && isDeclaration(symbolRoles); - bool isParsedReference = alreadyParsed && !dependentFilesAreModified() && isReference(symbolRoles); + return isAlreadyParsed(fileId, m_symbolSourcesManager) + && !m_symbolSourcesManager.dependentFilesModified(); +} + +bool IndexDataConsumer::isAlreadyParsed(clang::FileID fileId, SourcesManager &sourcesManager) +{ + const clang::FileEntry *fileEntry = m_sourceManager->getFileEntryForID(fileId); + if (!fileEntry) + return false; + return sourcesManager.alreadyParsed(filePathId(fileEntry), fileEntry->getModificationTime()); +} - return isParsedDeclaration || isParsedReference; +void IndexDataConsumer::setPreprocessor(std::shared_ptr<clang::Preprocessor> preprocessor) +{ + preprocessor->addPPCallbacks(std::make_unique<FileStatusPreprocessorCallbacks>( + m_fileStatuses, m_filePathCache, m_sourceManager, m_filePathIndices)); } -bool IndexDataConsumer::handleDeclOccurence( - const clang::Decl *declaration, - clang::index::SymbolRoleSet symbolRoles, - llvm::ArrayRef<clang::index::SymbolRelation> /*symbolRelations*/, - clang::SourceLocation sourceLocation, - IndexDataConsumer::ASTNodeInfo /*astNodeInfo*/) +bool IndexDataConsumer::handleDeclOccurence(const clang::Decl *declaration, + clang::index::SymbolRoleSet symbolRoles, + llvm::ArrayRef<clang::index::SymbolRelation> /*symbolRelations*/, + clang::SourceLocation sourceLocation, + IndexDataConsumer::ASTNodeInfo /*astNodeInfo*/) { const auto *namedDeclaration = clang::dyn_cast<clang::NamedDecl>(declaration); if (namedDeclaration) { @@ -137,7 +151,6 @@ bool IndexDataConsumer::handleDeclOccurence( return true; if (skipSymbol(m_sourceManager->getFileID(sourceLocation), symbolRoles)) - return true; SymbolIndex globalId = toSymbolIndex(declaration->getCanonicalDecl()); @@ -165,4 +178,64 @@ bool IndexDataConsumer::handleDeclOccurence( return true; } +namespace { + +SourceLocationKind macroSymbolType(clang::index::SymbolRoleSet roles) +{ + if (roles & static_cast<clang::index::SymbolRoleSet>(clang::index::SymbolRole::Definition)) + return SourceLocationKind::MacroDefinition; + + if (roles & static_cast<clang::index::SymbolRoleSet>(clang::index::SymbolRole::Undefinition)) + return SourceLocationKind::MacroUndefinition; + + if (roles & static_cast<clang::index::SymbolRoleSet>(clang::index::SymbolRole::Reference)) + return SourceLocationKind::MacroUsage; + + return SourceLocationKind::None; +} + +} // namespace + +bool IndexDataConsumer::handleMacroOccurence(const clang::IdentifierInfo *identifierInfo, + const clang::MacroInfo *macroInfo, + clang::index::SymbolRoleSet roles, + clang::SourceLocation sourceLocation) +{ + if (macroInfo && sourceLocation.isFileID() + && !isAlreadyParsed(m_sourceManager->getFileID(sourceLocation), m_macroSourcesManager) + && !isInSystemHeader(sourceLocation)) { + FilePathId fileId = filePathId(sourceLocation); + if (fileId.isValid()) { + auto macroName = identifierInfo->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), + macroName, + SymbolKind::Macro)); + } + } + + m_sourceLocationEntries.emplace_back(globalId, + fileId, + lineColum(sourceLocation), + macroSymbolType(roles)); + } + } + + return true; +} + +void IndexDataConsumer::finish() +{ + m_macroSourcesManager.updateModifiedTimeStamps(); + m_symbolSourcesManager.updateModifiedTimeStamps(); + m_filePathIndices.clear(); +} + } // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/indexdataconsumer.h b/src/tools/clangrefactoringbackend/source/indexdataconsumer.h index 6db595391c..730ca12b23 100644 --- a/src/tools/clangrefactoringbackend/source/indexdataconsumer.h +++ b/src/tools/clangrefactoringbackend/source/indexdataconsumer.h @@ -26,6 +26,7 @@ #pragma once #include "clangrefactoringbackend_global.h" +#include "filestatus.h" #include "sourcelocationentry.h" #include "symbolentry.h" #include "symbolsvisitorbase.h" @@ -42,28 +43,48 @@ class IndexDataConsumer : public clang::index::IndexDataConsumer, public: IndexDataConsumer(SymbolEntries &symbolEntries, SourceLocationEntries &sourceLocationEntries, + FileStatuses &fileStatuses, FilePathCachingInterface &filePathCache, - SourcesManager &sourcesManager) - : SymbolsVisitorBase(filePathCache, nullptr, sourcesManager), - m_symbolEntries(symbolEntries), - m_sourceLocationEntries(sourceLocationEntries) + SourcesManager &symbolSourcesManager, + SourcesManager ¯oSourcesManager) + : SymbolsVisitorBase(filePathCache, nullptr, m_filePathIndices) + , m_symbolEntries(symbolEntries) + , m_sourceLocationEntries(sourceLocationEntries) + , m_fileStatuses(fileStatuses) + , m_symbolSourcesManager(symbolSourcesManager) + , m_macroSourcesManager(macroSourcesManager) + {} IndexDataConsumer(const IndexDataConsumer &) = delete; IndexDataConsumer &operator=(const IndexDataConsumer &) = delete; + void setPreprocessor(std::shared_ptr<clang::Preprocessor> preprocessor) override; + bool handleDeclOccurence(const clang::Decl *declaration, clang::index::SymbolRoleSet symbolRoles, llvm::ArrayRef<clang::index::SymbolRelation> symbolRelations, clang::SourceLocation sourceLocation, ASTNodeInfo astNodeInfo) override; + bool handleMacroOccurence(const clang::IdentifierInfo *identifierInfo, + const clang::MacroInfo *macroInfo, + clang::index::SymbolRoleSet roles, + clang::SourceLocation sourceLocation) override; + + void finish() override; + private: bool skipSymbol(clang::FileID fileId, clang::index::SymbolRoleSet symbolRoles); + bool isAlreadyParsed(clang::FileID fileId, SourcesManager &sourcesManager); private: + FilePathIds m_filePathIndices; SymbolEntries &m_symbolEntries; SourceLocationEntries &m_sourceLocationEntries; + FileStatuses &m_fileStatuses; + SourcesManager &m_symbolSourcesManager; + SourcesManager &m_macroSourcesManager; }; } // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/symbolindexer.cpp b/src/tools/clangrefactoringbackend/source/symbolindexer.cpp index 9c84c4666a..1ee61eb67c 100644 --- a/src/tools/clangrefactoringbackend/source/symbolindexer.cpp +++ b/src/tools/clangrefactoringbackend/source/symbolindexer.cpp @@ -144,6 +144,8 @@ void SymbolIndexer::updateProjectPart(ProjectPartContainer &&projectPart) } } + m_pathWatcher.updateIdPaths( + {{projectPartId, m_buildDependencyStorage.fetchSources(projectPartId)}}); m_symbolIndexerTaskQueue.addOrUpdateTasks(std::move(symbolIndexerTask)); m_symbolIndexerTaskQueue.processEntries(); } diff --git a/src/tools/clangrefactoringbackend/source/symbolindexertaskqueue.h b/src/tools/clangrefactoringbackend/source/symbolindexertaskqueue.h index 7ca3513284..1f15f2ffaa 100644 --- a/src/tools/clangrefactoringbackend/source/symbolindexertaskqueue.h +++ b/src/tools/clangrefactoringbackend/source/symbolindexertaskqueue.h @@ -30,6 +30,7 @@ #include <filepathid.h> #include <progresscounter.h> +#include <sqlitedatabase.h> #include <taskschedulerinterface.h> #include <utils/algorithm.h> @@ -38,10 +39,6 @@ #include <functional> #include <vector> -namespace Sqlite { -class TransactionInterface; -} - namespace ClangBackEnd { class SymbolsCollectorInterface; @@ -53,9 +50,11 @@ public: using Task = SymbolIndexerTask::Callable; SymbolIndexerTaskQueue(TaskSchedulerInterface<Task> &symbolIndexerTaskScheduler, - ProgressCounter &progressCounter) - : m_symbolIndexerScheduler(symbolIndexerTaskScheduler), - m_progressCounter(progressCounter) + ProgressCounter &progressCounter, + Sqlite::DatabaseInterface &database) + : m_symbolIndexerScheduler(symbolIndexerTaskScheduler) + , m_progressCounter(progressCounter) + , m_database(database) {} void addOrUpdateTasks(std::vector<SymbolIndexerTask> &&tasks) @@ -94,12 +93,21 @@ public: void processEntries() { - uint taskCount = m_symbolIndexerScheduler.slotUsage().free; + auto slotUsage = m_symbolIndexerScheduler.slotUsage(); + uint taskCount = slotUsage.free; auto newEnd = std::prev(m_tasks.end(), std::min<int>(int(taskCount), int(m_tasks.size()))); m_symbolIndexerScheduler.addTasks({std::make_move_iterator(newEnd), std::make_move_iterator(m_tasks.end())}); m_tasks.erase(newEnd, m_tasks.end()); + + if (m_tasks.empty() && slotUsage.used == 0) { + try { + m_database.walCheckpointFull(); + } catch (Sqlite::Exception &exception) { + exception.printWarning(); + } + } } void syncTasks(); @@ -108,6 +116,7 @@ private: std::vector<SymbolIndexerTask> m_tasks; TaskSchedulerInterface<Task> &m_symbolIndexerScheduler; ProgressCounter &m_progressCounter; + Sqlite::DatabaseInterface &m_database; }; } // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/symbolindexing.h b/src/tools/clangrefactoringbackend/source/symbolindexing.h index d4e36499b1..5c391503bf 100644 --- a/src/tools/clangrefactoringbackend/source/symbolindexing.h +++ b/src/tools/clangrefactoringbackend/source/symbolindexing.h @@ -105,6 +105,7 @@ public: m_projectPartsStorage, m_modifiedTimeChecker, environment) + , m_indexerQueue(m_indexerScheduler, m_progressCounter, database) , m_indexerScheduler(m_collectorManger, m_indexerQueue, m_progressCounter, @@ -152,7 +153,7 @@ private: ModifiedTimeChecker<ClangBackEnd::SourceTimeStamps> m_modifiedTimeChecker{getModifiedTime, m_filePathCache}; SymbolIndexer m_indexer; - SymbolIndexerTaskQueue m_indexerQueue{m_indexerScheduler, m_progressCounter}; + SymbolIndexerTaskQueue m_indexerQueue; SymbolIndexerTaskScheduler m_indexerScheduler; }; diff --git a/src/tools/clangrefactoringbackend/source/symbolscollector.cpp b/src/tools/clangrefactoringbackend/source/symbolscollector.cpp index 1634512b50..071837ac52 100644 --- a/src/tools/clangrefactoringbackend/source/symbolscollector.cpp +++ b/src/tools/clangrefactoringbackend/source/symbolscollector.cpp @@ -32,10 +32,14 @@ namespace ClangBackEnd { SymbolsCollector::SymbolsCollector(Sqlite::Database &database) - : m_filePathCache(database), - m_indexDataConsumer(std::make_shared<IndexDataConsumer>(m_symbolEntries, m_sourceLocationEntries, m_filePathCache, m_sourcesManager)), - m_collectSymbolsAction(m_indexDataConsumer), - m_collectMacrosSourceFileCallbacks(m_symbolEntries, m_sourceLocationEntries, m_filePathCache, m_sourcesManager) + : m_filePathCache(database) + , m_indexDataConsumer(std::make_shared<IndexDataConsumer>(m_symbolEntries, + m_sourceLocationEntries, + m_fileStatuses, + m_filePathCache, + m_symbolSourcesManager, + m_macroSourcesManager)) + , m_collectSymbolsAction(m_indexDataConsumer) { } @@ -43,7 +47,6 @@ void SymbolsCollector::addFiles(const FilePathIds &filePathIds, const Utils::SmallStringVector &arguments) { m_clangTool.addFiles(m_filePathCache.filePaths(filePathIds), arguments); - m_collectMacrosSourceFileCallbacks.addSourceFiles(filePathIds); } void SymbolsCollector::setFile(FilePathId filePathId, const Utils::SmallStringVector &arguments) @@ -58,91 +61,73 @@ void SymbolsCollector::setUnsavedFiles(const V2::FileContainers &unsavedFiles) void SymbolsCollector::clear() { - m_indexDataConsumer->clear(); - m_collectMacrosSourceFileCallbacks.clear(); m_symbolEntries.clear(); m_sourceLocationEntries.clear(); + m_fileStatuses.clear(); m_clangTool = ClangTool(); } -template <typename Factory> -std::unique_ptr<clang::tooling::FrontendActionFactory> -newFrontendActionFactory(Factory *consumerFactory, - clang::tooling::SourceFileCallbacks *sourceFileCallbacks) +std::unique_ptr<clang::tooling::FrontendActionFactory> newFrontendActionFactory(CollectSymbolsAction *action) { class FrontendActionFactoryAdapter : public clang::tooling::FrontendActionFactory { public: - explicit FrontendActionFactoryAdapter(Factory *consumerFactory, - clang::tooling::SourceFileCallbacks *sourceFileCallbacks) - : m_consumerFactory(consumerFactory), - m_sourceFileCallbacks(sourceFileCallbacks) + explicit FrontendActionFactoryAdapter(CollectSymbolsAction *consumerFactory) + : m_action(consumerFactory) {} - clang::FrontendAction *create() override { - return new ConsumerFactoryAdaptor(m_consumerFactory, m_sourceFileCallbacks); - } + clang::FrontendAction *create() override { return new AdaptorAction(m_action); } private: - class ConsumerFactoryAdaptor : public clang::ASTFrontendAction { + class AdaptorAction : public clang::ASTFrontendAction + { public: - ConsumerFactoryAdaptor(Factory *consumerFactory, - clang::tooling::SourceFileCallbacks *sourceFileCallbacks) - : m_consumerFactory(consumerFactory), - m_sourceFileCallbacks(sourceFileCallbacks) + AdaptorAction(CollectSymbolsAction *action) + : m_action(action) {} std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(clang::CompilerInstance &instance, llvm::StringRef inFile) override { - return m_consumerFactory->newASTConsumer(instance, inFile); + return m_action->newASTConsumer(instance, inFile); } - protected: - bool BeginInvocation(clang::CompilerInstance &compilerInstance) override + bool BeginInvocation(clang::CompilerInstance &instance) override { - compilerInstance.getPreprocessorOpts().AllowPCHWithCompilerErrors = true; - compilerInstance.getDiagnosticOpts().ErrorLimit = 1; - - return clang::ASTFrontendAction::BeginInvocation(compilerInstance); + return m_action->BeginInvocation(instance); } - - bool BeginSourceFileAction(clang::CompilerInstance &compilerInstance) override + bool BeginSourceFileAction(clang::CompilerInstance &instance) override { - compilerInstance.getPreprocessor().SetSuppressIncludeNotFoundError(true); - - if (!clang::ASTFrontendAction::BeginSourceFileAction(compilerInstance)) - return false; - if (m_sourceFileCallbacks) - return m_sourceFileCallbacks->handleBeginSource(compilerInstance); - return true; + return m_action->BeginSourceFileAction(instance); } - void EndSourceFileAction() override + bool PrepareToExecuteAction(clang::CompilerInstance &instance) override { - if (m_sourceFileCallbacks) - m_sourceFileCallbacks->handleEndSource(); - clang::ASTFrontendAction::EndSourceFileAction(); + return m_action->PrepareToExecuteAction(instance); } + void ExecuteAction() override { m_action->ExecuteAction(); } + void EndSourceFileAction() override { m_action->EndSourceFileAction(); } + + bool hasPCHSupport() const override { return m_action->hasPCHSupport(); } + bool hasASTFileSupport() const override { return m_action->hasASTFileSupport(); } + bool hasIRSupport() const override { return false; } + bool hasCodeCompletionSupport() const override { return false; } private: - Factory *m_consumerFactory; - clang::tooling::SourceFileCallbacks *m_sourceFileCallbacks; + CollectSymbolsAction *m_action; }; - Factory *m_consumerFactory; - clang::tooling::SourceFileCallbacks *m_sourceFileCallbacks; + CollectSymbolsAction *m_action; }; - return std::unique_ptr<clang::tooling::FrontendActionFactory>( - new FrontendActionFactoryAdapter(consumerFactory, sourceFileCallbacks)); + return std::unique_ptr<clang::tooling::FrontendActionFactory>( + new FrontendActionFactoryAdapter(action)); } bool SymbolsCollector::collectSymbols() { auto tool = m_clangTool.createTool(); - auto actionFactory = ClangBackEnd::newFrontendActionFactory(&m_collectSymbolsAction, - &m_collectMacrosSourceFileCallbacks); + auto actionFactory = ClangBackEnd::newFrontendActionFactory(&m_collectSymbolsAction); return tool.run(actionFactory.get()) != 1; } @@ -161,24 +146,9 @@ const SourceLocationEntries &SymbolsCollector::sourceLocations() const return m_sourceLocationEntries; } -const FilePathIds &SymbolsCollector::sourceFiles() const -{ - return m_collectMacrosSourceFileCallbacks.sourceFiles(); -} - -const UsedMacros &SymbolsCollector::usedMacros() const -{ - return m_collectMacrosSourceFileCallbacks.usedMacros(); -} - const FileStatuses &SymbolsCollector::fileStatuses() const { - return m_collectMacrosSourceFileCallbacks.fileStatuses(); -} - -const SourceDependencies &SymbolsCollector::sourceDependencies() const -{ - return m_collectMacrosSourceFileCallbacks.sourceDependencies(); + return m_fileStatuses; } bool SymbolsCollector::isUsed() const diff --git a/src/tools/clangrefactoringbackend/source/symbolscollector.h b/src/tools/clangrefactoringbackend/source/symbolscollector.h index b37647e969..cc7ca4396c 100644 --- a/src/tools/clangrefactoringbackend/source/symbolscollector.h +++ b/src/tools/clangrefactoringbackend/source/symbolscollector.h @@ -58,10 +58,7 @@ public: const SymbolEntries &symbols() const override; const SourceLocationEntries &sourceLocations() const override; - const FilePathIds &sourceFiles() const override; - const UsedMacros &usedMacros() const override; const FileStatuses &fileStatuses() const override; - const SourceDependencies &sourceDependencies() const override; bool isUsed() const override; void setIsUsed(bool isUsed) override; @@ -71,10 +68,11 @@ private: ClangTool m_clangTool; SymbolEntries m_symbolEntries; SourceLocationEntries m_sourceLocationEntries; + FileStatuses m_fileStatuses; std::shared_ptr<IndexDataConsumer> m_indexDataConsumer; CollectSymbolsAction m_collectSymbolsAction; - CollectMacrosSourceFileCallbacks m_collectMacrosSourceFileCallbacks; - SourcesManager m_sourcesManager; + SourcesManager m_symbolSourcesManager; + SourcesManager m_macroSourcesManager; bool m_isUsed = false; }; diff --git a/src/tools/clangrefactoringbackend/source/symbolscollectorinterface.h b/src/tools/clangrefactoringbackend/source/symbolscollectorinterface.h index 94b3142371..07b5de223c 100644 --- a/src/tools/clangrefactoringbackend/source/symbolscollectorinterface.h +++ b/src/tools/clangrefactoringbackend/source/symbolscollectorinterface.h @@ -48,10 +48,7 @@ public: virtual const SymbolEntries &symbols() const = 0; virtual const SourceLocationEntries &sourceLocations() const = 0; - virtual const FilePathIds &sourceFiles() const = 0; - virtual const UsedMacros &usedMacros() const = 0; virtual const FileStatuses &fileStatuses() const = 0; - virtual const SourceDependencies &sourceDependencies() const = 0; }; } // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/symbolsvisitorbase.h b/src/tools/clangrefactoringbackend/source/symbolsvisitorbase.h index ff2142f40e..7b63cb223e 100644 --- a/src/tools/clangrefactoringbackend/source/symbolsvisitorbase.h +++ b/src/tools/clangrefactoringbackend/source/symbolsvisitorbase.h @@ -46,10 +46,10 @@ class SymbolsVisitorBase public: SymbolsVisitorBase(const FilePathCachingInterface &filePathCache, const clang::SourceManager *sourceManager, - SourcesManager &sourcesManager) - : m_filePathCache(filePathCache), - m_sourceManager(sourceManager), - m_sourcesManager(sourcesManager) + FilePathIds &filePathIndices) + : m_filePathCache(filePathCache) + , m_sourceManager(sourceManager) + , m_filePathIndices(filePathIndices) {} FilePathId filePathId(clang::SourceLocation sourceLocation) @@ -60,25 +60,6 @@ public: return filePathId(fileEntry); } - bool dependentFilesAreModified() - { - return m_sourcesManager.dependentFilesModified(); - } - - bool isAlreadyParsed(clang::FileID fileId) - { - const clang::FileEntry *fileEntry = m_sourceManager->getFileEntryForID(fileId); - if (!fileEntry) - return false; - return m_sourcesManager.alreadyParsed(filePathId(fileEntry), - fileEntry->getModificationTime()); - } - - bool alreadyParsed(clang::SourceLocation sourceLocation) - { - return isAlreadyParsed(m_sourceManager->getFileID(sourceLocation)); - } - FilePathId filePathId(const clang::FileEntry *fileEntry) { if (fileEntry) { @@ -156,22 +137,26 @@ public: return isSystem(m_sourceManager->getSLocEntry(fileId).getFile().getFileCharacteristic()); } + bool isInSystemHeader(clang::SourceLocation sourceLocation) const + { + return m_sourceManager->isInSystemHeader(sourceLocation); + } + static bool isSystem(clang::SrcMgr::CharacteristicKind kind) { return clang::SrcMgr::isSystem(kind); } - void clear() - { - m_filePathIndices.clear(); - } + const FilePathCachingInterface &filePathCache() const { return m_filePathCache; } + const clang::SourceManager *sourceManager() const { return m_sourceManager; } protected: - std::vector<FilePathId> m_filePathIndices; const FilePathCachingInterface &m_filePathCache; const clang::SourceManager *m_sourceManager = nullptr; - SourcesManager &m_sourcesManager; + +private: + FilePathIds &m_filePathIndices; }; } // namespace ClangBackend |