From 8d550863cb4a10c01b3798b0d20b56ef981851c1 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Sun, 26 Feb 2012 19:47:25 +0000 Subject: [PATCH] Move CharacterLiteral, FloatingLiteral and UnaryExprOrTypeTraitExpr flags over into Stmt. Apply the inheritance-padding trick to FloatingLiteral. Shrinks CharacterLiteral from 32 to 24 bytes and the other two from 40 to 32 bytes (x86_64). llvm-svn: 151500 --- clang/include/clang/AST/Expr.h | 67 +++++++++++++++++++--------------- clang/include/clang/AST/Stmt.h | 26 +++++++++++++ 2 files changed, 63 insertions(+), 30 deletions(-) diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 90f8bcdb805f..8da780c7a04d 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -1115,7 +1115,7 @@ public: void setValue(ASTContext &C, const llvm::APInt &Val) { setIntValue(C, Val); } }; -class APFloatStorage : public APNumericStorage { +class APFloatStorage : private APNumericStorage { public: llvm::APFloat getValue(bool IsIEEE) const { return llvm::APFloat(getIntValue(), IsIEEE); @@ -1183,28 +1183,30 @@ public: private: unsigned Value; SourceLocation Loc; - unsigned Kind : 2; public: // type should be IntTy CharacterLiteral(unsigned value, CharacterKind kind, QualType type, SourceLocation l) : Expr(CharacterLiteralClass, type, VK_RValue, OK_Ordinary, false, false, false, false), - Value(value), Loc(l), Kind(kind) { + Value(value), Loc(l) { + CharacterLiteralBits.Kind = kind; } /// \brief Construct an empty character literal. CharacterLiteral(EmptyShell Empty) : Expr(CharacterLiteralClass, Empty) { } SourceLocation getLocation() const { return Loc; } - CharacterKind getKind() const { return static_cast(Kind); } + CharacterKind getKind() const { + return static_cast(CharacterLiteralBits.Kind); + } SourceRange getSourceRange() const { return SourceRange(Loc); } unsigned getValue() const { return Value; } void setLocation(SourceLocation Location) { Loc = Location; } - void setKind(CharacterKind kind) { Kind = kind; } + void setKind(CharacterKind kind) { CharacterLiteralBits.Kind = kind; } void setValue(unsigned Val) { Value = Val; } static bool classof(const Stmt *T) { @@ -1216,41 +1218,41 @@ public: child_range children() { return child_range(); } }; -class FloatingLiteral : public Expr { - APFloatStorage Num; - bool IsIEEE : 1; // Distinguishes between PPC128 and IEEE128. - bool IsExact : 1; +class FloatingLiteral : public Expr, private APFloatStorage { SourceLocation Loc; FloatingLiteral(ASTContext &C, const llvm::APFloat &V, bool isexact, QualType Type, SourceLocation L) : Expr(FloatingLiteralClass, Type, VK_RValue, OK_Ordinary, false, false, - false, false), - IsIEEE(&C.getTargetInfo().getLongDoubleFormat() == - &llvm::APFloat::IEEEquad), - IsExact(isexact), Loc(L) { + false, false), Loc(L) { + FloatingLiteralBits.IsIEEE = + &C.getTargetInfo().getLongDoubleFormat() == &llvm::APFloat::IEEEquad; + FloatingLiteralBits.IsExact = isexact; setValue(C, V); } /// \brief Construct an empty floating-point literal. explicit FloatingLiteral(ASTContext &C, EmptyShell Empty) - : Expr(FloatingLiteralClass, Empty), - IsIEEE(&C.getTargetInfo().getLongDoubleFormat() == - &llvm::APFloat::IEEEquad), - IsExact(false) { } + : Expr(FloatingLiteralClass, Empty) { + FloatingLiteralBits.IsIEEE = + &C.getTargetInfo().getLongDoubleFormat() == &llvm::APFloat::IEEEquad; + FloatingLiteralBits.IsExact = false; + } public: static FloatingLiteral *Create(ASTContext &C, const llvm::APFloat &V, bool isexact, QualType Type, SourceLocation L); static FloatingLiteral *Create(ASTContext &C, EmptyShell Empty); - llvm::APFloat getValue() const { return Num.getValue(IsIEEE); } + llvm::APFloat getValue() const { + return APFloatStorage::getValue(FloatingLiteralBits.IsIEEE); + } void setValue(ASTContext &C, const llvm::APFloat &Val) { - Num.setValue(C, Val); + APFloatStorage::setValue(C, Val); } - bool isExact() const { return IsExact; } - void setExact(bool E) { IsExact = E; } + bool isExact() const { return FloatingLiteralBits.IsExact; } + void setExact(bool E) { FloatingLiteralBits.IsExact = E; } /// getValueAsApproximateDouble - This returns the value as an inaccurate /// double. Note that this may cause loss of precision, but is useful for @@ -1824,8 +1826,6 @@ public: /// expression operand. Used for sizeof/alignof (C99 6.5.3.4) and /// vec_step (OpenCL 1.1 6.11.12). class UnaryExprOrTypeTraitExpr : public Expr { - unsigned Kind : 2; - bool isType : 1; // true if operand is a type, false if an expression union { TypeSourceInfo *Ty; Stmt *Ex; @@ -1842,7 +1842,9 @@ public: TInfo->getType()->isDependentType(), TInfo->getType()->isInstantiationDependentType(), TInfo->getType()->containsUnexpandedParameterPack()), - Kind(ExprKind), isType(true), OpLoc(op), RParenLoc(rp) { + OpLoc(op), RParenLoc(rp) { + UnaryExprOrTypeTraitExprBits.Kind = ExprKind; + UnaryExprOrTypeTraitExprBits.IsType = true; Argument.Ty = TInfo; } @@ -1855,7 +1857,9 @@ public: E->isTypeDependent(), E->isInstantiationDependent(), E->containsUnexpandedParameterPack()), - Kind(ExprKind), isType(false), OpLoc(op), RParenLoc(rp) { + OpLoc(op), RParenLoc(rp) { + UnaryExprOrTypeTraitExprBits.Kind = ExprKind; + UnaryExprOrTypeTraitExprBits.IsType = false; Argument.Ex = E; } @@ -1864,11 +1868,11 @@ public: : Expr(UnaryExprOrTypeTraitExprClass, Empty) { } UnaryExprOrTypeTrait getKind() const { - return static_cast(Kind); + return static_cast(UnaryExprOrTypeTraitExprBits.Kind); } - void setKind(UnaryExprOrTypeTrait K) { Kind = K; } + void setKind(UnaryExprOrTypeTrait K) { UnaryExprOrTypeTraitExprBits.Kind = K;} - bool isArgumentType() const { return isType; } + bool isArgumentType() const { return UnaryExprOrTypeTraitExprBits.IsType; } QualType getArgumentType() const { return getArgumentTypeInfo()->getType(); } @@ -1884,10 +1888,13 @@ public: return const_cast(this)->getArgumentExpr(); } - void setArgument(Expr *E) { Argument.Ex = E; isType = false; } + void setArgument(Expr *E) { + Argument.Ex = E; + UnaryExprOrTypeTraitExprBits.IsType = false; + } void setArgument(TypeSourceInfo *TInfo) { Argument.Ty = TInfo; - isType = true; + UnaryExprOrTypeTraitExprBits.IsType = true; } /// Gets the argument type, or the type of the argument expression, whichever diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h index 1bc0c11ef597..c81798ccd2fb 100644 --- a/clang/include/clang/AST/Stmt.h +++ b/clang/include/clang/AST/Stmt.h @@ -159,6 +159,29 @@ protected: }; enum { NumExprBits = 16 }; + class CharacterLiteralBitfields { + friend class CharacterLiteral; + unsigned : NumExprBits; + + unsigned Kind : 2; + }; + + class FloatingLiteralBitfields { + friend class FloatingLiteral; + unsigned : NumExprBits; + + unsigned IsIEEE : 1; // Distinguishes between PPC128 and IEEE128. + unsigned IsExact : 1; + }; + + class UnaryExprOrTypeTraitExprBitfields { + friend class UnaryExprOrTypeTraitExpr; + unsigned : NumExprBits; + + unsigned Kind : 2; + unsigned IsType : 1; // true if operand is a type, false if an expression. + }; + class DeclRefExprBitfields { friend class DeclRefExpr; friend class ASTStmtReader; // deserialization @@ -252,6 +275,9 @@ protected: StmtBitfields StmtBits; CompoundStmtBitfields CompoundStmtBits; ExprBitfields ExprBits; + CharacterLiteralBitfields CharacterLiteralBits; + FloatingLiteralBitfields FloatingLiteralBits; + UnaryExprOrTypeTraitExprBitfields UnaryExprOrTypeTraitExprBits; DeclRefExprBitfields DeclRefExprBits; CastExprBitfields CastExprBits; CallExprBitfields CallExprBits;