Skip to content

Commit edb91fb

Browse files
committed
Handle virtual destructors in C++ classes
This resolves crashing on virtual destructors if Clang is build with assertions and corrects vtbl indices for tables with destructors. Fixes #240.
1 parent be69d0b commit edb91fb

File tree

2 files changed

+47
-11
lines changed

2 files changed

+47
-11
lines changed

sources/libClangSharp/ClangSharp.cpp

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4693,23 +4693,50 @@ CXCursor clangsharp_Cursor_getVBase(CXCursor C, unsigned i) {
46934693
return clang_getNullCursor();
46944694
}
46954695

4696-
int64_t clangsharp_Cursor_getVtblIdx(CXCursor C) {
4696+
namespace {
4697+
int64_t getVtblIdx(const GlobalDecl& d)
4698+
{
4699+
const CXXMethodDecl* CMD = static_cast<const CXXMethodDecl*>(d.getDecl());
4700+
if (VTableContextBase::hasVtableSlot(CMD)) {
4701+
VTableContextBase* VTC = CMD->getASTContext().getVTableContext();
4702+
4703+
if (MicrosoftVTableContext* MSVTC = dyn_cast<MicrosoftVTableContext>(VTC)) {
4704+
MethodVFTableLocation ML = MSVTC->getMethodVFTableLocation(d);
4705+
return ML.Index;
4706+
}
4707+
4708+
if (ItaniumVTableContext* IVTC = dyn_cast<ItaniumVTableContext>(VTC)) {
4709+
return IVTC->getMethodVTableIndex(d);
4710+
}
4711+
}
4712+
4713+
return -1;
4714+
}
4715+
}
4716+
4717+
int64_t clangsharp_Cursor_getDtorVtblIdx(CXCursor C, CX_DestructorType dtor)
4718+
{
46974719
if (isDeclOrTU(C.kind)) {
46984720
const Decl* D = getCursorDecl(C);
46994721

4700-
if (const CXXMethodDecl* CMD = dyn_cast<CXXMethodDecl>(D)) {
4701-
if (VTableContextBase::hasVtableSlot(CMD)) {
4702-
VTableContextBase* VTC = getASTUnit(getCursorTU(C))->getASTContext().getVTableContext();
4722+
if (const CXXDestructorDecl* CMD = dyn_cast<CXXDestructorDecl>(D)) {
4723+
return getVtblIdx(GlobalDecl(CMD, dtor));
4724+
}
4725+
}
4726+
return -1;
4727+
}
47034728

4704-
if (MicrosoftVTableContext* MSVTC = dyn_cast<MicrosoftVTableContext>(VTC)) {
4705-
MethodVFTableLocation ML = MSVTC->getMethodVFTableLocation(CMD);
4706-
return ML.Index;
4707-
}
4729+
int64_t clangsharp_Cursor_getVtblIdx(CXCursor C) {
4730+
if (isDeclOrTU(C.kind)) {
4731+
const Decl* D = getCursorDecl(C);
47084732

4709-
if (ItaniumVTableContext* IVTC = dyn_cast<ItaniumVTableContext>(VTC)) {
4710-
return IVTC->getMethodVTableIndex(CMD);
4711-
}
4733+
if (const CXXMethodDecl* CMD = dyn_cast<CXXMethodDecl>(D)) {
4734+
int64_t dtorIdx = clangsharp_Cursor_getDtorVtblIdx(C, Deleting);
4735+
if (dtorIdx != -1) {
4736+
return dtorIdx;
47124737
}
4738+
4739+
return getVtblIdx(CMD);
47134740
}
47144741
}
47154742

sources/libClangSharp/ClangSharp.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,13 @@ enum CX_VariableCaptureKind {
202202
CX_VCK_VLAType = clang::CapturedStmt::VCK_VLAType + 1
203203
};
204204

205+
enum CX_DestructorType {
206+
Deleting = clang::Dtor_Deleting,
207+
Complete = clang::Dtor_Complete,
208+
Base = clang::Dtor_Base,
209+
Comdat = clang::Dtor_Comdat
210+
};
211+
205212
struct CX_TemplateArgument {
206213
CXTemplateArgumentKind kind;
207214
int xdata;
@@ -722,6 +729,8 @@ CLANGSHARP_LINKAGE CXCursor clangsharp_Cursor_getUsedContext(CXCursor C);
722729

723730
CLANGSHARP_LINKAGE CXCursor clangsharp_Cursor_getVBase(CXCursor C, unsigned i);
724731

732+
CLANGSHARP_LINKAGE int64_t clangsharp_Cursor_getDtorVtblIdx(CXCursor C, CX_DestructorType dtor);
733+
725734
CLANGSHARP_LINKAGE int64_t clangsharp_Cursor_getVtblIdx(CXCursor C);
726735

727736
CLANGSHARP_LINKAGE void clangsharp_TemplateArgument_dispose(CX_TemplateArgument T);

0 commit comments

Comments
 (0)