Clang: Collect source dependencies

It is quite easy because we track the include directives in the
preprocessor callbacks.

Change-Id: I2d7bd67b31f50c0d8d4a46c57e83dffa0c558dc7
Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
This commit is contained in:
Marco Bubke
2018-01-31 13:53:57 +01:00
parent b2d3951bde
commit 048224bef1
13 changed files with 93 additions and 16 deletions

View File

@@ -27,6 +27,7 @@
#include "fileinformation.h"
#include "symbolsvisitorbase.h"
#include "sourcedependency.h"
#include "sourcelocationsutils.h"
#include "sourcelocationentry.h"
#include "symbolentry.h"
@@ -50,6 +51,7 @@ public:
FilePathIds &sourceFiles,
UsedMacros &usedMacros,
FileInformations &fileInformations,
SourceDependencies &sourceDependencies,
FilePathCachingInterface &filePathCache,
const clang::SourceManager &sourceManager,
std::shared_ptr<clang::Preprocessor> &&preprocessor)
@@ -59,7 +61,8 @@ public:
m_sourceLocationEntries(sourceLocationEntries),
m_sourceFiles(sourceFiles),
m_usedMacros(usedMacros),
m_fileInformations(fileInformations)
m_fileInformations(fileInformations),
m_sourceDependencies(sourceDependencies)
{
}
@@ -73,14 +76,15 @@ public:
const clang::FileEntry *fileEntry = m_sourceManager.getFileEntryForID(
m_sourceManager.getFileID(sourceLocation));
if (fileEntry) {
m_fileInformations.emplace_back(filePathId(sourceLocation),
m_fileInformations.emplace_back(filePathId(fileEntry),
fileEntry->getSize(),
fileEntry->getModificationTime());
addSourceFile(fileEntry);
}
}
}
void InclusionDirective(clang::SourceLocation /*hashLocation*/,
void InclusionDirective(clang::SourceLocation hashLocation,
const clang::Token &/*includeToken*/,
llvm::StringRef /*fileName*/,
bool /*isAngled*/,
@@ -91,7 +95,7 @@ public:
const clang::Module * /*imported*/) override
{
if (!m_skipInclude && file)
addSourceFile(file);
addSourceDependency(file, hashLocation);
m_skipInclude = false;
}
@@ -268,18 +272,26 @@ public:
void addSourceFile(const clang::FileEntry *file)
{
auto filePathId = m_filePathCache.filePathId(
FilePath::fromNativeFilePath(absolutePath(file->getName())));
auto id = filePathId(file);
auto found = std::find(m_sourceFiles.begin(), m_sourceFiles.end(), filePathId);
auto found = std::find(m_sourceFiles.begin(), m_sourceFiles.end(), id);
if (found == m_sourceFiles.end() || *found != filePathId)
m_sourceFiles.insert(found, filePathId);
if (found == m_sourceFiles.end() || *found != id)
m_sourceFiles.insert(found, id);
}
void addSourceDependency(const clang::FileEntry *file, clang::SourceLocation includeLocation)
{
auto includeFilePathId = filePathId(includeLocation);
auto includedFilePathId = filePathId(file);
m_sourceDependencies.emplace_back(includeFilePathId, includedFilePathId);
}
private:
UsedMacros m_maybeUsedMacros;
std::shared_ptr<clang::Preprocessor> m_preprocessor;
SourceDependencies &m_sourceDependencies;
SymbolEntries &m_symbolEntries;
SourceLocationEntries &m_sourceLocationEntries;
FilePathIds &m_sourceFiles;

View File

@@ -39,6 +39,7 @@ bool CollectMacrosSourceFileCallbacks::handleBeginSource(clang::CompilerInstance
m_sourceFiles,
m_usedMacros,
m_fileInformations,
m_sourceDependencies,
m_filePathCache,
compilerInstance.getSourceManager(),
compilerInstance.getPreprocessorPtr());

View File

@@ -26,6 +26,7 @@
#pragma once
#include "fileinformation.h"
#include "sourcedependency.h"
#include "sourcelocationentry.h"
#include "symbolentry.h"
#include "usedmacro.h"
@@ -77,10 +78,16 @@ public:
return m_fileInformations;
}
const SourceDependencies &sourceDependencies() const
{
return m_sourceDependencies;
}
private:
FilePathIds m_sourceFiles;
UsedMacros m_usedMacros;
FileInformations m_fileInformations;
SourceDependencies m_sourceDependencies;
SymbolEntries &m_symbolEntries;
SourceLocationEntries &m_sourceLocationEntries;
FilePathCachingInterface &m_filePathCache;

View File

@@ -87,4 +87,9 @@ const FileInformations &SymbolsCollector::fileInformations() const
return m_collectMacrosSourceFileCallbacks.fileInformations();
}
const SourceDependencies &SymbolsCollector::sourceDependencies() const
{
return m_collectMacrosSourceFileCallbacks.sourceDependencies();
}
} // namespace ClangBackEnd

View File

@@ -53,6 +53,7 @@ public:
const FilePathIds &sourceFiles() const override;
const UsedMacros &usedMacros() const override;
const FileInformations &fileInformations() const override;
const SourceDependencies &sourceDependencies() const override;
private:
ClangTool m_clangTool;

View File

@@ -27,6 +27,7 @@
#include "fileinformation.h"
#include "symbolentry.h"
#include "sourcedependency.h"
#include "sourcelocationentry.h"
#include "usedmacro.h"
@@ -56,6 +57,7 @@ public:
virtual const FilePathIds &sourceFiles() const = 0;
virtual const UsedMacros &usedMacros() const = 0;
virtual const FileInformations &fileInformations() const = 0;
virtual const SourceDependencies &sourceDependencies() const = 0;
};
} // namespace ClangBackEnd

View File

@@ -50,22 +50,30 @@ public:
FilePathId filePathId(clang::SourceLocation sourceLocation)
{
uint clangFileId = m_sourceManager.getFileID(sourceLocation).getHashValue();
clang::FileID clangFileId = m_sourceManager.getFileID(sourceLocation);
const clang::FileEntry *fileEntry = m_sourceManager.getFileEntryForID(clangFileId);
auto found = m_filePathIndices.find(clangFileId);
return filePathId(fileEntry);
}
if (found != m_filePathIndices.end())
return found->second;
FilePathId filePathId(const clang::FileEntry *fileEntry)
{
if (fileEntry) {
uint fileHash = fileEntry->getUID();
auto filePath = m_sourceManager.getFilename(sourceLocation);
auto found = m_filePathIndices.find(fileHash);
if (filePath.size() > 0) {
if (found != m_filePathIndices.end())
return found->second;
auto filePath = fileEntry->getName();
FilePathId filePathId = m_filePathCache.filePathId(FilePath::fromNativeFilePath(absolutePath(filePath)));
m_filePathIndices.emplace(clangFileId, filePathId);
m_filePathIndices.emplace(fileHash, filePathId);
return filePathId;
}
return {};
}