[clang] [CIR][CodeGen][NFCI] Move shared AST-only helpers into CodeGenUtils (PR #223418)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 21 07:14:35 PDT 2026
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
More information about the cfe-commits
mailing list