Skip to content

Commit 17e6475

Browse files
Update GetDatamembers and GetUnderlyingScope to work with UsingShadowDecl
`GetDatamembers` now also returns `UsingShadowDecl` that point to `FieldDecl`. Update `GetUnderlyingScope` to return the target Decl of using statements. Simplified `CheckVariableAccess` logic.
1 parent ebe0527 commit 17e6475

File tree

2 files changed

+36
-12
lines changed

2 files changed

+36
-12
lines changed

lib/Interpreter/CppInterOp.cpp

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,10 @@ namespace Cpp {
529529
auto Scope = GetScopeFromType(TND->getUnderlyingType());
530530
if (Scope)
531531
D = Scope;
532+
} else if (auto* USS = dyn_cast_or_null<UsingShadowDecl>(D)) {
533+
auto Scope = USS->getTargetDecl();
534+
if (Scope)
535+
D = Scope;
532536
}
533537

534538
return D;
@@ -1151,10 +1155,12 @@ namespace Cpp {
11511155
auto *D = (Decl *) scope;
11521156

11531157
if (auto* CXXRD = llvm::dyn_cast_or_null<CXXRecordDecl>(D)) {
1154-
llvm::SmallVector<RecordDecl::field_iterator, 2> stack_begin;
1155-
llvm::SmallVector<RecordDecl::field_iterator, 2> stack_end;
1156-
stack_begin.push_back(CXXRD->field_begin());
1157-
stack_end.push_back(CXXRD->field_end());
1158+
getSema().ForceDeclarationOfImplicitMembers(CXXRD);
1159+
1160+
llvm::SmallVector<RecordDecl::decl_iterator, 2> stack_begin;
1161+
llvm::SmallVector<RecordDecl::decl_iterator, 2> stack_end;
1162+
stack_begin.push_back(CXXRD->decls_begin());
1163+
stack_end.push_back(CXXRD->decls_end());
11581164
while (!stack_begin.empty()) {
11591165
if (stack_begin.back() == stack_end.back()) {
11601166
stack_begin.pop_back();
@@ -1167,14 +1173,18 @@ namespace Cpp {
11671173
if (const auto* RT = FD->getType()->getAs<RecordType>()) {
11681174
if (auto* CXXRD = llvm::dyn_cast<CXXRecordDecl>(RT->getDecl())) {
11691175
stack_begin.back()++;
1170-
stack_begin.push_back(CXXRD->field_begin());
1171-
stack_end.push_back(CXXRD->field_end());
1176+
stack_begin.push_back(CXXRD->decls_begin());
1177+
stack_end.push_back(CXXRD->decls_end());
11721178
continue;
11731179
}
11741180
}
11751181
}
1182+
datamembers.push_back((TCppScope_t)D);
1183+
1184+
} else if (auto* USD = llvm::dyn_cast<UsingShadowDecl>(D)) {
1185+
if (llvm::isa<FieldDecl>(USD->getTargetDecl()))
1186+
datamembers.push_back(USD);
11761187
}
1177-
datamembers.push_back((TCppScope_t)D);
11781188
stack_begin.back()++;
11791189
}
11801190
}
@@ -1321,11 +1331,7 @@ namespace Cpp {
13211331
bool CheckVariableAccess(TCppScope_t var, AccessSpecifier AS)
13221332
{
13231333
auto *D = (Decl *) var;
1324-
if (auto *CXXMD = llvm::dyn_cast_or_null<DeclaratorDecl>(D)) {
1325-
return CXXMD->getAccess() == AS;
1326-
}
1327-
1328-
return false;
1334+
return D->getAccess() == AS;
13291335
}
13301336

13311337
bool IsPublicVariable(TCppScope_t var)

unittests/CppInterOp/VariableReflectionTest.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,21 @@ TEST(VariableReflectionTest, GetDatamembers) {
2626
static int f;
2727
};
2828
void sum(int,int);
29+
30+
class D : public C {
31+
public:
32+
int x;
33+
using C::e;
34+
};
2935
)";
3036

3137
std::vector<Cpp::TCppScope_t> datamembers;
3238
std::vector<Cpp::TCppScope_t> datamembers1;
39+
std::vector<Cpp::TCppScope_t> datamembers2;
3340
GetAllTopLevelDecls(code, Decls);
3441
Cpp::GetDatamembers(Decls[0], datamembers);
3542
Cpp::GetDatamembers(Decls[1], datamembers1);
43+
Cpp::GetDatamembers(Decls[2], datamembers2);
3644

3745
// non static field
3846
EXPECT_EQ(Cpp::GetQualifiedName(datamembers[0]), "C::a");
@@ -53,6 +61,16 @@ TEST(VariableReflectionTest, GetDatamembers) {
5361
EXPECT_EQ(Cpp::GetQualifiedName(datamembers[2]), "C::f");
5462
EXPECT_EQ(datamembers.size(), 3);
5563
EXPECT_EQ(datamembers1.size(), 0);
64+
65+
// derived class
66+
EXPECT_EQ(datamembers2.size(), 2);
67+
EXPECT_EQ(Cpp::GetQualifiedName(datamembers2[0]), "D::x");
68+
EXPECT_EQ(Cpp::GetQualifiedName(Cpp::GetUnderlyingScope(datamembers2[1])),
69+
"C::e");
70+
EXPECT_TRUE(Cpp::IsPublicVariable(datamembers2[0]));
71+
EXPECT_TRUE(Cpp::IsPublicVariable(datamembers2[1]));
72+
EXPECT_TRUE(
73+
Cpp::IsProtectedVariable(Cpp::GetUnderlyingScope(datamembers2[1])));
5674
}
5775
// If on Windows disable warning due to unnamed structs/unions in defined CODE.
5876
#ifdef _WIN32

0 commit comments

Comments
 (0)