summaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
authorZequan Wu <zequanwu@google.com>2025-11-21 17:14:34 -0800
committerGitHub <noreply@github.com>2025-11-21 17:14:34 -0800
commit54a4da9df6906b63878ad6d0ea6da3ed7d2d8432 (patch)
tree26d9fa3d54fbec6de66f26ee732881245563f336 /clang/lib
parent58e2dde45f775328b71b532e65762a9696ccccbd (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')
-rw-r--r--clang/lib/AST/ASTContext.cpp65
-rw-r--r--clang/lib/AST/DeclCXX.cpp73
-rw-r--r--clang/lib/AST/Expr.cpp3
-rw-r--r--clang/lib/AST/ItaniumMangle.cpp2
-rw-r--r--clang/lib/AST/MicrosoftMangle.cpp22
-rw-r--r--clang/lib/AST/VTableBuilder.cpp18
-rw-r--r--clang/lib/Basic/TargetInfo.cpp7
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp7
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenFunction.cpp5
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenVTables.cpp4
-rw-r--r--clang/lib/CodeGen/CGCXX.cpp37
-rw-r--r--clang/lib/CodeGen/CGCXXABI.cpp14
-rw-r--r--clang/lib/CodeGen/CGCXXABI.h6
-rw-r--r--clang/lib/CodeGen/CGClass.cpp95
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.cpp8
-rw-r--r--clang/lib/CodeGen/CGExprCXX.cpp52
-rw-r--r--clang/lib/CodeGen/CGVTables.cpp4
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp50
-rw-r--r--clang/lib/CodeGen/CodeGenModule.h6
-rw-r--r--clang/lib/CodeGen/ItaniumCXXABI.cpp5
-rw-r--r--clang/lib/CodeGen/MicrosoftCXXABI.cpp70
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp30
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp13
-rw-r--r--clang/lib/Serialization/ASTCommon.h4
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp66
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp36
-rw-r--r--clang/lib/Serialization/ASTWriterDecl.cpp2
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;
}