diff --git a/bin/app/data/src/test/usage.cpp b/bin/app/data/src/test/usage.cpp new file mode 100644 index 00000000..c0646740 --- /dev/null +++ b/bin/app/data/src/test/usage.cpp @@ -0,0 +1,23 @@ +#include + +class A +{ +}; + +template +class B +{ +}; + +int main() +{ + A a; + + A* aPtr = nullptr; + + std::shared_ptr aSharedPtr = std::make_shared(); + + B b; + + return 0; +} diff --git a/src/lib/data/parser/cxx/ASTVisitor.cpp b/src/lib/data/parser/cxx/ASTVisitor.cpp index 6e5a9914..5be556b5 100644 --- a/src/lib/data/parser/cxx/ASTVisitor.cpp +++ b/src/lib/data/parser/cxx/ASTVisitor.cpp @@ -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(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( + 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( + 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( + 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( + 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(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(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(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 +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(type)->getNamedType().getTypePtr(); + } + + if (type->getTypeClass() == clang::Type::TemplateSpecialization) + { + const clang::TemplateSpecializationType* templateSpecializationType = type->getAs(); + 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(argumentName)); + + std::shared_ptr argumentType = std::make_shared(argumentNameHierarchy); + + m_client->onTypeUsageParsed(getParseTypeUsage(typeInfo->getTypeLoc(), argumentType), t); + } + } +} + +template +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(argumentName)); + + std::shared_ptr argumentType = std::make_shared(argumentNameHierarchy); + + m_client->onTypeUsageParsed(getParseTypeUsage(sourceRange, argumentType), t); + } + } +} diff --git a/src/lib/data/parser/cxx/ASTVisitor.h b/src/lib/data/parser/cxx/ASTVisitor.h index 445bdd45..641073ef 100644 --- a/src/lib/data/parser/cxx/ASTVisitor.h +++ b/src/lib/data/parser/cxx/ASTVisitor.h @@ -80,6 +80,13 @@ private: ParseFunction getParseFunction(const clang::FunctionDecl* declaration) const; ParseFunction getParseFunction(const clang::FunctionTemplateDecl* declaration) const; + template + void saveClassTemplateArgumentTypeUsages(const clang::TypeSourceInfo* typeInfo, const T& t); + + template + void saveFunctionTemplateArgumentTypeUsages( + const clang::FunctionDecl* decl, const clang::SourceRange& sourceRange, const T& t); + clang::ASTContext* m_context; ParserClient* m_client; FileRegister* m_fileRegister;