data: parse type usages of types used as template arguments
This change ist just an interim solution and does not cover all cases. The TokenLocation saved for the template argument is the location of the whole expression.
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
#include <memory>
|
||||
|
||||
class A
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class B
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
A a;
|
||||
|
||||
A* aPtr = nullptr;
|
||||
|
||||
std::shared_ptr<A> aSharedPtr = std::make_shared<A>();
|
||||
|
||||
B<A> b;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -9,6 +9,8 @@
|
||||
#include "utility/utilityString.h"
|
||||
|
||||
#include "data/parser/cxx/ASTBodyVisitor.h"
|
||||
#include "data/parser/cxx/name_resolver/CxxDeclNameResolver.h"
|
||||
#include "data/parser/cxx/name_resolver/CxxTemplateArgumentNameResolver.h"
|
||||
#include "data/parser/cxx/utilityCxx.h"
|
||||
#include "data/parser/ParseFunction.h"
|
||||
#include "data/parser/ParseLocation.h"
|
||||
@@ -233,6 +235,8 @@ bool ASTVisitor::VisitCXXConstructorDecl(clang::CXXConstructorDecl* declaration)
|
||||
getParseTypeUsage(init->getTypeSourceInfo()->getTypeLoc(), init->getTypeSourceInfo()->getType()),
|
||||
getParseFunction(declaration)
|
||||
);
|
||||
|
||||
saveClassTemplateArgumentTypeUsages<ParseFunction>(init->getTypeSourceInfo(), getParseFunction(declaration));
|
||||
}
|
||||
|
||||
ASTBodyVisitor bodyVisitor(this, declaration);
|
||||
@@ -517,6 +521,9 @@ void ASTVisitor::VisitCallExprInDeclBody(clang::FunctionDecl* decl, clang::CallE
|
||||
getParseFunction(decl),
|
||||
getParseFunction(expr->getDirectCallee())
|
||||
);
|
||||
|
||||
saveFunctionTemplateArgumentTypeUsages<ParseFunction>(
|
||||
expr->getDirectCallee(), expr->getSourceRange(), getParseFunction(decl));
|
||||
}
|
||||
|
||||
void ASTVisitor::VisitCallExprInDeclBody(clang::VarDecl* decl, clang::CallExpr* expr)
|
||||
@@ -532,6 +539,9 @@ void ASTVisitor::VisitCallExprInDeclBody(clang::VarDecl* decl, clang::CallExpr*
|
||||
getParseVariable(decl),
|
||||
getParseFunction(expr->getDirectCallee())
|
||||
);
|
||||
|
||||
saveFunctionTemplateArgumentTypeUsages<ParseVariable>(
|
||||
expr->getDirectCallee(), expr->getSourceRange(), getParseVariable(decl));
|
||||
}
|
||||
|
||||
void ASTVisitor::VisitCXXConstructExprInDeclBody(clang::FunctionDecl* decl, clang::CXXConstructExpr* expr)
|
||||
@@ -587,6 +597,9 @@ void ASTVisitor::VisitCXXConstructExprInDeclBody(clang::FunctionDecl* decl, clan
|
||||
getParseFunction(decl),
|
||||
getParseFunction(expr->getConstructor())
|
||||
);
|
||||
|
||||
saveFunctionTemplateArgumentTypeUsages<ParseFunction>(
|
||||
expr->getConstructor(), expr->getSourceRange(), getParseFunction(decl));
|
||||
}
|
||||
|
||||
void ASTVisitor::VisitCXXConstructExprInDeclBody(clang::VarDecl* decl, clang::CXXConstructExpr* expr)
|
||||
@@ -596,6 +609,9 @@ void ASTVisitor::VisitCXXConstructExprInDeclBody(clang::VarDecl* decl, clang::CX
|
||||
getParseVariable(decl),
|
||||
getParseFunction(expr->getConstructor())
|
||||
);
|
||||
|
||||
saveFunctionTemplateArgumentTypeUsages<ParseVariable>(
|
||||
expr->getConstructor(), expr->getSourceRange(), getParseVariable(decl));
|
||||
}
|
||||
|
||||
void ASTVisitor::VisitCXXNewExprInDeclBody(clang::FunctionDecl* decl, clang::CXXNewExpr* expr)
|
||||
@@ -604,6 +620,8 @@ void ASTVisitor::VisitCXXNewExprInDeclBody(clang::FunctionDecl* decl, clang::CXX
|
||||
getParseTypeUsage(expr->getAllocatedTypeSourceInfo()->getTypeLoc(), expr->getAllocatedType()),
|
||||
getParseFunction(decl)
|
||||
);
|
||||
|
||||
saveClassTemplateArgumentTypeUsages<ParseFunction>(expr->getAllocatedTypeSourceInfo(), getParseFunction(decl));
|
||||
}
|
||||
|
||||
void ASTVisitor::VisitCXXNewExprInDeclBody(clang::VarDecl* decl, clang::CXXNewExpr* expr)
|
||||
@@ -612,6 +630,8 @@ void ASTVisitor::VisitCXXNewExprInDeclBody(clang::VarDecl* decl, clang::CXXNewEx
|
||||
getParseTypeUsage(expr->getAllocatedTypeSourceInfo()->getTypeLoc(), expr->getAllocatedType()),
|
||||
getParseVariable(decl)
|
||||
);
|
||||
|
||||
saveClassTemplateArgumentTypeUsages<ParseVariable>(expr->getAllocatedTypeSourceInfo(), getParseVariable(decl));
|
||||
}
|
||||
|
||||
void ASTVisitor::VisitMemberExprInDeclBody(clang::FunctionDecl* decl, clang::MemberExpr* expr)
|
||||
@@ -690,6 +710,8 @@ void ASTVisitor::VisitVarDeclInDeclBody(clang::FunctionDecl* decl, clang::VarDec
|
||||
getParseTypeUsage(varDecl->getTypeSourceInfo()->getTypeLoc(), varDecl->getType()),
|
||||
getParseFunction(decl)
|
||||
);
|
||||
|
||||
saveClassTemplateArgumentTypeUsages<ParseFunction>(varDecl->getTypeSourceInfo(), getParseFunction(decl));
|
||||
}
|
||||
|
||||
bool ASTVisitor::isLocatedInUnparsedProjectFile(const clang::Decl* declaration) const
|
||||
@@ -920,3 +942,58 @@ ParseFunction ASTVisitor::getParseFunction(const clang::FunctionTemplateDecl* de
|
||||
{
|
||||
return getParseFunction(declaration->getTemplatedDecl());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void ASTVisitor::saveClassTemplateArgumentTypeUsages(const clang::TypeSourceInfo* typeInfo, const T& t)
|
||||
{
|
||||
const clang::Type* type = typeInfo->getType().getTypePtr();
|
||||
|
||||
if (type->getTypeClass() == clang::Type::Elaborated)
|
||||
{
|
||||
type = clang::dyn_cast<clang::ElaboratedType>(type)->getNamedType().getTypePtr();
|
||||
}
|
||||
|
||||
if (type->getTypeClass() == clang::Type::TemplateSpecialization)
|
||||
{
|
||||
const clang::TemplateSpecializationType* templateSpecializationType = type->getAs<clang::TemplateSpecializationType>();
|
||||
CxxDeclNameResolver declNameResolver(templateSpecializationType->getTemplateName().getAsTemplateDecl());
|
||||
|
||||
CxxTemplateArgumentNameResolver resolver;
|
||||
for (size_t i = 0; i < templateSpecializationType->getNumArgs(); i++)
|
||||
{
|
||||
std::string argumentName = resolver.getTemplateArgumentName(templateSpecializationType->getArg(i));
|
||||
NameHierarchy argumentNameHierarchy;
|
||||
argumentNameHierarchy.push(std::make_shared<NameElement>(argumentName));
|
||||
|
||||
std::shared_ptr<DataType> argumentType = std::make_shared<NamedDataType>(argumentNameHierarchy);
|
||||
|
||||
m_client->onTypeUsageParsed(getParseTypeUsage(typeInfo->getTypeLoc(), argumentType), t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void ASTVisitor::saveFunctionTemplateArgumentTypeUsages(
|
||||
const clang::FunctionDecl* decl, const clang::SourceRange& sourceRange, const T& t
|
||||
){
|
||||
const clang::TemplateArgumentList* argumentList = decl->getTemplateSpecializationArgs();
|
||||
if (!argumentList)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CxxTemplateArgumentNameResolver resolver;
|
||||
for (size_t i = 0; i < argumentList->size(); i++)
|
||||
{
|
||||
std::string argumentName = resolver.getTemplateArgumentName(argumentList->get(i));
|
||||
if (argumentName.size())
|
||||
{
|
||||
NameHierarchy argumentNameHierarchy;
|
||||
argumentNameHierarchy.push(std::make_shared<NameElement>(argumentName));
|
||||
|
||||
std::shared_ptr<DataType> argumentType = std::make_shared<NamedDataType>(argumentNameHierarchy);
|
||||
|
||||
m_client->onTypeUsageParsed(getParseTypeUsage(sourceRange, argumentType), t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,6 +80,13 @@ private:
|
||||
ParseFunction getParseFunction(const clang::FunctionDecl* declaration) const;
|
||||
ParseFunction getParseFunction(const clang::FunctionTemplateDecl* declaration) const;
|
||||
|
||||
template <typename T>
|
||||
void saveClassTemplateArgumentTypeUsages(const clang::TypeSourceInfo* typeInfo, const T& t);
|
||||
|
||||
template <typename T>
|
||||
void saveFunctionTemplateArgumentTypeUsages(
|
||||
const clang::FunctionDecl* decl, const clang::SourceRange& sourceRange, const T& t);
|
||||
|
||||
clang::ASTContext* m_context;
|
||||
ParserClient* m_client;
|
||||
FileRegister* m_fileRegister;
|
||||
|
||||
Reference in New Issue
Block a user