From 91728fcd199ea3952a401b0b3ee7651228245bd0 Mon Sep 17 00:00:00 2001 From: Bruno Ricci Date: Mon, 3 Dec 2018 12:32:32 +0000 Subject: [PATCH] [AST][NFC] Pack CXXDeleteExpr Use the newly available space in the bit-fields of Stmt. This saves 8 bytes per CXXDeleteExpr. NFC. llvm-svn: 348128 --- clang/include/clang/AST/ExprCXX.h | 58 ++++++++++++------------------- clang/include/clang/AST/Stmt.h | 26 ++++++++++++++ clang/lib/Serialization/ASTReaderStmt.cpp | 10 +++--- clang/lib/Serialization/ASTWriterStmt.cpp | 2 +- 4 files changed, 55 insertions(+), 41 deletions(-) diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index a525490..51db921 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -2086,55 +2086,43 @@ public: /// Represents a \c delete expression for memory deallocation and /// destructor calls, e.g. "delete[] pArray". class CXXDeleteExpr : public Expr { + friend class ASTStmtReader; + /// Points to the operator delete overload that is used. Could be a member. FunctionDecl *OperatorDelete = nullptr; /// The pointer expression to be deleted. Stmt *Argument = nullptr; - /// Location of the expression. - SourceLocation Loc; - - /// Is this a forced global delete, i.e. "::delete"? - bool GlobalDelete : 1; - - /// Is this the array form of delete, i.e. "delete[]"? - bool ArrayForm : 1; - - /// ArrayFormAsWritten can be different from ArrayForm if 'delete' is applied - /// to pointer-to-array type (ArrayFormAsWritten will be false while ArrayForm - /// will be true). - bool ArrayFormAsWritten : 1; - - /// Does the usual deallocation function for the element type require - /// a size_t argument? - bool UsualArrayDeleteWantsSize : 1; - public: - friend class ASTStmtReader; + CXXDeleteExpr(QualType Ty, bool GlobalDelete, bool ArrayForm, + bool ArrayFormAsWritten, bool UsualArrayDeleteWantsSize, + FunctionDecl *OperatorDelete, Expr *Arg, SourceLocation Loc) + : Expr(CXXDeleteExprClass, Ty, VK_RValue, OK_Ordinary, false, false, + Arg->isInstantiationDependent(), + Arg->containsUnexpandedParameterPack()), + OperatorDelete(OperatorDelete), Argument(Arg) { + CXXDeleteExprBits.GlobalDelete = GlobalDelete; + CXXDeleteExprBits.ArrayForm = ArrayForm; + CXXDeleteExprBits.ArrayFormAsWritten = ArrayFormAsWritten; + CXXDeleteExprBits.UsualArrayDeleteWantsSize = UsualArrayDeleteWantsSize; + CXXDeleteExprBits.Loc = Loc; + } - CXXDeleteExpr(QualType ty, bool globalDelete, bool arrayForm, - bool arrayFormAsWritten, bool usualArrayDeleteWantsSize, - FunctionDecl *operatorDelete, Expr *arg, SourceLocation loc) - : Expr(CXXDeleteExprClass, ty, VK_RValue, OK_Ordinary, false, false, - arg->isInstantiationDependent(), - arg->containsUnexpandedParameterPack()), - OperatorDelete(operatorDelete), Argument(arg), Loc(loc), - GlobalDelete(globalDelete), - ArrayForm(arrayForm), ArrayFormAsWritten(arrayFormAsWritten), - UsualArrayDeleteWantsSize(usualArrayDeleteWantsSize) {} explicit CXXDeleteExpr(EmptyShell Shell) : Expr(CXXDeleteExprClass, Shell) {} - bool isGlobalDelete() const { return GlobalDelete; } - bool isArrayForm() const { return ArrayForm; } - bool isArrayFormAsWritten() const { return ArrayFormAsWritten; } + bool isGlobalDelete() const { return CXXDeleteExprBits.GlobalDelete; } + bool isArrayForm() const { return CXXDeleteExprBits.ArrayForm; } + bool isArrayFormAsWritten() const { + return CXXDeleteExprBits.ArrayFormAsWritten; + } /// Answers whether the usual array deallocation function for the /// allocated type expects the size of the allocation as a /// parameter. This can be true even if the actual deallocation /// function that we're using doesn't want a size. bool doesUsualArrayDeleteWantSize() const { - return UsualArrayDeleteWantsSize; + return CXXDeleteExprBits.UsualArrayDeleteWantsSize; } FunctionDecl *getOperatorDelete() const { return OperatorDelete; } @@ -2148,7 +2136,7 @@ public: /// be a pointer, return an invalid type. QualType getDestroyedType() const; - SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; } + SourceLocation getBeginLoc() const { return CXXDeleteExprBits.Loc; } SourceLocation getEndLoc() const LLVM_READONLY { return Argument->getEndLoc(); } @@ -2158,7 +2146,7 @@ public: } // Iterators - child_range children() { return child_range(&Argument, &Argument+1); } + child_range children() { return child_range(&Argument, &Argument + 1); } }; /// Stores the type being destroyed by a pseudo-destructor expression. diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h index a78e461..0d1ca0a 100644 --- a/clang/include/clang/AST/Stmt.h +++ b/clang/include/clang/AST/Stmt.h @@ -586,6 +586,31 @@ protected: SourceLocation Loc; }; + class CXXDeleteExprBitfields { + friend class ASTStmtReader; + friend class CXXDeleteExpr; + + unsigned : NumExprBits; + + /// Is this a forced global delete, i.e. "::delete"? + unsigned GlobalDelete : 1; + + /// Is this the array form of delete, i.e. "delete[]"? + unsigned ArrayForm : 1; + + /// ArrayFormAsWritten can be different from ArrayForm if 'delete' is + /// applied to pointer-to-array type (ArrayFormAsWritten will be false + /// while ArrayForm will be true). + unsigned ArrayFormAsWritten : 1; + + /// Does the usual deallocation function for the element type require + /// a size_t argument? + unsigned UsualArrayDeleteWantsSize : 1; + + /// Location of the expression. + SourceLocation Loc; + }; + class TypeTraitExprBitfields { friend class ASTStmtReader; friend class ASTStmtWriter; @@ -692,6 +717,7 @@ protected: CXXThrowExprBitfields CXXThrowExprBits; CXXDefaultArgExprBitfields CXXDefaultArgExprBits; CXXDefaultInitExprBitfields CXXDefaultInitExprBits; + CXXDeleteExprBitfields CXXDeleteExprBits; TypeTraitExprBitfields TypeTraitExprBits; ExprWithCleanupsBitfields ExprWithCleanupsBits; diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index a9baca8..6e13bf0 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -1527,13 +1527,13 @@ void ASTStmtReader::VisitCXXNewExpr(CXXNewExpr *E) { void ASTStmtReader::VisitCXXDeleteExpr(CXXDeleteExpr *E) { VisitExpr(E); - E->GlobalDelete = Record.readInt(); - E->ArrayForm = Record.readInt(); - E->ArrayFormAsWritten = Record.readInt(); - E->UsualArrayDeleteWantsSize = Record.readInt(); + E->CXXDeleteExprBits.GlobalDelete = Record.readInt(); + E->CXXDeleteExprBits.ArrayForm = Record.readInt(); + E->CXXDeleteExprBits.ArrayFormAsWritten = Record.readInt(); + E->CXXDeleteExprBits.UsualArrayDeleteWantsSize = Record.readInt(); E->OperatorDelete = ReadDeclAs(); E->Argument = Record.readSubExpr(); - E->Loc = ReadSourceLocation(); + E->CXXDeleteExprBits.Loc = ReadSourceLocation(); } void ASTStmtReader::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) { diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index e36b557..edc66c5 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -1506,7 +1506,7 @@ void ASTStmtWriter::VisitCXXDeleteExpr(CXXDeleteExpr *E) { Record.push_back(E->doesUsualArrayDeleteWantSize()); Record.AddDeclRef(E->getOperatorDelete()); Record.AddStmt(E->getArgument()); - Record.AddSourceLocation(E->getSourceRange().getBegin()); + Record.AddSourceLocation(E->getBeginLoc()); Code = serialization::EXPR_CXX_DELETE; } -- 2.7.4