diff options
| author | Zequan Wu <zequanwu@google.com> | 2025-11-21 17:14:34 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-11-21 17:14:34 -0800 |
| commit | 54a4da9df6906b63878ad6d0ea6da3ed7d2d8432 (patch) | |
| tree | 26d9fa3d54fbec6de66f26ee732881245563f336 /clang/lib | |
| parent | 58e2dde45f775328b71b532e65762a9696ccccbd (diff) | |
Revert "Reland [MS][clang] Add support for vector deleting destructors" (#169116)
This reverts 4d10c1165442cbbbc0017b48fcdd7dae1ccf3678 and its two
dependent commits: e6b9805b574bb5c90263ec7fbcb94df76d2807a4 and
c243406a695ca056a07ef4064b0f9feee7685320, see discussion in
https://github.com/llvm/llvm-project/pull/165598#issuecomment-3563825509.
Diffstat (limited to 'clang/lib')
27 files changed, 70 insertions, 634 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index b929b0fc1aa8..b359fc835037 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -13337,71 +13337,6 @@ bool ASTContext::isTypeAwareOperatorNewOrDelete(const FunctionDecl *FD) const { return TypeAwareOperatorNewAndDeletes.contains(FD->getCanonicalDecl()); } -void ASTContext::addOperatorDeleteForVDtor(const CXXDestructorDecl *Dtor, - FunctionDecl *OperatorDelete, - OperatorDeleteKind K) const { - switch (K) { - case OperatorDeleteKind::Regular: - OperatorDeletesForVirtualDtor[Dtor->getCanonicalDecl()] = OperatorDelete; - break; - case OperatorDeleteKind::GlobalRegular: - GlobalOperatorDeletesForVirtualDtor[Dtor->getCanonicalDecl()] = - OperatorDelete; - break; - case OperatorDeleteKind::Array: - ArrayOperatorDeletesForVirtualDtor[Dtor->getCanonicalDecl()] = - OperatorDelete; - break; - case OperatorDeleteKind::ArrayGlobal: - GlobalArrayOperatorDeletesForVirtualDtor[Dtor->getCanonicalDecl()] = - OperatorDelete; - break; - } -} - -bool ASTContext::dtorHasOperatorDelete(const CXXDestructorDecl *Dtor, - OperatorDeleteKind K) const { - switch (K) { - case OperatorDeleteKind::Regular: - return OperatorDeletesForVirtualDtor.contains(Dtor->getCanonicalDecl()); - case OperatorDeleteKind::GlobalRegular: - return GlobalOperatorDeletesForVirtualDtor.contains( - Dtor->getCanonicalDecl()); - case OperatorDeleteKind::Array: - return ArrayOperatorDeletesForVirtualDtor.contains( - Dtor->getCanonicalDecl()); - case OperatorDeleteKind::ArrayGlobal: - return GlobalArrayOperatorDeletesForVirtualDtor.contains( - Dtor->getCanonicalDecl()); - } - return false; -} - -FunctionDecl * -ASTContext::getOperatorDeleteForVDtor(const CXXDestructorDecl *Dtor, - OperatorDeleteKind K) const { - const CXXDestructorDecl *Canon = Dtor->getCanonicalDecl(); - switch (K) { - case OperatorDeleteKind::Regular: - if (OperatorDeletesForVirtualDtor.contains(Canon)) - return OperatorDeletesForVirtualDtor[Canon]; - return nullptr; - case OperatorDeleteKind::GlobalRegular: - if (GlobalOperatorDeletesForVirtualDtor.contains(Canon)) - return GlobalOperatorDeletesForVirtualDtor[Canon]; - return nullptr; - case OperatorDeleteKind::Array: - if (ArrayOperatorDeletesForVirtualDtor.contains(Canon)) - return ArrayOperatorDeletesForVirtualDtor[Canon]; - return nullptr; - case OperatorDeleteKind::ArrayGlobal: - if (GlobalArrayOperatorDeletesForVirtualDtor.contains(Canon)) - return GlobalArrayOperatorDeletesForVirtualDtor[Canon]; - return nullptr; - } - return nullptr; -} - MangleNumberingContext & ASTContext::getManglingNumberContext(const DeclContext *DC) { assert(LangOpts.CPlusPlus); // We don't need mangling numbers for plain C. diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index c16b1bb7a345..24e4f189cbe4 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -3110,15 +3110,12 @@ CXXDestructorDecl *CXXDestructorDecl::Create( } void CXXDestructorDecl::setOperatorDelete(FunctionDecl *OD, Expr *ThisArg) { - assert(!OD || (OD->getDeclName().getCXXOverloadedOperator() == OO_Delete)); - if (OD && !getASTContext().dtorHasOperatorDelete( - this, ASTContext::OperatorDeleteKind::Regular)) { - getASTContext().addOperatorDeleteForVDtor( - this, OD, ASTContext::OperatorDeleteKind::Regular); - getCanonicalDecl()->OperatorDeleteThisArg = ThisArg; + auto *First = cast<CXXDestructorDecl>(getFirstDecl()); + if (OD && !First->OperatorDelete) { + First->OperatorDelete = OD; + First->OperatorDeleteThisArg = ThisArg; if (auto *L = getASTMutationListener()) - L->ResolvedOperatorDelete(cast<CXXDestructorDecl>(getCanonicalDecl()), OD, - ThisArg); + L->ResolvedOperatorDelete(First, OD, ThisArg); } } @@ -3130,63 +3127,14 @@ void CXXDestructorDecl::setOperatorGlobalDelete(FunctionDecl *OD) { assert(!OD || (OD->getDeclName().getCXXOverloadedOperator() == OO_Delete && OD->getDeclContext()->getRedeclContext()->isTranslationUnit())); - if (OD && !getASTContext().dtorHasOperatorDelete( - this, ASTContext::OperatorDeleteKind::GlobalRegular)) { - getASTContext().addOperatorDeleteForVDtor( - this, OD, ASTContext::OperatorDeleteKind::GlobalRegular); + auto *Canonical = cast<CXXDestructorDecl>(getCanonicalDecl()); + if (!Canonical->OperatorGlobalDelete) { + Canonical->OperatorGlobalDelete = OD; if (auto *L = getASTMutationListener()) - L->ResolvedOperatorGlobDelete(cast<CXXDestructorDecl>(getCanonicalDecl()), - OD); + L->ResolvedOperatorGlobDelete(Canonical, OD); } } -void CXXDestructorDecl::setOperatorArrayDelete(FunctionDecl *OD) { - assert(!OD || - (OD->getDeclName().getCXXOverloadedOperator() == OO_Array_Delete)); - if (OD && !getASTContext().dtorHasOperatorDelete( - this, ASTContext::OperatorDeleteKind::Array)) { - getASTContext().addOperatorDeleteForVDtor( - this, OD, ASTContext::OperatorDeleteKind::Array); - if (auto *L = getASTMutationListener()) - L->ResolvedOperatorArrayDelete( - cast<CXXDestructorDecl>(getCanonicalDecl()), OD); - } -} - -void CXXDestructorDecl::setGlobalOperatorArrayDelete(FunctionDecl *OD) { - assert(!OD || - (OD->getDeclName().getCXXOverloadedOperator() == OO_Array_Delete && - OD->getDeclContext()->getRedeclContext()->isTranslationUnit())); - if (OD && !getASTContext().dtorHasOperatorDelete( - this, ASTContext::OperatorDeleteKind::ArrayGlobal)) { - getASTContext().addOperatorDeleteForVDtor( - this, OD, ASTContext::OperatorDeleteKind::ArrayGlobal); - if (auto *L = getASTMutationListener()) - L->ResolvedOperatorGlobArrayDelete( - cast<CXXDestructorDecl>(getCanonicalDecl()), OD); - } -} - -const FunctionDecl *CXXDestructorDecl::getOperatorDelete() const { - return getASTContext().getOperatorDeleteForVDtor( - this, ASTContext::OperatorDeleteKind::Regular); -} - -const FunctionDecl *CXXDestructorDecl::getOperatorGlobalDelete() const { - return getASTContext().getOperatorDeleteForVDtor( - this, ASTContext::OperatorDeleteKind::GlobalRegular); -} - -const FunctionDecl *CXXDestructorDecl::getArrayOperatorDelete() const { - return getASTContext().getOperatorDeleteForVDtor( - this, ASTContext::OperatorDeleteKind::Array); -} - -const FunctionDecl *CXXDestructorDecl::getGlobalArrayOperatorDelete() const { - return getASTContext().getOperatorDeleteForVDtor( - this, ASTContext::OperatorDeleteKind::ArrayGlobal); -} - bool CXXDestructorDecl::isCalledByDelete(const FunctionDecl *OpDel) const { // C++20 [expr.delete]p6: If the value of the operand of the delete- // expression is not a null pointer value and the selected deallocation @@ -3198,8 +3146,7 @@ bool CXXDestructorDecl::isCalledByDelete(const FunctionDecl *OpDel) const { // delete operator, as that destructor is never called, unless the // destructor is virtual (see [expr.delete]p8.1) because then the // selected operator depends on the dynamic type of the pointer. - const FunctionDecl *SelectedOperatorDelete = - OpDel ? OpDel : getOperatorDelete(); + const FunctionDecl *SelectedOperatorDelete = OpDel ? OpDel : OperatorDelete; if (!SelectedOperatorDelete) return true; diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 1d914fa87675..340bb4b2ed6a 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -71,9 +71,6 @@ const CXXRecordDecl *Expr::getBestDynamicClassType() const { if (const PointerType *PTy = DerivedType->getAs<PointerType>()) DerivedType = PTy->getPointeeType(); - while (const ArrayType *ATy = DerivedType->getAsArrayTypeUnsafe()) - DerivedType = ATy->getElementType(); - if (DerivedType->isDependentType()) return nullptr; diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index a5bcf5c97e83..5572e0a7ae59 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -6040,8 +6040,6 @@ void CXXNameMangler::mangleCXXDtorType(CXXDtorType T) { case Dtor_Comdat: Out << "D5"; break; - case Dtor_VectorDeleting: - llvm_unreachable("Itanium ABI does not use vector deleting dtors"); } } diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index 551aa7bf3321..f1baf9f49384 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -1492,9 +1492,8 @@ void MicrosoftCXXNameMangler::mangleCXXDtorType(CXXDtorType T) { // <operator-name> ::= ?_G # scalar deleting destructor case Dtor_Deleting: Out << "?_G"; return; // <operator-name> ::= ?_E # vector deleting destructor - case Dtor_VectorDeleting: - Out << "?_E"; - return; + // FIXME: Add a vector deleting dtor type. It goes in the vtable, so we need + // it. case Dtor_Comdat: llvm_unreachable("not expecting a COMDAT"); case Dtor_Unified: @@ -2914,12 +2913,9 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T, // ::= @ # structors (they have no declared return type) if (IsStructor) { if (isa<CXXDestructorDecl>(D) && isStructorDecl(D)) { - // The deleting destructors take an extra argument of type int that - // indicates whether the storage for the object should be deleted and - // whether a single object or an array of objects is being destroyed. This - // extra argument is not reflected in the AST. - if (StructorType == Dtor_Deleting || - StructorType == Dtor_VectorDeleting) { + // The scalar deleting destructor takes an extra int argument which is not + // reflected in the AST. + if (StructorType == Dtor_Deleting) { Out << (PointersAre64Bit ? "PEAXI@Z" : "PAXI@Z"); return; } @@ -3915,10 +3911,10 @@ void MicrosoftMangleContextImpl::mangleCXXDtorThunk(const CXXDestructorDecl *DD, const ThunkInfo &Thunk, bool /*ElideOverrideInfo*/, raw_ostream &Out) { - // The dtor thunk should use vector deleting dtor mangling, however as an - // optimization we may end up emitting only scalar deleting dtor body, so just - // use the vector deleting dtor mangling manually. - assert(Type == Dtor_Deleting || Type == Dtor_VectorDeleting); + // FIXME: Actually, the dtor thunk should be emitted for vector deleting + // dtors rather than scalar deleting dtors. Just use the vector deleting dtor + // mangling manually until we support both deleting dtor types. + assert(Type == Dtor_Deleting); msvc_hashing_ostream MHO(Out); MicrosoftCXXNameMangler Mangler(*this, MHO, DD, Type); Mangler.getStream() << "??_E"; diff --git a/clang/lib/AST/VTableBuilder.cpp b/clang/lib/AST/VTableBuilder.cpp index 9951126c2c3a..3ded3a51206d 100644 --- a/clang/lib/AST/VTableBuilder.cpp +++ b/clang/lib/AST/VTableBuilder.cpp @@ -2658,12 +2658,7 @@ private: MethodVFTableLocation Loc(MI.VBTableIndex, WhichVFPtr.getVBaseWithVPtr(), WhichVFPtr.NonVirtualOffset, MI.VFTableIndex); if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) { - // In Microsoft ABI vftable always references vector deleting dtor. - CXXDtorType DtorTy = Context.getTargetInfo().emitVectorDeletingDtors( - Context.getLangOpts()) - ? Dtor_VectorDeleting - : Dtor_Deleting; - MethodVFTableLocations[GlobalDecl(DD, DtorTy)] = Loc; + MethodVFTableLocations[GlobalDecl(DD, Dtor_Deleting)] = Loc; } else { MethodVFTableLocations[MD] = Loc; } @@ -3293,11 +3288,7 @@ void VFTableBuilder::dumpLayout(raw_ostream &Out) { const CXXDestructorDecl *DD = Component.getDestructorDecl(); DD->printQualifiedName(Out); - if (Context.getTargetInfo().emitVectorDeletingDtors( - Context.getLangOpts())) - Out << "() [vector deleting]"; - else - Out << "() [scalar deleting]"; + Out << "() [scalar deleting]"; if (DD->isPureVirtual()) Out << " [pure]"; @@ -3767,7 +3758,7 @@ void MicrosoftVTableContext::dumpMethodLocations( PredefinedIdentKind::PrettyFunctionNoVirtual, MD); if (isa<CXXDestructorDecl>(MD)) { - IndicesMap[I.second] = MethodName + " [vector deleting]"; + IndicesMap[I.second] = MethodName + " [scalar deleting]"; } else { IndicesMap[I.second] = MethodName; } @@ -3883,8 +3874,7 @@ MicrosoftVTableContext::getMethodVFTableLocation(GlobalDecl GD) { assert(hasVtableSlot(cast<CXXMethodDecl>(GD.getDecl())) && "Only use this method for virtual methods or dtors"); if (isa<CXXDestructorDecl>(GD.getDecl())) - assert(GD.getDtorType() == Dtor_VectorDeleting || - GD.getDtorType() == Dtor_Deleting); + assert(GD.getDtorType() == Dtor_Deleting); GD = GD.getCanonicalDecl(); diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index ffaf98bf9c36..9a5db6e164f6 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -636,13 +636,6 @@ bool TargetInfo::callGlobalDeleteInDeletingDtor( return false; } -bool TargetInfo::emitVectorDeletingDtors(const LangOptions &LangOpts) const { - if (getCXXABI() == TargetCXXABI::Microsoft && - LangOpts.getClangABICompat() > LangOptions::ClangABI::Ver21) - return true; - return false; -} - bool TargetInfo::areDefaultedSMFStillPOD(const LangOptions &LangOpts) const { return LangOpts.getClangABICompat() > LangOptions::ClangABI::Ver15; } diff --git a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp index 28a42121052e..95c96d48bfac 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp @@ -746,13 +746,6 @@ void CIRGenFunction::emitCXXDeleteExpr(const CXXDeleteExpr *e) { deleteTy = getContext().getBaseElementType(deleteTy); ptr = ptr.withElementType(builder, convertTypeForMem(deleteTy)); - if (e->isArrayForm() && - cgm.getASTContext().getTargetInfo().emitVectorDeletingDtors( - cgm.getASTContext().getLangOpts())) { - cgm.errorNYI(e->getSourceRange(), - "emitCXXDeleteExpr: emitVectorDeletingDtors"); - } - if (e->isArrayForm()) { assert(!cir::MissingFeatures::deleteArray()); cgm.errorNYI(e->getSourceRange(), "emitCXXDeleteExpr: array delete"); diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp index 7df650984bdd..33bdfa315a9e 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp @@ -754,9 +754,7 @@ void CIRGenFunction::emitDestructorBody(FunctionArgList &args) { // outside of the function-try-block, which means it's always // possible to delegate the destructor body to the complete // destructor. Do so. - if (dtorType == Dtor_Deleting || dtorType == Dtor_VectorDeleting) { - if (cxxStructorImplicitParamValue && dtorType == Dtor_VectorDeleting) - cgm.errorNYI(dtor->getSourceRange(), "emitConditionalArrayDtorCall"); + if (dtorType == Dtor_Deleting) { RunCleanupsScope dtorEpilogue(*this); enterDtorCleanups(dtor, Dtor_Deleting); if (haveInsertPoint()) { @@ -789,7 +787,6 @@ void CIRGenFunction::emitDestructorBody(FunctionArgList &args) { case Dtor_Comdat: llvm_unreachable("not expecting a COMDAT"); case Dtor_Deleting: - case Dtor_VectorDeleting: llvm_unreachable("already handled deleting case"); case Dtor_Complete: diff --git a/clang/lib/CIR/CodeGen/CIRGenVTables.cpp b/clang/lib/CIR/CodeGen/CIRGenVTables.cpp index 301954405027..36bab625c4dd 100644 --- a/clang/lib/CIR/CodeGen/CIRGenVTables.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenVTables.cpp @@ -145,9 +145,7 @@ mlir::Attribute CIRGenVTables::getVTableComponent( case VTableComponent::CK_FunctionPointer: case VTableComponent::CK_CompleteDtorPointer: case VTableComponent::CK_DeletingDtorPointer: { - GlobalDecl gd = component.getGlobalDecl( - cgm.getASTContext().getTargetInfo().emitVectorDeletingDtors( - cgm.getASTContext().getLangOpts())); + GlobalDecl gd = component.getGlobalDecl(); assert(!cir::MissingFeatures::cudaSupport()); diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp index 8ca53c1b58a9..59aeff6804b6 100644 --- a/clang/lib/CodeGen/CGCXX.cpp +++ b/clang/lib/CodeGen/CGCXX.cpp @@ -174,6 +174,7 @@ bool CodeGenModule::TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D) { // requires explicit comdat support in the IL. if (llvm::GlobalValue::isWeakForLinker(TargetLinkage)) return true; + // Create the alias with no name. auto *Alias = llvm::GlobalAlias::create(AliasValueType, 0, Linkage, "", Aliasee, &getModule()); @@ -199,42 +200,6 @@ bool CodeGenModule::TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D) { return false; } -/// Emit a definition as a global alias for another definition, unconditionally. -void CodeGenModule::EmitDefinitionAsAlias(GlobalDecl AliasDecl, - GlobalDecl TargetDecl) { - - llvm::Type *AliasValueType = getTypes().GetFunctionType(AliasDecl); - - StringRef MangledName = getMangledName(AliasDecl); - llvm::GlobalValue *Entry = GetGlobalValue(MangledName); - if (Entry && !Entry->isDeclaration()) - return; - auto *Aliasee = cast<llvm::GlobalValue>(GetAddrOfGlobal(TargetDecl)); - - // Determine the linkage type for the alias. - llvm::GlobalValue::LinkageTypes Linkage = getFunctionLinkage(AliasDecl); - - // Create the alias with no name. - auto *Alias = llvm::GlobalAlias::create(AliasValueType, 0, Linkage, "", - Aliasee, &getModule()); - // Destructors are always unnamed_addr. - Alias->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); - - if (Entry) { - assert(Entry->getValueType() == AliasValueType && - Entry->getAddressSpace() == Alias->getAddressSpace() && - "declaration exists with different type"); - Alias->takeName(Entry); - Entry->replaceAllUsesWith(Alias); - Entry->eraseFromParent(); - } else { - Alias->setName(MangledName); - } - - // Set any additional necessary attributes for the alias. - SetCommonAttributes(AliasDecl, Alias); -} - llvm::Function *CodeGenModule::codegenCXXStructor(GlobalDecl GD) { const CGFunctionInfo &FnInfo = getTypes().arrangeCXXStructorDeclaration(GD); auto *Fn = cast<llvm::Function>( diff --git a/clang/lib/CodeGen/CGCXXABI.cpp b/clang/lib/CodeGen/CGCXXABI.cpp index 4051cacbbbc1..30e5dc2b6cbd 100644 --- a/clang/lib/CodeGen/CGCXXABI.cpp +++ b/clang/lib/CodeGen/CGCXXABI.cpp @@ -268,20 +268,6 @@ void CGCXXABI::ReadArrayCookie(CodeGenFunction &CGF, Address ptr, numElements = readArrayCookieImpl(CGF, allocAddr, cookieSize); } -void CGCXXABI::ReadArrayCookie(CodeGenFunction &CGF, Address ptr, - QualType eltTy, llvm::Value *&numElements, - llvm::Value *&allocPtr, CharUnits &cookieSize) { - assert(eltTy.isDestructedType()); - - // Derive a char* in the same address space as the pointer. - ptr = ptr.withElementType(CGF.Int8Ty); - - cookieSize = getArrayCookieSizeImpl(eltTy); - Address allocAddr = CGF.Builder.CreateConstInBoundsByteGEP(ptr, -cookieSize); - allocPtr = allocAddr.emitRawPointer(CGF); - numElements = readArrayCookieImpl(CGF, allocAddr, cookieSize); -} - llvm::Value *CGCXXABI::readArrayCookieImpl(CodeGenFunction &CGF, Address ptr, CharUnits cookieSize) { diff --git a/clang/lib/CodeGen/CGCXXABI.h b/clang/lib/CodeGen/CGCXXABI.h index 47090276c56b..2dd320dbda97 100644 --- a/clang/lib/CodeGen/CGCXXABI.h +++ b/clang/lib/CodeGen/CGCXXABI.h @@ -583,12 +583,6 @@ public: QualType ElementType, llvm::Value *&NumElements, llvm::Value *&AllocPtr, CharUnits &CookieSize); - /// Reads the array cookie associated with the given pointer, - /// that should have one. - void ReadArrayCookie(CodeGenFunction &CGF, Address Ptr, QualType ElementType, - llvm::Value *&NumElements, llvm::Value *&AllocPtr, - CharUnits &CookieSize); - /// Return whether the given global decl needs a VTT parameter. virtual bool NeedsVTTParameter(GlobalDecl GD); diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index ced175a9a8f0..f782b0cd17da 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -1442,95 +1442,6 @@ static bool CanSkipVTablePointerInitialization(CodeGenFunction &CGF, return true; } -static void EmitConditionalArrayDtorCall(const CXXDestructorDecl *DD, - CodeGenFunction &CGF, - llvm::Value *ShouldDeleteCondition) { - Address ThisPtr = CGF.LoadCXXThisAddress(); - llvm::BasicBlock *ScalarBB = CGF.createBasicBlock("dtor.scalar"); - llvm::BasicBlock *callDeleteBB = - CGF.createBasicBlock("dtor.call_delete_after_array_destroy"); - llvm::BasicBlock *VectorBB = CGF.createBasicBlock("dtor.vector"); - auto *CondTy = cast<llvm::IntegerType>(ShouldDeleteCondition->getType()); - llvm::Value *CheckTheBitForArrayDestroy = CGF.Builder.CreateAnd( - ShouldDeleteCondition, llvm::ConstantInt::get(CondTy, 2)); - llvm::Value *ShouldDestroyArray = - CGF.Builder.CreateIsNull(CheckTheBitForArrayDestroy); - CGF.Builder.CreateCondBr(ShouldDestroyArray, ScalarBB, VectorBB); - - CGF.EmitBlock(VectorBB); - - llvm::Value *numElements = nullptr; - llvm::Value *allocatedPtr = nullptr; - CharUnits cookieSize; - QualType EltTy = DD->getThisType()->getPointeeType(); - CGF.CGM.getCXXABI().ReadArrayCookie(CGF, ThisPtr, EltTy, numElements, - allocatedPtr, cookieSize); - - // Destroy the elements. - QualType::DestructionKind dtorKind = EltTy.isDestructedType(); - - assert(dtorKind); - assert(numElements && "no element count for a type with a destructor!"); - - CharUnits elementSize = CGF.getContext().getTypeSizeInChars(EltTy); - CharUnits elementAlign = - ThisPtr.getAlignment().alignmentOfArrayElement(elementSize); - - llvm::Value *arrayBegin = ThisPtr.emitRawPointer(CGF); - llvm::Value *arrayEnd = CGF.Builder.CreateInBoundsGEP( - ThisPtr.getElementType(), arrayBegin, numElements, "delete.end"); - - // We already checked that the array is not 0-length before entering vector - // deleting dtor. - CGF.emitArrayDestroy(arrayBegin, arrayEnd, EltTy, elementAlign, - CGF.getDestroyer(dtorKind), - /*checkZeroLength*/ false, CGF.needsEHCleanup(dtorKind)); - - llvm::BasicBlock *VectorBBCont = CGF.createBasicBlock("dtor.vector.cont"); - CGF.EmitBlock(VectorBBCont); - - llvm::Value *CheckTheBitForDeleteCall = CGF.Builder.CreateAnd( - ShouldDeleteCondition, llvm::ConstantInt::get(CondTy, 1)); - - llvm::Value *ShouldCallDelete = - CGF.Builder.CreateIsNull(CheckTheBitForDeleteCall); - CGF.Builder.CreateCondBr(ShouldCallDelete, CGF.ReturnBlock.getBlock(), - callDeleteBB); - CGF.EmitBlock(callDeleteBB); - const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CGF.CurCodeDecl); - const CXXRecordDecl *ClassDecl = Dtor->getParent(); - assert(Dtor->getArrayOperatorDelete()); - if (!Dtor->getGlobalArrayOperatorDelete()) { - CGF.EmitDeleteCall(Dtor->getArrayOperatorDelete(), allocatedPtr, - CGF.getContext().getCanonicalTagType(ClassDecl)); - } else { - // If global operator[] is set, the class had its own operator delete[]. - // In that case, check the 4th bit. If it is set, we need to call - // ::delete[]. - llvm::Value *CheckTheBitForGlobDeleteCall = CGF.Builder.CreateAnd( - ShouldDeleteCondition, llvm::ConstantInt::get(CondTy, 4)); - - llvm::Value *ShouldCallGlobDelete = - CGF.Builder.CreateIsNull(CheckTheBitForGlobDeleteCall); - llvm::BasicBlock *GlobDelete = - CGF.createBasicBlock("dtor.call_glob_delete_after_array_destroy"); - llvm::BasicBlock *ClassDelete = - CGF.createBasicBlock("dtor.call_class_delete_after_array_destroy"); - CGF.Builder.CreateCondBr(ShouldCallGlobDelete, ClassDelete, GlobDelete); - CGF.EmitBlock(ClassDelete); - CGF.EmitDeleteCall(Dtor->getArrayOperatorDelete(), allocatedPtr, - CGF.getContext().getCanonicalTagType(ClassDecl)); - CGF.EmitBranchThroughCleanup(CGF.ReturnBlock); - - CGF.EmitBlock(GlobDelete); - CGF.EmitDeleteCall(Dtor->getGlobalArrayOperatorDelete(), allocatedPtr, - CGF.getContext().getCanonicalTagType(ClassDecl)); - } - - CGF.EmitBranchThroughCleanup(CGF.ReturnBlock); - CGF.EmitBlock(ScalarBB); -} - /// EmitDestructorBody - Emits the body of the current destructor. void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) { const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CurGD.getDecl()); @@ -1560,9 +1471,7 @@ void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) { // outside of the function-try-block, which means it's always // possible to delegate the destructor body to the complete // destructor. Do so. - if (DtorType == Dtor_Deleting || DtorType == Dtor_VectorDeleting) { - if (CXXStructorImplicitParamValue && DtorType == Dtor_VectorDeleting) - EmitConditionalArrayDtorCall(Dtor, *this, CXXStructorImplicitParamValue); + if (DtorType == Dtor_Deleting) { RunCleanupsScope DtorEpilogue(*this); EnterDtorCleanups(Dtor, Dtor_Deleting); if (HaveInsertPoint()) { @@ -1593,8 +1502,6 @@ void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) { llvm_unreachable("not expecting a unified dtor"); case Dtor_Comdat: llvm_unreachable("not expecting a COMDAT"); case Dtor_Deleting: llvm_unreachable("already handled deleting case"); - case Dtor_VectorDeleting: - llvm_unreachable("already handled vector deleting case"); case Dtor_Complete: assert((Body || getTarget().getCXXABI().isMicrosoft()) && diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 1489b5116e6c..4eb99cc34227 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -2363,13 +2363,7 @@ llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction( // Emit MS ABI vftable information. There is only one entry for the // deleting dtor. const auto *DD = dyn_cast<CXXDestructorDecl>(Method); - GlobalDecl GD = - DD ? GlobalDecl( - DD, CGM.getContext().getTargetInfo().emitVectorDeletingDtors( - CGM.getContext().getLangOpts()) - ? Dtor_VectorDeleting - : Dtor_Deleting) - : GlobalDecl(Method); + GlobalDecl GD = DD ? GlobalDecl(DD, Dtor_Deleting) : GlobalDecl(Method); MethodVFTableLocation ML = CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD); VIndex = ML.Index; diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp index f64cf9f8a6c2..14d8db32bafc 100644 --- a/clang/lib/CodeGen/CGExprCXX.cpp +++ b/clang/lib/CodeGen/CGExprCXX.cpp @@ -1206,16 +1206,6 @@ void CodeGenFunction::EmitNewArrayInitializer( EmitCXXAggrConstructorCall(Ctor, NumElements, CurPtr, CCE, /*NewPointerIsChecked*/true, CCE->requiresZeroInitialization()); - - // For MSVC vector deleting destructors support we record that for the class - // new[] was called. We try to optimize the code size and only emit vector - // deleting destructors when they are required. Vector deleting destructors - // are required for delete[] call but MSVC triggers emission of them - // whenever new[] is called for an object of the class and we do the same - // for compatibility. - if (CGM.getContext().getTargetInfo().emitVectorDeletingDtors( - CGM.getContext().getLangOpts())) - CGM.requireVectorDestructorDefinition(Ctor->getParent()); return; } @@ -1922,8 +1912,10 @@ static void EmitDestroyingObjectDelete(CodeGenFunction &CGF, /// Emit the code for deleting a single object. /// \return \c true if we started emitting UnconditionalDeleteBlock, \c false /// if not. -static bool EmitObjectDelete(CodeGenFunction &CGF, const CXXDeleteExpr *DE, - Address Ptr, QualType ElementType, +static bool EmitObjectDelete(CodeGenFunction &CGF, + const CXXDeleteExpr *DE, + Address Ptr, + QualType ElementType, llvm::BasicBlock *UnconditionalDeleteBlock) { // C++11 [expr.delete]p3: // If the static type of the object to be deleted is different from its @@ -2117,42 +2109,6 @@ void CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) { DeleteTy = getContext().getBaseElementType(DeleteTy); Ptr = Ptr.withElementType(ConvertTypeForMem(DeleteTy)); - if (E->isArrayForm() && - CGM.getContext().getTargetInfo().emitVectorDeletingDtors( - CGM.getContext().getLangOpts())) { - if (auto *RD = DeleteTy->getAsCXXRecordDecl()) { - auto *Dtor = RD->getDestructor(); - if (Dtor && Dtor->isVirtual()) { - llvm::Value *NumElements = nullptr; - llvm::Value *AllocatedPtr = nullptr; - CharUnits CookieSize; - llvm::BasicBlock *BodyBB = createBasicBlock("vdtor.call"); - llvm::BasicBlock *DoneBB = createBasicBlock("vdtor.nocall"); - // Check array cookie to see if the array has length 0. Don't call - // the destructor in that case. - CGM.getCXXABI().ReadArrayCookie(*this, Ptr, E, DeleteTy, NumElements, - AllocatedPtr, CookieSize); - - auto *CondTy = cast<llvm::IntegerType>(NumElements->getType()); - llvm::Value *IsEmpty = Builder.CreateICmpEQ( - NumElements, llvm::ConstantInt::get(CondTy, 0)); - Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB); - - // Delete cookie for empty array. - const FunctionDecl *OperatorDelete = E->getOperatorDelete(); - EmitBlock(DoneBB); - EmitDeleteCall(OperatorDelete, AllocatedPtr, DeleteTy, NumElements, - CookieSize); - EmitBranch(DeleteEnd); - - EmitBlock(BodyBB); - if (!EmitObjectDelete(*this, E, Ptr, DeleteTy, DeleteEnd)) - EmitBlock(DeleteEnd); - return; - } - } - } - if (E->isArrayForm()) { EmitArrayDelete(*this, E, Ptr, DeleteTy); EmitBlock(DeleteEnd); diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp index c95bd9a3067a..3fbac308a917 100644 --- a/clang/lib/CodeGen/CGVTables.cpp +++ b/clang/lib/CodeGen/CGVTables.cpp @@ -775,9 +775,7 @@ void CodeGenVTables::addVTableComponent(ConstantArrayBuilder &builder, case VTableComponent::CK_FunctionPointer: case VTableComponent::CK_CompleteDtorPointer: case VTableComponent::CK_DeletingDtorPointer: { - GlobalDecl GD = component.getGlobalDecl( - CGM.getContext().getTargetInfo().emitVectorDeletingDtors( - CGM.getContext().getLangOpts())); + GlobalDecl GD = component.getGlobalDecl(); const bool IsThunk = nextVTableThunkIndex < layout.vtable_thunks().size() && diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 4bd3e4f8c02c..645b78a599f8 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -8288,53 +8288,3 @@ void CodeGenModule::moveLazyEmissionStates(CodeGenModule *NewBuilder) { NewBuilder->ABI->MangleCtx = std::move(ABI->MangleCtx); } - -bool CodeGenModule::classNeedsVectorDestructor(const CXXRecordDecl *RD) { - if (!Context.getTargetInfo().emitVectorDeletingDtors(Context.getLangOpts())) - return false; - CXXDestructorDecl *Dtor = RD->getDestructor(); - // The compiler can't know if new[]/delete[] will be used outside of the DLL, - // so just force vector deleting destructor emission if dllexport is present. - // This matches MSVC behavior. - if (Dtor && Dtor->isVirtual() && Dtor->isDefined() && - Dtor->hasAttr<DLLExportAttr>()) - return true; - - return RequireVectorDeletingDtor.count(RD); -} - -void CodeGenModule::requireVectorDestructorDefinition(const CXXRecordDecl *RD) { - if (!Context.getTargetInfo().emitVectorDeletingDtors(Context.getLangOpts())) - return; - RequireVectorDeletingDtor.insert(RD); - - // To reduce code size in general case we lazily emit scalar deleting - // destructor definition and an alias from vector deleting destructor to - // scalar deleting destructor. It may happen that we first emitted the scalar - // deleting destructor definition and the alias and then discovered that the - // definition of the vector deleting destructor is required. Then we need to - // remove the alias and the scalar deleting destructor and queue vector - // deleting destructor body for emission. Check if that is the case. - CXXDestructorDecl *DtorD = RD->getDestructor(); - GlobalDecl ScalarDtorGD(DtorD, Dtor_Deleting); - StringRef MangledName = getMangledName(ScalarDtorGD); - llvm::GlobalValue *Entry = GetGlobalValue(MangledName); - if (Entry && !Entry->isDeclaration()) { - GlobalDecl VectorDtorGD(DtorD, Dtor_VectorDeleting); - StringRef VDName = getMangledName(VectorDtorGD); - llvm::GlobalValue *VDEntry = GetGlobalValue(VDName); - // It exists and it should be an alias. - assert(VDEntry && isa<llvm::GlobalAlias>(VDEntry)); - auto *NewFn = llvm::Function::Create( - cast<llvm::FunctionType>(VDEntry->getValueType()), - llvm::Function::ExternalLinkage, VDName, &getModule()); - SetFunctionAttributes(VectorDtorGD, NewFn, /*IsIncompleteFunction*/ false, - /*IsThunk*/ false); - NewFn->takeName(VDEntry); - VDEntry->replaceAllUsesWith(NewFn); - VDEntry->eraseFromParent(); - Entry->replaceAllUsesWith(NewFn); - Entry->eraseFromParent(); - addDeferredDeclToEmit(VectorDtorGD); - } -} diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 2acfc83338a0..a253bcda2d06 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -529,9 +529,6 @@ private: /// that we don't re-emit the initializer. llvm::DenseMap<const Decl*, unsigned> DelayedCXXInitPosition; - /// To remember which types did require a vector deleting dtor. - llvm::SmallPtrSet<const CXXRecordDecl *, 16> RequireVectorDeletingDtor; - typedef std::pair<OrderGlobalInitsOrStermFinalizers, llvm::Function *> GlobalInitData; @@ -1550,7 +1547,6 @@ public: void EmitGlobal(GlobalDecl D); bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D); - void EmitDefinitionAsAlias(GlobalDecl Alias, GlobalDecl Target); llvm::GlobalValue *GetGlobalValue(StringRef Ref); @@ -1828,8 +1824,6 @@ public: // behavior. So projects like the Linux kernel can rely on it. return !getLangOpts().CPlusPlus; } - void requireVectorDestructorDefinition(const CXXRecordDecl *RD); - bool classNeedsVectorDestructor(const CXXRecordDecl *RD); // Helper to get the alignment for a variable. unsigned getVtableGlobalVarAlignment(const VarDecl *D = nullptr) { diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index 82a0acb9cd51..65c47633bc5c 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -93,8 +93,6 @@ public: llvm_unreachable("emitting dtor comdat as function?"); case Dtor_Unified: llvm_unreachable("emitting unified dtor as function?"); - case Dtor_VectorDeleting: - llvm_unreachable("unexpected dtor kind for this ABI"); } llvm_unreachable("bad dtor kind"); } @@ -460,8 +458,7 @@ public: if (!IsInlined) continue; - StringRef Name = CGM.getMangledName( - VtableComponent.getGlobalDecl(/*HasVectorDeletingDtors=*/false)); + StringRef Name = CGM.getMangledName(VtableComponent.getGlobalDecl()); auto *Entry = CGM.GetGlobalValue(Name); // This checks if virtual inline function has already been emitted. // Note that it is possible that this inline function would be emitted diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp index 11ca94f03cb9..71e24491f19a 100644 --- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp @@ -71,8 +71,8 @@ public: switch (GD.getDtorType()) { case Dtor_Complete: case Dtor_Deleting: - case Dtor_VectorDeleting: return true; + case Dtor_Base: return false; @@ -269,11 +269,7 @@ public: // There's only Dtor_Deleting in vftable but it shares the this // adjustment with the base one, so look up the deleting one instead. - LookupGD = GlobalDecl( - DD, CGM.getContext().getTargetInfo().emitVectorDeletingDtors( - CGM.getContext().getLangOpts()) - ? Dtor_VectorDeleting - : Dtor_Deleting); + LookupGD = GlobalDecl(DD, Dtor_Deleting); } MethodVFTableLocation ML = CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD); @@ -355,9 +351,8 @@ public: void adjustCallArgsForDestructorThunk(CodeGenFunction &CGF, GlobalDecl GD, CallArgList &CallArgs) override { - assert((GD.getDtorType() == Dtor_VectorDeleting || - GD.getDtorType() == Dtor_Deleting) && - "Only vector deleting destructor thunks are available in this ABI"); + assert(GD.getDtorType() == Dtor_Deleting && + "Only deleting destructor thunks are available in this ABI"); CallArgs.add(RValue::get(getStructorImplicitParamValue(CGF)), getContext().IntTy); } @@ -1112,8 +1107,7 @@ bool MicrosoftCXXABI::HasThisReturn(GlobalDecl GD) const { static bool isDeletingDtor(GlobalDecl GD) { return isa<CXXDestructorDecl>(GD.getDecl()) && - (GD.getDtorType() == Dtor_Deleting || - GD.getDtorType() == Dtor_VectorDeleting); + GD.getDtorType() == Dtor_Deleting; } bool MicrosoftCXXABI::hasMostDerivedReturn(GlobalDecl GD) const { @@ -1366,8 +1360,7 @@ MicrosoftCXXABI::buildStructorSignature(GlobalDecl GD, AddedStructorArgCounts Added; // TODO: 'for base' flag if (isa<CXXDestructorDecl>(GD.getDecl()) && - (GD.getDtorType() == Dtor_Deleting || - GD.getDtorType() == Dtor_VectorDeleting)) { + GD.getDtorType() == Dtor_Deleting) { // The scalar deleting destructor takes an implicit int parameter. ArgTys.push_back(getContext().IntTy); ++Added.Suffix; @@ -1399,7 +1392,7 @@ void MicrosoftCXXABI::setCXXDestructorDLLStorage(llvm::GlobalValue *GV, CXXDtorType DT) const { // Deleting destructor variants are never imported or exported. Give them the // default storage class. - if (DT == Dtor_Deleting || DT == Dtor_VectorDeleting) { + if (DT == Dtor_Deleting) { GV->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass); } else { const NamedDecl *ND = Dtor; @@ -1435,12 +1428,6 @@ llvm::GlobalValue::LinkageTypes MicrosoftCXXABI::getCXXDestructorLinkage( return llvm::GlobalValue::LinkOnceODRLinkage; case Dtor_Unified: llvm_unreachable("MS C++ ABI does not support unified dtors"); - case Dtor_VectorDeleting: - // Use the weak, non-ODR linkage for vector deleting destructors to block - // inlining. This enables an MS ABI code-size saving optimization that - // allows us to avoid emitting array deletion code when arrays of a given - // type are not allocated within the final linkage unit. - return llvm::GlobalValue::WeakAnyLinkage; case Dtor_Comdat: llvm_unreachable("MS C++ ABI does not support comdat dtors"); } @@ -1472,11 +1459,7 @@ MicrosoftCXXABI::getVirtualFunctionPrologueThisAdjustment(GlobalDecl GD) { // There's no Dtor_Base in vftable but it shares the this adjustment with // the deleting one, so look it up instead. - GD = - GlobalDecl(DD, CGM.getContext().getTargetInfo().emitVectorDeletingDtors( - CGM.getContext().getLangOpts()) - ? Dtor_VectorDeleting - : Dtor_Deleting); + GD = GlobalDecl(DD, Dtor_Deleting); } MethodVFTableLocation ML = @@ -1525,11 +1508,7 @@ Address MicrosoftCXXABI::adjustThisArgumentForVirtualFunctionCall( // There's only Dtor_Deleting in vftable but it shares the this adjustment // with the base one, so look up the deleting one instead. - LookupGD = - GlobalDecl(DD, CGM.getContext().getTargetInfo().emitVectorDeletingDtors( - CGM.getContext().getLangOpts()) - ? Dtor_VectorDeleting - : Dtor_Deleting); + LookupGD = GlobalDecl(DD, Dtor_Deleting); } MethodVFTableLocation ML = CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD); @@ -2039,30 +2018,24 @@ llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall( auto *CE = dyn_cast<const CXXMemberCallExpr *>(E); auto *D = dyn_cast<const CXXDeleteExpr *>(E); assert((CE != nullptr) ^ (D != nullptr)); - assert(CE == nullptr || CE->arg_begin() == CE->arg_end()); - assert(DtorType == Dtor_VectorDeleting || DtorType == Dtor_Complete || - DtorType == Dtor_Deleting); + assert(CE == nullptr || CE->arguments().empty()); + assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete); // We have only one destructor in the vftable but can get both behaviors // by passing an implicit int parameter. - ASTContext &Context = getContext(); - bool VectorDeletingDtorsEnabled = - Context.getTargetInfo().emitVectorDeletingDtors(Context.getLangOpts()); - GlobalDecl GD(Dtor, VectorDeletingDtorsEnabled ? Dtor_VectorDeleting - : Dtor_Deleting); + GlobalDecl GD(Dtor, Dtor_Deleting); const CGFunctionInfo *FInfo = &CGM.getTypes().arrangeCXXStructorDeclaration(GD); llvm::FunctionType *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo); CGCallee Callee = CGCallee::forVirtual(CE, GD, This, Ty); + ASTContext &Context = getContext(); bool IsDeleting = DtorType == Dtor_Deleting; - bool IsArrayDelete = D && D->isArrayForm() && VectorDeletingDtorsEnabled; bool IsGlobalDelete = D && D->isGlobalDelete() && Context.getTargetInfo().callGlobalDeleteInDeletingDtor( Context.getLangOpts()); llvm::Value *ImplicitParam = - CGF.Builder.getInt32((IsDeleting ? 1 : 0) | (IsGlobalDelete ? 4 : 0) | - (IsArrayDelete ? 2 : 0)); + CGF.Builder.getInt32((IsDeleting ? 1 : 0) | (IsGlobalDelete ? 4 : 0)); QualType ThisTy; if (CE) { @@ -2071,9 +2044,6 @@ llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall( ThisTy = D->getDestroyedType(); } - while (const ArrayType *ATy = Context.getAsArrayType(ThisTy)) - ThisTy = ATy->getElementType(); - This = adjustThisArgumentForVirtualFunctionCall(CGF, GD, This, true); RValue RV = CGF.EmitCXXDestructorCall(GD, Callee, This.emitRawPointer(CGF), ThisTy, @@ -4104,18 +4074,6 @@ void MicrosoftCXXABI::emitCXXStructor(GlobalDecl GD) { if (GD.getDtorType() == Dtor_Base && !CGM.TryEmitBaseDestructorAsAlias(dtor)) return; - if (GD.getDtorType() == Dtor_VectorDeleting && - !CGM.classNeedsVectorDestructor(dtor->getParent())) { - // Create GlobalDecl object with the correct type for the scalar - // deleting destructor. - GlobalDecl ScalarDtorGD(dtor, Dtor_Deleting); - - // Emit an alias from the vector deleting destructor to the scalar deleting - // destructor. - CGM.EmitDefinitionAsAlias(GD, ScalarDtorGD); - return; - } - llvm::Function *Fn = CGM.codegenCXXStructor(GD); if (Fn->isWeakForLinker()) Fn->setComdat(CGM.getModule().getOrInsertComdat(Fn->getName())); diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index aa36a79142e5..8030aac3d877 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -11139,11 +11139,9 @@ bool Sema::CheckDestructor(CXXDestructorDecl *Destructor) { else Loc = RD->getLocation(); - DeclarationName Name = - Context.DeclarationNames.getCXXOperatorName(OO_Delete); // If we have a virtual destructor, look up the deallocation function if (FunctionDecl *OperatorDelete = FindDeallocationFunctionForDestructor( - Loc, RD, /*Diagnose=*/true, /*LookForGlobal=*/false, Name)) { + Loc, RD, /*Diagnose=*/true, /*LookForGlobal=*/false)) { Expr *ThisArg = nullptr; // If the notional 'delete this' expression requires a non-trivial @@ -11191,33 +11189,9 @@ bool Sema::CheckDestructor(CXXDestructorDecl *Destructor) { // delete calls that require it. FunctionDecl *GlobalOperatorDelete = FindDeallocationFunctionForDestructor(Loc, RD, /*Diagnose*/ false, - /*LookForGlobal*/ true, Name); + /*LookForGlobal*/ true); Destructor->setOperatorGlobalDelete(GlobalOperatorDelete); } - - if (Context.getTargetInfo().emitVectorDeletingDtors( - Context.getLangOpts())) { - // Lookup delete[] too in case we have to emit a vector deleting dtor. - DeclarationName VDeleteName = - Context.DeclarationNames.getCXXOperatorName(OO_Array_Delete); - FunctionDecl *ArrOperatorDelete = FindDeallocationFunctionForDestructor( - Loc, RD, /*Diagnose*/ false, - /*LookForGlobal*/ false, VDeleteName); - if (ArrOperatorDelete && isa<CXXMethodDecl>(ArrOperatorDelete)) { - FunctionDecl *GlobalArrOperatorDelete = - FindDeallocationFunctionForDestructor(Loc, RD, /*Diagnose*/ false, - /*LookForGlobal*/ true, - VDeleteName); - Destructor->setGlobalOperatorArrayDelete(GlobalArrOperatorDelete); - } else if (!ArrOperatorDelete) { - ArrOperatorDelete = FindDeallocationFunctionForDestructor( - Loc, RD, /*Diagnose*/ false, - /*LookForGlobal*/ true, VDeleteName); - } - assert(ArrOperatorDelete && - "Should've found at least global array delete"); - Destructor->setOperatorArrayDelete(ArrOperatorDelete); - } } } diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 3157119dd453..43bcb4f743cf 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -3612,9 +3612,11 @@ Sema::FindUsualDeallocationFunction(SourceLocation StartLoc, return Result.FD; } -FunctionDecl *Sema::FindDeallocationFunctionForDestructor( - SourceLocation Loc, CXXRecordDecl *RD, bool Diagnose, bool LookForGlobal, - DeclarationName Name) { +FunctionDecl *Sema::FindDeallocationFunctionForDestructor(SourceLocation Loc, + CXXRecordDecl *RD, + bool Diagnose, + bool LookForGlobal) { + DeclarationName Name = Context.DeclarationNames.getCXXOperatorName(OO_Delete); FunctionDecl *OperatorDelete = nullptr; CanQualType DeallocType = Context.getCanonicalTagType(RD); @@ -3647,11 +3649,8 @@ bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD, // Try to find operator delete/operator delete[] in class scope. LookupQualifiedName(Found, RD); - if (Found.isAmbiguous()) { - if (!Diagnose) - Found.suppressDiagnostics(); + if (Found.isAmbiguous()) return true; - } Found.suppressDiagnostics(); diff --git a/clang/lib/Serialization/ASTCommon.h b/clang/lib/Serialization/ASTCommon.h index 23d3954f257e..c9b9b1bbf874 100644 --- a/clang/lib/Serialization/ASTCommon.h +++ b/clang/lib/Serialization/ASTCommon.h @@ -42,9 +42,7 @@ enum class DeclUpdateKind { DeclMarkedOpenMPDeclareTarget, DeclExported, AddedAttrToRecord, - CXXResolvedDtorGlobDelete, - CXXResolvedDtorArrayDelete, - CXXResolvedDtorGlobArrayDelete + CXXResolvedDtorGlobDelete }; TypeIdx TypeIdxFromBuiltin(const BuiltinType *BT); diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 0ee8c3511527..5456e7395665 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -2339,33 +2339,19 @@ void ASTDeclReader::VisitCXXConstructorDecl(CXXConstructorDecl *D) { void ASTDeclReader::VisitCXXDestructorDecl(CXXDestructorDecl *D) { VisitCXXMethodDecl(D); - ASTContext &C = Reader.getContext(); - CXXDestructorDecl *Canon = cast<CXXDestructorDecl>(D->getCanonicalDecl()); + CXXDestructorDecl *Canon = D->getCanonicalDecl(); if (auto *OperatorDelete = readDeclAs<FunctionDecl>()) { auto *ThisArg = Record.readExpr(); // FIXME: Check consistency if we have an old and new operator delete. - if (!C.dtorHasOperatorDelete(D, ASTContext::OperatorDeleteKind::Regular)) { - C.addOperatorDeleteForVDtor(D, OperatorDelete, - ASTContext::OperatorDeleteKind::Regular); + if (!Canon->OperatorDelete) { + Canon->OperatorDelete = OperatorDelete; Canon->OperatorDeleteThisArg = ThisArg; } } if (auto *OperatorGlobDelete = readDeclAs<FunctionDecl>()) { - if (!C.dtorHasOperatorDelete(D, - ASTContext::OperatorDeleteKind::GlobalRegular)) - C.addOperatorDeleteForVDtor( - D, OperatorGlobDelete, ASTContext::OperatorDeleteKind::GlobalRegular); - } - if (auto *OperatorArrayDelete = readDeclAs<FunctionDecl>()) { - if (!C.dtorHasOperatorDelete(D, ASTContext::OperatorDeleteKind::Array)) - C.addOperatorDeleteForVDtor(D, OperatorArrayDelete, - ASTContext::OperatorDeleteKind::Array); - } - if (auto *OperatorGlobArrayDelete = readDeclAs<FunctionDecl>()) { - if (!C.dtorHasOperatorDelete(D, - ASTContext::OperatorDeleteKind::ArrayGlobal)) - C.addOperatorDeleteForVDtor(D, OperatorGlobArrayDelete, - ASTContext::OperatorDeleteKind::ArrayGlobal); + if (!Canon->OperatorGlobalDelete) { + Canon->OperatorGlobalDelete = OperatorGlobDelete; + } } } @@ -4866,48 +4852,22 @@ void ASTDeclReader::UpdateDecl(Decl *D) { case DeclUpdateKind::CXXResolvedDtorDelete: { // Set the 'operator delete' directly to avoid emitting another update // record. - CXXDestructorDecl *Canon = cast<CXXDestructorDecl>(D->getCanonicalDecl()); - ASTContext &C = Reader.getContext(); auto *Del = readDeclAs<FunctionDecl>(); + auto *First = cast<CXXDestructorDecl>(D->getCanonicalDecl()); auto *ThisArg = Record.readExpr(); - auto *Dtor = cast<CXXDestructorDecl>(D); // FIXME: Check consistency if we have an old and new operator delete. - if (!C.dtorHasOperatorDelete(Dtor, - ASTContext::OperatorDeleteKind::Regular)) { - C.addOperatorDeleteForVDtor(Dtor, Del, - ASTContext::OperatorDeleteKind::Regular); - Canon->OperatorDeleteThisArg = ThisArg; + if (!First->OperatorDelete) { + First->OperatorDelete = Del; + First->OperatorDeleteThisArg = ThisArg; } break; } case DeclUpdateKind::CXXResolvedDtorGlobDelete: { auto *Del = readDeclAs<FunctionDecl>(); - auto *Dtor = cast<CXXDestructorDecl>(D); - ASTContext &C = Reader.getContext(); - if (!C.dtorHasOperatorDelete( - Dtor, ASTContext::OperatorDeleteKind::GlobalRegular)) - C.addOperatorDeleteForVDtor( - Dtor, Del, ASTContext::OperatorDeleteKind::GlobalRegular); - break; - } - case DeclUpdateKind::CXXResolvedDtorArrayDelete: { - auto *Del = readDeclAs<FunctionDecl>(); - auto *Dtor = cast<CXXDestructorDecl>(D); - ASTContext &C = Reader.getContext(); - if (!C.dtorHasOperatorDelete(Dtor, ASTContext::OperatorDeleteKind::Array)) - C.addOperatorDeleteForVDtor(Dtor, Del, - ASTContext::OperatorDeleteKind::Array); - break; - } - case DeclUpdateKind::CXXResolvedDtorGlobArrayDelete: { - auto *Del = readDeclAs<FunctionDecl>(); - auto *Dtor = cast<CXXDestructorDecl>(D); - ASTContext &C = Reader.getContext(); - if (!C.dtorHasOperatorDelete(Dtor, - ASTContext::OperatorDeleteKind::ArrayGlobal)) - C.addOperatorDeleteForVDtor( - Dtor, Del, ASTContext::OperatorDeleteKind::ArrayGlobal); + auto *Canon = cast<CXXDestructorDecl>(D->getCanonicalDecl()); + if (!Canon->OperatorGlobalDelete) + Canon->OperatorGlobalDelete = Del; break; } diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 547497cbd87d..e8c0d3f2b4ee 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -6531,14 +6531,6 @@ void ASTWriter::WriteDeclUpdatesBlocks(ASTContext &Context, Record.AddDeclRef(Update.getDecl()); break; - case DeclUpdateKind::CXXResolvedDtorArrayDelete: - Record.AddDeclRef(Update.getDecl()); - break; - - case DeclUpdateKind::CXXResolvedDtorGlobArrayDelete: - Record.AddDeclRef(Update.getDecl()); - break; - case DeclUpdateKind::CXXResolvedExceptionSpec: { auto prototype = cast<FunctionDecl>(D)->getType()->castAs<FunctionProtoType>(); @@ -7612,34 +7604,6 @@ void ASTWriter::ResolvedOperatorGlobDelete(const CXXDestructorDecl *DD, }); } -void ASTWriter::ResolvedOperatorArrayDelete(const CXXDestructorDecl *DD, - const FunctionDecl *ArrayDelete) { - if (Chain && Chain->isProcessingUpdateRecords()) - return; - assert(!WritingAST && "Already writing the AST!"); - assert(ArrayDelete && "Not given an operator delete"); - if (!Chain) - return; - Chain->forEachImportedKeyDecl(DD, [&](const Decl *D) { - DeclUpdates[D].push_back( - DeclUpdate(DeclUpdateKind::CXXResolvedDtorArrayDelete, ArrayDelete)); - }); -} - -void ASTWriter::ResolvedOperatorGlobArrayDelete( - const CXXDestructorDecl *DD, const FunctionDecl *GlobArrayDelete) { - if (Chain && Chain->isProcessingUpdateRecords()) - return; - assert(!WritingAST && "Already writing the AST!"); - assert(GlobArrayDelete && "Not given an operator delete"); - if (!Chain) - return; - Chain->forEachImportedKeyDecl(DD, [&](const Decl *D) { - DeclUpdates[D].push_back(DeclUpdate( - DeclUpdateKind::CXXResolvedDtorGlobArrayDelete, GlobArrayDelete)); - }); -} - void ASTWriter::CompletedImplicitDefinition(const FunctionDecl *D) { if (Chain && Chain->isProcessingUpdateRecords()) return; assert(!WritingAST && "Already writing the AST!"); diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 89e6d8e2acfe..c9f8797ab973 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -1794,8 +1794,6 @@ void ASTDeclWriter::VisitCXXDestructorDecl(CXXDestructorDecl *D) { if (D->getOperatorDelete()) Record.AddStmt(D->getOperatorDeleteThisArg()); Record.AddDeclRef(D->getOperatorGlobalDelete()); - Record.AddDeclRef(D->getArrayOperatorDelete()); - Record.AddDeclRef(D->getGlobalArrayOperatorDelete()); Code = serialization::DECL_CXX_DESTRUCTOR; } |
