data: template argument handling
* storing template argument relations for cases where at lease one of these (template class, template argument) is defined inside the parsed project files. * prevented storage from saving the same source location multiple times.
This commit is contained in:
@@ -264,6 +264,10 @@
|
||||
<normal>#C1305D</normal>
|
||||
<hover>#C1305D</hover>
|
||||
</template_specialization>
|
||||
<template_member_specialization>
|
||||
<normal>#C1305D</normal>
|
||||
<hover>#C1305D</hover>
|
||||
</template_member_specialization>
|
||||
|
||||
<include>
|
||||
<normal>#878787</normal>
|
||||
|
||||
@@ -264,6 +264,10 @@
|
||||
<normal>#C1305D</normal>
|
||||
<hover>#C1305D</hover>
|
||||
</template_specialization>
|
||||
<template_member_specialization>
|
||||
<normal>#C1305D</normal>
|
||||
<hover>#C1305D</hover>
|
||||
</template_member_specialization>
|
||||
|
||||
<include>
|
||||
<normal>#247368</normal>
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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<StorageSourceLocation> getAllSourceLocations() const;
|
||||
std::shared_ptr<TokenLocationFile> getTokenLocationsForFile(const FilePath& filePath) const;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<clang::FunctionDecl>(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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -113,11 +113,11 @@ ApplicationSettings::ApplicationSettings()
|
||||
|
||||
std::vector<FilePath> ApplicationSettings::getRecentProjects() const
|
||||
{
|
||||
std::vector<FilePath> loadedRecentProjects = getPathValues("user/recent_projects/recent_project");
|
||||
std::vector<FilePath> recentProjects;
|
||||
for(FilePath project : loadedRecentProjects)
|
||||
std::vector<FilePath> loadedRecentProjects = getPathValues("user/recent_projects/recent_project");
|
||||
for (FilePath project: loadedRecentProjects)
|
||||
{
|
||||
if(project.exists())
|
||||
if (project.exists())
|
||||
{
|
||||
recentProjects.push_back(project);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user