Index: flang/CMakeLists.txt =================================================================== --- flang/CMakeLists.txt +++ flang/CMakeLists.txt @@ -2,8 +2,9 @@ set(CMAKE_BUILD_WITH_INSTALL_NAME_DIR ON) -# Flang requires C++17. +# Flang requires C++17 or later. set(CMAKE_CXX_STANDARD 17) +#set(CMAKE_CXX_STANDARD 20) # also works set(CMAKE_CXX_STANDARD_REQUIRED TRUE) set(CMAKE_CXX_EXTENSIONS OFF) @@ -116,7 +117,7 @@ # avoid some mixed compilation flangs (e.g. -std=c++11 ... -std=c++17). if (DEFINED LLVM_CXX_STD) message("LLVM configuration set a C++ standard: ${LLVM_CXX_STD}") - if (NOT LLVM_CXX_STD EQUAL "c++17") + if (NOT LLVM_CXX_STD STREQUAL "c++${CMAKE_CXX_STANDARD}") message("Flang: Overriding LLVM's 'cxx_std' setting...") message(" removing '-std=${LLVM_CXX_STD}'") message(" CMAKE_CXX_FLAGS='${CMAKE_CXX_FLAGS}'") Index: flang/include/flang/Parser/parse-tree.h =================================================================== --- flang/include/flang/Parser/parse-tree.h +++ flang/include/flang/Parser/parse-tree.h @@ -269,7 +269,8 @@ // A parse tree node with provenance only struct Verbatim { - BOILERPLATE(Verbatim); + COPY_AND_ASSIGN_BOILERPLATE(Verbatim); + constexpr Verbatim() {} using EmptyTrait = std::true_type; CharBlock source; }; Index: flang/lib/Evaluate/check-expression.cpp =================================================================== --- flang/lib/Evaluate/check-expression.cpp +++ flang/lib/Evaluate/check-expression.cpp @@ -173,7 +173,7 @@ return (*this)(x.left()); } template bool operator()(const Expr &x) { - return std::visit([=](const auto &y) { return (*this)(y); }, x.u); + return std::visit([this](const auto &y) { return (*this)(y); }, x.u); } bool operator()(const Expr &x) { if (IsNullPointer(x)) { Index: flang/lib/Lower/ConvertExpr.cpp =================================================================== --- flang/lib/Lower/ConvertExpr.cpp +++ flang/lib/Lower/ConvertExpr.cpp @@ -2587,13 +2587,13 @@ if (isParenthesizedVariable(x)) { // Parenthesised variables are lowered to a reference to the variable // storage. When passing it as an argument, a copy must be passed. - return [=](IterSpace iters) -> ExtValue { + return [this, loc, cc](IterSpace iters) -> ExtValue { return createInMemoryScalarCopy(builder, loc, cc(iters)); }; } mlir::Type storageType = fir::unwrapSequenceType(converter.genType(toEvExpr(x))); - return [=](IterSpace iters) -> ExtValue { + return [this, loc, cc, storageType](IterSpace iters) -> ExtValue { return placeScalarValueInMemory(builder, loc, cc(iters), storageType); }; } @@ -2621,7 +2621,7 @@ mlir::Value isPresent = genActualIsPresentTest(builder, loc, optionalArg); operands.emplace_back( - [=](IterSpace iters) -> ExtValue { + [this, loc, optionalArg](IterSpace iters) -> ExtValue { return genLoad(builder, loc, optionalArg); }, isPresent); @@ -2640,7 +2640,8 @@ fir::FirOpBuilder *bldr = &converter.getFirOpBuilder(); llvm::StringRef name = intrinsic.name; - return [=](IterSpace iters) -> ExtValue { + return [this, bldr, loc, name, operands, + retTy](IterSpace iters) -> ExtValue { auto getArgument = [&](std::size_t i) -> ExtValue { return operands[i].first(iters); }; @@ -2696,7 +2697,7 @@ case Fortran::lower::LowerIntrinsicArgAs::Box: { PushSemantics(ConstituentSemantics::RefOpaque); auto lambda = genElementalArgument(*expr); - operands.emplace_back([=](IterSpace iters) { + operands.emplace_back([this, lambda, loc](IterSpace iters) { return builder.createBox(loc, lambda(iters)); }); } break; @@ -2708,7 +2709,7 @@ } // Let the intrinsic library lower the intrinsic procedure call - return [=](IterSpace iters) { + return [this, loc, name, operands, retTy](IterSpace iters) { llvm::SmallVector args; for (const auto &cc : operands) args.push_back(cc(iters)); @@ -2748,7 +2749,7 @@ procRef.proc().GetSpecificIntrinsic()) { if (explicitSpaceIsActive() && procRef.Rank() == 0) { // Elide any implicit loop iters. - return [=, &procRef](IterSpace) { + return [this, intrinsic, loc, &procRef, retTy](IterSpace) { return ScalarExprLowering{loc, converter, symMap, stmtCtx} .genIntrinsicRef(procRef, *intrinsic, retTy); }; @@ -2760,7 +2761,7 @@ if (explicitSpaceIsActive() && procRef.Rank() == 0) { // Elide any implicit loop iters. - return [=, &procRef](IterSpace) { + return [this, loc, &procRef, retTy](IterSpace) { return ScalarExprLowering{loc, converter, symMap, stmtCtx} .genProcedureRef(procRef, retTy); }; @@ -2836,7 +2837,7 @@ mlir::Location loc = getLoc(); auto lambda = genarr(evEx.left()); auto rf = genarr(evEx.right()); - return [=](IterSpace iters) -> ExtValue { + return [this, lambda, loc, rf](IterSpace iters) -> ExtValue { mlir::Value left = fir::getBase(lambda(iters)); mlir::Value right = fir::getBase(rf(iters)); return builder.create(loc, left, right); @@ -3405,7 +3406,7 @@ CC genAsScalar(const A &x) { mlir::Location loc = getLoc(); if (isProjectedCopyInCopyOut()) { - return [=, &x, builder = &converter.getFirOpBuilder()]( + return [this, loc, &x, builder = &converter.getFirOpBuilder()]( IterSpace iters) -> ExtValue { ExtValue exv = asScalarRef(x); mlir::Value val = fir::getBase(exv); @@ -3424,7 +3425,7 @@ return exv; }; } - return [=, &x](IterSpace) { return asScalar(x); }; + return [this, &x](IterSpace) { return asScalar(x); }; } CC genarr(const Fortran::semantics::Symbol &x, ComponentPath &components) { @@ -3560,7 +3561,8 @@ ArrayOperand{memref, shape, noSlice, /*mayBeAbsent=*/true}); // By value semantics. - auto cc = [=](IterSpace iters) -> ExtValue { + auto cc = [this, arrLd, arrLdTypeParams, eleType, exv, loc, + noSlice](IterSpace iters) -> ExtValue { auto arrFetch = builder.create( loc, eleType, arrLd, iters.iterVec(), arrLdTypeParams); return fir::factory::arraySectionElementToExtendedValue( @@ -3594,7 +3596,7 @@ mlir::Value isPresent; mlir::Type eleType; std::tie(cc, isPresent, eleType) = genOptionalArrayFetch(expr); - return [=](IterSpace iters) -> ExtValue { + return [this, cc, eleType, isPresent, loc](IterSpace iters) -> ExtValue { mlir::Value elementValue = builder .genIfOp(loc, {eleType}, isPresent, @@ -3704,7 +3706,8 @@ // Here the continuation will `array_fetch` a value from an array and // then store that value in a temporary. One can thus imitate pass by // value even when the call is pass by reference. - return [=](IterSpace iters) -> ExtValue { + return [this, arrLd, arrLdTypeParams, arrTy, extMemref, loc, + slice](IterSpace iters) -> ExtValue { mlir::Value base; mlir::Type eleTy = fir::applyPathToType(arrTy, iters.iterVec()); if (isAdjustedArrayElementType(eleTy)) { @@ -3726,7 +3729,8 @@ } // In the default case, the array reference forwards an `array_fetch` or // `array_access` Op in the continuation. - return [=](IterSpace iters) -> ExtValue { + return [this, arrLd, arrLdTypeParams, arrTy, components, extMemref, loc, + slice](IterSpace iters) -> ExtValue { mlir::Type eleTy = fir::applyPathToType(arrTy, iters.iterVec()); if (isAdjustedArrayElementType(eleTy)) { mlir::Type eleRefTy = builder.getRefType(eleTy); @@ -3817,7 +3821,7 @@ /// `iters.element` into the destination array, `iters.innerArgument`. Handles /// by value and by reference assignment. CC defaultStoreToDestination(const Fortran::evaluate::Substring *substring) { - return [=](IterSpace iterSpace) -> ExtValue { + return [this, substring](IterSpace iterSpace) -> ExtValue { mlir::Location loc = getLoc(); mlir::Value innerArg = iterSpace.innerArgument(); fir::ExtendedValue exv = iterSpace.elementExv(); Index: flang/lib/Optimizer/CodeGen/TargetRewrite.cpp =================================================================== --- flang/lib/Optimizer/CodeGen/TargetRewrite.cpp +++ flang/lib/Optimizer/CodeGen/TargetRewrite.cpp @@ -130,14 +130,14 @@ rewriter->create(loc, dyn_cast_ptrEleTy(resTy)); newInTys.push_back(resTy); newOpers.push_back(stack); - return [=](mlir::Operation *) -> mlir::Value { + return [this, loc, stack, ty](mlir::Operation *) -> mlir::Value { auto memTy = ReferenceType::get(ty); auto cast = rewriter->create(loc, memTy, stack); return rewriter->create(loc, cast); }; } newResTys.push_back(resTy); - return [=](mlir::Operation *call) -> mlir::Value { + return [this, loc, resTy, ty](mlir::Operation *call) -> mlir::Value { auto mem = rewriter->create(loc, resTy); rewriter->create(loc, call->getResult(0), mem); auto memTy = ReferenceType::get(ty); @@ -719,10 +719,11 @@ auto argTy = std::get(tup); if (attr.isSRet()) { unsigned argNo = newInTys.size(); - fixups.emplace_back( - FixupTy::Codes::ReturnAsStore, argNo, [=](mlir::FuncOp func) { - func.setArgAttr(argNo, "llvm.sret", rewriter->getUnitAttr()); - }); + fixups.emplace_back(FixupTy::Codes::ReturnAsStore, argNo, + [this, argNo](mlir::FuncOp func) { + func.setArgAttr(argNo, "llvm.sret", + rewriter->getUnitAttr()); + }); newInTys.push_back(argTy); return; } @@ -751,7 +752,8 @@ if (attr.isByVal()) { if (auto align = attr.getAlignment()) fixups.emplace_back( - FixupTy::Codes::ArgumentAsLoad, argNo, [=](mlir::FuncOp func) { + FixupTy::Codes::ArgumentAsLoad, argNo, + [this, align, argNo](mlir::FuncOp func) { func.setArgAttr(argNo, "llvm.byval", rewriter->getUnitAttr()); func.setArgAttr(argNo, "llvm.align", rewriter->getIntegerAttr( @@ -759,17 +761,18 @@ }); else fixups.emplace_back(FixupTy::Codes::ArgumentAsLoad, newInTys.size(), - [=](mlir::FuncOp func) { + [this, argNo](mlir::FuncOp func) { func.setArgAttr(argNo, "llvm.byval", rewriter->getUnitAttr()); }); } else { if (auto align = attr.getAlignment()) - fixups.emplace_back(fixupCode, argNo, index, [=](mlir::FuncOp func) { - func.setArgAttr( - argNo, "llvm.align", - rewriter->getIntegerAttr(rewriter->getIntegerType(32), align)); - }); + fixups.emplace_back( + fixupCode, argNo, index, [this, align, argNo](mlir::FuncOp func) { + func.setArgAttr(argNo, "llvm.align", + rewriter->getIntegerAttr( + rewriter->getIntegerType(32), align)); + }); else fixups.emplace_back(fixupCode, argNo, index); } Index: flang/lib/Semantics/resolve-names.cpp =================================================================== --- flang/lib/Semantics/resolve-names.cpp +++ flang/lib/Semantics/resolve-names.cpp @@ -5485,7 +5485,7 @@ const parser::TypeParamValue &x, common::TypeParamAttr attr) { return std::visit( common::visitors{ - [=](const parser::ScalarIntExpr &x) { // C704 + [this, attr](const parser::ScalarIntExpr &x) { // C704 return ParamValue{EvaluateIntExpr(x), attr}; }, [=](const parser::Star &) { return ParamValue::Assumed(attr); }, @@ -6126,8 +6126,8 @@ const parser::DataRef &x) { return std::visit( common::visitors{ - [=](const parser::Name &y) { return ResolveName(y); }, - [=](const Indirection &y) { + [this](const parser::Name &y) { return ResolveName(y); }, + [this](const Indirection &y) { return ResolveStructureComponent(y.value()); }, [&](const Indirection &y) { @@ -6622,10 +6622,10 @@ for (const auto &accessId : accessIds) { std::visit( common::visitors{ - [=](const parser::Name &y) { + [this, accessAttr](const parser::Name &y) { Resolve(y, SetAccess(y.source, accessAttr)); }, - [=](const Indirection &y) { + [this, accessAttr](const Indirection &y) { auto info{GenericSpecInfo{y.value()}}; const auto &symbolName{info.symbolName()}; if (auto *symbol{FindInScope(symbolName)}) {