Skip to content

Commit 515c1c8

Browse files
fix GetNumBases to handle templated typedefs (#681)
* fix GetNumBases to handle templated typedefs Co-authored-by: Vassil Vassilev <[email protected]> --------- Co-authored-by: Vassil Vassilev <[email protected]>
1 parent b7aacc1 commit 515c1c8

File tree

3 files changed

+31
-0
lines changed

3 files changed

+31
-0
lines changed

lib/CppInterOp/Compatibility.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,13 @@
55
#ifndef CPPINTEROP_COMPATIBILITY_H
66
#define CPPINTEROP_COMPATIBILITY_H
77

8+
#include "clang/AST/DeclTemplate.h"
89
#include "clang/AST/GlobalDecl.h"
10+
#include "clang/Basic/SourceLocation.h"
11+
#include "clang/Basic/Specifiers.h"
912
#include "clang/Basic/Version.h"
1013
#include "clang/Config/config.h"
14+
#include "clang/Sema/Sema.h"
1115

1216
#ifdef _MSC_VER
1317
#define dup _dup
@@ -413,6 +417,22 @@ template <typename T> inline T convertTo(clang::Value V) {
413417
}
414418
#endif // CPPINTEROP_USE_CLING
415419

420+
inline void InstantiateClassTemplateSpecialization(
421+
Interpreter& interp, clang::ClassTemplateSpecializationDecl* CTSD) {
422+
#ifdef CPPINTEROP_USE_CLING
423+
cling::Interpreter::PushTransactionRAII RAII(&interp);
424+
#endif
425+
#if CLANG_VERSION_MAJOR < 20
426+
interp.getSema().InstantiateClassTemplateSpecialization(
427+
clang::SourceLocation::getFromRawEncoding(1), CTSD,
428+
clang::TemplateSpecializationKind::TSK_Undeclared, /*Complain=*/true);
429+
#else
430+
interp.getSema().InstantiateClassTemplateSpecialization(
431+
clang::SourceLocation::getFromRawEncoding(1), CTSD,
432+
clang::TemplateSpecializationKind::TSK_Undeclared, /*Complain=*/true,
433+
/*PrimaryHasMatchedPackOnParmToNonPackOnArg=*/false);
434+
#endif
435+
}
416436
} // namespace compat
417437

418438
#endif // CPPINTEROP_COMPATIBILITY_H

lib/CppInterOp/CppInterOp.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,9 @@ TCppScope_t GetParentScope(TCppScope_t scope) {
718718
TCppIndex_t GetNumBases(TCppScope_t klass) {
719719
auto* D = (Decl*)klass;
720720

721+
if (auto* CTSD = llvm::dyn_cast_or_null<ClassTemplateSpecializationDecl>(D))
722+
if (!CTSD->hasDefinition())
723+
compat::InstantiateClassTemplateSpecialization(getInterp(), CTSD);
721724
if (auto* CXXRD = llvm::dyn_cast_or_null<CXXRecordDecl>(D)) {
722725
if (CXXRD->hasDefinition())
723726
return CXXRD->getNumBases();

unittests/CppInterOp/ScopeReflectionTest.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,13 @@ TEST(ScopeReflectionTest, GetNumBases) {
641641
class D : public B, public C {};
642642
class E : public D {};
643643
class NoDef;
644+
645+
template<typename T, int N>
646+
struct Klass : public A {
647+
T t{N};
648+
};
649+
650+
typedef Klass<int, 1> TKlass;
644651
)";
645652

646653
GetAllTopLevelDecls(code, Decls);
@@ -653,6 +660,7 @@ TEST(ScopeReflectionTest, GetNumBases) {
653660
// FIXME: Perhaps we should have a special number or error out as this
654661
// operation is not well defined if a class has no definition.
655662
EXPECT_EQ(Cpp::GetNumBases(Decls[5]), 0);
663+
EXPECT_EQ(Cpp::GetNumBases(Cpp::GetUnderlyingScope(Decls[7])), 1);
656664
}
657665

658666
TEST(ScopeReflectionTest, GetBaseClass) {

0 commit comments

Comments
 (0)