Skip to content

Commit e071de7

Browse files
Malofeev MikhailVladislav Kalugin
Malofeev Mikhail
authored and
Vladislav Kalugin
committed
Add rvalue support
1 parent c036aa4 commit e071de7

File tree

8 files changed

+248
-9
lines changed

8 files changed

+248
-9
lines changed

server/src/printers/Printer.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -281,9 +281,13 @@ namespace printer {
281281
strTabIf(needTabs);
282282
std::vector<std::string> parameters;
283283
for (const auto &param : method.params) {
284-
std::string maybeAmpersand =
285-
param.type.maybeJustPointer() && !param.type.isFilePointer() ? "&" : "";
286-
parameters.push_back(maybeAmpersand + param.name);
284+
if (param.type.isRValueReference()) {
285+
parameters.push_back("std::move(" + param.name + ")");
286+
} else if (param.type.maybeJustPointer() && !param.type.isFilePointer()) {
287+
parameters.push_back("&" + param.name);
288+
} else {
289+
parameters.push_back(param.name);
290+
}
287291
}
288292
auto classObjName = method.getClassName();
289293
return strFunctionCall(method.name, parameters, end, classObjName, needTabs,

server/src/printers/TestsPrinter.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -714,10 +714,12 @@ TestsPrinter::methodParametersListVerbose(const Tests::MethodDescription &method
714714
std::string qualifier = Printer::getConstQualifier(param.type);
715715
std::string arg = StringUtils::stringFormat("(%svoid **) %s", qualifier, param.name);
716716
args.push_back(arg);
717+
} else if (param.type.isRValueReference()) {
718+
args.push_back("std::move(" + param.name + ")");
719+
} else if (param.type.maybeJustPointer() && !param.type.isFilePointer() ) {
720+
args.push_back("&" + param.name);
717721
} else {
718-
std::string maybeAmpersand =
719-
param.type.maybeJustPointer() && !param.type.isFilePointer() ? "&" : "";
720-
args.push_back(maybeAmpersand + param.name);
722+
args.push_back(param.name);
721723
}
722724
}
723725
return args;

server/src/types/Types.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,10 @@ bool types::Type::isLValueReference() const {
248248
return isSimple() && dynamic_cast<SimpleType *>(mKinds.front().get())->isLValue();
249249
}
250250

251+
bool types::Type::isRValueReference() const {
252+
return isSimple() && dynamic_cast<SimpleType *>(mKinds.front().get())->isRValue();
253+
}
254+
251255
bool types::Type::isConstQualified() const {
252256
return isSimple() && dynamic_cast<SimpleType *>(mKinds.front().get())->isConstQualified();
253257
}

server/src/types/Types.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,12 @@ namespace types {
150150
*/
151151
[[nodiscard]] bool isLValueReference() const;
152152

153+
/**
154+
* Checks whether given type is an rvalue reference type.
155+
* @return true if type is rvalue reference, false otherwise.
156+
*/
157+
[[nodiscard]] bool isRValueReference() const;
158+
153159
/**
154160
* Checks whether given type is an const qualified.
155161
* @return true if type is const, false otherwise.

server/test/framework/Syntax_Tests.cpp

Lines changed: 143 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,11 @@ namespace {
5454
fs::path inner_unnamed_c = getTestFilePath("inner_unnamed.c");
5555
fs::path array_sort_c = getTestFilePath("array_sort.c");
5656
fs::path stubs_c = getTestFilePath("stubs.c");
57-
fs::path namespace_cpp = getTestFilePath("namespace.cpp");
5857
fs::path input_output_c = getTestFilePath("input_output.c");
5958
fs::path file_c = getTestFilePath("file.c");
6059
fs::path bitfields_c = getTestFilePath("bitfields.c");
60+
fs::path namespace_cpp = getTestFilePath("namespace.cpp");
61+
fs::path rvalue_reference_cpp = getTestFilePath("function_with_rvalue_params.cpp");
6162

6263
void SetUp() override {
6364
clearEnv(CompilationUtils::CompilerName::CLANG);
@@ -2779,7 +2780,7 @@ namespace {
27792780
);
27802781
}
27812782

2782-
TEST_F(Syntax_Test, multi_union) {
2783+
TEST_F(Syntax_Test, multi_union_cpp) {
27832784
auto [testGen, status] = createTestForFunction(namespace_cpp, 38);
27842785

27852786
ASSERT_TRUE(status.ok()) << status.error_message();
@@ -2798,6 +2799,146 @@ namespace {
27982799
);
27992800
}
28002801

2802+
TEST_F(Syntax_Test, multiple_rvalue_params) {
2803+
auto [testGen, status] = createTestForFunction(rvalue_reference_cpp, 9);
2804+
2805+
ASSERT_TRUE(status.ok()) << status.error_message();
2806+
2807+
testUtils::checkMinNumberOfTests(testGen.tests.at(rvalue_reference_cpp).methods.begin().value().testCases, 2);
2808+
2809+
checkTestCasePredicates(
2810+
testGen.tests.at(rvalue_reference_cpp).methods.begin().value().testCases,
2811+
std::vector<TestCasePredicate>(
2812+
{
2813+
[] (const tests::Tests::MethodTestCase& testCase) {
2814+
return stoi(testCase.paramValues[0].view->getEntryValue(nullptr)) >
2815+
stoi(testCase.paramValues[1].view->getEntryValue(nullptr));
2816+
},
2817+
[] (const tests::Tests::MethodTestCase& testCase) {
2818+
return stoi(testCase.paramValues[0].view->getEntryValue(nullptr)) <=
2819+
stoi(testCase.paramValues[1].view->getEntryValue(nullptr));
2820+
}
2821+
})
2822+
);
2823+
2824+
checkTestCasePredicates(
2825+
testGen.tests.at(rvalue_reference_cpp).methods.begin().value().testCases,
2826+
std::vector<TestCasePredicate>(
2827+
{
2828+
[] (const tests::Tests::MethodTestCase& testCase) {
2829+
return 2 * stoi(testCase.paramValues[0].view->getEntryValue(nullptr)) ==
2830+
stoi(testCase.returnValue.view->getEntryValue(nullptr));
2831+
},
2832+
[] (const tests::Tests::MethodTestCase& testCase) {
2833+
return 2 * stoi(testCase.paramValues[1].view->getEntryValue(nullptr)) ==
2834+
stoi(testCase.returnValue.view->getEntryValue(nullptr));
2835+
}
2836+
})
2837+
);
2838+
2839+
}
2840+
2841+
TEST_F(Syntax_Test, const_rvalue_reference) {
2842+
auto [testGen, status] = createTestForFunction(rvalue_reference_cpp, 17);
2843+
2844+
ASSERT_TRUE(status.ok()) << status.error_message();
2845+
2846+
testUtils::checkMinNumberOfTests(testGen.tests.at(rvalue_reference_cpp).methods.begin().value().testCases, 3);
2847+
2848+
checkTestCasePredicates(
2849+
testGen.tests.at(rvalue_reference_cpp).methods.begin().value().testCases,
2850+
std::vector<TestCasePredicate>(
2851+
{
2852+
[] (const tests::Tests::MethodTestCase& testCase) {
2853+
return stoi(testCase.returnValue.view->getEntryValue(nullptr)) == 0;
2854+
},
2855+
[] (const tests::Tests::MethodTestCase& testCase) {
2856+
return stoi(testCase.returnValue.view->getEntryValue(nullptr)) == 1;
2857+
},
2858+
[] (const tests::Tests::MethodTestCase& testCase) {
2859+
return stoi(testCase.returnValue.view->getEntryValue(nullptr)) == 2;
2860+
}
2861+
})
2862+
);
2863+
2864+
checkTestCasePredicates(
2865+
testGen.tests.at(rvalue_reference_cpp).methods.begin().value().testCases,
2866+
std::vector<TestCasePredicate>(
2867+
{
2868+
[] (const tests::Tests::MethodTestCase& testCase) {
2869+
return stoi(testCase.paramValues.front().view->getEntryValue(nullptr)) % 3 == 0;
2870+
},
2871+
[] (const tests::Tests::MethodTestCase& testCase) {
2872+
return stoi(testCase.paramValues.front().view->getEntryValue(nullptr)) % 3 == 1;
2873+
},
2874+
[] (const tests::Tests::MethodTestCase& testCase) {
2875+
return stoi(testCase.paramValues.front().view->getEntryValue(nullptr)) % 3 == 2;
2876+
}
2877+
})
2878+
);
2879+
}
2880+
2881+
TEST_F(Syntax_Test, return_and_get_params) {
2882+
auto [testGen, status] = createTestForFunction(rvalue_reference_cpp, 28);
2883+
2884+
ASSERT_TRUE(status.ok()) << status.error_message();
2885+
2886+
testUtils::checkMinNumberOfTests(testGen.tests.at(rvalue_reference_cpp).methods.begin().value().testCases, 3);
2887+
2888+
checkTestCasePredicates(
2889+
testGen.tests.at(rvalue_reference_cpp).methods.begin().value().testCases,
2890+
std::vector<TestCasePredicate>(
2891+
{
2892+
[] (const tests::Tests::MethodTestCase& testCase) {
2893+
return stoi(testCase.paramValues[0].view->getEntryValue(nullptr)) % 5 == 0;
2894+
},
2895+
[] (const tests::Tests::MethodTestCase& testCase) {
2896+
return stoi(testCase.paramValues[1].view->getEntryValue(nullptr)) % 5 == 0;
2897+
}
2898+
})
2899+
);
2900+
2901+
checkTestCasePredicates(
2902+
testGen.tests.at(rvalue_reference_cpp).methods.begin().value().testCases,
2903+
std::vector<TestCasePredicate>(
2904+
{
2905+
[] (const tests::Tests::MethodTestCase& testCase) {
2906+
return stoi(testCase.paramValues[0].view->getEntryValue(nullptr)) ==
2907+
stoi(testCase.returnValue.view->getEntryValue(nullptr));
2908+
},
2909+
[] (const tests::Tests::MethodTestCase& testCase) {
2910+
return stoi(testCase.paramValues[1].view->getEntryValue(nullptr)) ==
2911+
stoi(testCase.returnValue.view->getEntryValue(nullptr));
2912+
},
2913+
[] (const tests::Tests::MethodTestCase& testCase) {
2914+
return stoi(testCase.paramValues[0].view->getEntryValue(nullptr)) + stoi(testCase.paramValues[1].view->getEntryValue(nullptr))==
2915+
stoi(testCase.returnValue.view->getEntryValue(nullptr));
2916+
}
2917+
})
2918+
);
2919+
}
2920+
2921+
TEST_F(Syntax_Test, rvalue_struct_param) {
2922+
auto [testGen, status] = createTestForFunction(rvalue_reference_cpp, 38);
2923+
2924+
ASSERT_TRUE(status.ok()) << status.error_message();
2925+
2926+
testUtils::checkMinNumberOfTests(testGen.tests.at(rvalue_reference_cpp).methods.begin().value().testCases, 4);
2927+
2928+
checkTestCasePredicates(
2929+
testGen.tests.at(rvalue_reference_cpp).methods.begin().value().testCases,
2930+
std::vector<TestCasePredicate>(
2931+
{
2932+
[] (const tests::Tests::MethodTestCase& testCase) {
2933+
return stoi(testCase.returnValue.view->getEntryValue(nullptr)) == 1;
2934+
},
2935+
[] (const tests::Tests::MethodTestCase& testCase) {
2936+
return stoi(testCase.returnValue.view->getEntryValue(nullptr)) == 2;
2937+
}
2938+
})
2939+
);
2940+
}
2941+
28012942
TEST_F(Syntax_Test, simple_getc) {
28022943
auto [testGen, status] = createTestForFunction(input_output_c, 4);
28032944

server/test/suites/syntax/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,5 @@ add_executable(syntax1
4040
namespace.cpp
4141
input_output.c
4242
file.c
43-
bitfields.c)
43+
bitfields.c
44+
function_with_rvalue_params.cpp)
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#include <utility>
2+
#include "function_with_rvalue_params.h"
3+
4+
int double_max(int && first, int && second) {
5+
if (first > second) {
6+
return 2 * first;
7+
} else {
8+
return 2 * second;
9+
}
10+
}
11+
12+
int remainder(const int && value) {
13+
if (value % 3 == 0) {
14+
return 0;
15+
} else if (value % 3 == 1) {
16+
return 1;
17+
} else {
18+
return 2;
19+
}
20+
}
21+
22+
int && return_and_get_rvalue_reference(int && first, int && second) {
23+
if (first % 5 == 0) {
24+
return std::move(first);
25+
} else if (second % 5 == 0) {
26+
return std::move(second);
27+
} else {
28+
return std::move(first + second);
29+
}
30+
}
31+
32+
int get_rvalue_custom_struct_as_param(Closet && closet) {
33+
if (closet.height > 5 && closet.width > 5 && closet.length > 5) {
34+
closet.height /= 5;
35+
closet.volume /= 5;
36+
closet.width /= 5;
37+
return 1;
38+
} else {
39+
closet.width = 5;
40+
closet.height = 5;
41+
closet.length = 5;
42+
closet.volume = 125;
43+
return 2;
44+
}
45+
}
46+
47+
Closet::Closet() {
48+
length = 1.5;
49+
width = 0.5;
50+
height = 2.5;
51+
volume = height * width * length;
52+
}
53+
54+
Closet::Closet(double length_, double width_, double height_, double volume_) {
55+
length = length_;
56+
width = width_;
57+
height = height_;
58+
volume = volume_;
59+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#ifndef UNITTESTBOT_FUNCTION_WITH_RVALUE_PARAMS_H
2+
#define UNITTESTBOT_FUNCTION_WITH_RVALUE_PARAMS_H
3+
4+
struct Closet {
5+
double length;
6+
double width;
7+
double height;
8+
double volume;
9+
10+
Closet();
11+
Closet(double length_, double width_, double height_, double volume_);
12+
};
13+
14+
int double_max(int && first, int && second);
15+
16+
int remainder(const int && value);
17+
18+
int && return_and_get_rvalue_reference(int && first, int && second);
19+
20+
int get_rvalue_custom_struct_as_param(Closet && closet);
21+
22+
#endif // UNITTESTBOT_FUNCTION_WITH_RVALUE_PARAMS_H

0 commit comments

Comments
 (0)