data: ClangTool gets invoked for cpp files only, headers are parsed on-the-fly
This change adds the class FileRegister, that splits cpp and h files for the Parser and keeps track which headers have been parsed yet. TranslationUnits get only created for cpp files now, and headers are parsed on the fly. This reduces parse time by around half.
This commit is contained in:
@@ -4,9 +4,9 @@
|
||||
|
||||
#include "data/parser/cxx/PreprocessorCallbacks.h"
|
||||
|
||||
ASTAction::ASTAction(ParserClient* client, FileManager* fileManager)
|
||||
ASTAction::ASTAction(ParserClient* client, FileRegister* fileRegister)
|
||||
: m_client(client)
|
||||
, m_fileManager(fileManager)
|
||||
, m_fileRegister(fileRegister)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ ASTAction::~ASTAction()
|
||||
|
||||
std::unique_ptr<clang::ASTConsumer> ASTAction::CreateASTConsumer(clang::CompilerInstance& compiler, llvm::StringRef inFile)
|
||||
{
|
||||
return std::unique_ptr<clang::ASTConsumer>(new ASTConsumer(&compiler.getASTContext(), m_client, m_fileManager));
|
||||
return std::unique_ptr<clang::ASTConsumer>(new ASTConsumer(&compiler.getASTContext(), m_client, m_fileRegister));
|
||||
}
|
||||
|
||||
bool ASTAction::BeginSourceFileAction(clang::CompilerInstance& compiler, llvm::StringRef filePath)
|
||||
@@ -25,7 +25,12 @@ bool ASTAction::BeginSourceFileAction(clang::CompilerInstance& compiler, llvm::S
|
||||
|
||||
clang::Preprocessor& preprocessor = compiler.getPreprocessor();
|
||||
preprocessor.addPPCallbacks(
|
||||
llvm::make_unique<PreprocessorCallbacks>(compiler.getSourceManager(), m_client, m_fileManager));
|
||||
llvm::make_unique<PreprocessorCallbacks>(compiler.getSourceManager(), m_client, m_fileRegister));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ASTAction::EndSourceFileAction()
|
||||
{
|
||||
m_fileRegister->markParsingIncludeFilesParsed();
|
||||
}
|
||||
|
||||
@@ -5,21 +5,23 @@
|
||||
#include "clang/Frontend/FrontendAction.h"
|
||||
|
||||
#include "data/parser/cxx/ASTConsumer.h"
|
||||
#include "utility/file/FileManager.h"
|
||||
#include "utility/file/FileRegister.h"
|
||||
|
||||
class ASTAction : public clang::ASTFrontendAction
|
||||
{
|
||||
public:
|
||||
explicit ASTAction(ParserClient* client, FileManager* fileManager);
|
||||
explicit ASTAction(ParserClient* client, FileRegister* fileRegister);
|
||||
virtual ~ASTAction();
|
||||
|
||||
protected:
|
||||
virtual std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(clang::CompilerInstance& compiler, llvm::StringRef inFile);
|
||||
|
||||
virtual bool BeginSourceFileAction(clang::CompilerInstance& compiler, llvm::StringRef filePath);
|
||||
virtual void EndSourceFileAction();
|
||||
|
||||
private:
|
||||
ParserClient* m_client;
|
||||
FileManager* m_fileManager;
|
||||
FileRegister* m_fileRegister;
|
||||
};
|
||||
|
||||
#endif // AST_ACTION_H
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include "data/parser/cxx/ASTActionFactory.h"
|
||||
|
||||
ASTActionFactory::ASTActionFactory(ParserClient* client, FileManager* fileManager)
|
||||
ASTActionFactory::ASTActionFactory(ParserClient* client, FileRegister* fileRegister)
|
||||
: m_client(client)
|
||||
, m_fileManager(fileManager)
|
||||
, m_fileRegister(fileRegister)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -12,5 +12,5 @@ ASTActionFactory::~ASTActionFactory()
|
||||
|
||||
clang::FrontendAction* ASTActionFactory::create()
|
||||
{
|
||||
return new ASTAction(m_client, m_fileManager);
|
||||
return new ASTAction(m_client, m_fileRegister);
|
||||
}
|
||||
|
||||
@@ -4,19 +4,19 @@
|
||||
#include "clang/Tooling/Tooling.h"
|
||||
|
||||
#include "data/parser/cxx/ASTAction.h"
|
||||
#include "utility/file/FileManager.h"
|
||||
#include "utility/file/FileRegister.h"
|
||||
|
||||
class ASTActionFactory : public clang::tooling::FrontendActionFactory
|
||||
{
|
||||
public:
|
||||
explicit ASTActionFactory(ParserClient* client, FileManager* fileManager);
|
||||
explicit ASTActionFactory(ParserClient* client, FileRegister* fileRegister);
|
||||
virtual ~ASTActionFactory();
|
||||
|
||||
virtual clang::FrontendAction* create();
|
||||
|
||||
private:
|
||||
ParserClient* m_client;
|
||||
FileManager* m_fileManager;
|
||||
FileRegister* m_fileRegister;
|
||||
};
|
||||
|
||||
#endif // AST_ACTION_FACTORY
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
#include "data/parser/ParserClient.h"
|
||||
|
||||
ASTConsumer::ASTConsumer(clang::ASTContext* context, ParserClient* client, FileManager* fileManager)
|
||||
: m_visitor(context, client, fileManager)
|
||||
ASTConsumer::ASTConsumer(clang::ASTContext* context, ParserClient* client, FileRegister* fileRegister)
|
||||
: m_visitor(context, client, fileRegister)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -4,13 +4,15 @@
|
||||
#include "clang/AST/ASTConsumer.h"
|
||||
#include "clang/AST/ASTContext.h"
|
||||
|
||||
#include "data/parser/cxx/ASTVisitor.h"
|
||||
#include "utility/file/FileManager.h"
|
||||
#include "utility/file/FileRegister.h"
|
||||
|
||||
class ASTConsumer : public clang::ASTConsumer
|
||||
#include "data/parser/cxx/ASTVisitor.h"
|
||||
|
||||
class ASTConsumer
|
||||
: public clang::ASTConsumer
|
||||
{
|
||||
public:
|
||||
explicit ASTConsumer(clang::ASTContext* context, ParserClient* client, FileManager* fileManager);
|
||||
explicit ASTConsumer(clang::ASTContext* context, ParserClient* client, FileRegister* fileRegister);
|
||||
virtual ~ASTConsumer();
|
||||
|
||||
virtual void HandleTranslationUnit(clang::ASTContext& context);
|
||||
|
||||
@@ -3,6 +3,11 @@
|
||||
#include <clang/AST/ParentMap.h>
|
||||
#include <clang/Lex/Lexer.h>
|
||||
|
||||
#include "utility/file/FileManager.h"
|
||||
#include "utility/file/FileSystem.h"
|
||||
#include "utility/logging/logging.h"
|
||||
#include "utility/utilityString.h"
|
||||
|
||||
#include "data/parser/cxx/ASTBodyVisitor.h"
|
||||
#include "data/parser/cxx/utilityCxx.h"
|
||||
#include "data/parser/ParseFunction.h"
|
||||
@@ -10,14 +15,11 @@
|
||||
#include "data/parser/ParseTypeUsage.h"
|
||||
#include "data/parser/ParseVariable.h"
|
||||
#include "data/type/DataType.h"
|
||||
#include "utility/file/FileSystem.h"
|
||||
#include "utility/logging/logging.h"
|
||||
#include "utility/utilityString.h"
|
||||
|
||||
ASTVisitor::ASTVisitor(clang::ASTContext* context, ParserClient* client, FileManager* fileManager)
|
||||
ASTVisitor::ASTVisitor(clang::ASTContext* context, ParserClient* client, FileRegister* fileRegister)
|
||||
: m_context(context)
|
||||
, m_client(client)
|
||||
, m_fileManager(fileManager)
|
||||
, m_fileRegister(fileRegister)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -32,7 +34,7 @@ bool ASTVisitor::VisitStmt(const clang::Stmt* statement)
|
||||
|
||||
bool ASTVisitor::VisitTypedefDecl(clang::TypedefDecl* declaration)
|
||||
{
|
||||
if (isLocatedInMainFile(declaration))
|
||||
if (isLocatedInUnparsedProjectFile(declaration))
|
||||
{
|
||||
m_client->onTypedefParsed(
|
||||
getParseLocationForNamedDecl(declaration),
|
||||
@@ -47,7 +49,7 @@ bool ASTVisitor::VisitTypedefDecl(clang::TypedefDecl* declaration)
|
||||
|
||||
bool ASTVisitor::VisitCXXRecordDecl(clang::CXXRecordDecl* declaration)
|
||||
{
|
||||
if (isLocatedInMainFile(declaration))
|
||||
if (isLocatedInUnparsedProjectFile(declaration))
|
||||
{
|
||||
if (declaration->isClass())
|
||||
{
|
||||
@@ -96,7 +98,7 @@ bool ASTVisitor::VisitVarDecl(clang::VarDecl* declaration)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isLocatedInMainFile(declaration))
|
||||
if (isLocatedInUnparsedProjectFile(declaration))
|
||||
{
|
||||
clang::AccessSpecifier access = declaration->getAccess();
|
||||
|
||||
@@ -128,7 +130,7 @@ bool ASTVisitor::VisitVarDecl(clang::VarDecl* declaration)
|
||||
|
||||
bool ASTVisitor::VisitFieldDecl(clang::FieldDecl* declaration)
|
||||
{
|
||||
if (isLocatedInMainFile(declaration))
|
||||
if (isLocatedInUnparsedProjectFile(declaration))
|
||||
{
|
||||
m_client->onFieldParsed(
|
||||
getParseLocationForNamedDecl(declaration),
|
||||
@@ -148,7 +150,7 @@ bool ASTVisitor::VisitFunctionDecl(clang::FunctionDecl* declaration)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isLocatedInMainFile(declaration))
|
||||
if (isLocatedInUnparsedProjectFile(declaration))
|
||||
{
|
||||
m_client->onFunctionParsed(
|
||||
getParseLocationForNamedDecl(declaration),
|
||||
@@ -168,7 +170,7 @@ bool ASTVisitor::VisitFunctionDecl(clang::FunctionDecl* declaration)
|
||||
|
||||
bool ASTVisitor::VisitCXXMethodDecl(clang::CXXMethodDecl* declaration)
|
||||
{
|
||||
if (isLocatedInMainFile(declaration))
|
||||
if (isLocatedInUnparsedProjectFile(declaration))
|
||||
{
|
||||
ParserClient::AbstractionType abstraction = ParserClient::ABSTRACTION_NONE;
|
||||
if (declaration->isPure())
|
||||
@@ -208,7 +210,7 @@ bool ASTVisitor::VisitCXXMethodDecl(clang::CXXMethodDecl* declaration)
|
||||
|
||||
bool ASTVisitor::VisitCXXConstructorDecl(clang::CXXConstructorDecl* declaration)
|
||||
{
|
||||
if (isLocatedInMainFile(declaration))
|
||||
if (isLocatedInUnparsedProjectFile(declaration))
|
||||
{
|
||||
for (clang::CXXConstructorDecl::init_const_iterator it = declaration->init_begin(); it != declaration->init_end(); it++)
|
||||
{
|
||||
@@ -242,7 +244,7 @@ bool ASTVisitor::VisitCXXConstructorDecl(clang::CXXConstructorDecl* declaration)
|
||||
|
||||
bool ASTVisitor::VisitNamespaceDecl(clang::NamespaceDecl* declaration)
|
||||
{
|
||||
if (isLocatedInMainFile(declaration))
|
||||
if (isLocatedInUnparsedProjectFile(declaration))
|
||||
{
|
||||
m_client->onNamespaceParsed(
|
||||
declaration->isAnonymousNamespace() ? ParseLocation() : getParseLocationForNamedDecl(declaration),
|
||||
@@ -255,7 +257,7 @@ bool ASTVisitor::VisitNamespaceDecl(clang::NamespaceDecl* declaration)
|
||||
|
||||
bool ASTVisitor::VisitEnumDecl(clang::EnumDecl* declaration)
|
||||
{
|
||||
if (isLocatedInMainFile(declaration))
|
||||
if (isLocatedInUnparsedProjectFile(declaration))
|
||||
{
|
||||
m_client->onEnumParsed(
|
||||
getParseLocationForNamedDecl(declaration),
|
||||
@@ -269,7 +271,7 @@ bool ASTVisitor::VisitEnumDecl(clang::EnumDecl* declaration)
|
||||
|
||||
bool ASTVisitor::VisitEnumConstantDecl(clang::EnumConstantDecl* declaration)
|
||||
{
|
||||
if (isLocatedInMainFile(declaration))
|
||||
if (isLocatedInUnparsedProjectFile(declaration))
|
||||
{
|
||||
m_client->onEnumConstantParsed(
|
||||
getParseLocation(declaration->getSourceRange()),
|
||||
@@ -281,7 +283,7 @@ bool ASTVisitor::VisitEnumConstantDecl(clang::EnumConstantDecl* declaration)
|
||||
|
||||
bool ASTVisitor::VisitTemplateTypeParmDecl(clang::TemplateTypeParmDecl *declaration)
|
||||
{
|
||||
if (declaration->hasDefaultArgument())
|
||||
if (isLocatedInUnparsedProjectFile(declaration) && declaration->hasDefaultArgument())
|
||||
{
|
||||
m_client->onTemplateDefaultArgumentTypeParsed(
|
||||
getParseTypeUsage(declaration->getDefaultArgumentInfo()->getTypeLoc(), declaration->getDefaultArgument()),
|
||||
@@ -294,27 +296,24 @@ bool ASTVisitor::VisitTemplateTypeParmDecl(clang::TemplateTypeParmDecl *declarat
|
||||
bool ASTVisitor::VisitClassTemplateDecl(clang::ClassTemplateDecl* declaration)
|
||||
{
|
||||
std::vector<std::string> rarchy = utility::getDeclNameHierarchy(declaration);
|
||||
if (isLocatedInMainFile(declaration))
|
||||
if (isLocatedInUnparsedProjectFile(declaration))
|
||||
{
|
||||
std::vector<std::string> templateRecordNameHierarchy = utility::getDeclNameHierarchy(declaration);
|
||||
clang::TemplateParameterList* parameterList = declaration->getTemplateParameters();
|
||||
for (size_t i = 0; i < parameterList->size(); i++)
|
||||
{
|
||||
clang::NamedDecl* namedDecl = parameterList->getParam(i);
|
||||
if (isLocatedInMainFile(namedDecl))
|
||||
{
|
||||
m_client->onTemplateRecordParameterTypeParsed(
|
||||
getParseLocationForNamedDecl(namedDecl),
|
||||
utility::getDeclNameHierarchy(namedDecl),
|
||||
templateRecordNameHierarchy
|
||||
);
|
||||
}
|
||||
m_client->onTemplateRecordParameterTypeParsed(
|
||||
getParseLocationForNamedDecl(namedDecl),
|
||||
utility::getDeclNameHierarchy(namedDecl),
|
||||
templateRecordNameHierarchy
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// for implicit template specializations we do not need a valid location of the original template class definition (since that file could be included)
|
||||
// handles explicit specializations and implicit specializations but no explicit partial specializations
|
||||
if (isLocatedInSourceFile(declaration))
|
||||
if (isLocatedInProjectFile(declaration)) // TODO: evaluate if explicit specializations have to be parsed in every source file
|
||||
{
|
||||
for (clang::ClassTemplateDecl::spec_iterator it = declaration->specializations().begin();
|
||||
it != declaration->specializations().end(); it++
|
||||
@@ -354,7 +353,7 @@ bool ASTVisitor::VisitClassTemplateDecl(clang::ClassTemplateDecl* declaration)
|
||||
|
||||
bool ASTVisitor::VisitClassTemplatePartialSpecializationDecl(clang::ClassTemplatePartialSpecializationDecl* declaration)
|
||||
{
|
||||
if (isLocatedInMainFile(declaration))
|
||||
if (isLocatedInUnparsedProjectFile(declaration))
|
||||
{
|
||||
std::vector<std::string> specializedRecordNameHierarchy = utility::getDeclNameHierarchy(declaration);
|
||||
std::vector<std::string> specializationParentNameHierarchy = utility::getTemplateSpecializationParentNameHierarchy(declaration);
|
||||
@@ -368,26 +367,27 @@ bool ASTVisitor::VisitClassTemplatePartialSpecializationDecl(clang::ClassTemplat
|
||||
for (size_t i = 0; i < parameterList->size(); i++)
|
||||
{
|
||||
clang::NamedDecl* namedDecl = parameterList->getParam(i);
|
||||
if (isLocatedInMainFile(namedDecl))
|
||||
{
|
||||
m_client->onTemplateRecordParameterTypeParsed(
|
||||
getParseLocationForNamedDecl(namedDecl),
|
||||
utility::getDeclNameHierarchy(namedDecl),
|
||||
specializedRecordNameHierarchy
|
||||
);
|
||||
}
|
||||
m_client->onTemplateRecordParameterTypeParsed(
|
||||
getParseLocationForNamedDecl(namedDecl),
|
||||
utility::getDeclNameHierarchy(namedDecl),
|
||||
specializedRecordNameHierarchy
|
||||
);
|
||||
}
|
||||
|
||||
const clang::ASTTemplateArgumentListInfo* argumentInfoList = declaration->getTemplateArgsAsWritten();
|
||||
for (size_t i = 0; i < argumentInfoList->NumTemplateArgs; i++)
|
||||
{
|
||||
const clang::TemplateArgumentLoc& argumentLoc = argumentInfoList->operator[](i);
|
||||
const clang::QualType argumentType = argumentLoc.getArgument().getAsType();
|
||||
const clang::TemplateArgument& argument = argumentLoc.getArgument();
|
||||
if (argument.getKind() == clang::TemplateArgument::Type)
|
||||
{
|
||||
const clang::QualType argumentType = argument.getAsType();
|
||||
|
||||
m_client->onTemplateArgumentParsed(
|
||||
getParseLocation(argumentLoc.getSourceRange()),
|
||||
utility::qualTypeToDataType(argumentType).getTypeNameHierarchy(),
|
||||
specializedRecordNameHierarchy);
|
||||
m_client->onTemplateArgumentParsed(
|
||||
getParseLocation(argumentLoc.getSourceRange()),
|
||||
utility::qualTypeToDataType(argumentType).getTypeNameHierarchy(),
|
||||
specializedRecordNameHierarchy);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -396,14 +396,14 @@ bool ASTVisitor::VisitClassTemplatePartialSpecializationDecl(clang::ClassTemplat
|
||||
bool ASTVisitor::VisitFunctionTemplateDecl(clang::FunctionTemplateDecl *declaration)
|
||||
{
|
||||
const ParseFunction templateFunction = getParseFunction(declaration);
|
||||
if (isLocatedInMainFile(declaration))
|
||||
if (isLocatedInUnparsedProjectFile(declaration))
|
||||
{
|
||||
clang::TemplateParameterList* parameterList = declaration->getTemplateParameters();
|
||||
for (size_t i = 0; i < parameterList->size(); i++)
|
||||
{
|
||||
clang::NamedDecl* namedDecl = parameterList->getParam(i);
|
||||
|
||||
if (isLocatedInMainFile(namedDecl))
|
||||
if (isLocatedInUnparsedProjectFile(namedDecl))
|
||||
{
|
||||
std::vector<std::string> templateParameterTypeNameHierarchy = utility::getDeclNameHierarchy(namedDecl);
|
||||
|
||||
@@ -415,7 +415,7 @@ bool ASTVisitor::VisitFunctionTemplateDecl(clang::FunctionTemplateDecl *declarat
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isLocatedInSourceFile(declaration))
|
||||
if (isLocatedInProjectFile(declaration))
|
||||
{
|
||||
for (clang::FunctionTemplateDecl::spec_iterator it = declaration->specializations().begin(); it != declaration->specializations().end(); it++)
|
||||
{
|
||||
@@ -426,7 +426,7 @@ bool ASTVisitor::VisitFunctionTemplateDecl(clang::FunctionTemplateDecl *declarat
|
||||
clang::FunctionTemplateSpecializationInfo* info = specializedFunctionDecl->getTemplateSpecializationInfo();
|
||||
if (info->getTemplateSpecializationKind() == clang::TSK_ExplicitSpecialization)
|
||||
{
|
||||
if (isLocatedInMainFile(declaration))
|
||||
if (isLocatedInUnparsedProjectFile(declaration))
|
||||
{
|
||||
m_client->onTemplateFunctionSpecializationParsed(
|
||||
specializedFunctionLocation,
|
||||
@@ -672,20 +672,31 @@ void ASTVisitor::VisitVarDeclInDeclBody(clang::FunctionDecl* decl, clang::VarDec
|
||||
);
|
||||
}
|
||||
|
||||
bool ASTVisitor::isLocatedInMainFile(const clang::Decl* declaration) const
|
||||
bool ASTVisitor::isLocatedInUnparsedProjectFile(const clang::Decl* declaration) const
|
||||
{
|
||||
const clang::SourceLocation& location = declaration->getLocStart();
|
||||
return location.isValid() && m_context->getSourceManager().isWrittenInMainFile(location);
|
||||
|
||||
if (!location.isValid())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_context->getSourceManager().isWrittenInMainFile(location))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_fileRegister->includeFileIsParsing(m_context->getSourceManager().getFilename(location));
|
||||
}
|
||||
|
||||
bool ASTVisitor::isLocatedInSourceFile(const clang::Decl* declaration) const
|
||||
bool ASTVisitor::isLocatedInProjectFile(const clang::Decl* declaration) const
|
||||
{
|
||||
const clang::SourceLocation& location = declaration->getLocStart();
|
||||
if (location.isValid())
|
||||
{
|
||||
const clang::SourceManager& sourceManager = m_context->getSourceManager();
|
||||
std::string filePath = FileSystem::absoluteFilePath(sourceManager.getFilename(location));
|
||||
return m_fileManager->hasFilePath(filePath);
|
||||
return m_fileRegister->getFileManager()->hasFilePath(filePath);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -4,16 +4,17 @@
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/RecursiveASTVisitor.h"
|
||||
|
||||
#include "utility/file/FileRegister.h"
|
||||
|
||||
#include "data/parser/cxx/ASTBodyVisitorClient.h"
|
||||
#include "data/parser/ParserClient.h"
|
||||
#include "utility/file/FileManager.h"
|
||||
|
||||
class ASTVisitor
|
||||
: public clang::RecursiveASTVisitor<ASTVisitor>
|
||||
, public ASTBodyVisitorClient
|
||||
{
|
||||
public:
|
||||
ASTVisitor(clang::ASTContext* context, ParserClient* client, FileManager* fileManager);
|
||||
ASTVisitor(clang::ASTContext* context, ParserClient* client, FileRegister* fileRegister);
|
||||
virtual ~ASTVisitor();
|
||||
|
||||
// Left for debugging purposes. Uncomment to see a colored ast-dump of the parsed file.
|
||||
@@ -57,8 +58,9 @@ public:
|
||||
virtual void VisitVarDeclInDeclBody(clang::FunctionDecl* decl, clang::VarDecl* varDecl); // type usages
|
||||
|
||||
private:
|
||||
bool isLocatedInMainFile(const clang::Decl* declaration) const;
|
||||
bool isLocatedInSourceFile(const clang::Decl* declaration) const;
|
||||
bool isLocatedInUnparsedProjectFile(const clang::Decl* declaration) const;
|
||||
bool isLocatedInProjectFile(const clang::Decl* declaration) const;
|
||||
|
||||
ParserClient::AccessType convertAccessType(clang::AccessSpecifier) const;
|
||||
|
||||
ParseLocation getParseLocation(const clang::SourceRange& sourceRange) const;
|
||||
@@ -77,7 +79,7 @@ private:
|
||||
|
||||
clang::ASTContext* m_context;
|
||||
ParserClient* m_client;
|
||||
FileManager* m_fileManager;
|
||||
FileRegister* m_fileRegister;
|
||||
};
|
||||
|
||||
#endif // AST_VISITOR_H
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "data/parser/cxx/CxxParser.h"
|
||||
|
||||
#include "utility/file/FileRegister.h"
|
||||
#include "utility/logging/logging.h"
|
||||
#include "utility/text/TextAccess.h"
|
||||
|
||||
@@ -34,13 +35,11 @@ namespace
|
||||
clang::tooling::ToolInvocation Invocation(getSyntaxOnlyToolArgs(Args, FileNameRef), ToolAction, Files.get());
|
||||
|
||||
llvm::SmallString<1024> CodeStorage;
|
||||
Invocation.mapVirtualFile(FileNameRef,
|
||||
Code.toNullTerminatedStringRef(CodeStorage));
|
||||
Invocation.mapVirtualFile(FileNameRef, Code.toNullTerminatedStringRef(CodeStorage));
|
||||
|
||||
for (auto &FilenameWithContent : VirtualMappedFiles)
|
||||
{
|
||||
Invocation.mapVirtualFile(FilenameWithContent.first,
|
||||
FilenameWithContent.second);
|
||||
Invocation.mapVirtualFile(FilenameWithContent.first, FilenameWithContent.second);
|
||||
}
|
||||
|
||||
Invocation.setDiagnosticConsumer(DiagConsumer);
|
||||
@@ -49,7 +48,7 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
CxxParser::CxxParser(ParserClient* client, FileManager* fileManager)
|
||||
CxxParser::CxxParser(ParserClient* client, const FileManager* fileManager)
|
||||
: Parser(client)
|
||||
, m_fileManager(fileManager)
|
||||
{
|
||||
@@ -112,13 +111,15 @@ void CxxParser::parseFiles(
|
||||
return;
|
||||
}
|
||||
|
||||
clang::tooling::ClangTool tool(*compilationDatabase, filePaths);
|
||||
FileRegister fileRegister(m_fileManager, filePaths);
|
||||
|
||||
llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> options = new clang::DiagnosticOptions();
|
||||
CxxDiagnosticConsumer reporter(llvm::errs(), &*options, m_client);
|
||||
tool.setDiagnosticConsumer(&reporter);
|
||||
|
||||
ASTActionFactory actionFactory(m_client, m_fileManager);
|
||||
ASTActionFactory actionFactory(m_client, &fileRegister);
|
||||
|
||||
clang::tooling::ClangTool tool(*compilationDatabase, fileRegister.getSourceFilePaths());
|
||||
tool.setDiagnosticConsumer(&reporter);
|
||||
tool.run(&actionFactory);
|
||||
}
|
||||
|
||||
@@ -130,6 +131,8 @@ void CxxParser::parseFile(std::shared_ptr<TextAccess> textAccess)
|
||||
llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> options = new clang::DiagnosticOptions();
|
||||
CxxDiagnosticConsumer reporter(llvm::errs(), &*options, m_client, false);
|
||||
|
||||
ASTActionFactory actionFactory(m_client, m_fileManager);
|
||||
FileRegister fileRegister(m_fileManager, std::vector<std::string>());
|
||||
|
||||
ASTActionFactory actionFactory(m_client, &fileRegister);
|
||||
runToolOnCodeWithArgs(&reporter, actionFactory.create(), textAccess->getText(), args);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
class CxxParser: public Parser
|
||||
{
|
||||
public:
|
||||
CxxParser(ParserClient* client, FileManager* fileManager);
|
||||
CxxParser(ParserClient* client, const FileManager* fileManager);
|
||||
~CxxParser();
|
||||
|
||||
virtual void parseFiles(
|
||||
@@ -17,7 +17,7 @@ public:
|
||||
virtual void parseFile(std::shared_ptr<TextAccess> textAccess);
|
||||
|
||||
private:
|
||||
FileManager* m_fileManager;
|
||||
const FileManager* m_fileManager;
|
||||
};
|
||||
|
||||
#endif // CXX_PARSER_H
|
||||
|
||||
@@ -1,18 +1,35 @@
|
||||
#include "data/parser/cxx/PreprocessorCallbacks.h"
|
||||
|
||||
#include "utility/file/FileManager.h"
|
||||
#include "utility/file/FileRegister.h"
|
||||
|
||||
#include "data/parser/ParserClient.h"
|
||||
#include "data/parser/ParseLocation.h"
|
||||
|
||||
PreprocessorCallbacks::PreprocessorCallbacks(
|
||||
clang::SourceManager& sourceManager, ParserClient* client, FileManager* fileManager
|
||||
clang::SourceManager& sourceManager, ParserClient* client, FileRegister* fileRegister
|
||||
)
|
||||
: m_sourceManager(sourceManager)
|
||||
, m_client(client)
|
||||
, m_fileManager(fileManager)
|
||||
, m_fileRegister(fileRegister)
|
||||
{
|
||||
}
|
||||
|
||||
void PreprocessorCallbacks::FileChanged(
|
||||
clang::SourceLocation location, FileChangeReason reason, clang::SrcMgr::CharacteristicKind, clang::FileID)
|
||||
{
|
||||
if (reason != EnterFile)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const clang::FileEntry *fileEntry = m_sourceManager.getFileEntryForID(m_sourceManager.getFileID(location));
|
||||
if (fileEntry && m_fileRegister->getFileManager()->hasFilePath(fileEntry->getName()))
|
||||
{
|
||||
m_fileRegister->markIncludeFileParsing(fileEntry->getName());
|
||||
}
|
||||
}
|
||||
|
||||
void PreprocessorCallbacks::InclusionDirective(
|
||||
clang::SourceLocation hashLocation, const clang::Token& includeToken, llvm::StringRef fileName, bool isAngled,
|
||||
clang::CharSourceRange fileNameRange, const clang::FileEntry* fileEntry, llvm::StringRef searchPath,
|
||||
@@ -24,10 +41,10 @@ void PreprocessorCallbacks::InclusionDirective(
|
||||
std::string baseFilePath = baseFileEntry->getName();
|
||||
std::string filePath = fileEntry->getName();
|
||||
|
||||
if (m_fileManager->hasFilePath(baseFilePath) && m_fileManager->hasFilePath(filePath))
|
||||
if (m_fileRegister->getFileManager()->hasFilePath(baseFilePath) &&
|
||||
m_fileRegister->getFileManager()->hasFilePath(filePath))
|
||||
{
|
||||
m_client->onFileIncludeParsed(
|
||||
getParseLocation(fileNameRange.getAsRange()), baseFileEntry->getName(), fileEntry->getName());
|
||||
m_client->onFileIncludeParsed(getParseLocation(fileNameRange.getAsRange()), baseFilePath, filePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
#include "clang/Lex/PPCallbacks.h"
|
||||
|
||||
class FileManager;
|
||||
class FileRegister;
|
||||
class ParserClient;
|
||||
|
||||
struct ParseLocation;
|
||||
@@ -13,7 +13,9 @@ class PreprocessorCallbacks
|
||||
: public clang::PPCallbacks
|
||||
{
|
||||
public:
|
||||
explicit PreprocessorCallbacks(clang::SourceManager& sourceManager, ParserClient* client, FileManager* fileManager);
|
||||
explicit PreprocessorCallbacks(clang::SourceManager& sourceManager, ParserClient* client, FileRegister* fileRegister);
|
||||
|
||||
virtual void FileChanged(clang::SourceLocation location, FileChangeReason reason, clang::SrcMgr::CharacteristicKind, clang::FileID);
|
||||
|
||||
virtual void InclusionDirective(
|
||||
clang::SourceLocation hashLocation, const clang::Token& includeToken, llvm::StringRef fileName, bool isAngled,
|
||||
@@ -25,7 +27,7 @@ private:
|
||||
|
||||
const clang::SourceManager& m_sourceManager;
|
||||
ParserClient* m_client;
|
||||
FileManager* m_fileManager;
|
||||
FileRegister* m_fileRegister;
|
||||
};
|
||||
|
||||
#endif // PREPROCESSOR_CALLBACKS_H
|
||||
|
||||
Reference in New Issue
Block a user