[clang] [RFC] Initial implementation of P2719 (PR #113510)

via cfe-commits cfe-commits at lists.llvm.org
Thu Jan 30 02:29:59 PST 2025


================
@@ -16147,6 +16169,108 @@ bool Sema::CompleteConstructorCall(CXXConstructorDecl *Constructor,
   return Invalid;
 }
 
+bool Sema::isTypeAwareOperatorNewOrDelete(const NamedDecl *ND) const {
+  const FunctionDecl *FnDecl = nullptr;
+  if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ND))
+    FnDecl = FTD->getTemplatedDecl();
+  else if (auto *FD = dyn_cast<FunctionDecl>(ND))
+    FnDecl = FD;
+
+  return FnDecl->isTypeAwareOperatorNewOrDelete();
+}
+
+FunctionDecl *
+Sema::instantiateTypeAwareUsualDelete(FunctionTemplateDecl *FnTemplateDecl,
+                                      QualType DeallocType) {
+  if (!getLangOpts().TypeAwareAllocators)
+    return nullptr;
+
+  TemplateParameterList *TemplateParameters =
+      FnTemplateDecl->getTemplateParameters();
+  if (TemplateParameters->hasParameterPack())
+    return nullptr;
+
+  FunctionDecl *FnDecl = FnTemplateDecl->getTemplatedDecl();
+  if (!FnDecl->isTypeAwareOperatorNewOrDelete())
+    return nullptr;
+
+  if (FnDecl->isVariadic())
+    return nullptr;
+
+  unsigned NumParams = FnDecl->getNumParams();
+  if (NumParams < 2)
+    return nullptr;
+
+  for (size_t Idx = 1; Idx < NumParams; ++Idx) {
+    // A type aware allocation is only usual if the only dependent parameter is
+    // the first parameter.
+    const ParmVarDecl *ParamDecl = FnDecl->getParamDecl(Idx);
+    if (ParamDecl->getType()->isDependentType())
+      return nullptr;
+  }
+
+  QualType SpecializedTypeIdentity =
+      instantiateSpecializedTypeIdentity(DeallocType);
+  if (SpecializedTypeIdentity.isNull())
+    return nullptr;
+  SmallVector<QualType, 4> ArgTypes;
+  ArgTypes.reserve(NumParams);
+  ArgTypes.push_back(SpecializedTypeIdentity);
+  ArgTypes.push_back(FnDecl->getParamDecl(1)->getType());
+  unsigned UsualParamsIdx = 2;
+  if (UsualParamsIdx < NumParams && FnDecl->isDestroyingOperatorDelete()) {
+    QualType Type = FnDecl->getParamDecl(UsualParamsIdx)->getType();
+    ArgTypes.push_back(Type);
+    ++UsualParamsIdx;
+  }
+
+  if (UsualParamsIdx < NumParams) {
+    QualType Type = FnDecl->getParamDecl(UsualParamsIdx)->getType();
+    if (Context.hasSameUnqualifiedType(Type, Context.getSizeType())) {
+      ArgTypes.push_back(Type);
+      ++UsualParamsIdx;
+    }
+  }
+
+  if (UsualParamsIdx < NumParams) {
+    QualType Type = FnDecl->getParamDecl(UsualParamsIdx)->getType();
+    if (Type->isAlignValT()) {
+      ArgTypes.push_back(Type);
+      ++UsualParamsIdx;
+    }
+  }
+
+  if (UsualParamsIdx != NumParams)
+    return nullptr;
+
+  FunctionProtoType::ExtProtoInfo EPI;
+  QualType ExpectedFunctionType =
+      Context.getFunctionType(Context.VoidTy, ArgTypes, EPI);
+  SourceLocation Loc;
+  sema::TemplateDeductionInfo Info(Loc);
+  FunctionDecl *Result;
+  if (DeduceTemplateArguments(FnTemplateDecl, nullptr, ExpectedFunctionType,
+                              Result, Info) != TemplateDeductionResult::Success)
+    return nullptr;
+  return Result;
+}
+
+QualType Sema::instantiateSpecializedTypeIdentity(QualType Subject) {
+  assert(getLangOpts().TypeAwareAllocators);
+  ClassTemplateDecl *TypeIdentity = getStdTypeIdentity();
+  if (!TypeIdentity)
+    return QualType();
+
+  auto TN = TemplateName(TypeIdentity);
+  TemplateArgumentListInfo Arguments;
+  Arguments.addArgument(getTrivialTemplateArgumentLoc(
+      TemplateArgument(Subject), QualType(), SourceLocation()));
+  QualType Result = CheckTemplateIdType(TN, SourceLocation(), Arguments);
+  if (Result.isNull())
+    return QualType();
+  return Result;
----------------
cor3ntin wrote:

```suggestion
     return Result;
```

https://github.com/llvm/llvm-project/pull/113510


More information about the cfe-commits mailing list