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:
malte_langkabel
2015-11-17 18:09:20 +01:00
parent 88b94a21d0
commit 901fa1a387
8 changed files with 92 additions and 37 deletions
+4
View File
@@ -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>
+4
View File
@@ -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>
+13
View File
@@ -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(
+1
View File
@@ -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;
+11 -2
View File
@@ -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;
}
}
+55 -32
View File
@@ -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();
+1
View File
@@ -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;
+3 -3
View File
@@ -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);
}