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:
Eberhard Graether
2015-03-09 01:32:51 +01:00
parent abddf57004
commit 7014c8ac4c
22 changed files with 290 additions and 115 deletions
+1
View File
@@ -15,6 +15,7 @@ void init()
std::shared_ptr<ConsoleLogger> consoleLogger = std::make_shared<ConsoleLogger>(); std::shared_ptr<ConsoleLogger> consoleLogger = std::make_shared<ConsoleLogger>();
consoleLogger->setLogLevel(Logger::LOG_WARNINGS | Logger::LOG_ERRORS); consoleLogger->setLogLevel(Logger::LOG_WARNINGS | Logger::LOG_ERRORS);
LogManager::getInstance()->addLogger(consoleLogger); LogManager::getInstance()->addLogger(consoleLogger);
std::shared_ptr<FileLogger> fileLogger = std::make_shared<FileLogger>(); std::shared_ptr<FileLogger> fileLogger = std::make_shared<FileLogger>();
fileLogger->setLogLevel(Logger::LOG_ALL); fileLogger->setLogLevel(Logger::LOG_ALL);
LogManager::getInstance()->addLogger(fileLogger); LogManager::getInstance()->addLogger(fileLogger);
+2
View File
@@ -192,6 +192,8 @@ add_files(
utility/file/FileInfo.h utility/file/FileInfo.h
utility/file/FileManager.cpp utility/file/FileManager.cpp
utility/file/FileManager.h utility/file/FileManager.h
utility/file/FileRegister.cpp
utility/file/FileRegister.h
utility/file/FileSystem.cpp utility/file/FileSystem.cpp
utility/file/FileSystem.h utility/file/FileSystem.h
+9 -4
View File
@@ -4,9 +4,9 @@
#include "data/parser/cxx/PreprocessorCallbacks.h" #include "data/parser/cxx/PreprocessorCallbacks.h"
ASTAction::ASTAction(ParserClient* client, FileManager* fileManager) ASTAction::ASTAction(ParserClient* client, FileRegister* fileRegister)
: m_client(client) : 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) 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) 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(); clang::Preprocessor& preprocessor = compiler.getPreprocessor();
preprocessor.addPPCallbacks( preprocessor.addPPCallbacks(
llvm::make_unique<PreprocessorCallbacks>(compiler.getSourceManager(), m_client, m_fileManager)); llvm::make_unique<PreprocessorCallbacks>(compiler.getSourceManager(), m_client, m_fileRegister));
return true; return true;
} }
void ASTAction::EndSourceFileAction()
{
m_fileRegister->markParsingIncludeFilesParsed();
}
+5 -3
View File
@@ -5,21 +5,23 @@
#include "clang/Frontend/FrontendAction.h" #include "clang/Frontend/FrontendAction.h"
#include "data/parser/cxx/ASTConsumer.h" #include "data/parser/cxx/ASTConsumer.h"
#include "utility/file/FileManager.h" #include "utility/file/FileRegister.h"
class ASTAction : public clang::ASTFrontendAction class ASTAction : public clang::ASTFrontendAction
{ {
public: public:
explicit ASTAction(ParserClient* client, FileManager* fileManager); explicit ASTAction(ParserClient* client, FileRegister* fileRegister);
virtual ~ASTAction(); virtual ~ASTAction();
protected:
virtual std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(clang::CompilerInstance& compiler, llvm::StringRef inFile); virtual std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(clang::CompilerInstance& compiler, llvm::StringRef inFile);
virtual bool BeginSourceFileAction(clang::CompilerInstance& compiler, llvm::StringRef filePath); virtual bool BeginSourceFileAction(clang::CompilerInstance& compiler, llvm::StringRef filePath);
virtual void EndSourceFileAction();
private: private:
ParserClient* m_client; ParserClient* m_client;
FileManager* m_fileManager; FileRegister* m_fileRegister;
}; };
#endif // AST_ACTION_H #endif // AST_ACTION_H
+3 -3
View File
@@ -1,8 +1,8 @@
#include "data/parser/cxx/ASTActionFactory.h" #include "data/parser/cxx/ASTActionFactory.h"
ASTActionFactory::ASTActionFactory(ParserClient* client, FileManager* fileManager) ASTActionFactory::ASTActionFactory(ParserClient* client, FileRegister* fileRegister)
: m_client(client) : m_client(client)
, m_fileManager(fileManager) , m_fileRegister(fileRegister)
{ {
} }
@@ -12,5 +12,5 @@ ASTActionFactory::~ASTActionFactory()
clang::FrontendAction* ASTActionFactory::create() clang::FrontendAction* ASTActionFactory::create()
{ {
return new ASTAction(m_client, m_fileManager); return new ASTAction(m_client, m_fileRegister);
} }
+3 -3
View File
@@ -4,19 +4,19 @@
#include "clang/Tooling/Tooling.h" #include "clang/Tooling/Tooling.h"
#include "data/parser/cxx/ASTAction.h" #include "data/parser/cxx/ASTAction.h"
#include "utility/file/FileManager.h" #include "utility/file/FileRegister.h"
class ASTActionFactory : public clang::tooling::FrontendActionFactory class ASTActionFactory : public clang::tooling::FrontendActionFactory
{ {
public: public:
explicit ASTActionFactory(ParserClient* client, FileManager* fileManager); explicit ASTActionFactory(ParserClient* client, FileRegister* fileRegister);
virtual ~ASTActionFactory(); virtual ~ASTActionFactory();
virtual clang::FrontendAction* create(); virtual clang::FrontendAction* create();
private: private:
ParserClient* m_client; ParserClient* m_client;
FileManager* m_fileManager; FileRegister* m_fileRegister;
}; };
#endif // AST_ACTION_FACTORY #endif // AST_ACTION_FACTORY
+2 -2
View File
@@ -2,8 +2,8 @@
#include "data/parser/ParserClient.h" #include "data/parser/ParserClient.h"
ASTConsumer::ASTConsumer(clang::ASTContext* context, ParserClient* client, FileManager* fileManager) ASTConsumer::ASTConsumer(clang::ASTContext* context, ParserClient* client, FileRegister* fileRegister)
: m_visitor(context, client, fileManager) : m_visitor(context, client, fileRegister)
{ {
} }
+6 -4
View File
@@ -4,13 +4,15 @@
#include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h" #include "clang/AST/ASTContext.h"
#include "data/parser/cxx/ASTVisitor.h" #include "utility/file/FileRegister.h"
#include "utility/file/FileManager.h"
class ASTConsumer : public clang::ASTConsumer #include "data/parser/cxx/ASTVisitor.h"
class ASTConsumer
: public clang::ASTConsumer
{ {
public: public:
explicit ASTConsumer(clang::ASTContext* context, ParserClient* client, FileManager* fileManager); explicit ASTConsumer(clang::ASTContext* context, ParserClient* client, FileRegister* fileRegister);
virtual ~ASTConsumer(); virtual ~ASTConsumer();
virtual void HandleTranslationUnit(clang::ASTContext& context); virtual void HandleTranslationUnit(clang::ASTContext& context);
+59 -48
View File
@@ -3,6 +3,11 @@
#include <clang/AST/ParentMap.h> #include <clang/AST/ParentMap.h>
#include <clang/Lex/Lexer.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/ASTBodyVisitor.h"
#include "data/parser/cxx/utilityCxx.h" #include "data/parser/cxx/utilityCxx.h"
#include "data/parser/ParseFunction.h" #include "data/parser/ParseFunction.h"
@@ -10,14 +15,11 @@
#include "data/parser/ParseTypeUsage.h" #include "data/parser/ParseTypeUsage.h"
#include "data/parser/ParseVariable.h" #include "data/parser/ParseVariable.h"
#include "data/type/DataType.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_context(context)
, m_client(client) , 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) bool ASTVisitor::VisitTypedefDecl(clang::TypedefDecl* declaration)
{ {
if (isLocatedInMainFile(declaration)) if (isLocatedInUnparsedProjectFile(declaration))
{ {
m_client->onTypedefParsed( m_client->onTypedefParsed(
getParseLocationForNamedDecl(declaration), getParseLocationForNamedDecl(declaration),
@@ -47,7 +49,7 @@ bool ASTVisitor::VisitTypedefDecl(clang::TypedefDecl* declaration)
bool ASTVisitor::VisitCXXRecordDecl(clang::CXXRecordDecl* declaration) bool ASTVisitor::VisitCXXRecordDecl(clang::CXXRecordDecl* declaration)
{ {
if (isLocatedInMainFile(declaration)) if (isLocatedInUnparsedProjectFile(declaration))
{ {
if (declaration->isClass()) if (declaration->isClass())
{ {
@@ -96,7 +98,7 @@ bool ASTVisitor::VisitVarDecl(clang::VarDecl* declaration)
return true; return true;
} }
if (isLocatedInMainFile(declaration)) if (isLocatedInUnparsedProjectFile(declaration))
{ {
clang::AccessSpecifier access = declaration->getAccess(); clang::AccessSpecifier access = declaration->getAccess();
@@ -128,7 +130,7 @@ bool ASTVisitor::VisitVarDecl(clang::VarDecl* declaration)
bool ASTVisitor::VisitFieldDecl(clang::FieldDecl* declaration) bool ASTVisitor::VisitFieldDecl(clang::FieldDecl* declaration)
{ {
if (isLocatedInMainFile(declaration)) if (isLocatedInUnparsedProjectFile(declaration))
{ {
m_client->onFieldParsed( m_client->onFieldParsed(
getParseLocationForNamedDecl(declaration), getParseLocationForNamedDecl(declaration),
@@ -148,7 +150,7 @@ bool ASTVisitor::VisitFunctionDecl(clang::FunctionDecl* declaration)
return true; return true;
} }
if (isLocatedInMainFile(declaration)) if (isLocatedInUnparsedProjectFile(declaration))
{ {
m_client->onFunctionParsed( m_client->onFunctionParsed(
getParseLocationForNamedDecl(declaration), getParseLocationForNamedDecl(declaration),
@@ -168,7 +170,7 @@ bool ASTVisitor::VisitFunctionDecl(clang::FunctionDecl* declaration)
bool ASTVisitor::VisitCXXMethodDecl(clang::CXXMethodDecl* declaration) bool ASTVisitor::VisitCXXMethodDecl(clang::CXXMethodDecl* declaration)
{ {
if (isLocatedInMainFile(declaration)) if (isLocatedInUnparsedProjectFile(declaration))
{ {
ParserClient::AbstractionType abstraction = ParserClient::ABSTRACTION_NONE; ParserClient::AbstractionType abstraction = ParserClient::ABSTRACTION_NONE;
if (declaration->isPure()) if (declaration->isPure())
@@ -208,7 +210,7 @@ bool ASTVisitor::VisitCXXMethodDecl(clang::CXXMethodDecl* declaration)
bool ASTVisitor::VisitCXXConstructorDecl(clang::CXXConstructorDecl* 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++) 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) bool ASTVisitor::VisitNamespaceDecl(clang::NamespaceDecl* declaration)
{ {
if (isLocatedInMainFile(declaration)) if (isLocatedInUnparsedProjectFile(declaration))
{ {
m_client->onNamespaceParsed( m_client->onNamespaceParsed(
declaration->isAnonymousNamespace() ? ParseLocation() : getParseLocationForNamedDecl(declaration), declaration->isAnonymousNamespace() ? ParseLocation() : getParseLocationForNamedDecl(declaration),
@@ -255,7 +257,7 @@ bool ASTVisitor::VisitNamespaceDecl(clang::NamespaceDecl* declaration)
bool ASTVisitor::VisitEnumDecl(clang::EnumDecl* declaration) bool ASTVisitor::VisitEnumDecl(clang::EnumDecl* declaration)
{ {
if (isLocatedInMainFile(declaration)) if (isLocatedInUnparsedProjectFile(declaration))
{ {
m_client->onEnumParsed( m_client->onEnumParsed(
getParseLocationForNamedDecl(declaration), getParseLocationForNamedDecl(declaration),
@@ -269,7 +271,7 @@ bool ASTVisitor::VisitEnumDecl(clang::EnumDecl* declaration)
bool ASTVisitor::VisitEnumConstantDecl(clang::EnumConstantDecl* declaration) bool ASTVisitor::VisitEnumConstantDecl(clang::EnumConstantDecl* declaration)
{ {
if (isLocatedInMainFile(declaration)) if (isLocatedInUnparsedProjectFile(declaration))
{ {
m_client->onEnumConstantParsed( m_client->onEnumConstantParsed(
getParseLocation(declaration->getSourceRange()), getParseLocation(declaration->getSourceRange()),
@@ -281,7 +283,7 @@ bool ASTVisitor::VisitEnumConstantDecl(clang::EnumConstantDecl* declaration)
bool ASTVisitor::VisitTemplateTypeParmDecl(clang::TemplateTypeParmDecl *declaration) bool ASTVisitor::VisitTemplateTypeParmDecl(clang::TemplateTypeParmDecl *declaration)
{ {
if (declaration->hasDefaultArgument()) if (isLocatedInUnparsedProjectFile(declaration) && declaration->hasDefaultArgument())
{ {
m_client->onTemplateDefaultArgumentTypeParsed( m_client->onTemplateDefaultArgumentTypeParsed(
getParseTypeUsage(declaration->getDefaultArgumentInfo()->getTypeLoc(), declaration->getDefaultArgument()), getParseTypeUsage(declaration->getDefaultArgumentInfo()->getTypeLoc(), declaration->getDefaultArgument()),
@@ -294,27 +296,24 @@ bool ASTVisitor::VisitTemplateTypeParmDecl(clang::TemplateTypeParmDecl *declarat
bool ASTVisitor::VisitClassTemplateDecl(clang::ClassTemplateDecl* declaration) bool ASTVisitor::VisitClassTemplateDecl(clang::ClassTemplateDecl* declaration)
{ {
std::vector<std::string> rarchy = utility::getDeclNameHierarchy(declaration); std::vector<std::string> rarchy = utility::getDeclNameHierarchy(declaration);
if (isLocatedInMainFile(declaration)) if (isLocatedInUnparsedProjectFile(declaration))
{ {
std::vector<std::string> templateRecordNameHierarchy = utility::getDeclNameHierarchy(declaration); std::vector<std::string> templateRecordNameHierarchy = utility::getDeclNameHierarchy(declaration);
clang::TemplateParameterList* parameterList = declaration->getTemplateParameters(); clang::TemplateParameterList* parameterList = declaration->getTemplateParameters();
for (size_t i = 0; i < parameterList->size(); i++) for (size_t i = 0; i < parameterList->size(); i++)
{ {
clang::NamedDecl* namedDecl = parameterList->getParam(i); clang::NamedDecl* namedDecl = parameterList->getParam(i);
if (isLocatedInMainFile(namedDecl)) m_client->onTemplateRecordParameterTypeParsed(
{ getParseLocationForNamedDecl(namedDecl),
m_client->onTemplateRecordParameterTypeParsed( utility::getDeclNameHierarchy(namedDecl),
getParseLocationForNamedDecl(namedDecl), templateRecordNameHierarchy
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) // 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 // 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(); for (clang::ClassTemplateDecl::spec_iterator it = declaration->specializations().begin();
it != declaration->specializations().end(); it++ it != declaration->specializations().end(); it++
@@ -354,7 +353,7 @@ bool ASTVisitor::VisitClassTemplateDecl(clang::ClassTemplateDecl* declaration)
bool ASTVisitor::VisitClassTemplatePartialSpecializationDecl(clang::ClassTemplatePartialSpecializationDecl* 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> specializedRecordNameHierarchy = utility::getDeclNameHierarchy(declaration);
std::vector<std::string> specializationParentNameHierarchy = utility::getTemplateSpecializationParentNameHierarchy(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++) for (size_t i = 0; i < parameterList->size(); i++)
{ {
clang::NamedDecl* namedDecl = parameterList->getParam(i); clang::NamedDecl* namedDecl = parameterList->getParam(i);
if (isLocatedInMainFile(namedDecl)) m_client->onTemplateRecordParameterTypeParsed(
{ getParseLocationForNamedDecl(namedDecl),
m_client->onTemplateRecordParameterTypeParsed( utility::getDeclNameHierarchy(namedDecl),
getParseLocationForNamedDecl(namedDecl), specializedRecordNameHierarchy
utility::getDeclNameHierarchy(namedDecl), );
specializedRecordNameHierarchy
);
}
} }
const clang::ASTTemplateArgumentListInfo* argumentInfoList = declaration->getTemplateArgsAsWritten(); const clang::ASTTemplateArgumentListInfo* argumentInfoList = declaration->getTemplateArgsAsWritten();
for (size_t i = 0; i < argumentInfoList->NumTemplateArgs; i++) for (size_t i = 0; i < argumentInfoList->NumTemplateArgs; i++)
{ {
const clang::TemplateArgumentLoc& argumentLoc = argumentInfoList->operator[](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( m_client->onTemplateArgumentParsed(
getParseLocation(argumentLoc.getSourceRange()), getParseLocation(argumentLoc.getSourceRange()),
utility::qualTypeToDataType(argumentType).getTypeNameHierarchy(), utility::qualTypeToDataType(argumentType).getTypeNameHierarchy(),
specializedRecordNameHierarchy); specializedRecordNameHierarchy);
}
} }
} }
return true; return true;
@@ -396,14 +396,14 @@ bool ASTVisitor::VisitClassTemplatePartialSpecializationDecl(clang::ClassTemplat
bool ASTVisitor::VisitFunctionTemplateDecl(clang::FunctionTemplateDecl *declaration) bool ASTVisitor::VisitFunctionTemplateDecl(clang::FunctionTemplateDecl *declaration)
{ {
const ParseFunction templateFunction = getParseFunction(declaration); const ParseFunction templateFunction = getParseFunction(declaration);
if (isLocatedInMainFile(declaration)) if (isLocatedInUnparsedProjectFile(declaration))
{ {
clang::TemplateParameterList* parameterList = declaration->getTemplateParameters(); clang::TemplateParameterList* parameterList = declaration->getTemplateParameters();
for (size_t i = 0; i < parameterList->size(); i++) for (size_t i = 0; i < parameterList->size(); i++)
{ {
clang::NamedDecl* namedDecl = parameterList->getParam(i); clang::NamedDecl* namedDecl = parameterList->getParam(i);
if (isLocatedInMainFile(namedDecl)) if (isLocatedInUnparsedProjectFile(namedDecl))
{ {
std::vector<std::string> templateParameterTypeNameHierarchy = utility::getDeclNameHierarchy(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++) 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(); clang::FunctionTemplateSpecializationInfo* info = specializedFunctionDecl->getTemplateSpecializationInfo();
if (info->getTemplateSpecializationKind() == clang::TSK_ExplicitSpecialization) if (info->getTemplateSpecializationKind() == clang::TSK_ExplicitSpecialization)
{ {
if (isLocatedInMainFile(declaration)) if (isLocatedInUnparsedProjectFile(declaration))
{ {
m_client->onTemplateFunctionSpecializationParsed( m_client->onTemplateFunctionSpecializationParsed(
specializedFunctionLocation, 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(); 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(); const clang::SourceLocation& location = declaration->getLocStart();
if (location.isValid()) if (location.isValid())
{ {
const clang::SourceManager& sourceManager = m_context->getSourceManager(); const clang::SourceManager& sourceManager = m_context->getSourceManager();
std::string filePath = FileSystem::absoluteFilePath(sourceManager.getFilename(location)); std::string filePath = FileSystem::absoluteFilePath(sourceManager.getFilename(location));
return m_fileManager->hasFilePath(filePath); return m_fileRegister->getFileManager()->hasFilePath(filePath);
} }
return false; return false;
} }
+7 -5
View File
@@ -4,16 +4,17 @@
#include "clang/AST/ASTContext.h" #include "clang/AST/ASTContext.h"
#include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/RecursiveASTVisitor.h"
#include "utility/file/FileRegister.h"
#include "data/parser/cxx/ASTBodyVisitorClient.h" #include "data/parser/cxx/ASTBodyVisitorClient.h"
#include "data/parser/ParserClient.h" #include "data/parser/ParserClient.h"
#include "utility/file/FileManager.h"
class ASTVisitor class ASTVisitor
: public clang::RecursiveASTVisitor<ASTVisitor> : public clang::RecursiveASTVisitor<ASTVisitor>
, public ASTBodyVisitorClient , public ASTBodyVisitorClient
{ {
public: public:
ASTVisitor(clang::ASTContext* context, ParserClient* client, FileManager* fileManager); ASTVisitor(clang::ASTContext* context, ParserClient* client, FileRegister* fileRegister);
virtual ~ASTVisitor(); virtual ~ASTVisitor();
// Left for debugging purposes. Uncomment to see a colored ast-dump of the parsed file. // 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 virtual void VisitVarDeclInDeclBody(clang::FunctionDecl* decl, clang::VarDecl* varDecl); // type usages
private: private:
bool isLocatedInMainFile(const clang::Decl* declaration) const; bool isLocatedInUnparsedProjectFile(const clang::Decl* declaration) const;
bool isLocatedInSourceFile(const clang::Decl* declaration) const; bool isLocatedInProjectFile(const clang::Decl* declaration) const;
ParserClient::AccessType convertAccessType(clang::AccessSpecifier) const; ParserClient::AccessType convertAccessType(clang::AccessSpecifier) const;
ParseLocation getParseLocation(const clang::SourceRange& sourceRange) const; ParseLocation getParseLocation(const clang::SourceRange& sourceRange) const;
@@ -77,7 +79,7 @@ private:
clang::ASTContext* m_context; clang::ASTContext* m_context;
ParserClient* m_client; ParserClient* m_client;
FileManager* m_fileManager; FileRegister* m_fileRegister;
}; };
#endif // AST_VISITOR_H #endif // AST_VISITOR_H
+12 -9
View File
@@ -1,5 +1,6 @@
#include "data/parser/cxx/CxxParser.h" #include "data/parser/cxx/CxxParser.h"
#include "utility/file/FileRegister.h"
#include "utility/logging/logging.h" #include "utility/logging/logging.h"
#include "utility/text/TextAccess.h" #include "utility/text/TextAccess.h"
@@ -34,13 +35,11 @@ namespace
clang::tooling::ToolInvocation Invocation(getSyntaxOnlyToolArgs(Args, FileNameRef), ToolAction, Files.get()); clang::tooling::ToolInvocation Invocation(getSyntaxOnlyToolArgs(Args, FileNameRef), ToolAction, Files.get());
llvm::SmallString<1024> CodeStorage; llvm::SmallString<1024> CodeStorage;
Invocation.mapVirtualFile(FileNameRef, Invocation.mapVirtualFile(FileNameRef, Code.toNullTerminatedStringRef(CodeStorage));
Code.toNullTerminatedStringRef(CodeStorage));
for (auto &FilenameWithContent : VirtualMappedFiles) for (auto &FilenameWithContent : VirtualMappedFiles)
{ {
Invocation.mapVirtualFile(FilenameWithContent.first, Invocation.mapVirtualFile(FilenameWithContent.first, FilenameWithContent.second);
FilenameWithContent.second);
} }
Invocation.setDiagnosticConsumer(DiagConsumer); Invocation.setDiagnosticConsumer(DiagConsumer);
@@ -49,7 +48,7 @@ namespace
} }
} }
CxxParser::CxxParser(ParserClient* client, FileManager* fileManager) CxxParser::CxxParser(ParserClient* client, const FileManager* fileManager)
: Parser(client) : Parser(client)
, m_fileManager(fileManager) , m_fileManager(fileManager)
{ {
@@ -112,13 +111,15 @@ void CxxParser::parseFiles(
return; return;
} }
clang::tooling::ClangTool tool(*compilationDatabase, filePaths); FileRegister fileRegister(m_fileManager, filePaths);
llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> options = new clang::DiagnosticOptions(); llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> options = new clang::DiagnosticOptions();
CxxDiagnosticConsumer reporter(llvm::errs(), &*options, m_client); 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); tool.run(&actionFactory);
} }
@@ -130,6 +131,8 @@ void CxxParser::parseFile(std::shared_ptr<TextAccess> textAccess)
llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> options = new clang::DiagnosticOptions(); llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> options = new clang::DiagnosticOptions();
CxxDiagnosticConsumer reporter(llvm::errs(), &*options, m_client, false); 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); runToolOnCodeWithArgs(&reporter, actionFactory.create(), textAccess->getText(), args);
} }
+2 -2
View File
@@ -7,7 +7,7 @@
class CxxParser: public Parser class CxxParser: public Parser
{ {
public: public:
CxxParser(ParserClient* client, FileManager* fileManager); CxxParser(ParserClient* client, const FileManager* fileManager);
~CxxParser(); ~CxxParser();
virtual void parseFiles( virtual void parseFiles(
@@ -17,7 +17,7 @@ public:
virtual void parseFile(std::shared_ptr<TextAccess> textAccess); virtual void parseFile(std::shared_ptr<TextAccess> textAccess);
private: private:
FileManager* m_fileManager; const FileManager* m_fileManager;
}; };
#endif // CXX_PARSER_H #endif // CXX_PARSER_H
@@ -1,18 +1,35 @@
#include "data/parser/cxx/PreprocessorCallbacks.h" #include "data/parser/cxx/PreprocessorCallbacks.h"
#include "utility/file/FileManager.h" #include "utility/file/FileManager.h"
#include "utility/file/FileRegister.h"
#include "data/parser/ParserClient.h" #include "data/parser/ParserClient.h"
#include "data/parser/ParseLocation.h" #include "data/parser/ParseLocation.h"
PreprocessorCallbacks::PreprocessorCallbacks( PreprocessorCallbacks::PreprocessorCallbacks(
clang::SourceManager& sourceManager, ParserClient* client, FileManager* fileManager clang::SourceManager& sourceManager, ParserClient* client, FileRegister* fileRegister
) )
: m_sourceManager(sourceManager) : m_sourceManager(sourceManager)
, m_client(client) , 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( void PreprocessorCallbacks::InclusionDirective(
clang::SourceLocation hashLocation, const clang::Token& includeToken, llvm::StringRef fileName, bool isAngled, clang::SourceLocation hashLocation, const clang::Token& includeToken, llvm::StringRef fileName, bool isAngled,
clang::CharSourceRange fileNameRange, const clang::FileEntry* fileEntry, llvm::StringRef searchPath, clang::CharSourceRange fileNameRange, const clang::FileEntry* fileEntry, llvm::StringRef searchPath,
@@ -24,10 +41,10 @@ void PreprocessorCallbacks::InclusionDirective(
std::string baseFilePath = baseFileEntry->getName(); std::string baseFilePath = baseFileEntry->getName();
std::string filePath = fileEntry->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( m_client->onFileIncludeParsed(getParseLocation(fileNameRange.getAsRange()), baseFilePath, filePath);
getParseLocation(fileNameRange.getAsRange()), baseFileEntry->getName(), fileEntry->getName());
} }
} }
} }
@@ -4,7 +4,7 @@
#include "clang/Basic/SourceManager.h" #include "clang/Basic/SourceManager.h"
#include "clang/Lex/PPCallbacks.h" #include "clang/Lex/PPCallbacks.h"
class FileManager; class FileRegister;
class ParserClient; class ParserClient;
struct ParseLocation; struct ParseLocation;
@@ -13,7 +13,9 @@ class PreprocessorCallbacks
: public clang::PPCallbacks : public clang::PPCallbacks
{ {
public: 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( virtual void InclusionDirective(
clang::SourceLocation hashLocation, const clang::Token& includeToken, llvm::StringRef fileName, bool isAngled, clang::SourceLocation hashLocation, const clang::Token& includeToken, llvm::StringRef fileName, bool isAngled,
@@ -25,7 +27,7 @@ private:
const clang::SourceManager& m_sourceManager; const clang::SourceManager& m_sourceManager;
ParserClient* m_client; ParserClient* m_client;
FileManager* m_fileManager; FileRegister* m_fileRegister;
}; };
#endif // PREPROCESSOR_CALLBACKS_H #endif // PREPROCESSOR_CALLBACKS_H
+10
View File
@@ -96,3 +96,13 @@ bool FileManager::hasFilePath(const std::string& filePath) const
{ {
return (m_files.find(FileSystem::absoluteFilePath(filePath)) != m_files.end()); return (m_files.find(FileSystem::absoluteFilePath(filePath)) != m_files.end());
} }
bool FileManager::hasSourceExtension(const std::string& filePath) const
{
return FileSystem::hasExtension(filePath, m_sourceExtensions);
}
bool FileManager::hasIncludeExtension(const std::string& filePath) const
{
return FileSystem::hasExtension(filePath, m_includeExtensions);
}
+2
View File
@@ -25,6 +25,8 @@ public:
std::set<std::string> getRemovedFilePaths() const; std::set<std::string> getRemovedFilePaths() const;
virtual bool hasFilePath(const std::string& filePath) const; virtual bool hasFilePath(const std::string& filePath) const;
virtual bool hasSourceExtension(const std::string& filePath) const;
virtual bool hasIncludeExtension(const std::string& filePath) const;
private: private:
std::vector<std::string> m_sourcePaths; std::vector<std::string> m_sourcePaths;
+66
View File
@@ -0,0 +1,66 @@
#include "utility/file/FileRegister.h"
#include "utility/file/FileManager.h"
#include "utility/file/FileSystem.h"
FileRegister::FileRegister(const FileManager* fileManager, const std::vector<std::string>& filePaths)
: m_fileManager(fileManager)
{
for (const std::string& path : filePaths)
{
if (m_fileManager->hasSourceExtension(path))
{
m_sourceFilePaths.push_back(path);
}
else
{
m_includeFilePaths.emplace(path, STATE_UNPARSED);
}
}
}
const FileManager* FileRegister::getFileManager() const
{
return m_fileManager;
}
const std::vector<std::string>& FileRegister::getSourceFilePaths() const
{
return m_sourceFilePaths;
}
bool FileRegister::includeFileIsParsing(const std::string& filePath) const
{
std::map<std::string, ParseState>::const_iterator it = m_includeFilePaths.find(FileSystem::absoluteFilePath(filePath));
if (it == m_includeFilePaths.end())
{
return false;
}
return it->second == STATE_PARSING;
}
void FileRegister::markIncludeFileParsing(const std::string& filePath)
{
std::map<std::string, ParseState>::iterator it = m_includeFilePaths.find(FileSystem::absoluteFilePath(filePath));
if (it == m_includeFilePaths.end())
{
return;
}
if (it->second != STATE_PARSED)
{
it->second = STATE_PARSING;
}
}
void FileRegister::markParsingIncludeFilesParsed()
{
for (std::pair<std::string, ParseState>&& p : m_includeFilePaths)
{
if (p.second == STATE_PARSING)
{
p.second = STATE_PARSED;
}
}
}
+38
View File
@@ -0,0 +1,38 @@
#ifndef FILE_REGISTER_H
#define FILE_REGISTER_H
#include <map>
#include <string>
#include <vector>
class FileManager;
class FileRegister
{
public:
FileRegister(const FileManager* fileManager, const std::vector<std::string>& filePaths);
const FileManager* getFileManager() const;
const std::vector<std::string>& getSourceFilePaths() const;
bool includeFileIsParsing(const std::string& filePath) const;
void markIncludeFileParsing(const std::string& filePath);
void markParsingIncludeFilesParsed();
private:
enum ParseState
{
STATE_UNPARSED,
STATE_PARSING,
STATE_PARSED
};
const FileManager* m_fileManager;
std::vector<std::string> m_sourceFilePaths;
std::map<std::string, ParseState> m_includeFilePaths;
};
#endif // FILE_REGISTER_H
+19 -19
View File
@@ -15,7 +15,7 @@ std::vector<std::string> FileSystem::getFileNamesFromDirectory(
boost::filesystem::recursive_directory_iterator endit; boost::filesystem::recursive_directory_iterator endit;
while (it != endit) while (it != endit)
{ {
if (boost::filesystem::is_regular_file(*it) && isValidExtension(it->path().string(), extensions)) if (boost::filesystem::is_regular_file(*it) && hasExtension(it->path().string(), extensions))
{ {
files.push_back(it->path().generic_string()); files.push_back(it->path().generic_string());
} }
@@ -38,7 +38,7 @@ std::vector<std::string> FileSystem::getFileNamesFromDirectoryUpdatedAfter(
boost::filesystem::recursive_directory_iterator endit; boost::filesystem::recursive_directory_iterator endit;
while (it != endit) while (it != endit)
{ {
if (boost::filesystem::is_regular_file(*it) && isValidExtension(it->path().string(), extensions)) if (boost::filesystem::is_regular_file(*it) && hasExtension(it->path().string(), extensions))
{ {
std::time_t t = boost::filesystem::last_write_time(*it); std::time_t t = boost::filesystem::last_write_time(*it);
boost::posix_time::ptime lastWriteTime = boost::posix_time::from_time_t(t); boost::posix_time::ptime lastWriteTime = boost::posix_time::from_time_t(t);
@@ -65,7 +65,7 @@ std::vector<FileInfo> FileSystem::getFileInfosFromDirectoryPaths(
boost::filesystem::recursive_directory_iterator endit; boost::filesystem::recursive_directory_iterator endit;
while (it != endit) while (it != endit)
{ {
if (boost::filesystem::is_regular_file(*it) && isValidExtension(it->path().string(), fileExtensions)) if (boost::filesystem::is_regular_file(*it) && hasExtension(it->path().string(), fileExtensions))
{ {
std::time_t t = boost::filesystem::last_write_time(*it); std::time_t t = boost::filesystem::last_write_time(*it);
boost::posix_time::ptime lastWriteTime = boost::posix_time::from_time_t(t); boost::posix_time::ptime lastWriteTime = boost::posix_time::from_time_t(t);
@@ -93,6 +93,11 @@ std::string FileSystem::fileName(const std::string& path)
return boost::filesystem::path(path).filename().generic_string(); return boost::filesystem::path(path).filename().generic_string();
} }
std::string FileSystem::absoluteFilePath(const std::string& path)
{
return boost::filesystem::absolute(boost::filesystem::path(path)).generic_string();
}
std::string FileSystem::extension(const std::string& path) std::string FileSystem::extension(const std::string& path)
{ {
return boost::filesystem::path(path).extension().generic_string(); return boost::filesystem::path(path).extension().generic_string();
@@ -103,22 +108,7 @@ std::string FileSystem::filePathWithoutExtension(const std::string& path)
return boost::filesystem::path(path).replace_extension().generic_string(); return boost::filesystem::path(path).replace_extension().generic_string();
} }
std::string FileSystem::absoluteFilePath(const std::string& path) bool FileSystem::hasExtension(const std::string& filepath, const std::vector<std::string>& extensions)
{
return boost::filesystem::absolute(boost::filesystem::path(path)).generic_string();
}
bool FileSystem::equivalent(const std::string& pathA, const std::string& pathB)
{
if (exists(pathA) && exists(pathB))
{
return boost::filesystem::equivalent(boost::filesystem::path(pathA), boost::filesystem::path(pathB));
}
return boost::filesystem::path(pathA).compare(boost::filesystem::path(pathB)) == 0;
}
bool FileSystem::isValidExtension(const std::string& filepath, const std::vector<std::string>& extensions)
{ {
boost::filesystem::path path(filepath); boost::filesystem::path path(filepath);
@@ -131,3 +121,13 @@ bool FileSystem::isValidExtension(const std::string& filepath, const std::vector
} }
return false; return false;
} }
bool FileSystem::equivalent(const std::string& pathA, const std::string& pathB)
{
if (exists(pathA) && exists(pathB))
{
return boost::filesystem::equivalent(boost::filesystem::path(pathA), boost::filesystem::path(pathB));
}
return boost::filesystem::path(pathA).compare(boost::filesystem::path(pathB)) == 0;
}
+4 -5
View File
@@ -21,14 +21,13 @@ public:
static bool exists(const std::string& path); static bool exists(const std::string& path);
static std::string fileName(const std::string& path); static std::string fileName(const std::string& path);
static std::string extension(const std::string& path);
static std::string filePathWithoutExtension(const std::string& path);
static std::string absoluteFilePath(const std::string& path); static std::string absoluteFilePath(const std::string& path);
static bool equivalent(const std::string& pathA, const std::string& pathB); static std::string extension(const std::string& path);
static std::string filePathWithoutExtension(const std::string& path);
static bool hasExtension(const std::string& filepath, const std::vector<std::string>& extensions);
private: static bool equivalent(const std::string& pathA, const std::string& pathB);
static bool isValidExtension(const std::string& filepath, const std::vector<std::string>& extensions);
}; };
#endif // FILE_SYSTEM_H #endif // FILE_SYSTEM_H
+10
View File
@@ -14,3 +14,13 @@ bool TestFileManager::hasFilePath(const std::string& filePath) const
{ {
return true; return true;
} }
bool TestFileManager::hasSourceExtension(const std::string& filePath) const
{
return true;
}
bool TestFileManager::hasIncludeExtension(const std::string& filePath) const
{
return true;
}
+3
View File
@@ -7,7 +7,10 @@ class TestFileManager: public FileManager
{ {
public: public:
TestFileManager(); TestFileManager();
virtual bool hasFilePath(const std::string& filePath) const; virtual bool hasFilePath(const std::string& filePath) const;
virtual bool hasSourceExtension(const std::string& filePath) const;
virtual bool hasIncludeExtension(const std::string& filePath) const;
}; };
#endif // TEST_FILE_MANAGER_H #endif // TEST_FILE_MANAGER_H