forked from qt-creator/qt-creator
Clang: Don't index already indexed symbols
We don't index system headers any more and introduce a first step to decrease double indexing. For that we introduces the SourcesManager which so far tells you only if a file was already indexed for a certain time stamp. Change-Id: Icde54465693ca84a622764c595635cac365c0111 Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
This commit is contained in:
@@ -30,6 +30,7 @@
|
|||||||
#include "sourcedependency.h"
|
#include "sourcedependency.h"
|
||||||
#include "sourcelocationsutils.h"
|
#include "sourcelocationsutils.h"
|
||||||
#include "sourcelocationentry.h"
|
#include "sourcelocationentry.h"
|
||||||
|
#include "sourcesmanager.h"
|
||||||
#include "symbolentry.h"
|
#include "symbolentry.h"
|
||||||
#include "usedmacro.h"
|
#include "usedmacro.h"
|
||||||
|
|
||||||
@@ -54,8 +55,9 @@ public:
|
|||||||
SourceDependencies &sourceDependencies,
|
SourceDependencies &sourceDependencies,
|
||||||
FilePathCachingInterface &filePathCache,
|
FilePathCachingInterface &filePathCache,
|
||||||
const clang::SourceManager &sourceManager,
|
const clang::SourceManager &sourceManager,
|
||||||
std::shared_ptr<clang::Preprocessor> &&preprocessor)
|
std::shared_ptr<clang::Preprocessor> &&preprocessor,
|
||||||
: SymbolsVisitorBase(filePathCache, &sourceManager),
|
SourcesManager &sourcesManager)
|
||||||
|
: SymbolsVisitorBase(filePathCache, &sourceManager, sourcesManager),
|
||||||
m_preprocessor(std::move(preprocessor)),
|
m_preprocessor(std::move(preprocessor)),
|
||||||
m_sourceDependencies(sourceDependencies),
|
m_sourceDependencies(sourceDependencies),
|
||||||
m_symbolEntries(symbolEntries),
|
m_symbolEntries(symbolEntries),
|
||||||
@@ -165,6 +167,7 @@ public:
|
|||||||
{
|
{
|
||||||
filterOutHeaderGuards();
|
filterOutHeaderGuards();
|
||||||
mergeUsedMacros();
|
mergeUsedMacros();
|
||||||
|
m_sourcesManager.updateModifiedTimeStamps();
|
||||||
}
|
}
|
||||||
|
|
||||||
void filterOutHeaderGuards()
|
void filterOutHeaderGuards()
|
||||||
@@ -205,6 +208,9 @@ public:
|
|||||||
void addUsedMacro(const clang::Token ¯oNameToken,
|
void addUsedMacro(const clang::Token ¯oNameToken,
|
||||||
const clang::MacroDefinition ¯oDefinition)
|
const clang::MacroDefinition ¯oDefinition)
|
||||||
{
|
{
|
||||||
|
if (isInSystemHeader(macroNameToken.getLocation()))
|
||||||
|
return;
|
||||||
|
|
||||||
clang::MacroInfo *macroInfo = macroDefinition.getMacroInfo();
|
clang::MacroInfo *macroInfo = macroDefinition.getMacroInfo();
|
||||||
UsedMacro usedMacro{macroNameToken.getIdentifierInfo()->getName(),
|
UsedMacro usedMacro{macroNameToken.getIdentifierInfo()->getName(),
|
||||||
filePathId(macroNameToken.getLocation())};
|
filePathId(macroNameToken.getLocation())};
|
||||||
@@ -229,12 +235,17 @@ public:
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isInSystemHeader(clang::SourceLocation sourceLocation) const
|
||||||
|
{
|
||||||
|
return m_sourceManager->isInSystemHeader(sourceLocation);
|
||||||
|
}
|
||||||
|
|
||||||
void addMacroAsSymbol(const clang::Token ¯oNameToken,
|
void addMacroAsSymbol(const clang::Token ¯oNameToken,
|
||||||
const clang::MacroInfo *macroInfo,
|
const clang::MacroInfo *macroInfo,
|
||||||
SourceLocationKind symbolType)
|
SourceLocationKind symbolType)
|
||||||
{
|
{
|
||||||
clang::SourceLocation sourceLocation = macroNameToken.getLocation();
|
clang::SourceLocation sourceLocation = macroNameToken.getLocation();
|
||||||
if (macroInfo && sourceLocation.isFileID()) {
|
if (macroInfo && sourceLocation.isFileID() && !isInSystemHeader(sourceLocation)) {
|
||||||
FilePathId fileId = filePathId(sourceLocation);
|
FilePathId fileId = filePathId(sourceLocation);
|
||||||
if (fileId.isValid()) {
|
if (fileId.isValid()) {
|
||||||
auto macroName = macroNameToken.getIdentifierInfo()->getName();
|
auto macroName = macroNameToken.getIdentifierInfo()->getName();
|
||||||
|
@@ -42,7 +42,8 @@ bool CollectMacrosSourceFileCallbacks::handleBeginSource(clang::CompilerInstance
|
|||||||
m_sourceDependencies,
|
m_sourceDependencies,
|
||||||
m_filePathCache,
|
m_filePathCache,
|
||||||
compilerInstance.getSourceManager(),
|
compilerInstance.getSourceManager(),
|
||||||
compilerInstance.getPreprocessorPtr());
|
compilerInstance.getPreprocessorPtr(),
|
||||||
|
m_sourcesManager);
|
||||||
|
|
||||||
compilerInstance.getPreprocessorPtr()->addPPCallbacks(std::move(callbacks));
|
compilerInstance.getPreprocessorPtr()->addPPCallbacks(std::move(callbacks));
|
||||||
|
|
||||||
|
@@ -37,15 +37,19 @@
|
|||||||
|
|
||||||
namespace ClangBackEnd {
|
namespace ClangBackEnd {
|
||||||
|
|
||||||
|
class SourcesManager;
|
||||||
|
|
||||||
class CollectMacrosSourceFileCallbacks : public clang::tooling::SourceFileCallbacks
|
class CollectMacrosSourceFileCallbacks : public clang::tooling::SourceFileCallbacks
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CollectMacrosSourceFileCallbacks(SymbolEntries &symbolEntries,
|
CollectMacrosSourceFileCallbacks(SymbolEntries &symbolEntries,
|
||||||
SourceLocationEntries &sourceLocationEntries,
|
SourceLocationEntries &sourceLocationEntries,
|
||||||
FilePathCachingInterface &filePathCache)
|
FilePathCachingInterface &filePathCache,
|
||||||
|
SourcesManager &sourcesManager)
|
||||||
: m_symbolEntries(symbolEntries),
|
: m_symbolEntries(symbolEntries),
|
||||||
m_sourceLocationEntries(sourceLocationEntries),
|
m_sourceLocationEntries(sourceLocationEntries),
|
||||||
m_filePathCache(filePathCache)
|
m_filePathCache(filePathCache),
|
||||||
|
m_sourcesManager(sourcesManager)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,6 +95,7 @@ private:
|
|||||||
SymbolEntries &m_symbolEntries;
|
SymbolEntries &m_symbolEntries;
|
||||||
SourceLocationEntries &m_sourceLocationEntries;
|
SourceLocationEntries &m_sourceLocationEntries;
|
||||||
FilePathCachingInterface &m_filePathCache;
|
FilePathCachingInterface &m_filePathCache;
|
||||||
|
SourcesManager &m_sourcesManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ClangBackEnd
|
} // namespace ClangBackEnd
|
||||||
|
@@ -98,6 +98,12 @@ SymbolKindAndTags symbolKindAndTags(const clang::Decl *declaration)
|
|||||||
static IndexingDeclVisitor visitor;
|
static IndexingDeclVisitor visitor;
|
||||||
return visitor.Visit(declaration);
|
return visitor.Visit(declaration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isContextIndependentDeclaration(const clang::Decl *declaration)
|
||||||
|
{
|
||||||
|
return clang::dyn_cast<clang::ValueDecl>(declaration)
|
||||||
|
|| clang::dyn_cast<clang::TypeDecl>(declaration);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IndexDataConsumer::handleDeclOccurence(const clang::Decl *declaration,
|
bool IndexDataConsumer::handleDeclOccurence(const clang::Decl *declaration,
|
||||||
@@ -107,12 +113,14 @@ bool IndexDataConsumer::handleDeclOccurence(const clang::Decl *declaration,
|
|||||||
unsigned offset,
|
unsigned offset,
|
||||||
IndexDataConsumer::ASTNodeInfo astNodeInfo)
|
IndexDataConsumer::ASTNodeInfo astNodeInfo)
|
||||||
{
|
{
|
||||||
|
|
||||||
const auto *namedDeclaration = clang::dyn_cast<clang::NamedDecl>(declaration);
|
const auto *namedDeclaration = clang::dyn_cast<clang::NamedDecl>(declaration);
|
||||||
if (namedDeclaration) {
|
if (namedDeclaration) {
|
||||||
if (!namedDeclaration->getIdentifier())
|
if (!namedDeclaration->getIdentifier())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if (alreadyParsed(fileId) && isContextIndependentDeclaration(declaration))
|
||||||
|
return true;
|
||||||
|
|
||||||
SymbolIndex globalId = toSymbolIndex(declaration->getCanonicalDecl());
|
SymbolIndex globalId = toSymbolIndex(declaration->getCanonicalDecl());
|
||||||
clang::SourceLocation sourceLocation = m_sourceManager->getLocForStartOfFile(fileId).getLocWithOffset(offset);
|
clang::SourceLocation sourceLocation = m_sourceManager->getLocForStartOfFile(fileId).getLocWithOffset(offset);
|
||||||
|
|
||||||
|
@@ -42,8 +42,9 @@ class IndexDataConsumer : public clang::index::IndexDataConsumer,
|
|||||||
public:
|
public:
|
||||||
IndexDataConsumer(SymbolEntries &symbolEntries,
|
IndexDataConsumer(SymbolEntries &symbolEntries,
|
||||||
SourceLocationEntries &sourceLocationEntries,
|
SourceLocationEntries &sourceLocationEntries,
|
||||||
FilePathCachingInterface &filePathCache)
|
FilePathCachingInterface &filePathCache,
|
||||||
: SymbolsVisitorBase(filePathCache, nullptr),
|
SourcesManager &sourcesManager)
|
||||||
|
: SymbolsVisitorBase(filePathCache, nullptr, sourcesManager),
|
||||||
m_symbolEntries(symbolEntries),
|
m_symbolEntries(symbolEntries),
|
||||||
m_sourceLocationEntries(sourceLocationEntries)
|
m_sourceLocationEntries(sourceLocationEntries)
|
||||||
{}
|
{}
|
||||||
|
@@ -30,9 +30,9 @@
|
|||||||
namespace ClangBackEnd {
|
namespace ClangBackEnd {
|
||||||
|
|
||||||
SymbolsCollector::SymbolsCollector(FilePathCachingInterface &filePathCache)
|
SymbolsCollector::SymbolsCollector(FilePathCachingInterface &filePathCache)
|
||||||
: m_indexDataConsumer(std::make_shared<IndexDataConsumer>(m_symbolEntries, m_sourceLocationEntries, filePathCache)),
|
: m_indexDataConsumer(std::make_shared<IndexDataConsumer>(m_symbolEntries, m_sourceLocationEntries, filePathCache, m_sourcesManager)),
|
||||||
m_collectSymbolsAction(m_indexDataConsumer),
|
m_collectSymbolsAction(m_indexDataConsumer),
|
||||||
m_collectMacrosSourceFileCallbacks(m_symbolEntries, m_sourceLocationEntries, filePathCache),
|
m_collectMacrosSourceFileCallbacks(m_symbolEntries, m_sourceLocationEntries, filePathCache, m_sourcesManager),
|
||||||
m_filePathCache(filePathCache)
|
m_filePathCache(filePathCache)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@@ -28,6 +28,7 @@
|
|||||||
#include "clangtool.h"
|
#include "clangtool.h"
|
||||||
#include "collectmacrossourcefilecallbacks.h"
|
#include "collectmacrossourcefilecallbacks.h"
|
||||||
#include "collectsymbolsaction.h"
|
#include "collectsymbolsaction.h"
|
||||||
|
#include "sourcesmanager.h"
|
||||||
#include "symbolscollectorinterface.h"
|
#include "symbolscollectorinterface.h"
|
||||||
|
|
||||||
#include <filepathcachingfwd.h>
|
#include <filepathcachingfwd.h>
|
||||||
@@ -62,6 +63,7 @@ private:
|
|||||||
std::shared_ptr<IndexDataConsumer> m_indexDataConsumer;
|
std::shared_ptr<IndexDataConsumer> m_indexDataConsumer;
|
||||||
CollectSymbolsAction m_collectSymbolsAction;
|
CollectSymbolsAction m_collectSymbolsAction;
|
||||||
CollectMacrosSourceFileCallbacks m_collectMacrosSourceFileCallbacks;
|
CollectMacrosSourceFileCallbacks m_collectMacrosSourceFileCallbacks;
|
||||||
|
SourcesManager m_sourcesManager;
|
||||||
FilePathCachingInterface &m_filePathCache;
|
FilePathCachingInterface &m_filePathCache;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -26,6 +26,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "sourcelocationsutils.h"
|
#include "sourcelocationsutils.h"
|
||||||
|
#include "sourcesmanager.h"
|
||||||
|
#include "symbolentry.h"
|
||||||
|
|
||||||
#include <filepathcachinginterface.h>
|
#include <filepathcachinginterface.h>
|
||||||
|
|
||||||
@@ -43,9 +45,11 @@ class SymbolsVisitorBase
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SymbolsVisitorBase(FilePathCachingInterface &filePathCache,
|
SymbolsVisitorBase(FilePathCachingInterface &filePathCache,
|
||||||
const clang::SourceManager *sourceManager)
|
const clang::SourceManager *sourceManager,
|
||||||
|
SourcesManager &sourcesManager)
|
||||||
: m_filePathCache(filePathCache),
|
: m_filePathCache(filePathCache),
|
||||||
m_sourceManager(sourceManager)
|
m_sourceManager(sourceManager),
|
||||||
|
m_sourcesManager(sourcesManager)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
FilePathId filePathId(clang::SourceLocation sourceLocation)
|
FilePathId filePathId(clang::SourceLocation sourceLocation)
|
||||||
@@ -56,6 +60,19 @@ public:
|
|||||||
return filePathId(fileEntry);
|
return filePathId(fileEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool alreadyParsed(clang::FileID fileId)
|
||||||
|
{
|
||||||
|
const clang::FileEntry *fileEntry = m_sourceManager->getFileEntryForID(fileId);
|
||||||
|
|
||||||
|
return m_sourcesManager.alreadyParsed(filePathId(fileEntry),
|
||||||
|
fileEntry->getModificationTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool alreadyParsed(clang::SourceLocation sourceLocation)
|
||||||
|
{
|
||||||
|
return alreadyParsed(m_sourceManager->getFileID(sourceLocation));
|
||||||
|
}
|
||||||
|
|
||||||
FilePathId filePathId(const clang::FileEntry *fileEntry)
|
FilePathId filePathId(const clang::FileEntry *fileEntry)
|
||||||
{
|
{
|
||||||
if (fileEntry) {
|
if (fileEntry) {
|
||||||
@@ -128,10 +145,17 @@ public:
|
|||||||
m_sourceManager = sourceManager;
|
m_sourceManager = sourceManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isInSystemHeader(clang::FileID fileId) const
|
||||||
|
{
|
||||||
|
return clang::SrcMgr::isSystem(
|
||||||
|
m_sourceManager->getSLocEntry(fileId).getFile().getFileCharacteristic());
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::vector<FilePathId> m_filePathIndices;
|
std::vector<FilePathId> m_filePathIndices;
|
||||||
FilePathCachingInterface &m_filePathCache;
|
FilePathCachingInterface &m_filePathCache;
|
||||||
const clang::SourceManager *m_sourceManager = nullptr;
|
const clang::SourceManager *m_sourceManager = nullptr;
|
||||||
|
SourcesManager &m_sourcesManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ClangBackend
|
} // namespace ClangBackend
|
||||||
|
@@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define HEADER_DEFINE
|
||||||
|
|
||||||
|
void HeaderFunction();
|
||||||
|
|
||||||
|
class Class
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int Member = 20;
|
||||||
|
};
|
5
tests/unit/unittest/data/symbolscollector_unmodified.cpp
Normal file
5
tests/unit/unittest/data/symbolscollector_unmodified.cpp
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#include <symbolscollector_unmodified_header.h>
|
||||||
|
|
||||||
|
#define MAINFILE_DEFINE
|
||||||
|
|
||||||
|
void MainFileFunction();
|
@@ -0,0 +1,5 @@
|
|||||||
|
#include <symbolscollector_unmodified_header.h>
|
||||||
|
|
||||||
|
#define MAINFILE_DEFINE
|
||||||
|
|
||||||
|
void MainFileFunction();
|
@@ -707,4 +707,34 @@ TEST_F(SymbolsCollector, IsVariableSymbol)
|
|||||||
HasSymbolKind(SymbolKind::Variable))));
|
HasSymbolKind(SymbolKind::Variable))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST_F(SymbolsCollector, DontIndexUnmodifiedHeaderFiles)
|
||||||
|
{
|
||||||
|
collector.addFiles({filePathId(TESTDATA_DIR "/symbolscollector_unmodified.cpp")}, {"cc", "-I", {TESTDATA_DIR, "/include"}});
|
||||||
|
collector.collectSymbols();
|
||||||
|
collector.clear();
|
||||||
|
collector.addFiles({filePathId(TESTDATA_DIR "/symbolscollector_unmodified2.cpp")}, {"cc", "-I", {TESTDATA_DIR, "/include"}});
|
||||||
|
|
||||||
|
collector.collectSymbols();
|
||||||
|
|
||||||
|
ASSERT_THAT(collector.symbols(),
|
||||||
|
AllOf(
|
||||||
|
Not(Contains(HasSymbolName("HeaderFunction"))),
|
||||||
|
Not(Contains(HasSymbolName("Class"))),
|
||||||
|
Not(Contains(HasSymbolName("Member")))));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SymbolsCollector, DontIndexSystemIncudes)
|
||||||
|
{
|
||||||
|
collector.addFiles({filePathId(TESTDATA_DIR "/symbolscollector_unmodified.cpp")}, {"cc", "-isystem", {TESTDATA_DIR, "/include"}});
|
||||||
|
|
||||||
|
collector.collectSymbols();
|
||||||
|
|
||||||
|
ASSERT_THAT(collector.symbols(),
|
||||||
|
AllOf(
|
||||||
|
Not(Contains(HasSymbolName("HeaderFunction"))),
|
||||||
|
Not(Contains(HasSymbolName("Class"))),
|
||||||
|
Not(Contains(HasSymbolName("Member"))),
|
||||||
|
Not(Contains(HasSymbolName("HEADER_DEFINE")))));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user