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:
Marco Bubke
2018-08-13 16:56:41 +02:00
parent cc0db43c34
commit 39e78bd3f6
12 changed files with 116 additions and 13 deletions

View File

@@ -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 &macroNameToken, void addUsedMacro(const clang::Token &macroNameToken,
const clang::MacroDefinition &macroDefinition) const clang::MacroDefinition &macroDefinition)
{ {
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 &macroNameToken, void addMacroAsSymbol(const clang::Token &macroNameToken,
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();

View File

@@ -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));

View File

@@ -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

View File

@@ -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);

View File

@@ -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)
{} {}

View File

@@ -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)
{ {
} }

View File

@@ -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;
}; };

View File

@@ -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

View File

@@ -0,0 +1,11 @@
#pragma once
#define HEADER_DEFINE
void HeaderFunction();
class Class
{
public:
int Member = 20;
};

View File

@@ -0,0 +1,5 @@
#include <symbolscollector_unmodified_header.h>
#define MAINFILE_DEFINE
void MainFileFunction();

View File

@@ -0,0 +1,5 @@
#include <symbolscollector_unmodified_header.h>
#define MAINFILE_DEFINE
void MainFileFunction();

View File

@@ -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")))));
}
} }