Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion include/CppInterOp/CppInterOp.h
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,10 @@ CPPINTEROP_API size_t SizeOf(TCppScope_t scope);
/// Checks if it is a "built-in" or a "complex" type.
CPPINTEROP_API bool IsBuiltin(TCppType_t type);

/// Checks if it is a templated class.
/// Checks if it is a template class.
CPPINTEROP_API bool IsTemplateClass(TCppScope_t handle);

/// Checks if it is a template.
CPPINTEROP_API bool IsTemplate(TCppScope_t handle);

/// Checks if it is a class template specialization class.
Expand Down Expand Up @@ -373,6 +376,8 @@ CPPINTEROP_API bool IsVariable(TCppScope_t scope);
/// namespace, variable, or a function).
CPPINTEROP_API std::string GetName(TCppScope_t klass);

CPPINTEROP_API std::string GetDocString(TCppScope_t scope);

/// This is similar to GetName() function, but besides
/// the name, it also gets the template arguments.
CPPINTEROP_API std::string GetCompleteName(TCppScope_t klass);
Expand Down Expand Up @@ -437,6 +442,12 @@ CPPINTEROP_API bool IsSubclass(TCppScope_t derived, TCppScope_t base);
CPPINTEROP_API int64_t GetBaseClassOffset(TCppScope_t derived,
TCppScope_t base);

CPPINTEROP_API void GetDatamembersInNamespace(TCppScope_t ns, std::vector<TCppScope_t>& members);
CPPINTEROP_API void GetFunctionsInNamespace(TCppScope_t ns, std::vector<TCppScope_t>& members);
CPPINTEROP_API void GetClassInNamespace(TCppScope_t ns, std::vector<TCppScope_t>& members);
CPPINTEROP_API void GetTemplatedClassInNamespace(TCppScope_t ns, std::vector<TCppScope_t>& members);
CPPINTEROP_API void GetTemplatedFunctionsInNamespace(TCppScope_t ns, std::vector<TCppScope_t>& members);

/// Sets a list of all the Methods that are in the Class that is
/// supplied as a parameter.
///\param[in] klass - Pointer to the scope/class under which the methods have
Expand Down Expand Up @@ -490,6 +501,8 @@ CPPINTEROP_API std::string GetFunctionSignature(TCppFunction_t func);
///\returns if a function was marked as \c =delete.
CPPINTEROP_API bool IsFunctionDeleted(TCppConstFunction_t function);

CPPINTEROP_API bool IsTemplateInstantiationOrSpecialization(TCppScope_t scope);

CPPINTEROP_API bool IsTemplatedFunction(TCppFunction_t func);

/// This function performs a lookup to check if there is a
Expand Down Expand Up @@ -670,6 +683,12 @@ CPPINTEROP_API bool IsConstMethod(TCppFunction_t method);
CPPINTEROP_API std::string GetFunctionArgDefault(TCppFunction_t func,
TCppIndex_t param_index);

///\returns the size of template arguments
CPPINTEROP_API TCppIndex_t GetTemplateNumArgs(TCppScope_t scope);

///\returns the template argument name of template as string.
CPPINTEROP_API std::string GetTemplateArgName(TCppScope_t scope, TCppIndex_t param_index);

///\returns the argument name of function as string.
CPPINTEROP_API std::string GetFunctionArgName(TCppFunction_t func,
TCppIndex_t param_index);
Expand Down
108 changes: 103 additions & 5 deletions lib/CppInterOp/CppInterOp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "Compatibility.h"

#include "clang/AST/Attrs.inc"
#include "clang/AST/Comment.h"
#include "clang/AST/CXXInheritance.h"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: #includes are not sorted properly [llvm-include-order]

Suggested change
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/Comment.h"

#include "clang/AST/Decl.h"
#include "clang/AST/DeclAccessPair.h"
Expand Down Expand Up @@ -380,6 +381,11 @@
return llvm::StringRef(Ty.getAsString()).contains("complex");
}

bool IsTemplateClass(TCppScope_t handle) {
auto* D = (clang::Decl*)handle;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use C-style cast to convert between unrelated types [cppcoreguidelines-pro-type-cstyle-cast]

  auto* D = (clang::Decl*)handle;
            ^

return llvm::isa_and_nonnull<clang::ClassTemplateDecl>(D);

Check warning on line 386 in lib/CppInterOp/CppInterOp.cpp

View check run for this annotation

Codecov / codecov/patch

lib/CppInterOp/CppInterOp.cpp#L384-L386

Added lines #L384 - L386 were not covered by tests
}

bool IsTemplate(TCppScope_t handle) {
auto* D = (clang::Decl*)handle;
return llvm::isa_and_nonnull<clang::TemplateDecl>(D);
Expand Down Expand Up @@ -546,6 +552,15 @@
return llvm::isa_and_nonnull<clang::VarDecl>(D);
}

std::string GetDocString(TCppScope_t scope) {
auto *D = static_cast<Decl*>(scope);
auto &AST = getASTContext();
const clang::RawComment *Comment = AST.getRawCommentForAnyRedecl(D);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "clang::RawComment" is directly included [misc-include-cleaner]

lib/CppInterOp/CppInterOp.cpp:42:

- #if CLANG_VERSION_MAJOR >= 19
+ #include <clang/AST/RawCommentList.h>
+ #if CLANG_VERSION_MAJOR >= 19

if (!Comment)
return "";
return Comment->getFormattedText(AST.getSourceManager(), AST.getDiagnostics());

Check warning on line 561 in lib/CppInterOp/CppInterOp.cpp

View check run for this annotation

Codecov / codecov/patch

lib/CppInterOp/CppInterOp.cpp#L555-L561

Added lines #L555 - L561 were not covered by tests
}

std::string GetName(TCppType_t klass) {
auto* D = (clang::NamedDecl*)klass;

Expand Down Expand Up @@ -877,6 +892,51 @@
return ComputeBaseOffset(getSema().getASTContext(), DCXXRD, Paths.front());
}

template <typename DeclType>
static void GetNamespaceDecls(TCppScope_t ns,

Check warning on line 896 in lib/CppInterOp/CppInterOp.cpp

View check run for this annotation

Codecov / codecov/patch

lib/CppInterOp/CppInterOp.cpp#L896

Added line #L896 was not covered by tests
std::vector<TCppScope_t>& members) {
if (!ns)
return;

Check warning on line 899 in lib/CppInterOp/CppInterOp.cpp

View check run for this annotation

Codecov / codecov/patch

lib/CppInterOp/CppInterOp.cpp#L898-L899

Added lines #L898 - L899 were not covered by tests

auto* D = (clang::Decl*)ns;

Check warning on line 901 in lib/CppInterOp/CppInterOp.cpp

View check run for this annotation

Codecov / codecov/patch

lib/CppInterOp/CppInterOp.cpp#L901

Added line #L901 was not covered by tests
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use C-style cast to convert between unrelated types [cppcoreguidelines-pro-type-cstyle-cast]

  auto* D = (clang::Decl*)ns;
            ^


if (!D || !isa<NamespaceDecl>(D))
return;

Check warning on line 904 in lib/CppInterOp/CppInterOp.cpp

View check run for this annotation

Codecov / codecov/patch

lib/CppInterOp/CppInterOp.cpp#L903-L904

Added lines #L903 - L904 were not covered by tests

auto* NSD = dyn_cast<NamespaceDecl>(D)->getMostRecentDecl();
while (NSD) {
for (Decl* DI : NSD->decls()) {
if (auto* MD = dyn_cast<DeclType>(DI))
members.push_back(MD);
else if (auto* USD = dyn_cast<UsingShadowDecl>(DI)) {
if (auto *MD = dyn_cast<DeclType>(USD->getTargetDecl()))
members.push_back(MD);

Check warning on line 913 in lib/CppInterOp/CppInterOp.cpp

View check run for this annotation

Codecov / codecov/patch

lib/CppInterOp/CppInterOp.cpp#L906-L913

Added lines #L906 - L913 were not covered by tests
}
}
NSD = NSD->getPreviousDecl();

Check warning on line 916 in lib/CppInterOp/CppInterOp.cpp

View check run for this annotation

Codecov / codecov/patch

lib/CppInterOp/CppInterOp.cpp#L916

Added line #L916 was not covered by tests
}
}

void GetDatamembersInNamespace(TCppScope_t ns, std::vector<TCppScope_t>& members) {
GetNamespaceDecls<VarDecl>(ns, members);

Check warning on line 921 in lib/CppInterOp/CppInterOp.cpp

View check run for this annotation

Codecov / codecov/patch

lib/CppInterOp/CppInterOp.cpp#L920-L921

Added lines #L920 - L921 were not covered by tests
}

void GetFunctionsInNamespace(TCppScope_t ns, std::vector<TCppScope_t>& members) {
GetNamespaceDecls<FunctionDecl>(ns, members);

Check warning on line 925 in lib/CppInterOp/CppInterOp.cpp

View check run for this annotation

Codecov / codecov/patch

lib/CppInterOp/CppInterOp.cpp#L924-L925

Added lines #L924 - L925 were not covered by tests
}

void GetClassInNamespace(TCppScope_t ns, std::vector<TCppScope_t>& members) {
GetNamespaceDecls<RecordDecl>(ns, members);

Check warning on line 929 in lib/CppInterOp/CppInterOp.cpp

View check run for this annotation

Codecov / codecov/patch

lib/CppInterOp/CppInterOp.cpp#L928-L929

Added lines #L928 - L929 were not covered by tests
}

void GetTemplatedClassInNamespace(TCppScope_t ns, std::vector<TCppScope_t>& members) {
GetNamespaceDecls<ClassTemplateDecl>(ns, members);

Check warning on line 933 in lib/CppInterOp/CppInterOp.cpp

View check run for this annotation

Codecov / codecov/patch

lib/CppInterOp/CppInterOp.cpp#L932-L933

Added lines #L932 - L933 were not covered by tests
}

void GetTemplatedFunctionsInNamespace(TCppScope_t ns, std::vector<TCppScope_t>& members) {
GetNamespaceDecls<FunctionTemplateDecl>(ns, members);

Check warning on line 937 in lib/CppInterOp/CppInterOp.cpp

View check run for this annotation

Codecov / codecov/patch

lib/CppInterOp/CppInterOp.cpp#L936-L937

Added lines #L936 - L937 were not covered by tests
}

template <typename DeclType>
static void GetClassDecls(TCppScope_t klass,
std::vector<TCppFunction_t>& methods) {
Expand All @@ -888,6 +948,10 @@
if (auto* TD = dyn_cast<TypedefNameDecl>(D))
D = GetScopeFromType(TD->getUnderlyingType());

if (auto *CTD = llvm::dyn_cast_or_null<ClassTemplateDecl>(D)) {
D = CTD->getTemplatedDecl();

Check warning on line 952 in lib/CppInterOp/CppInterOp.cpp

View check run for this annotation

Codecov / codecov/patch

lib/CppInterOp/CppInterOp.cpp#L952

Added line #L952 was not covered by tests
}

if (!D || !isa<CXXRecordDecl>(D))
return;

Expand Down Expand Up @@ -1011,7 +1075,7 @@
QualType Type = FD->getReturnType();
if (Type->isUndeducedAutoType()) {
bool needInstantiation = false;
if (IsTemplatedFunction(FD) && !FD->isDefined())
if (IsTemplateInstantiationOrSpecialization(FD) && !FD->isDefined())
needInstantiation = true;
if (auto* MD = llvm::dyn_cast<clang::CXXMethodDecl>(FD)) {
if (IsTemplateSpecialization(MD->getParent()))
Expand Down Expand Up @@ -1055,8 +1119,10 @@
}

TCppType_t GetFunctionArgType(TCppFunction_t func, TCppIndex_t iarg) {
auto* D = (clang::Decl*)func;

auto* D = static_cast<clang::Decl*>(func);
if (auto *FTD = llvm::dyn_cast_or_null<FunctionTemplateDecl>(D)) {
D = FTD->getTemplatedDecl();

Check warning on line 1124 in lib/CppInterOp/CppInterOp.cpp

View check run for this annotation

Codecov / codecov/patch

lib/CppInterOp/CppInterOp.cpp#L1124

Added line #L1124 was not covered by tests
}
if (auto* FD = llvm::dyn_cast_or_null<clang::FunctionDecl>(D)) {
if (iarg < FD->getNumParams()) {
auto* PVD = FD->getParamDecl(iarg);
Expand Down Expand Up @@ -1122,7 +1188,12 @@

bool IsTemplatedFunction(TCppFunction_t func) {
auto* D = (Decl*)func;
return IsTemplatedFunction(D) || IsTemplateInstantiationOrSpecialization(D);
return IsTemplatedFunction(D) /*|| IsTemplateInstantiationOrSpecialization(D)*/;
}

bool IsTemplateInstantiationOrSpecialization(TCppScope_t scope) {
auto *D = static_cast<Decl*>(scope);
return IsTemplateInstantiationOrSpecialization(D);
}

// FIXME: This lookup is broken, and should no longer be used in favour of
Expand Down Expand Up @@ -1334,6 +1405,9 @@

bool IsStaticMethod(TCppConstFunction_t method) {
const auto* D = static_cast<const Decl*>(method);
if (auto *FTD = llvm::dyn_cast_or_null<FunctionTemplateDecl>(D)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: 'auto *FTD' can be declared as 'const auto *FTD' [readability-qualified-auto]

Suggested change
if (auto *FTD = llvm::dyn_cast_or_null<FunctionTemplateDecl>(D)) {
if (const auto *FTD = llvm::dyn_cast_or_null<FunctionTemplateDecl>(D)) {

D = FTD->getTemplatedDecl();

Check warning on line 1409 in lib/CppInterOp/CppInterOp.cpp

View check run for this annotation

Codecov / codecov/patch

lib/CppInterOp/CppInterOp.cpp#L1409

Added line #L1409 was not covered by tests
}
if (auto* CXXMD = llvm::dyn_cast_or_null<CXXMethodDecl>(D)) {
return CXXMD->isStatic();
}
Expand Down Expand Up @@ -1404,6 +1478,9 @@

void GetDatamembers(TCppScope_t scope, std::vector<TCppScope_t>& datamembers) {
auto* D = (Decl*)scope;
if (auto *CTD = llvm::dyn_cast_or_null<ClassTemplateDecl>(D)) {
D = CTD->getTemplatedDecl();

Check warning on line 1482 in lib/CppInterOp/CppInterOp.cpp

View check run for this annotation

Codecov / codecov/patch

lib/CppInterOp/CppInterOp.cpp#L1482

Added line #L1482 was not covered by tests
}

if (auto* CXXRD = llvm::dyn_cast_or_null<CXXRecordDecl>(D)) {
getSema().ForceDeclarationOfImplicitMembers(CXXRD);
Expand Down Expand Up @@ -1497,7 +1574,7 @@
QualType QT = DD->getType();

// Check if the type is a typedef type
if (QT->isTypedefNameType()) {
if (QT->isTypedefNameType() || QT->getAs<clang::TemplateTypeParmType>()) {
return QT.getAsOpaquePtr();
}

Expand Down Expand Up @@ -1758,6 +1835,8 @@
if (!type)
return 0;
QualType QT = QualType::getFromOpaquePtr(type);
if (QT->getAs<clang::TemplateTypeParmType>())
return type;

Check warning on line 1839 in lib/CppInterOp/CppInterOp.cpp

View check run for this annotation

Codecov / codecov/patch

lib/CppInterOp/CppInterOp.cpp#L1839

Added line #L1839 was not covered by tests
return QT.getCanonicalType().getAsOpaquePtr();
}

Expand Down Expand Up @@ -3841,6 +3920,25 @@
return false;
}

TCppIndex_t GetTemplateNumArgs(TCppScope_t scope) {
auto *D = static_cast<Decl*>(scope);
if (auto *TD = llvm::dyn_cast<TemplateDecl>(D)) {
auto *TPL = TD->getTemplateParameters();
return TPL->size();

Check warning on line 3927 in lib/CppInterOp/CppInterOp.cpp

View check run for this annotation

Codecov / codecov/patch

lib/CppInterOp/CppInterOp.cpp#L3923-L3927

Added lines #L3923 - L3927 were not covered by tests
}
return -1;

Check warning on line 3929 in lib/CppInterOp/CppInterOp.cpp

View check run for this annotation

Codecov / codecov/patch

lib/CppInterOp/CppInterOp.cpp#L3929

Added line #L3929 was not covered by tests
}

std::string GetTemplateArgName(TCppScope_t scope, TCppIndex_t param_index) {
auto *D = static_cast<Decl*>(scope);
if (auto *TD = llvm::dyn_cast<TemplateDecl>(D)) {
auto *TPL = TD->getTemplateParameters();
NamedDecl *ND = TPL->getParam(param_index);
return ND->getNameAsString();

Check warning on line 3937 in lib/CppInterOp/CppInterOp.cpp

View check run for this annotation

Codecov / codecov/patch

lib/CppInterOp/CppInterOp.cpp#L3932-L3937

Added lines #L3932 - L3937 were not covered by tests
}
return "";

Check warning on line 3939 in lib/CppInterOp/CppInterOp.cpp

View check run for this annotation

Codecov / codecov/patch

lib/CppInterOp/CppInterOp.cpp#L3939

Added line #L3939 was not covered by tests
}

std::string GetFunctionArgName(TCppFunction_t func, TCppIndex_t param_index) {
auto* D = (clang::Decl*)func;
clang::ParmVarDecl* PI = nullptr;
Expand Down
4 changes: 2 additions & 2 deletions unittests/CppInterOp/FunctionReflectionTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -929,7 +929,7 @@ TYPED_TEST(CppInterOpTest, FunctionReflectionTestInstantiateVariadicFunction) {
C.IntTy.getAsOpaquePtr()};
auto Instance1 = Cpp::InstantiateTemplate(Decls[1], args1.data(),
/*type_size*/ args1.size());
EXPECT_TRUE(Cpp::IsTemplatedFunction(Instance1));
EXPECT_TRUE(Cpp::IsTemplateInstantiationOrSpecialization(Instance1));
EXPECT_EQ(Cpp::GetFunctionSignature(Instance1),
"template<> void VariadicFn<<double, int>>(double args, int args)");

Expand All @@ -952,7 +952,7 @@ TYPED_TEST(CppInterOpTest, FunctionReflectionTestInstantiateVariadicFunction) {
// instantiate VariadicFnExtended
auto Instance2 =
Cpp::InstantiateTemplate(Decls[2], args2.data(), args2.size(), true);
EXPECT_TRUE(Cpp::IsTemplatedFunction(Instance2));
EXPECT_TRUE(Cpp::IsTemplateInstantiationOrSpecialization(Instance2));

FunctionDecl* FD2 = cast<FunctionDecl>((Decl*)Instance2);
FunctionDecl* FnTD2 = FD2->getTemplateInstantiationPattern();
Expand Down
Loading