logic: implemented recording correct signatures for c++ lambdas

This commit is contained in:
malte_langkabel
2016-11-16 16:34:41 +01:00
parent 7873710ba8
commit f6bae317c9
5 changed files with 28 additions and 151 deletions
-3
View File
@@ -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());
}
*/
}
-25
View File
@@ -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
+18 -4
View File
@@ -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()