ClangRefactoring: Improve indexing

Fix some bugs in the indexing and use the new macro indexer from clang.

Change-Id: I2ba1b28097a8751aea942071851a60d164c6f371
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
Marco Bubke
2019-05-23 18:32:47 +02:00
parent b36e9d0e95
commit ee27ae2ef7
26 changed files with 393 additions and 454 deletions

View File

@@ -24,11 +24,13 @@
****************************************************************************/
#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>
@@ -115,33 +117,41 @@ 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 isParsedDeclaration || isParsedReference;
return isAlreadyParsed(fileId, m_symbolSourcesManager)
&& !m_symbolSourcesManager.dependentFilesModified();
}
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::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());
}
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*/)
{
const auto *namedDeclaration = clang::dyn_cast<clang::NamedDecl>(declaration);
if (namedDeclaration) {
if (!namedDeclaration->getIdentifier())
return true;
if (skipSymbol(m_sourceManager->getFileID(sourceLocation), symbolRoles)) {
namedDeclaration->getDeclName().dump();
if (skipSymbol(m_sourceManager->getFileID(sourceLocation), symbolRoles))
return true;
}
SymbolIndex globalId = toSymbolIndex(declaration->getCanonicalDecl());
@@ -168,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