logic: implemented recording correct signatures for c++ lambdas
This commit is contained in:
@@ -46,12 +46,9 @@ add_files(
|
||||
data/parser/cxx/CxxVerboseAstVisitor.h
|
||||
data/parser/cxx/PreprocessorCallbacks.cpp
|
||||
data/parser/cxx/PreprocessorCallbacks.h
|
||||
data/parser/cxx/utilityCxx.cpp
|
||||
data/parser/cxx/utilityCxx.h
|
||||
|
||||
utility/CompilationDatabase.cpp
|
||||
utility/CompilationDatabase.h
|
||||
|
||||
)
|
||||
|
||||
add_files(
|
||||
|
||||
@@ -158,35 +158,24 @@ std::shared_ptr<CxxDeclName> CxxDeclNameResolver::getDeclName(const clang::Named
|
||||
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(declaration->getLocStart());
|
||||
const std::string symbolKindName = (recordDecl->isStruct() ? "struct" : "class");
|
||||
return std::make_shared<CxxDeclName>(getNameForAnonymousSymbol(symbolKindName, presumedBegin), std::vector<std::string>());
|
||||
// TODO: TESt what if this one has template params??
|
||||
}
|
||||
}
|
||||
else if (clang::isa<clang::FunctionDecl>(declaration))
|
||||
{
|
||||
if (const clang::CXXMethodDecl* methodDecl = clang::dyn_cast_or_null<clang::CXXMethodDecl>(declaration))
|
||||
{
|
||||
if (methodDecl->getParent()->isLambda())
|
||||
{
|
||||
const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager();
|
||||
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(methodDecl->getParent()->getLocStart());
|
||||
std::string lambdaName = "lambda at " + std::to_string(presumedBegin.getLine()) + ":" + std::to_string(presumedBegin.getColumn());
|
||||
|
||||
return std::make_shared<CxxFunctionDeclName>(
|
||||
lambdaName,
|
||||
std::vector<std::string>(),
|
||||
std::make_shared<CxxTypeName>("void", std::vector<std::string>(), std::shared_ptr<CxxName>()), // TODO: check signature!
|
||||
std::vector<std::shared_ptr<CxxTypeName>>(),
|
||||
false,
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
const clang::FunctionDecl* functionDecl = clang::dyn_cast<clang::FunctionDecl>(declaration);
|
||||
|
||||
std::string functionName = declNameString;
|
||||
std::vector<std::string> templateArguments;
|
||||
|
||||
const clang::FunctionDecl* functionDecl = clang::dyn_cast<clang::FunctionDecl>(declaration);
|
||||
if (clang::FunctionTemplateDecl* templateFunctionDeclaration = functionDecl->getDescribedFunctionTemplate())
|
||||
|
||||
if ((clang::dyn_cast_or_null<clang::CXXMethodDecl>(functionDecl)) &&
|
||||
(clang::dyn_cast_or_null<clang::CXXMethodDecl>(functionDecl)->getParent()->isLambda()))
|
||||
{
|
||||
const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager();
|
||||
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(clang::dyn_cast_or_null<clang::CXXMethodDecl>(functionDecl)->getParent()->getLocStart());
|
||||
functionName = "lambda at " + std::to_string(presumedBegin.getLine()) + ":" + std::to_string(presumedBegin.getColumn());
|
||||
}
|
||||
else if (clang::FunctionTemplateDecl* templateFunctionDeclaration = functionDecl->getDescribedFunctionTemplate())
|
||||
{
|
||||
std::shared_ptr<CxxDeclName> templateDeclName = getDeclName(templateFunctionDeclaration);
|
||||
functionName = templateDeclName->getName();
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
#include "data/parser/cxx/utilityCxx.h"
|
||||
|
||||
#include "data/parser/cxx/name_resolver/CxxDeclNameResolver.h"
|
||||
#include "data/parser/cxx/name_resolver/CxxTypeNameResolver.h"
|
||||
#include "utility/logging/logging.h"
|
||||
|
||||
namespace utility
|
||||
{
|
||||
/*
|
||||
std::shared_ptr<DataType> qualTypeToDataType(clang::QualType qualType)
|
||||
{
|
||||
CxxTypeNameResolver resolver;
|
||||
return resolver.qualTypeToDataType(qualType);
|
||||
}
|
||||
|
||||
NameHierarchy getDeclNameHierarchy(const clang::Decl* declaration)
|
||||
{
|
||||
CxxDeclNameResolver resolver(declaration);
|
||||
return resolver.getDeclNameHierarchy();
|
||||
}
|
||||
|
||||
NameHierarchy getTemplateSpecializationParentNameHierarchy(clang::ClassTemplateSpecializationDecl* declaration)
|
||||
{
|
||||
NameHierarchy specializationParentNameHierarchy;
|
||||
llvm::PointerUnion<clang::ClassTemplateDecl*, clang::ClassTemplatePartialSpecializationDecl*> pu = declaration->getSpecializedTemplateOrPartial();
|
||||
if (pu.is<clang::ClassTemplateDecl*>())
|
||||
{
|
||||
clang::ClassTemplateDecl* specializedFromDecl = pu.get<clang::ClassTemplateDecl*>();
|
||||
specializationParentNameHierarchy = utility::getDeclNameHierarchy(specializedFromDecl);
|
||||
}
|
||||
else if (pu.is<clang::ClassTemplatePartialSpecializationDecl*>())
|
||||
{
|
||||
clang::ClassTemplatePartialSpecializationDecl* specializedFromDecl = pu.get<clang::ClassTemplatePartialSpecializationDecl*>();
|
||||
specializationParentNameHierarchy = utility::getDeclNameHierarchy(specializedFromDecl);
|
||||
}
|
||||
return specializationParentNameHierarchy;
|
||||
}
|
||||
|
||||
std::shared_ptr<DataType> templateArgumentToDataType(const clang::TemplateArgument& argument) // remove this! this is stupid! agurment is not always a datatype.
|
||||
{
|
||||
const clang::TemplateArgument::ArgKind kind = argument.getKind();
|
||||
switch (kind)
|
||||
{
|
||||
case clang::TemplateArgument::Type:
|
||||
return utility::qualTypeToDataType(argument.getAsType());
|
||||
case clang::TemplateArgument::Integral:
|
||||
return utility::qualTypeToDataType(argument.getIntegralType());
|
||||
case clang::TemplateArgument::Null:
|
||||
LOG_ERROR("Type of template argument not handled: Null");
|
||||
break;
|
||||
case clang::TemplateArgument::Declaration:
|
||||
return utility::qualTypeToDataType(argument.getAsDecl()->getType());
|
||||
case clang::TemplateArgument::NullPtr:
|
||||
return utility::qualTypeToDataType(argument.getNullPtrType());
|
||||
break;
|
||||
case clang::TemplateArgument::Template:
|
||||
{
|
||||
clang::TemplateName templateName = argument.getAsTemplate();
|
||||
switch (templateName.getKind())
|
||||
{
|
||||
case clang::TemplateName::Template:
|
||||
return std::make_shared<NamedDataType>(getDeclNameHierarchy(templateName.getAsTemplateDecl()));
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("Type of template argument not handled: Template");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case clang::TemplateArgument::TemplateExpansion:
|
||||
LOG_ERROR("Type of template argument not handled: TemplateExpansion");
|
||||
break;
|
||||
case clang::TemplateArgument::Expression:
|
||||
return utility::qualTypeToDataType(argument.getAsExpr()->getType());
|
||||
case clang::TemplateArgument::Pack:
|
||||
{
|
||||
std::string typeName = "<";
|
||||
argument.getPackAsArray();
|
||||
llvm::ArrayRef<clang::TemplateArgument> pack = argument.getPackAsArray();
|
||||
for (size_t i = 0; i < pack.size(); i++)
|
||||
{
|
||||
typeName += templateArgumentToDataType(pack[i])->getFullTypeName();
|
||||
if (i < pack.size() - 1)
|
||||
{
|
||||
typeName += ", ";
|
||||
}
|
||||
}
|
||||
typeName += ">";
|
||||
|
||||
NameHierarchy typeNameHerarchy;
|
||||
typeNameHerarchy.push(std::make_shared<NameElement>(typeName));
|
||||
return std::make_shared<NamedDataType>(typeNameHerarchy);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return std::make_shared<NamedDataType>(NameHierarchy());
|
||||
}
|
||||
*/
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
#ifndef UTILITY_CLANG_H
|
||||
#define UTILITY_CLANG_H
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "clang/AST/Type.h"
|
||||
#include "clang/AST/TypeLoc.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclTemplate.h"
|
||||
|
||||
class DataType;
|
||||
class NameHierarchy;
|
||||
|
||||
namespace utility
|
||||
{
|
||||
std::shared_ptr<DataType> qualTypeToDataType(clang::QualType qualType);
|
||||
|
||||
NameHierarchy getDeclNameHierarchy(const clang::Decl* declaration);
|
||||
std::shared_ptr<DataType> templateArgumentToDataType(const clang::TemplateArgument& argument);
|
||||
NameHierarchy getTemplateSpecializationParentNameHierarchy(clang::ClassTemplateSpecializationDecl* declaration);
|
||||
}
|
||||
|
||||
#endif // UTILITY_CLANG_H
|
||||
@@ -914,9 +914,23 @@ public:
|
||||
|
||||
TS_ASSERT_EQUALS(client->functions.size(), 2);
|
||||
TS_ASSERT_EQUALS(client->functions[0], "void lambdaCaller() <1:1 <1:6 1:17> 4:1>");
|
||||
TS_ASSERT_EQUALS(client->functions[1], "void lambdaCaller::lambda at 3:2() <3:5 <3:2 3:2> 3:7>");
|
||||
TS_ASSERT_EQUALS(client->functions[1], "void lambdaCaller::lambda at 3:2() const <3:5 <3:2 3:2> 3:7>");
|
||||
TS_ASSERT_EQUALS(client->calls.size(), 1);
|
||||
TS_ASSERT_EQUALS(client->calls[0], "void lambdaCaller() -> void lambdaCaller::lambda at 3:2() <3:8 3:8>");
|
||||
TS_ASSERT_EQUALS(client->calls[0], "void lambdaCaller() -> void lambdaCaller::lambda at 3:2() const <3:8 3:8>");
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_mutable_lambda_definition()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"void lambdaWrapper()\n"
|
||||
"{\n"
|
||||
" [](int foo) mutable { return foo; };\n"
|
||||
"}\n"
|
||||
);
|
||||
|
||||
TS_ASSERT_EQUALS(client->functions.size(), 2);
|
||||
TS_ASSERT_EQUALS(client->functions[0], "void lambdaWrapper() <1:1 <1:6 1:18> 4:1>");
|
||||
TS_ASSERT_EQUALS(client->functions[1], "int lambdaWrapper::lambda at 3:2(int) <3:14 <3:2 3:2> 3:36>");
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_definition_of_local_symbol_in_function_parameter_list()
|
||||
@@ -2922,8 +2936,8 @@ public:
|
||||
);
|
||||
|
||||
TS_ASSERT_EQUALS(client->calls.size(), 2);
|
||||
TS_ASSERT_EQUALS(client->calls[0], "void lambdaCaller() -> void lambdaCaller::lambda at 4:2() <7:3 7:3>");
|
||||
TS_ASSERT_EQUALS(client->calls[1], "void lambdaCaller::lambda at 4:2() -> void func() <6:3 6:6>");
|
||||
TS_ASSERT_EQUALS(client->calls[0], "void lambdaCaller() -> void lambdaCaller::lambda at 4:2() const <7:3 7:3>");
|
||||
TS_ASSERT_EQUALS(client->calls[1], "void lambdaCaller::lambda at 4:2() const -> void func() <6:3 6:6>");
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_template_argument_of_unresolved_lookup_expression_as_type_use()
|
||||
|
||||
Reference in New Issue
Block a user