Skip to content

Commit

Permalink
Merge pull request #5 from sudo-panda/overload-fix
Browse files Browse the repository at this point in the history
Add methods to support detection of implicitly castable arguments
  • Loading branch information
wlav authored Jul 24, 2023
2 parents ef2cedc + 1eb1f7c commit 25917de
Show file tree
Hide file tree
Showing 9 changed files with 179 additions and 0 deletions.
18 changes: 18 additions & 0 deletions cling/src/core/meta/inc/TInterpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,24 @@ class TInterpreter : public TNamed {
// additional virtual methods at the end for build-time backwards compatibility
virtual DeclId_t GetTagDeclId(DataMemberInfo_t *info) const = 0;
virtual ClassInfo_t *ClassInfo_FactoryWithScope(Bool_t /*all*/ = kTRUE, const char* /*scope*/ = nullptr) const = 0;

// additional MethodArgInfo interface
virtual TypeInfo_t *MethodArgInfo_TypeInfo(MethodArgInfo_t * /* marginfo */) const {return 0;}

// additional TypeInfo interface
virtual void *TypeInfo_QualTypePtr(TypeInfo_t * /* tinfo */) const {return 0;}

// QualType Opaque Ptr interface
virtual Bool_t IsSameType(const void * /* QualTypePtr1 */, const void * /* QualTypePtr2 */) const {return 0;}
virtual Bool_t IsIntegerType(const void * /* QualTypePtr */) const {return 0;}
virtual Bool_t IsSignedIntegerType(const void * /* QualTypePtr */) const {return 0;}
virtual Bool_t IsUnsignedIntegerType(const void * /* QualTypePtr */) const {return 0;}
virtual Bool_t IsFloatingType(const void * /* QualTypePtr */) const {return 0;}
virtual Bool_t IsPointerType(const void * /* QualTypePtr */) const {return 0;}
virtual Bool_t IsVoidPointerType(const void * /* QualTypePtr */) const {return 0;}

// FunctionDecl interface
virtual Bool_t FunctionDeclId_IsMethod(DeclId_t /* fdeclid */) const {return 0;}
};

} // namespace CppyyLegacy
Expand Down
1 change: 1 addition & 0 deletions cling/src/core/meta/inc/TMethodArg.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ friend class TMethod;
const char *GetFullTypeName() const;
std::string GetTypeNormalizedName() const;
Long_t Property() const;
TypeInfo_t *GetTypeInfo() const;

void Update(MethodArgInfo_t *info);

Expand Down
8 changes: 8 additions & 0 deletions cling/src/core/meta/src/TMethodArg.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,14 @@ Long_t TMethodArg::Property() const
return gCling->MethodArgInfo_Property(fInfo);
}

////////////////////////////////////////////////////////////////////////////////
/// Get the QualType of the argument.

TypeInfo_t *TMethodArg::GetTypeInfo() const
{
return gCling->MethodArgInfo_TypeInfo(fInfo);
}

////////////////////////////////////////////////////////////////////////////////
/// Update fInfo (to 0 for unloading and non-zero for reloading).
/// This takes ownership of 'info'
Expand Down
81 changes: 81 additions & 0 deletions cling/src/core/metacling/src/TCling.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -8250,6 +8250,14 @@ std::string TCling::MethodArgInfo_TypeNormalizedName(MethodArgInfo_t* marginfo)
return info->Type()->NormalizedName(*fNormalizedCtxt);
}

////////////////////////////////////////////////////////////////////////////////

TypeInfo_t* TCling::MethodArgInfo_TypeInfo(MethodArgInfo_t *marginfo) const
{
TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
return (TypeInfo_t*) info->Type();
}

//______________________________________________________________________________
//
// TypeInfo interface
Expand Down Expand Up @@ -8342,6 +8350,14 @@ const char* TCling::TypeInfo_TrueName(TypeInfo_t* tinfo) const
return TClinginfo->TrueName(*fNormalizedCtxt);
}

////////////////////////////////////////////////////////////////////////////////

void* TCling::TypeInfo_QualTypePtr(TypeInfo_t* tinfo) const
{
TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
return TClinginfo->QualTypePtr();
}


//______________________________________________________________________________
//
Expand Down Expand Up @@ -8446,6 +8462,71 @@ const char* TCling::TypedefInfo_Title(TypedefInfo_t* tinfo) const

////////////////////////////////////////////////////////////////////////////////

bool TCling::IsSameType(const void * QualTypePtr1, const void * QualTypePtr2) const
{
clang::QualType QT1 = clang::QualType::getFromOpaquePtr(QualTypePtr1);
clang::QualType QT2 = clang::QualType::getFromOpaquePtr(QualTypePtr2);
return fInterpreter->getCI()->getASTContext().hasSameType(QT1, QT2);
}

////////////////////////////////////////////////////////////////////////////////

bool TCling::IsIntegerType(const void * QualTypePtr) const
{
clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
return QT->hasIntegerRepresentation();
}

////////////////////////////////////////////////////////////////////////////////

bool TCling::IsSignedIntegerType(const void * QualTypePtr) const
{
clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
return QT->hasSignedIntegerRepresentation();
}

////////////////////////////////////////////////////////////////////////////////

bool TCling::IsUnsignedIntegerType(const void * QualTypePtr) const
{
clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
return QT->hasUnsignedIntegerRepresentation();
}

////////////////////////////////////////////////////////////////////////////////

bool TCling::IsFloatingType(const void * QualTypePtr) const
{
clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
return QT->hasFloatingRepresentation();
}

////////////////////////////////////////////////////////////////////////////////

bool TCling::IsPointerType(const void * QualTypePtr) const
{
clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
return QT->hasPointerRepresentation();
}

////////////////////////////////////////////////////////////////////////////////

bool TCling::IsVoidPointerType(const void * QualTypePtr) const
{
clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
return QT->isVoidPointerType();
}

////////////////////////////////////////////////////////////////////////////////

bool TCling::FunctionDeclId_IsMethod(DeclId_t fdeclid) const
{
clang::FunctionDecl *FD = (clang::FunctionDecl *) fdeclid;
return llvm::isa_and_nonnull<clang::CXXMethodDecl>(FD);
}

////////////////////////////////////////////////////////////////////////////////

void TCling::SnapshotMutexState(CppyyLegacy::TVirtualRWMutex* mtx)
{
if (!fInitialMutex.back()) {
Expand Down
19 changes: 19 additions & 0 deletions cling/src/core/metacling/src/TCling.h
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,25 @@ class TCling final : public TInterpreter {
// additional virtual methods at the end for build-time backwards compatibility
virtual DeclId_t GetTagDeclId(DataMemberInfo_t *info) const;
virtual ClassInfo_t *ClassInfo_FactoryWithScope(Bool_t /*all*/ = kTRUE, const char* /*scope*/ = nullptr) const;

public:
// additional MethodArgInfo interface
virtual TypeInfo_t* MethodArgInfo_TypeInfo(MethodArgInfo_t *marginfo) const;

// additional TypeInfo interface
virtual void* TypeInfo_QualTypePtr(TypeInfo_t* tinfo) const;

// QualType Opaque Ptr interface
virtual bool IsSameType(const void * QualTypePtr1, const void * QualTypePtr2) const;
virtual bool IsIntegerType(const void * QualTypePtr) const;
virtual bool IsSignedIntegerType(const void * QualTypePtr) const;
virtual bool IsUnsignedIntegerType(const void * QualTypePtr) const;
virtual bool IsFloatingType(const void * QualTypePtr) const;
virtual bool IsPointerType(const void * QualTypePtr) const;
virtual bool IsVoidPointerType(const void * QualTypePtr) const;

// FunctionDecl interface
bool FunctionDeclId_IsMethod(DeclId_t fdeclid) const;
};

} // namespace CppyyLegacy
Expand Down
7 changes: 7 additions & 0 deletions cling/src/core/metacling/src/TClingTypeInfo.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ TClingTypeInfo::TClingTypeInfo(cling::Interpreter *interp, const char *name)

////////////////////////////////////////////////////////////////////////////////

void *TClingTypeInfo::QualTypePtr() const
{
return fQualType.getAsOpaquePtr();
}

////////////////////////////////////////////////////////////////////////////////

void TClingTypeInfo::Init(const char *name)
{
fQualType = clang::QualType();
Expand Down
2 changes: 2 additions & 0 deletions cling/src/core/metacling/src/TClingTypeInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ class TClingTypeInfo {

clang::QualType GetQualType() const { return fQualType; }

void *QualTypePtr() const;

void Init(const char *name); // Set type by name.
void Init(clang::QualType ty) { fQualType = ty; }
bool IsValid() const { return !fQualType.isNull(); }
Expand Down
41 changes: 41 additions & 0 deletions clingwrapper/src/clingwrapper.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
// Standard
#include <assert.h>
#include <algorithm> // for std::count, std::remove
#include <climits>
#include <stdexcept>
#include <map>
#include <new>
Expand Down Expand Up @@ -375,6 +376,16 @@ TFunction* m2f(Cppyy::TCppMethod_t method) {
return wrap->fTF;
}

static inline
CallWrapper::DeclId_t m2d(Cppyy::TCppMethod_t method) {
CallWrapper* wrap = ((CallWrapper*)method);
if (!wrap->fTF || wrap->fTF->GetDeclId() != wrap->fDecl) {
MethodInfo_t* mi = gInterpreter->MethodInfo_Factory(wrap->fDecl);
wrap->fTF = new TFunction(mi);
}
return wrap->fDecl;
}

static inline
char* cppstring_to_cstring(const std::string& cppstr)
{
Expand Down Expand Up @@ -1699,6 +1710,36 @@ std::string Cppyy::GetMethodArgType(TCppMethod_t method, TCppIndex_t iarg)
return "<unknown>";
}

Cppyy::TCppIndex_t Cppyy::CompareMethodArgType(TCppMethod_t method, TCppIndex_t iarg, const std::string &req_type)
{
if (method) {
TFunction* f = m2f(method);
TMethodArg* arg = (TMethodArg *)f->GetListOfMethodArgs()->At((int)iarg);
void *argqtp = gInterpreter->TypeInfo_QualTypePtr(arg->GetTypeInfo());

TypeInfo_t *reqti = gInterpreter->TypeInfo_Factory(req_type.c_str());
void *reqqtp = gInterpreter->TypeInfo_QualTypePtr(reqti);

// This scoring is not based on any particular rules
if (gInterpreter->IsSameType(argqtp, reqqtp))
return 0; // Best match
else if ((gInterpreter->IsSignedIntegerType(argqtp) && gInterpreter->IsSignedIntegerType(reqqtp)) ||
(gInterpreter->IsUnsignedIntegerType(argqtp) && gInterpreter->IsUnsignedIntegerType(reqqtp)) ||
(gInterpreter->IsFloatingType(argqtp) && gInterpreter->IsFloatingType(reqqtp)))
return 1;
else if ((gInterpreter->IsSignedIntegerType(argqtp) && gInterpreter->IsUnsignedIntegerType(reqqtp)) ||
(gInterpreter->IsFloatingType(argqtp) && gInterpreter->IsUnsignedIntegerType(reqqtp)))
return 2;
else if ((gInterpreter->IsIntegerType(argqtp) && gInterpreter->IsIntegerType(reqqtp)))
return 3;
else if ((gInterpreter->IsVoidPointerType(argqtp) && gInterpreter->IsPointerType(reqqtp)))
return 4;
else
return 10; // Penalize heavily for no possible match
}
return INT_MAX; // Method is not valid
}

std::string Cppyy::GetMethodArgDefault(TCppMethod_t method, TCppIndex_t iarg)
{
if (method) {
Expand Down
2 changes: 2 additions & 0 deletions clingwrapper/src/cpp_cppyy.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,8 @@ namespace Cppyy {
RPY_EXPORTED
std::string GetMethodArgType(TCppMethod_t, TCppIndex_t iarg);
RPY_EXPORTED
TCppIndex_t CompareMethodArgType(TCppMethod_t, TCppIndex_t iarg, const std::string &req_type);
RPY_EXPORTED
std::string GetMethodArgDefault(TCppMethod_t, TCppIndex_t iarg);
RPY_EXPORTED
std::string GetMethodSignature(TCppMethod_t, bool show_formalargs, TCppIndex_t maxargs = (TCppIndex_t)-1);
Expand Down

0 comments on commit 25917de

Please sign in to comment.