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

Reply via email to