data: parsing template functions

* implemented parsing of template functions.
* added tests for those cases.
This commit is contained in:
malte_langkabel
2015-02-16 16:22:58 +01:00
parent 115b19c266
commit 6c3c8cdcc1
7 changed files with 214 additions and 76 deletions
+5 -5
View File
@@ -100,14 +100,14 @@ public:
virtual Id onTypeUsageParsed(const ParseTypeUsage& type, const ParseFunction& function) = 0;
virtual Id onTypeUsageParsed(const ParseTypeUsage& type, const ParseVariable& variable) = 0;
virtual Id onTemplateArgumentParsed(
const ParseLocation& location, const std::vector<std::string>& argumentNameHierarchy,
const std::vector<std::string>& templateNameHierarchy) = 0;
virtual Id onTemplateDefaultArgumentTypeParsed(
const ParseTypeUsage& type, const std::vector<std::string>& templateArgumentTypeNameHierarchy) = 0;
virtual Id onTemplateRecordParameterTypeParsed(
const ParseLocation& location, const std::string& templateParameterTypeName,
const std::vector<std::string>& templateRecordNameHierarchy) = 0;
virtual Id onTemplateRecordArgumentTypeParsed(
const ParseLocation& location, const std::vector<std::string>& templateArgumentTypeNameHierarchy,
const std::vector<std::string>& templateRecordNameHierarchy) = 0;
virtual Id onTemplateDefaultArgumentTypeParsed(
const ParseTypeUsage& type, const std::vector<std::string>& templateArgumentTypeNameHierarchy) = 0;
virtual Id onTemplateRecordSpecializationParsed(
const ParseLocation& location, const std::vector<std::string>& specializedRecordNameHierarchy,
const RecordType specializedRecordType, const std::vector<std::string>& specializedFromNameHierarchy) = 0;
+84 -18
View File
@@ -322,6 +322,7 @@ bool ASTVisitor::VisitClassTemplateDecl(clang::ClassTemplateDecl* declaration)
{
clang::ClassTemplateSpecializationDecl* specializationDecl = *it;
// The specializationParent can be an indirect specialization of the ClassTemplate (by specializing a partial specialization).
std::vector<std::string> specializationParentNameHierarchy = utility::getTemplateSpecializationParentNameHierarchy(specializationDecl);
ParserClient::RecordType specializedRecordType = specializationDecl->isStruct() ? ParserClient::RECORD_STRUCT : ParserClient::RECORD_CLASS;
@@ -336,7 +337,7 @@ bool ASTVisitor::VisitClassTemplateDecl(clang::ClassTemplateDecl* declaration)
std::vector<std::string> argumentNameHierarchy = utility::templateArgumentToDataType(argList.get(i)).getTypeNameHierarchy();
if (argumentNameHierarchy.size()) // FIXME: Some TemplateArgument kinds are not handled yet.
{
m_client->onTemplateRecordArgumentTypeParsed(
m_client->onTemplateArgumentParsed(
ParseLocation(), // TODO: Find a valid ParseLocation here!
argumentNameHierarchy,
specializedRecordNameHierarchy
@@ -380,7 +381,7 @@ bool ASTVisitor::VisitClassTemplatePartialSpecializationDecl(clang::ClassTemplat
const clang::TemplateArgumentLoc& argumentLoc = argumentInfoList->operator[](i);
const clang::QualType argumentType = argumentLoc.getArgument().getAsType();
m_client->onTemplateRecordArgumentTypeParsed(
m_client->onTemplateArgumentParsed(
getParseLocation(argumentLoc.getSourceRange()),
utility::qualTypeToDataType(argumentType).getTypeNameHierarchy(),
specializedRecordNameHierarchy);
@@ -391,21 +392,9 @@ bool ASTVisitor::VisitClassTemplatePartialSpecializationDecl(clang::ClassTemplat
bool ASTVisitor::VisitFunctionTemplateDecl(clang::FunctionTemplateDecl *declaration)
{
const ParseFunction templateFunction = getParseFunction(declaration);
if (isLocatedInMainFile(declaration))
{
const ParseFunction templateFunction = getParseFunction(declaration->getTemplatedDecl());
for (clang::FunctionTemplateDecl::spec_iterator it = declaration->specializations().begin(); it != declaration->specializations().end(); it++)
{
ParseLocation specializedFunctionLocation = getParseLocationForNamedDecl(*(it));
ParseFunction specializedFunction = getParseFunction(*(it));
m_client->onTemplateFunctionSpecializationParsed(
specializedFunctionLocation,
specializedFunction,
templateFunction);
m_client->onFunctionParsed(specializedFunctionLocation, specializedFunction, getParseLocationOfFunctionBody(*(it)));
}
clang::TemplateParameterList* parameterList = declaration->getTemplateParameters();
for (size_t i = 0; i < parameterList->size(); i++)
{
@@ -423,7 +412,58 @@ bool ASTVisitor::VisitFunctionTemplateDecl(clang::FunctionTemplateDecl *declarat
}
}
}
if (isLocatedInSourceFile(declaration))
{
for (clang::FunctionTemplateDecl::spec_iterator it = declaration->specializations().begin(); it != declaration->specializations().end(); it++)
{
const clang::FunctionDecl* specializedFunctionDecl = *it;
ParseLocation specializedFunctionLocation = getParseLocationForNamedDecl(specializedFunctionDecl);
ParseFunction specializedFunction = getParseFunction(specializedFunctionDecl);
clang::FunctionTemplateSpecializationInfo* info = specializedFunctionDecl->getTemplateSpecializationInfo();
if (info->getTemplateSpecializationKind() == clang::TSK_ExplicitSpecialization)
{
if (isLocatedInMainFile(declaration))
{
m_client->onTemplateFunctionSpecializationParsed(
specializedFunctionLocation,
specializedFunction,
templateFunction);
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->onTemplateArgumentParsed(
getParseLocation(argumentLoc.getSourceRange()),
utility::qualTypeToDataType(argumentType).getTypeNameHierarchy(),
specializedFunction.nameHierarchy);
}
}
}
else // info->getTemplateSpecializationKind() == clang::TSK_ImplicitInstantiation
{
m_client->onTemplateFunctionSpecializationParsed(
specializedFunctionLocation,
specializedFunction,
templateFunction);
const clang::TemplateArgumentList* argumentList = specializedFunctionDecl->getTemplateSpecializationArgs();
for (size_t i = 0; i < argumentList->size(); i++)
{
const clang::TemplateArgument& argument = argumentList->get(i);
const clang::QualType argumentType = argument.getAsType();
m_client->onTemplateArgumentParsed(
ParseLocation(), // TODO: get ParseLocation
utility::qualTypeToDataType(argumentType).getTypeNameHierarchy(),
specializedFunction.nameHierarchy);
}
}
}
}
return true;
}
@@ -682,7 +722,7 @@ ParseLocation ASTVisitor::getParseLocation(const clang::SourceRange& sourceRange
);
}
ParseLocation ASTVisitor::getParseLocationForNamedDecl(clang::NamedDecl* decl, const clang::SourceLocation& loc) const
ParseLocation ASTVisitor::getParseLocationForNamedDecl(const clang::NamedDecl* decl, const clang::SourceLocation& loc) const
{
const clang::SourceManager& sourceManager = m_context->getSourceManager();
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(loc);
@@ -696,12 +736,12 @@ ParseLocation ASTVisitor::getParseLocationForNamedDecl(clang::NamedDecl* decl, c
);
}
ParseLocation ASTVisitor::getParseLocationForNamedDecl(clang::NamedDecl* decl) const
ParseLocation ASTVisitor::getParseLocationForNamedDecl(const clang::NamedDecl* decl) const
{
return getParseLocationForNamedDecl(decl, decl->getLocation());
}
ParseLocation ASTVisitor::getParseLocationOfFunctionBody(clang::FunctionDecl* decl) const
ParseLocation ASTVisitor::getParseLocationOfFunctionBody(const clang::FunctionDecl* decl) const
{
if (decl->hasBody() && decl->isThisDeclarationADefinition())
{
@@ -818,3 +858,29 @@ ParseFunction ASTVisitor::getParseFunction(const clang::FunctionDecl* declaratio
isConst
);
}
ParseFunction ASTVisitor::getParseFunction(const clang::FunctionTemplateDecl* declaration) const
{
bool isStatic = false;
bool isConst = false;
const clang::FunctionDecl* templatedDecl = declaration->getTemplatedDecl();
if (clang::isa<clang::CXXMethodDecl>(templatedDecl))
{
const clang::CXXMethodDecl* methodDecl = clang::dyn_cast<const clang::CXXMethodDecl>(templatedDecl);
isStatic = methodDecl->isStatic();
isConst = methodDecl->isConst();
}
else
{
isStatic = templatedDecl->getStorageClass() == clang::SC_Static;
}
return ParseFunction(
getParseTypeUsageOfReturnType(templatedDecl),
utility::getDeclNameHierarchy(declaration),
getParameters(templatedDecl),
isStatic,
isConst
);
}
+4 -3
View File
@@ -62,9 +62,9 @@ private:
ParserClient::AccessType convertAccessType(clang::AccessSpecifier) const;
ParseLocation getParseLocation(const clang::SourceRange& sourceRange) const;
ParseLocation getParseLocationForNamedDecl(clang::NamedDecl* decl, const clang::SourceLocation& loc) const;
ParseLocation getParseLocationForNamedDecl(clang::NamedDecl* decl) const;
ParseLocation getParseLocationOfFunctionBody(clang::FunctionDecl* decl) const;
ParseLocation getParseLocationForNamedDecl(const clang::NamedDecl* decl, const clang::SourceLocation& loc) const;
ParseLocation getParseLocationForNamedDecl(const clang::NamedDecl* decl) const;
ParseLocation getParseLocationOfFunctionBody(const clang::FunctionDecl* decl) const;
ParseLocation getParseLocationOfRecordBody(clang::CXXRecordDecl* decl) const;
ParseTypeUsage getParseTypeUsage(clang::TypeLoc typeLoc, const clang::QualType& type) const;
@@ -73,6 +73,7 @@ private:
ParseVariable getParseVariable(const clang::DeclaratorDecl* declaration) const;
ParseFunction getParseFunction(const clang::FunctionDecl* declaration) const;
ParseFunction getParseFunction(const clang::FunctionTemplateDecl* declaration) const;
clang::ASTContext* m_context;
ParserClient* m_client;
+21
View File
@@ -255,6 +255,27 @@ namespace utility
declName += specializedParameterNamePart;
}
}
else if (clang::isa<clang::FunctionDecl>(declaration))
{
clang::FunctionTemplateDecl* templateFunctionDeclaration = clang::dyn_cast<clang::FunctionDecl>(declaration)->getDescribedFunctionTemplate();
if (templateFunctionDeclaration)
{
declName = getDeclName(templateFunctionDeclaration);
}
else if (clang::dyn_cast<clang::FunctionDecl>(declaration)->isFunctionTemplateSpecialization())
{
std::string specializedParameterNamePart = "<";
const clang::TemplateArgumentList* templateArgumentList = clang::dyn_cast<clang::FunctionDecl>(declaration)->getTemplateSpecializationArgs();
for (size_t i = 0; i < templateArgumentList->size(); i++)
{
const clang::TemplateArgument& templateArgument = templateArgumentList->get(i);
specializedParameterNamePart += templateArgumentToDataType(templateArgument).getFullTypeName();
specializedParameterNamePart += (i < templateArgumentList->size() - 1) ? ", " : "";
}
specializedParameterNamePart += ">";
declName += specializedParameterNamePart;
}
}
else if (clang::isa<clang::TemplateDecl>(declaration))
{
std::string templateParameterNamePart = "<";