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:
Eberhard Graether
2015-05-05 23:21:43 +02:00
parent 7dcf8b0bdb
commit 7d48a873f7
3 changed files with 107 additions and 0 deletions
+23
View File
@@ -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;
}
+77
View File
@@ -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);
}
}
}
+7
View File
@@ -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;