llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-modules Author: Haojian Wu (hokein) <details> <summary>Changes</summary> This patch reduces the size of several AST nodes by moving some fields into the free bitfield space in the base `Stmt` class: * `CXXForRangeStmt`: 96 → 88 bytes * `ChooseExpr`: 56 → 48 bytes * `ArrayTypeTraitExpr`: 56 → 48 bytes * `ExpressionTraitExpr`: 40 → 32 bytes * `CXXFoldExpr`: 64 → 56 bytes * `ShuffleExpr`: 40 → 32 bytes * `PackIndexingExpr`: 48 → 40 bytes There are no noticeable memory savings (`Expr/Stmt` memory usage 125,824,496 vs 125,826,336 bytes for `SemaExpr.cpp`) in my testing, likely because these node types are not among the most common in typical ASTs. --- Patch is 20.98 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/142585.diff 8 Files Affected: - (modified) clang/include/clang/AST/Expr.h (+19-13) - (modified) clang/include/clang/AST/ExprCXX.h (+36-38) - (modified) clang/include/clang/AST/Stmt.h (+77) - (modified) clang/include/clang/AST/StmtCXX.h (+1-1) - (modified) clang/lib/AST/Expr.cpp (+4-3) - (modified) clang/lib/AST/ExprCXX.cpp (+2-1) - (modified) clang/lib/Serialization/ASTReaderStmt.cpp (+7-7) - (modified) clang/lib/Serialization/ASTWriterStmt.cpp (+3-3) ``````````diff diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index a83320a7ddec2..5b033ff8660fb 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -3110,7 +3110,9 @@ class CallExpr : public Expr { /// Bluntly set a new number of arguments without doing any checks whatsoever. /// Only used during construction of a CallExpr in a few places in Sema. /// FIXME: Find a way to remove it. - void setNumArgsUnsafe(unsigned NewNumArgs) { NumArgs = NewNumArgs; } + void setNumArgsUnsafe(unsigned NewNumArgs) { + NumArgs = NewNumArgs; + } typedef ExprIterator arg_iterator; typedef ConstExprIterator const_arg_iterator; @@ -4523,7 +4525,6 @@ class ShuffleVectorExpr : public Expr { // indices. The number of values in this list is always // 2+the number of indices in the vector type. Stmt **SubExprs; - unsigned NumExprs; public: ShuffleVectorExpr(const ASTContext &C, ArrayRef<Expr*> args, QualType Type, @@ -4549,34 +4550,39 @@ class ShuffleVectorExpr : public Expr { /// getNumSubExprs - Return the size of the SubExprs array. This includes the /// constant expression, the actual arguments passed in, and the function /// pointers. - unsigned getNumSubExprs() const { return NumExprs; } + unsigned getNumSubExprs() const { return ShuffleVectorExprBits.NumExprs; } /// Retrieve the array of expressions. Expr **getSubExprs() { return reinterpret_cast<Expr **>(SubExprs); } /// getExpr - Return the Expr at the specified index. Expr *getExpr(unsigned Index) { - assert((Index < NumExprs) && "Arg access out of range!"); + assert((Index < ShuffleVectorExprBits.NumExprs) && + "Arg access out of range!"); return cast<Expr>(SubExprs[Index]); } const Expr *getExpr(unsigned Index) const { - assert((Index < NumExprs) && "Arg access out of range!"); + assert((Index < ShuffleVectorExprBits.NumExprs) && + "Arg access out of range!"); return cast<Expr>(SubExprs[Index]); } void setExprs(const ASTContext &C, ArrayRef<Expr *> Exprs); llvm::APSInt getShuffleMaskIdx(const ASTContext &Ctx, unsigned N) const { - assert((N < NumExprs - 2) && "Shuffle idx out of range!"); + assert((N < ShuffleVectorExprBits.NumExprs - 2) && + "Shuffle idx out of range!"); return getExpr(N+2)->EvaluateKnownConstInt(Ctx); } // Iterators child_range children() { - return child_range(&SubExprs[0], &SubExprs[0]+NumExprs); + return child_range(&SubExprs[0], + &SubExprs[0] + ShuffleVectorExprBits.NumExprs); } const_child_range children() const { - return const_child_range(&SubExprs[0], &SubExprs[0] + NumExprs); + return const_child_range(&SubExprs[0], + &SubExprs[0] + ShuffleVectorExprBits.NumExprs); } }; @@ -4718,13 +4724,13 @@ class ChooseExpr : public Expr { enum { COND, LHS, RHS, END_EXPR }; Stmt* SubExprs[END_EXPR]; // Left/Middle/Right hand sides. SourceLocation BuiltinLoc, RParenLoc; - bool CondIsTrue; + public: ChooseExpr(SourceLocation BLoc, Expr *cond, Expr *lhs, Expr *rhs, QualType t, ExprValueKind VK, ExprObjectKind OK, SourceLocation RP, bool condIsTrue) - : Expr(ChooseExprClass, t, VK, OK), BuiltinLoc(BLoc), RParenLoc(RP), - CondIsTrue(condIsTrue) { + : Expr(ChooseExprClass, t, VK, OK), BuiltinLoc(BLoc), RParenLoc(RP) { + ChooseExprBits.CondIsTrue = condIsTrue; SubExprs[COND] = cond; SubExprs[LHS] = lhs; SubExprs[RHS] = rhs; @@ -4740,9 +4746,9 @@ class ChooseExpr : public Expr { bool isConditionTrue() const { assert(!isConditionDependent() && "Dependent condition isn't true or false"); - return CondIsTrue; + return ChooseExprBits.CondIsTrue; } - void setIsConditionTrue(bool isTrue) { CondIsTrue = isTrue; } + void setIsConditionTrue(bool isTrue) { ChooseExprBits.CondIsTrue = isTrue; } bool isConditionDependent() const { return getCond()->isTypeDependent() || getCond()->isValueDependent(); diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index 844f6dd90ae1d..bc70ba08f3073 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -2973,10 +2973,6 @@ class TypeTraitExpr final /// __array_extent(int[10][20], 1) == 20 /// \endcode class ArrayTypeTraitExpr : public Expr { - /// The trait. An ArrayTypeTrait enum in MSVC compat unsigned. - LLVM_PREFERRED_TYPE(ArrayTypeTrait) - unsigned ATT : 2; - /// The value of the type trait. Unspecified if dependent. uint64_t Value = 0; @@ -2998,21 +2994,27 @@ class ArrayTypeTraitExpr : public Expr { ArrayTypeTraitExpr(SourceLocation loc, ArrayTypeTrait att, TypeSourceInfo *queried, uint64_t value, Expr *dimension, SourceLocation rparen, QualType ty) - : Expr(ArrayTypeTraitExprClass, ty, VK_PRValue, OK_Ordinary), ATT(att), + : Expr(ArrayTypeTraitExprClass, ty, VK_PRValue, OK_Ordinary), Value(value), Dimension(dimension), Loc(loc), RParen(rparen), QueriedType(queried) { assert(att <= ATT_Last && "invalid enum value!"); - assert(static_cast<unsigned>(att) == ATT && "ATT overflow!"); + ArrayTypeTraitExprBits.ATT = att; + assert(static_cast<unsigned>(att) == ArrayTypeTraitExprBits.ATT && + "ATT overflow!"); setDependence(computeDependence(this)); } explicit ArrayTypeTraitExpr(EmptyShell Empty) - : Expr(ArrayTypeTraitExprClass, Empty), ATT(0) {} + : Expr(ArrayTypeTraitExprClass, Empty) { + ArrayTypeTraitExprBits.ATT = 0; + } SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; } SourceLocation getEndLoc() const LLVM_READONLY { return RParen; } - ArrayTypeTrait getTrait() const { return static_cast<ArrayTypeTrait>(ATT); } + ArrayTypeTrait getTrait() const { + return static_cast<ArrayTypeTrait>(ArrayTypeTraitExprBits.ATT); + } QualType getQueriedType() const { return QueriedType->getType(); } @@ -3044,14 +3046,6 @@ class ArrayTypeTraitExpr : public Expr { /// __is_lvalue_expr(1) == false /// \endcode class ExpressionTraitExpr : public Expr { - /// The trait. A ExpressionTrait enum in MSVC compatible unsigned. - LLVM_PREFERRED_TYPE(ExpressionTrait) - unsigned ET : 31; - - /// The value of the type trait. Unspecified if dependent. - LLVM_PREFERRED_TYPE(bool) - unsigned Value : 1; - /// The location of the type trait keyword. SourceLocation Loc; @@ -3067,24 +3061,32 @@ class ExpressionTraitExpr : public Expr { ExpressionTraitExpr(SourceLocation loc, ExpressionTrait et, Expr *queried, bool value, SourceLocation rparen, QualType resultType) : Expr(ExpressionTraitExprClass, resultType, VK_PRValue, OK_Ordinary), - ET(et), Value(value), Loc(loc), RParen(rparen), - QueriedExpression(queried) { + Loc(loc), RParen(rparen), QueriedExpression(queried) { + ExpressionTraitExprBits.ET = et; + ExpressionTraitExprBits.Value = value; + assert(et <= ET_Last && "invalid enum value!"); - assert(static_cast<unsigned>(et) == ET && "ET overflow!"); + assert(static_cast<unsigned>(et) == ExpressionTraitExprBits.ET && + "ET overflow!"); setDependence(computeDependence(this)); } explicit ExpressionTraitExpr(EmptyShell Empty) - : Expr(ExpressionTraitExprClass, Empty), ET(0), Value(false) {} + : Expr(ExpressionTraitExprClass, Empty) { + ExpressionTraitExprBits.ET = 0; + ExpressionTraitExprBits.Value = false; + } SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; } SourceLocation getEndLoc() const LLVM_READONLY { return RParen; } - ExpressionTrait getTrait() const { return static_cast<ExpressionTrait>(ET); } + ExpressionTrait getTrait() const { + return static_cast<ExpressionTrait>(ExpressionTraitExprBits.ET); + } Expr *getQueriedExpression() const { return QueriedExpression; } - bool getValue() const { return Value; } + bool getValue() const { return ExpressionTraitExprBits.Value; } static bool classof(const Stmt *T) { return T->getStmtClass() == ExpressionTraitExprClass; @@ -4505,22 +4507,15 @@ class PackIndexingExpr final // The pack being indexed, followed by the index Stmt *SubExprs[2]; - // The size of the trailing expressions. - unsigned TransformedExpressions : 31; - - LLVM_PREFERRED_TYPE(bool) - unsigned FullySubstituted : 1; - PackIndexingExpr(QualType Type, SourceLocation EllipsisLoc, SourceLocation RSquareLoc, Expr *PackIdExpr, Expr *IndexExpr, ArrayRef<Expr *> SubstitutedExprs = {}, bool FullySubstituted = false) : Expr(PackIndexingExprClass, Type, VK_LValue, OK_Ordinary), EllipsisLoc(EllipsisLoc), RSquareLoc(RSquareLoc), - SubExprs{PackIdExpr, IndexExpr}, - TransformedExpressions(SubstitutedExprs.size()), - FullySubstituted(FullySubstituted) { - + SubExprs{PackIdExpr, IndexExpr} { + PackIndexingExprBits.TransformedExpressions = SubstitutedExprs.size(); + PackIndexingExprBits.FullySubstituted = FullySubstituted; auto *Exprs = getTrailingObjects<Expr *>(); std::uninitialized_copy(SubstitutedExprs.begin(), SubstitutedExprs.end(), Exprs); @@ -4534,7 +4529,7 @@ class PackIndexingExpr final PackIndexingExpr(EmptyShell Empty) : Expr(PackIndexingExprClass, Empty) {} unsigned numTrailingObjects(OverloadToken<Expr *>) const { - return TransformedExpressions; + return PackIndexingExprBits.TransformedExpressions; } public: @@ -4547,11 +4542,14 @@ class PackIndexingExpr final static PackIndexingExpr *CreateDeserialized(ASTContext &Context, unsigned NumTransformedExprs); - bool isFullySubstituted() const { return FullySubstituted; } + bool isFullySubstituted() const { + return PackIndexingExprBits.FullySubstituted; + } /// Determine if the expression was expanded to empty. bool expandsToEmptyPack() const { - return isFullySubstituted() && TransformedExpressions == 0; + return isFullySubstituted() && + PackIndexingExprBits.TransformedExpressions == 0; } /// Determine the location of the 'sizeof' keyword. @@ -4589,7 +4587,8 @@ class PackIndexingExpr final /// Return the trailing expressions, regardless of the expansion. ArrayRef<Expr *> getExpressions() const { - return {getTrailingObjects<Expr *>(), TransformedExpressions}; + return {getTrailingObjects<Expr *>(), + PackIndexingExprBits.TransformedExpressions}; } static bool classof(const Stmt *T) { @@ -4987,7 +4986,6 @@ class CXXFoldExpr : public Expr { // than the number of expansions. UnsignedOrNone NumExpansions = std::nullopt; Stmt *SubExprs[SubExpr::Count]; - BinaryOperatorKind Opcode; public: CXXFoldExpr(QualType T, UnresolvedLookupExpr *Callee, @@ -5020,7 +5018,7 @@ class CXXFoldExpr : public Expr { SourceLocation getLParenLoc() const { return LParenLoc; } SourceLocation getRParenLoc() const { return RParenLoc; } SourceLocation getEllipsisLoc() const { return EllipsisLoc; } - BinaryOperatorKind getOperator() const { return Opcode; } + BinaryOperatorKind getOperator() const { return CXXFoldExprBits.Opcode; } UnsignedOrNone getNumExpansions() const { return NumExpansions; } diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h index 336eb6d3df7e1..43e9f61c1b461 100644 --- a/clang/include/clang/AST/Stmt.h +++ b/clang/include/clang/AST/Stmt.h @@ -19,6 +19,7 @@ #include "clang/AST/OperationKinds.h" #include "clang/AST/StmtIterator.h" #include "clang/Basic/CapturedStmt.h" +#include "clang/Basic/ExpressionTraits.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/Lambda.h" @@ -732,6 +733,15 @@ class alignas(void *) Stmt { unsigned ProducedByFoldExpansion : 1; }; + class ShuffleVectorExprBitfields { + friend class ShuffleVectorExpr; + + LLVM_PREFERRED_TYPE(ExprBitfields) + unsigned : NumExprBits; + + unsigned NumExprs; + }; + class StmtExprBitfields { friend class ASTStmtReader; friend class StmtExpr; @@ -745,6 +755,16 @@ class alignas(void *) Stmt { unsigned TemplateDepth; }; + class ChooseExprBitfields { + friend class ASTStmtReader; + friend class ChooseExpr; + + LLVM_PREFERRED_TYPE(ExprBitfields) + unsigned : NumExprBits; + + bool CondIsTrue : 1; + }; + //===--- C++ Expression bitfields classes ---===// class CXXOperatorCallExprBitfields { @@ -1180,6 +1200,57 @@ class alignas(void *) Stmt { SourceLocation RequiresKWLoc; }; + class ArrayTypeTraitExprBitfields { + friend class ArrayTypeTraitExpr; + friend class ASTStmtReader; + LLVM_PREFERRED_TYPE(ExprBitfields) + unsigned : NumExprBits; + + /// The trait. An ArrayTypeTrait enum in MSVC compat unsigned. + LLVM_PREFERRED_TYPE(ArrayTypeTrait) + unsigned ATT : 2; + }; + + class ExpressionTraitExprBitfields { + friend class ExpressionTraitExpr; + friend class ASTStmtReader; + LLVM_PREFERRED_TYPE(ExprBitfields) + unsigned : NumExprBits; + + /// The trait. A ExpressionTrait enum in MSVC compatible unsigned. + LLVM_PREFERRED_TYPE(ExpressionTrait) + unsigned ET : 31; + + /// The value of the type trait. Unspecified if dependent. + LLVM_PREFERRED_TYPE(bool) + unsigned Value : 1; + }; + + class CXXFoldExprBitfields { + friend class CXXFoldExpr; + friend class ASTStmtReader; + friend class ASTStmtWriter; + + LLVM_PREFERRED_TYPE(ExprBitfields) + unsigned : NumExprBits; + + BinaryOperatorKind Opcode; + }; + + class PackIndexingExprBitfields { + friend class PackIndexingExpr; + friend class ASTStmtWriter; + friend class ASTStmtReader; + + LLVM_PREFERRED_TYPE(ExprBitfields) + unsigned : NumExprBits; + // The size of the trailing expressions. + unsigned TransformedExpressions : 31; + + LLVM_PREFERRED_TYPE(bool) + unsigned FullySubstituted : 1; + }; + //===--- C++ Coroutines bitfields classes ---===// class CoawaitExprBitfields { @@ -1275,9 +1346,11 @@ class alignas(void *) Stmt { PseudoObjectExprBitfields PseudoObjectExprBits; SourceLocExprBitfields SourceLocExprBits; ParenExprBitfields ParenExprBits; + ShuffleVectorExprBitfields ShuffleVectorExprBits; // GNU Extensions. StmtExprBitfields StmtExprBits; + ChooseExprBitfields ChooseExprBits; // C++ Expressions CXXOperatorCallExprBitfields CXXOperatorCallExprBits; @@ -1304,6 +1377,10 @@ class alignas(void *) Stmt { SubstNonTypeTemplateParmExprBitfields SubstNonTypeTemplateParmExprBits; LambdaExprBitfields LambdaExprBits; RequiresExprBitfields RequiresExprBits; + ArrayTypeTraitExprBitfields ArrayTypeTraitExprBits; + ExpressionTraitExprBitfields ExpressionTraitExprBits; + CXXFoldExprBitfields CXXFoldExprBits; + PackIndexingExprBitfields PackIndexingExprBits; // C++ Coroutines expressions CoawaitExprBitfields CoawaitBits; diff --git a/clang/include/clang/AST/StmtCXX.h b/clang/include/clang/AST/StmtCXX.h index 8b4ef24ed376a..a15a445fbea40 100644 --- a/clang/include/clang/AST/StmtCXX.h +++ b/clang/include/clang/AST/StmtCXX.h @@ -133,11 +133,11 @@ class CXXTryStmt final : public Stmt, /// analysis of the constituent components. The original syntactic components /// can be extracted using getLoopVariable and getRangeInit. class CXXForRangeStmt : public Stmt { - SourceLocation ForLoc; enum { INIT, RANGE, BEGINSTMT, ENDSTMT, COND, INC, LOOPVAR, BODY, END }; // SubExprs[RANGE] is an expression or declstmt. // SubExprs[COND] and SubExprs[INC] are expressions. Stmt *SubExprs[END]; + SourceLocation ForLoc; SourceLocation CoawaitLoc; SourceLocation ColonLoc; SourceLocation RParenLoc; diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 59c0e47c7c195..dee1258691698 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -4405,7 +4405,8 @@ ShuffleVectorExpr::ShuffleVectorExpr(const ASTContext &C, ArrayRef<Expr *> args, QualType Type, SourceLocation BLoc, SourceLocation RP) : Expr(ShuffleVectorExprClass, Type, VK_PRValue, OK_Ordinary), - BuiltinLoc(BLoc), RParenLoc(RP), NumExprs(args.size()) { + BuiltinLoc(BLoc), RParenLoc(RP) { + ShuffleVectorExprBits.NumExprs = args.size(); SubExprs = new (C) Stmt*[args.size()]; for (unsigned i = 0; i != args.size(); i++) SubExprs[i] = args[i]; @@ -4416,8 +4417,8 @@ ShuffleVectorExpr::ShuffleVectorExpr(const ASTContext &C, ArrayRef<Expr *> args, void ShuffleVectorExpr::setExprs(const ASTContext &C, ArrayRef<Expr *> Exprs) { if (SubExprs) C.Deallocate(SubExprs); - this->NumExprs = Exprs.size(); - SubExprs = new (C) Stmt*[NumExprs]; + this->ShuffleVectorExprBits.NumExprs = Exprs.size(); + SubExprs = new (C) Stmt *[ShuffleVectorExprBits.NumExprs]; memcpy(SubExprs, Exprs.data(), sizeof(Expr *) * Exprs.size()); } diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp index 169f11b611066..0d56d10d1a58b 100644 --- a/clang/lib/AST/ExprCXX.cpp +++ b/clang/lib/AST/ExprCXX.cpp @@ -1989,7 +1989,8 @@ CXXFoldExpr::CXXFoldExpr(QualType T, UnresolvedLookupExpr *Callee, UnsignedOrNone NumExpansions) : Expr(CXXFoldExprClass, T, VK_PRValue, OK_Ordinary), LParenLoc(LParenLoc), EllipsisLoc(EllipsisLoc), RParenLoc(RParenLoc), - NumExpansions(NumExpansions), Opcode(Opcode) { + NumExpansions(NumExpansions) { + CXXFoldExprBits.Opcode = Opcode; // We rely on asserted invariant to distinguish left and right folds. assert(((LHS && LHS->containsUnexpandedParameterPack()) != (RHS && RHS->containsUnexpandedParameterPack())) && diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index f41cfcc53a35d..142332b1cf4bc 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -2156,7 +2156,7 @@ void ASTStmtReader::VisitTypeTraitExpr(TypeTraitExpr *E) { void ASTStmtReader::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) { VisitExpr(E); - E->ATT = (ArrayTypeTrait)Record.readInt(); + E->ArrayTypeTraitExprBits.ATT = (ArrayTypeTrait)Record.readInt(); E->Value = (unsigned int)Record.readInt(); SourceRange Range = readSourceRange(); E->Loc = Range.getBegin(); @@ -2167,8 +2167,8 @@ void ASTStmtReader::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) { void ASTStmtReader::VisitExpressionTraitExpr(ExpressionTraitExpr *E) { VisitExpr(E); - E->ET = (ExpressionTrait)Record.readInt(); - E->Value = (bool)Record.readInt(); + E->ExpressionTraitExprBits.ET = (ExpressionTrait)Record.readInt(); + E->ExpressionTraitExprBits.Value = (bool)Record.readInt(); SourceRange Range = readSourceRange(); E->QueriedExpression = Record.readSubExpr(); E->Loc = Range.getBegin(); @@ -2209,14 +2209,14 @@ void ASTStmtReader::VisitSizeOfPackExpr(SizeOfPackExpr *E) { void ASTStmtReader::VisitPackIndexingExpr(PackIndexingExpr *E) { VisitExpr(E); - E->TransformedExpressions = Record.readInt(); - E->FullySubstituted = Record.readInt(); + E->PackIndexingExprBits.TransformedExpressions = Record.readInt(); + E->PackIndexingExprBits.FullySubstituted = Record.readInt(); E->EllipsisLoc = readSourceLocation(); E->RSquareLoc = readSourceLocation(); E->SubExprs[0] = Record.readStmt(); E->SubExprs[1] = Record.readStmt(); auto **Exprs = E->getTrailingObjects<Expr *>(); - for (unsigned I = 0; I < E->TransformedExpressions; ++I) + for (unsigned I = 0; I < E->PackIndexingExprBits.TransformedExpressions; ++I) Exprs[I] = Record.readExpr(); } @@ -2275,7 +2275,7 @@ void ASTStmtReader::VisitCXXFoldExpr(CXXFoldExpr *E) { E->SubExprs[0] = Record.readSubExpr(); E->SubExprs[1] = Record.readSubExpr(); E->SubExprs[2] = Record.readSubExpr(); - E->Opcode = (BinaryOperatorKind)Record.readInt(); + E->CXXFoldExprBits.Opcode = (BinaryOperatorKind)Record.readInt(); } void ASTStmtReader::VisitCXXParenListInitExpr(CXXParenListInitExpr *E) { diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serializa... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/142585 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits