diff --git a/bin/app/data/color_schemes/bright.xml b/bin/app/data/color_schemes/bright.xml index da80a91e..da21c92f 100644 --- a/bin/app/data/color_schemes/bright.xml +++ b/bin/app/data/color_schemes/bright.xml @@ -264,6 +264,10 @@ #C1305D #C1305D + + #C1305D + #C1305D + #878787 diff --git a/bin/app/data/color_schemes/dark.xml b/bin/app/data/color_schemes/dark.xml index 50a3e961..6893e025 100644 --- a/bin/app/data/color_schemes/dark.xml +++ b/bin/app/data/color_schemes/dark.xml @@ -264,6 +264,10 @@ #C1305D #C1305D + + #C1305D + #C1305D + #247368 diff --git a/src/lib/data/SqliteStorage.cpp b/src/lib/data/SqliteStorage.cpp index 37114f16..914188c9 100644 --- a/src/lib/data/SqliteStorage.cpp +++ b/src/lib/data/SqliteStorage.cpp @@ -603,6 +603,19 @@ NameHierarchy SqliteStorage::getNameHierarchyById(const Id id) const return nameHierarchy; } +StorageSourceLocation SqliteStorage::getSourceLocationByData(Id elementId, Id fileNodeId, uint startLine, uint startCol, uint endLine, uint endCol, bool isScope) const +{ + return getFirstSourceLocation(( + "SELECT * FROM source_location WHERE element_id == " + std::to_string(elementId) + + " AND file_node_id == " + std::to_string(fileNodeId) + + " AND start_line == " + std::to_string(startLine) + + " AND start_column == " + std::to_string(startCol) + + " AND end_line == " + std::to_string(endLine) + + " AND end_column == " + std::to_string(endCol) + + " AND is_scope == " + std::to_string(isScope) + ";" + ).c_str()); +} + StorageSourceLocation SqliteStorage::getSourceLocationById(const Id id) const { return getFirstSourceLocation( diff --git a/src/lib/data/SqliteStorage.h b/src/lib/data/SqliteStorage.h index 0f6a557f..d55be866 100644 --- a/src/lib/data/SqliteStorage.h +++ b/src/lib/data/SqliteStorage.h @@ -96,6 +96,7 @@ public: NameHierarchy getNameHierarchyById(const Id id) const; + StorageSourceLocation getSourceLocationByData(Id elementId, Id fileNodeId, uint startLine, uint startCol, uint endLine, uint endCol, bool isScope) const; StorageSourceLocation getSourceLocationById(const Id id) const; std::vector getAllSourceLocations() const; std::shared_ptr getTokenLocationsForFile(const FilePath& filePath) const; diff --git a/src/lib/data/Storage.cpp b/src/lib/data/Storage.cpp index 58beeb85..7944341b 100644 --- a/src/lib/data/Storage.cpp +++ b/src/lib/data/Storage.cpp @@ -1356,10 +1356,19 @@ int Storage::addSourceLocation(int elementNodeId, const ParseLocation& location, return 0; } - int locationId = m_sqliteStorage.addSourceLocation( + int locationId = m_sqliteStorage.getSourceLocationByData( elementNodeId, fileNodeId, location.startLineNumber, location.startColumnNumber, location.endLineNumber, location.endColumnNumber, isScope - ); + ).id; + + if (locationId == 0) + { + locationId = m_sqliteStorage.addSourceLocation( + elementNodeId, fileNodeId, location.startLineNumber, location.startColumnNumber, + location.endLineNumber, location.endColumnNumber, isScope + ); + } + return locationId; } } diff --git a/src/lib/data/parser/cxx/ASTVisitor.cpp b/src/lib/data/parser/cxx/ASTVisitor.cpp index 1ec0cc17..229ee7e2 100644 --- a/src/lib/data/parser/cxx/ASTVisitor.cpp +++ b/src/lib/data/parser/cxx/ASTVisitor.cpp @@ -305,6 +305,7 @@ bool ASTVisitor::VisitTemplateTemplateParmDecl(clang::TemplateTemplateParmDecl * bool ASTVisitor::VisitClassTemplateDecl(clang::ClassTemplateDecl* declaration) { NameHierarchy rarchy = utility::getDeclNameHierarchy(declaration); + if (isLocatedInUnparsedProjectFile(declaration)) { NameHierarchy templateRecordNameHierarchy = utility::getDeclNameHierarchy(declaration); @@ -323,43 +324,42 @@ bool ASTVisitor::VisitClassTemplateDecl(clang::ClassTemplateDecl* declaration) } } - // 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 (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++ + ) { - for (clang::ClassTemplateDecl::spec_iterator it = declaration->specializations().begin(); - it != declaration->specializations().end(); it++ - ) + clang::ClassTemplateSpecializationDecl* specializationDecl = *it; + NameHierarchy specializedRecordNameHierarchy = utility::getDeclNameHierarchy(specializationDecl); + + ParseLocation specializationLocation = getParseLocationForNamedDecl(*it); + if (specializationDecl->getSpecializationKind() == clang::TSK_ImplicitInstantiation) { - clang::ClassTemplateSpecializationDecl* specializationDecl = *it; + specializationLocation = getParseLocation(specializationDecl->getPointOfInstantiation()); + } - ParseLocation specializationLocation = getParseLocationForNamedDecl(*it); - if (specializationDecl->getSpecializationKind() == clang::TSK_ImplicitInstantiation) + // template arguments + std::string specializationFilePath = specializationLocation.filePath.str(); + const clang::TemplateArgumentList &argList = specializationDecl->getTemplateArgs(); + for (size_t i = 0; i < argList.size(); i++) // TODO: handle arguments of partial template spec and template functions the same! + { + const clang::TemplateArgument& argument = argList.get(i); + + bool addArgument = isLocatedInProjectFile(declaration); // TODO: Store this value somewhere! + if (!addArgument) { - specializationLocation = getParseLocation(specializationDecl->getPointOfInstantiation()); + if (argument.getKind() == clang::TemplateArgument::Type) + { + clang::TagDecl *argumentDecl = argument.getAsType()->getAsTagDecl(); + if (argumentDecl && isLocatedInProjectFile(getParseLocation(argumentDecl->getSourceRange()))) + { + addArgument = true; + } + } } - - NameHierarchy specializedRecordNameHierarchy = utility::getDeclNameHierarchy(specializationDecl); - - ParserClient::RecordType specializedRecordType = specializationDecl->isStruct() ? ParserClient::RECORD_STRUCT : ParserClient::RECORD_CLASS; - - // The specializationParent can be an indirect specialization of the ClassTemplate (by specializing a partial specialization). - NameHierarchy specializationParentNameHierarchy = utility::getTemplateSpecializationParentNameHierarchy(specializationDecl); - - m_client->onTemplateRecordSpecializationParsed( - specializationLocation, - specializedRecordNameHierarchy, - specializedRecordType, - specializationParentNameHierarchy - ); - - - // template arguments - std::string specializationFilePath = specializationLocation.filePath.str(); - const clang::TemplateArgumentList &argList = specializationDecl->getTemplateArgs(); - for (size_t i = 0; i < argList.size(); i++) + if (addArgument) { - NameHierarchy argumentNameHierarchy = utility::templateArgumentToDataType(argList.get(i))->getTypeNameHierarchy(); + NameHierarchy argumentNameHierarchy = utility::templateArgumentToDataType(argument)->getTypeNameHierarchy(); if (argumentNameHierarchy.size()) // FIXME: Some TemplateArgument kinds are not handled yet. { @@ -370,8 +370,22 @@ bool ASTVisitor::VisitClassTemplateDecl(clang::ClassTemplateDecl* declaration) ); } } + } - // template methods + if (isLocatedInProjectFile(declaration)) + { + ParserClient::RecordType specializedRecordType = specializationDecl->isStruct() ? ParserClient::RECORD_STRUCT : ParserClient::RECORD_CLASS; + // The specializationParent can be an indirect specialization of the ClassTemplate (by specializing a partial specialization). + NameHierarchy specializationParentNameHierarchy = utility::getTemplateSpecializationParentNameHierarchy(specializationDecl); + + m_client->onTemplateRecordSpecializationParsed( + specializationLocation, + specializedRecordNameHierarchy, + specializedRecordType, + specializationParentNameHierarchy + ); + + // template member specializations if (specializationDecl->getSpecializationKind() == clang::TSK_ImplicitInstantiation) { for (clang::CXXRecordDecl::method_iterator methodIt = specializationDecl->method_begin(); methodIt != specializationDecl->method_end(); methodIt++) @@ -394,7 +408,7 @@ bool ASTVisitor::VisitClassTemplateDecl(clang::ClassTemplateDecl* declaration) getParseLocation(methodDecl->getMemberSpecializationInfo()->getPointOfInstantiation()), getParseFunction(methodDecl), getParseFunction(clang::dyn_cast(specializedNamedDecel)) - ); + ); } } } @@ -778,6 +792,15 @@ bool ASTVisitor::isLocatedInUnparsedProjectFile(const clang::Decl* declaration) return m_fileRegister->includeFileIsParsing(FilePath(m_context->getSourceManager().getFilename(location))); } +bool ASTVisitor::isLocatedInProjectFile(const ParseLocation& location) const +{ + if (location.isValid()) + { + return m_fileRegister->getFileManager()->hasFilePath(location.filePath); + } + return false; +} + bool ASTVisitor::isLocatedInProjectFile(const clang::Decl* declaration) const { const clang::SourceLocation& location = declaration->getLocStart(); diff --git a/src/lib/data/parser/cxx/ASTVisitor.h b/src/lib/data/parser/cxx/ASTVisitor.h index 9e51fcbd..275eef08 100644 --- a/src/lib/data/parser/cxx/ASTVisitor.h +++ b/src/lib/data/parser/cxx/ASTVisitor.h @@ -61,6 +61,7 @@ public: private: bool isLocatedInUnparsedProjectFile(const clang::Decl* declaration) const; + bool isLocatedInProjectFile(const ParseLocation& location) const; bool isLocatedInProjectFile(const clang::Decl* declaration) const; ParserClient::AccessType convertAccessType(clang::AccessSpecifier) const; diff --git a/src/lib/settings/ApplicationSettings.cpp b/src/lib/settings/ApplicationSettings.cpp index 439986a6..ef8d3672 100644 --- a/src/lib/settings/ApplicationSettings.cpp +++ b/src/lib/settings/ApplicationSettings.cpp @@ -113,11 +113,11 @@ ApplicationSettings::ApplicationSettings() std::vector ApplicationSettings::getRecentProjects() const { - std::vector loadedRecentProjects = getPathValues("user/recent_projects/recent_project"); std::vector recentProjects; - for(FilePath project : loadedRecentProjects) + std::vector loadedRecentProjects = getPathValues("user/recent_projects/recent_project"); + for (FilePath project: loadedRecentProjects) { - if(project.exists()) + if (project.exists()) { recentProjects.push_back(project); }