Skip to content

Commit 7a232f2

Browse files
Saveliy Grigoryevsava-cska
authored andcommitted
Fix namespace issue
1 parent 09cb9b1 commit 7a232f2

File tree

10 files changed

+339
-10
lines changed

10 files changed

+339
-10
lines changed

integration-tests/c-example/lib/structures/structs/simple_structs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ struct StructWithUnion {
5151
int x;
5252
} un2;
5353
} is;
54-
54+
5555
int x;
5656
};
5757

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright (c) Huawei Technologies Co., Ltd. 2012-2021. All rights reserved.
3+
*/
4+
5+
#include "namespace.hpp"
6+
7+
test::A example_namespace(int a, int b) {
8+
test::A res;
9+
if (a + b > 7) {
10+
res.x = 5;
11+
res.ex.c = 't';
12+
res.ex.y = 1e5;
13+
res.u.k = 17;
14+
} else if (a + b < -3) {
15+
res.x = -1;
16+
res.ex.c = 'u';
17+
res.ex.y = -1e2;
18+
res.u.k = 101;
19+
} else {
20+
res.x = 10;
21+
res.ex.c = 'z';
22+
res.ex.y = 1.23;
23+
res.u.b = 'j';
24+
}
25+
return res;
26+
}
27+
28+
StructWithUnion struct_with_union_as_return_type_cpp(int t) {
29+
StructWithUnion st;
30+
if (t == 0) {
31+
st.un.c = 'a';
32+
st.is.un2.x = 101;
33+
st.x = 155;
34+
} else {
35+
st.un.x = 17;
36+
st.is.un2.c = '0';
37+
st.x = -108;
38+
}
39+
return st;
40+
}
41+
42+
A1 multi_union(int t) {
43+
A1 res;
44+
if (t == 0) {
45+
res.b1.a1.x = 10;
46+
res.c1.x = 9;
47+
} else {
48+
res.b1.a1.x = 5;
49+
res.c1.x = 6;
50+
}
51+
return res;
52+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright (c) Huawei Technologies Co., Ltd. 2012-2021. All rights reserved.
3+
*/
4+
5+
#ifndef NAMESPACE_HPP
6+
#define NAMESPACE_HPP
7+
8+
namespace uni {
9+
namespace inner1 {
10+
union U {
11+
int k;
12+
char b;
13+
};
14+
}
15+
}
16+
17+
namespace str {
18+
struct B {
19+
char c;
20+
double y;
21+
};
22+
}
23+
24+
namespace test {
25+
struct A {
26+
int x;
27+
str::B ex;
28+
uni::inner1::U u;
29+
};
30+
}
31+
32+
test::A example_namespace(int a, int b);
33+
34+
struct StructWithUnion {
35+
union InnerUnion {
36+
char c;
37+
int x;
38+
} un;
39+
40+
struct InnerStructWithUnion {
41+
union Inner2Union {
42+
char c;
43+
int x;
44+
} un2;
45+
} is;
46+
47+
int x;
48+
};
49+
50+
StructWithUnion struct_with_union_as_return_type_cpp(int t);
51+
52+
struct A1 {
53+
union B1 {
54+
union A1 {
55+
int x;
56+
} a1;
57+
} b1;
58+
59+
union C1 {
60+
int x;
61+
} c1;
62+
};
63+
64+
A1 multi_union(int t);
65+
66+
#endif

server/src/Tests.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -310,18 +310,15 @@ shared_ptr<StructValueView> KTestObjectParser::structView(const vector<char> &by
310310
break;
311311
case TypeKind::STRUCT:
312312
innerStruct = typesHandler.getStructInfo(field.type);
313-
innerStruct.name = curStruct.name + "::" + innerStruct.name;
314313
subViews.push_back(structView(byteArray, innerStruct, curPos + offsetField, usage, testingMethod,
315314
PrinterUtils::getFieldAccess(name, field.name), fromAddressToName, initReferences));
316315
break;
317316
case TypeKind::ENUM:
318317
innerEnum = typesHandler.getEnumInfo(field.type);
319-
innerEnum.name = curStruct.name + "::" + innerEnum.name;
320318
subViews.push_back(enumView(byteArray, innerEnum, curPos + offsetField, len));
321319
break;
322320
case TypeKind::UNION:
323321
innerUnion = typesHandler.getUnionInfo(field.type);
324-
innerUnion.name = curStruct.name + "::" + innerUnion.name;
325322
subViews.push_back(unionView(byteArray, innerUnion, curPos + offsetField, usage));
326323
break;
327324
case TypeKind::ARRAY:

server/src/types/TypesResolver.cpp

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,25 @@ static void addInfo(uint64_t id, std::unordered_map<uint64_t, Info> &someMap, In
6262
}
6363
}
6464

65+
std::string TypesResolver::getFullname(const clang::TagDecl *TD, const clang::QualType &canonicalType,
66+
uint64_t id, const fs::path &sourceFilePath) {
67+
auto pp = clang::PrintingPolicy(clang::LangOptions());
68+
pp.SuppressTagKeyword = true;
69+
std::string currentStructName = canonicalType.getNonReferenceType().getUnqualifiedType().getAsString(pp);
70+
fullname.insert(std::make_pair(id, currentStructName));
71+
72+
if (Paths::getSourceLanguage(sourceFilePath) == utbot::Language::C) {
73+
if (const clang::RecordDecl *parentNode = llvm::dyn_cast<const clang::RecordDecl>(TD->getLexicalParent())) {
74+
clang::QualType parentCanonicalType = parentNode->getASTContext().getTypeDeclType(parentNode).getCanonicalType();
75+
uint64_t parentID = types::Type::getIdFromCanonicalType(parentCanonicalType);
76+
if (!fullname[parentID].empty()) {
77+
fullname[id] = fullname[parentID] + "::" + fullname[id];
78+
}
79+
}
80+
}
81+
return fullname[id];
82+
}
83+
6584
void TypesResolver::resolveStruct(const clang::RecordDecl *D, const std::string &name) {
6685
clang::ASTContext const &context = D->getASTContext();
6786
clang::SourceManager const &sourceManager = context.getSourceManager();
@@ -71,14 +90,15 @@ void TypesResolver::resolveStruct(const clang::RecordDecl *D, const std::string
7190
if (!isCandidateToReplace(id, parent->projectTypes->structs, name)) {
7291
return;
7392
}
93+
7494
types::StructInfo structInfo;
7595
fs::path filename =
7696
sourceManager.getFilename(sourceManager.getSpellingLoc(D->getLocation())).str();
97+
fs::path sourceFilePath = sourceManager.getFileEntryForID(sourceManager.getMainFileID())->tryGetRealPathName().str();
7798
structInfo.filePath = Paths::getCCJsonFileFullPath(filename, parent->buildRootPath);
78-
structInfo.name = name;
99+
structInfo.name = getFullname(D, canonicalType, id, sourceFilePath);
79100
structInfo.hasUnnamedFields = false;
80101

81-
82102
if (Paths::isGtest(structInfo.filePath)) {
83103
return;
84104
}
@@ -88,7 +108,6 @@ void TypesResolver::resolveStruct(const clang::RecordDecl *D, const std::string
88108
ss << "Struct: " << structInfo.name << "\n"
89109
<< "\tFile path: " << structInfo.filePath.string() << "";
90110
std::vector<types::Field> fields;
91-
fs::path sourceFilePath = sourceManager.getFileEntryForID(sourceManager.getMainFileID())->tryGetRealPathName().str();
92111
for (const clang::FieldDecl *F : D->fields()) {
93112
if (F->isUnnamedBitfield()) {
94113
continue;
@@ -182,8 +201,10 @@ void TypesResolver::resolveEnum(const clang::EnumDecl *EN, const string &name) {
182201
if (!isCandidateToReplace(id, parent->projectTypes->enums, name)) {
183202
return;
184203
}
204+
185205
types::EnumInfo enumInfo;
186-
enumInfo.name = name;
206+
fs::path sourceFilePath = sourceManager.getFileEntryForID(sourceManager.getMainFileID())->tryGetRealPathName().str();
207+
enumInfo.name = getFullname(EN, canonicalType, id, sourceFilePath);
187208
enumInfo.filePath = Paths::getCCJsonFileFullPath(
188209
sourceManager.getFilename(EN->getLocation()).str(), parent->buildRootPath.string());
189210
clang::QualType promotionType = EN->getPromotionType();
@@ -226,10 +247,12 @@ void TypesResolver::resolveUnion(const clang::RecordDecl *D, const std::string &
226247
if (!isCandidateToReplace(id, parent->projectTypes->unions, name)) {
227248
return;
228249
}
250+
229251
types::UnionInfo unionInfo;
252+
fs::path sourceFilePath = sourceManager.getFileEntryForID(sourceManager.getMainFileID())->tryGetRealPathName().str();
230253
unionInfo.filePath = Paths::getCCJsonFileFullPath(
231254
sourceManager.getFilename(D->getLocation()).str(), parent->buildRootPath.string());
232-
unionInfo.name = name;
255+
unionInfo.name = getFullname(D, canonicalType, id, sourceFilePath);
233256

234257
if (Paths::isGtest(unionInfo.filePath)) {
235258
return;

server/src/types/TypesResolver.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class Fetcher;
1717
class TypesResolver {
1818
private:
1919
const Fetcher *const parent;
20+
std::map <uint64_t, std::string> fullname;
2021
public:
2122
explicit TypesResolver(Fetcher const *parent);
2223

@@ -29,6 +30,9 @@ class TypesResolver {
2930
void resolve(const clang::QualType &type);
3031

3132
private:
33+
std::string getFullname(const clang::TagDecl *TD, const clang::QualType &canonicalType,
34+
uint64_t id, const fs::path &sourceFilePath);
35+
3236
void updateMaximumAlignment(uint64_t alignment) const;
3337
};
3438

server/test/framework/Syntax_Tests.cpp

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ namespace {
5353
fs::path inner_unnamed_c = getTestFilePath("inner_unnamed.c");
5454
fs::path array_sort_c = getTestFilePath("array_sort.c");
5555
fs::path stubs_c = getTestFilePath("stubs.c");
56+
fs::path namespace_cpp = getTestFilePath("namespace.cpp");
5657

5758
void SetUp() override {
5859
clearEnv();
@@ -2544,6 +2545,73 @@ namespace {
25442545
})
25452546
);
25462547
}
2548+
2549+
TEST_F(Syntax_Test, example_namespace) {
2550+
auto [testGen, status] = createTestForFunction(namespace_cpp, 7);
2551+
2552+
ASSERT_TRUE(status.ok()) << status.error_message();
2553+
2554+
checkTestCasePredicates(
2555+
testGen.tests.at(namespace_cpp).methods.begin().value().testCases,
2556+
vector<TestCasePredicate>(
2557+
{
2558+
[] (const tests::Tests::MethodTestCase& testCase) {
2559+
return StringUtils::startsWith(testCase.returnValueView->getSubViews()[2]->getEntryValue(), "from_bytes<uni::inner1::U>") &&
2560+
stoi(testCase.returnValueView->getSubViews()[0]->getEntryValue()) == 5;
2561+
},
2562+
[] (const tests::Tests::MethodTestCase& testCase) {
2563+
return StringUtils::startsWith(testCase.returnValueView->getSubViews()[2]->getEntryValue(), "from_bytes<uni::inner1::U>") &&
2564+
stoi(testCase.returnValueView->getSubViews()[0]->getEntryValue()) == -1;
2565+
},
2566+
[] (const tests::Tests::MethodTestCase& testCase) {
2567+
return StringUtils::startsWith(testCase.returnValueView->getSubViews()[2]->getEntryValue(), "from_bytes<uni::inner1::U>") &&
2568+
stoi(testCase.returnValueView->getSubViews()[0]->getEntryValue()) == 10;
2569+
}
2570+
})
2571+
);
2572+
}
2573+
2574+
TEST_F(Syntax_Test, struct_with_union_as_return_type_cpp) {
2575+
auto [testGen, status] = createTestForFunction(namespace_cpp, 28);
2576+
2577+
ASSERT_TRUE(status.ok()) << status.error_message();
2578+
2579+
checkTestCasePredicates(
2580+
testGen.tests.at(namespace_cpp).methods.begin().value().testCases,
2581+
vector<TestCasePredicate>(
2582+
{
2583+
[] (const tests::Tests::MethodTestCase& testCase) {
2584+
return StringUtils::startsWith(testCase.returnValueView->getSubViews()[0]->getEntryValue(), "from_bytes<StructWithUnion::InnerUnion>") &&
2585+
StringUtils::startsWith(testCase.returnValueView->getSubViews()[1]->getSubViews()[0]->getEntryValue(),
2586+
"from_bytes<StructWithUnion::InnerStructWithUnion::Inner2Union>") &&
2587+
stoi(testCase.returnValueView->getSubViews()[2]->getEntryValue()) == -108;
2588+
},
2589+
[] (const tests::Tests::MethodTestCase& testCase) {
2590+
return StringUtils::startsWith(testCase.returnValueView->getSubViews()[0]->getEntryValue(), "from_bytes<StructWithUnion::InnerUnion>") &&
2591+
StringUtils::startsWith(testCase.returnValueView->getSubViews()[1]->getSubViews()[0]->getEntryValue(),
2592+
"from_bytes<StructWithUnion::InnerStructWithUnion::Inner2Union>") &&
2593+
stoi(testCase.returnValueView->getSubViews()[2]->getEntryValue()) == 155;
2594+
}
2595+
})
2596+
);
2597+
}
2598+
2599+
TEST_F(Syntax_Test, multi_union) {
2600+
auto [testGen, status] = createTestForFunction(namespace_cpp, 42);
2601+
2602+
ASSERT_TRUE(status.ok()) << status.error_message();
2603+
2604+
checkTestCasePredicates(
2605+
testGen.tests.at(namespace_cpp).methods.begin().value().testCases,
2606+
vector<TestCasePredicate>(
2607+
{
2608+
[] (const tests::Tests::MethodTestCase& testCase) {
2609+
return StringUtils::startsWith(testCase.returnValueView->getSubViews()[0]->getEntryValue(), "from_bytes<A1::B1>") &&
2610+
StringUtils::startsWith(testCase.returnValueView->getSubViews()[1]->getEntryValue(), "from_bytes<A1::C1>");
2611+
}
2612+
})
2613+
);
2614+
}
25472615
}
25482616

25492617

server/test/suites/syntax/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,5 @@ add_executable(syntax1
3636
simple_class.cpp
3737
inner_unnamed.c
3838
array_sort.c
39-
stubs.c)
39+
stubs.c
40+
namespace.cpp)
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright (c) Huawei Technologies Co., Ltd. 2012-2021. All rights reserved.
3+
*/
4+
5+
#include "namespace.h"
6+
7+
test::A example_namespace(int a, int b) {
8+
test::A res;
9+
if (a + b > 7) {
10+
res.x = 5;
11+
res.ex.c = 't';
12+
res.ex.y = 1e5;
13+
res.u.k = 17;
14+
} else if (a + b < -3) {
15+
res.x = -1;
16+
res.ex.c = 'u';
17+
res.ex.y = -1e2;
18+
res.u.k = 101;
19+
} else {
20+
res.x = 10;
21+
res.ex.c = 'z';
22+
res.ex.y = 1.23;
23+
res.u.b = 'j';
24+
}
25+
return res;
26+
}
27+
28+
StructWithUnion struct_with_union_as_return_type_cpp(int t) {
29+
StructWithUnion st;
30+
if (t == 0) {
31+
st.un.c = 'a';
32+
st.is.un2.x = 101;
33+
st.x = 155;
34+
} else {
35+
st.un.x = 17;
36+
st.is.un2.c = '0';
37+
st.x = -108;
38+
}
39+
return st;
40+
}
41+
42+
A1 multi_union(int t) {
43+
A1 res;
44+
if (t == 0) {
45+
res.b1.a1.x = 10;
46+
res.c1.x = 9;
47+
} else {
48+
res.b1.a1.x = 5;
49+
res.c1.x = 6;
50+
}
51+
return res;
52+
}

0 commit comments

Comments
 (0)