|
16 | 16 |
|
17 | 17 | #include "clang/AST/DeclCXX.h" |
18 | 18 | #include "clang/AST/ExprCXX.h" |
| 19 | +#include "clang/Basic/OperatorKinds.h" |
19 | 20 | #include "clang/CIR/MissingFeatures.h" |
20 | 21 |
|
21 | 22 | using namespace clang; |
@@ -648,6 +649,36 @@ static RValue emitNewDeleteCall(CIRGenFunction &cgf, |
648 | 649 | return rv; |
649 | 650 | } |
650 | 651 |
|
| 652 | +RValue CIRGenFunction::emitNewOrDeleteBuiltinCall(const FunctionProtoType *type, |
| 653 | + const CallExpr *callExpr, |
| 654 | + OverloadedOperatorKind op) { |
| 655 | + CallArgList args; |
| 656 | + emitCallArgs(args, type, callExpr->arguments()); |
| 657 | + // Find the allocation or deallocation function that we're calling. |
| 658 | + ASTContext &astContext = getContext(); |
| 659 | + assert(op == OO_New || op == OO_Delete); |
| 660 | + DeclarationName name = astContext.DeclarationNames.getCXXOperatorName(op); |
| 661 | + |
| 662 | + clang::DeclContextLookupResult lookupResult = |
| 663 | + astContext.getTranslationUnitDecl()->lookup(name); |
| 664 | + for (const auto *decl : lookupResult) { |
| 665 | + if (const auto *funcDecl = dyn_cast<FunctionDecl>(decl)) { |
| 666 | + if (astContext.hasSameType(funcDecl->getType(), QualType(type, 0))) { |
| 667 | + if (sanOpts.has(SanitizerKind::AllocToken)) { |
| 668 | + // TODO: Set !alloc_token metadata. |
| 669 | + assert(!cir::MissingFeatures::allocToken()); |
| 670 | + cgm.errorNYI("Alloc token sanitizer not yet supported!"); |
| 671 | + } |
| 672 | + |
| 673 | + // Emit the call to operator new/delete. |
| 674 | + return emitNewDeleteCall(*this, funcDecl, type, args); |
| 675 | + } |
| 676 | + } |
| 677 | + } |
| 678 | + |
| 679 | + llvm_unreachable("predeclared global operator new/delete is missing"); |
| 680 | +} |
| 681 | + |
651 | 682 | namespace { |
652 | 683 | /// Calls the given 'operator delete' on a single object. |
653 | 684 | struct CallObjectDelete final : EHScopeStack::Cleanup { |
|
0 commit comments