From f6bae317c9f5fd7b454ef4a027933c26851db2ac Mon Sep 17 00:00:00 2001 From: malte_langkabel Date: Wed, 16 Nov 2016 16:34:41 +0100 Subject: [PATCH] logic: implemented recording correct signatures for c++ lambdas --- src/lib_cxx/CMakeLists.txt | 3 - .../cxx/name_resolver/CxxDeclNameResolver.cpp | 31 ++---- src/lib_cxx/data/parser/cxx/utilityCxx.cpp | 98 ------------------- src/lib_cxx/data/parser/cxx/utilityCxx.h | 25 ----- src/test/CxxParserTestSuite.h | 22 ++++- 5 files changed, 28 insertions(+), 151 deletions(-) delete mode 100644 src/lib_cxx/data/parser/cxx/utilityCxx.cpp delete mode 100644 src/lib_cxx/data/parser/cxx/utilityCxx.h diff --git a/src/lib_cxx/CMakeLists.txt b/src/lib_cxx/CMakeLists.txt index 05be90ed..f8f2a1fa 100644 --- a/src/lib_cxx/CMakeLists.txt +++ b/src/lib_cxx/CMakeLists.txt @@ -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( diff --git a/src/lib_cxx/data/parser/cxx/name_resolver/CxxDeclNameResolver.cpp b/src/lib_cxx/data/parser/cxx/name_resolver/CxxDeclNameResolver.cpp index b1832c4a..93ac8c61 100644 --- a/src/lib_cxx/data/parser/cxx/name_resolver/CxxDeclNameResolver.cpp +++ b/src/lib_cxx/data/parser/cxx/name_resolver/CxxDeclNameResolver.cpp @@ -158,35 +158,24 @@ std::shared_ptr 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(getNameForAnonymousSymbol(symbolKindName, presumedBegin), std::vector()); - // TODO: TESt what if this one has template params?? } } else if (clang::isa(declaration)) { - if (const clang::CXXMethodDecl* methodDecl = clang::dyn_cast_or_null(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( - lambdaName, - std::vector(), - std::make_shared("void", std::vector(), std::shared_ptr()), // TODO: check signature! - std::vector>(), - false, - false - ); - } - } + const clang::FunctionDecl* functionDecl = clang::dyn_cast(declaration); std::string functionName = declNameString; std::vector templateArguments; - const clang::FunctionDecl* functionDecl = clang::dyn_cast(declaration); - if (clang::FunctionTemplateDecl* templateFunctionDeclaration = functionDecl->getDescribedFunctionTemplate()) + + if ((clang::dyn_cast_or_null(functionDecl)) && + (clang::dyn_cast_or_null(functionDecl)->getParent()->isLambda())) + { + const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager(); + const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(clang::dyn_cast_or_null(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 templateDeclName = getDeclName(templateFunctionDeclaration); functionName = templateDeclName->getName(); diff --git a/src/lib_cxx/data/parser/cxx/utilityCxx.cpp b/src/lib_cxx/data/parser/cxx/utilityCxx.cpp deleted file mode 100644 index 18a6cd56..00000000 --- a/src/lib_cxx/data/parser/cxx/utilityCxx.cpp +++ /dev/null @@ -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 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 pu = declaration->getSpecializedTemplateOrPartial(); - if (pu.is()) - { - clang::ClassTemplateDecl* specializedFromDecl = pu.get(); - specializationParentNameHierarchy = utility::getDeclNameHierarchy(specializedFromDecl); - } - else if (pu.is()) - { - clang::ClassTemplatePartialSpecializationDecl* specializedFromDecl = pu.get(); - specializationParentNameHierarchy = utility::getDeclNameHierarchy(specializedFromDecl); - } - return specializationParentNameHierarchy; - } - - std::shared_ptr 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(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 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(typeName)); - return std::make_shared(typeNameHerarchy); - } - break; - } - return std::make_shared(NameHierarchy()); - } - */ -} diff --git a/src/lib_cxx/data/parser/cxx/utilityCxx.h b/src/lib_cxx/data/parser/cxx/utilityCxx.h deleted file mode 100644 index 07b8910c..00000000 --- a/src/lib_cxx/data/parser/cxx/utilityCxx.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef UTILITY_CLANG_H -#define UTILITY_CLANG_H - -#include -#include -#include - -#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 qualTypeToDataType(clang::QualType qualType); - - NameHierarchy getDeclNameHierarchy(const clang::Decl* declaration); - std::shared_ptr templateArgumentToDataType(const clang::TemplateArgument& argument); - NameHierarchy getTemplateSpecializationParentNameHierarchy(clang::ClassTemplateSpecializationDecl* declaration); -} - -#endif // UTILITY_CLANG_H diff --git a/src/test/CxxParserTestSuite.h b/src/test/CxxParserTestSuite.h index e9f5fff6..9c227cc3 100644 --- a/src/test/CxxParserTestSuite.h +++ b/src/test/CxxParserTestSuite.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 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()