data: parsing template functions
* implemented parsing of template functions. * added tests for those cases.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 = "<";
|
||||
|
||||
Reference in New Issue
Block a user