Skip to content
Open
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
33 changes: 20 additions & 13 deletions clang/lib/CodeGen/CGVTables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -586,31 +586,37 @@ llvm::Constant *CodeGenVTables::maybeEmitThunk(GlobalDecl GD,
// CHEERP: If there are virtual bases it is possible that the type of `this` mismatches
// between the existing and new think, but one is directbase of the other.
// We keep the thunk with the most basic `this` type

if (!ThunkFn->hasParamAttribute(thisIndex, llvm::Attribute::ElementType))
ThunkFn->addParamAttr(thisIndex, llvm::Attribute::get(CGM.getLLVMContext(), llvm::Attribute::ElementType, CurrentThisTy));

bool NewIsDirectBase = false;
bool CurrentIsDirectBase = false;
if (!CGM.getTarget().isByteAddressable()) {
// Geth the `this` type. It can be the first or second parameter (if there is a
// Get the `this` type. It can be the first or second parameter (if there is a
// struct return pointer)
llvm::StructType* CurrentThisStructTy = cast<llvm::StructType>(CurrentThisTy);
llvm::StructType* NewThisTy = cast<llvm::StructType>(ThunkFn->getParamAttribute(thisIndex, llvm::Attribute::ElementType).getValueAsType());

// Check if one of the types is directbase of the other (check all the directbase hierarchy)
for (llvm::StructType* I = NewThisTy; I != nullptr; I = I->getDirectBase()) {
if (I == CurrentThisTy) {
NewIsDirectBase = true;
break;
// If the attribute type is the same as current, or doesn't exist, skip the directbase check
if (NewThisTy && NewThisTy != CurrentThisTy) {
// Check if one of the types is directbase of the other (check all the directbase hierarchy)
for (llvm::StructType* I = NewThisTy; I != nullptr; I = I->getDirectBase()) {
if (I == CurrentThisTy) {
NewIsDirectBase = true;
break;
}
}
}
for (llvm::StructType* I = CurrentThisStructTy; I != nullptr; I = I->getDirectBase()) {
if (I == NewThisTy) {
CurrentIsDirectBase = true;
break;
for (llvm::StructType* I = CurrentThisStructTy; I != nullptr; I = I->getDirectBase()) {
if (I == NewThisTy) {
CurrentIsDirectBase = true;
break;
}
}
}
}

if (ThunkFn->getFunctionType() != ThunkFnTy && !NewIsDirectBase) {
llvm::GlobalValue *OldThunkFn = ThunkFn;

// If the types mismatch then we have to rewrite the definition.
assert((OldThunkFn->isDeclaration() || CurrentIsDirectBase) &&
"Shouldn't replace non-declaration");
Expand All @@ -634,6 +640,7 @@ llvm::Constant *CodeGenVTables::maybeEmitThunk(GlobalDecl GD,
OldThunkFn->eraseFromParent();
}


bool ABIHasKeyFunctions = CGM.getTarget().getCXXABI().hasKeyFunctions();
bool UseAvailableExternallyLinkage = ForVTable && ABIHasKeyFunctions;

Expand Down
Loading