From 73b1b77ca807c440bb0a9806b77d70a1b943d45d Mon Sep 17 00:00:00 2001 From: Andreas Stallinger Date: Wed, 16 Sep 2015 17:08:16 +0200 Subject: [PATCH] data, utility: Fixes to run Opensource Projects templateSpecializationArgsAsWritten returning null caused a crash VisitMemberExprInDeclBody for vardecl was missing subdirectories for headersearchpaths, that the user does not need to add a hugh amount of folders --- CMakeLists.txt | 1 + src/lib/Project.cpp | 12 ++++- src/lib/data/Storage.cpp | 11 +++++ src/lib/data/Storage.h | 2 + src/lib/data/parser/ParserClient.h | 2 + src/lib/data/parser/cxx/ASTBodyVisitor.cpp | 9 +++- .../data/parser/cxx/ASTBodyVisitorClient.h | 1 + src/lib/data/parser/cxx/ASTVisitor.cpp | 47 +++++++++++++++---- src/lib/data/parser/cxx/ASTVisitor.h | 1 + .../cxx/name_resolver/CxxDeclNameResolver.cpp | 14 ++++-- src/lib/settings/Settings.cpp | 6 +-- src/lib/utility/file/FileSystem.cpp | 12 +++++ src/lib/utility/file/FileSystem.h | 1 + src/test/CxxParserTestSuite.h | 7 +++ 14 files changed, 110 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 038ea69b..dc1f1aa3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -383,6 +383,7 @@ if(UNIX AND NOT APPLE) SET(CPACK_PACKAGING_INSTALL_PREFIX "/usr/local") SET(CPACK_PACKAGE_VERSION ${GIT_VERSION_NUMBER}) SET(CPACK_PACKAGE_EXECUTABLES "Coati") + SET(CPACK_STRIP_FILES "share/coati/Coati") INCLUDE(CPack) diff --git a/src/lib/Project.cpp b/src/lib/Project.cpp index 9423b305..4b6c9e92 100644 --- a/src/lib/Project.cpp +++ b/src/lib/Project.cpp @@ -9,6 +9,7 @@ #include "data/parser/cxx/TaskParseCxx.h" #include "settings/ApplicationSettings.h" #include "settings/ProjectSettings.h" +#include "utility/file/FileSystem.h" std::shared_ptr Project::create(StorageAccessProxy* storageAccessProxy) { @@ -146,7 +147,16 @@ Parser::Arguments Project::getParserArguments() const // Add the include paths as HeaderSearchPaths as well, so clang will also look here when searching include files. utility::append(args.systemHeaderSearchPaths, m_fileManager.getIncludePaths()); - utility::append(args.systemHeaderSearchPaths, projSettings->getHeaderSearchPaths()); + + std::vector headerSearchPaths; + for(FilePath p : projSettings->getHeaderSearchPaths()) + { + std::vector tempPaths = FileSystem::getSubDirectoies(p); + headerSearchPaths.insert( headerSearchPaths.end(), tempPaths.begin(), tempPaths.end() ); + } + + std::unique(headerSearchPaths.begin(),headerSearchPaths.end()); + utility::append(args.systemHeaderSearchPaths, headerSearchPaths); utility::append(args.systemHeaderSearchPaths, appSettings->getHeaderSearchPaths()); utility::append(args.frameworkSearchPaths, projSettings->getFrameworkSearchPaths()); diff --git a/src/lib/data/Storage.cpp b/src/lib/data/Storage.cpp index b60e83aa..a0cc16ef 100644 --- a/src/lib/data/Storage.cpp +++ b/src/lib/data/Storage.cpp @@ -309,6 +309,17 @@ Id Storage::onFieldUsageParsed( return edgeId; } +Id Storage::onFieldUsageParsed( + const ParseLocation& location, const ParseVariable& user, const NameHierarchy& usedNameHierarchy +){ + Id userNodeId = addNodeHierarchy(Node::NODE_UNDEFINED_FUNCTION, user.nameHierarchy); + Id usedNodeId = addNodeHierarchy(Node::NODE_UNDEFINED_VARIABLE, usedNameHierarchy); + + Id edgeId = addEdge(userNodeId, usedNodeId, Edge::EDGE_USAGE, location); + + return edgeId; +} + Id Storage::onGlobalVariableUsageParsed( // or static variable used const ParseLocation& location, const ParseFunction& user, const NameHierarchy& usedNameHierarchy ){ diff --git a/src/lib/data/Storage.h b/src/lib/data/Storage.h index 32637c4c..054f3d97 100644 --- a/src/lib/data/Storage.h +++ b/src/lib/data/Storage.h @@ -76,6 +76,8 @@ public: const ParseLocation& location, const ParseVariable& caller, const ParseFunction& callee); virtual Id onFieldUsageParsed( const ParseLocation& location, const ParseFunction& user, const NameHierarchy& usedNameHierarchy); + virtual Id onFieldUsageParsed( + const ParseLocation& location, const ParseVariable& user, const NameHierarchy& usedNameHierarchy); virtual Id onGlobalVariableUsageParsed( const ParseLocation& location, const ParseFunction& user, const NameHierarchy& usedNameHierarchy); virtual Id onGlobalVariableUsageParsed( diff --git a/src/lib/data/parser/ParserClient.h b/src/lib/data/parser/ParserClient.h index 34df6f7e..4160935d 100644 --- a/src/lib/data/parser/ParserClient.h +++ b/src/lib/data/parser/ParserClient.h @@ -95,6 +95,8 @@ public: const ParseLocation& location, const ParseVariable& caller, const ParseFunction& callee) = 0; virtual Id onFieldUsageParsed( const ParseLocation& location, const ParseFunction& user, const NameHierarchy& usedNameHierarchy) = 0; + virtual Id onFieldUsageParsed( + const ParseLocation& location, const ParseVariable& user, const NameHierarchy& usedNameHierarchy) = 0; virtual Id onGlobalVariableUsageParsed( const ParseLocation& location, const ParseFunction& user, const NameHierarchy& usedNameHierarchy) = 0; virtual Id onGlobalVariableUsageParsed( diff --git a/src/lib/data/parser/cxx/ASTBodyVisitor.cpp b/src/lib/data/parser/cxx/ASTBodyVisitor.cpp index ff2c2ceb..93ec3e70 100644 --- a/src/lib/data/parser/cxx/ASTBodyVisitor.cpp +++ b/src/lib/data/parser/cxx/ASTBodyVisitor.cpp @@ -80,7 +80,14 @@ void ASTBodyVisitor::VisitMemberExpr(clang::make_ptr::type ex { if (expr->getMemberDecl()->getKind() == clang::Decl::Kind::Field) { - m_client->VisitMemberExprInDeclBody(m_functionDecl, expr); + if(m_functionDecl) + { + m_client->VisitMemberExprInDeclBody(m_functionDecl, expr); + } + else + { + m_client->VisitMemberExprInDeclBody(m_varDecl, expr); + } } VisitStmt(expr); } diff --git a/src/lib/data/parser/cxx/ASTBodyVisitorClient.h b/src/lib/data/parser/cxx/ASTBodyVisitorClient.h index 48bd1fe5..b623f0ce 100644 --- a/src/lib/data/parser/cxx/ASTBodyVisitorClient.h +++ b/src/lib/data/parser/cxx/ASTBodyVisitorClient.h @@ -18,6 +18,7 @@ public: virtual void VisitCXXNewExprInDeclBody(clang::FunctionDecl* decl, clang::CXXNewExpr* expr) = 0; virtual void VisitCXXNewExprInDeclBody(clang::VarDecl* decl, clang::CXXNewExpr* expr) = 0; virtual void VisitMemberExprInDeclBody(clang::FunctionDecl* decl, clang::MemberExpr* expr) = 0; + virtual void VisitMemberExprInDeclBody(clang::VarDecl* decl, clang::MemberExpr* expr) = 0; virtual void VisitGlobalVariableExprInDeclBody(clang::FunctionDecl* decl, clang::DeclRefExpr* expr) = 0; virtual void VisitGlobalVariableExprInDeclBody(clang::VarDecl* decl, clang::DeclRefExpr* expr) = 0; virtual void VisitEnumExprInDeclBody(clang::FunctionDecl* decl, clang::DeclRefExpr* expr) = 0; diff --git a/src/lib/data/parser/cxx/ASTVisitor.cpp b/src/lib/data/parser/cxx/ASTVisitor.cpp index 1a7cb5b2..cd0d1765 100644 --- a/src/lib/data/parser/cxx/ASTVisitor.cpp +++ b/src/lib/data/parser/cxx/ASTVisitor.cpp @@ -456,16 +456,33 @@ bool ASTVisitor::VisitFunctionTemplateDecl(clang::FunctionTemplateDecl *declarat specializedFunction, templateFunction); - const clang::ASTTemplateArgumentListInfo* argumentInfoList = specializedFunctionDecl->getTemplateSpecializationArgsAsWritten(); - for (size_t i = 0; i < argumentInfoList->NumTemplateArgs; i++) + if(specializedFunctionDecl->getTemplateSpecializationArgsAsWritten()) { - const clang::TemplateArgumentLoc& argumentLoc = argumentInfoList->operator[](i); - const clang::QualType argumentType = argumentLoc.getArgument().getAsType(); + const clang::ASTTemplateArgumentListInfo* argumentInfoList = specializedFunctionDecl->getTemplateSpecializationArgsAsWritten(); + for (size_t i = 0; i < argumentInfoList->NumTemplateArgs; i++) + { + const clang::TemplateArgumentLoc& argumentLoc = argumentInfoList->operator[](i); + const clang::QualType argumentType = argumentLoc.getArgument().getAsType(); - m_client->onTemplateArgumentTypeParsed( - getParseLocation(argumentLoc.getSourceRange()), - utility::qualTypeToDataType(argumentType)->getTypeNameHierarchy(), - specializedFunction.nameHierarchy); + m_client->onTemplateArgumentTypeParsed( + getParseLocation(argumentLoc.getSourceRange()), + utility::qualTypeToDataType(argumentType)->getTypeNameHierarchy(), + specializedFunction.nameHierarchy); + } + } + else + { + const clang::TemplateArgumentList* argumentList = specializedFunctionDecl->getTemplateSpecializationArgs(); + for(size_t i = 0; i < argumentList->size(); ++i) + { + const clang::TemplateArgumentLoc& argumentLoc = clang::TemplateArgumentLoc(argumentList->get(i), specializedFunctionDecl->getTypeSourceInfo()); + const clang::QualType argumentType = argumentLoc.getArgument().getAsType(); + + m_client->onTemplateArgumentTypeParsed( + getParseLocation(argumentLoc.getSourceRange()), + utility::qualTypeToDataType(argumentType)->getTypeNameHierarchy(), + specializedFunction.nameHierarchy); + } } } } @@ -649,6 +666,20 @@ void ASTVisitor::VisitMemberExprInDeclBody(clang::FunctionDecl* decl, clang::Mem ); } +void ASTVisitor::VisitMemberExprInDeclBody(clang::VarDecl* decl, clang::MemberExpr* expr) +{ + ParseLocation parseLocation = getParseLocation(expr->getSourceRange()); + + const std::string exprName = expr->getMemberNameInfo().getAsString(); + parseLocation.endColumnNumber += exprName.size() - 1; + + m_client->onFieldUsageParsed( + parseLocation, + getParseVariable(decl), + utility::getDeclNameHierarchy(expr->getMemberDecl()) + ); +} + void ASTVisitor::VisitGlobalVariableExprInDeclBody(clang::FunctionDecl* decl, clang::DeclRefExpr* expr) { ParseLocation parseLocation = getParseLocation(expr->getSourceRange()); diff --git a/src/lib/data/parser/cxx/ASTVisitor.h b/src/lib/data/parser/cxx/ASTVisitor.h index 641073ef..25c0e6d8 100644 --- a/src/lib/data/parser/cxx/ASTVisitor.h +++ b/src/lib/data/parser/cxx/ASTVisitor.h @@ -52,6 +52,7 @@ public: virtual void VisitCXXNewExprInDeclBody(clang::FunctionDecl* decl, clang::CXXNewExpr* expr); // type use of new operator virtual void VisitCXXNewExprInDeclBody(clang::VarDecl* decl, clang::CXXNewExpr* expr); // type use of new operator in global space virtual void VisitMemberExprInDeclBody(clang::FunctionDecl* decl, clang::MemberExpr* expr); // field usages + virtual void VisitMemberExprInDeclBody(clang::VarDecl* decl, clang::MemberExpr* expr); // field usages virtual void VisitGlobalVariableExprInDeclBody(clang::FunctionDecl* decl, clang::DeclRefExpr* expr); // global variable usage virtual void VisitGlobalVariableExprInDeclBody(clang::VarDecl* decl, clang::DeclRefExpr* expr); // global variable usage virtual void VisitEnumExprInDeclBody(clang::FunctionDecl* decl, clang::DeclRefExpr* expr); // enum field usage diff --git a/src/lib/data/parser/cxx/name_resolver/CxxDeclNameResolver.cpp b/src/lib/data/parser/cxx/name_resolver/CxxDeclNameResolver.cpp index ed7ead42..1483066d 100644 --- a/src/lib/data/parser/cxx/name_resolver/CxxDeclNameResolver.cpp +++ b/src/lib/data/parser/cxx/name_resolver/CxxDeclNameResolver.cpp @@ -99,7 +99,7 @@ std::string CxxDeclNameResolver::getDeclName() clang::dyn_cast(declaration); clang::TemplateParameterList* parameterList = partialSpecializationDecl->getTemplateParameters(); - int currentParameterIndex = 0; + unsigned int currentParameterIndex = 0; std::string specializedParameterNamePart = "<"; int templateArgumentCount = partialSpecializationDecl->getTemplateArgs().size(); @@ -109,7 +109,16 @@ std::string CxxDeclNameResolver::getDeclName() const clang::TemplateArgument& templateArgument = templateArgumentList.get(i); if (templateArgument.isDependent()) // IMPORTANT_TODO: fix case when arg depends on template parameter of outer template class, or depends on first template parameter. { - specializedParameterNamePart += getTemplateParameterString(parameterList->getParam(currentParameterIndex)); + if(currentParameterIndex < parameterList->size()) + { + specializedParameterNamePart += getTemplateParameterString(parameterList->getParam(currentParameterIndex)); + } + else + { + //this if fixes the crash, but not the problem TODO + const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager(); + LOG_ERROR("Template getParam out of Range "+declaration->getLocation().printToString(sourceManager)); + } currentParameterIndex++; } else @@ -250,4 +259,3 @@ std::string CxxDeclNameResolver::getTemplateArgumentName(const clang::TemplateAr CxxTemplateArgumentNameResolver resolver(getIgnoredContextDecls()); return resolver.getTemplateArgumentName(argument); } - diff --git a/src/lib/settings/Settings.cpp b/src/lib/settings/Settings.cpp index 7dd09a46..7b739fe0 100644 --- a/src/lib/settings/Settings.cpp +++ b/src/lib/settings/Settings.cpp @@ -20,7 +20,7 @@ bool Settings::load(const FilePath& filePath) else { clear(); - LOG_WARNING("File for Settings not found."); + LOG_WARNING("File for Settings not found: " + filePath.str()); return false; } } @@ -33,7 +33,7 @@ void Settings::save() } else { - LOG_WARNING("Settings were not saved."); + LOG_WARNING("Settings were not saved: " + m_filePath.str()); } } @@ -47,7 +47,7 @@ void Settings::save(const FilePath& filePath) } else { - LOG_WARNING("Settings were not saved."); + LOG_WARNING("Settings were not saved: " + filePath.str()); } } diff --git a/src/lib/utility/file/FileSystem.cpp b/src/lib/utility/file/FileSystem.cpp index 78221b09..a2ab34f0 100644 --- a/src/lib/utility/file/FileSystem.cpp +++ b/src/lib/utility/file/FileSystem.cpp @@ -52,6 +52,8 @@ std::vector FileSystem::getFileNamesFromDirectoryUpdatedAfter( return files; } + + std::vector FileSystem::getFileInfosFromPaths( const std::vector& paths, const std::vector& fileExtensions ){ @@ -136,3 +138,13 @@ bool FileSystem::equivalent(const std::string& pathA, const std::string& pathB) return boost::filesystem::path(pathA).compare(boost::filesystem::path(pathB)) == 0; } + +std::vector FileSystem::getSubDirectoies(const FilePath &path) { + std::vector v; + for ( boost::filesystem::recursive_directory_iterator end, dir(path.str()); + dir != end; ++dir ) { + if(boost::filesystem::is_directory(dir->path())) + v.push_back(FilePath(dir->path())); + } + return v; +} diff --git a/src/lib/utility/file/FileSystem.h b/src/lib/utility/file/FileSystem.h index 3db76234..638ade56 100644 --- a/src/lib/utility/file/FileSystem.h +++ b/src/lib/utility/file/FileSystem.h @@ -18,6 +18,7 @@ public: const std::vector& paths, const std::vector& fileExtensions); static std::string getTimeStringNow(); + static std::vector getSubDirectoies(const FilePath& path); static bool exists(const std::string& path); static std::string fileName(const std::string& path); diff --git a/src/test/CxxParserTestSuite.h b/src/test/CxxParserTestSuite.h index 8941980f..59352d9c 100644 --- a/src/test/CxxParserTestSuite.h +++ b/src/test/CxxParserTestSuite.h @@ -2600,6 +2600,13 @@ private: return 0; } + virtual Id onFieldUsageParsed( + const ParseLocation& location, const ParseVariable& user, const NameHierarchy& usedNameHierarchy) + { + usages.push_back(addLocationSuffix(variableStr(user) + " -> " + usedNameHierarchy.getFullName(), location)); + return 0; + } + virtual Id onGlobalVariableUsageParsed( const ParseLocation& location, const ParseFunction& user, const NameHierarchy& usedNameHierarchy) {