llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clangir @llvm/pr-subscribers-clang-codegen Author: Henrich Lauko (xlauko) <details> <summary>Changes</summary> Follow-up to PR #<!-- -->221001. Ten more helpers that both CodeGens had equivalent copies of, several of them already marked "should be shared" in CIR. Instead of growing CodeGenUtils.h, each helper goes in a header named for the classic CodeGen file it came from, with the CGExpr*.cpp family sharing ExprUtils.h. CIR's files mirror the classic ones, so the grouping reads the same from both sides. CIR's getNoFPClassTestMask returned unsigned where classic returns llvm::FPClassTest; the shared version keeps the classic return type. Assisted-by: Claude Code (Claude Fable 5.1). --- Patch is 62.73 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/223418.diff 25 Files Affected: - (added) clang/include/clang/CodeGenUtils/CallUtils.h (+32) - (added) clang/include/clang/CodeGenUtils/ClassUtils.h (+29) - (added) clang/include/clang/CodeGenUtils/ExprUtils.h (+48) - (added) clang/include/clang/CodeGenUtils/FunctionUtils.h (+28) - (added) clang/include/clang/CodeGenUtils/ItaniumCXXABIUtils.h (+28) - (modified) clang/lib/CIR/CodeGen/CIRGenCall.cpp (+7-21) - (modified) clang/lib/CIR/CodeGen/CIRGenClass.cpp (+2-25) - (modified) clang/lib/CIR/CodeGen/CIRGenExpr.cpp (+3-21) - (modified) clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp (+3-89) - (modified) clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp (+5-19) - (modified) clang/lib/CIR/CodeGen/CIRGenFunction.cpp (+2-19) - (modified) clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp (+3-53) - (modified) clang/lib/CodeGen/CGCall.cpp (+10-24) - (modified) clang/lib/CodeGen/CGClass.cpp (+3-25) - (modified) clang/lib/CodeGen/CGExpr.cpp (+3-21) - (modified) clang/lib/CodeGen/CGExprAgg.cpp (+3-90) - (modified) clang/lib/CodeGen/CGExprScalar.cpp (+5-20) - (modified) clang/lib/CodeGen/CodeGenFunction.cpp (+3-20) - (modified) clang/lib/CodeGen/ItaniumCXXABI.cpp (+3-53) - (modified) clang/lib/CodeGenUtils/CMakeLists.txt (+5) - (added) clang/lib/CodeGenUtils/CallUtils.cpp (+28) - (added) clang/lib/CodeGenUtils/ClassUtils.cpp (+39) - (added) clang/lib/CodeGenUtils/ExprUtils.cpp (+128) - (added) clang/lib/CodeGenUtils/FunctionUtils.cpp (+29) - (added) clang/lib/CodeGenUtils/ItaniumCXXABIUtils.cpp (+64) ``````````diff diff --git a/clang/include/clang/CodeGenUtils/CallUtils.h b/clang/include/clang/CodeGenUtils/CallUtils.h new file mode 100644 index 00000000000000..450a62a448e491 --- /dev/null +++ b/clang/include/clang/CodeGenUtils/CallUtils.h @@ -0,0 +1,32 @@ +//===--- CallUtils.h - Shared call emission queries -------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file holds the AST and language option queries that both classic +// CodeGen and CIR CodeGen need while building a call and its argument and +// return value attributes. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_CODEGENUTILS_CALLUTILS_H +#define LLVM_CLANG_CODEGENUTILS_CALLUTILS_H + +#include "clang/AST/ASTContext.h" +#include "llvm/ADT/FloatingPointMode.h" + +namespace clang::CodeGenUtils { + +/// Returns the canonical formal type of the given C++ method. +CanQual<FunctionProtoType> getFormalType(const CXXMethodDecl *MD); + +/// Returns the set of floating-point value kinds that the language options +/// promise never reach a function's arguments or return value. +llvm::FPClassTest getNoFPClassTestMask(const LangOptions &LangOpts); + +} // namespace clang::CodeGenUtils + +#endif // LLVM_CLANG_CODEGENUTILS_CALLUTILS_H diff --git a/clang/include/clang/CodeGenUtils/ClassUtils.h b/clang/include/clang/CodeGenUtils/ClassUtils.h new file mode 100644 index 00000000000000..63664ed737933a --- /dev/null +++ b/clang/include/clang/CodeGenUtils/ClassUtils.h @@ -0,0 +1,29 @@ +//===--- ClassUtils.h - Shared C++ class emission queries -------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file holds the AST queries about C++ class construction and destruction +// that both classic CodeGen and CIR CodeGen need, chiefly to decide when a +// vtable pointer has to be established before running member initializers or +// a destructor body. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_CODEGENUTILS_CLASSUTILS_H +#define LLVM_CLANG_CODEGENUTILS_CLASSUTILS_H + +#include "clang/AST/ASTContext.h" + +namespace clang::CodeGenUtils { + +/// Check whether \p Init uses 'this' in a way which requires the vtable to be +/// properly set. +bool baseInitializerUsesThis(ASTContext &Ctx, const Expr *Init); + +} // namespace clang::CodeGenUtils + +#endif // LLVM_CLANG_CODEGENUTILS_CLASSUTILS_H diff --git a/clang/include/clang/CodeGenUtils/ExprUtils.h b/clang/include/clang/CodeGenUtils/ExprUtils.h new file mode 100644 index 00000000000000..e6a5248440d339 --- /dev/null +++ b/clang/include/clang/CodeGenUtils/ExprUtils.h @@ -0,0 +1,48 @@ +//===--- ExprUtils.h - Shared expression emission queries -------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file holds the AST queries about expressions that both classic CodeGen +// and CIR CodeGen need while emitting scalar, aggregate and lvalue +// expressions. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_CODEGENUTILS_EXPRUTILS_H +#define LLVM_CLANG_CODEGENUTILS_EXPRUTILS_H + +#include "clang/AST/ASTContext.h" + +namespace clang::CodeGenUtils { + +/// Strip off the variably-modified array types wrapping \p VLA and return the +/// first element type that has a fixed size. +QualType getFixedSizeElementType(const ASTContext &Ctx, + const VariableArrayType *VLA); + +/// Check whether the value of \p E is possibly a reference to or into a +/// __block variable. +bool isBlockVarRef(const Expr *E); + +/// Check whether \p E is cheap enough and side-effect-free enough to evaluate +/// unconditionally instead of conditionally. This is used to convert control +/// flow into selects in some cases. +bool isCheapEnoughToEvaluateUnconditionally(const Expr *E, + const ASTContext &Ctx); + +/// Check whether \p E is a trivial array filler, that is, one that is +/// equivalent to zero-initialization. +bool isTrivialFiller(const Expr *E); + +/// Detect the unusual situation where an inline version of a builtin is +/// shadowed by a non-inline version. In that case we should pick the external +/// one everywhere. That's GCC behavior too. +bool onlyHasInlineBuiltinDeclaration(const FunctionDecl *FD); + +} // namespace clang::CodeGenUtils + +#endif // LLVM_CLANG_CODEGENUTILS_EXPRUTILS_H diff --git a/clang/include/clang/CodeGenUtils/FunctionUtils.h b/clang/include/clang/CodeGenUtils/FunctionUtils.h new file mode 100644 index 00000000000000..f924874d829e06 --- /dev/null +++ b/clang/include/clang/CodeGenUtils/FunctionUtils.h @@ -0,0 +1,28 @@ +//===--- FunctionUtils.h - Shared function emission queries -----*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file holds the queries that both classic CodeGen and CIR CodeGen need +// while emitting a function body. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_CODEGENUTILS_FUNCTIONUTILS_H +#define LLVM_CLANG_CODEGENUTILS_FUNCTIONUTILS_H + +#include "clang/Basic/CodeGenOptions.h" +#include "clang/Basic/LangOptions.h" + +namespace clang::CodeGenUtils { + +/// Decide whether we need to emit the lifetime markers. +bool shouldEmitLifetimeMarkers(const CodeGenOptions &CGOpts, + const LangOptions &LangOpts); + +} // namespace clang::CodeGenUtils + +#endif // LLVM_CLANG_CODEGENUTILS_FUNCTIONUTILS_H diff --git a/clang/include/clang/CodeGenUtils/ItaniumCXXABIUtils.h b/clang/include/clang/CodeGenUtils/ItaniumCXXABIUtils.h new file mode 100644 index 00000000000000..45b358ad343bba --- /dev/null +++ b/clang/include/clang/CodeGenUtils/ItaniumCXXABIUtils.h @@ -0,0 +1,28 @@ +//===--- ItaniumCXXABIUtils.h - Shared Itanium C++ ABI queries --*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file holds the Itanium C++ ABI queries that both classic CodeGen and +// CIR CodeGen need while lowering ABI constructs whose encoding the ABI +// specifies in terms of the AST. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_CODEGENUTILS_ITANIUMCXXABIUTILS_H +#define LLVM_CLANG_CODEGENUTILS_ITANIUMCXXABIUTILS_H + +#include "clang/AST/ASTContext.h" + +namespace clang::CodeGenUtils { + +/// Compute the src2dst_offset hint as described in the Itanium C++ ABI [2.9.7]. +CharUnits computeOffsetHint(ASTContext &Ctx, const CXXRecordDecl *Src, + const CXXRecordDecl *Dst); + +} // namespace clang::CodeGenUtils + +#endif // LLVM_CLANG_CODEGENUTILS_ITANIUMCXXABIUTILS_H diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.cpp b/clang/lib/CIR/CodeGen/CIRGenCall.cpp index e7b451b82d853e..d0ef751347b5a5 100644 --- a/clang/lib/CIR/CodeGen/CIRGenCall.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenCall.cpp @@ -20,6 +20,7 @@ #include "mlir/IR/Attributes.h" #include "clang/CIR/ABIArgInfo.h" #include "clang/CIR/MissingFeatures.h" +#include "clang/CodeGenUtils/CallUtils.h" #include "llvm/ADT/FloatingPointMode.h" #include "llvm/ADT/StringSet.h" #include "llvm/Support/TypeSize.h" @@ -619,16 +620,6 @@ static bool determineNoUndef(QualType clangTy, CIRGenTypes &types, return false; } -/// Compute the nofpclass mask for FP types based on language options. -static unsigned getNoFPClassTestMask(const LangOptions &langOpts) { - unsigned mask = 0; - if (langOpts.NoHonorInfs) - mask |= llvm::fcInf; - if (langOpts.NoHonorNaNs) - mask |= llvm::fcNan; - return mask; -} - void CIRGenModule::constructFunctionReturnAttributes( const CIRGenFunctionInfo &info, const Decl *targetDecl, bool isThunk, mlir::NamedAttrList &retAttrs) { @@ -644,7 +635,8 @@ void CIRGenModule::constructFunctionReturnAttributes( mlir::UnitAttr::get(&getMLIRContext())); if (retTy->hasFloatingRepresentation()) - if (unsigned mask = getNoFPClassTestMask(getLangOpts())) + if (llvm::FPClassTest mask = + CodeGenUtils::getNoFPClassTestMask(getLangOpts())) retAttrs.set(mlir::LLVM::LLVMDialect::getNoFPClassAttrName(), builder.getI64IntegerAttr(mask)); @@ -769,7 +761,8 @@ void CIRGenModule::constructFunctionArgumentAttributes( } if (argType->hasFloatingRepresentation()) - if (unsigned mask = getNoFPClassTestMask(getLangOpts())) + if (llvm::FPClassTest mask = + CodeGenUtils::getNoFPClassTestMask(getLangOpts())) argAttrList.set(mlir::LLVM::LLVMDialect::getNoFPClassAttrName(), builder.getI64IntegerAttr(mask)); @@ -793,13 +786,6 @@ void CIRGenModule::constructFunctionArgumentAttributes( } } -/// Returns the canonical formal type of the given C++ method. -static CanQual<FunctionProtoType> getFormalType(const CXXMethodDecl *md) { - return md->getType() - ->getCanonicalTypeUnqualified() - .getAs<FunctionProtoType>(); -} - /// Adds the formal parameters in FPT to the given prefix. If any parameter in /// FPT has pass_object_size attrs, then we'll add parameters for those, too. /// TODO(cir): this should be shared with LLVM codegen @@ -844,7 +830,7 @@ CIRGenTypes::arrangeCXXStructorDeclaration(GlobalDecl gd) { passParams = inheritingCtorHasParams(inherited, gd.getCtorType()); } - CanQual<FunctionProtoType> fpt = getFormalType(md); + CanQual<FunctionProtoType> fpt = CodeGenUtils::getFormalType(md); if (passParams) appendParameterTypes(*this, argTypes, fpt); @@ -994,7 +980,7 @@ const CIRGenFunctionInfo &CIRGenTypes::arrangeCXXConstructorCall( // +1 for implicit this, which should always be args[0] unsigned totalPrefixArgs = 1 + extraPrefixArgs; - CanQual<FunctionProtoType> fpt = getFormalType(d); + CanQual<FunctionProtoType> fpt = CodeGenUtils::getFormalType(d); RequiredArgs required = passProtoArgs ? RequiredArgs::getFromProtoWithExtraSlots( fpt, totalPrefixArgs + extraSuffixArgs) diff --git a/clang/lib/CIR/CodeGen/CIRGenClass.cpp b/clang/lib/CIR/CodeGen/CIRGenClass.cpp index 8cd014415e4eee..c8edc1ccd02c68 100644 --- a/clang/lib/CIR/CodeGen/CIRGenClass.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenClass.cpp @@ -14,12 +14,12 @@ #include "CIRGenFunction.h" #include "CIRGenValue.h" -#include "clang/AST/EvaluatedExprVisitor.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/RecordLayout.h" #include "clang/AST/Type.h" #include "clang/CIR/Dialect/IR/CIRDialect.h" #include "clang/CIR/MissingFeatures.h" +#include "clang/CodeGenUtils/ClassUtils.h" #include "clang/CodeGenUtils/CodeGenUtils.h" using namespace clang; @@ -199,31 +199,8 @@ struct CallDelegatingCtorDtor final : EHScopeStack::Cleanup { } }; -/// A visitor which checks whether an initializer uses 'this' in a -/// way which requires the vtable to be properly set. -struct DynamicThisUseChecker - : ConstEvaluatedExprVisitor<DynamicThisUseChecker> { - using super = ConstEvaluatedExprVisitor<DynamicThisUseChecker>; - - bool usesThis = false; - - DynamicThisUseChecker(const ASTContext &c) : super(c) {} - - // Black-list all explicit and implicit references to 'this'. - // - // Do we need to worry about external references to 'this' derived - // from arbitrary code? If so, then anything which runs arbitrary - // external code might potentially access the vtable. - void VisitCXXThisExpr(const CXXThisExpr *e) { usesThis = true; } -}; } // end anonymous namespace -static bool baseInitializerUsesThis(ASTContext &c, const Expr *init) { - DynamicThisUseChecker checker(c); - checker.Visit(init); - return checker.usesThis; -} - /// Gets the address of a direct base class within a complete object. /// This should only be used for (1) non-virtual bases or (2) virtual bases /// when the type is known to be complete (e.g. in complete destructors). @@ -266,7 +243,7 @@ void CIRGenFunction::emitBaseInitializer(mlir::Location loc, // If the initializer for the base (other than the constructor // itself) accesses 'this' in any way, we need to initialize the // vtables. - if (baseInitializerUsesThis(getContext(), baseInit->getInit())) + if (CodeGenUtils::baseInitializerUsesThis(getContext(), baseInit->getInit())) initializeVTablePointers(loc, classDecl); // We can pretend to be a complete class because it only matters for diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp index 7e9a4d9458c93a..664425b20577f9 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp @@ -31,6 +31,7 @@ #include "clang/CIR/Dialect/IR/CIRTypes.h" #include "clang/CIR/MissingFeatures.h" #include "clang/CodeGenUtils/CodeGenUtils.h" +#include "clang/CodeGenUtils/ExprUtils.h" #include <optional> using namespace clang; @@ -1300,15 +1301,6 @@ static CharUnits getArrayElementAlign(CharUnits arrayAlign, mlir::Value idx, return arrayAlign.alignmentOfArrayElement(eltSize); } -static QualType getFixedSizeElementType(const ASTContext &astContext, - const VariableArrayType *vla) { - QualType eltType; - do { - eltType = vla->getElementType(); - } while ((vla = astContext.getAsVariableArrayType(eltType))); - return eltType; -} - static mlir::Value emitArraySubscriptPtr(CIRGenFunction &cgf, mlir::Location beginLoc, mlir::Location endLoc, mlir::Value ptr, @@ -1332,7 +1324,7 @@ static Address emitArraySubscriptPtr(CIRGenFunction &cgf, // the thing that the indices are expressed in terms of. if (const VariableArrayType *vla = cgf.getContext().getAsVariableArrayType(eltType)) { - eltType = getFixedSizeElementType(cgf.getContext(), vla); + eltType = CodeGenUtils::getFixedSizeElementType(cgf.getContext(), vla); } // We can use that to compute the best alignment of the element. @@ -2218,16 +2210,6 @@ RValue CIRGenFunction::emitAnyExpr(const Expr *e, AggValueSlot aggSlot, llvm_unreachable("bad evaluation kind"); } -// Detect the unusual situation where an inline version is shadowed by a -// non-inline version. In that case we should pick the external one -// everywhere. That's GCC behavior too. -static bool onlyHasInlineBuiltinDeclaration(const FunctionDecl *fd) { - for (const FunctionDecl *pd = fd; pd; pd = pd->getPreviousDecl()) - if (!pd->isInlineBuiltinDeclaration()) - return false; - return true; -} - CIRGenCallee CIRGenFunction::emitDirectCallee(const GlobalDecl &gd) { const auto *fd = cast<FunctionDecl>(gd.getDecl()); @@ -2249,7 +2231,7 @@ CIRGenCallee CIRGenFunction::emitDirectCallee(const GlobalDecl &gd) { // name to make it clear it's not the actual builtin. if (auto fn = dyn_cast<cir::FuncOp>(curFn); (!fn || fn.getName() != fdInlineName) && - onlyHasInlineBuiltinDeclaration(fd)) { + CodeGenUtils::onlyHasInlineBuiltinDeclaration(fd)) { cir::FuncOp clone = mlir::cast_or_null<cir::FuncOp>(cgm.getGlobalValue(fdInlineName)); diff --git a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp index 2fb66232d806cd..f9a4eb2b2033a2 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp @@ -20,6 +20,7 @@ #include "clang/AST/Expr.h" #include "clang/AST/RecordLayout.h" #include "clang/AST/StmtVisitor.h" +#include "clang/CodeGenUtils/ExprUtils.h" #include "llvm/IR/Value.h" #include <cstdint> @@ -27,73 +28,6 @@ using namespace clang; using namespace clang::CIRGen; namespace { -// FIXME(cir): This should be a common helper between CIRGen -// and traditional CodeGen -/// Is the value of the given expression possibly a reference to or -/// into a __block variable? -static bool isBlockVarRef(const Expr *e) { - // Make sure we look through parens. - e = e->IgnoreParens(); - - // Check for a direct reference to a __block variable. - if (const DeclRefExpr *dre = dyn_cast<DeclRefExpr>(e)) { - const VarDecl *var = dyn_cast<VarDecl>(dre->getDecl()); - return (var && var->hasAttr<BlocksAttr>()); - } - - // More complicated stuff. - - // Binary operators. - if (const BinaryOperator *op = dyn_cast<BinaryOperator>(e)) { - // For an assignment or pointer-to-member operation, just care - // about the LHS. - if (op->isAssignmentOp() || op->isPtrMemOp()) - return isBlockVarRef(op->getLHS()); - - // For a comma, just care about the RHS. - if (op->getOpcode() == BO_Comma) - return isBlockVarRef(op->getRHS()); - - // FIXME: pointer arithmetic? - return false; - - // Check both sides of a conditional operator. - } else if (const AbstractConditionalOperator *op = - dyn_cast<AbstractConditionalOperator>(e)) { - return isBlockVarRef(op->getTrueExpr()) || - isBlockVarRef(op->getFalseExpr()); - - // OVEs are required to support BinaryConditionalOperators. - } else if (const OpaqueValueExpr *op = dyn_cast<OpaqueValueExpr>(e)) { - if (const Expr *src = op->getSourceExpr()) - return isBlockVarRef(src); - - // Casts are necessary to get things like (*(int*)&var) = foo(). - // We don't really care about the kind of cast here, except - // we don't want to look through l2r casts, because it's okay - // to get the *value* in a __block variable. - } else if (const CastExpr *cast = dyn_cast<CastExpr>(e)) { - if (cast->getCastKind() == CK_LValueToRValue) - return false; - return isBlockVarRef(cast->getSubExpr()); - - // Handle unary operators. Again, just aggressively look through - // it, ignoring the operation. - } else if (const UnaryOperator *uop = dyn_cast<UnaryOperator>(e)) { - return isBlockVarRef(uop->getSubExpr()); - - // Look into the base of a field access. - } else if (const MemberExpr *mem = dyn_cast<MemberExpr>(e)) { - return isBlockVarRef(mem->getBase()); - - // Look into the base of a subscript. - } else if (const ArraySubscriptExpr *sub = dyn_cast<ArraySubscriptExpr>(e)) { - return isBlockVarRef(sub->getBase()); - } - - return false; -} - class AggExprEmitter : public StmtVisitor<AggExprEmitter> { CIRGenFunction &cgf; @@ -172,7 +106,7 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> { e->getRHS()->getType()) && "Invalid assignment"); - if (isBlockVarRef(e->getLHS()) && + if (CodeGenUtils::isBlockVarRef(e->getLHS()) && e->getRHS()->HasSideEffects(cgf.getContext())) { cgf.cgm.errorNYI(e->getSourceRange(), "block var reference with side effects"); @@ -729,26 +663,6 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> { } // namespace -static bool isTrivialFiller(Expr *e) { - if (!e) - return true; - - if (isa<ImplicitValueInitExpr>(e)) - return true; - - if (auto *ile = dyn_cast<InitListExpr>(e)) { - if (ile->getNumInits()) - return false; - return isTrivialFiller(ile->getArrayFiller()); - } - - if (const auto *cons = dyn_cast_or_null<CXXCon... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/223418 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
