Skip to content

Commit ae3ccbe

Browse files
sudo-pandavgvassilev
authored andcommitted
Implement GetUnderlyingScope
1 parent 28a91d8 commit ae3ccbe

File tree

3 files changed

+57
-18
lines changed

3 files changed

+57
-18
lines changed

include/clang/Interpreter/CppInterOp.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,10 @@ namespace Cpp {
220220
/// Gets the global scope of the whole C++ instance.
221221
TCppScope_t GetGlobalScope();
222222

223+
/// Strips the typedef and returns the underlying class, and if the
224+
/// underlying decl is not a class it returns the input unchanged.
225+
TCppScope_t GetUnderlyingScope(TCppScope_t scope);
226+
223227
/// Gets the namespace or class for the name passed as a parameter,
224228
/// and if the parent is not passed, then global scope will be assumed.
225229
TCppScope_t GetScope(const std::string &name, TCppScope_t parent = 0);

lib/Interpreter/CppInterOp.cpp

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,39 @@ namespace Cpp {
462462
return getSema().getASTContext().getTranslationUnitDecl();
463463
}
464464

465+
static Decl *GetScopeFromType(QualType QT) {
466+
if (auto *Type = QT.getTypePtrOrNull()) {
467+
Type = Type->getPointeeOrArrayElementType();
468+
Type = Type->getUnqualifiedDesugaredType();
469+
if (auto *ET = llvm::dyn_cast<EnumType>(Type))
470+
return ET->getDecl();
471+
return Type->getAsCXXRecordDecl();
472+
}
473+
return 0;
474+
}
475+
476+
TCppScope_t GetScopeFromType(TCppType_t type)
477+
{
478+
QualType QT = QualType::getFromOpaquePtr(type);
479+
return (TCppScope_t) GetScopeFromType(QT);
480+
}
481+
482+
static clang::Decl* GetUnderlyingScope(clang::Decl * D) {
483+
if (auto *TND = dyn_cast_or_null<TypedefNameDecl>(D)) {
484+
auto Scope = GetScopeFromType(TND->getUnderlyingType());
485+
if (Scope)
486+
D = Scope;
487+
}
488+
489+
return D;
490+
}
491+
492+
TCppScope_t GetUnderlyingScope(TCppScope_t scope) {
493+
if (!scope)
494+
return 0;
495+
return GetUnderlyingScope((clang::Decl *) scope);
496+
}
497+
465498
TCppScope_t GetScope(const std::string &name, TCppScope_t parent)
466499
{
467500
if (name == "")
@@ -494,28 +527,13 @@ namespace Cpp {
494527
return GetScope(name.substr(start, end), curr_scope);
495528
}
496529

497-
static CXXRecordDecl *GetScopeFromType(QualType QT) {
498-
if (auto *Type = QT.getTypePtrOrNull()) {
499-
Type = Type->getPointeeOrArrayElementType();
500-
Type = Type->getUnqualifiedDesugaredType();
501-
return Type->getAsCXXRecordDecl();
502-
}
503-
return 0;
504-
}
505-
506-
TCppScope_t GetScopeFromType(TCppType_t type) {
507-
QualType QT = QualType::getFromOpaquePtr(type);
508-
return (TCppScope_t)GetScopeFromType(QT);
509-
}
510-
511530
TCppScope_t GetNamed(const std::string &name,
512531
TCppScope_t parent /*= nullptr*/)
513532
{
514533
clang::DeclContext *Within = 0;
515534
if (parent) {
516535
auto *D = (clang::Decl *)parent;
517-
if (auto *TD = dyn_cast<TypedefNameDecl>(D))
518-
D = GetScopeFromType(TD->getUnderlyingType());
536+
D = GetUnderlyingScope(D);
519537
Within = llvm::dyn_cast<clang::DeclContext>(D);
520538
}
521539

@@ -734,8 +752,7 @@ namespace Cpp {
734752
if (!scope || name.empty())
735753
return {};
736754

737-
if (auto *TD = llvm::dyn_cast<TypedefNameDecl>(D))
738-
D = GetScopeFromType(TD->getUnderlyingType());
755+
D = GetUnderlyingScope(D);
739756

740757
std::vector<TCppFunction_t> funcs;
741758
llvm::StringRef Name(name);

unittests/CppInterOp/ScopeReflectionTest.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,24 @@ TEST(ScopeReflectionTest, GetGlobalScope) {
330330
EXPECT_EQ(Cpp::GetName(Cpp::GetGlobalScope()), "");
331331
}
332332

333+
TEST(ScopeReflectionTest, GetUnderlyingScope) {
334+
std::vector<Decl *> Decls;
335+
std::string code = R"(
336+
namespace N {
337+
class C {};
338+
}
339+
340+
typedef N::C NC;
341+
typedef int INT;
342+
)";
343+
344+
GetAllTopLevelDecls(code, Decls);
345+
346+
EXPECT_EQ(Cpp::GetQualifiedName(Cpp::GetUnderlyingScope(Decls[0])), "N");
347+
EXPECT_EQ(Cpp::GetQualifiedName(Cpp::GetUnderlyingScope(Decls[1])), "N::C");
348+
EXPECT_EQ(Cpp::GetQualifiedName(Cpp::GetUnderlyingScope(Decls[2])), "INT");
349+
}
350+
333351
TEST(ScopeReflectionTest, GetScope) {
334352
std::string code = R"(namespace N {
335353
class C {

0 commit comments

Comments
 (0)