diff options
Diffstat (limited to 'clang/lib/CIR/CodeGen/CIRGenDecl.cpp')
| -rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenDecl.cpp | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp index 7cc024fd5596..66cd67389c1c 100644 --- a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp @@ -31,6 +31,8 @@ CIRGenFunction::emitAutoVarAlloca(const VarDecl &d, cgm.errorNYI(d.getSourceRange(), "emitAutoVarAlloca: address space"); mlir::Location loc = getLoc(d.getSourceRange()); + bool nrvo = + getContext().getLangOpts().ElideConstructors && d.isNRVOVariable(); CIRGenFunction::AutoVarEmission emission(d); emission.IsEscapingByRef = d.isEscapingByref(); @@ -44,16 +46,37 @@ CIRGenFunction::emitAutoVarAlloca(const VarDecl &d, if (ty->isVariablyModifiedType()) cgm.errorNYI(d.getSourceRange(), "emitAutoVarDecl: variably modified type"); + assert(!cir::MissingFeatures::openMP()); + Address address = Address::invalid(); if (!ty->isConstantSizeType()) cgm.errorNYI(d.getSourceRange(), "emitAutoVarDecl: non-constant size type"); // A normal fixed sized variable becomes an alloca in the entry block, - mlir::Type allocaTy = convertTypeForMem(ty); - // Create the temp alloca and declare variable using it. - address = createTempAlloca(allocaTy, alignment, loc, d.getName(), - /*arraySize=*/nullptr, /*alloca=*/nullptr, ip); - declare(address.getPointer(), &d, ty, getLoc(d.getSourceRange()), alignment); + // unless: + // - it's an NRVO variable. + // - we are compiling OpenMP and it's an OpenMP local variable. + if (nrvo) { + // The named return value optimization: allocate this variable in the + // return slot, so that we can elide the copy when returning this + // variable (C++0x [class.copy]p34). + address = returnValue; + + if (const RecordDecl *rd = ty->getAsRecordDecl()) { + if (const auto *cxxrd = dyn_cast<CXXRecordDecl>(rd); + (cxxrd && !cxxrd->hasTrivialDestructor()) || + rd->isNonTrivialToPrimitiveDestroy()) + cgm.errorNYI(d.getSourceRange(), "emitAutoVarAlloca: set NRVO flag"); + } + } else { + // A normal fixed sized variable becomes an alloca in the entry block, + mlir::Type allocaTy = convertTypeForMem(ty); + // Create the temp alloca and declare variable using it. + address = createTempAlloca(allocaTy, alignment, loc, d.getName(), + /*arraySize=*/nullptr, /*alloca=*/nullptr, ip); + declare(address.getPointer(), &d, ty, getLoc(d.getSourceRange()), + alignment); + } emission.Addr = address; setAddrOfLocalVar(&d, address); |
