data: Improved file path caching in CXX indexer

* centralized all file path caching in CanonicalFilePathCache
* added cache by clang::FileID
* moved FileRegister into CanonicalFilePathCache and removed it from AST* classes
* only record files once
This commit is contained in:
Eberhard Graether
2018-07-27 12:39:55 +02:00
parent afec261872
commit 713a8eec50
19 changed files with 158 additions and 215 deletions
+6 -10
View File
@@ -3,14 +3,13 @@
#include <memory>
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Lex/Preprocessor.h"
#include <clang/Frontend/CompilerInstance.h>
#include <clang/Frontend/FrontendAction.h>
#include <clang/Lex/Preprocessor.h>
#include "data/parser/cxx/ASTConsumer.h"
#include "data/parser/cxx/CommentHandler.h"
#include "data/parser/cxx/PreprocessorCallbacks.h"
#include "utility/file/FileRegister.h"
template <typename ASTActionBase>
class ASTAction
@@ -19,13 +18,11 @@ class ASTAction
public:
explicit ASTAction(
std::shared_ptr<ParserClient> client,
std::shared_ptr<FileRegister> fileRegister,
std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache
)
: m_client(client)
, m_fileRegister(fileRegister)
, m_canonicalFilePathCache(canonicalFilePathCache)
, m_commentHandler(client, fileRegister, canonicalFilePathCache)
, m_commentHandler(client, canonicalFilePathCache)
{}
virtual ~ASTAction() {}
@@ -34,21 +31,20 @@ protected:
virtual std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(clang::CompilerInstance& compiler, llvm::StringRef inFile) override
{
return std::unique_ptr<clang::ASTConsumer>(
new ASTConsumer(&compiler.getASTContext(), &compiler.getPreprocessor(), m_client, m_fileRegister, m_canonicalFilePathCache));
new ASTConsumer(&compiler.getASTContext(), &compiler.getPreprocessor(), m_client, m_canonicalFilePathCache));
}
virtual bool BeginSourceFileAction(clang::CompilerInstance& compiler) override
{
clang::Preprocessor& preprocessor = compiler.getPreprocessor();
preprocessor.addPPCallbacks(
llvm::make_unique<PreprocessorCallbacks>(compiler.getSourceManager(), m_client, m_fileRegister, m_canonicalFilePathCache));
llvm::make_unique<PreprocessorCallbacks>(compiler.getSourceManager(), m_client, m_canonicalFilePathCache));
preprocessor.addCommentHandler(&m_commentHandler);
return true;
}
private:
std::shared_ptr<ParserClient> m_client;
std::shared_ptr<FileRegister> m_fileRegister;
std::shared_ptr<CanonicalFilePathCache> m_canonicalFilePathCache;
CommentHandler m_commentHandler;
};
@@ -1,15 +1,14 @@
#include "data/parser/cxx/ASTActionFactory.h"
#include "clang/Frontend/FrontendActions.h"
#include <clang/Frontend/FrontendActions.h>
#include "data/parser/cxx/ASTAction.h"
ASTActionFactory::ASTActionFactory(
std::shared_ptr<ParserClient> client,
std::shared_ptr<FileRegister> fileRegister,
std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache
)
: m_client(client)
, m_fileRegister(fileRegister)
, m_canonicalFilePathCache(canonicalFilePathCache)
{
}
@@ -20,5 +19,5 @@ ASTActionFactory::~ASTActionFactory()
clang::FrontendAction* ASTActionFactory::create()
{
return new ASTAction<clang::ASTFrontendAction>(m_client, m_fileRegister, m_canonicalFilePathCache);
return new ASTAction<clang::ASTFrontendAction>(m_client, m_canonicalFilePathCache);
}
@@ -1,9 +1,7 @@
#ifndef AST_ACTION_FACTORY
#define AST_ACTION_FACTORY
#include "clang/Tooling/Tooling.h"
#include "utility/file/FileRegister.h"
#include <clang/Tooling/Tooling.h>
class CanonicalFilePathCache;
class ParserClient;
@@ -14,7 +12,6 @@ class ASTActionFactory
public:
explicit ASTActionFactory(
std::shared_ptr<ParserClient> client,
std::shared_ptr<FileRegister> fileRegister,
std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache
);
@@ -24,7 +21,6 @@ public:
private:
std::shared_ptr<ParserClient> m_client;
std::shared_ptr<FileRegister> m_fileRegister;
std::shared_ptr<CanonicalFilePathCache> m_canonicalFilePathCache;
};
+2 -3
View File
@@ -8,7 +8,6 @@ ASTConsumer::ASTConsumer(
clang::ASTContext* context,
clang::Preprocessor* preprocessor,
std::shared_ptr<ParserClient> client,
std::shared_ptr<FileRegister> fileRegister,
std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache
)
{
@@ -16,11 +15,11 @@ ASTConsumer::ASTConsumer(
if (appSettings->getLoggingEnabled() && appSettings->getVerboseIndexerLoggingEnabled())
{
m_visitor = std::make_shared<CxxVerboseAstVisitor>(context, preprocessor, client, fileRegister, canonicalFilePathCache);
m_visitor = std::make_shared<CxxVerboseAstVisitor>(context, preprocessor, client, canonicalFilePathCache);
}
else
{
m_visitor = std::make_shared<CxxAstVisitor>(context, preprocessor, client, fileRegister, canonicalFilePathCache);
m_visitor = std::make_shared<CxxAstVisitor>(context, preprocessor, client, canonicalFilePathCache);
}
}
@@ -6,7 +6,6 @@
class CanonicalFilePathCache;
class CxxAstVisitor;
class FileRegister;
class ParserClient;
class ASTConsumer
@@ -17,7 +16,6 @@ public:
clang::ASTContext* context,
clang::Preprocessor* preprocessor,
std::shared_ptr<ParserClient> client,
std::shared_ptr<FileRegister> fileRegister,
std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache
);
@@ -3,6 +3,40 @@
#include "utility/utilityString.h"
#include "data/parser/cxx/utilityClang.h"
CanonicalFilePathCache::CanonicalFilePathCache(std::shared_ptr<FileRegister> fileRegister)
: m_fileRegister(fileRegister)
{
}
std::shared_ptr<FileRegister> CanonicalFilePathCache::getFileRegister() const
{
return m_fileRegister;
}
FilePath CanonicalFilePathCache::getCanonicalFilePath(const clang::FileID& fileId, const clang::SourceManager& sourceManager)
{
if (!fileId.isValid())
{
return FilePath();
}
auto it = m_fileIdMap.find(fileId);
if (it != m_fileIdMap.end())
{
return it->second;
}
FilePath filePath;
const clang::FileEntry* fileEntry = sourceManager.getFileEntryForID(fileId);
if (fileEntry != nullptr && fileEntry->isValid())
{
filePath = getCanonicalFilePath(fileEntry);
m_fileIdMap.emplace(fileId, filePath);
}
return filePath;
}
FilePath CanonicalFilePathCache::getCanonicalFilePath(const clang::FileEntry* entry)
{
@@ -13,8 +47,8 @@ FilePath CanonicalFilePathCache::getCanonicalFilePath(const std::wstring& path)
{
const std::wstring lowercasePath = utility::toLowerCase(path);
std::unordered_map<std::wstring, FilePath>::const_iterator it = m_map.find(lowercasePath);
if (it != m_map.end())
auto it = m_fileStringMap.find(lowercasePath);
if (it != m_fileStringMap.end())
{
return it->second;
}
@@ -22,8 +56,26 @@ FilePath CanonicalFilePathCache::getCanonicalFilePath(const std::wstring& path)
const FilePath canonicalPath = FilePath(path).makeCanonical();
const std::wstring lowercaseCanonicalPath = utility::toLowerCase(canonicalPath.wstr());
m_map.insert(std::make_pair(lowercasePath, canonicalPath));
m_map.insert(std::make_pair(lowercaseCanonicalPath, canonicalPath));
m_fileStringMap.emplace(std::move(lowercasePath), canonicalPath);
m_fileStringMap.emplace(std::move(lowercaseCanonicalPath), canonicalPath);
return canonicalPath;
}
bool CanonicalFilePathCache::isProjectFile(const clang::FileID fileId, const clang::SourceManager& sourceManager)
{
if (!fileId.isValid())
{
return false;
}
auto it = m_isProjectFileMap.find(fileId);
if (it != m_isProjectFileMap.end())
{
return it->second;
}
bool ret = m_fileRegister->hasFilePath(getCanonicalFilePath(fileId, sourceManager));
m_isProjectFileMap.emplace(fileId, ret);
return ret;
}
@@ -4,17 +4,31 @@
#include <string>
#include <unordered_map>
#include "clang/Basic/FileManager.h"
#include <clang/Basic/SourceManager.h>
#include "utility/file/FilePath.h"
#include "utility/file/FileRegister.h"
class CanonicalFilePathCache
{
public:
CanonicalFilePathCache(std::shared_ptr<FileRegister> fileRegister);
std::shared_ptr<FileRegister> getFileRegister() const;
FilePath getCanonicalFilePath(const clang::FileID& fileId, const clang::SourceManager& sourceManager);
FilePath getCanonicalFilePath(const clang::FileEntry* entry);
FilePath getCanonicalFilePath(const std::wstring& path);
bool isProjectFile(const clang::FileID fileId, const clang::SourceManager& sourceManager);
private:
std::unordered_map<std::wstring, FilePath> m_map;
std::shared_ptr<FileRegister> m_fileRegister;
std::map<clang::FileID, FilePath> m_fileIdMap;
std::unordered_map<std::wstring, FilePath> m_fileStringMap;
std::map<clang::FileID, bool> m_isProjectFileMap;
};
#endif // CANONICAL_FILE_PATH_CACHE_H
+14 -24
View File
@@ -4,15 +4,12 @@
#include "data/parser/cxx/utilityClang.h"
#include "data/parser/ParseLocation.h"
#include "data/parser/ParserClient.h"
#include "utility/file/FileRegister.h"
CommentHandler::CommentHandler(
std::shared_ptr<ParserClient> client,
std::shared_ptr<FileRegister> fileRegister,
std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache
)
: m_client(client)
, m_fileRegister(fileRegister)
, m_canonicalFilePathCache(canonicalFilePathCache)
{
}
@@ -23,30 +20,23 @@ CommentHandler::~CommentHandler()
bool CommentHandler::HandleComment(clang::Preprocessor& preprocessor, clang::SourceRange sourceRange)
{
clang::SourceManager& sourceManager = preprocessor.getSourceManager();
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(sourceRange.getBegin(), false);
const clang::PresumedLoc& presumedEnd = sourceManager.getPresumedLoc(sourceRange.getEnd(), false);
const clang::SourceManager& sourceManager = preprocessor.getSourceManager();
clang::FileID fileId = sourceManager.getFileID(sourceRange.getBegin());
const clang::FileID fileId = sourceManager.getFileID(sourceRange.getBegin());
FilePath filePath = m_canonicalFilePathCache->getCanonicalFilePath(fileId, sourceManager);
// find the location file
if (fileId.isValid())
if (m_canonicalFilePathCache->isProjectFile(fileId, sourceManager))
{
const clang::FileEntry* fileEntry = sourceManager.getFileEntryForID(fileId);
if (fileEntry != nullptr && fileEntry->isValid())
{
FilePath filePath = m_canonicalFilePathCache->getCanonicalFilePath(fileEntry);
if (m_fileRegister->hasFilePath(filePath))
{
m_client->recordComment(ParseLocation(
filePath,
presumedBegin.getLine(),
presumedBegin.getColumn(),
presumedEnd.getLine(),
presumedEnd.getColumn()
));
}
}
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(sourceRange.getBegin(), false);
const clang::PresumedLoc& presumedEnd = sourceManager.getPresumedLoc(sourceRange.getEnd(), false);
m_client->recordComment(ParseLocation(
filePath,
presumedBegin.getLine(),
presumedBegin.getColumn(),
presumedEnd.getLine(),
presumedEnd.getColumn()
));
}
return false;
+1 -4
View File
@@ -1,10 +1,9 @@
#ifndef COMMENT_HANDLER_H
#define COMMENT_HANDLER_H
#include "clang/Lex/Preprocessor.h"
#include <clang/Lex/Preprocessor.h>
class CanonicalFilePathCache;
class FileRegister;
class ParserClient;
class CommentHandler
@@ -13,7 +12,6 @@ class CommentHandler
public:
CommentHandler(
std::shared_ptr<ParserClient> client,
std::shared_ptr<FileRegister> fileRegister,
std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache
);
@@ -23,7 +21,6 @@ public:
private:
std::shared_ptr<ParserClient> m_client;
std::shared_ptr<FileRegister> m_fileRegister;
std::shared_ptr<CanonicalFilePathCache> m_canonicalFilePathCache;
};
+10 -52
View File
@@ -17,7 +17,6 @@
#include "data/parser/cxx/utilityClang.h"
#include "data/parser/ParserClient.h"
#include "data/parser/ParseLocation.h"
#include "utility/file/FileRegister.h"
#include "utility/utilityString.h"
@@ -25,13 +24,11 @@ CxxAstVisitor::CxxAstVisitor(
clang::ASTContext* astContext,
clang::Preprocessor* preprocessor,
std::shared_ptr<ParserClient> client,
std::shared_ptr<FileRegister> fileRegister,
std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache
)
: m_astContext(astContext)
, m_preprocessor(preprocessor)
, m_client(client)
, m_fileRegister(fileRegister)
, m_canonicalFilePathCache(canonicalFilePathCache)
{
m_declNameCache = std::make_shared<DeclNameCache>([&](const clang::NamedDecl* decl) -> NameHierarchy
@@ -702,14 +699,7 @@ ParseLocation CxxAstVisitor::getParseLocation(const clang::SourceLocation& sourc
const clang::FileID fileId = sourceManager.getFileID(startLoc);
// find the location file
if (!fileId.isInvalid())
{
const clang::FileEntry* fileEntry = sourceManager.getFileEntryForID(fileId);
if (fileEntry != nullptr && fileEntry->isValid())
{
parseLocation.filePath = m_canonicalFilePathCache->getCanonicalFilePath(fileEntry);
}
}
parseLocation.filePath = m_canonicalFilePathCache->getCanonicalFilePath(fileId, sourceManager);
// find the start location
{
@@ -765,17 +755,10 @@ ParseLocation CxxAstVisitor::getParseLocation(const clang::SourceRange& sourceRa
const clang::PresumedLoc presumedBegin = sourceManager.getPresumedLoc(beginLoc, false);
const clang::PresumedLoc presumedEnd = sourceManager.getPresumedLoc(endLoc.isValid() ? endLoc : range.getEnd(), false);
FilePath filePath;
FilePath filePath = m_canonicalFilePathCache->getCanonicalFilePath(sourceManager.getFileID(beginLoc), sourceManager);
if (filePath.empty())
{
const clang::FileEntry* fileEntry = sourceManager.getFileEntryForID(sourceManager.getFileID(beginLoc));
if (fileEntry != nullptr && fileEntry->isValid())
{
filePath = m_canonicalFilePathCache->getCanonicalFilePath(fileEntry);
}
else
{
filePath = m_canonicalFilePathCache->getCanonicalFilePath(utility::decodeFromUtf8(presumedBegin.getFilename()));
}
filePath = m_canonicalFilePathCache->getCanonicalFilePath(utility::decodeFromUtf8(presumedBegin.getFilename()));
}
parseLocation = ParseLocation(
@@ -845,36 +828,11 @@ bool CxxAstVisitor::shouldVisitReference(const clang::SourceLocation& referenceL
bool CxxAstVisitor::isLocatedInProjectFile(clang::SourceLocation loc) const
{
if (loc.isInvalid())
{
return false;
}
const clang::SourceManager& sourceManager = m_astContext->getSourceManager();
clang::FileID fileId;
if (loc.isValid())
{
if (sourceManager.isWrittenInMainFile(loc))
{
return true;
}
fileId = sourceManager.getFileID(loc);
}
if (fileId.isValid())
{
auto it = m_inProjectFileMap.find(fileId);
if (it != m_inProjectFileMap.end())
{
return it->second;
}
const clang::FileEntry* fileEntry = sourceManager.getFileEntryForID(fileId);
if (fileEntry != nullptr && fileEntry->isValid())
{
FilePath filePath = m_canonicalFilePathCache->getCanonicalFilePath(fileEntry);
const bool ret = m_fileRegister->hasFilePath(filePath);
m_inProjectFileMap[fileId] = ret;
return ret;
}
}
return false;
return m_canonicalFilePathCache->isProjectFile(sourceManager.getFileID(loc), sourceManager);
}
@@ -11,7 +11,6 @@
class CanonicalFilePathCache;
class ParserClient;
struct ParseLocation;
class FileRegister;
class FilePath;
class CxxAstVisitorComponent;
@@ -41,7 +40,6 @@ public:
clang::ASTContext* astContext,
clang::Preprocessor* preprocessor,
std::shared_ptr<ParserClient> client,
std::shared_ptr<FileRegister> fileRegister,
std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache
);
virtual ~CxxAstVisitor() = default;
@@ -161,7 +159,6 @@ private:
clang::ASTContext* m_astContext;
clang::Preprocessor* m_preprocessor;
std::shared_ptr<ParserClient> m_client;
std::shared_ptr<FileRegister> m_fileRegister;
std::shared_ptr<CanonicalFilePathCache> m_canonicalFilePathCache;
MessageInterruptTasksCounter m_interruptCounter;
@@ -176,16 +173,6 @@ private:
std::shared_ptr<DeclNameCache> m_declNameCache;
std::shared_ptr<TypeNameCache> m_typeNameCache;
struct FileIdHash
{
size_t operator()(clang::FileID fileID) const
{
return fileID.getHashValue();
}
};
mutable std::unordered_map<const clang::FileID, bool, FileIdHash> m_inProjectFileMap;
};
template <>
@@ -7,21 +7,18 @@
#include "data/parser/cxx/utilityClang.h"
#include "data/parser/ParseLocation.h"
#include "data/parser/ParserClient.h"
#include "utility/file/FileRegister.h"
#include "utility/utilityString.h"
CxxDiagnosticConsumer::CxxDiagnosticConsumer(
clang::raw_ostream &os,
clang::DiagnosticOptions *diags,
std::shared_ptr<ParserClient> client,
std::shared_ptr<FileRegister> fileRegister,
std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache,
const FilePath& sourceFilePath,
bool useLogging
)
: clang::TextDiagnosticPrinter(os, diags)
, m_client(client)
, m_register(fileRegister)
, m_canonicalFilePathCache(canonicalFilePathCache)
, m_sourceFilePath(sourceFilePath)
, m_isParsingFile(false)
@@ -36,8 +33,6 @@ void CxxDiagnosticConsumer::BeginSourceFile(const clang::LangOptions& langOption
clang::TextDiagnosticPrinter::BeginSourceFile(langOptions, preProcessor);
}
m_isParsingFile = true;
}
@@ -111,7 +106,7 @@ void CxxDiagnosticConsumer::HandleDiagnostic(clang::DiagnosticsEngine::Level lev
location,
utility::decodeFromUtf8(message),
level == clang::DiagnosticsEngine::Fatal,
m_register->hasFilePath(location.filePath),
m_canonicalFilePathCache->getFileRegister()->hasFilePath(location.filePath),
m_sourceFilePath
);
}
@@ -5,7 +5,6 @@
#include "utility/file/FilePath.h"
class CanonicalFilePathCache;
class FileRegister;
class ParserClient;
class CxxDiagnosticConsumer
@@ -16,7 +15,6 @@ public:
clang::raw_ostream &os,
clang::DiagnosticOptions *diags,
std::shared_ptr<ParserClient> client,
std::shared_ptr<FileRegister> fileRegister,
std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache,
const FilePath& sourceFilePath,
bool useLogging = true
@@ -29,7 +27,6 @@ public:
private:
std::shared_ptr<ParserClient> m_client;
std::shared_ptr<FileRegister> m_register;
std::shared_ptr<CanonicalFilePathCache> m_canonicalFilePathCache;
const FilePath m_sourceFilePath;
+8 -7
View File
@@ -1,7 +1,7 @@
#include "data/parser/cxx/CxxParser.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/Support/TargetSelect.h"
#include <clang/Tooling/Tooling.h>
#include <llvm/Support/TargetSelect.h>
#include "data/indexer/IndexerCommandCxxCdb.h"
#include "data/indexer/IndexerCommandCxxEmpty.h"
@@ -101,10 +101,11 @@ void CxxParser::buildIndex(std::shared_ptr<IndexerCommandCxxEmpty> indexerComman
void CxxParser::buildIndex(const std::wstring& fileName, std::shared_ptr<TextAccess> fileContent, std::vector<std::wstring> compilerFlags)
{
std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache = std::make_shared<CanonicalFilePathCache>();
std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache =
std::make_shared<CanonicalFilePathCache>(m_fileRegister);
std::shared_ptr<CxxDiagnosticConsumer> diagnostics = getDiagnostics(FilePath(), canonicalFilePathCache, false);
ASTActionFactory actionFactory(m_client, m_fileRegister, canonicalFilePathCache);
ASTActionFactory actionFactory(m_client, canonicalFilePathCache);
std::vector<std::string> args = getCommandlineArgumentsEssential(compilerFlags, std::vector<FilePath>(), std::vector<FilePath>());
@@ -121,13 +122,13 @@ void CxxParser::runTool(clang::tooling::CompilationDatabase* compilationDatabase
{
clang::tooling::ClangTool tool(*compilationDatabase, std::vector<std::string>(1, utility::encodeToUtf8(sourceFilePath.wstr())));
std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache = std::make_shared<CanonicalFilePathCache>();
std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache = std::make_shared<CanonicalFilePathCache>(m_fileRegister);
std::shared_ptr<CxxDiagnosticConsumer> diagnostics = getDiagnostics(sourceFilePath, canonicalFilePathCache, true);
tool.setDiagnosticConsumer(diagnostics.get());
ASTActionFactory actionFactory(m_client, m_fileRegister, canonicalFilePathCache);
ASTActionFactory actionFactory(m_client, canonicalFilePathCache);
tool.run(&actionFactory);
}
@@ -201,6 +202,6 @@ std::shared_ptr<CxxDiagnosticConsumer> CxxParser::getDiagnostics(const FilePath&
{
llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> options = new clang::DiagnosticOptions();
return std::make_shared<CxxDiagnosticConsumer>(
llvm::errs(), &*options, m_client, m_fileRegister, canonicalFilePathCache, sourceFilePath, logErrors
llvm::errs(), &*options, m_client, canonicalFilePathCache, sourceFilePath, logErrors
);
}
@@ -7,7 +7,6 @@
#include "data/parser/ParseLocation.h"
#include "data/parser/ParserClient.h"
#include "utility/file/FileRegister.h"
#include "utility/logging/logging.h"
#include "utility/ScopedSwitcher.h"
@@ -16,10 +15,9 @@ CxxVerboseAstVisitor::CxxVerboseAstVisitor(
clang::ASTContext* context,
clang::Preprocessor* preprocessor,
std::shared_ptr<ParserClient> client,
std::shared_ptr<FileRegister> fileRegister,
std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache
)
: base(context, preprocessor, client, fileRegister, canonicalFilePathCache)
: base(context, preprocessor, client, canonicalFilePathCache)
, m_currentFilePath(L"")
, m_indentation(0)
{
@@ -1,3 +1,4 @@
#ifndef CXX_VERBOSE_AST_VISITOR_H
#define CXX_VERBOSE_AST_VISITOR_H
@@ -7,7 +8,6 @@
class CanonicalFilePathCache;
class ParserClient;
class FileRegister;
class CxxVerboseAstVisitor: public CxxAstVisitor
{
@@ -16,7 +16,6 @@ public:
clang::ASTContext* context,
clang::Preprocessor* preprocessor,
std::shared_ptr<ParserClient> client,
std::shared_ptr<FileRegister> fileRegister,
std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache
);
@@ -1,8 +1,8 @@
#include "data/parser/cxx/PreprocessorCallbacks.h"
#include "clang/Driver/Util.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Lex/MacroArgs.h"
#include <clang/Driver/Util.h>
#include <clang/Basic/IdentifierTable.h>
#include <clang/Lex/MacroArgs.h>
#include "data/parser/cxx/CanonicalFilePathCache.h"
#include "data/parser/cxx/utilityClang.h"
@@ -10,18 +10,15 @@
#include "data/parser/ParseLocation.h"
#include "utility/file/FileSystem.h"
#include "utility/file/FileRegister.h"
#include "utility/utilityString.h"
PreprocessorCallbacks::PreprocessorCallbacks(
clang::SourceManager& sourceManager,
std::shared_ptr<ParserClient> client,
std::shared_ptr<FileRegister> fileRegister,
std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache
)
: m_sourceManager(sourceManager)
, m_client(client)
, m_fileRegister(fileRegister)
, m_canonicalFilePathCache(canonicalFilePathCache)
{
}
@@ -29,17 +26,18 @@ PreprocessorCallbacks::PreprocessorCallbacks(
void PreprocessorCallbacks::FileChanged(
clang::SourceLocation location, FileChangeReason reason, clang::SrcMgr::CharacteristicKind, clang::FileID prevID)
{
m_currentPath = FilePath();
const clang::FileID fileId = m_sourceManager.getFileID(location);
m_currentPath = m_canonicalFilePathCache->getCanonicalFilePath(fileId, m_sourceManager);
m_currentPathIsProjectFile = false;
const clang::FileEntry* fileEntry = m_sourceManager.getFileEntryForID(m_sourceManager.getFileID(location));
if (fileEntry != nullptr && fileEntry->isValid())
if (!m_currentPath.empty())
{
m_currentPath = m_canonicalFilePathCache->getCanonicalFilePath(fileEntry);
m_currentPathIsProjectFile = m_canonicalFilePathCache->getFileRegister()->hasFilePath(m_currentPath);
if (!m_currentPath.empty())
if (m_fileWasRecorded.find(fileId) == m_fileWasRecorded.end())
{
bool hasFilePath = m_fileRegister->hasFilePath(m_currentPath);
m_client->recordFile(FileSystem::getFileInfoForPath(m_currentPath), hasFilePath); // todo: fix for tests
m_client->recordFile(FileSystem::getFileInfoForPath(m_currentPath), m_currentPathIsProjectFile); // todo: fix for tests
m_fileWasRecorded.insert(fileId);
}
}
}
@@ -66,7 +64,7 @@ void PreprocessorCallbacks::InclusionDirective(
void PreprocessorCallbacks::MacroDefined(const clang::Token& macroNameToken, const clang::MacroDirective* macroDirective)
{
if (!m_currentPath.empty() && m_fileRegister->hasFilePath(m_currentPath))
if (m_currentPathIsProjectFile)
{
// ignore builtin macros
if (m_sourceManager.getSpellingLoc(macroNameToken.getLocation()).printToString(m_sourceManager)[0] == '<')
@@ -119,7 +117,7 @@ void PreprocessorCallbacks::MacroExpands(
void PreprocessorCallbacks::onMacroUsage(const clang::Token& macroNameToken)
{
if (!m_currentPath.empty() && m_fileRegister->hasFilePath(m_currentPath) && isLocatedInProjectFile(macroNameToken.getLocation()))
if (m_currentPathIsProjectFile && isLocatedInProjectFile(macroNameToken.getLocation()))
{
const ParseLocation loc = getParseLocation(macroNameToken);
@@ -140,11 +138,11 @@ ParseLocation PreprocessorCallbacks::getParseLocation(const clang::Token& macroN
const clang::SourceLocation& location = m_sourceManager.getSpellingLoc(macroNameTok.getLocation());
const clang::SourceLocation& endLocation = m_sourceManager.getSpellingLoc(macroNameTok.getEndLoc());
const clang::FileEntry* fileEntry = m_sourceManager.getFileEntryForID(m_sourceManager.getFileID(location));
if (fileEntry != nullptr && fileEntry->isValid())
FilePath filePath = m_canonicalFilePathCache->getCanonicalFilePath(m_sourceManager.getFileID(location), m_sourceManager);
if (!filePath.empty())
{
return ParseLocation(
m_canonicalFilePathCache->getCanonicalFilePath(fileEntry),
filePath,
m_sourceManager.getSpellingLineNumber(location),
m_sourceManager.getSpellingColumnNumber(location),
m_sourceManager.getSpellingLineNumber(endLocation),
@@ -160,11 +158,11 @@ ParseLocation PreprocessorCallbacks::getParseLocation(const clang::MacroInfo* ma
clang::SourceLocation location = macroInfo->getDefinitionLoc();
clang::SourceLocation endLocation = macroInfo->getDefinitionEndLoc();
const clang::FileEntry* fileEntry = m_sourceManager.getFileEntryForID(m_sourceManager.getFileID(location));
if (fileEntry != nullptr && fileEntry->isValid())
FilePath filePath = m_canonicalFilePathCache->getCanonicalFilePath(m_sourceManager.getFileID(location), m_sourceManager);
if (!filePath.empty())
{
return ParseLocation(
m_canonicalFilePathCache->getCanonicalFilePath(fileEntry),
filePath,
m_sourceManager.getSpellingLineNumber(location),
m_sourceManager.getSpellingColumnNumber(location),
m_sourceManager.getSpellingLineNumber(endLocation),
@@ -182,11 +180,13 @@ ParseLocation PreprocessorCallbacks::getParseLocation(const clang::SourceRange&
const clang::PresumedLoc& presumedBegin = m_sourceManager.getPresumedLoc(sourceRange.getBegin(), false);
const clang::PresumedLoc& presumedEnd = m_sourceManager.getPresumedLoc(sourceRange.getEnd(), false);
const clang::FileEntry *fileEntry = m_sourceManager.getFileEntryForID(m_sourceManager.getFileID(sourceRange.getBegin()));
if (fileEntry != nullptr && fileEntry->isValid())
FilePath filePath = m_canonicalFilePathCache->getCanonicalFilePath(
m_sourceManager.getFileID(sourceRange.getBegin()), m_sourceManager);
if (!filePath.empty())
{
return ParseLocation(
m_canonicalFilePathCache->getCanonicalFilePath(fileEntry),
filePath,
presumedBegin.getLine(),
presumedBegin.getColumn(),
presumedEnd.getLine(),
@@ -201,30 +201,10 @@ bool PreprocessorCallbacks::isLocatedInProjectFile(const clang::SourceLocation l
{
// we need the spelling loc here, since this is the location where the macro comes from
clang::SourceLocation spellingLoc = m_sourceManager.getSpellingLoc(loc);
clang::FileID fileId;
if (spellingLoc.isValid())
if (!spellingLoc.isValid())
{
fileId = m_sourceManager.getFileID(spellingLoc);
return false;
}
if (fileId.isValid())
{
auto it = m_inProjectFileMap.find(fileId);
if (it != m_inProjectFileMap.end())
{
return it->second;
}
const clang::FileEntry* fileEntry = m_sourceManager.getFileEntryForID(fileId);
if (fileEntry != nullptr && fileEntry->isValid())
{
const FilePath filePath = m_canonicalFilePathCache->getCanonicalFilePath(fileEntry);
bool ret = m_fileRegister->hasFilePath(filePath);
m_inProjectFileMap[fileId] = ret;
return ret;
}
}
return false;
return m_canonicalFilePathCache->isProjectFile(m_sourceManager.getFileID(spellingLoc), m_sourceManager);
}
@@ -2,7 +2,7 @@
#define PREPROCESSOR_CALLBACKS_H
#include <memory>
#include <unordered_map>
#include <set>
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/MacroInfo.h"
@@ -12,7 +12,6 @@
#include "utility/file/FilePath.h"
class CanonicalFilePathCache;
class FileRegister;
class ParserClient;
struct ParseLocation;
@@ -24,7 +23,6 @@ public:
explicit PreprocessorCallbacks(
clang::SourceManager& sourceManager,
std::shared_ptr<ParserClient> client,
std::shared_ptr<FileRegister> fileRegister,
std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache);
void FileChanged(
@@ -54,14 +52,6 @@ public:
) override;
private:
struct FileIdHash
{
size_t operator()(clang::FileID fileID) const
{
return fileID.getHashValue();
}
};
void onMacroUsage(const clang::Token& macroNameToken);
ParseLocation getParseLocation(const clang::Token& macroNameToc) const;
@@ -71,11 +61,12 @@ private:
const clang::SourceManager& m_sourceManager;
std::shared_ptr<ParserClient> m_client;
std::shared_ptr<FileRegister> m_fileRegister;
std::shared_ptr<CanonicalFilePathCache> m_canonicalFilePathCache;
std::unordered_map<const clang::FileID, bool, FileIdHash> m_inProjectFileMap;
FilePath m_currentPath;
bool m_currentPathIsProjectFile = false;
std::set<clang::FileID> m_fileWasRecorded;
};
#endif // PREPROCESSOR_CALLBACKS_H
@@ -215,7 +215,7 @@ std::shared_ptr<CxxDeclName> CxxDeclNameResolver::getDeclName(const clang::Named
else if (clang::isa<clang::ClassTemplatePartialSpecializationDecl>(declaration))
{
return std::make_shared<CxxDeclName>(
std::move(declNameString),
std::move(declNameString),
getTemplateParameterStringsOfPatrialSpecialitarion(
clang::dyn_cast<clang::ClassTemplatePartialSpecializationDecl>(declaration)
)
@@ -431,24 +431,20 @@ std::shared_ptr<CxxDeclName> CxxDeclNameResolver::getDeclName(const clang::Named
std::wstring CxxDeclNameResolver::getTranslationUnitMainFileName(const clang::Decl* declaration)
{
const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager();
clang::FileID fileId = sourceManager.getMainFileID();
if (fileId.isValid())
{
const clang::FileEntry* fileEntry = sourceManager.getFileEntryForID(fileId);
return getCanonicalFilePathCache()->getCanonicalFilePath(fileEntry).fileName();
}
return L"";
return getCanonicalFilePathCache()->getCanonicalFilePath(sourceManager.getMainFileID(), sourceManager).fileName();
}
std::wstring CxxDeclNameResolver::getDeclarationFileName(const clang::Decl* declaration)
{
const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager();
const clang::FileEntry* fileEntry = sourceManager.getFileEntryForID(sourceManager.getFileID(declaration->getLocStart()));
const clang::FileID fileId = sourceManager.getFileID(declaration->getLocStart());
const clang::FileEntry* fileEntry = sourceManager.getFileEntryForID(fileId);
if (fileEntry != nullptr && fileEntry->isValid())
{
return getCanonicalFilePathCache()->getCanonicalFilePath(fileEntry).fileName();
return getCanonicalFilePathCache()->getCanonicalFilePath(fileId, sourceManager).fileName();
}
return getCanonicalFilePathCache()->getCanonicalFilePath(utility::decodeFromUtf8(sourceManager.getPresumedLoc(declaration->getLocStart()).getFilename())).fileName();
return getCanonicalFilePathCache()->getCanonicalFilePath(
utility::decodeFromUtf8(sourceManager.getPresumedLoc(declaration->getLocStart()).getFilename())).fileName();
}
std::wstring CxxDeclNameResolver::getNameForAnonymousSymbol(const std::wstring& symbolKindName, const clang::Decl* declaration)