Skip to content

Commit 0e2e57d

Browse files
WIP
1 parent 226a22e commit 0e2e57d

File tree

3 files changed

+113
-6
lines changed

3 files changed

+113
-6
lines changed

include/CppInterOp/CppInterOp.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,10 @@ CPPINTEROP_API size_t SizeOf(TCppScope_t scope);
300300
/// Checks if it is a "built-in" or a "complex" type.
301301
CPPINTEROP_API bool IsBuiltin(TCppType_t type);
302302

303-
/// Checks if it is a templated class.
303+
/// Checks if it is a template class.
304+
CPPINTEROP_API bool IsTemplateClass(TCppScope_t handle);
305+
306+
/// Checks if it is a template.
304307
CPPINTEROP_API bool IsTemplate(TCppScope_t handle);
305308

306309
/// Checks if it is a class template specialization class.
@@ -436,6 +439,12 @@ CPPINTEROP_API bool IsSubclass(TCppScope_t derived, TCppScope_t base);
436439
CPPINTEROP_API int64_t GetBaseClassOffset(TCppScope_t derived,
437440
TCppScope_t base);
438441

442+
CPPINTEROP_API void GetDatamembersInNamespace(TCppScope_t ns, std::vector<TCppScope_t>& members);
443+
CPPINTEROP_API void GetFunctionsInNamespace(TCppScope_t ns, std::vector<TCppScope_t>& members);
444+
CPPINTEROP_API void GetClassInNamespace(TCppScope_t ns, std::vector<TCppScope_t>& members);
445+
CPPINTEROP_API void GetTemplatedClassInNamespace(TCppScope_t ns, std::vector<TCppScope_t>& members);
446+
CPPINTEROP_API void GetTemplatedFunctionsInNamespace(TCppScope_t ns, std::vector<TCppScope_t>& members);
447+
439448
/// Sets a list of all the Methods that are in the Class that is
440449
/// supplied as a parameter.
441450
///\param[in] klass - Pointer to the scope/class under which the methods have
@@ -489,6 +498,8 @@ CPPINTEROP_API std::string GetFunctionSignature(TCppFunction_t func);
489498
///\returns if a function was marked as \c =delete.
490499
CPPINTEROP_API bool IsFunctionDeleted(TCppConstFunction_t function);
491500

501+
CPPINTEROP_API bool IsTemplateInstantiationOrSpecialization(TCppScope_t scope);
502+
492503
CPPINTEROP_API bool IsTemplatedFunction(TCppFunction_t func);
493504

494505
/// This function performs a lookup to check if there is a
@@ -669,6 +680,12 @@ CPPINTEROP_API bool IsConstMethod(TCppFunction_t method);
669680
CPPINTEROP_API std::string GetFunctionArgDefault(TCppFunction_t func,
670681
TCppIndex_t param_index);
671682

683+
///\returns the size of template arguments
684+
CPPINTEROP_API TCppIndex_t GetTemplateNumArgs(TCppScope_t scope);
685+
686+
///\returns the template argument name of template as string.
687+
CPPINTEROP_API std::string GetTemplateArgName(TCppScope_t scope, TCppIndex_t param_index);
688+
672689
///\returns the argument name of function as string.
673690
CPPINTEROP_API std::string GetFunctionArgName(TCppFunction_t func,
674691
TCppIndex_t param_index);

lib/CppInterOp/CppInterOp.cpp

Lines changed: 93 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,11 @@ bool IsBuiltin(TCppType_t type) {
437437
return llvm::StringRef(Ty.getAsString()).contains("complex");
438438
}
439439

440+
bool IsTemplateClass(TCppScope_t handle) {
441+
auto* D = (clang::Decl*)handle;
442+
return llvm::isa_and_nonnull<clang::ClassTemplateDecl>(D);
443+
}
444+
440445
bool IsTemplate(TCppScope_t handle) {
441446
auto* D = (clang::Decl*)handle;
442447
return llvm::isa_and_nonnull<clang::TemplateDecl>(D);
@@ -951,6 +956,52 @@ int64_t GetBaseClassOffset(TCppScope_t derived, TCppScope_t base) {
951956
return ComputeBaseOffset(getSema(DD).getASTContext(), DCXXRD, Paths.front());
952957
}
953958

959+
template <typename DeclType>
960+
static void GetNamespaceDecls(TCppScope_t ns,
961+
std::vector<TCppScope_t>& members) {
962+
if (!ns)
963+
return;
964+
965+
auto* D = (clang::Decl*)ns;
966+
LOCK(getInterpInfo(D));
967+
968+
if (!D || !isa<NamespaceDecl>(D))
969+
return;
970+
971+
auto* NSD = dyn_cast<NamespaceDecl>(D)->getMostRecentDecl();
972+
while (NSD) {
973+
for (Decl* DI : NSD->decls()) {
974+
if (auto* MD = dyn_cast<DeclType>(DI))
975+
members.push_back(MD);
976+
else if (auto* USD = dyn_cast<UsingShadowDecl>(DI)) {
977+
if (auto *MD = dyn_cast<DeclType>(USD->getTargetDecl()))
978+
members.push_back(MD);
979+
}
980+
}
981+
NSD = NSD->getPreviousDecl();
982+
}
983+
}
984+
985+
void GetDatamembersInNamespace(TCppScope_t ns, std::vector<TCppScope_t>& members) {
986+
GetNamespaceDecls<VarDecl>(ns, members);
987+
}
988+
989+
void GetFunctionsInNamespace(TCppScope_t ns, std::vector<TCppScope_t>& members) {
990+
GetNamespaceDecls<FunctionDecl>(ns, members);
991+
}
992+
993+
void GetClassInNamespace(TCppScope_t ns, std::vector<TCppScope_t>& members) {
994+
GetNamespaceDecls<RecordDecl>(ns, members);
995+
}
996+
997+
void GetTemplatedClassInNamespace(TCppScope_t ns, std::vector<TCppScope_t>& members) {
998+
GetNamespaceDecls<ClassTemplateDecl>(ns, members);
999+
}
1000+
1001+
void GetTemplatedFunctionsInNamespace(TCppScope_t ns, std::vector<TCppScope_t>& members) {
1002+
GetNamespaceDecls<FunctionTemplateDecl>(ns, members);
1003+
}
1004+
9541005
template <typename DeclType>
9551006
static void GetClassDecls(TCppScope_t klass,
9561007
std::vector<TCppFunction_t>& methods) {
@@ -963,6 +1014,10 @@ static void GetClassDecls(TCppScope_t klass,
9631014
if (auto* TD = dyn_cast<TypedefNameDecl>(D))
9641015
D = GetScopeFromType(TD->getUnderlyingType());
9651016

1017+
if (auto *CTD = llvm::dyn_cast_or_null<ClassTemplateDecl>(D)) {
1018+
D = CTD->getTemplatedDecl();
1019+
}
1020+
9661021
if (!D || !isa<CXXRecordDecl>(D))
9671022
return;
9681023

@@ -1094,7 +1149,7 @@ TCppType_t GetFunctionReturnType(TCppFunction_t func) {
10941149
QualType Type = FD->getReturnType();
10951150
if (Type->isUndeducedAutoType()) {
10961151
bool needInstantiation = false;
1097-
if (IsTemplatedFunction(FD) && !FD->isDefined())
1152+
if (IsTemplateInstantiationOrSpecialization(FD) && !FD->isDefined())
10981153
needInstantiation = true;
10991154
if (auto* MD = llvm::dyn_cast<clang::CXXMethodDecl>(FD)) {
11001155
if (IsTemplateSpecialization(MD->getParent()))
@@ -1141,6 +1196,9 @@ TCppIndex_t GetFunctionRequiredArgs(TCppConstFunction_t func) {
11411196

11421197
TCppType_t GetFunctionArgType(TCppFunction_t func, TCppIndex_t iarg) {
11431198
auto* D = static_cast<clang::Decl*>(func);
1199+
if (auto *FTD = llvm::dyn_cast_or_null<FunctionTemplateDecl>(D)) {
1200+
D = FTD->getTemplatedDecl();
1201+
}
11441202
if (auto* FD = llvm::dyn_cast_or_null<clang::FunctionDecl>(D)) {
11451203
LOCK(getInterpInfo(FD));
11461204
if (iarg < FD->getNumParams()) {
@@ -1207,7 +1265,12 @@ bool IsFunctionDeleted(TCppConstFunction_t function) {
12071265

12081266
bool IsTemplatedFunction(TCppFunction_t func) {
12091267
auto* D = (Decl*)func;
1210-
return IsTemplatedFunction(D) || IsTemplateInstantiationOrSpecialization(D);
1268+
return IsTemplatedFunction(D) /*|| IsTemplateInstantiationOrSpecialization(D)*/;
1269+
}
1270+
1271+
bool IsTemplateInstantiationOrSpecialization(TCppScope_t scope) {
1272+
auto *D = static_cast<Decl*>(scope);
1273+
return IsTemplateInstantiationOrSpecialization(D);
12111274
}
12121275

12131276
// FIXME: This lookup is broken, and should no longer be used in favour of
@@ -1430,6 +1493,9 @@ bool IsDestructor(TCppConstFunction_t method) {
14301493

14311494
bool IsStaticMethod(TCppConstFunction_t method) {
14321495
const auto* D = static_cast<const Decl*>(method);
1496+
if (auto *FTD = llvm::dyn_cast_or_null<FunctionTemplateDecl>(D)) {
1497+
D = FTD->getTemplatedDecl();
1498+
}
14331499
if (auto* CXXMD = llvm::dyn_cast_or_null<CXXMethodDecl>(D)) {
14341500
LOCK(getInterpInfo(D));
14351501
return CXXMD->isStatic();
@@ -1503,6 +1569,9 @@ bool IsVirtualMethod(TCppFunction_t method) {
15031569

15041570
void GetDatamembers(TCppScope_t scope, std::vector<TCppScope_t>& datamembers) {
15051571
auto* D = (Decl*)scope;
1572+
if (auto *CTD = llvm::dyn_cast_or_null<ClassTemplateDecl>(D)) {
1573+
D = CTD->getTemplatedDecl();
1574+
}
15061575

15071576
if (auto* CXXRD = llvm::dyn_cast_or_null<CXXRecordDecl>(D)) {
15081577
LOCK(getInterpInfo(CXXRD));
@@ -1604,7 +1673,7 @@ TCppType_t GetVariableType(TCppScope_t var) {
16041673
QualType QT = DD->getType();
16051674

16061675
// Check if the type is a typedef type
1607-
if (QT->isTypedefNameType()) {
1676+
if (QT->isTypedefNameType() || QT->getAs<clang::TemplateTypeParmType>()) {
16081677
return QT.getAsOpaquePtr();
16091678
}
16101679

@@ -1865,6 +1934,8 @@ TCppType_t GetCanonicalType(TCppType_t type) {
18651934
if (!type)
18661935
return 0;
18671936
QualType QT = QualType::getFromOpaquePtr(type);
1937+
if (QT->getAs<clang::TemplateTypeParmType>())
1938+
return type;
18681939
return QT.getCanonicalType().getAsOpaquePtr();
18691940
}
18701941

@@ -3996,6 +4067,25 @@ bool IsConstMethod(TCppFunction_t method) {
39964067
return false;
39974068
}
39984069

4070+
TCppIndex_t GetTemplateNumArgs(TCppScope_t scope) {
4071+
auto *D = static_cast<Decl*>(scope);
4072+
if (auto *TD = llvm::dyn_cast<TemplateDecl>(D)) {
4073+
auto *TPL = TD->getTemplateParameters();
4074+
return TPL->size();
4075+
}
4076+
return -1;
4077+
}
4078+
4079+
std::string GetTemplateArgName(TCppScope_t scope, TCppIndex_t param_index) {
4080+
auto *D = static_cast<Decl*>(scope);
4081+
if (auto *TD = llvm::dyn_cast<TemplateDecl>(D)) {
4082+
auto *TPL = TD->getTemplateParameters();
4083+
NamedDecl *ND = TPL->getParam(param_index);
4084+
return ND->getNameAsString();
4085+
}
4086+
return "";
4087+
}
4088+
39994089
std::string GetFunctionArgName(TCppFunction_t func, TCppIndex_t param_index) {
40004090
auto* D = (clang::Decl*)func;
40014091
clang::ParmVarDecl* PI = nullptr;

unittests/CppInterOp/FunctionReflectionTest.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -929,7 +929,7 @@ TEST(FunctionReflectionTest, InstantiateVariadicFunction) {
929929
C.IntTy.getAsOpaquePtr()};
930930
auto Instance1 = Cpp::InstantiateTemplate(Decls[1], args1.data(),
931931
/*type_size*/ args1.size());
932-
EXPECT_TRUE(Cpp::IsTemplatedFunction(Instance1));
932+
EXPECT_TRUE(Cpp::IsTemplateInstantiationOrSpecialization(Instance1));
933933
EXPECT_EQ(Cpp::GetFunctionSignature(Instance1),
934934
"template<> void VariadicFn<<double, int>>(double args, int args)");
935935

@@ -952,7 +952,7 @@ TEST(FunctionReflectionTest, InstantiateVariadicFunction) {
952952
// instantiate VariadicFnExtended
953953
auto Instance2 =
954954
Cpp::InstantiateTemplate(Decls[2], args2.data(), args2.size(), true);
955-
EXPECT_TRUE(Cpp::IsTemplatedFunction(Instance2));
955+
EXPECT_TRUE(Cpp::IsTemplateInstantiationOrSpecialization(Instance2));
956956

957957
FunctionDecl* FD2 = cast<FunctionDecl>((Decl*)Instance2);
958958
FunctionDecl* FnTD2 = FD2->getTemplateInstantiationPattern();

0 commit comments

Comments
 (0)