From a3657e77d40a61613fea7f1a267530d8f1de4e99 Mon Sep 17 00:00:00 2001 From: xvenge00 Date: Tue, 12 Mar 2019 11:27:30 +0100 Subject: [PATCH] ctypesparser: borland ast to ctypes parser can parse named types --- .../ctypesparser/borland_ast_ctypes_parser.h | 2 + .../borland_ast_ctypes_parser.cpp | 11 +++++ .../borland_ast_to_ctypes_tests.cpp | 44 ++++++++++++++++--- 3 files changed, 52 insertions(+), 5 deletions(-) diff --git a/include/retdec/ctypesparser/borland_ast_ctypes_parser.h b/include/retdec/ctypesparser/borland_ast_ctypes_parser.h index 07d5da64a..14cae35e3 100644 --- a/include/retdec/ctypesparser/borland_ast_ctypes_parser.h +++ b/include/retdec/ctypesparser/borland_ast_ctypes_parser.h @@ -25,6 +25,7 @@ #include "retdec/ctypes/function.h" #include "retdec/ctypes/type.h" #include "retdec/ctypes/integral_type.h" +#include "retdec/ctypes/named_type.h" #include "retdec/ctypes/pointer_type.h" #include "retdec/ctypes/floating_point_type.h" #include "retdec/ctypesparser/ctypes_parser.h" @@ -64,6 +65,7 @@ class BorlandToCtypesParser: public CTypesParser std::shared_ptr parsePointerType(std::shared_ptr pointerNode); std::shared_ptr parseReferenceType(std::shared_ptr referenceNode); std::shared_ptr parseRReferenceType(std::shared_ptr referenceNode); + std::shared_ptr parseNamedType(std::shared_ptr namedTypeNode); ctypes::Function::Parameters parseFuncParameters(std::shared_ptr paramsNode); ctypes::CallConvention parseCallConvention(demangler::borland::CallConv callConv); ctypes::FunctionType::VarArgness parseVarArgness(bool isVarArg); diff --git a/src/ctypesparser/borland_ast_ctypes_parser.cpp b/src/ctypesparser/borland_ast_ctypes_parser.cpp index 1a4f5d512..cb20cf6fd 100644 --- a/src/ctypesparser/borland_ast_ctypes_parser.cpp +++ b/src/ctypesparser/borland_ast_ctypes_parser.cpp @@ -126,6 +126,10 @@ std::shared_ptr BorlandToCtypesParser::parseType(std::shared_ptr(typeNode)); return std::static_pointer_cast(referenceType); } + case Kind::KNamedType: { + auto namedType = parseNamedType(std::static_pointer_cast(typeNode)); + return std::static_pointer_cast(namedType); + } default: break; } @@ -208,6 +212,13 @@ std::shared_ptr BorlandToCtypesParser::parseRReferenceType( return std::static_pointer_cast(ctypes::UnknownType::create()); // TODO rreference } +std::shared_ptr BorlandToCtypesParser::parseNamedType( + std::shared_ptr namedTypeNode) +{ + std::string name = namedTypeNode->name()->str(); + return ctypes::NamedType::create(context, name); +} + ctypes::Function::Parameters BorlandToCtypesParser::parseFuncParameters( std::shared_ptr paramsNode) { diff --git a/tests/ctypesparser/borland_ast_to_ctypes_tests.cpp b/tests/ctypesparser/borland_ast_to_ctypes_tests.cpp index c4b29d2b1..2012f7358 100644 --- a/tests/ctypesparser/borland_ast_to_ctypes_tests.cpp +++ b/tests/ctypesparser/borland_ast_to_ctypes_tests.cpp @@ -7,9 +7,12 @@ #include #include "retdec/demangler/demangler.h" -#include "retdec/ctypes/module.h" #include "retdec/demangler/context.h" +#include "retdec/ctypes/module.h" #include "retdec/ctypes/context.h" +#include "retdec/ctypes/function.h" +#include "retdec/ctypes/parameter.h" +#include "retdec/ctypes/unknown_type.h" using namespace ::testing; @@ -23,16 +26,47 @@ class BorlandCtypesTests : public Test using status = retdec::demangler::Demangler::Status; BorlandCtypesTests() : - demangler(retdec::demangler::DemanglerFactory::getDemangler("borland")) {} + demangler(retdec::demangler::DemanglerFactory::getDemangler("borland")), + context(std::make_shared()), + module(std::make_unique(context)) {} protected: + void mangledToCtypes( + const std::string &mangled) + { + demangler->demangleToModule(mangled, module); + } + std::unique_ptr demangler; + std::shared_ptr context; + std::unique_ptr module; }; TEST_F(BorlandCtypesTests, basic) { - auto context = std::make_shared(); - auto module = std::make_unique(context); - demangler->demangleToModule("@myFunc_int_$qi", module); + mangledToCtypes("@myFunc_int_$qi"); + + EXPECT_TRUE(module->hasFunctionWithName("myFunc_int_")); + + auto func = module->getFunctionWithName("myFunc_int_"); + EXPECT_TRUE(func->getReturnType()->isUnknown()); + + EXPECT_EQ(func->getParameterCount(), 1); + EXPECT_FALSE(func->isVarArg()); + EXPECT_TRUE(func->getParameter(1).getType()->isIntegral()); +} + +TEST_F(BorlandCtypesTests, templateTypes) +{ + mangledToCtypes("@%foo$60std@%basic_string$c19std@%char_traits$c%17std@%allocator$c%%%$q60std@%basic_string$c19std@%char_traits$c%17std@%allocator$c%%$v"); + + EXPECT_TRUE(module->hasFunctionWithName("foo, std::allocator>>")); + + auto func = module->getFunctionWithName("foo, std::allocator>>"); + EXPECT_TRUE(func->getReturnType()->isVoid()); + + EXPECT_EQ(func->getParameterCount(), 1); + EXPECT_FALSE(func->isVarArg()); + EXPECT_TRUE(func->getParameter(1).getType()->isNamed()); // TODO } }