Repository: llvm/llvm-project
File: clang/lib/CodeGen/ItaniumCXXABI.cpp (C++)

Code before:
    ThunkFn->setVisibility(llvm::GlobalValue::HiddenVisibility);
  assert(ThunkFn->getName() == ThunkName && "name was uniqued!");

  CGM.SetLLVMFunctionAttributes(MD, FnInfo, ThunkFn, /*IsThunk=*/true);
  CGM.SetLLVMFunctionAttributesForDefinition(MD, ThunkFn);

  // Stack protection sometimes gets inserted after the musttail call.
  ThunkFn->removeFnAttr(llvm::Attribute::StackProtect);
  ThunkFn->removeFnAttr(llvm::Attribute::StackProtectStrong);
  ThunkFn->removeFnAttr(llvm::Attribute::StackProtectReq);

  // Start codegen.
  CodeGenFunction CGF(CGM);
  CGF.CurGD = GlobalDecl(MD);
  CGF.CurFuncIsThunk = true;

  // Build FunctionArgs.
  FunctionArgList FunctionArgs;
  CGF.BuildFunctionArgList(CGF.CurGD, FunctionArgs);

  CGF.StartFunction(GlobalDecl(), FnInfo.getReturnType(), ThunkFn, FnInfo,
                    FunctionArgs, MD->getLocation(), SourceLocation());

  // Emit an artificial location for this function.
  auto AL = ApplyDebugLocation::CreateArtificial(CGF);

  llvm::Value *ThisVal = loadIncomingCXXThis(CGF);
  setCXXABIThisValue(CGF, ThisVal);

  CallArgList CallArgs;
  for (const VarDecl *VD : FunctionArgs)
    CGF.EmitDelegateCallArg(CallArgs, VD, SourceLocation());

  const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
  RequiredArgs Required = RequiredArgs::forPrototypePlus(FPT, /*this*/ 1);
  const CGFunctionInfo &CallInfo =
      CGM.getTypes().arrangeCXXMethodCall(CallArgs, FPT, Required, 0);
  CGCallee Callee = CGCallee::forVirtual(nullptr, GlobalDecl(MD),
                                         getThisAddress(CGF), ThunkTy);
  llvm::CallBase *CallOrInvoke;
  CGF.EmitCall(CallInfo, Callee, ReturnValueSlot(), CallArgs, &CallOrInvoke,
               /*IsMustTail=*/true, SourceLocation(), true);
  auto *Call = cast<llvm::CallInst>(CallOrInvoke);
  Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
  if (Call->getType()->isVoidTy())
    CGF.Builder.CreateRetVoid();
  else
    CGF.Builder.CreateRet(Call);

  // Finish the function to maintain CodeGenFunction invariants.
  // FIXME: Don't emit unreachable code.

Review comment (suggestion):
Is there really nothing better that we can do? I guess not as anything else would be confusing.

It would be nice if there was a way do say

```cpp
// Compiler generated code
T virtual_member_thunk_for_X(this, ...) {
  return this->virtualFunction(); // You are here
}
```

But that's so very far outside of the scope of this PR :D

Code after:
  if (Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
    ThunkFn->setVisibility(llvm::GlobalValue::HiddenVisibility);
  assert(ThunkFn->getName() == ThunkName && "name was uniqued!");

  CGM.SetLLVMFunctionAttributes(MD, FnInfo, ThunkFn, /*IsThunk=*/true);
  CGM.SetLLVMFunctionAttributesForDefinition(MD, ThunkFn);

  // Stack protection sometimes gets inserted after the musttail call.
  ThunkFn->removeFnAttr(llvm::Attribute::StackProtect);
  ThunkFn->removeFnAttr(llvm::Attribute::StackProtectStrong);
  ThunkFn->removeFnAttr(llvm::Attribute::StackProtectReq);

  // Start codegen.
  CodeGenFunction CGF(CGM);
  CGF.CurGD = GlobalDecl(MD);
  CGF.CurFuncIsThunk = true;

  // Build FunctionArgs.
  FunctionArgList FunctionArgs;
  CGF.BuildFunctionArgList(CGF.CurGD, FunctionArgs);

  CGF.StartFunction(GlobalDecl(), FnInfo.getReturnType(), ThunkFn, FnInfo,
                    FunctionArgs, MD->getLocation(), SourceLocation());

  // Emit an artificial location for this function.
  auto AL = ApplyDebugLocation::CreateArtificial(CGF);

  llvm::Value *ThisVal = loadIncomingCXXThis(CGF);
  setCXXABIThisValue(CGF, ThisVal);

  CallArgList CallArgs;
  for (const VarDecl *VD : FunctionArgs)
    CGF.EmitDelegateCallArg(CallArgs, VD, SourceLocation());

  const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
  RequiredArgs Required = RequiredArgs::forPrototypePlus(FPT, /*this*/ 1);
  const CGFunctionInfo &CallInfo =
      CGM.getTypes().arrangeCXXMethodCall(CallArgs, FPT, Required, 0);
  CGCallee Callee = CGCallee::forVirtual(nullptr, GlobalDecl(MD),
                                         getThisAddress(CGF), ThunkTy);
  llvm::CallBase *CallOrInvoke;
  CGF.EmitCall(CallInfo, Callee, ReturnValueSlot(), CallArgs, &CallOrInvoke,
               /*IsMustTail=*/true, SourceLocation(), true);
  auto *Call = cast<llvm::CallInst>(CallOrInvoke);
  Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
  if (Call->getType()->isVoidTy())
    CGF.Builder.CreateRetVoid();
  else
    CGF.Builder.CreateRet(Call);

  // Finish the function to maintain CodeGenFunction invariants.